# Basic tools ## ROPgadget - là powerful tool của mọi pwner - tìm những đoạn nhỏ chương trình - [ref](https://github.com/JonathanSalwan/ROPgadget) - tải: ```bash $ 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"`` :::spoiler 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: ```bash sudo apt install python3-pip sudo pip3 install capstone filebytes ropper ``` - lệnh: ```bash 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` - [ref](https://github.com/david942j/one_gadget) - lệnh: ```bash one_gadget <filelibcname> ``` ![](https://hackmd.io/_uploads/rkVcJb8jn.png) - 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: ```bash sudo gem install one_gadget ``` :::warning :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](https://github.com/david942j/seccomp-tools) - tải: ```bash sudo apt install libseccomp-dev libseccomp2 seccomp sudo apt install gcc ruby-dev sudo gem install seccomp-tools ``` - lệnh: ```bash $ seccomp-tools dump ./<filename> ``` ![](https://hackmd.io/_uploads/HJHUJZIi2.png) - đâ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: ```bash $ sudo apt install file ``` - lệnh: ```bash $ file <filename> ``` ![](https://hackmd.io/_uploads/SJ2gy-Uon.png) ## 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: ```bash $ sudo apt install checksec ``` - lệnh: ```bash $ checksec <filename> ``` ![](https://hackmd.io/_uploads/SJyTAeLj3.png) - hoặc khi debug bằng gdb, ta kiểm tra vẫn được ```gef gef➤ checksec ``` ![](https://hackmd.io/_uploads/HkXC0xIjh.png) ## 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õ ![](https://hackmd.io/_uploads/B1XHal8s3.png) > tìm hỉu về hàm **strncmp()** - tải: ```bash $ sudo apt install man-db ``` - lệnh: ```bash $ 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 ![](https://hackmd.io/_uploads/SyLF0xUj2.png) > option *-d* để xem dynamic section - lệnh: ```bash $ readelf -d <filename> ``` ## tldr - 1 loại tool giúp mình tìm hiểu các command ![](https://hackmd.io/_uploads/H1mEVHAT2.png) - tải: ```bash $ sudo snap install tldr ``` - lệnh: ```bash $ 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ụ: ```bash $ 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ụ: ```bash $ python3 solve.py DEBUG NOASLR --- $ ./solve.py DEBUG NOASLR ``` # genscr ```python #!/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' ```py os.system('code solve.py') ``` # IDA - chỉ decompile được file có kiến trúc `x86-64` (**amd64**) hay `x86` ## Linux - [link tải](https://hex-rays.com/ida-free/#download) - 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 - thực ra link trên tải cho Window vẫn được nhưng mình sẽ cho mng 2 link phiên bản IDA Pro Full Crack - [IDA 7 Pro full-crack stable](https://drive.google.com/file/d/1rUHkARsAP8GIn-IothjcpZ6RoKvX3DIt/view) - [IDA 9 full-crack stable](https://51ypsj-my.sharepoint.com/:u:/g/personal/as_51ypsj_onmicrosoft_com/EWiOAI9utytPuyGNI7tBdYsBLbSL36w_gBQ_d0eAdyajKA) > 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](https://github.com/NationalSecurityAgency/ghidra/releases) - là 1 decompiler khỏi phải bàn =))) - cân được cả [arm](https://hackmd.io/@trhoanglan04/arm), [risc-v](https://hackmd.io/@trhoanglan04/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 ```bash git clone https://github.com/pwndbg/pwndbg cd pwndbg ./setup.sh ``` ## GDBserver - https://hackmd.io/@trhoanglan04/GDB_server ## GDB/GDBserver static - https://github.com/hugsy/gdb-static/blob/master/README.md # Load libc in python ```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 - https://blog.yadutaf.fr/2014/05/29/introduction-to-seccomp-bpf-linux-syscall-filter/ # 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](https://hackmd.io/_uploads/SJTQebY50.png) >$rdi=0 và $rsi là path tuyệt đối >If pathname is absolute, then dirfd is ignored. ```py shellcode = shellcraft.openat(0, '/flag.txt', 0) shellcode += shellcraft.sendfile(1,'rax',0,0x80) ``` ![image](https://hackmd.io/_uploads/By0UgZK5C.png) >$rdi=-100 và $rsi là file_name (path tương đối) >If pathname is relative and dirfd is the special value AT_FDCWD > [ref](https://sites.uclouvain.be/SystInfo/usr/include/linux/fcntl.h.html) ```py shellcode = shellcraft.openat(-100, 'flag.txt', 0) shellcode += shellcraft.sendfile(1,'rax',0,0x80) ```