1. Return Oriented Programming (ROP) – x86
- 공격자가 실행 간 보호 (NX-bit) 및 코드 서명(Code signing)과 같은 보안 방어가 있는 상태에서 코드를 실행할 수 있게 해주는 기술
RTL + Gadgets
- Stack Overflow 취약성 (프로그램 흐름 변경) + “Gadgets(가젯)” (해당 프로그램이 사용하는 메모리에 이미 있는 기계 명령어)
2. Gadgets – POP; POP; POP; RET
- ROP = RTL + Gadgets
-- RTL 공격에서는 system 함수 이외 다른 라이브러리 함수 호출도 가능
- 여러 개의 함수 호출 위해 Gadgets 사용
-- “pop; pop; pop; ret” : 호출하는 함수의 인자가 3 개인 경우
-- “pop; ret” : 호출하는 함수의 인자가 1개인 경우
-- “ret” : 호출하는 함수의 인자가 없는 경우
-- Gadgets 역할 : ESP 레지스터 값의 증가
- 여러 개의 함수 연속해서 실행
--RTL에서 호출할 함수의 다음 영역은 해당 함수 종료된 후 이동할 Return address 영역
--해당 영역에 Gadgets의 주소 저장해서 연속해서 다음 함수 호출
--Ex. Read 함수 호출 후 system 함수 호출
Read 함수 libc 주소
Gadgets 주소 (pop; pop; pop; ret)
1st 인자값 (read 함수의)
2nd 인자값 (‘’)
3rd 인자값 (‘’)
System 함수 libc 주소
System 함수 호출 이후 return 할 주소
1st 인자값 (system 함수의)
Pop;pop;pop 으로 pop 세 번 수행하면 read 함수의 인자 3개를 pop하게 되고, 마지막 ret에 system 함수 libc 주소를 가리키게 되어 system 함수 주소로 리턴하게 된다. 그럼 두 번째 RTL이 실행되어 system 함수의 첫 번째 인자값으로 system 함수가 실행된다. (이때 인자값이 “/bin/sh”면 쉘이 실행될 것)
3. PLT & GOT
- PLT (Procedure Likage Table) : 동적 링커가 공유 라이브러리 함수를 호출하기 위한 코드 저장, 해당 정보들은 “.plt” 섹션에 저장
- GOT (Globle Offset Table) : 동적 링커에 의해 공유 라이브러리에서 호출할 함수의 주소 저장, 이 정보들은 “.got.plt” 섹션에 저장 -> 이 섹션은 공격자들의 공격 대상이며 힙, 즉 “.bss” exploit 에 의해 포인터 값을 변조
Ex. Debugging
Read 함수 처음으로 호출되기 전 breakpoint 설정
Read@plt 영역 : libc에서 read 함수 호출 위한 코드 저장
-read@got 영역에 저장된 주소로 이동
Read@got 영역 : <read@plt+6> 영역의 주소 저장되어 있음 -> read 함수를 해당 프로그램에서 처음 호출한 경우
<read@plt+11> 의 “jmp 0x80482f0” 코드에 의해 _dl_runtime_resolve() 함수 호출
_dl_runtime_resolve() 함수는 libc에서 찾고자 하는 함수(read)의 주소를 .got.plt 영역에 저장
Read 함수 호출된 후 read@got 영역에는 libc의 read 함수 주소가 저장되어 있음
4. example code
Read 함수로 크기 50 바이트인 buf 변수에 256 바이트 입력받음 -> overflow 취약점
# 보호기법 확인
#ROP 과정
Read(0, writable, len(str(binsh))) : writable 영역에 “/bin/sh”를 올린다.
Write(1, read_got, len(str(read_got))) : read_got에 있는 read 함수 주소 출력
Read(0, read_got, len(str(read_got))) : read_got에 system 함수 주소 덮어씀
Read(writable) : read 함수 호출 -> system 함수 호출되어 writable 인자로 주면 쉘 실행
# offset
libc_binsh_offfset : 0x18cd57
Libc_system_offset : 0x45390
Libc_read_offset : 0xf7250
Read_system_offset : 0x9ad60
# read@plt, read@got, write@plt
Write_plt_addr : 0x8048320
Read_plt : 0x8048300
Read_got : 0x804a00c
# writable area
Writable area ; 0x804a000-0x804b000
“.bss” 영역이 속하니 0x804a020을 “/bin/sh” 넣을 시작주소로 선택
# “pop;pop;pop;ret”
./rp-lin-x86 -f rop -r 4 | grep “pop”
pppr address : 0x80484e9
# buf에서 return address까지 거리
Buf(50) + dummy(6) + SFP(4) + return address(4)
# exploit code
$ vi ex2.py
Read_addr를 받을 때는 unpack해야 하므로 pwntools의 u32 함수를 사용한다.
$ vi ex3.py
# exploit
[Exploit Tech] One gadget (3) | 2019.11.02 |
---|---|
[Exploit Tech] ROP (Return Oriented Programming) -x64 (0) | 2019.08.17 |
Return to Shellcode (0) | 2019.08.10 |
2. RTL (Return into Library) -x64 (0) | 2019.07.26 |
1. RTL (Return into Library) -x84 (0) | 2019.07.25 |