Try   HackMD

Basic tools

ROPgadget

  • là powerful tool của mọi pwner
  • tìm những đoạn nhỏ chương trình
  • ref
  • tải:
$ sudo apt install python3-pip
$ sudo -H python3 -m pip install ROPgadget
$ ROPgadget --help
  • lệnh:
ROPgadget --binary <file>
  • tìm chọn lọc (filter):

ROpgadget --binary libc.so.6 | grep "pop rdi"

Trick
  • nếu cần gadget syscall ; ret từ libc, khó mà ROPgadget rồi grep chính xác
  • thì ta sẽ dùng trick lỏ này

objdump -D -Mintel ./libc-2.31.so | grep -B 1 ret | grep -A 1 syscall

ropper

  • tương đồng như ROPgadget
  • tải:
sudo apt install python3-pip
sudo pip3 install capstone filebytes ropper
  • lệnh:
ropper -f <file>

one_gadget

  • với kỹ thuật này ta có thể thực thi "execve" sau khi ret ở main

thay vì pop_rdi -> /bin/sh -> system

one_gadget <filelibcname>

  • ta sẽ nhận thường là 3 đến 4 offset của execve sau khi sử dụng one_gadget
  • với điều kiện đi kèm trong 3(4) offset đó là các thanh ghi | địa chỉ cần phải thoả mãn
  • để biết chọn offset nào thì ta hãy chạy chương trình và dừng ngay ret của main(), kiểm tra thanh ghi | địa chỉ và cái nào thoả thì lấy cái đó
  • lưu ý là nó chỉ là offset, nên muốn đưa one_gadget đó thực thi thì phải cộng chung với libc_base :
payload = b'A'*8 ---> save_rbp
payload += libc.address + p64(<offset>)   ---> rip
  • tải:
sudo gem install one_gadget

:warning: không khuyến khích sử dụng tool này bởi vì nó sẽ hạn chế khả năng tư duy của mình

:+1: chỉ sử dụng khi bắt buộc phải dùng đến nó

như chỉ có thể overflow thêm 8 byte ở $rip

seccomp-tools

  • đây là tool để kiểm tra file có bị filter bởi các syscall nào nó hay k
  • ref
  • tải:
sudo apt install libseccomp-dev libseccomp2 seccomp
sudo apt install gcc ruby-dev
sudo gem install seccomp-tools
  • lệnh:
$ seccomp-tools dump ./<filename> 

  • đây là chủ đích do author muốn ta hạn chế gọi các phương thức khác từ bên ngoài

file

  • là công cụ check thông tin chall ta đang khai thác, cho biết kiểu file ta đang exploit là gì
    • ELF ?
    • 32 bits, 64 bits ?
    • chip Intel 80386, x86-64, ARM , riscv ?
    • dynamically hay statically linked ?
    • not strip hoặc stripped
    • v.v
  • tải:
$ sudo apt install file
  • lệnh:
$ file <filename>

checksec

  • là công cụ để kiểm tra các lớp bảo vệ của chương trình
    • Arch : xem kiến trúc của chương trình là gì
    • RELRO : xem có thể thay đổi GOT được không?
    • Stack : có canary bảo vệ việc overflow hay không?
    • NX : stack có quyền thực thi hay không?
    • PIE : file có địa chỉ exe động hay tĩnh?
  • tải:
$ sudo apt install checksec
  • lệnh:
$ checksec <filename>

  • hoặc khi debug bằng gdb, ta kiểm tra vẫn được
gef➤ checksec

man

  • là công cụ khá hữu ích khi tìm kiếm thông tin về 1 hàm
  • có đầy đủ về arg yêu cầu của hàm đó, chi tiết và hoạt động của hàm đó ra sao
  • và có cả examble nhỏ cho ta hiểu rõ

tìm hỉu về hàm strncmp()

  • tải:
$ sudo apt install man-db
  • lệnh:
$ man <function>

pwninit

  • là công cụ khá là hữu ích khi ta muốn link glibc vào 1 file binary
  • tải:
cd /usr/bin
sudo wget https://github.com/io12/pwninit/releases/download/3.3.0/pwninit
sudo chmod +x pwninit
sudo apt-get install elfutils
  • lệnh:
$ pwninit

readelf

  • cũng là 1 tool hỗ trợ ta khai thác
  • mục đích để dump file ra và xem các địa chỉ có thể hỗ trợ khai thác

option -d để xem dynamic section

  • lệnh:
$ readelf -d <filename>

tldr

  • 1 loại tool giúp mình tìm hiểu các command

  • tải:
$ sudo snap install tldr
  • lệnh:
$ tldr <command>

parameters

DEBUG

  • chạy script và thêm tham số DEBUG để dễ dàng xem dữ liệu vào ra
  • ví dụ:
$ python3 solve.py DEBUG
---
$ ./solve.py DEBUG

NOASLR

  • là 1 chức năng khi ta DEBUG stack và binary sẽ chạy động (PIE bật)
  • ASLR stand for Address Space Layout Randomization
  • nhưng nếu ta muốn chạy tĩnh như ta gdb chal thì thêm tham số NOASLR là được
  • ví dụ:
$ python3 solve.py DEBUG NOASLR
---
$ ./solve.py DEBUG NOASLR

genscr

#!/usr/bin/python3

import sys, os, subprocess

