🧠 ROP(리턴 지향 프로그래밍) 쉽게 이해하기: 일상적인 예시 포함
ROP(Return-Oriented Programming)를 이해하려면 메모리 구조와 함수 호출 방식을 알아야 합니다.
이를 쉽게 설명하기 위해 택배 배달 시스템을 예로 들어보겠습니다. 🚚📦
🔍 1️⃣ ROP란?
✅ 기본 개념
- 프로그램의 **리턴 주소(Return Address)**를 조작하여 원하는 함수를 실행하는 기법입니다.
- 일반적인 BOF(버퍼 오버플로우) 공격과 달리, 쉘코드를 삽입하지 않고 바이너리에 존재하는 코드 조각(가젯, gadgets)을 조합하여 원하는 기능을 수행합니다.
- NX(Non-Executable) 보호 우회 가능 → system("/bin/sh") 실행 가능!
🏠 2️⃣ ROP를 택배 배달 시스템으로 비유하기
📌 메모리 구조 = 택배 회사 창고
컴퓨터의 메모리는 택배 회사의 창고라고 생각해봅시다.
- 택배 상자(스택): 함수의 실행 정보가 담긴 공간
- 택배 주소(리턴 주소): 다음에 실행할 함수의 위치
- 택배 기사(CPU): 현재 할 일을 수행하는 프로세서
- 택배 배달 경로(ROP 체인): 특정한 순서로 함수를 실행하는 과정
🚀 정상적인 함수 호출 과정:
- 사용자가 "A 지점에서 B 지점으로 택배를 배달해!"라고 요청(함수 호출).
- 택배 기사가 스택(택배 창고)에 정보를 보관하고 출발.
- B 지점에서 할 일을 마치면, 택배 기사는 창고에 보관된 정보를 보고 원래 위치로 돌아옴(리턴).
✅ 하지만! 해커(공격자)가 택배 창고를 조작하면?
- 택배 기사가 엉뚱한 곳으로 이동하여, 원래 할 일이 아니라 해커가 원하는 일을 수행하게 만듦.
- 이게 바로 ROP 공격!
📝 3️⃣ 메모리 구조 & ROP 이해
📌 스택(Frame)과 함수 호출
프로그램이 함수를 호출하면, **스택(stack)**에 실행 정보를 저장합니다.
주소 내용
0x400080 | (리턴 주소, 다음에 실행될 코드) |
0x400078 | (이전 RBP 값, 이전 프레임 복구) |
0x400070 | (로컬 변수) |
0x400068 | (로컬 변수) |
✅ 함수 호출 과정:
- call function() 실행
- 현재 RIP(Instruction Pointer) 값을 스택에 저장
- 함수가 실행된 후, 리턴 주소(Return Address)를 읽어서 원래 위치로 돌아감
🔴 ROP 공격 = 이 리턴 주소를 조작해서 원래 함수가 아닌 system("/bin/sh")을 실행하는 것!
💥 4️⃣ ROP 공격 실제 흐름
✅ 공격 목표
- 정상적인 함수 실행 흐름을 깨고, system("/bin/sh") 실행하여 쉘을 획득.
✅ 일반적인 BOF(버퍼 오버플로우)와의 차이
- 예전에는 스택에 쉘코드를 넣고 실행했음.
- 하지만 현대 OS에서는 NX(Non-Executable) 보호로 스택 실행이 막혀 있음.
- 따라서 ROP 기법을 사용하여 바이너리에 존재하는 system("/bin/sh")을 호출해야 함.
📌 ROP 공격 과정
- BOF 발생
- read()나 gets() 등을 이용하여 리턴 주소 덮어쓰기.
- 스택에 새로운 리턴 주소 삽입
- 원래 리턴할 함수가 아니라, system("/bin/sh")이 실행되도록 조작.
- 필요한 가젯을 활용하여 system("/bin/sh") 실행
- pop rdi; ret 가젯을 사용하여 "/bin/sh"를 인자로 설정.
- ret 가젯을 사용하여 스택 정렬 맞춤.
🔚 결론
📌 ROP 공격의 핵심
- 리턴 주소를 조작하여 원하는 함수 실행
- ROP 가젯을 활용하여 system("/bin/sh") 호출
- 스택 정렬 문제 해결 (ret 가젯 추가)
- 최종적으로 쉘 획득!
🏠 ROP = 택배 시스템 비유 정리
✅ 정상적인 택배 시스템:
- CPU(택배 기사)가 원래 경로(리턴 주소)로 배달 🚚
✅ ROP 공격: - 해커가 택배 창고(스택)를 조작하여 엉뚱한 곳(해커가 원하는 코드)으로 배달 🚀
💡 이제 ROP를 좀 더 직관적으로 이해할 수 있겠죠?
실제로 Pwndbg에서 디버깅하며 실행하면 더 이해하기 쉬울 거예요! 🚀😊
'Study > System' 카테고리의 다른 글
왜 BOF로 return address를 덮어 씌울까? (0) | 2025.02.24 |
---|---|
return address vs ret 가젯 차이점과 관계 (0) | 2025.02.24 |
ret(return) 가젯 (0) | 2025.02.24 |
가젯(Gadget) (0) | 2025.02.24 |
RWX메모리를 만드는 mprotect(), mmap() (1) | 2025.02.22 |