# note the order of opcode and operands # This is the order of machine code(need to change) #------------------------------- #| operand2 | operand1 | opcode | #-------------------------------
# opcode operand1, operand2 # This is the order of assembly code(no need to change) imm = 0x02# imm r, byte: r = byte add = 0x40# add r1, r2: r1 = r1 + r2 push = 0x08# push 0, r: stack[sp] = r; sp++ pop = 0x08# pop r, 0: r = stack[--sp] stm = 0x04# stm r1, r2: mem[r1] = r2 ldm = 0x01# ldm r1, r2: r1 = mem[r2] cmp = 0x80# cmp r1, r2: flag = (r1 == r2) jmp = 0x20# jmp f, r: ip = addr if f == flag syscall = 0x10# sys call, r: syscall(call) -> r
# syscall: oprand2 call = { "open": 0x02, # open(mem[a], b) "read_code": 0x04, # read(a, code[3*b], c) "read_memory": 0x08, # read(a, mem[b], c) "write": 0x10, # write(a, mem[b], c) "sleep": 0x20, # sleep(a) "exit": 0x01# exit(a) }
deffind_exit(): for imm in values: for syscall in values: for sys_exit in values: for a in values: # print(f"{i*8*8 + j*8 + k}: imm={hex(i)}, syscall={hex(j)}, exit={hex(k)}, a={hex(r)}") payload = b"" # imm a, 63 payload += bytes([a, imm, 63]) # syscall exit, a payload += bytes([sys_exit, syscall, a]) p = process(bin) p.send(payload) p.wait(0.1) if (p.proc.returncode == 63): print(f"Found: imm={hex(imm)}, syscall={hex(syscall)}, sys_exit={hex(sys_exit)}, a={hex(a)}") return (imm, syscall, sys_exit, a) else: p.close() return (0, 0, 0, 0)
deffind_add(): for add in values: if (add == imm or add == syscall): continue for reg in values: if (reg == a): continue payload = b"" # imm a, 29 payload += bytes([a, imm, 29]) # imm r, 34 payload += bytes([reg, imm, 34]) # add a, r payload += bytes([a, add, reg]) # syscall exit, a payload += bytes([sys_exit, syscall, a]) p = process(bin) p.send(payload) p.wait(0.1) if (p.proc.returncode == 63): print(f"Found: add={hex(add)}, reg={hex(reg)}") return (add, reg) return (0, 0)
# to avoid stk mistaking the found of stm&ldm, find stk first deffind_stk(): for stk in values: if (stk == imm or stk == syscall or stk == add): continue payload = b"" # imm reg, 63 payload += bytes([reg, imm, 63]) # stk a, reg payload += bytes([a, stk, reg]) # syscall exit, a payload += bytes([sys_exit, syscall, a]) p = process(bin) p.send(payload) p.wait(0.1) # reg may be sp, so add 1 if (p.proc.returncode == 63or p.proc.returncode == 64): print(f"Found: stk={hex(stk)}") return stk return0
deffind_stm_ldm(): for stm in values: if (stm == imm or stm == syscall or stm == add or stm == stk): continue for ldm in values: if (ldm == imm or ldm == syscall or ldm == add or ldm == stk or ldm == stm): continue payload = b"" # imm reg, 63 payload += bytes([reg, imm, 63]) # stm reg, reg payload += bytes([reg, stm, reg]) # ldm a, reg payload += bytes([a, ldm, reg]) # syscall exit, a payload += bytes([sys_exit, syscall, a]) p = process(bin) p.send(payload) p.wait(0.1) if (p.proc.returncode == 63): print(f"Found: stm={hex(stm)}, ldm={hex(ldm)}") return (stm, ldm) return (0, 0)
deffind_write(): for sys_write in values: if (sys_write == sys_exit): continue for b in values: if (b == a): continue for c in values: if (c == a or c == b): continue payload = b"" # imm a, 1 payload += bytes([a, imm, 1]) # imm b, "W" payload += bytes([b, imm, ord("W")]) # stm b, b payload += bytes([b, stm, b]) # imm c, 1 payload += bytes([c, imm, 1]) # syscall write, a payload += bytes([sys_write, syscall, a]) # syscall exit, a payload += bytes([sys_exit, syscall, a]) p = process(bin) p.sendafter(b"Please input your yancode: ", payload) try: recv = p.recv(4096, timeout=1) except EOFError: p.kill() p.close() continue print(recv.decode()) if (b"W"in recv): print(f"Found: sys_write={hex(sys_write)}, b={hex(b)}, c={hex(c)}") return (sys_write, b, c) else: p.kill() p.close() return (0, 0, 0)
deffind_open_read(): for sys_open in values: if (sys_open == sys_exit or sys_open == sys_write): continue for sys_read in values: if (sys_read == sys_exit or sys_read == sys_write or sys_read == sys_open): continue payload = b"" # imm a, 0 payload += bytes([a, imm, 0]) # imm c, 1 payload += bytes([c, imm, 1]) # imm b, "/" payload += bytes([b, imm, ord("/")]) # stm a, b payload += bytes([a, stm, b]) # add a, c payload += bytes([a, add, c]) # imm b, "f" payload += bytes([b, imm, ord("f")]) # stm a, b payload += bytes([a, stm, b]) # add a, c payload += bytes([a, add, c]) # imm b, "l" payload += bytes([b, imm, ord("l")]) # stm a, b payload += bytes([a, stm, b]) # add a, c payload += bytes([a, add, c]) # imm b, "a" payload += bytes([b, imm, ord("a")]) # stm a, b payload += bytes([a, stm, b]) # add a, c payload += bytes([a, add, c]) # imm b, "g" payload += bytes([b, imm, ord("g")]) # stm a, b payload += bytes([a, stm, b]) # add a, c payload += bytes([a, add, c]) # imm b, 0 payload += bytes([b, imm, 0]) # stm a, b payload += bytes([a, stm, b]) # imm a, 0 payload += bytes([a, imm, 0]) # syscall open, a payload += bytes([sys_open, syscall, a]) # imm b, 0x10 payload += bytes([b, imm, 0x10]) # imm c, 64 payload += bytes([c, imm, 64]) # syscall read_memory, a payload += bytes([sys_read, syscall, a]) # imm a, 1 payload += bytes([a, imm, 1]) # imm b, 0x10 payload += bytes([b, imm, 0x10]) # imm c, 64 payload += bytes([c, imm, 64]) # syscall write, a payload += bytes([sys_write, syscall, a]) # syscall exit, a payload += bytes([sys_exit, syscall, a]) try: p = process(bin) p.sendafter(b"Please input your yancode: ", payload) try: recv = p.recvall(timeout=1) except EOFError: p.kill() p.close() continue if (b"pwn.college"in recv): print(f"Found: sys_open={hex(sys_open)}, sys_read={hex(sys_read)}") print(recv.decode()) return (sys_open, sys_read) else: p.kill() p.close() except: continue return (0, 0)
import hashlib for i inrange(5): for j inrange(5): print(f"0{i}C, 0{j}B") s = f"0{i}C0{j}B" print(hashlib.sha256(s.encode()).hexdigest())
level 4
将一个16字节的数和target Cows_Bulls拼接到一起hash,都hook出来即可。
import hashlib b = b"\x8d\xf1\x96\x84\x85\xe2\xac)S\xb4\x073\xcc\xb2\xde\x12" for i inrange(5): for j inrange(5): s = b"0%dC0%dB" % (i, j) print(s) print(hashlib.sha256(b+s).hexdigest())
# note the order of opcode and operands # This is the order of machine code(need to change) #------------------------------------------- #| opcode(8B) | operand1(8B) | operand2(8B) | #-------------------------------------------
# opcode operand1, operand2 # This is the order of assembly code(no need to change) imm = p64(0x04) # imm r, byte: r = byte add = p64(0x02) # add r1, r2: r1 = r1 + r2 push = p64(0x10) # push 0, r: stack[sp] = r; sp++ pop = p64(0x10) # pop r, 0: r = stack[--sp] stm = p64(0x20) # stm r1, r2: mem[r1] = r2 ldm = p64(0x40) # ldm r1, r2: r1 = mem[r2] cmp = p64(0x80) # cmp r1, r2: flag = (r1 == r2) jmp = p64(0x01) # jmp f, r: ip = addr if f == flag syscall = p64(0x08) # sys call, r: syscall(call) -> r