openwall / john

John the Ripper jumbo - advanced offline password cracker, which supports hundreds of hash and cipher types, and runs on many operating systems, CPUs, GPUs, and even some FPGAs
https://www.openwall.com/john/
Other
10.04k stars 2.08k forks source link

gpg2john segfaults with fuzzed input #2255

Closed frank-dittrich closed 7 years ago

frank-dittrich commented 8 years ago

This is the contents of fail_gpg2john-1.hex:

a6dba6db0002271700022717

(no newline, in case it matters for base64conf)

~/git/JtR/run$ ./base64conv -q -i hex -o raw -r fail_gpg2john-1.hex -w fail_gpg2john-1.raw
~/git/JtR/run$ ./gpg2john fail_gpg2john-1.raw
    Encrypted data [sym alg is IDEA, simple string-to-key]
[gpg2john] MDC is misssing, expect false positives!
ASAN:SIGSEGV
=================================================================
==28549==ERROR: AddressSanitizer: SEGV on unknown address 0x7ffc8d3ec4f3 (pc 0x7f5a157955ab bp 0x000000000001 sp 0x7ffcd5f106e0 T0)
    #0 0x7f5a157955aa in _IO_default_xsputn (/lib/x86_64-linux-gnu/libc.so.6+0x7b5aa)
    #1 0x7f5a15767200 in vfprintf (/lib/x86_64-linux-gnu/libc.so.6+0x4d200)
    #2 0x7f5a1582fe93 in __vsprintf_chk (/lib/x86_64-linux-gnu/libc.so.6+0x115e93)
    #3 0x7f5a1582fdec in __sprintf_chk (/lib/x86_64-linux-gnu/libc.so.6+0x115dec)
    #4 0xe6fea5 in sprintf /usr/include/x86_64-linux-gnu/bits/stdio2.h:33
    #5 0xe6fea5 in Symmetrically_Encrypted_Data_Packet /home/ubuntuadm/git/JtR/src/gpg2john.c:953
    #6 0xe84bb3 in parse_packet /home/ubuntuadm/git/JtR/src/gpg2john.c:1531
    #7 0xe87714 in gpg2john /home/ubuntuadm/git/JtR/src/gpg2john.c:360
    #8 0x419909 in main /home/ubuntuadm/git/JtR/src/john.c:1933
    #9 0x7f5a1573a82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #10 0x422628 in _start (/home/ubuntuadm/git/JtR/run/john+0x422628)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV ??:0 _IO_default_xsputn
==28549==ABORTING

Similar segfaults with these files converted back from hex to raw:

c9ffff7ffffffc
d2ffff000010000000ff283a19fe45
frank-dittrich commented 8 years ago

Three more files which cause gpg2john to segfault:

a6a6fc0000a6fe00001f7f
a680000034a6fffc610a070000ff610a0700000080150080
8800cfa6e520004820

All the above found using american fuzzy lop, in less than 1 hour of fuzzing gpg2john using afl. Alf produced 103 crashes so far, and thinks these 6 are unique segfaults. I found at least 2 different back traces. This is the 2nd backtrace:

==27895==ERROR: AddressSanitizer: SEGV on unknown address 0x7ffd800586d0 (pc 0x7f440ad2b5ab bp 0x000000000001 sp 0x7ffd82057e90 T0)
    #0 0x7f440ad2b5aa in _IO_default_xsputn (/lib/x86_64-linux-gnu/libc.so.6+0x7b5aa)
    #1 0x7f440acfd200 in vfprintf (/lib/x86_64-linux-gnu/libc.so.6+0x4d200)
    #2 0x7f440adc5e93 in __vsprintf_chk (/lib/x86_64-linux-gnu/libc.so.6+0x115e93)
    #3 0x7f440adc5dec in __sprintf_chk (/lib/x86_64-linux-gnu/libc.so.6+0x115dec)
    #4 0xe70ef9 in sprintf /usr/include/x86_64-linux-gnu/bits/stdio2.h:33
    #5 0xe70ef9 in Symmetrically_Encrypted_and_MDC_Packet /home/ubuntuadm/git/JtR/src/gpg2john.c:1065
    #6 0xe84bb3 in parse_packet /home/ubuntuadm/git/JtR/src/gpg2john.c:1531
    #7 0xe87714 in gpg2john /home/ubuntuadm/git/JtR/src/gpg2john.c:360
    #8 0x419909 in main /home/ubuntuadm/git/JtR/src/john.c:1933
    #9 0x7f440acd082f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #10 0x422628 in _start (/home/ubuntuadm/git/JtR/run/john+0x422628)

