用Radare2模拟shellcode运行

news2024/11/20 18:30:09

当我们在编写汇编时,可能有的时候你需要看看编译器中到底发生了什么。如果你正在排除shellcode出现的问题,你那么更需要耐心地、慎重地运行指令。

本文将探讨如何在x86_64的Ubuntu系统上模拟32位ARM shellcode。由于大多数笔记本电脑和工作站还没有运行ARM,我们这里需要一种其他方法在系统上执行非原生的指令。另外,原始的shellcode二进制文件并不是可执行文件格式,并不能被大多数工具所运行,所以我们需要一种其他的方法来执行这些文件。

在这里我们使用的是Radare2, Radare2是一个控制台驱动的框架,集成了一套简便易用的二进制分析工具。你可以把这些工具编写成脚本,或者使用交互式的命令行界面。要在Ubuntu上设置这个,我们只需要几个简单的命令。

mkdir ~/github
cd ~/github
git clone https://github.com/radareorg/radare2.git
cd radare2
sys/install.sh

如果你已经安装了radare2,请确保你目前运行的是最新版本。这个工具一直在积极维护并定期进行更新。另外,在2022年6月的版本之前有一些错误,使得此次试验可能无法更好的完成。

cd ~/github/radare2
git pull
sys/install.sh
r2 -V

为了复制我们将在本文中使用的shellcode二进制文件,你可以在bash提示符下运行以下内容:

nemo@hammerhead:~$ echo -n -e '\x01\x30\x8f\xe2\x13\xff\x2f\xe1\x78\x46\x0c\x30\xc0\x46\x01\x90\x49\x1a\x92\x1a\x0b\x27\x01\xdf\x2f\x62\x69\x6e\x2f\x73\x68\x00' > shellcode-696.bin

nemo@hammerhead:~$ md5sum shellcode-696.bin 
42ba1c77446594cac3508b940926575d  shellcode-696.bin

ESIL简介

可评估字符串中间语言(ESIL)是radare2使用的一种从硬件中抽象出来的指令,可以在不考虑底层硬件的情况下,来 “执行” 机器指令。这对于在仿真环境中执行非本地的汇编指令是非常理想的。

为了使用ESIL来执行我们的shellcode,我们需要做以下工作:

  1. 加载我们的shellcode二进制文件
  2. 配置radare2,使其知道如何正确解释我们的shellcode二进制文件
  3. 初始化ESIL
  4. 根据需要设置寄存器
  5. 通过我们的汇编指令来验证其功能

帮助网安学习,全套资料S信免费领取:
① 网安学习成长路径思维导图
② 60+网安经典常用工具包
③ 100+SRC分析报告
④ 150+网安攻防实战技术电子书
⑤ 最权威CISSP 认证考试指南+题库
⑥ 超1800页CTF实战技巧手册
⑦ 最新网安大厂面试题合集(含答案)
⑧ APP客户端安全检测指南(安卓+IOS)

用 ESIL 执行ARM shellcode

  1. 加载我们的shellcode二进制文件

当我们对shellcode二进制文件运行 "file"命令时,我们看到Linux不能确定其文件格式。同样地,radare2也不能确定它是什么。

nemo@hammerhead:~/labs/shellcode/asm$ file shellcode-696.bin
shellcode-696.bin: data

由于它只是一个二进制的文件,我们需要把它加载到radare2中后指定我们要看的是什么。在这里,我们修改了一些软件的分析设置,以便我们能够正确地分析我们的ARM文件:

nemo@hammerhead:~/labs/shellcode/asm$ r2 shellcode-696.bin
[0x00000000]> e anal.arch = arm
[0x00000000]> e asm.arch = arm
[0x00000000]> e asm.bits = 32
[0x00000000]> e anal.armthumb=true
  1. 配置radare2,使其知道如何正确运行我们的shellcode二进制文件

接下来我们要指定哪些指令是ARM,哪些是THUMB。我发现要做到这一点,就需要定义指令类型改变的函数。在这个特定的shellcode中,它会在ARM和THUMB指令之间进行切换。

