pwn学习总结(一) —— 常用命令
pwn學習總結(一) —— 常用命令
- 編譯程序
- 文件信息
- 本地測試
- 遠程調試
- cyclic
- ROPgadget
- gdb
- pwntools
編譯程序
GCC編譯參數:
-m32:編譯為32位程序
-fstack-protector:啟用棧溢出保護,不過只為局部變量中含有數組的函數插入保護
-fstack-protector-all:啟用棧溢出保護,為所有函數插入保護
-fno-stack-protector:禁用棧溢出保護
-z noexecstack:開啟NX保護
-z execstack:關閉NX保護
-z norelro:關閉relro
-z lazy:開啟relro,等級為1
-z now:開啟relro,等級為2
-fpie -pie:開啟pie,此時強度為1
-fPIE -pie:開啟pie,此時最高強度為2
-no-pie:關閉pie
文件信息
查看文件屬性:file 文件名
查看程序防護:checksec 文件名
Arch:文件屬性
RELRO:開啟后,符號重定向表格屬性為只讀,或在程序啟動時就解析并綁定所有動態符號,從而減少對GOT(Global Offset Table)攻擊,圖中Partial RELRO表示我們對GOT表具有寫的權限
Stack:Canary Stack保護(俗稱金絲雀),開啟后,程序在函數返回前會設置好的金絲雀值進行檢查,從而達到堆棧保護的目的
NX:即No-eXecute(不可執行)的意思,開啟后,就算溢出到shellcode位置也不可執行,cpu會拋出異常
PIE:地址隨機化
查看文件頭信息:readelf -h 文件名
查看十六進制數據:
完整顯示:xxd 文件名 | od -A x -t x1z 文件名
部分顯示:od --skip bytes=偏移地址 --read-bytes=字節數 -A x -t x1z 文件名
x1z表示每顯示一個十六進制數輸出一個空格;x2z表示每顯示兩個十六進制數輸出一個空格*
檢索程序導入的函數:objdump -R 文件名
查看程序所有函數及反匯編:objdump -d 文件名
反匯編單個函數:
#!/bin/bashvmlinux=$1 symbol=$2 if [ -z "$vmlinux" ]; then echo "usage : $0 vmlinux symbol"exit fi startaddress=$(nm -n $vmlinux | grep "\w\s$symbol" | awk '{print "0x"$1;exit}') endaddress=$(nm -n $vmlinux | grep -A1 "\w\s$symbol" | awk '{getline; print "0x"$1;exit}') if [ -z "$symbol" ]; then echo "dump all symbol"objdump -d $vmlinux else echo "start-address: $startaddress, end-address: $endaddress" objdump -d $vmlinux --start-address=$startaddress --stop-address=$endaddress fi
反匯編整個文件:ndisasm -u 文件名
查找ROP:ROPgadget --binary 文件名
過濾ROP:ROPgadget --binary 文件名 --only '指令1|指令2'
本地測試
運行程序:./文件名
通過python構造payload:python -c 'print "payload"' | ./文件名
將文件內容作為輸入:cat payload文件 -| ./文件名
遠程調試
連接遠程服務器:nc ip port
下載遠程目錄中的程序:scp -P 端口號 -p IP地址:路徑/* ./
cyclic
生成字符串隊列:cyclic 字符數
計算字符串偏移:cyclic -l 四個字母
ROPgadget
搜索ROP指令:ROPgadget --binary 文件名 --only '指令1|指令2' | grep '需包含的字符串'
自動生成ROP鏈(若存在),只適用于靜態鏈接程序:ROPgadget --binary 文件名 --ropchain
gdb
安裝pwndbg插件
git clone https://github.com/pwndbg/pwndbg cd pwndbg sudo ./setup.sh選擇文件
附加進程:attach 進程ID
運行:run
將文件數據作為運行參數:run < file
運行至程序入口:start
單步步入:si
單步步過:ni
在指定函數設置斷點:b 函數名
在指定地址設置斷點:b *地址
繼續運行程序:continue | c
查看所有寄存器的值:reg
查看指定寄存器的值:p $寄存器代號
查看內存布局:i proc mappings
查看內存數據:
查看函數調用情況:backtrace | bt
查看棧數據:stack
查看所有函數定義:i functions
查看指定函數反匯編代碼:disassemble 函數名
查看當前函數反匯編代碼:disassemble $pc
查看libc動態地址:libc
查找字符串所在地址:search '字符串'
pwntools
安裝pwntools:pip install pwntools
導入pwntools:from pwn import *
輸出調試信息:context.log_level = 'debug'
設置cpu架構:context.arch = 'i386'/'amd64'
遠程連接:sh = remote('IP',PORT)
本地運行:sh = process('./elf')
發送數據:sh.send(data)
發送數據,并在末尾加上換行符(\n):sh.sendline(data)
在指定字符出現后輸入指定字符串:sh.sendafter('等待的字符串', '輸入的字符串')
在指定字符出現后輸入指定字符串與回車:sh.sendlineafter('等待的字符串', '輸入的字符串')
接收數據,numb指定字節數,timeout指定超時時間:sh.recv(numb=4096, timeout=default)
接收一行數據,keepends表示是否保留行尾的換行符(\n):sh.recvline(keepends=True)
一直接收到字符串delims出現,drop表示是否保留參數1:sh.recvuntil(delims, drop=False)
一直接收數據直到EOF:sh.recvall()
進入shell模式:sh.interactive()
附加gdb調試:gdb.attach(sh)
加載elf文件:elf = ELF('[文件名]')
查看指定函數的PLT地址:function_plt = elf.plt['函數名']
定位字符串靜態偏移:elf.search('字符串').next()
將整數轉換成32位的小端字節序:p32(整數)
將4個字節轉換成最多4字節的整數:u32(字符串.ljust(4, '\x00'))
將整數轉換成64位的小端字節序:p64(整數)
將8個字節轉換成最多8字節的整數:u64(字符串.ljust(8, '\x00'))
生成指定字符數量的字符串:str = cyclic(字符數)
查找指定字符串偏移:index = cyclic_find('四個字母')
生成一段shellcode匯編代碼:shellcode = shellcraft.sh()
編譯shellcode匯編代碼為字節碼:shellcode = asm(shellcraft.sh())
總結
以上是生活随笔為你收集整理的pwn学习总结(一) —— 常用命令的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows进程与线程学习笔记(五)—
- 下一篇: pwn学习总结(二) —— 基础知识(持