SigReturn-Oriented Programming (SROP)
“ในวันที่เราไม่มี Gadget สำหรับการ jmp, ในวันที่โปรแกรมไม่มีอะไรให้เราเล่น แต่ Kernel ก็ยังมีสิ่งมหัศจรรย์หลงเหลือไว้ให้เราใช้อยู่”
SigReturn-Oriented Programming (SROP)
“ในวันที่เราไม่มี Gadget สำหรับการ jmp, ในวันที่โปรแกรมไม่มีอะไรให้เราเล่น แต่ Kernel ก็ยังมีสิ่งมหัศจรรย์หลงเหลือไว้ให้เราใช้อยู่”
ไม่มีใครพูด เนทพูดเอง | 2025
สวัสดีครับ วันนี้ “เนท” ต้องการนำเสนอแบบความสั้นๆ เกี่ยวกับหนึ่งในเรื่องที่ถูกลืมในหัวข้อ Pwnable & Binary exploitation นั่นก็คือ SROP ครับ
https://medium.com/@netorika/seccon-ctf-13-quals-paragraph-pwnable-writeup-606877568169
ROP (Return Oriented Programing) คือ หนึ่งในท่าที่ใช้ในการโจมตีโปรแกรมหลังจากที่เราสามารถควบคุม Stack Frame ของโปรแกรมได้แล้ว
โดยการเชื่อม(Chain) ตัวโค้ดที่อยู่ในส่วนต่างๆของ Binary (Gadgets) เข้าด้วยกัน เพื่อสร้างโปรแกรมเล็กๆที่สามารถทำงานตามที่ Attacker ต้องการได้
ไม่ว่าจะเป็น “Pwner” หน้าเก่า หรือ หน้าใหม่ก็ตาม ทุกคนจะต้องรู้จัก ROP กันอย่างแน่นอน
คือ เรื่องมันเป็นแบบนี้ครับ
เมื่อ 2–3 วันก่อนผมได้ไปเจอโจทย์ข้อนึงของ HTB Apocalypse CTF 2025 ที่โค้ดมันไม่มีอะไรเลยนอกจาก BOF และ syscall
mov rdi, 0
mov rsi, rsp
sub rsi, 8
mov rdx, 106h
syscall
retn
pop rax
retn

rax = 0
จะเห็นว่า ตัวโค้ดเรียกใช้ read() จาก rax = 0 เริ่มต้นของโปรแกรม โดยอ่าน input 0x106 byte และ วางเอาไว้ที่ rsp ทำให้เรามีสิทธ์ที่จะ overwrite return address ของโปรแกรม และ ทำ ROP
แต่แล้ว เราจะทำยังไงอะ? Rop ไปไหน Rop ยังไงให้เกิดโปรแกรม ถึงเราจะมี pop rax ที่ทำให้เท่ากับ 0x3b(execv) ได้ก็เถอะ แต่เราจะ mov rdi, binsh ยังไง
นั่นแหละคือคำถามครับ 5555
ถ้าสมมุติเราเลื่อนลงไปดูที่ 0xf เราก็จะเจอสิ่งนี้ครับ sigret

ถ้าใครขยันลองไปอ่านใน Man ดูนะครับ555 แต่เดี๋ยวผมสรุปให้ๆ
How kernel handle interupted signal
เมื่อโปรแกรมได้รับ [signal](https://man7.org/linux/man-pages/man7/signal.7.html) ไม่ว่าจากการเรียกใช้ syscall หรือ user เช่น SIGSEGV, SIGINT -> ตัว Operating Systemจะเก็บ [ucontext](https://en.wikipedia.org/wiki/File:Sigret_stackframe.svg)หรือพวกdataใน register ต่างๆเอาไว้บน Stack และไปทำงานในส่วน signal handler
หลังจากทำงานตรงนั้นเสร็จปุ๊ปก็จะเรียกใช้ rt_sigreturn เพื่อส่งค่าทั้งหมดกลับเข้าที่ที่มันควรอยู่
ความจริงมันซับซ้อนกว่านี้อีก แต่ช่างมันเถอะครับ เอาเท่านี้ก็พอแล้ว555

https://en.wikipedia.org/wiki/Sigreturn-oriented_programming#/media/File:Sigret_stackframe.svg
SROP คือการ abuse การทำงานของ rt_sigreturn โดยการสร้าง ucontext ปลอมขึ้นมาจากการ overwrite บน stack และเรียกใช้ syscall rax = 0xf
โดยวิธีการสร้าง Payload ใน pwntools ก็ทำแบบนี้ครับ
from pwn import *
r = process("./xxxx")
frame = SigreturnFrame()
frame.rax = 0xf
frame.rdi = 0
frame....
payload = bytes(frame)
r.sendline(payload)
อะไรก็ว่าไป
ซึ่งผลลัพท์ที่ออกมาคือการ Load ค่าเข้าไปใน registers เหมือนกับการ mov rdi, value เลย
ซึ่ง ถ้าหากเราสามารถควบคุม registers ต่างๆได้ เราก็จะสามารถเรียกใช้ execv ด้วย syscall และเปิด shell ได้
จะเห็นว่าในตัวโปรแกรมอาจจะไม่มี Gadgets อะไรเลยให้ สร้าง ROP แต่ก็ยังสามารถถูก Pwned ได้อย่างง่าย ผ่านการ Direct Syscall และ SROP
ประมาณนี้แหละครับ!
อ้างอิง :
메타데이터
- post_id
- 8c7143c1719c
- slug
- sigreturn-oriented-programming-srop-8c7143c1719c
- url
- https://medium.com/@netorika/sigreturn-oriented-programming-srop-8c7143c1719c
- canonical_url
- https://medium.com/@netorika/sigreturn-oriented-programming-srop-8c7143c1719c
- author_url
- https://medium.com/@netorika
- status
- ok
- fetched_at
- 2026-06-26 03:39:16