[0x00000000]> af
[0x00000000]> pdf
┌ 8: fcn.00000000 ();
│ rg: 0 (vars 0, args 0)
│ bp: 0 (vars 0, args 0)
│ sp: 0 (vars 0, args 0)
│           0x00000000      01308fe2       add r3, pc, 1
└           0x00000004      13ff2fe1       bx r3

在这个radare2命令的片段中,我正在分析一个地址为0的函数。在这里并不存在一个真正的函数,但是我们这样做是为了让我们的"函数"可以指定为ARM或者THUMB。"pdf "命令只是打印了函数的反汇编指令,这其中包含了add和bx指令。

<p>[0x00000000]> s 8
[0x00000008]> af
[0x00000008]> pdf
┌ 24: fcn.00000008 (int32_t arg1, int32_t arg2);
│           ; arg int32_t arg1 @ r0
│           ; arg int32_t arg2 @ r1
│           0x00000008      78460c30       andlo r4, ip, r8, ror r6
│           0x0000000c      c0460190       andls r4, r1, r0, asr 13    ; arg2
│       ┌─< 0x00000010      491a921a       bne 0xfe48693c
│       │   0x00000014      0b2701df       svcle 0x1270b
│       │   0x00000018      2f62696e       cdpvs p2, 6, c6, c9, c15, 1
└       │   0x0000001c      2f736800       rsbeq r7, r8, pc, lsr 6
[0x00000008]> afB 16</p>

从地址8开始的下一组指令是THUMB指令。"s 8 " 指令会在文件中寻找8个字节,并跳转到一个我们希望到达的地方,然后定义下一个 “函数”。用 "af "创建函数后,当我们试图用 "pdf "显示它时,它看起来有点古怪。这是因为工具仍然会将这些指令解释为ARM。

我们可以通过设置比特数为16来指定这个 "函数 " 是THUMB。也就是将asm.bits设置为16,不过只针对这个函数生效。在一个正常的ARM二进制文件中,radare2会尝试自动进行这种区分,但是由于我们只有这一串shellcode指令,我们仍然需要进行手动区分。

注意
我们可以删掉前两条指令并使用全THUMB的shellcode。如果我们这样做,我们就可以在打开文件时设置 “e asm.bits=16”,而不必再重新定义函数。只不过,如果需要的话,你可以区分这两种指令类型。

Radare2还有一个更方便的方法,就是用 "izz "命令显示二进制文件中的所有字符串。

> izz
[Strings]
nth paddr      vaddr      len size section type  string
―――――――――――――――――――――――――――――――――――――――――――――――――――――――
0   0x00000008 0x00000008 4   5            ascii xF\f0
1   0x00000018 0x00000018 7   8            ascii /bin/sh</p>

现在我们已经能够正确的加载我们的shellcode二进制文件了。

  1. 初始化ESIL

如前所述,radare2内置了很多命令,在命令前缀中加入"?" 可以列出所有相关的命令。"ae? " 命令将列出与ESIL和仿真相关的命令。

[0x00000000]> ae?
Usage: ae[idesr?] [arg]  ESIL code emulation
| ae [expr]                evaluate ESIL expression
| ae?                      show this help
| ae??                     show ESIL help
| aea[f] [count]           analyse n esil instructions accesses (regs, mem..)
| aeA[f] [count]           analyse n bytes for their esil accesses (regs, mem..)
| aeb ([addr])             emulate block in current or given address
| aeC[arg0 arg1..] @ addr  appcall in esil
| aec[?]                   continue until ^C
| aef [addr]               emulate function
| aefa [addr]              emulate function to find out args in given or current offset
| aeg [expr]               esil data flow graph
| aegf [expr] [register]   esil data flow graph filter
| aei[?]                   initialize ESIL VM state (aei- to deinitialize)
| aek[?] [query]           perform sdb query on ESIL.info
| aeL                      list ESIL plugins
| aep[?] [addr]            manage esil pin hooks (see “e cmd.esil.pin”)
| aepc [addr]              change esil PC to this address
| aer[?] [..]              handle ESIL registers like “ar” or “dr” does
| aes[?]                   perform emulated debugger step
| aets[?]                  esil Trace session
| aev [esil]        visual esil debugger for the given expression or current instruction
| aex [hex]                evaluate opcode expression