Afl is still running, so I guess more problems might be found.

magnumripper commented 8 years ago

Any issues that involve fuzzed / purposely b0rken input should state so in the title please.

frank-dittrich commented 8 years ago

While most of the other segfaults afl found so far result in the same two back traces I already posted, this one

d2ffffffffcb8dd24c

will result in

ASAN:SIGSEGV
=================================================================
==3623==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f35f001ad84 bp 0x7ffc609a1d70 sp 0x7ffc60981cc8 T0)
    #0 0x7f35f001ad83 in strlen (/lib/x86_64-linux-gnu/libc.so.6+0x8ad83)
    #1 0x7f35effff5db in _IO_puts (/lib/x86_64-linux-gnu/libc.so.6+0x6f5db)
    #2 0x8429d6 in Symmetrically_Encrypted_and_MDC_Packet /home/ubuntuadm/git/JtR/src/gpg2john.c:1071
    #3 0x8442b2 in parse_packet /home/ubuntuadm/git/JtR/src/gpg2john.c:1531
    #4 0x844802 in gpg2john /home/ubuntuadm/git/JtR/src/gpg2john.c:360
    #5 0x7d5a3d in main /home/ubuntuadm/git/JtR/src/john.c:1933
    #6 0x7f35effb082f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #7 0x4061f8 in _start (/home/ubuntuadm/git/JtR/run/john+0x4061f8)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV ??:0 strlen

(after converting from hex to raw)

frank-dittrich commented 8 years ago

afl also found several hangs. When I test such an input running gpg2john from gdb and then killing gpg2john, this is the back trace:

Program received signal SIGTERM, Terminated.
0x00007ffff56cb9b0 in __read_nocancel () at ../sysdeps/unix/syscall-template.S:84
84  ../sysdeps/unix/syscall-template.S: Datei oder Verzeichnis nicht gefunden.
(gdb) bt
#0  0x00007ffff56cb9b0 in __read_nocancel () at ../sysdeps/unix/syscall-template.S:84
#1  0x00007ffff564dea9 in __GI__IO_file_xsgetn (fp=0x7ffff59988e0 <_IO_2_1_stdin_>, data=<optimized out>, n=8192) at fileops.c:1434
#2  0x00007ffff5643176 in __GI__IO_fread (buf=<optimized out>, size=size@entry=1, count=8192, fp=0x7ffff59988e0 <_IO_2_1_stdin_>) at iofread.c:38
#3  0x000000000083e9f0 in fread (__stream=<optimized out>, __n=<optimized out>, __size=1, __ptr=<optimized out>) at /usr/include/x86_64-linux-gnu/bits/stdio2.h:295
#4  read_binary (p=<optimized out>, max=<optimized out>) at gpg2john.c:2619
#5  0x000000000083f4a5 in inflate_bzip2 (p=<optimized out>, max=8192) at gpg2john.c:2802
#6  0x000000000083f973 in Getc1 () at gpg2john.c:2837
#7  0x0000000000844351 in parse_packet () at gpg2john.c:1473
#8  0x0000000000844803 in gpg2john (argc=2, argv=0x7fffffffde68) at gpg2john.c:360
#9  0x00000000007d5a3e in main (argc=2, argv=0x7fffffffde68) at john.c:1933
jfoug commented 8 years ago

This problem appears to mostly stem from using int vs an unsigned (like size_t) type value. Thus, if (len > sizeof(buf)) would not be triggered if len was < 0.

frank-dittrich commented 8 years ago

@jfoug looks like none of the crashes can be reproduced anymore. But the input files identified as "hangs" still cause gpg2john to somehow run really long, if not virtually forever.

