Closed N3vv closed 5 years ago
And here is the debug result of executing lrzip
without the -asan
option(The version of LZO library is 2.10):
pwndbg> file ./lrzip
Reading symbols from ./lrzip...done.
pwndbg> set args -d -f ../id:000002,sig:06,src:000008,op:flip2,pos:35
pwndbg> r
Starting program: /home/nevv/Desktop/lrzip-master (copy)/lrzip -d -f ../id:000002,sig:06,src:000008,op:flip2,pos:35
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Output filename is: ../id:000002,sig:06,src:000008,op:flip2,pos:35
Warning, inadequate free space detected, but attempting to decompress due to -f option being used.
Decompressing...
[New Thread 0x7ffff6902700 (LWP 30631)]
Thread 2 "lrzip" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff6902700 (LWP 30631)]
0x00007ffff7bc8144 in lzo1x_decompress () from /lib/x86_64-linux-gnu/liblzo2.so.2
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
─────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]─────────────────────────────────────────────────────────────────────────────────────
RAX 0x1ef2ae4
RBX 0x7ffff000148a ◂— 0x0
RCX 0x7ffff6901ed0 ◂— 0x0
RDX 0x7ffff00008c0 ◂— 0xda5bd6f00000000
RDI 0x65c310 ◂— 0xbd6f000000000200
RSI 0x18
R8 0x0
R9 0x67c000
R10 0x65cee2 ◂— 0x0
R11 0x65ced9 ◂— 0x0
R12 0x0
R13 0x43b0a0 ◂— push -3
R14 0x0
R15 0x65c310 ◂— 0xbd6f000000000200
RBP 0x7ffff000148a ◂— 0x0
RSP 0x7ffff6901e80 —▸ 0x65c130 —▸ 0x7ffff00008c0 ◂— 0xda5bd6f00000000
RIP 0x7ffff7bc8144 (lzo1x_decompress+276) ◂— movzx r8d, byte ptr [r9]
──────────────────────────────────────────────────────────────────────────────────────[ DISASM ]───────────────────────────────────────────────────────────────────────────────────────
► 0x7ffff7bc8144 <lzo1x_decompress+276> movzx r8d, byte ptr [r9]
0x7ffff7bc8148 <lzo1x_decompress+280> add rax, 0xff
0x7ffff7bc814e <lzo1x_decompress+286> test r8b, r8b
0x7ffff7bc8151 <lzo1x_decompress+289> je lzo1x_decompress+272 <0x7ffff7bc8140>
↓
0x7ffff7bc8140 <lzo1x_decompress+272> add r9, 1
► 0x7ffff7bc8144 <lzo1x_decompress+276> movzx r8d, byte ptr [r9]
0x7ffff7bc8148 <lzo1x_decompress+280> add rax, 0xff
0x7ffff7bc814e <lzo1x_decompress+286> test r8b, r8b
0x7ffff7bc8151 <lzo1x_decompress+289> je lzo1x_decompress+272 <0x7ffff7bc8140>
↓
0x7ffff7bc8140 <lzo1x_decompress+272> add r9, 1
► 0x7ffff7bc8144 <lzo1x_decompress+276> movzx r8d, byte ptr [r9]
───────────────────────────────────────────────────────────────────────────────────────[ STACK ]───────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp 0x7ffff6901e80 —▸ 0x65c130 —▸ 0x7ffff00008c0 ◂— 0xda5bd6f00000000
01:0008│ 0x7ffff6901e88 —▸ 0x6449a0 (local_control) —▸ 0x7fffffffe166 ◂— '../id:000002,sig:06,src:000008,op:flip2,pos:35'
02:0010│ 0x7ffff6901e90 ◂— 0x0
03:0018│ 0x7ffff6901e98 —▸ 0x411bb2 (ucompthread+882) ◂— test eax, eax
04:0020│ 0x7ffff6901ea0 —▸ 0x7ffff6901ed0 ◂— 0x0
05:0028│ 0x7ffff6901ea8 ◂— 0x0
06:0030│ 0x7ffff6901eb0 —▸ 0x644a60 (local_control+192) ◂— 0x0
07:0038│ 0x7ffff6901eb8 —▸ 0x7ffff6901ec8 ◂— 0x0
─────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────────────────────────────────────────
► f 0 7ffff7bc8144 lzo1x_decompress+276
f 1 411bb2 ucompthread+882
f 2 411bb2 ucompthread+882
f 3 7ffff75756ba start_thread+202
Program received signal SIGSEGV (fault address 0x67c000)
pwndbg> vmmap
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
0x400000 0x444000 r-xp 44000 0
0x643000 0x644000 r--p 1000 43000
0x644000 0x645000 rw-p 1000 44000
0x645000 0x67c000 rw-p 37000 0 [heap]
This was assigned CVE-2019-10654.
Hello N3vv,
based on the output I get, I think it is the same issue. However it is still not fixed, so basically this is an incomplete fix for CVE-2017-8845
Hello N3vv,
this CVE-2019-10654 is a flaw in lrzip or lzo?
Wasn't this bug corrected? It's not an LZO bug. The POC file is corrupt. Did you manually edit the LRZ file in bytes 0x6-0xd? What was the original file you compressed? @N3vv will you provide that?
peter@tommyiv:~/Downloads$ lrzip -i POC Detected lrzip version 0.6 file. Rzip chunk 1: Chunk byte width: 1 Stream: 0 Block Comp Percent Size 1 lzo 240.0% 24 / 10 Stream: 1 Block Comp Percent Size 1 none 100.0% 2 / 2 Rzip compression: 0.0% 12 / 281474974679042 Back end compression: 216.7% 26 / 12 Overall compression: 0.0% 26 / 281474974679042 POC: l>rzip version: 0.6 file Compression: rzip + lzo Decompressed file size: 281474974679042 Compressed file size: 71 Compression ratio: 3964436263085.099 MD5 used for integrity testing MD5: 26ab0db90d72e28ad0ba1e22ee510510
peter@tommyiv:~/Downloads$ lrzip -t POC Using configuration file /home/peter/.lrzip/lrzip.conf The following options are in effect for this INTEGRITY TEST. Threading is ENABLED. Number of CPUs detected: 8 Detected 8341680128 bytes ram Nice Value: 19 Show Progress Verbose Test file integrity Temporary Directory set as: ./ Detected lrzip version 0.6 file. Inadequate free space to test file. Space needed: 281474974679042. Space available: >8194113536. Try setting
TMP=dirname
and select a larger volume. Fatal error - exiting
Hello N3vv,
this CVE-2019-10654 is a flaw in lrzip or lzo?
I think it's in lzo
Hello N3vv, this CVE-2019-10654 is a flaw in lrzip or lzo?
I think it's in lzo
Without the source file you used to compress, it's not possible to tell. lrzip thinks the file is 281474974679042 bytes large. lrzip never starts to decompress (in the latest version I use which applies the test size patches).
Wasn't this bug corrected? It's not an LZO bug. The POC file is corrupt. Did you manually edit the LRZ file in bytes 0x6-0xd? What was the original file you compressed? @N3vv will you provide that?
peter@tommyiv:~/Downloads$ lrzip -i POC Detected lrzip version 0.6 file. Rzip chunk 1: Chunk byte width: 1 Stream: 0 Block Comp Percent Size 1 lzo 240.0% 24 / 10 Stream: 1 Block Comp Percent Size 1 none 100.0% 2 / 2 Rzip compression: 0.0% 12 / 281474974679042 Back end compression: 216.7% 26 / 12 Overall compression: 0.0% 26 / 281474974679042 POC: l>rzip version: 0.6 file Compression: rzip + lzo Decompressed file size: 281474974679042 Compressed file size: 71 Compression ratio: 3964436263085.099 MD5 used for integrity testing MD5: 26ab0db90d72e28ad0ba1e22ee510510
peter@tommyiv:~/Downloads$ lrzip -t POC Using configuration file /home/peter/.lrzip/lrzip.conf The following options are in effect for this INTEGRITY TEST. Threading is ENABLED. Number of CPUs detected: 8 Detected 8341680128 bytes ram Nice Value: 19 Show Progress Verbose Test file integrity Temporary Directory set as: ./ Detected lrzip version 0.6 file. Inadequate free space to test file. Space needed: 281474974679042. Space available: >8194113536. Try setting
TMP=dirname
and select a larger volume. Fatal error - exiting
I found this issue by AFL. And I just tried and it seems that I uploaded the wrong POC file before.Unfortunately my virtual machine broke down and reinstalled, so the correct POC file was lost. This problem did exist and I'm trying to use the previous seed to reprodfuce this.
Well, you closed the issue, @N3vv . All I can see is the POC file is borked. Without further details and a source file (not lrzip file) to test, nothing more can be done. The source file that was compressed was 12 bytes long, yet lrzip thinks it is 281,474,974,679,042 bytes long. Try applying pull request #140 and try and reproduce the file you used to create the initial bug.
Block | Comp | Percent | Size |
---|---|---|---|
1 | lzo | 240.0% | 24 / 10 |
1 | none | 100.0% | 2 / 2 |
Well, you closed the issue, @N3vv . All I can see is the POC file is borked. Without further details and a source file (not lrzip file) to test, nothing more can be done. The source file that was compressed was 12 bytes long, yet lrzip thinks it is 281,474,974,679,042 bytes long. Try applying pull request #140 and try and reproduce the file you used to create the initial bug.
Block Comp Percent Size 1 lzo 240.0% 24 / 10 1 none 100.0% 2 / 2
I got a similar poc and I compress it with zip. You can reproduce this with argument lrzip -d -o 1234 -f poc.lrz
pwndbg> file lrzip
Reading symbols from lrzip...done.
pwndbg> set args -d -o 1234 -f poc.lrz
pwndbg> r
Starting program: /home/ne vv/Desktop/pwn1/lrzip-0.631/lrzip -d -o 1234 -f poc.lrz
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Output filename is: 1234
Decompressing...
[New Thread 0x7faf62cad700 (LWP 48431)]
Thread 2 "lrzip" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7faf62cad700 (LWP 48431)]
0x00007fb009b6f144 in lzo1x_decompress () from /lib/x86_64-linux-gnu/liblzo2.so.2
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
────────────────────────────────────────────────────────────[ REGISTERS ]────────────────────────────────────────────────────────────
RAX 0xdbee35
RBX 0x7faf5c001627 ◂— 0x0
RCX 0x7faf62caceb0 ◂— 0x0
RDX 0x7faf5c000b20 ◂— 0xdae1e80200000000
RDI 0x558384779820 ◂— 0xe802000000000700
RSI 0xa
R8 0x0
R9 0x558384788000
R10 0x55838477a333 ◂— 0x0
R11 0x55838477a331 ◂— 0x0
R12 0x0
R13 0x558382a64ba0 ◂— 0xfffd7490fffd73f0
R14 0x7faf62caceb0 ◂— 0x0
R15 0x558384779820 ◂— 0xe802000000000700
RBP 0x7faf5c001627 ◂— 0x0
RSP 0x7faf62cace60 —▸ 0x5583847795e0 —▸ 0x7faf5c000b20 ◂— 0xdae1e80200000000
RIP 0x7fb009b6f144 (lzo1x_decompress+276) ◂— movzx r8d, byte ptr [r9]
─────────────────────────────────────────────────────────────[ DISASM ]──────────────────────────────────────────────────────────────
► 0x7fb009b6f144 <lzo1x_decompress+276> movzx r8d, byte ptr [r9]
0x7fb009b6f148 <lzo1x_decompress+280> add rax, 0xff
0x7fb009b6f14e <lzo1x_decompress+286> test r8b, r8b
0x7fb009b6f151 <lzo1x_decompress+289> je lzo1x_decompress+272 <0x7fb009b6f140>
↓
0x7fb009b6f140 <lzo1x_decompress+272> add r9, 1
► 0x7fb009b6f144 <lzo1x_decompress+276> movzx r8d, byte ptr [r9]
0x7fb009b6f148 <lzo1x_decompress+280> add rax, 0xff
0x7fb009b6f14e <lzo1x_decompress+286> test r8b, r8b
0x7fb009b6f151 <lzo1x_decompress+289> je lzo1x_decompress+272 <0x7fb009b6f140>
↓
0x7fb009b6f140 <lzo1x_decompress+272> add r9, 1
► 0x7fb009b6f144 <lzo1x_decompress+276> movzx r8d, byte ptr [r9]
──────────────────────────────────────────────────────────────[ STACK ]──────────────────────────────────────────────────────────────
00:0000│ rsp 0x7faf62cace60 —▸ 0x5583847795e0 —▸ 0x7faf5c000b20 ◂— 0xdae1e80200000000
01:0008│ 0x7faf62cace68 —▸ 0x558382c6d5e0 (local_control) —▸ 0x7ffd43268173 ◂— 0x7a726c2e636f70 /* 'poc.lrz' */
02:0010│ 0x7faf62cace70 —▸ 0x7faf62caceb0 ◂— 0x0
03:0018│ 0x7faf62cace78 —▸ 0x558382a3c069 (ucompthread+905) ◂— test eax, eax
04:0020│ 0x7faf62cace80 ◂— 0x0
... ↓
06:0030│ 0x7faf62cace90 —▸ 0x558382c6d6a0 (local_control+192) ◂— 0x0
07:0038│ 0x7faf62cace98 —▸ 0x7faf62cacea8 ◂— 0x0
────────────────────────────────────────────────────────────[ BACKTRACE ]────────────────────────────────────────────────────────────
► f 0 7fb009b6f144 lzo1x_decompress+276
f 1 558382a3c069 ucompthread+905
f 2 558382a3c069 ucompthread+905
f 3 7fb0095176db start_thread+219
Program received signal SIGSEGV (fault address 0x558384788000)
pwndbg> Quit
pwndbg> bt
#0 0x00007fb009b6f144 in lzo1x_decompress () from /lib/x86_64-linux-gnu/liblzo2.so.2
#1 0x0000558382a3c069 in lzo_decompress_buf (ucthread=0x5583847795e0, control=0x558382c6d5e0 <local_control>) at stream.c:590
#2 ucompthread (data=0x0) at stream.c:1525
#3 0x00007fb0095176db in start_thread (arg=0x7faf62cad700) at pthread_create.c:463
#4 0x00007fb00890188f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
I see the segfault. But I still need to see the uncompressed file. It looks like it was only 7 bytes long. Without seeing the source file, it looks like the chunk is being read badly and maybe even passing a zero length chunk to the lzo decoder. My workaround would be to refuse to lrzip any file under 4K.
Seeing a chunk size of 0 is an issue. This should never happen. However, lrzip stands for LONG RANGE ZIP. This type of error for a 7 byte long file is not worth the effort to try and fix. Personally, I'm working with the SDK 19.00 of lzma (and a whole bunch of commits ahead of 0.631), not the current. Either reopen the issue and provide the uncompressed file, or not.
Reading chunk_bytes at 24 Expected size: 7 Chunk byte width: 1 Reading eof flag at 25 EOF: 1 Reading expected chunksize at 26 Chunk size: 0
peter@tommyiv:/share/docs/downloads$ lrzip -vi poc.lrz Using configuration file /home/peter/.lrzip/lrzip.conf Detected lrzip version 0.6 file. Rzip chunk 1: Chunk byte width: 1 (this means the chunk size is between 1 and 15 bytes long) Stream: 0 Offset: 27 Block Comp Percent Size 1 lzo 100.0% 10 / 10 Offset: 0 Head: 0 Stream: 1 Offset: 27 Block Comp Percent Size 1 none 100.0% 7 / 7 Offset: 0 Head: 0 Rzip compression: 242.9% 17 / 7 Back end compression: 100.0% 17 / 17 Overall compression: 242.9% 17 / 7 poc.lrz: lrzip version: 0.6 file Compression: rzip + lzo Decompressed file size: 7 Compressed file size: 76 (silly to compress small files) Compression ratio: 0.092 MD5 used for integrity testing MD5: d2fde576f44a6601b73201234b491904
I see the segfault. But I still need to see the uncompressed file. It looks like it was only 7 bytes long. Without seeing the source file, it looks like the chunk is being read badly and maybe even passing a zero length chunk to the lzo decoder. My workaround would be to refuse to lrzip any file under 4K.
Seeing a chunk size of 0 is an issue. This should never happen. However, lrzip stands for LONG RANGE ZIP. This type of error for a 7 byte long file is not worth the effort to try and fix. Personally, I'm working with the SDK 19.00 of lzma (and a whole bunch of commits ahead of 0.631), not the current. Either reopen the issue and provide the uncompressed file, or not.
Reading chunk_bytes at 24 Expected size: 7 Chunk byte width: 1 Reading eof flag at 25 EOF: 1 Reading expected chunksize at 26 Chunk size: 0
peter@tommyiv:/share/docs/downloads$ lrzip -vi poc.lrz Using configuration file /home/peter/.lrzip/lrzip.conf Detected lrzip version 0.6 file. Rzip chunk 1: Chunk byte width: 1 (this means the chunk size is between 1 and 15 bytes long) Stream: 0 Offset: 27 Block Comp Percent Size 1 lzo 100.0% 10 / 10 Offset: 0 Head: 0 Stream: 1 Offset: 27 Block Comp Percent Size 1 none 100.0% 7 / 7 Offset: 0 Head: 0 Rzip compression: 242.9% 17 / 7 Back end compression: 100.0% 17 / 17 Overall compression: 242.9% 17 / 7 poc.lrz: lrzip version: 0.6 file Compression: rzip + lzo Decompressed file size: 7 Compressed file size: 76 (silly to compress small files) Compression ratio: 0.092 MD5 used for integrity testing MD5: d2fde576f44a6601b73201234b491904
There is no uncompressed file here. This test case is obtained by mutating some bytes with a valid compressed file. Because I want to use the fuzz(which is mainly providing unexpected input and monitoring for abnormal results) to find flaws or vulnerabilities.
Use PR #140. Should fix the issue before it gets too lzo. Messing with the magic header will of course cause problems. Most will be caught as each chunk is decompressed. This is a self inflicted wound. Unless you sign an archive after creation or generate a hash on the compressed archive, you have to protect your own assets against intrusion. Not a bug and has been resolved.
On lrzip 0.631, there is an invalid memory read in lzo1x_decompress, which is different from CVE-2017-8845.
POC is here: POC.zip