program = sys.argv[1]
if len(sys.argv) > 2: libc = sys.argv[2]

script = f'''#!/usr/bin/python3

from pwn import *

exe = ELF('{program if len(sys.argv) != 1 else ""}', checksec=False)
{("libc = ELF('" + libc + "', checksec=False)") if len(sys.argv) != 2 else ""}
context.binary = exe

info = lambda msg: log.info(msg)
sla = lambda msg, data: p.sendlineafter(msg, data)
sa = lambda msg, data: p.sendafter(msg, data)
sl = lambda data: p.sendline(data)
s = lambda data: p.send(data)
sln = lambda msg, num: sla(msg, str(num).encode())
sn = lambda msg, num: sa(msg, str(num).encode())

def GDB():
    if not args.REMOTE:
        gdb.attach(p, gdbscript=\'\'\'


        c
        \'\'\')
        input()


if args.REMOTE:
    p = remote('')
else:
    p = process(exe.path)
GDB()



p.interactive()
'''

with open('solve.py', 'wt') as f:
    f.write(script)

os.system('chmod +x ' + program)
os.chmod('solve.py', 0o755)
os.system('subl solve.py')

for those who use sublime_text

  • copy and write into /usr/bin/genscr
  • then chmod +x /usr/bin/genscr
  • usage: genscr <chall_name> <libc>
  • for anyone use VScode in WSL, just change 'subl' to 'code'
os.system('code solve.py')

IDA

  • chỉ decompile được file có kiến trúc x86-64 (amd64) hay x86

Linux

  • link tải
  • sau khi tải về, ta chmod +x <file_ida>.run rồi ./<file_ida>.run
  • mở IDA lên bằng cách double-click icon hoặc chạy bằng lệnh ./<path_to_ida64.exe>

Window

nhược điểm là chỉ xài được cho Window nếu mấy friend dùng WSL
mà máy mình thì lâu lâu chạy bị lỗi (Not Responed)
nên nếu máy các bạn chạy bình thường thì thôi =))))

  • sau khi tải về, giải nén ra và trong thư mục đó sẽ có 2 file .exe
  • decompile file 64 thì mở ida64.exe, file 32 thì mở ida32.exe

gọi ida từ terminal

  • ta thiết lập symlink:

ln -s <path_to_ida64.exe> /usr/bin

  • ví dụ:

ln -s "C:\Program File\IDA\ida64.exe" /usr/bin

  • xong chạy thì gọi ida64 chal là được

Ghidra

  • link tải
  • là 1 decompiler khỏi phải bàn =)))
  • cân được cả arm, risc-v,
  • nếu gặp chall có arch k phải x86-64 hay x86 thì Ghidra là công cụ khá mạnh mẽ

hoặc đôi lúc IDA dịch hơi ngu thì Ghidra sẽ dịch được (đa phần)
nhưng do giao diện sau khi decompile sẽ hơi rối so với IDA
nên nếu cần thiết thì dùng Ghidra nha (tại khởi động hơi phức tạp)

  • tải xong giải nén
  • thiết lập symlink cho thuận tiện và lệnh setup

ln -s <path_to_ghidraRun> /usr/bin

sudo apt-get install openjdk-17-jdk

setup cái JDK dẫn vào PATH /usr/lib/jvm/<phienbanjava>

  • sử dụng thì mở terminal chạy lệnh ghidraRun

GDB

sudo apt-get install libc6-dbg gdb valgrind

GEF

bash -c "$(curl -fsSL https://gef.blah.cat/sh)"

pwndbg

git clone https://github.com/pwndbg/pwndbg
cd pwndbg
./setup.sh

GDBserver

GDB/GDBserver static

Load libc in python

from ctypes import *

glibc = cdll.LoadLibrary('./libc.so.6')

glibc.srand(glibc.time(0))

val = glibc.rand()

print(hex(val))

Compile

Canary

  • fno-stack-protector : No canary
  • fstack-protector : Turn on canary of a function when local buffer is < 8 bytes
  • --param ssp-buffer-size=<k> : Used with -fstack-protector to specify if local buffer larger than <k> bytes, then add canary to that function
  • fstack-full-protector (default): Turn on canary for all functions

No RELRO

  • -z norelro

No NX

  • -z execstack

No PIE

  • -no-pie

static built

  • -static

seccomp rule

Service

  • Normal:

ncat -vc ./binary -kl 127.0.0.1 $port

  • With specific library:

ncat -vc 'LD_PRELOAD=/path/to/libc.so ./binary' -kl 127.0.0.1 $port
ncat -vc 'LD_LIBRARY_PATH=/path/of/libc.so ./binary' -kl 127.0.0.1 $port

After this, you can connect to binary service by command nc localhost $port.

openat syscall

int openat(int dirfd, const char *pathname, int flags, mode_t mode);

image

$rdi=0 và $rsi là path tuyệt đối
If pathname is absolute, then dirfd is ignored.

shellcode = shellcraft.openat(0, '/flag.txt', 0)
shellcode += shellcraft.sendfile(1,'rax',0,0x80)

image

$rdi=-100 và $rsi là file_name (path tương đối)
If pathname is relative and dirfd is the special value AT_FDCWD
ref

shellcode = shellcraft.openat(-100, 'flag.txt', 0)
shellcode += shellcraft.sendfile(1,'rax',0,0x80)