When cracking fuzzed hashes, I would expect something like that if the fuzzer generates ridiculous iteration counts etc. But is it to be expected that gpg2john takes forever processing a single input file of just 3 bytes length? (The 3 bytes are <A0><E8>^C.)

jfoug commented 8 years ago

When I ran that file, I instantly got this error message:

$ ../run/gpg2john a

bzip2 BZ2_bzDecompress error (-5).

Then when run without bzip2, I get this (instantly again)

 $ ../run/gpg2john /c/JtR/bleed-64/src/a

unknown compress algorithm.
frank-dittrich commented 8 years ago

That's strange. I get the hangs on my ubuntu system which I've upgraded from 14.04 to 16.04. Will have to try other systems.

Here's the list of hangs I got with afl.

$ for f in ../afl-new/findings_dir-gpg2john/hangs/id*; do echo $f ; xxd < $f; done
../afl-new/findings_dir-gpg2john/hangs/id:000000,src:000003,op:havoc,rep:32
00000000: a0e8 03                                  ...
../afl-new/findings_dir-gpg2john/hangs/id:000001,src:000043,op:havoc,rep:8
00000000: a203 0b35 e703                           ...5..
../afl-new/findings_dir-gpg2john/hangs/id:000002,src:000061,op:havoc,rep:32
00000000: c81e 03                                  ...
../afl-new/findings_dir-gpg2john/hangs/id:000003,src:000109,op:arith8,pos:3,val:-7
00000000: a189 3a03                                ..:.
../afl-new/findings_dir-gpg2john/hangs/id:000004,src:000135,op:havoc,rep:2
00000000: 8000 a2a0 a2a2 e803                      ........
../afl-new/findings_dir-gpg2john/hangs/id:000005,src:000138,op:havoc,rep:64
00000000: a303                                     ..
../afl-new/findings_dir-gpg2john/hangs/id:000006,src:000143,op:int16,pos:1,val:+1000
00000000: c8e8 03                                  ...
../afl-new/findings_dir-gpg2john/hangs/id:000007,src:000192,op:havoc,rep:64
00000000: ffff ffff 0000 a064 03                   .......d.
../afl-new/findings_dir-gpg2john/hangs/id:000008,src:000201,op:flip1,pos:3
00000000: c8c8 0103                                ....
../afl-new/findings_dir-gpg2john/hangs/id:000009,src:001177,op:havoc,rep:4
00000000: fe00 2002 03                             .. ..
../afl-new/findings_dir-gpg2john/hangs/id:000010,src:002316,op:havoc,rep:32
00000000: e900 2303                                ..#.
../afl-new/findings_dir-gpg2john/hangs/id:000011,src:000537,op:int16,pos:202,val:+1000
00000000: ffaf bcb9 1313 1313 1e13 13dd b0a0 a0a0  ................
00000010: a0a0 97a0 cfa0 a0a0 a0ad a0a0 a07e a09f  .............~..
00000020: a087 a0a0 aea0 a2a0 3737 3737 3737 3737  ........77777777
00000030: 3737 3737 3737 3737 3737 3737 3737 a0a0  77777777777777..
00000040: 7ea0 9f9f 1313 1313 1313 1374 1313 1313  ~..........t....
00000050: 130b 0b0b 0b0b 0b0b 0b0b 0b0b 0b0b 0b0b  ................
00000060: 0b0b 0b0b 0b0b 1313 13ff ff13 1313 131e  ................
00000070: 1313 ddb0 a0a0 a0a0 a0b9 a097 a0a0 b9a0  ................
00000080: 9700 7aa0 a08a a0ad 9da0 b9a0 979d cfa0  ..z.............
00000090: a0a0 a0a0 88a0 ad9d a0b9 a097 a0cf a0a0  ................
000000a0: a0a0 ada0 aab7 7ea0 9fa0 a08e 8e8e 8e8e  ......~.........
000000b0: 8e8e 8e8e 8e8e 8e8e 8e8e 8e8e 8e8e 8e8e  ................
000000c0: 8e8e 8ea0 b6c1 a0ad a0a0 e803            ............
../afl-new/findings_dir-gpg2john/hangs/id:000012,src:000630,op:havoc,rep:2
00000000: c810 00c8 0003                           ......
../afl-new/findings_dir-gpg2john/hangs/id:000013,src:000666,op:int16,pos:18,val:+1000
00000000: d609 0906 06a0 f2e3 10a0 a0a0 0100 a000  ................
00000010: 00a0 e803                                ....
../afl-new/findings_dir-gpg2john/hangs/id:000014,src:000269,op:arith8,pos:21,val:+27
00000000: ca10 1010 100f f810 1910 1010 10df 9dca  ................
00000010: df9d a110 ff03                           ......
../afl-new/findings_dir-gpg2john/hangs/id:000015,src:000273,op:flip1,pos:8
00000000: c906 4000 0340 0003 2140 0003            ..@..@..!@..
../afl-new/findings_dir-gpg2john/hangs/id:000016,src:001408,op:havoc,rep:128
00000000: 8002 2110 2303                           ..!.#.
../afl-new/findings_dir-gpg2john/hangs/id:000017,src:001927,op:havoc,rep:16
00000000: 8800 23e9 0023 03                        ..#..#.
../afl-new/findings_dir-gpg2john/hangs/id:000018,src:000125,op:havoc,rep:4
00000000: a156 6603                                .Vf.
../afl-new/findings_dir-gpg2john/hangs/id:000019,src:000256,op:havoc,rep:8
00000000: f100 2303                                ..#.
../afl-new/findings_dir-gpg2john/hangs/id:000020,src:001746,op:flip2,pos:10
00000000: c903 2002 68c9 0320 0268 2203 8000 2403  .. .h.. .h"...$.

With xxd -r you should be able to convert each file to raw.

frank-dittrich commented 8 years ago

This is from testing the first file (id:000000*) and then killing john:

(gdb) bt
#0  0x00007ffff56cb9b0 in __read_nocancel () at ../sysdeps/unix/syscall-template.S:84
#1  0x00007ffff564dea9 in __GI__IO_file_xsgetn (fp=0x7ffff59988e0 <_IO_2_1_stdin_>, data=<optimized out>, n=8192) at fileops.c:1434
#2  0x00007ffff5643176 in __GI__IO_fread (buf=<optimized out>, size=size@entry=1, count=8192, fp=0x7ffff59988e0 <_IO_2_1_stdin_>) at iofread.c:38
#3  0x0000000000e5dc61 in fread (__stream=<optimized out>, __n=<optimized out>, __size=1, __ptr=<optimized out>) at /usr/include/x86_64-linux-gnu/bits/stdio2.h:295
#4  read_binary (p=<optimized out>, max=<optimized out>) at gpg2john.c:2670
#5  0x0000000000e5f68c in inflate_bzip2 (p=<optimized out>, max=8192) at gpg2john.c:2853
#6  0x0000000000e83850 in Getc1 () at gpg2john.c:2888
#7  parse_packet (hash=hash@entry=0x61600000ae80 '\276' <repeats 200 times>...) at gpg2john.c:1496
#8  0x0000000000e85499 in gpg2john (argc=argc@entry=2, argv=argv@entry=0x7fffffffde68) at gpg2john.c:367
#9  0x000000000041a358 in main (argc=2, argv=0x7fffffffde68) at john.c:1944
frank-dittrich commented 8 years ago

Same on my fedora 24 system:

(bleeding-jumbo)run $ echo "00000000: a0e8 03"|xxd -r > hang_gpg2john
(bleeding-jumbo)run $ ./gpg2john hang_gpg2john

... and gpg2john hangs

jfoug commented 8 years ago

Ok, I can get things to hang if the bz2 lib is installed (but not without it). Should be an easy 'fix'

jfoug commented 8 years ago

@frank-dittrich please retest after bd56033

The code got into an infinite loop on truncated data (bz2 compressed). bz.avail_in was 0. Size found was 0 and plugged into bz.avail_in and it would continue that way. Now, if there is no data left, we simply break out of the decompression returning failure.