DIMICTF_Gyeongje_write up.docx
(제일 인상깊었던 Reversing 200 점 문제만 올렸습니다 위에 파일이 원본입니다.)
전국청소년모의해킹대회 DIMICTF 2017 Reversing 200 문제 풀이입니다.
해당 문제는 ELF 파일이며 입력값을 input 받고 연산한 값과 일치할시 Correct문을 뿜는 간단한 크랙입니다.
IDA로 보면 위와 보이는것과 같이 v41 변수에 33개의 문자열을 입력 받는것을 볼수있습니다,
그리고 밑으로 가보면
ptrace 함수는 디버깅시 -1 아닐시에는 0의 리턴값을 반환함으로 디버깅을 감지합니다
그냥 edb로 분석하면서 EAX리턴값을 0으로 바꿔주면 됩니다.
그다음 첫번째 반복문에서 입력한 값 하나하나와 rand() 값을 xor연산 해주고 있습니다 (v5는 0이므로 생략하겠습니다.)
rand() 함수는 따로 srand에서 time(NULL)로 초기화를 해주거나 시드값이 주어지지 않았기 때문에 동일한 랜덤값들이
생성될 것입니다. 그래서 edb로 rand() 함수가 생성하는 값들을 33개의 각 4byte 값들을 찾아내었습니다
xor할때는 하위 1byte값만 xor 하므로 rand 값을 나열해 보자면
0x67, 0xc6, 0x69, 0x73, 0x51 ,0xff ,0x4a, 0xec, 0x29, 0xcd, 0xba, 0xab, 0xf2, 0xfb, 0xe3, 0x46, 0x7c, 0xc2, 0x54, 0xf8, 0x1b, 0xe8, 0xe7, 0x8d, 0x76, 0x5a, 0x2e, 0x63, 0x33, 0x9f, 0xc9, 0x9a, 0x66
총 33개의 값들이 들어있습니다.
v8배열에는 unsigned __int8 로 고쳐서 값을 나열해보면
172, 171, 30, 44, 166, 161, 156, 232, 255, 97, 9, 83, 37, 20, 130, 60, 165, 145, 165, 219, 233, 4, 96, 224, 26, 110, 97, 65, 183, 79, 83, 205, 27
의 값이 들어있습니다.
후에 v8 배열의 들어있는 값들과 위 반복문에서 xor연산한 입력받은 값과 다시 xor해 입력받은 문자열 배열의 [i+1] 값과 비교해주고 있습니다.
말로하기가 힘들어서.. 따로 정리해보자면
scan = 입력받은 33개의 문자열
rand = 각각 1byte 값의 33개 배열
v8 = 각각 1byte 값의 33개 배열
이라고 가정 해보면
(scan[i] ^ rand[i]) ^ v8[i] = (scan[i+1] ^ rand[i+1]) 가 됩니다.
Correct 문을 출력하고 따로 플래그를 출력하는 부분이 없는걸로 보아 input 에 넣는 값 자체가 플래그라고 생각했습니다.
그렇다면 입력받는 33개의 문자열을 구해야되므로 xor 역연산 해주면 됩니다.
scan[i] = scan[i+1] ^ rand[i+1] ^ v8[i] ^ rand[i] 가 일치함으로 따로 간단하게 브루트포스 해주었습니다.
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 | #include <stdio.h> #include <string.h> int main() { int rand[34] = { 0x67, 0xc6, 0x69, 0x73, 0x51 ,0xff ,0x4a, 0xec, 0x29, 0xcd, 0xba, 0xab, 0xf2, 0xfb, 0xe3, 0x46, 0x7c, 0xc2, 0x54, 0xf8, 0x1b, 0xe8, 0xe7, 0x8d, 0x76, 0x5a, 0x2e, 0x63, 0x33, 0x9f, 0xc9, 0x9a, 0x66, }; int v8[34] = { 172, 171, 30, 44, 166, 161, 156, 232, 255, 97, 9, 83, 37, 20, 130, 60, 165, 145, 165, 219, 233, 4, 96, 224, 26, 110, 97, 65, 183, 79, 83, 205, 27, }; char flag[34] = { 0, }; char a[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_{}?!"; char s = 'd'; for (int i = 0; i <= 32; i++) { for (int j = 0; j < strlen(a); j++) { if (s == (a[j] ^ rand[i + 1] ^ v8[i] ^ rand[i])) { flag[i] = a[j]; s = a[j]; j = 0; break; } } } printf("Flag is = %c%s\n", 'd', flag); return 0; } | cs |
'CTF' 카테고리의 다른 글
제 12회 정보보호올림피아드 예선풀이 (2) | 2017.10.30 |
---|---|
ASIS CTF Final 2017 Write up (ABC Reversing challenge) (0) | 2017.09.19 |
YISF 2017 본선 풀이(x) (0) | 2017.09.18 |
YISF 2017 write up (0) | 2017.08.09 |
[CODEAGATE 2017] Junior write up (2) | 2017.02.15 |