Open
Description
When open a crafted swf
file , it could tigger Integer overflow
Let's see gdb output
Program received signal SIGSEGV, Segmentation fault.
0x000000000047aa6c in SWF::Reader::getWord (this=this@entry=0xd94970) at SWFReader.cpp:46
46 int r = data[pos++];
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
─────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]─────────────────────────────────────────
*RAX 0x82208
*RBX 0xd94990 —▸ 0x919c10 —▸ 0x8612e0 (SWF::Header::~Header()) ◂— lea rsp, [rsp - 0x98]
*RCX 0xb8dd12f2
*RDX 0xb8dd12f1
*RDI 0xd94970 —▸ 0x7ffff7f46010 ◂— 0x2b0000002c010088
*RSI 0xffffffffb8dd12f0
*R8 0x7ffff7f46010 ◂— 0x2b0000002c010088
*R9 0x3e
R10 0x0
*R11 0x246
*R12 0x82208
*R13 0xda9760 —▸ 0x91b2e0 —▸ 0x8731f0 (SWF::DoAction::~DoAction()) ◂— lea rsp, [rsp - 0x98]
*R14 0xd94970 —▸ 0x7ffff7f46010 ◂— 0x2b0000002c010088
*R15 0x7fffffffe300 ◂— 0x100000000000009 /* '\t' */
*RBP 0xd94970 —▸ 0x7ffff7f46010 ◂— 0x2b0000002c010088
*RSP 0x7fffffffe218 —▸ 0x48c791 ◂— movzx ebp, ax
*RIP 0x47aa6c (SWF::Reader::getWord()+140) ◂— movzx r9d, byte ptr [r8 + rsi]
──────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]───────────────────────────────────────────
► 0x47aa6c <SWF::Reader::getWord()+140> movzx r9d, byte ptr [r8 + rsi]
0x47aa71 <SWF::Reader::getWord()+145> mov dword ptr [rdi + 8], ecx
0x47aa74 <SWF::Reader::getWord()+148> movsxd rdi, edx
0x47aa77 <SWF::Reader::getWord()+151> movzx eax, byte ptr [r8 + rdi]
0x47aa7c <SWF::Reader::getWord()+156> shl eax, 8
0x47aa7f <SWF::Reader::getWord()+159> add eax, r9d
0x47aa82 <SWF::Reader::getWord()+162> ret
0x47aa83 <SWF::Reader::getWord()+163> nop dword ptr [rax + rax]
0x47aa88 <SWF::Reader::getWord()+168> add eax, 1
0x47aa8b <SWF::Reader::getWord()+171> mov dword ptr [rdi + 0x14], 2
0x47aa92 <SWF::Reader::getWord()+178> mov dword ptr [rdi + 8], eax
───────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]───────────────────────────────────────
41 if (pos+2 > length) {
42 err = Reader::eof;
43 pos = length+1;
44 return 0;
45 }
► 46 int r = data[pos++];
47 r += data[pos++]<<8;
48 return r;
49 }
50
51 uint32_t Reader::getInt() {
───────────────────────────────────────────────────────────────────────────────────────────[ STACK ]───────────────────────────────────────────
00:0000│ rsp 0x7fffffffe218 —▸ 0x48c791 ◂— movzx ebp, ax
01:0008│ 0x7fffffffe220 —▸ 0xd94990 —▸ 0x919c10 —▸ 0x8612e0 (SWF::Header::~Header()) ◂— lea rsp, [rsp - 0x98]
... ↓
03:0018│ 0x7fffffffe230 —▸ 0xd94970 —▸ 0x7ffff7f46010 ◂— 0x2b0000002c010088
04:0020│ 0x7fffffffe238 ◂— 0x82208
05:0028│ 0x7fffffffe240 —▸ 0xda9760 —▸ 0x91b2e0 —▸ 0x8731f0 (SWF::DoAction::~DoAction()) ◂— lea rsp, [rsp - 0x98]
06:0030│ 0x7fffffffe248 —▸ 0x7fffffffe300 ◂— 0x100000000000009 /* '\t' */
07:0038│ 0x7fffffffe250 —▸ 0xd94990 —▸ 0x919c10 —▸ 0x8612e0 (SWF::Header::~Header()) ◂— lea rsp, [rsp - 0x98]
─────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────
► f 0 47aa6c SWF::Reader::getWord()+140
f 1 48c791
f 2 56641e
f 3 487518
f 4 4a7337
f 5 7ffff6296830 __libc_start_main+240
Program received signal SIGSEGV (fault address 0x7fffb0d17300)
pwndbg> vmmap 0x7ffff7f46010
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
0x7ffff7f46000 0x7ffff7fd5000 rw-p 8f000 0
pwndbg> p dataa
No symbol "dataa" in current context.
pwndbg> p data
$1 = (const unsigned char *) 0x7ffff7f46010 "\210"
pwndbg> p pos
$2 = -1193471247
pwndbg> pwd
/home/haclh/vmdk/fuzz_workplace/swfmill-0.3.6/src
pwndbg> bt
#0 0x000000000047aa6c in SWF::Reader::getWord (this=this@entry=0xd94970) at SWFReader.cpp:46
#1 0x000000000048c791 in SWF::Tag::get (r=r@entry=0xd94970, end=end@entry=533000, ctx=ctx@entry=0x7fffffffe300) at SWFTag.cpp:8
#2 0x000000000056641e in SWF::Header::parse (this=this@entry=0xd94990, r=r@entry=0xd94970, end=533000, ctx=ctx@entry=0x7fffffffe300) at gSWFPa
#3 0x0000000000487518 in SWF::File::load (this=this@entry=0x7fffffffe2f0, fp=fp@entry=0xd91b30, _ctx=_ctx@entry=0x7fffffffe300, filesize=files
#4 0x00000000004a7337 in swfmill_swf2xml (argc=<optimized out>, argv=<optimized out>) at swfmill.cpp:135
#5 0x00007ffff6296830 in __libc_start_main (main=0x408890 <main(int, char**)>, argc=3, argv=0x7fffffffe4e8, init=<optimized out>, fini=<optimix7fffffffe4d8) at ../csu/libc-start.c:291
#6 0x0000000000409509 in _start ()
As you can see , The program crash in SWF::Reader::getWord
( SWFReader.cpp )
uint16_t Reader::getWord() {
if (pos+2 > length) {
err = Reader::eof;
pos = length+1;
return 0;
}
int r = data[pos++];
r += data[pos++]<<8; // crash at here !!!!
return r;
}
From the gdb debug infomation , the pos
is negative number
pwndbg> p pos
$2 = -1193471247
so when access data[pos] ( data + pos ), it could access invalid memory.
The vulnerability locate in SWFReader.cpp
and SWFReader.h
.
class Reader {
protected:
int pos, length;
};
The pos
and length
is signed int value.
And when read data from file , it could call Reader::getXXX
.
For example , Reader::getData
's code are as below:
bool Reader::getData(void *dst, size_t len) {
if (pos+len > length) {
err = Reader::eof;
pos = length+1;
return false;
} else {
memcpy(dst, &data[pos], len);
pos += len;
return true;
}
}
When read data from file , the pos
would add , although pos+len > length.
It can lead pos
to be negative number
The fix method is to change the type of pos
and length
to unsigned int
in SWFReader.h
protected:
// the uncompressed swf data and our position within
const unsigned char *data;
unsigned int pos, length;
The poc file
https://gitee.com/hac425/fuzz_data/blob/master/swf_seg_poc_12