在这里,我们首先需要用 "aei "命令来初始化ESIL。之后,我们需要初始化一个堆栈。Radare2会自动选择一个堆栈的位置,不过这也可以使用"aeim "命令参数来指定地址 。

[0x00000008]> aei
[0x00000008]> aeim
  1. 根据需要设置寄存器

由于我们的shellcode指令是从0开始的,我们需要用 "aepc 0 "命令将我们的程序计数器(PC)设置为0。如果我们想在偏移量0以外的位置开始执行,我们可以用 "aepc

"来设置起始地址。

[0x00000008]> aepc 0

我们的shellcode中的一条指令(“subs r1, r1, r1”)会将r1设置为0.由于这个寄存器默认已经为0,让我们将它设置为0xffff,这样我们就可以看到当我们在shellcode中步进时所发生的变化。要做到这一点,我们需要使用 "aer "命令。

[0x00000008]> aer r1 = 0xffff
  1. 通过我们的设置来验证其功能

好了,现在我们已经设置好了。我们可以切换到可视化模式,进入到调试器面板。在可视模式下有多个选项(面板),所以我们需要敲两次 "p “来进入正确的面板。如果你想在任何时候退出可视化模式,只需按下escape键。你也可以按”?"来查看可用的命令列表。

[0x00000008]> V
(hit “p” twice to get to the debugger panel)

然后你会注意到靠近顶部有一组寄存器。它看起来会像这样:

通常在控制台输入的任何r2命令也可以在视觉模式下输入。例如,如果我们想打印偏移量为0x18的字符串,我们需要执行以下命令:

# Hit “:” while in visual mode.

> ps @0x18
/bin/sh
> # Hit enter on a blank line to return to visual mode.

现在,我们可以通过使用"s "键来执行汇编指令。当你在浏览时,你会注意到顶部的寄存器与堆栈数据会一起被更新(在第一张图片中从0x00178000开始)。你还会注意到,下一条要执行的指令(又称PC)的地址在汇编指令中被突出显示(第一幅图中的0x00000010)。

注意,上面的图片显示r1寄存器持有0x0000ffff。还注意到下一条指令将会被执行,即 “subs r1, r1, r1”。这条指令将会从自身减去r1,并将其存回r1,本质上是使其变为0。

再次按 "s "键,进入下一条指令。

现在一切都准备好了,可以通过 "svc 1 "指令通过守护进程调用了。我们现在正在进行 "execve "调用,所以我们应该在r7寄存器中设置0xb。r0中的第一个参数应该是一个指向我们要执行的二进制文件路径的指针。我们可以发现r0持有0x18。我们可以通过运行以下命令来验证它的指向:

# Hit “:” while at the “svc 1” instruction in visual mode.

> ps @r0
/bin/sh
>

现在我们没有向"/bin/sh "传递任何参数,也没有设置任何环境变量,因此我们可以发现r1和r2都被设置为0。

由于我们不是在ARM系统上运行,所以我们不能正确地使用守护进程调用(“svc 1”)指令。当你在测试更复杂的shellcode时,请牢记这一点。

总结

无论您是对自定义的shellcode进行故障排除,还是验证您所看到的静态内容,有时您只需要看看指令到底在做什么。Radare2允许您从一个未知的文件格式(如shellcode二进制文件或固件镜像)加载非本地汇编文件,并一步一步地执行指令。

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

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

相关文章

单篇笔记涨粉8w,10秒视频播放超1000w,小红书最近在流行什么?

四月&#xff0c;小红书平台又涌现出哪些优质博主&#xff1f;品牌在投放种草方面有何亮眼表现&#xff1f; 为洞察小红书平台的内容创作趋势及品牌营销策略&#xff0c;新红推出4月月度榜单&#xff0c;从创作者及品牌两方面入手&#xff0c;解析月榜数据&#xff0c;为从业者…

