diff 32bit vs 64bit
General BOF
EBP-8에 할당되어 있는 변수를 오버플로우 한다고 가정하였을때,
EBP에는 SFP가 존재하고, EBP+4에는 RET이 존재한다.
32bit system에서는 SFP가 4byte크기를 갖기 때문에 RET 변조를 위해서는 최소 스택 + 4 byte의 더미를 주고 RET에 접근한다.
하지만 64bit system의 경우에는 4byte 주소를 사용하던 32bit와는 달리 8byte 주소를 사용한다.
따라서, SFP가 8byte이므로 스택 + 8byte만큼의 더미를 주어야 한다.
RTL and ROP
이에 대해 학습하기 이전에는
Calling Convention
에 대한 이해가 필요하다.콜링 컨벤션은 크게 3가지 존재하며 여기서 주목할 것은
cdecl
과fastcall
이다.두 가지의 호출규약의 가장 큰 차이는 인자를 전달하는 방식이다.
cdecl
: 스택 ,fastcall
: 레지스터 를 사용하여 인자를 전달한다.32bit system에서의 RTL Payload는 아래와 같다. (ebp-8 Overflow)
payload = '' payload += 'A' * (8 + 4) payload += p32(system) payload += 'A' * 4 payload += p32(binsh)
EBP까지의 거리 + SFP 크기의 더미를 주어 RET에 접근하기 위해 스택을 채우고 RET위치를
system
함수의 주소로 Overwrite한다. 그 이후 4byte는system
함수가 호출된 이후 호출 될 주소를 의미한다.그리고 그 다음 4byte는
system
이 끝나고 호출 될 주소이다. (위 예시에서는binsh
의 주소)그 뒤 4byte는 첫번째 인자로 들어간다.
64bit
System에서는 어떠한 레지스터에 몇번째 인자가 들어가는지 알고있어야 한다.
RDI, RSI, RDX, RCX
순으로 인자가 들어간다.이를 바탕으로
64bit
System에서의 RTL Payload를 펴보자. (ebp-8 Overflow)payload = '' payload += 'A' * (8 + 8) payload += p64(pr) # pop rdi, ret , 첫번째 인자 pop payload += p64(binsh) payload += p64(system)
64 bit 체제에서는
ret
에 바로 함수 주소를 쓸 수 없기 때문에,gadget
을 이용해야한다.(만일, 인자가 없는 함수의 경우에는 그냥 써도 무방하다.)
위 예시에서 쓰인
system
함수는 인자가 하나인 함수이며 따라서 첫 번째 인자가 들어갈 레지스터인RDI
를pop
해줘야 한다.먼저,
pop
을 이용해서 첫 번쨰 인자가 위치할rdi
내부 값을 빼주고,binsh
문자열을 넣은 뒤,system
함수를 호출한다.
'Hacking & Security > Exploit' 카테고리의 다른 글
Return To Libc ( RTL ) (0) | 2018.12.29 |
---|---|
Return to Shellcode (0) | 2018.12.27 |
Basic of pwnable (0) | 2018.12.27 |
BOF 기초문서 (0) | 2018.11.03 |