Thêm debug symbol vào stripped libc
Thêm debug symbol vào stripped libc
Vào một ngày khi làm một bài pwn, với đề bài đưa libc trước, mình xài pwninit tool …
pwninit bị lỗi nào đó không thể lấy file dbg trong package package libc6-dbg_....deb
để unstrip libc.
Khi gặp nhiều bài ctf cần debug các hàm trong libc, đặc biệt là liên quan tới heap, việc không có debug symbol sẽ gây khó khăn hơn trong việc debug.
Sau đây, mình xin trình bày 2 cách để “chữa cháy” lỗi này.
Cách 1: Load debug symbol vào gdb
Bạn để ý thì pwninit nó cũng tải package libc6-dbg_….deb rồi giải nén ra, mình cũng thử tải package xem sao.
Ta để ý bây giờ file tên là data.tar.xz
thay vì data.tar
nên pwninit mới báo lỗi failed to find file in data.tar
.
Mình thử giải nén file data.tar.xz
ra.
Giải nén ta được thư mục usr
1 | tree usr -all ─╯ |
Ta thấy giờ người ta đã chia nhỏ thành nhiều file dbg nên ta phải viết script add từng file vào gdb.
1 | import gdb |
Document về lệnh debug-file-directory trong gdb
Mình lưu tên file là add_sym_libc.py
.
Mở gdb rồi chạy lệnh source add_sym_libc.py
(trước khi run
).
Enjoy …
Lưu ý:
- Phải add sym trước khi chạy chương trình, khi chương trình đang chạy hay attach một process thì việc add sym không có giá trị (Khi viết script python dùng pwntool các bạn nên xài
gdb.debug
thay vìgdb.attach
) - Biến
path_of_dbg_files
luôn có/
ở sau cùng.
Cách 2: Build lại pwninit từ source code
Đã có @dp1 viết lại code cho libc >=2.34, dù pull request này đã được chấp nhận nhưng mình không hiểu sao tác giả io12 vẫn giữ code cũ và không release ra phiên bản mới.
Mình clone repo https://github.com/dp1/pwninit rồi sửa lại một chút source code.
Trước khi sửa source code thì mình có đọc qua, tác giả dp1 viết code xử lý các trường hợp khi tên file là data.tar.xz
, data.tar.gz
, data,tar.zst
,gom các file dbg thành 1 file duy nhất (thật là out trình :)) )
1 | match ext { |
(Đoạn này ở trong file libc_deb.rs)
Bước 1: sửa source code
Vào file unstrip_libc.rs ở line 61
1 | let name = if version_compare::compare_to(&ver.string_short, "2.34", Cmp::Lt).unwrap() { |
sửa "2.34"
thành "2.31"
(theo như mình tìm hiểu thì từ libc 2.31 mới chia thành các file dbg nhỏ khác nhau)
Bước 2: Cài các compiler và thư viện để build
Chúng ta cần cài rustc
, cargo
, rust-lzma
Mình xài ubuntu nên mình chạy lệnh
1 | sudo apt install rustc cargo rust-lzma-sys |
Vào thư mục pwninit
rồi chạy lệnh
1 | export source="$(pwd)" |
Nếu các bạn build thành công thì binary sẽ nằm ở thư mục target/release
Enjoy …
file libc từ stripped
đã thành not stripped
.
Trong trường hợp không build được ( hoặc lười ), mình đã release binary trên github.
Good luck pwning.
P/s: Mình đang viết một tool thay thế pwninit <(“)