Phantom

[Bugbear] bugbear -> giant 풀이 본문

Pwnable/[Wargame]Load of Bof

[Bugbear] bugbear -> giant 풀이

Ph4nt0m_ 2015. 1. 7. 21:44
반응형


Colored By Color Scripter

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




저번 포스팅에 이에 RTL2번째입니다

이번에도 저번단계와 비슷한 문제입니다


쉘 획득 과정 페이로드



이번에는 popen으로 명령어를 파일 fp에 담습니다


먼저 권한이 없으므로 다음 코드를 수정합니다

fp = popen("/usr/bin/ldd /home/giant/assassin | 
                                               /bin/grep libc | /bin/awk '{print $4}'""r");

이것을


 fp = popen("/usr/bin/ldd /home/bugbear/giant | 
                                               /bin/grep libc | /bin/awk '{print $4}'""r");
이렇게 바꿉니다

그리고 popen안의 명령어들을 실행해보면 두 주소가 있습니다




이 두개의 주소를 더하면 execve의 주소가 나옵니다


execve함수란 다른 프로그램을 실행시키는 함수입니다 실행한 프로세스를 프로그램으로 바꾸어 주는 함수인데


system 함수와 execve함수의 차이점은 system함수의 경우 작업이 끝날 때까지

호출한 프로세스가 대기하다 계속 수행하고 execve는 호출 프로세스가 바뀐다는 점입니다

이제 system, exit /bin/sh의 주소를 알아내고 공격을 하면 됩니다




1
2
3
4
5
6
7
8
9
10
findsh.c
 
#include <stdio.h>
 
int main(int argc, char *argv[]){
        long shell;
        shell = 0x40058ae0;
        while(memcmp((void *)shell, "/bin/sh", 8)) shell++;
        printf("\"/bin/sh\" is at [ %#x ]\n",shell);
}

아 참 /bin/sh가 라이브러리에서 찾을 수 있는 것은 
system함수에서 내부적으로 /bin/sh -c를 사용하기 때문입니다
공격 코드 구성은 다음과 같습니다

NOP 

 execve

system 

exit 

/bin/sh 

argv 

NULL 


다음과 같은 구성을 한 이유는 execve함수의 인자를 맞춰서 실행하기 위함인데요

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

filename에 system이 들어가며 system의 인자를 넣어주고요 그 위에 execve의 다음인자로 argv를 사용합니다 그 다음에 NULL을 넣어주고요


그럼 명령문을 작성하기 위해 argv는 copied argv를 사용하고요 비어있는곳을 이용해 null을 구합니다


argv의 경우 argv[0], 프로그램의 이름이 담기는 부분의 주소를 찾아야 하는데 그 이유는

execve가 새로운 프로그램을 실행시키는 것이며 /bin/sh의 주소가 프로그램 이름이기 때문에 /home/bugbear/를 제외한 주소를 구해야 합니다

 

copied argv는 0xbffffff6을 사용하고 NULL은 0xbffffffc를 사용합니다




명령문 작성하기




명령이 실행되지 않는다 왜그럴까?

이유는 \x0a에 있다 execve의 주소를 넣는중에 \x0a라는 부분이 있는데 이것을 00으로 인식을한다

따라서 스크립트 양쪽에 더블쿼티( "")를 입력해야 한다



이로써 giant의 권한을 얻었다


반응형
Comments