argv 값을 strcpy로 buffer에 저장하여 오버플로우가 일어나는 전형적인 코드이다.

문제 서버는 레드헷 6.2버전으로 매우 오래된 버전이기 때문에 문자열이 깨지는 것을 방지하기 위해서 bash2 쉘을 실행해 주었다.

우선 buffer에서 ebp까지의 거리를 확인하기 위해 gdb로 disas 해보면 buffer의 주소가 ebp로부터 0xffffff00 떨어진 것을 알 수 있다.

즉, 10진수로 계산하면 ebp에서 256byte 떨어진 곳에 ebp가 있고 ebp를 덮기 위해서는 260byte의 더미 값이 필요하다.
쉘을 띄우기 위해 쉘코드를 사용하는 방법이 있지만 왜 그런지 계속 실패해서 system함수를 실행하는 방법으로 시도해보았다.
system함수의 인자값으로 들어갈 임의의 데이터를 심볼릭 링크를 걸어 bash쉘이 실행되도록 하였으나 이 방법 역시 실패했다. 분명 심볼릭 링크가 걸린 파일만 실행하면 쉘이 띄워지지만 이상하게 실제 공격만하면 알 수 없는 명령어라고 나온다.
마지막으로 성공한 방법은 system 함수의 인자 값을 직접 지정해주는 방법이다.
system 함수의 주소를 알아내기 위해 gremlin 파일에서 gdb로 run을 하면 권한이 없다고 나오길래 다른 임의의 파일을 만들어 확인하였다.

system 함수의 주소는 0x40058ae0이다. => “\xe0\x8a\x05\x40”

system 함수의 인자 값으로 들어갈 /bin/sh 문자열을 찾기 위해 system 함수의 주소부터 문자열을 검색했다.
/bin/sh 주소는 0x400fbff9 => “\xf9\xbf\x0f\x40”
함수를 호출할 때 복귀 주소를 저장하기 위해 pop eip 명령어가 실행된다. 따라서 system 함수 뒤에는 eip로 넣을 4byte 더미 값이 필요하다. 그리고 argv 값으로 전달될 /bin/sh 주소를 넣는다.
./gremlin `perl -e 'print "a"x260,"\xe0\x8a\x05\x40","aaaa","\xf9\xbf\x0f\x40"'`

gremlin password