Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integer overflow in SWF::Reader::getWord and the repair plan in the last of the report #51

Open
jinyu00 opened this issue Jul 21, 2018 · 1 comment
Labels

Comments

@jinyu00
Copy link

jinyu00 commented Jul 21, 2018

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
@jinyu00 jinyu00 changed the title Integer overflow in SWF::Reader::getWord and the repair plan in the last of the reporter Integer overflow in SWF::Reader::getWord and the repair plan in the last of the report Jul 21, 2018
@djcsdy djcsdy added the bug label Jul 21, 2018
@djcsdy
Copy link
Owner

djcsdy commented Jul 21, 2018

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants