[DREAMHACK] rev-basic 4~6
https://s0scod3.tistory.com/13
[DREAMHACK] rev-basic 1~4
DREAMHACK에서 제공하는 리버스 엔지니어링 기초 문제 4개를 풀어보자. 네 문제 모두 비슷한 구조를 갖고 있어 하나를 해결하면 다음 문제는 쉽게 접근할 수 있다. 따라서 1번 문제를 자세하게 설명
s0scod3.tistory.com
위 게시물에 이어서 rev-basic 4~6번 문제를 풀어보자.
https://dreamhack.io/wargame/challenges/18
rev-basic-4
Reversing Basic Challenge #4 이 문제는 사용자에게 문자열 입력을 받아 정해진 방법으로 입력값을 검증하여 correct 또는 wrong을 출력하는 프로그램이 주어집니다. 해당 바이너리를 분석하여 correct를 출
dreamhack.io
__int64 __fastcall sub_140001000(__int64 a1)
{
int i; // [rsp+0h] [rbp-18h]
for ( i = 0; (unsigned __int64)i < 0x1C; ++i )
{
if ( ((unsigned __int8)(16 * *(_BYTE *)(a1 + i)) | ((int)*(unsigned __int8 *)(a1 + i) >> 4)) != byte_140003000[i] )
return 0i64;
}
return 1i64;
}
16 * a1[i] | a1[i]>>4 와 byte_140003000[i]가 같은지 0x1C번 비교한다. 16 * a1[i]는 a1[i]<<4 와 같다.
a1[i]<<4 | a1[i]>>4 와 byte_140003000[i]가 같은지 0x1C번 비교한다. 연산 a1[i]<<4 | a1[i]>>4 을 수행하면 byte_140003000[i]는 아래처럼 변할 것이다.
ABCDEFGH -> EFGHABCD
Python으로 구현하자.
arr = [0x24, 0x27, 0x13, 0xC6, 0xC6, 0x13, 0x16, 0xE6, 0x47,
0xF5, 0x26, 0x96, 0x47, 0xF5, 0x46, 0x27, 0x13, 0x26,
0x26, 0xC6, 0x56, 0xF5, 0xC3, 0xC3, 0xF5, 0xE3, 0xE3, 0]
for i in range(0x1C):
print(chr((arr[i] << 4 | arr[i] >> 4) % (16 * 16)), end="")
Flag : DH{Br1ll1ant_bit_dr1bble_<<_>>}
https://dreamhack.io/wargame/challenges/19
rev-basic-5
Reversing Basic Challenge #5 이 문제는 사용자에게 문자열 입력을 받아 정해진 방법으로 입력값을 검증하여 correct 또는 wrong을 출력하는 프로그램이 주어집니다. 해당 바이너리를 분석하여 correct를 출
dreamhack.io
__int64 __fastcall sub_140001000(__int64 a1)
{
int i; // [rsp+0h] [rbp-18h]
for ( i = 0; (unsigned __int64)i < 0x18; ++i )
{
if ( *(unsigned __int8 *)(a1 + i + 1) + *(unsigned __int8 *)(a1 + i) != byte_140003000[i] )
return 0i64;
}
return 1i64;
}
a1[i+1] + a1[i] 와 byte_140003000[i]가 같은지 24번 비교한다. hex-view에서 확인한 byte_140003000[i]는 아래와 같다.
AD D8 CB CB 9D 97 CB C4 92 A1 D2 D7 D2 D6 A8 A5 DC C7 AD A3 A1 98 4C 00
DP스럽게 접근하자. 점화식이 주어진 DP문제로 바라보면 쉽게 해결할 수 있다.
점화식 유추
PW[23] = arr[23] - PW[24] = 0
PW[22] = arr[22] - PW[23]
PW[21] = arr[21] - PW[22]
...
점화식 PW[23-i] = arr[23-i] - PW[24-i] 를 얻을 수 있다. 주의할 점은, PW[24]를 고려하여 배열의 크기를 1 크게 잡아야 한다.
arr = [0xAD, 0xD8, 0xCB, 0xCB, 0x9D, 0x97, 0xCB, 0xC4,
0x92, 0xA1, 0xD2, 0xD7, 0xD2, 0xD6, 0xA8, 0xA5,
0xDC, 0xC7, 0xAD, 0xA3, 0xA1, 0x98, 0x4C, 0x00, 0x00, 0x00]
PW = [0 for _ in range(25)]
for i in range(0x18):
PW[23-i] = arr[23-i]-PW[24-i]
for i in range(0x18):
print("{}".format(chr(PW[i])), end="")
Flag : DH{All_l1fe_3nds_w1th_NULL}
https://dreamhack.io/wargame/challenges/20
rev-basic-6
Reversing Basic Challenge #6 이 문제는 사용자에게 문자열 입력을 받아 정해진 방법으로 입력값을 검증하여 correct 또는 wrong을 출력하는 프로그램이 주어집니다. 해당 바이너리를 분석하여 correct를 출
dreamhack.io
__int64 __fastcall sub_140001000(__int64 a1)
{
int i; // [rsp+0h] [rbp-18h]
for ( i = 0; (unsigned __int64)i < 0x12; ++i )
{
if ( byte_140003020[*(unsigned __int8 *)(a1 + i)] != byte_140003000[i] )
return 0i64;
}
return 1i64;
}
기존 문제와 달리 배열 2개를 사용한다.
byte_140003020[a1[i]] 와 byte_140003000[i] 를 비교한다. 이중 반복문으로 만족하는 값을 완전탐색하면 구할 수 있다.
li1 = [0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B,
0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26,
0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2,
0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED,
0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F,
0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC,
0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14,
0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D,
0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F,
0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11,
0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F,
0xB0, 0x54, 0xBB, 0x16]
li2 = [0x00, 0x4D, 0x51, 0x50, 0xEF, 0xFB, 0xC3, 0xCF, 0x92, 0x45, 0x4D, 0xCF,
0xF5, 0x04, 0x40, 0x50, 0x43, 0x63]
for i in range(0x12):
for j in range(256):
if li1[j] == li2[i]:
print(chr(j), end="")
Flag : DH{Replac3_the_w0rld}