본문으로 바로가기

해커스쿨 LOB golem 풀이, write-up

category Wargame/LOB 2018. 8. 30. 16:57

golem --- cup of coffee



우선 darkknight의 디렉터리를 확인한다.





darkknight라는 의심스러운 파일이 존재한다. darkknight는 darkknight의 권한을 가지고 있고, setuid가 걸려있는 파일이다.



darkknight.c를 가지고 darkknight 파일을 만들었을 가능성이 있기 때문에, darkknight.c 파일을 본 뒤 어떤 취약점을 가지고 있는지 확인해보자.





인자가 없으면 "argv error\n"를 출력하고 종료한다.



1
2
3
4
5
if(argc<2)
{
    printf("argv error\n");                                                            
    exit(0);
}
cs



첫 번째 인자를 problem_child의 파라미터로 전달한다.



1
problem_child(argv[1]));                                                            
cs



buffer를 선언하고 파라미터를 buffer에 복사한 뒤 출력한다.



1
2
3
char buffer[40];
strncpy(buffer, src, 41);                                                            
printf("%s\n", buffer);
cs



darkknight의 메모리 구조를 예상해보면 아래와 같이 그릴 수 있다.




실제 변수가 할당될 때 gcc가 최적화를 위해 자동적으로 dummy를 생성할 수 있다.


gdb를 이용하여 darkknight를 분석해보자. darkknight를 gdb로 실행하는 도중 permission denied가 발생하면 cp 명령을 이용해 파일을 복사하면 된다. 현재 user의 권한으로 똑같은 파일을 가질 수 있기 때문이다.





위와 같이 darkknightcp가 golem의 권한으로 복사된 것을 확인할 수 있다.


dummy가 생성되었는지 gdb를 통해 확인해보자.





dummy가 추가적으로 생성되지 않고 정확히 40(0x28) byte가 생성된것을 확인할 수 있다.


darkknight.c를 보면 FPO(Frame Pointer Overflow) 라는 힌트를 주었다. FPO 대해서 공부해보자.



우선 가장 기본적인 스택 프레임의 프롤로그(prologue)와 에필로그(epilogue), leave, ret에 대해 공부해야한다.


프롤로그


push ebp

mov esp, ebp


에필로그


mov ebp, esp

pop ebp


leave 명령어는 에필로그를 의미한다.


mov ebp, esp

pop ebp


ret


pop eip

jmp eip





SFP에는 main의 ebp가 저장되어 있을것이다.

intel cpu는 little endian 방식을 이용하고 있다.

SFP[0]를 수정하면 main ebp의 마지막 1바이트를 수정할 수 있는 것이다.

따라서 SFP[0]를 통해 수정한 주소(ebp) + 4 위치에 쉘 코드의 주소가 존재하면 쉘을 실행할 것으로 예상할 수 있다.



problem_child() 함수의 SFP = 0xbffffa41, RET = 0x0804849e 이다.

41 byte의 문자를 strcpy를 통해 복사했기 때문에 SFP 1 byte(A, 0x41)가 overwrite 되었다.


아래의 그림을 보면 buffer의 시작주소는 0xbffffa9c(0xbffffc37)이다.

우리가 SFP를 0xbffffa98로 수정하면 RET은 0xbffffa9c번지에 있다고 생각한다.

따라서 우리는 0xbffffa9c번지에 쉘 코드를 삽입하면 된다.





공격 코드는 아래와 같다.


25 byte의 쉘 코드 + 15 byte의 NOP padding + 1 byte의 SFP overwrite