8. 보호 기법 우회
1) DEP 우회 : RTL (Return To Libc)
▣ 공유 라이브러리 (shared library)
- 여러 프로세스에서 동시에 공동 이용이 가능한 라이브러리
- 파일 이름에 .so 가 포함되어 있음
- 프로그램 시작시 적재됨 --> 무조건 시작을 해야함.
▣ 우회 원리
- RET에 이전처럼 Shellcode를 넣지 않고 라이브러리 함수를 이용함.
- 인자값을 전달할 필요가 있음.
▣ RTL 공격 실습
[공격 시나리오]
1. Buffer에서 EBP까지의 거리
2. system() Libc 주소
3. system() 인자 주소
- /tmp/bof.c 작성 & 컴파일
#include <stdio.h> int main(int argc, char *argv[]) { char buffer[40]; strcpy(buffer, argv[1]); printf("%s\n", buffer); }
>> 여기서부터는 일반사용자 계정에서 진행..
1. Buffer에서 EBP까지 거리 알아내기
☞ EBP 크기까지 더하면 RET 까지의 거리는 60임을 알 수 있음.
2. system() Libc의 주소알아내기.
☞ 공유라이브러리는 프로그램이 시작을 해야 적재되기 때문에 중단점으로 프로그램을 실행시켜서 찾음.
3. system() 인자 주소
☞ 환경변수에 "/bin/sh"를 넣을 것임.
☞ DEP 우회라며..? 환경변수 못쓰는거 아니야..?
A) DEP는 실행권한을 없앤 경우라서 쉘코드 실행을 못할뿐 문자열을 저장은 할 수 있음.
4. 공격!
☞ shell이 실행됐지만 권한은 i2sec 일반사용자의 것 그대로임...
☞ /bin/sh는 EUID와 RUID를 비교하기 때문!
▣ 왜 안될까..?
- setuid(0);를 추가한 /tmp/sh 파일을 만들어서 돌려도 root권한의 쉘을 획득하지 못함..
- system("/bin/sh") == /bin/sh -c /bin/sh
☞ 이미 실행자체를 /bin/sh 로 해당 명령어를 실행중임.
[해결방안]
- execl 함수를 사용하자!!
- int execl(const char *path, cont char *arg, ..., NULL);
☞ path다음의 인자는 몇개나 와도 되지만 마지막에는 항상 NULL이 있어야함.
☞ 이 때 NULL은 0x00이 아닌 0x00000000임.
- execl("/tmp/sh", "/tmp/sh", NULL)
push NULL
push "/tmp/sh"
push "/tmp/sh"
▣ RTL 공격 실습 (2)
[공격 시나리오]
1. execl() 주소
2. "/tmp/sh" 문자열 주소
3. 인자값 (널찾기)
- /tmp/sh.c 작성 & 컴파일
#include <stdio.h> int main() { setuid(0); system("/bin/sh"); }
>> 여기서부터는 일반사용자 계정에서 진행..
1. execl() 주소 알아내기
2. "/tmp/sh" 문자열 주소
3. 인자값 (NULL 찾기)
☞ RET 앞에서 브레이크 걸어줌! 마지막에 EBP를 기준으로 해서 스택 정보를 보려고!
☞ NULL인자값으로 점찍어둔 위치가 내가 넣은 문자열의 NULL 바이트 때문에 0x00000002에서 0x00000000으로 변함.
☞ 앞에 5개의 문장만 넣으면 자동으로 마지막 인자인 NULL이 스택에 들어있는 것과 같음.
4. 공격!
☞ perl문을 왜 " "로 감싸는가?? 기계어 도중에 0x0a(개행문자)가 존재. 도중에 개행으로 여길수 있음.
---> 고로 기계어를 따로 처리하지 않겠다는 의미로 양쪽에 "를 붙임.
☞ 직접 값을 넣지 않아도 스택상에 인자들이 순서대로 알맞게 존재한다면 실행되는것을 확인.
2) DEP & ASLR 우회
▣ 쉘코드를 실행하지 못하고 심지어 환경변수의 주소가 RANDOM 하다면??
- 뭘 고민해? 고정된 곳에 쓰면 되지!
☞ 고정된 주소 사이에 쓰면 됨!
- 근데 저 메모리에 어떻게 직접쓰니...?
---> 직접 못씀!!! 심볼릭 링크로 해당 파일을 실행하도록 해줄거얌!!
▣ 고정된 위치 확인하기
- export LANG 해주기
- 일단 프로그램을 시작해야 메모리상에 상주하니까 breakpoint를 이용해 시작은 시켜주자.
☞ 빨간상자안의 01을 "/tmp/sh"로 쓸거임. 다시 말하면 심볼릭 링크를 사용하여 01 바이트를 파일명으로 대체하여 쓰는 것임.
☞ 반드시 내가 쓰고자하는 위치의 바이트 뒤에 NULL바이트가 필요! (문자열의 끝이니까..)
☞ 01 바이트의 주소는 0x08048014임.
▣ 심볼릭 링크 생성
▣ 공격!!
- "\xa0\xca\x0a\x42" : execl() 주소
- "\x14\x80\x04\x08" 1개 : execl()의 RET (다음 실행할 주소) -> 뭐가 되든 노상관...
- "\x14\x80\x04\x08" : 0x01 / 심볼릭 링크를 통한 파일명 주소 (/tmp/sh)
i2sec 대구지점 23기 수료생.
'해킹&보안 > 시스템해킹&보안' 카테고리의 다른 글
[D+12] HEAP BOF (0) | 2017.04.13 |
---|---|
[D+11] 보호 기법 우회 (2) (0) | 2017.04.13 |
[D+9] 메모리 보호 기법 (0) | 2017.04.12 |
[D+8] 쉘 코드 제작 (심화) (0) | 2017.04.12 |
[D+7] 쉘 코드 제작 (0) | 2017.04.11 |