iOS总结_UI层自我复习总结

UI层复习笔记 在main文件中&#xff0c;UIApplicationMain函数一共做了三件事 根据第三个参数创建了一个应用程序对象 默认写nil&#xff0c;即创建的是UIApplication类型的对象&#xff0c;此对象看成是整个应用程序的一个抽象&#xff0c;负责存储应用程序的状态。根据第四…

SpringBoot访问静态资源

SpringBoot项目中没有WebApp目录&#xff0c;只有src目录。在src/main/resources下面有static和templates两个文件夹。SpringBoot默认在static目录中存放静态资源&#xff0c;而templates中放动态页面。 static目录 SpringBoot通过/resources/static目录访问静态资源&#xff…

怎么衡量纸白银走势图的强弱?

目前国内银行提供的纸白银交易基本实现了全天候连续的交易时间&#xff0c;但由于银行所提供的交易终端的技术分析功能有限&#xff0c;投资者在分析行情时绑手绑脚&#xff0c;因此小编建议大家可以尝试使用国际上主流的MT4的平台&#xff0c;作为观察国际银价走势的参考和技术…

在 Python 中获取昨天的日期

文章目录 在 Python 中获取昨天的日期Python 中的Date模块 在 Python 中获取昨天日期的示例 我们将通过多个示例介绍如何使用 Python 获取昨天的日期。 在 Python 中获取昨天的日期 Python 是一种高级语言&#xff0c;可用于数据科学和机器学习&#xff0c;以使用 Python 的数…

unity进阶学习笔记:消息框架

1 使用消息框架的目的 对于小型游戏&#xff0c;可能不需要任何框架&#xff0c;而是让各个游戏脚本直接相互通信。如要实现玩家受到攻击血量减少&#xff0c;通过玩家控制类向血条脚本发送消息减少血量。但是这样直接通信会导致各脚本通信关系记为复杂&#xff0c;并且每一个…

测试5年从中兴 15K 跳槽去腾讯 32K+16,啃完这份笔记你也可以

粉丝小王转行做测试已经是第5个年头&#xff0c;一直是一个不温不火的小职员&#xff0c;本本分分做着自己的事情&#xff0c;觉得自己的工作已经遇到了瓶颈&#xff0c;一个偶然的机会&#xff0c;获得了一份软件测试全栈知识点学习笔记&#xff0c;通过几个月的学习&#xff…

基于AT89C51单片机的计算器设计与仿真

点击链接获取Keil源码与Project Backups仿真图: https://download.csdn.net/download/qq_64505944/87759134?spm=1001.2014.3001.5503 源码获取 主要内容: 本次设计所提出的一种基于单片机技术的简易计算器的方案,能更好的解决计算机计算的问题,随着数字生活的到来,单片…

什么是皮安计?皮安表测试测量软件分享NS-SourceMeter

什么是皮安计 测量低直流电流&#xff0c;其需求常常远远超出数字万用表的功能。一般来说&#xff0c;数字万用表缺少测量低于100nA的电流所需的灵敏度。即使在较高的电流水平上&#xff0c;一个DMM的输入电压降&#xff08;电压负担&#xff09;高达几百毫伏&#xff0c;也不…

记录线上排查内存泄露问题

背景 记录一次云上排查内存泄露的问题&#xff0c;最近监控告警云上有空指针异常报出&#xff0c;于是找到运维查日志定位到具体是哪一行代码抛出的空指针异常&#xff0c; 问题分析 发现是在解析cookie的一个方法内&#xff0c;调用HttpServletRequest.getServerName()获取…

嵌入式软考备考_5 安全性基础知识

安全性基础知识 网安问题概述 被动攻击&#xff1a;监听&#xff08;截获&#xff09;。 主动攻击&#xff1a;主动破坏&#xff08;中断篡改&#xff0c;病毒&#xff0c;ddos使得某个服务拒绝服务&#xff0c;重放攻击&#xff1a;黑客截取了正常用户输入用户名密码的加密…

