튜기's blogggg

LOB nightmare -> xavius

by St1tch



코드를 보면 buffer에 fgets함수를 통해 256바이트만큼 표준입력을 받는다.

gdb를 통해 보면 buffer의 주소는 ebp-40이다.

따라서 buffer+47의 ret주소의 최상위바이트이다.

이 최상위 바이트가 '\xbf', '\x08'이 되면 함수가 종료된다.

즉 스택이나 data, bss, dtors 섹션 등을 이용 할 수가 없다.


이제 남은 곳은 힙 부분과 memset에서 제외된 buf-40 ~ buf까지 40byte이다.

근데 buf는 스택부분이라 \xbf로 주소가 시작한다.

따라서 힙 부분에서 쓸만한 곳을 찾아야한다.


코드를 보면 fgets함수에서 stdin 표준스트림을 이용해서 입력을 받는다.

표준 입력을 받을때는 read함수를 이용해 엔터를 칠때까지 임시입력버퍼에 저장을 해놓고 buffer에 저장을 한다.

근데 fgets이후에 입력버퍼를 초기화 해주지않는다.

버퍼를 초기화할때는 보통 출력버퍼는 fflush함수를, 입력버퍼는 getchar()등을 이용해서 초기화 해주는 방법이있다.

strace를 이용해서 시스템콜을 추적해보았다.




mmap을 이용해서 0x40015000영역을 4096바이트 만큼 할당한다.

그리고 read함수로 입력을 받는다.


12345를 입력을 한 이후이다.

다시 mmap을 이용해서 0x40016000영역을 4096바이트만큼 할당한다.

그리고 write함수로 표준 출력을 한다.

 여기서 munmap함수를 이용해서 출력버퍼로 사용했던 부분을 회수한다.


여기서 종료시까지 입력버퍼로 사용했던 부분을 회수를 하지 않는다.

따라서 입력버퍼의 주소를 ret주소로 사용을 했다.

입력을 하는 그대로 입력버퍼에 저장이 되기 때문에 그냥 shellcode + ret로 하면 쉘이따진다.

여기서 입력버퍼의 주소가 0x40015000인데 \x00이 들어가면 \x00이후의 byte들이 안들어가기 때문에 shellcode앞에 적당이 \x90을 넣어서 ret주소를 더해주었다.


[exploit code]

(python -c 'print "\x90" * 19 + "\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" + "\x05\x50\x01\x40"';cat) | ./xavius







블로그의 정보

튜기's blogg(st1tch)

St1tch

활동하기