본문 바로가기

WARGAME/smch ctf

SMCH CTF - Rock Paper scissors(EZ)

 

 

이번 문제는 바이너리가 아닌 무슨 소스코드를 다운받는거 같다. 한번 코드를 다운 받아 보면,

 

 

 

 

요런 C언어 소스코드가 다운 받아짐을 확인 할 수 있다. 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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <ctype.h>
 
void get_flag(){
    system("cat flag");
}
 
int rps(){
    int computer=rand()%3,len,player=-1,i=0;
    char input[10]={0,};
    switch(computer){
        case 0:
            puts("My choice >Rock");
            break;
        case 1:
            puts("My choice >Paper");
            break;
        case 2:
            puts("My choice >Scissors");
            break;
    }
    printf("Your input(Rock, Scissors, Paper) >");
    len = read(STDIN_FILENO,input,10);
    if(input[len-1]=='\n')  input[len-1]='\0';
    while(input[i]){
        input[i]=toupper(input[i]);
        i++;
    }
    if(!strcmp(input,"ROCK"))   player=2;
    if(!strcmp(input,"SCISSORS"))   player=1;
    if(!strcmp(input,"PAPER"))  player=0;
    if(player==-1)return 0;
    if(player==computer){
        return 1;
    }
    else{
        puts("Seriously??");
        return 0;
    }
}
 
void intro(){
    puts("===== Play a game with me! =====");
    puts("Do you know rock paper scissors?");
    puts("It's a simple game.. Rock beats scissors,");
    puts("And scissors beat paper.");
    puts("Finally, paper beats rock.");
    puts("So simple rule.. if you win 100times, I'll just give you flag");
}
 
int main(){
    setvbuf(stdin,0,2,0);
    setvbuf(stdout,0,2,0);
    srand(time(NULL));
    int cnt=0;
    intro();
    while(1){
        printf("\nYou have won %d times.\n",cnt);
        if(cnt >= 100){
            get_flag();
            exit(0);
        }
        cnt += rps();
    }
    exit(0);
    return 0;
}
 

 

 

코드를 해석해보면  "Rock", "Scissors", "Paper" 중 무작위로 하나를 보여주고 프로그램이 "Rock"이면, "Paper",

"Siccors"면 "Rock", "Paper"면 " Siccors"를 입력해서 즉, 가위바위보에서 이기면 1점을 얻는다. 그리고 총 100번을 이기면

flag를 얻게 되는 방식인데 물론 100번 손수 다 입력해서 flag를 얻을 수도 있겠지만, pwntools를 활용하면,

아~~주 쉽게 flag를 쓱싹 할 수 있당. 

 

우선 저 프로그램 컴파일후 실행 시켜보면,

 

 

 

 

"My choice >(프로그램이 낸 값)"이라는 문자열과 밑에 줄에는 우리가 입력을 할 수가 있당 예시로 위와 같이 프로그램이 

"Scissors"를 냈고 내가 "Rock"을 입력으로 넣으면 밑에 내가 한번 이겼다는 문자열과 함께 또 다시 프로그램이 낸 값과 내가 입력을 할 수

있게 된당 이제 내가 짠 익스코드를 보면,

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from pwn import *
 
i=0
 
p=remote("ssh.luxroot.com"9006)
 
while i<100:
 
        p.recvuntil("My choice >")
        data=p.recvuntil("\n")[:-1]
 
        p.recvuntil("Your input(Rock, Scissors, Paper) >")
 
        if data=="Rock":
                p.sendline("Paper")
        elif data=="Scissors":
                p.sendline("Rock")
        elif data=="Paper":
                p.sendline("Scissors")
        i=i+1
 
 
p.interactive()
 

 

 

remote로 nc 서버랑 연결한 다음 while문을 100번 돌리면서 recvuntil함수로 "My choice"까지 받아서 저장하지 않고 버린당 그럼 그줄에 남는 문자열은 프로그램이 낸 값만 남게될 거고, 다음 한번더 recvuntil함수를 통해 개행문자"\n"전까지인 데이터를 담는다. 즉 프로그램이 낸 값만 문자열로 data라는 변수에 저장이 된당 이후 한번더 recvuntil함수로 "Your input(Rock, Scissors, Paper) >" 까지 걸러낸 다음,

프로그램이 낸 값에 따라 sendline함수로 데이터를 보낸당 이렇게 100돌리고 나면 위과 같이 flag가 잘 나옴을 확인 할 수 있다.

 

 

 

 

 

 

FLAG : flag{Y0u_kn0w_'bout_s0ck3t_pro9ramm1n9!!}

'WARGAME > smch ctf' 카테고리의 다른 글

SMCH CTF - BOF_ret  (0) 2019.11.09
SMCH CTF - Calc  (0) 2019.11.09
SMCH CTF - BOF4  (0) 2019.11.08
SHCH CTF - BOF3  (0) 2019.11.03
SMCH CTF - BOF2 (EZ)  (0) 2019.11.03