[LOB] assassin -> zombie_assassin

Posted by dw0rdptr
2015. 4. 18. 03:01 System/LOB
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
27
28
29
30
31
32
33
34
/*
        The Lord of the BOF : The Fellowship of the BOF
        - zombie_assassin
        - FEBP
*/
 
#include <stdio.h>
#include <stdlib.h>
 
main(int argc, char *argv[])
{
    char buffer[40];
 
    if(argc < 2){
        printf("argv error\n");
        exit(0);
    }
 
    if(argv[1][47== '\xbf')
    {
        printf("stack retbayed you!\n");
        exit(0);
    }
 
        if(argv[1][47== '\x40')
        {
                printf("library retbayed you, too!!\n");
                exit(0);
        }
 
    // strncpy instead of strcpy!
    strncpy(buffer, argv[1], 48); 
    printf("%s\n", buffer);
}
cs


소스를보면 strncpy로 인자가 48바이트로 제한돼 ret까지밖에 덮지 못한다. 이렇게 스택과 라이브러리를 필터링하고 ret이후로 덮어쓸 수 없을 때 fake ebp 기법을 활용한다


fake ebp란 sfp에 buffer-4의 주소를 덮어 ebp를 버퍼주소로 옮기고 ret에 leave주소를 덮어 함수 에필로그 과정을 한번 더 수행해 sfp를 변조해 만든 가짜 ebp로 esp가 가게 만들어 우회하는 기법이다. buffer-4 인 이유는 leave를 한번 더 수행할 때 pop ebp 과정으로 인해 esp+4가 되기 때문에 버퍼의 시작주소에 맞추기 위함이다


[system()][dummy(or exit())]["/bin/sh"][28byte dummy][buffer-4][leave]

                                                                                 ↓         ↓

                                                                                sfp       ret


system()과 /bin/sh 주소구하는 방법 전레벨과 같으므로 생략

buffer-4와 leave의 주소를 구하자


leave : 0x80484df

buffer-4 : 0xbffffa60-4 = 0xbffffa5c

[0x40058ae0][AAAA][0x400fbff9][AAA...AA(28byte)][0xbffffa5c][0x80484df]


페이로드와 Password


'System > LOB' 카테고리의 다른 글

[LOB] succubus -> nightmare  (0) 2015.06.01
[LOB] zombie_assassin -> succubus  (0) 2015.04.30
[LOB] giant -> assassin  (0) 2015.04.14
[LOB] bugbear -> giant  (2) 2015.04.14
[LOB] darkknight -> bugbear  (0) 2015.04.12

[LOB] giant -> assassin

Posted by dw0rdptr
2015. 4. 14. 17:22 System/LOB

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
27
28
29
30
31
32
33
34
35
36
/*
        The Lord of the BOF : The Fellowship of the BOF
        - assassin
        - no stack, no RTL
*/
 
#include <stdio.h>
#include <stdlib.h>
 
main(int argc, char *argv[])
{
    char buffer[40];
 
    if(argc < 2){
        printf("argv error\n");
        exit(0);
    }
 
    if(argv[1][47== '\xbf')
    {
        printf("stack retbayed you!\n");
        exit(0);
    }
 
    if(argv[1][47== '\x40')
    {
        printf("library retbayed you, too!!\n");
        exit(0);
    }
 
    strcpy(buffer, argv[1]); 
    printf("%s\n", buffer);
 
    // buffer+sfp hunter
    memset(buffer, 044);
}
cs

no stack, no RTL로 ret에 스택과 공유라이브러리 주소를 쓰지 못하게 됐다


하지만 ret에 ret주소를 덮게되면 esp+4에 있는 주소를 실행해 우회할 수 있다.

[ret주소][system()주소][dummy]["/bin/sh"] 이렇게 페이로드를구성한다면


higher address

----------

   /bin/sh

----------

   dummy

----------

    system

------------

       ret

------------  <- esp

lower address

ret가 pop eip, jmp eip 명령을 수행한다는것은 알고 있을것이다.

pop eip를 할 때 eip에 ret주소가 들어가고 jmp eip를하면 ret로 돌아오지만 esp는 pop명령으로 인해 +4가 되어 있는 상태다


higher address

----------

   /bin/sh

----------

   dummy

----------

    system

------------ <- esp

       ret

------------  

lower address


현재 ret주소로 다시 돌아왔으니 ret명령이 또한번 수행된다

pop eip, jmp eip를 수행하면 eip에는 system함수의 주소가 들어가고, jmp로 system함수를 실행해 /bin/sh가 실행된다



gdb로 main함수에서 ret주소를 찾자

ret : 0x804851f

system() : 0x40058ae0

/bin/sh : 0x400fbff9

system함수와 /bin/sh를 구하는 방법은 전레벨에서 설명이 되어있으니 건너뛰겠다



페이로드와 Password


'System > LOB' 카테고리의 다른 글

[LOB] zombie_assassin -> succubus  (0) 2015.04.30
[LOB] assassin -> zombie_assassin  (0) 2015.04.18
[LOB] bugbear -> giant  (2) 2015.04.14
[LOB] darkknight -> bugbear  (0) 2015.04.12
[LOB] golem -> darkknight  (0) 2015.04.11

[LOB] bugbear -> giant

Posted by dw0rdptr
2015. 4. 14. 16:34 System/LOB
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/*
        The Lord of the BOF : The Fellowship of the BOF
        - giant
        - RTL2
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
 
main(int argc, char *argv[])
{
    char buffer[40];
    FILE *fp;
    char *lib_addr, *execve_offset, *execve_addr;
    char *ret;
 
    if(argc < 2){
        printf("argv error\n");
        exit(0);
    }
 
    // gain address of execve
    fp = popen("/usr/bin/ldd /home/giant/assassin | /bin/grep libc | /bin/awk '{print $4}'""r");
    fgets(buffer, 255, fp);
    sscanf(buffer, "(%x)", &lib_addr);
    fclose(fp);
 
    fp = popen("/usr/bin/nm /lib/libc.so.6 | /bin/grep __execve | /bin/awk '{print $1}'""r");
    fgets(buffer, 255, fp);
    sscanf(buffer, "%x", &execve_offset);
    fclose(fp);
 
    execve_addr = lib_addr + (int)execve_offset;
    // end
 
    memcpy(&ret, &(argv[1][44]), 4);
    if(ret != execve_addr)
    {
        printf("You must use execve!\n");
        exit(0);
    }
 
    strcpy(buffer, argv[1]); 
    printf("%s\n", buffer);
}
cs

코드가 복잡해졌다. execve의 주소를 구하고 ret를 execve함수의 주소로 덮어쓰지 않으면 프로그램이 종료된다


execve는 호출한 프로세스를 새로운 프로세스로 변경한다. 이때 환경변수 정보를 추가 가능하다


프로토타입

execve (const char *filename, char *const argv[], char *const envp[])

첫번째 인자 : 실행시킬 파일명

두번째 인자 : 전달할 인자값 (포인터배열)

세번째 인자 : 환경변수 (NULL을 주면됨)


ret에 execve의 주소를 덮으면

(lower address) [execve()][execve의 ret][인자1][인자2][인자3] (higher addess)


[execve()][system()][exit()]["bin/sh"][NULL]

execve함수로 exit함수를 실행하면 바로 종료해버리면서 ret에있는 system함수를 실행하고 두번째 인자로 전달한 /bin/sh이 실행된다.


system() : 0x40058ae0

execve() : 0x400a9d48

exit() : 0x400391e0

NULL : 0xbffffffc (스택끝부분에 있는걸 씀)

/bin/sh : 0x400fbff9 ( darkknight에서 구한 주소)



페이로드와 Password


*exit주소를 쓰지 않고 dummy로 채워도 쉘을 딸 수 있지만 dummy로 채웠을 경우 쉘을 나가면 세폴 오류가 뜬다는 차이점이 있다

 


'System > LOB' 카테고리의 다른 글

[LOB] assassin -> zombie_assassin  (0) 2015.04.18
[LOB] giant -> assassin  (0) 2015.04.14
[LOB] darkknight -> bugbear  (0) 2015.04.12
[LOB] golem -> darkknight  (0) 2015.04.11
함수의 프롤로그(prologue) 및 에필로그(epilogue)  (0) 2015.04.10