Spark SQL

一、理解介绍 Spark SQL是spark中用于结构化数据处理的组件&#xff0c;可访问多种数据源&#xff0c;如连接Hive、MySQL&#xff0c;实现读写等操作。为什么要用spark去操作这些数据库呢&#xff1f;hive是一个基于Hadoop的数据仓库工具&#xff0c;hive的查询操作语句都要依…

走进两邻文化,全民禁种铲毒——禁毒公益大集活动

四月梧桐芳菲尽&#xff0c;五月槐花飘香来。五月的春风赋予了劳动者应有的权利和由衷的自豪感&#xff1b;五月的春雨浇灌了我们肩负禁毒工作的义务和责任的使命感。现在也是今年禁种铲毒工作的深入执行阶段&#xff0c;禁毒工作一直以来都是维护社会稳定的重要工作之一&#…

C语言函数大全-- s 开头的函数(4)

C语言函数大全 本篇介绍C语言函数大全-- s 开头的函数&#xff08;4&#xff09; 1. strdup 1.1 函数说明 函数声明函数功能char * strdup(const char *s);用于将一个以 NULL 结尾的字符串复制到新分配的内存空间中 注意&#xff1a; strdup() 函数返回指向新分配的内存空间…

EasyMedia播放rtsp视频流(vue2、vue3皆可用)

之前发布过WebRtc播放rtsp视频流的博客&#xff0c;已经解决了web播放rtsp的问题&#xff0c;但WebRtc太耗内存&#xff0c;且需要命令行启动&#xff0c;对用户不太友好&#xff0c;虽然可以写脚本&#xff0c;让用户一键启动。这是无意间发现的另一种web播放rtsp视频流的办法…

相当Python程序员,选择培训班还是自学?我结合自己的经历谈谈看法

前几天我写了一篇文章&#xff0c;分享了自己当上程序员的经历。然后&#xff0c;我收到了很多小伙伴的提问&#xff0c;都在问同一个问题&#xff0c;即如何选择报培训班还是自学。今天&#xff0c;我结合自己的个人经历&#xff0c;来谈一下个人的看法。 我认为这个问题的第…

C/C++内存管理以及new/delete的底层实现。

一、C/C 内存分布 我们平常写代码所用的内存叫虚拟内存&#xff0c;是操作系统分配给每个进程的4G的内存&#xff0c;其中3G叫用户空间&#xff0c;1G叫内核空间。 我们所用的也就是3G的用户空间&#xff0c;如下图&#xff1a; 说明&#xff1a; 1. 代码段—可执行的代码/只…

【Linux】Linux学习之常用命令一

介绍 这里是小编成长之路的历程&#xff0c;也是小编的学习之路。希望和各位大佬们一起成长&#xff01; 以下为小编最喜欢的两句话&#xff1a; 要有最朴素的生活和最遥远的梦想&#xff0c;即使明天天寒地冻&#xff0c;山高水远&#xff0c;路远马亡。 一个人为什么要努力&a…

【嵌入式笔/面试】嵌入式软件基础题和真题总结——单片机与Linux

在学习的时候找到几个十分好的工程和个人博客&#xff0c;先码一下&#xff0c;内容都摘自其中&#xff0c;有些重难点做了补充&#xff01; 才鲸 / 嵌入式软件笔试题汇总 嵌入式与Linux那些事 阿秀的学习笔记 小林coding 百问网linux 嵌入式软件面试合集 2022年春招实习十四面…

在离职1年后,我后悔了,决定再战阿里,涨薪50%,成为卷王

2021年初&#xff0c;我通过一整天的笔试及面试加入一家&#xff08;某一线城市国资委全资控股&#xff09;某集团的研究机构&#xff08;中央研究院&#xff09;&#xff0c;任职中级软件测试工程师&#xff1b;在这边工作了整整一年&#xff0c;目前已经跳槽到一家互联网公司…