• [ Reversing.kr ] Metroapp

    2020. 4. 9.

    by. ugonfor

    음... 

    처음에 내가 헤맸는 데 약간 어처구니 없는 이유로 헤맸다. 

    처음에 EasyCrackme 같은거 풀 때는 오히려 안하던 실수를 했다 ㅇㅇ...

     

    당연히 string을 살펴볼 때는 Ascii로도 봐야하고 Unicode로도 봐야한다.

    그런데 이번에 내가 풀때는 Unicode를 살펴보지 않아서 단서를 잡는 데 오래걸렸다.

     

     

    이런 코드는 처음보는 듯 ㅋㅋ...

    거의 모든 코드들이 한 함수에 의존해서 결정됨 ㅇㅇ...

    그리고 저곳을 좀 분석해보니 ...

    이처럼 되어 있었는 데, 어떤 함수를 호출하길래 매우 중요하구나... 하고 important라 이름붙여줌 

    근데 뭐 확인해보니까.. 여러가지 라이브러리에서 함수를 호출하는 게 아마도 appx 파일에서 특정 기능을 호출하는? 아니면 화면에 출력해주는 함수인것 같다 ..

     

    보면 위쪽에 주황색이 있고, 아래쪽에 파란색이 있는 데,

    주황색은 "tce", 파란색은 "gno"라는 텍스트가 있는 곳이다.

    왜 그곳을 주목했냐면 

    각 텍스트에 Wrong과 Correct를 배정했기 때문이다 ㅇㅇ...

     

     

    다시 그래프에서 파란색은 수도코드로 보면 위와 같다. 

     

    근데 리버싱을 하다보면 진짜 감으로 때려 맞추는 경우가 진짜 많은 데 풀고나서 든 생각인데 이문제도 진짜 어쩌다 때려맞췄는 데 된거같다. 

    저기 아래에 보면 "gno" 라는 게 있는 데, 이 부분이 Wrong!으로 가게 되죠?

    근데 그 위에 if문이 있고, v1이 어디서 변하는 지 봤더니 사진의 위에서 두번째 줄이었습니다.

     

    그래서 저게 어떤 input을 실제랑 확인하는 부분인가? 하고 해봤더니 되더라구요 ㅎㅎ;;;;

    그리고 이건 사실 IDA로 ATTACH 해서 보는 게 좀 어려워서 x64dbg사용해서 확인해봤어요

     

    저 문자열 부분을 특정 키라고 생각했고, 이에 대해서 적절히 코드를 짜줬습니다. 

     

    근데 꼭 컴퓨터가 저 매개변수들이 어떤 매개변수인지 잘 안알려주더라구요? 그래서 레지스터를 잘 알려주는 x64dbg로 확인을 해봤더니

    맞죠??

    보시면

    이렇게 문자 하나끼리 비교를 합니다.

     

    D9의 경우에는 제가 입력한 U를 특정키를 이용해서 암호화하는 패턴을 통해서 변형시킨 값이고, g는 ugonfor에서 다음문자입니다.

     

    그러니까 비교하는 값이 첫번째 값의 암호화한 값과 두번째 값을 비교하는 거죠 

    계속 값이 하나씩 밀립니다.

     

    그리고 그 아래에 cmp값에 따라 점프문이 있는 데 이부분 점프문 패치를 해주면 Correct가 나오는 것을 보고 확신했습니다. 

     

    이제 그럼 저 알고리즘의 역과정을 찾아봐야겠죠.

     

    __ROL1__ 이 뭔지 

    https://github.com/joxeankoret/tahh/blob/master/comodo/defs.h

     

    joxeankoret/tahh

    Source codes for "The Antivirus Hackers Handbook" book. - joxeankoret/tahh

    github.com

    여기서 봤구요...

     

    역과정 파이썬으로 짜줬습니다. 

     

    text = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    key = [119, 173, 7, 2, 165, 0, 41, 153, 40, 41, 36, 94, 46, 42, 43, 63, 91, 93, 124, 92, 45, 123, 125, 44, 58, 61, 33, 10, 13, 8, 0, 0]
    
    def ror1(value, count):
        tmp = bin(value)
    
        if len(tmp) != 10 :
            tmp = tmp[:2] + "0"*(10-len(tmp)) + tmp[2:]
        
        tmp2 = "0b" + tmp[10-count:] + tmp[2:10-count]
    
        return int(tmp2,2)
        
    def rol1(value, count):
        return ror1(value, 8-count)
        
    
    def flag_start_with(first):
        input = [0] * 20
        input[0] = first
    
        for i in range(20):
    
            for j in text:
                if ord(j) == (key[i&7] ^rol1(ord(input[i]),ord(input[i])&7))%0x100:
                    input[i+1] = j
                    break
                
            if input[i+1] == 0:
                if i == 0:
                    return 0
                if i != 0:
                    print ("".join(input[:i+1]))
                    return 0
    
            
    for i in text:
        flag_start_with(i)
                
            
    

     

    'Writeup > Wargame_Writeup' 카테고리의 다른 글

    [ Reversing.kr ] PEpassword  (0) 2020.04.14
    [ Reversing.kr ] WindowKernel  (0) 2020.04.13
    [ Reversing.kr ] HateIntel  (0) 2020.04.08
    [ Reversing.kr ] Multiplicative  (0) 2020.04.08
    [ Reversing.kr ] flashenc  (0) 2020.04.08

    댓글