본문 바로가기

[Wargame Write-up]/OverTheWire

[OverTheWire] [Leviathan] Level 1 → Level 2

leviathan1 계정에 접속해보면, 다음 ELF 파일 하나가 존재한다.

소유자는 leviathan2로, setuid가 걸려있는 파일이다.

실행해보면 패스워드를 요구한다.

 

 

디버깅을 위해, gdb를 실행한다.

 

가장 먼저 실행한 set disassembly-flavor intel 명령은 어셈블리어를 intel 문법으로 설정한다.

 

우선 흐름을 분석해보자.

 

<main+82>~<main+100>에서 password를 3글자 입력받는다. 몇 글자를 입력하든, 3글자만 인식한다.

<main+105>~<main+128>에서 strcmp 함수의 인자를 설정한다.

역순으로 push되므로, [esp+0x18]이 2번째 인자, [esp+0x14]가 첫번째 인자가 된다.

<main+129>~<main+150>에서 strcmp 함수의 결과에 따라 분기한다.

 

 

 

strcmp의 결과가 0 즉, 두 문자열이 같으면, jne문을 무시하고, system("bin/sh");를 leviathan2의 권한으로 실행한다.

결과가 0이 아니면, puts("Wrong password, Good Bye ..."); 라는 메시지를 출력하고 종료한다.

 

 

 

그래서, 패스워드는 무엇이란 말인가?

 

답은 strcmp 인자에 있다. 즉, [esp+0x14], [esp+0x18] 중 하나는 사용자 입력 문자열, 하나는 정답이 된다.

 

그것을 판단하는 건 좀더 앞쪽 구문을 보면 가능하다.

 

 

 

밑줄 친 곳을 보면, [esp+0x14]부터 getchar()의 결과를 넣으므로, 사용자 입력 문자열,

[esp+0x18]은 하드코딩된 정답 문자열이 된다. 즉, 0x786573이 password이며,

이것을 big-endian 문자열로 치환하면, sex가 된다.

 

linux에선 byte 배열을 little-endian 방식으로 하기 때문에, 거꾸로 읽어야 한다.

 

gdb를 종료하고, 맞는지 확인해보자.

 

분석한 대로 leviathan2로 쉘이 실행되었다.

 

 

그 다음, leviathan2의 패스워드를 확인하기 위해, 웹페이지에 기재된 디렉터리에서 파일 내용을 확인하면 된다.