본문 바로가기

pwn/HackCTF

Keygen

problem

제목부터 역연산이겠구나 싶은 문제입니다

이미 많은 사람들이 푼 문제이기도 하고 풀고 나서 다른 분들 write-up보고 아... 나 정말 이상하게 했네 싶어서 글로 남기려고 합니다

main

main함수를 보면 check_key함수에 입력한 문자열이 들어가고 반환 값이 1이면 되면 플레그를 출력해줍니다

check_key

check_key함수를 보면 encoding함수 호출 후 strcmp함수를 통해 문자열과 비교하여 같고 그때 반환 값인 0이 면 1(True)을 반환하게 됩니다

encoding

encoding함수의 경우 일련의 연산을 수행하게 됩니다 여기서 a1[i]가 입력한 문자열이고 v2의 초기 값은 72이고 첫 연산 이후 encode 된 값이 들어갑니다

 

결국 encode된 값과 비교하기 때문에 여러 결과가 나올 수 있습니다

그래서 결국 비교하는 문자열의 각 문자와 비교해주면 되는데 이전에 이런 비슷한 문제에서 입력하는 값이 플레그로 되어서 역연산을 쪼금 더 섬세(?)하게 해 줘야만 했는데 그 문제의 영향 때문인지 역연산 코드를 좀....ㅎ

#include <stdio.h>
#include <string.h>

typedef struct flag
{
        int count;
        char flag_table[10];
}FLAG;

int main(){
        char string[18] = "OO]oUU2U<sU2UsUsK";
        char encode = 72;
        int length = strlen(string);
        FLAG flag[18];
        int sub = 0;
        int count;
        for(int i = 0;  i < length; i++){
                                count = 0;
                for(int j = 0; j < 126; j++){
                        sub = ((j + 12) * encode + 17) % 70 + 48;
                        if(sub == string[i] && j > 45 && j < 126){
                                flag[i].flag_table[count] = j;
                                ++count;
                        }
                }

                if(count != 0){
                        flag[i].count = count;
                        encode = ((flag[i].flag_table[flag[i].count - 1] + 12) * encode + 17) % 70 + 48;
                }
                else{
                        while(1){
                                --i;
                                if(flag[i].count > 1){
                                        flag[i].count -= 1;
                                        encode = flag[i].flag_table[flag[i].count];
                                        break;
                                }
                        }
                }
        }


        for(int i=0; i< length; i++){
                printf("string[%d] (%c) %d: ", i, string[i], flag[i].count);
                        printf("%d(%c) ", flag[i].flag_table[flag[i].count - 1], flag[i].flag_table[flag[i].count - 1]);
                        printf("\n");
        }
        for(int i=0;i < length; i++){
                printf("%c", flag[i].flag_table[flag[i].count - 1]);
        }
        printf("\n");
}

어.... 그냥 하나의 답만이 존재하고 만약에 각 문자를 비교할 때 어떤 인덱스에서 같은 문자가 나오지 않으면 이전 문자로 돌아가서 조건에 맞는 다른 문자를 넣어 다시 수행하도록 해주는 코드입니다 

그리고 만약에 이전의 인덱스의 문자에서 조건에 맞는 문자가 오직 한 개만 존재한다면 그전의 인덱스로 이동하게 됩니다

./sol

그래서 해당 코드를 돌리면 "drd<lxqx{{tqxztzz"라는 문자열을 얻게 됩니다

하지만 해당 문제에서 개행까지 문자로 받기 때문에 strcmp를 할 경우 인덱스가 1 더 많은 값으로 비교되기 때문에 같지 않게 됩니다

exploit.py

그래서 해당문자열 뒤에 null 값을 추가하여 값을 보내도록 하여 해당 문제를 해결하였습니다

flag

어... 음... 네.. 조금 더 주어진 코드를 유심히 봤더라면 역연산 코드양이 많이 줄지 않았을까 싶습니다

'pwn > HackCTF' 카테고리의 다른 글

ezshell  (0) 2022.03.05
babyfsb  (0) 2022.02.10
Unexploitable #1  (0) 2021.10.19
poet  (0) 2021.08.12
BOF_PIE  (0) 2021.08.06