Wargame/LOB

LOB giant Write-Up

0xe82de_ 2019. 8. 1. 07:23
728x90
728x90
728x90

LOB giant 풀어보자.

 

[사진 1]

주어진 코드를 보면 첫 번째 인자가 "\xbf" 또는 "\x40"으로 시작하면 프로그램을 종료시킨다. 아래에서 확인하겠지만 첫 번째 인자의 44~47번째 값들은 ret를 변조시키는데 ret를 buffer 변수, 환경변수, argv, 공유 라이브러리 주소로 변조할 수 없다는 뜻이다.

 

 

[사진 2]
[사진 3]

먼저 main 함수의 어셈블리어 코드를 보면 strcpy 함수를 호출하기 전에 ebp-0x28 주소를 eax 레지스터에 저장한다. 즉, 이 곳이 buffer 변수의 시작점이다.

 

 

[사진 4]

따라서 스택은 위와 같이 형성될 것이고, buffer 변수부터 44bytes의 값을 입력하면 ebp까지 변조할 수 있다.

임의의 값 44bytes를 입력하고 4bytes를 입력하면 ret를 변조할 수 있지만 [사진 1]에서 확인했듯이 buffer 변수, 환경변수, argv 인자, 공유 라이브러리 주소를 입력할 수 없다. ret 명령어를 이용하여 풀어보자.

 

ret 명령어의 기능은 다음과 같다.

 1) pop eip // 현재 esp가 가리키는 스택의 값을 eip 레지스터에 저장한다.

 2) jmp eip // eip 레지스터에 저장된 값은 다음에 실행할 명령어이므로 해당 명령어로 점프한다.

 

즉, ret 값을 명령어 ret의 주소로 변조하면 ret 명령어가 수행되고 ebp+8 지점의 값이 eip 레지스터에 저장될 것이다.

따라서 buffer 변수에 shellcode를 저장하고 ebp+8 지점에 buffer 변수의 주소를 입력하면 된다.

 

 

[사진 5]

먼저 명령어 ret의 주소를 찾아야 하는데 objdump 명령어로 쉽게 찾을 수 있다. [사진 5]에서 확인할 수 있는 모든 ret 명령어의 주소를 사용할 수 있다. 여기선 0x08048336 주소를 사용한다.

 

 

[사진 6]

디버깅하기 위해 assassin 파일을 다른 이름(kssassin)으로 복사해준다. 입력 값으로 임의의 값 "\x90" 44bytes와 명령어 ret의 주소로 ret 지점까지 변조하고 ebp+8 지점은 문자열 "ABCD"를 넣었다.

위와 같이 buffer 변수의 시작 주소는 0xbffffac0이고 ebp까지 변조된 것을 확인할 수 있다. 그리고 ret는 명령어 ret의 주소로 변조되었고, ebp+8 지점인 0xbffffaf0 주소도 "ABCD" 문자열로 변조되었다.

 

 

[사진 7]

따라서 nop "\x90" 19bytes와 shellcode 25bytes를 입력하여 ebp까지 변조하고 명령어 ret의 주소로 ret 지점을 변조한 후 buffer 변수의 주소로 ebp+8 지점을 변조하였다. 사용한 shellcode는 다음과 같다.

\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

하지만 공격이 성공하지 않고 core 파일이 생성되었다. core 파일을 gdb로 실행하여 확인해보면 실제 buffer 변수의 주소가 0xbffffc46이다. 이유는 gdb를 통해 실행하면 gdb 환경변수 등과 같은 이유로 실제 주소와 차이날 수 있다.

 

[사진 8]

위와 같이 정확한 buffer 변수의 주소로 바꿔주면 assassin 계정의 password를 확인할 수 있다.

728x90
728x90