2017/01/11 - [Study :)/FTZ] - [해커스쿨] FTZ level10 풀이과정
힌트!!! 보자고~
attackme 라는 파일이 보이고, 힌트에는 어떤 소스코드가 들어있다.
attackme 를 실행시켜 보니. 역시 소스코드데로 실행된다. 즉, 힌트가 attackme의 소스코드 인것이다.
그러면 이 문제는 어떻게 풀어야 될까...
소스 코드를 보니 단순히 256byte의 str배열을 선언하고 setreuid를 실행하고 argv[1]의 인자값을 str에 복사하고 str를 출력하는게 끝이다.
그런데.. strcpy를 사용하는 것을 보니 이또한 버퍼 오버플로우에 취약하다.
level9 풀이(http://eunice513.tistory.com/54)를 보면 Buffer Overflow에 대한 설명이 들어있다.
그래서 버퍼 오버플로우로 접근해보자. 먼저 gdb로 attackme를 파헤쳐 보자.
그런데 attackme의 권한을 보면 일반사용자는 어떠한 권한도 없다. 그래서 힌트의 내용을 그대로 복사해서 새로운 파일을 하나 만들자.
새로 만든 /home/level11/tmp/attackme를 gdb로 파헤쳐 보자.
<main+3> 부분을 보면 16진수로 0x108만큼 공간을 할당한다. 0x108은 10진수로 264이다. 분명 우린 256byte만큼 배열을 선언했는데 gcc로 컴파일하니 264만큼 공간을 할당한다. 왜그런지는 gcc에 대해 자세히 몰라 패스~ 나중에 검색해보자.
메모리구조는 str[256]만큼 쌓이고, dummy[8]쌓이고, SFP[4], RET[4] 이렇게 쌓이게 된다.
버퍼 오버플로우 공격은 해커가 쉘코드를 집어넣고, RET부분에 쉘코드 시작주소를 넣어서 프로그램이 비정상 종료되면서 쉘코드를 실행시키게 하는 방법이다.
자 그럼 이제 문제를 풀어보자.
FTZ 풀이법에는 크게 2가지 방법이 있다. 첫번째로는 해당 프로그램 버퍼 내에 넣고 NOP코드를 넣고
RET부분에 버퍼내의 쉘코드 주소를 적는 방법이다.
두번째는 환경변수를 이용하는 방법이다. 환경변수안에 쉘코드를 넣어두고, 프로그램 버퍼 상에 쓰레기값을 넣다가 RET부분에 환경변수의 주소를 넣어주는 방식이다.
필자는 환경변수를 이용하는 방법으로 문제를 풀것이다. 이유는 버퍼상에 쉘코드를 올려서 쉘코드를 알라오는 방법은, 프로그램을 실행할때마다, 버퍼에 올리가는 주소가 바뀌고, 그때마다 쉘코드 시작 주소를 알아와야 되기 때문이다. 아직 필자는 실력이 미흡하기 때문에, 어떠한 것이 더 좋다 라고 말 할 수는 없다.
먼저 환경변수에 쉘코드를 등록하자. export 명령어를 입력하면 현재 환경변수에 등록되어 있는 정보들이 출력된다.
쉘코드를 추가해보자. (이 쉘코드는 단순히 bash쉘을 띄워주는 코드이다.)
shell code :
shell_code : \x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\xb0\x01\xcd\x80
앞에 NOP코드를 넣는 이유는 혹시라도 주소값이 달라지더라도 NOP슬라이딩으로 쉘코드에 접근 할 수 있게끔 한것이다.
다시 export 명령어를 쳐보면 추가한 환경변수가 보일 것이다.
이제 이 환경변수의 주소값을 알아오는 코딩을 해보자.
<사진 11-11>을 보면 환경변수의 주소값을 알아오는 코딩은 매~우 간단하다. 코딩한 프로그램을 실행하면 해당 환경변수의 주소값을 알아온다. 환경변수 값을 알아오는데 가~~끔 주소값이 다르게 알려주는 경우가 있어서 필자는 2-3번 정도 실행시켜서 같은 값이 나오는지 확인한다.
그럼 우리의 환경변수의 주소값은 0xbffffeb5 인 것으로 확인했다. 이제 문제의 버퍼에
str[256] + dummy[8] + SFP[4] = 268byte만큼 "A"값으로 채우고, RET[4]주소에 환경 변수값을 넣어보겠다.