-
TIM CTF - easyrev Write upCTF/Rev 2019. 9. 24. 14:45
TIM CTF가 최근에 막을 내렸다.
필자는 비교적 가벼운 난이도의 문제만 풀었지만 킹갓 대한민국의 다른 팀들이 본선에 진출하여 대거 루마니아행 비행기를 끊었따는 소식을 들었다.
모두들 화이팅!
-----------------
코드만 이해할 수 있다면 쉬운 easyrev 풀이를 포스팅해보도록 하자!
undefined8 main(void) { int iVar1; size_t sVar2; int local_1c; printf("Enter password: "); scanf("%s",password); sVar2 = strlen(password); if (sVar2 < 0x41) { sVar2 = strlen(password); if (sVar2 < 8) { puts("Error: password too short!"); } else { local_1c = 0; while (sVar2 = strlen(password), (ulong)(long)local_1c < sVar2) { if (('`' < (char)password[(long)local_1c]) && ((char)password[(long)local_1c] < '{')) { password[(long)local_1c] = (char)((int)(char)password[(long)local_1c] + -0x54) + (char)(((int)(char)password[(long)local_1c] + -0x54) / 0x1a) * -0x1a + 'a'; } local_1c = local_1c + 1; } iVar1 = strcmp(password,flag); if (iVar1 == 0) { puts("Congratulations, that is correct!"); } else { puts("NOOOOOOOOOOOOOOOO"); } } } else { puts("Error: password too long!"); } return 0; }
기드라 디컴파일러로 본 메인 함수 코드이다.
8자리 이상의 password를 입력 받고 while문을 통해서 한글자 씩 암호화 된다.
password[i]를 n라 보기 쉽게 표현했을 때
n - 0x54 + (n + 0x54)/ 0x1a * (-0x1a)+ 'a'
가 핵심 암호문이다.
범위는 `부터 {전까지로 아스키코드표를 확인해보면 소문자에 해당하는 범위인 것을 알 수가 있다.
다만 이 내용만 봐서는 사실 뭘 하라고 그러는 건지 잘 모를 수 밖에 없다.
주어진 입력값이 없기 때문이다.
풀이로는 적지않았지만 이 이전단계 babyrev에서 스트링 값을 확인하면 바로 플래그가 있던 문제가 있었다.
그 문제를 생각해보고 다시 string들을 검색해보았다.
가장 밑에 보면 TIMCTF{ebgngrq13synt}라고 적혀있는 것을 확인 할 수 있다.
무턱대고 그냥 플래그 인증하면 당연히 이번엔 안된다..
잘 보면 영어로 적혀있는 부분이 다 소문자인 것을 확인 할 수가 있다.
그렇다면 설마? 하는 생각에 저 문자열을 main알고리즘을 재구성하여 돌려보았다.
#include <stdio.h> int main(int argc, const char * argv[]) { char buf[14] = "ebgngrq13synt"; for (int i=0; i<13; i++){ buf[i] = buf[i] - 'T' + ((buf[i] - 'T') / 0x1a) * (-0x1a) + 'a'; printf("%c", buf[i]); } puts("") return 0; }
킹차니즘으로 소문자만 알고리즘에 돌리는 코드는 작성하지 않았다.
이렇게 해서 돌리면 그럴듯한 문자열이 출력된다.
rotatedXZflag
XZ는 13이 돌아간 값이므로 다시 13으로 바꾸어 준다.
rotated13flag
즉 TIMCTF{rotated13flag}가 flag이다!