当前位置:网站首页>Apple Silicon配置二进制环境(二)
Apple Silicon配置二进制环境(二)
2022-08-03 09:23:00 【ZERO-A-ONE】
- Author:ZERO-A-ONE
- Date:2022-07-31
本系列旨在记录我本人在使用基于M1 Pro的Apple Silicon芯片MacBook Pro笔记本搭建适用于二进制研究的环境,包括逆向、PWN之类的场景
0x1 前序补充
之前有朋友反映Wine配IDA Pro还是有些麻烦,之后发现可以使用最新的PD虚拟机跑Windows11 ARM,就可以直接跑IDA Pro 7.5或者IDA Pro 7.6
提供一个我自己明确能跑起来的IDA Pro 7.5 版本
https://pan.quark.cn/s/775be0173189
如果遇到Python插件无法启动的情况,可以考虑使用官方提供的ARM架构同版本的Python去替换原来的Python包
0x2 PWN全家桶
对于一个PWN手或者二进制研究员而言,以下的工具是必不可少的:
- pwntools —— CTF framework and exploit development library
- pwndbg —— a GDB plug-in that makes debugging with GDB suck less, with a focus on features needed by low-level software developers, hardware hackers, reverse-engineers and exploit developers
- pwngdb —— gdb for pwn
- ROPgadget —— facilitate ROP exploitation tool
- roputils —— A Return-oriented Programming toolkit
- one_gadget —— A searching one-gadget of execve(‘/bin/sh’, NULL, NULL) tool for amd64 and i386
- angr —— A platform-agnostic binary analysis framework
- radare2 —— A rewrite from scratch of radare in order to provide a set of libraries and tools to work with binary files
- seccomp-tools —— Provide powerful tools for seccomp analysis
- linux_server[64] —— IDA 7.0 debug server for linux
- tmux —— a terminal multiplexer
- ltrace —— trace library function call
- strace —— trace system call
然而以上这些工具往往运行在X86架构上才能比较稳妥,如果Apple Silicon需要曲线救国的话,我目前的解决方案是一台VPS + Docker + Termius。这一套下来其实和在本地虚拟机上对二进制文件进行调试没有什么太大的区别
2.1 PWN Docker
VPS的购买应该就不用再啰嗦了,直接到如何部署PWN Docker就好了。这里使用到的Docker是一个基于修改后的ubuntu 20.04镜像。它里面已经包含了大量的常用工具
https://github.com/skysider/pwndocker
2.1.1 安装Docker
下载安装脚本:
curl -fsSL https://get.docker.com -o get-docker.sh
使用阿里云镜像下载安装:
sh get-docker.sh --mirror Aliyun
执行脚本后会自动识别arm架构,下载安装对应版本docker,稍等片刻即可
将当前用户加入docker组:
sudo usermod -aG docker $USER
退出当前终端并重新登录,此时操作docker不再需要加sudo权限
安装python和pip:
sudo apt-get install -y python python-pip
安装libffi-dev,否则在安装docker-compose的时候会报错:
sudo apt-get install -y libffi-dev
安装docker-compose
sudo apt install docker-compose
下载安装Docker图形化界面portainer
#下载 Docker 图形化界面 portainer
sudo docker pull portainer/portainer
#创建 portainer 容器
sudo docker volume create portainer_data
#运行 portainer
sudo docker run -d -p 9000:9000 --name portainer --restart always -v /
2.1.2 安装PWN-Docker
首先使用git命令拖下来
git clone https://github.com/skysider/pwndocker.git
然后进入pwn-docker文件
docker-compose up -d
之后都是执行以下命令进入pwn docker
docker exec -it pwn_test /bin/bash
2.1.3 TMUX启动鼠标控制
这里强烈推荐看起TMUX的鼠标控制功能,这样在PWNTOOLS使用TMUX分屏调试的时候十分方便
临时启动
老版本的Tmux开启鼠标模式的方法:
先按Ctrl + B, 松开以后,输入冒号,输入set mouse-mode on
回车。
新版本取消了这条命令。
在新版本中,开启鼠标模式的方法为:
先按Ctrl + B, 松开以后,输入冒号,输入set -g mouse on
回车。
永久启动
查看tmux当前版本:
tmux -V
编辑tmux配置文件 :
vim ~/.tmux.conf
tmux2.1之后版本:
set -g mouse on
tmux2.1之前版本:
setw -g mouse-resize-pane on
setw -g mouse-select-pane on
setw -g mouse-select-window on
setw -g mode-mouse on
2.2 Tips for pwn docker
2.2.1 使用不同的libc运行
这里因为我们需要调试,而pwn docker里面虽然内置了一些libc,但是没有保存.debug文件,我们需要自行手动下载完整版的glibc-all-in-one
git clone https://github.com/matrix1001/glibc-all-in-one
然后我们需要更新libc的目录,然后查看可下载的glibc
./update_list #更新最新版本的glibc
cat list #查看可下载的glibc
我们现在根目录创建一个tmp目录
mkdir ~/tmp
然后我们将我们想要的libc复制到tmp目录,这里以64位的2.23为例子
cp /glibc/2.27/64/lib/ld-2.23.so ~/tmp/ld-2.23.so
cp /glibc/2.23/64/lib/libc-2.23.so ~/tmp
然后把我们的运行程序也放入tmp目录,并使用patchelf,首先替换libc
patchelf --replace-needed libc.so.6 ./libc-2.23.so ./test
然后设置ld文件
patchelf --set-interpreter ./ld-2.23.so ./test
查看patch之后的程序
[email protected]:~/tmp# ldd ./test
linux-vdso.so.1 (0x00007ffc031e0000)
./libc-2.23.so (0x00007f401411e000)
./ld-2.23.so => /lib64/ld-linux-x86-64.so.2 (0x00007f40144f1000)
尝试执行以下发现可以正常执行
[email protected]:~/tmp# ./test
This file doesn't demonstrate an attack, but shows the nature of glibc's allocator.
glibc uses a first-fit algorithm to select a free chunk.
If a chunk is free and large enough, malloc will select this chunk.
This can be exploited in a use-after-free situation.
Allocating 2 buffers. They can be large, don't have to be fastbin. 1st malloc(0x512): 0x556d1ef1f010 2nd malloc(0x256): 0x556d1ef1f530 we could continue mallocing here... now let's put a string at a that we can read later "this is A!"
first allocation 0x556d1ef1f010 points to this is A!
Freeing the first one...
We don't need to free anything again. As long as we allocate smaller than 0x512, it will end up at 0x556d1ef1f010 So, let's allocate 0x500 bytes
3rd malloc(0x500): 0x556d1ef1f010
And put a different string here, "this is C!"
3rd allocation 0x556d1ef1f010 points to this is C!
first allocation 0x556d1ef1f010 points to this is C!
If we reuse the first allocation, it now holds the data from the third allocation.
但是如果我们直接使用GDB进行调试会出现问题,因为我们没有提供符号表,我推荐直接将.debug移动到题目的同级目录下
mkdir .debug
cd .debug
cp /ctf/work/2.23-0ubuntu11.3_amd64/.debug/* ./
然后我们就可以开始使用gdb正常执行bins和heap等指令
2.2.2 用GDB查看内存
这里可以介绍一下用gdb查看内存
格式: x /nfu <addr>
- x:是 examine 的缩写
- n:表示要显示的内存单元的个数
- f:表示显示方式, 可取如下值
- x:按十六进制格式显示变量
- d:按十进制格式显示变量
- u:按十进制格式显示无符号整型
- o:按八进制格式显示变量
- t:按二进制格式显示变量
- a:按十六进制格式显示变量
- i:指令地址格式
- c:按字符格式显示变量
- f:按浮点数格式显示变量
- u:表示一个地址单元的长度,可按如下取值
- b:表示单字节
- h:表示双字节
- w:表示四字节,32位应用常用
- g:表示八字节,64位应用常用
2.3 一些好用的脚本
2.3.1 Docker
我推荐大家可以使用一些脚本,来方便使用Docker,不用总是去记忆和查看Docker的指令。我编写了以下脚本:
rundocker.py:启动PWN Docker
import os
cmd = "docker exec -it pwn_test /bin/bash"
os.system(cmd)
todocker.py:将HOST文件送入Docker内
import sys
import os
container_id = "3e018bcbbf46e1b770d245bf55a61e6474085abfd56d0afe2951805f7753ccc4"
pwndocker_dir = "/ctf/work"
path_dir = ""
if __name__ == '__main__':
print(sys.argv[1])
path_dir = sys.argv[1]
cmd = "docker cp " + path_dir + " " + container_id + ":" + pwndocker_dir
print(cmd)
os.system(cmd)
fromdocker.py:将Docker文件送入HOST内
import sys
import os
container_id = "3e018bcbbf46e1b770d245bf55a61e6474085abfd56d0afe2951805f7753ccc4"
pwndocker_dir = "/ctf/work"
path_dir = "./"
if __name__ == '__main__':
print(sys.argv[1])
pwndocker_dir = sys.argv[1]
cmd = "docker cp " + container_id + ":" + pwndocker_dir + " " + path_dir
print(cmd)
os.system(cmd)
2.3.2 pwntools
自定义LIBC后的GDB调试
建议使用pwntools来间接启动GDB调试,可以使用以下脚本:
from pwn import *
context.terminal = ['tmux', 'splitw', '-h']
p = process(["./test"], env={
"LD_PRELOAD":"./libc.so.6"})
gdb.attach(p, "b main")
p.interactive()
在执行这个脚本前,需要启动tmux
边栏推荐
猜你喜欢
mysql 事务原理详解
【LeetCode】226.翻转二叉树
Industry SaaS Microservice Stability Guarantee Actual Combat
分区分表(一)
深度学习之 10 卷积神经网络1
AUC的两种计算方式
命令行加载特效 【cli-spinner.js】 实用教程
Machine learning (formula derivation and code implementation)--sklearn machine learning library
Network LSTM both short-term and long-term memory
pytorch one-hot 小技巧
随机推荐
LINGO 18.0软件安装包下载及安装教程
selenium IDE的3种下载安装方式
ClickHouse删除数据之delete问题详解
ClickHouse查询语句详解
What are pseudo-classes and pseudo-elements?The difference between pseudo-classes and pseudo-elements
分区分表(一)
dflow入门1——HelloWorld!
【LeetCode】112.路径总和
Industry SaaS Microservice Stability Guarantee Actual Combat
验证浮点数输入
mysql数据库配置性能调优
系统io统计
Flink Yarn Per Job - 提交应用
MySQL 中 is null 和 =null 的区别
QImage的指针问题
Oracle数据库表空间整理回收与释放操作
MySQL 主从切换步骤
What exactly does a firmware engineer do?
好用的插件
mysql 事务原理详解