Mac M1 Install Pwntools, Solve 'as' and bus error

解決 Mac M1 安裝 pwntools 找不到 as 的問題,與其他如 bus error 等等的問題。由於 M1 剛出沒多久,配適上可能還沒完成,或許在未來 pwntools 的版本會解決的這些問題,而目前這些方法可以使 pwntools 在 M1 上面運行。

備註

不建議採用 mac m1 作為 x86_64 binary exploit 的主要工具,若採用 docker 是使用 qemu-user,而 binary exploit 對特殊的記憶體地址數值很敏感,可能因為 mapping 的差異導致 leak 無法成功進行 (比方說: 0x40000000),沒辦法開箱即用,可能需要對 qemu 的原始碼進行修改,如果有人有更好的解決辦法可以聯繫我 (打開 issue 或 send an email)。

透過 qemu-system-x86_64 運行 ubuntu,效能與 x86_64 架構的 cpu 差了 10 倍左右的單核心性能 (Geekbench 5),並且在使用時明顯感覺開發工具緩慢,因此也不是最佳的解決方案。

目前建議直接透過 m1 ssh 到 x86_64 arch 的 server 進行利用開發。

(2021 年 8 月 23日 更新)

I buy an M1 MacBook, and I think it is not suitable for x86/x86-64 to exploit development for CTF challenge, that has two ways I have been tried to running on M1 mac, once is using qemu-user-mode, and also docker through qemu-user to running elf executable, but memory mapping is different from x86 Linux host system, that would make some address could not leaking, another like a Qiling framework I don’t try, but I think that is not out-of-the-box, the second way is to install and emulation x86_64 Linux system, using like qemu-system, but is too slowly than x86 host, you open vim is slowly, you save the exploit is slowly, run exploit is slowly.

if you want to use M1 to solve the x86/x86_64 challenge, I do not recommend, the current best way to save your productivity, using x86 host, and ssh to the host, that is my current solution, if someone has another solution you can open an issue with this or send an email to me. I would update my post to save other people time.

(2022 年 3 月 13日更新)

安裝 pwntools

brew install pwntools

MacBook m1 安装 pwntools path 參照這篇

Could not find ‘as’ installed

完成安裝後依然會遇到問題

[ERROR] Could not find 'as' installed for ContextType()
    Try installing binutils for this architecture:
    https://docs.pwntools.com/en/stable/install/binutils.html

預設 brew 的 binutils 沒有 as ,並且參照官網的單行指令 binuntils 一直安裝失敗,因此必須透過以下方法安裝

git clone https://github.com/Gallopsled/pwntools-binutils.git
cd pwntools-binutils/macos
./install_all.sh

重新開啟 python 並且檢查

>>> from pwn import *
>>> asm('pop eax')
b'X'

成功組譯

Unicorn Engine Bus Error

在執行 ELF(’./a.out’) 時會發生 bus error

python3 exploit.py                                                                                                                                                                      CTF-Solve/pwnable.tw/death_note master
[+] Opening connection to example.com on port 1337: Done
zsh: bus error  python3 exploit.py

我們可以透過 lldb 除錯 python 來定位 bug,並且輸入執行

from pwn import *
ELF('./a.out')

這時崩潰,透過 bt 可以發現問題出在 libunicorn.dylib

* frame #0: 0x0000000108bb7c00
    frame #1: 0x00000001063d194c libunicorn.dylib`cpu_x86_exec + 732
    frame #2: 0x00000001063d1550 libunicorn.dylib`resume_all_vcpus_x86_64 + 148
    frame #3: 0x00000001063d14b0 libunicorn.dylib`vm_start_x86_64 + 12
    frame #4: 0x00000001068b9c24 libunicorn.dylib`uc_emu_start + 492
    frame #5: 0x0000000196fe0050 libffi.dylib`ffi_call_SYSV + 80
    frame #6: 0x0000000196fe89d8 libffi.dylib`ffi_call_int + 944

透過 lldb 進行定位 image dump sections 發現 pwntools 本身帶有的 lib 有問題 (是否有可能在未來的版本解決?)

/opt/homebrew/Cellar/pwntools/4.3.1/libexec/lib/python3.9/site-packages/unicorn/lib/libunicorn.dylib

而 DYLD_LIBRARY_PATH 不可用 (可能受到 SIP 限制 ) 可以使用 install_name_tool 或 disable SIP 之類的,不過這裡打算用打補丁的方式,或許某天 unicorn 或 pwntools 會釋出解決方案等等。

透過 brew install --build-from-source unicorn 安裝的 unicorn 依然會有這樣的問題,就算確保路徑在 opt/homebrew/Cellar/unicorn/1.0.2_1 ,而解決方案是:

  1. 安裝 x86_64 版本的 unicorn ,方法參見網路上裝 x86_64 brew 的方法即可,這裡透過 ibrew 來稱呼 x86_64 版的 brew
  2. 建立軟連結取代 pwntools 的 unicorn

檢視安裝的路徑

ibrew info unicorn

之後可以得到我們自行安裝的 unicorn 位置

/usr/local/Cellar/unicorn/1.0.2_1/lib/python3.9/site-packages/unicorn/lib

執行腳本,透過軟連結覆蓋掉檔案

x86_unicorn_path=/usr/local/Cellar/unicorn/1.0.2_1/lib/python3.9/site-packages/unicorn/lib
pwntools_unicorn_path=/opt/homebrew/Cellar/pwntools/4.3.1/libexec/lib/python3.9/site-packages/unicorn/lib/
mkdir $pwntools_unicorn_path/back/
mv $pwntools_unicorn_path/* $pwntools_unicorn_path/back/
ln -s $x86_unicorn_path/* $pwntools_unicorn_path/

這個腳本保留了原始檔案以便還原,如果修改不回來,重新安裝 pwntools 應該也可以還原原始檔案。接下來執行 exploit.py 就可以正常執行 ELF()

參見


PWN macOS Apple Silicon