ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • TIM CTF - easyrev Write up
    CTF/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이다!

     

     

    댓글

Designed by Tistory.