| Beschreibung | ## Description
[upx](https://github.com/upx/upx) has heap-buffer-overflow in /src/upx/vendor/ucl/src/n2b_d.c:75:31 in ucl_nrv2b_decompress_safe_le32
## version
```shell
commit 06b0de9c77551cd4e856d453e094d8a0b6ef0d6d
```
## harnss
From https://github.com/google/oss-fuzz/blob/master/projects/upx/fuzzers/decompress_packed_file_fuzzer.cpp
```c++
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include "../src/headers.h"
#include "../src/conf.h"
#include "../src/file.h"
#include "../src/packmast.h"
enum OpenMode { RO_MUST_EXIST, WO_MUST_EXIST_TRUNCATE, WO_MUST_CREATE, WO_CREATE_OR_TRUNCATE };
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
char infilename[256];
char outfilename[256];
snprintf(infilename, 256, "/tmp/libfuzzer.%d", getpid());
snprintf(outfilename, 256, "/tmp/libfuzzer.%d.decompressed", getpid());
FILE *fp = fopen(infilename, "wb");
if (!fp) {
return 0;
}
fwrite(data, size, 1, fp);
fclose(fp);
char argv_progname[4] = "upx";
char argv_decompression[3] = "-d";
char argv_output[3] = "-o";
char* argv_data[] = {argv_progname, argv_decompression, infilename, argv_output, outfilename};
try {
upx_main(5, argv_data);
} catch(...) {
}
unlink(infilename);
unlink(outfilename);
return 0;
}
```
## Proof of Concept
The poc can be obtained from Google Drive: https://drive.google.com/drive/folders/1qlUXvycOzGJygfkdQB9dGO6VwNRRZoih?usp=sharing
```shell
$ ./decompress_packed_file_fuzzer 8df2a286-e396-4abf-9576-1cb1ebb56b74
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 1524011844
INFO: Loaded 1 modules (39313 inline 8-bit counters): 39313 [0xd3a518, 0xd43ea9),
INFO: Loaded 1 PC tables (39313 PCs): 39313 [0xbbbb28,0xc55438),
./decompress_packed_file_fuzzer: Running 1 inputs 1 time(s) each.
Running: 8df2a286-e396-4abf-9576-1cb1ebb56b74
Ultimate Packer for eXecutables
Copyright (C) 1996 - 2024
UPX git-8f7578+ Markus Oberhumer, Laszlo Molnar & John Reiser Jan 24th 2024
File size Ratio Format Name
-------------------- ------ ----------- -----------
=================================================================
==1066948==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7ffff74ff39e at pc 0x0000008f6d8a bp 0x7fffffffbab0 sp 0x7fffffffbaa8
READ of size 4 at 0x7ffff74ff39e thread T0
#0 0x8f6d89 in ucl_nrv2b_decompress_safe_le32 /src/upx/vendor/ucl/src/n2b_d.c:75:31
#1 0x66cb2c in upx_ucl_decompress(unsigned char const*, unsigned int, unsigned char*, unsigned int*, int, upx_compress_result_t const*) /src/upx/src/compress/compress_ucl.cpp:165:13
#2 0x62c84a in upx_decompress(unsigned char const*, unsigned int, unsigned char*, unsigned int*, int, upx_compress_result_t const*) /src/upx/src/compress/compress.cpp:161:13
#3 0x851c69 in ph_decompress(PackHeader&, XSpan::PtrOrSpan<unsigned char const>, XSpan::PtrOrSpan<unsigned char>, bool, Filter*) /src/upx/src/packhead.cpp:335:13
#4 0x83dc24 in Packer::decompress(XSpan::PtrOrSpan<unsigned char const>, XSpan::PtrOrSpan<unsigned char>, bool, Filter*) /src/upx/src/packer.cpp:303:5
#5 0x7ebfd5 in PackUnix::unpack(OutputFile*) /src/upx/src/p_unix.cpp:680:13
#6 0x83ac1f in Packer::doUnpack(OutputFile*) /src/upx/src/packer.cpp:98:5
#7 0x8e71fd in do_one_file(char const*, char*) /src/upx/src/work.cpp:333:12
#8 0x8e8b88 in do_files(int, int, char**) /src/upx/src/work.cpp:421:13
#9 0x6c0dee in upx_main(int, char**) /src/upx/src/main.cpp:1303:9
#10 0x5886d3 in LLVMFuzzerTestOneInput /src/upx/fuzzers/decompress_packed_file_fuzzer.cpp:44:5
#11 0x459d13 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:611:15
#12 0x434ea2 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:337:6
#13 0x43ff81 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:1053:9
#14 0x4740b2 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
#15 0x7ffff7c43082 in __libc_start_main /build/glibc-wuryBv/glibc-2.31/csu/../csu/libc-start.c:308:16
#16 0x42b06d in _start (/home/zhangwei28/80result/upx/decompress_packed_file_fuzzer+0x42b06d)
0x7ffff74ff39e is located 2 bytes to the right of 322460-byte region [0x7ffff74b0800,0x7ffff74ff39c)
allocated by thread T0 here:
#0 0x54af86 in __interceptor_malloc /src/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:69:3
#1 0x8bc385 in MemBuffer::alloc(unsigned long long) /src/upx/src/util/membuffer.cpp:179:24
#2 0x7eb769 in PackUnix::unpack(OutputFile*) /src/upx/src/p_unix.cpp:639:10
#3 0x83ac1f in Packer::doUnpack(OutputFile*) /src/upx/src/packer.cpp:98:5
#4 0x8e71fd in do_one_file(char const*, char*) /src/upx/src/work.cpp:333:12
#5 0x8e8b88 in do_files(int, int, char**) /src/upx/src/work.cpp:421:13
#6 0x6c0dee in upx_main(int, char**) /src/upx/src/main.cpp:1303:9
#7 0x5886d3 in LLVMFuzzerTestOneInput /src/upx/fuzzers/decompress_packed_file_fuzzer.cpp:44:5
#8 0x459d13 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:611:15
#9 0x434ea2 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:337:6
#10 0x43ff81 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:1053:9
#11 0x4740b2 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
#12 0x7ffff7c43082 in __libc_start_main /build/glibc-wuryBv/glibc-2.31/csu/../csu/libc-start.c:308:16
SUMMARY: AddressSanitizer: heap-buffer-overflow /src/upx/vendor/ucl/src/n2b_d.c:75:31 in ucl_nrv2b_decompress_safe_le32
Shadow bytes around the buggy address:
0x10007ee97e20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10007ee97e30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10007ee97e40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10007ee97e50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10007ee97e60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x10007ee97e70: 00 00 00[04]fa fa fa fa fa fa fa fa fa fa fa fa
0x10007ee97e80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x10007ee97e90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x10007ee97ea0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x10007ee97eb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x10007ee97ec0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==1066948==ABORTING
``` |
|---|