문제에서 주어진 실행파일을 IDA Pro7.5에서 실행하면 위 그림과 같이 sub_140001000 함수 결과가 참이 나오면 Correct가 출력된다.
return 1을 반환하기 위해서는 조건문이 거짓이 되어야 하므로 입력할 문자열을 input이라고 하고 140003000에 저장된 문자열을 buf라고 가정하면 input[i+1]+input[i]=buf[i]가 되어야한다.
input[i]를 구하기 위해서 식을 변형하면 아래 식과 같이 규칙이 존재한다.
input[0]-input[24]=buf[0]-buf[1]+buf[2]-buf[3]+...-buf[23]
input[1]+input[24]=buf[1]-buf[2]+buf[3]-buf[4]+...+buf[23]
중요한점은 입력할 문자열의 마지막은 널 바이트이므로 input[24]=0이다. 따라서 아래 식과 같이 input[i]를 구할 수 있다.
input[0]=buf[0]-buf[1]+buf[2]-buf[3]+...-buf[23]
input[1]=buf[1]-buf[2]+buf[3]-buf[4]+...+buf[23]
...
input[23]=buf[23]
x64dbg를 이용하여 140003000에 저장된 문자열을 확인하면 위 그림과 같이 바이트를 구할 수 있다.
#include <stdio.h>
#include <string.h>
void main()
{
char buf[] = {0xAD, 0xD8, 0xCB , 0xCB , 0x9D , 0x97 , 0xCB , 0xC4 , 0x92 , 0xA1 , 0xD2 , 0xD7 , 0xD2 , 0xD6 , 0xA8 , 0xA5 , 0xDC , 0xC7 , 0xAD , 0xA3 , 0xA1 , 0x98 , 0x4C , 0x00 };
int input[24]= { 0, };
for (int i = 0; i < 24; i++)
{
if (i % 2 == 0) //짝수
{
for (int j = i; j < 24; j++)
{
if (j % 2 == 0)
{
input[i] += buf[j];
}
if (j % 2 == 1)
{
input[i] -= buf[j];
}
}
printf("%c", input[i]);
}
if (i % 2 == 1) //홀수
{
for (int j = i; j < 24; j++)
{
if (j % 2 == 0)
{
input[i] -= buf[j];
}
if (j % 2 == 1)
{
input[i] += buf[j];
}
}
printf("%c", input[i]);
}
}
}
위 코드는 input[i]를 추출하는 코드이다. 해당 코드를 실행하면 플래그가 추출된다.
플래그: All_l1fe_3nds_w1th_NULL
'Reversing > 드림핵' 카테고리의 다른 글
[Dreamhack] rev-basic-8 (0) | 2021.04.12 |
---|---|
[Dreamhack] rev-basic-7 (0) | 2021.03.30 |
[Dreamhack] rev-basic-4 (0) | 2021.03.30 |
[Dreamhack] rev-basic-3 (0) | 2021.03.30 |
[Dreamhack] rev-basic-0 (0) | 2021.03.24 |
댓글