본문 바로가기

Return Oriented Programming(ROP) 공격 기법

@eouya22025. 7. 23. 20:56

 

ROP란

버퍼 오버플로우 취약점이 존재하는 바이너리에서 바이너리에 존재하는 gadget(코드 조각)들을 이용하여 공격하는 기법을 말한다.

return gadget들을 이용하여 프로그램의 흐름이나 함수의 인자를 조작하거나 got 영역을 overwrite하는 등의 공격이 가능하다.

 

gadget의 경우 바이너리에 존재하는 코드 조각이라고 앞서 설명 했듯이, PIE가 걸려있다면 PIE_base 주소를 leak한 다음, 

base주소에 gadget의 offset을 더하여 사용이 가능하다.

 

처음 배울 때는 '아 그냥 gadget 맞춰서 인자에 들어갈거, 덮어쓸 거 쓰고 호출하고 싶은 함수 쓰고 하면 되구나' 하면서 배웠는데

이번에 정리하며 원리를 자세히 알아보고자 하였다.

 

ROPgadget 찾기

 

바이너리의 gadget은 위와 같은 명령어로 확인이 가능하다.

 

다양한 형태의 gadget들이 있는 것을 볼 수 있다.

현재 보고있는 바이너리에는 PIE 보호 기법이 안걸려 있어서 gadget 주소를 바로 사용할 수 있다.

위에서 설명했듯 PIE가 걸려있으면 offset만 나오게 된다.

뒤에서 알게 되겠지만 저 많은 gadget들 중에 실제로 사용하는 gadget들은 거의 정해져 있다고 보면 된다.

 

ROP Scenario

위 사진에서 pop..; ret / pop.. ; pop... ; ret 이러한 gadget들을 주로 사용할 것이다.

gadget에서 pop rdi ; ret 을 예로 들어 작동하는 과정을 설명하도록 하겠다. system("/bin/sh")을 호출한다고 해보자.

 

 

사진처럼 ROP공격시에 버퍼 오버플로우 취약점을 이용하여 ret이후의 ROPchain(ret instruction들을 이용해서 연결된 gadget 체인)을 만들게 될 것이다.  RET 이후의 ROPchain은 우리가 만드는 새로운 스택이라고 생각하면 편하다. 

 

main함수에서 RET -> 현재 rsp가 가리키고 있는 주소(pop rdi ; ret)를 rip에 넣고, rsp += 8

--> pop rdi ; ret gadget 실행 시작

 

pop rdi -> "/bin/sh"이 저장된 주소(rsp)를 pop하여 rdi 레지스터에 저장한다. 이후 rsp += 8을 해준다.

ret -> rsp가 가리키는 곳(system())으로 return한다.

 

동작 방식을 이렇게 설명하였지만 이해만 하고 가젯 다음에 들어갈 인자 넣고 호출할 함수 쓰고.. 하면서 익스플로잇을 하면 되겠다.

단일 chain을 설명했는데, ROPchain을 무한정으로 연결하여 원하는 함수를 계속 호출하거나 ret2main, got 테이블을 덮어 쓰거나 하는 공격들이 가능하다.

 

'PWN > 개념' 카테고리의 다른 글

one_gadget  (0) 2025.07.23
PIE / RELRO  (0) 2025.07.23
PLT, GOT  (0) 2025.06.26
NX(No-eXecute) & ASLR(Address Space Layout Randomization)  (1) 2025.06.26
스택 카나리(Stack Canary)  (0) 2025.06.19
eouya2
@eouya2 :: eouya2

개인공부 기록 / 틀린거 있으면 돌팔매질 부탁드립니다

목차