Wargame.kr 포스트는 이해한 내용과 복습을 위한 목적으로 작성되었습니다.

이번 포스트에서는 Crypto Crackme Basic 문제에 대한 이해와 풀이를 진행해보도록 하겠습니다.


이번에는 생각보다 간단하지만, 어느정도 도구를 다룰 줄 알아야 합니다.

사용할 수 있는 도구는 굉장히 다양하지만 목적은 C# Decompile, 혹은 C# Analysis로 동일합니다.

문제를 풀어보도록 하겠습니다.




 

 문제 이해


문제는 다음과 같습니다.


Crypto Crackme Basic에서는 C# Reversing이 가능하는지 묻고 있습니다.

문제를 풀면서 생각해보건데, 일반적은 디버거(OllyDBG 혹은 X64DBG, IDA 등)으로는 분석하기가 은근 까다롭습니다.


OllyDBG나 X64DBG의 경우 중단점의 위치를 파악하기 어려운데, 이는 dll을 동적으로 가져오는 원리 때문이라고 합니다.

또한 IDA의 경우 Decompile이 일반적인 방법으로 되지 않았습니다.(그냥 코드 가져다가 쭈욱 따라가면 디컴파일 해주던데 ㅠㅠ)


때문에 저는 IDA를 조금 사용하다가 중간에 C# Decompiler를 검색하여 사용해보았습니다.


일단 문제의 상세 내용은 다음과 같습니다.



위의 프로그램을 다운로드 받고 실행시키면 아래와 같이 됩니다.



WTF AUTH FAILED라는 문자열이 나오는 것을 중심으로 IDA를 응용해보려 했습니다. ㅠㅠ





 

 문제 풀이


일단 문제를 풀이하기 앞서 제가 한 삽질과 문제 풀이, 두 가지로 구분하려 합니다.

제가 삽질한 부분을 넘어가고자 하시면 [문제 풀이] 소제목으로 넘어가주시기 바랍니다.



 

 IDA를 이용한 C# 디컴파일(리버싱) - 실패


IDA를 이용하여 C#을 디컴파일 해보게 되면 다음과 같이 나오게 됩니다.


처음엔 오잉? 했으나, 저게 이 프로그램의 코드 흐름 전체입니다.

여기서 얻을 수 있는 힌트는 어떤 함수로 쓰여 있고, 어떤 값이 들어가 있는지 등이 쓰여 있을 뿐, 다른 큰 정보는 없습니다.

특히 name 값이 BluSH4G라는 것을 알 수 있다는 점에서 조금의 힌트는 얻을 수 있었습니다.


이제 F5를 눌러 디컴파일을 하려했는데...


띠용.

안 됩니다...


원래 이 외에도 다양한 삽질을 시도 하였으나, 의미있는 건 저정도 뿐이라 여기까지만 작성해보도록 하겠습니다.


이처럼 디컴파일이 안 되기 때문에 다른 방법을 찾아야 했습니다.

디컴파일을 위해 다른 C# Decompiler툴을 찾아보았습니다.


찾아본 툴의 종류는 굉장히 다양하나, 저는 JetBrain에서 제공하는 Dot Peek이라는 프로그램을 사용하였습니다.

여러분은 dnSpy를 사용하시는 것을 권장합니다.



 

 문제 풀이


문제 풀이를 위해 Dot Peek을 설치해보았습니다.

원래는 Decompile한 파일을 Export하여 동적 디버깅을 수행하기 위해 Visual Studio를 설치하였으나, 굳이 그럴 필요까지는 없었습니다.
(파일이 워낙 작고 하나에 모아둬서 그럴 필요까지는 없다는 것입니다.)


Dot Peek으로 디컴파일하게 되면 다음과 같이 나타나게 됩니다.

IDA에서 바랐던 모습이 좀 더 상세하게 나온 기분이네요.

위와 같이 아예 프로젝트 소스를 완전하게 디컴파일 해주는 것처럼 보입니다.

변수 이름이나 함수 이름을 완벽하게 가져왔습니다.


C#은 원래 이런가...


여기어 이 프로젝트를 Export하여 동적 디버깅을 수행하여 이것저것 알아보려 했으나 크게 소득이 없었습니다.


물론 C# 코드를 모르시는 분이나, 이해가 잘 안 간다 하시는 분은 Visual Studio를 설치하여 동적디버깅 하면서 변수의 값을 일일이 체크해보는 게 더 빠르고 도움될 수 있습니다.


저는 후자이기 때문에 동적 디버깅을 수행하였습니다.


먼저 DES 암호 알고리즘임으 알 수 있습니다.

또한 모드는 ECB 모드이며, Key만 이용되는 암호화 방식입니다.

따라서 여기서는 Key 값만 유효하며 IV는 의미가 없습니다.


중단점을 삽입하고, F11을 눌러가며 디버깅을 수행하면서, Key 값과 IV(Initial Vector) 값을 확인했습니다.

여기서 Key 값과 IV 값은 동일하며 name + '*' 값입니다.

즉 BluSH4G 값이 이름이면 뒤에 *을 붙여 BluSH4G* 가 Key와 IV가 된다는 것입니다.


이제 암호화된 값이 어디있는지 찾아야 하는데, 이는 getps라는 함수를 통해 값을 얻어옵니다.



동적 디버깅을 쭉 따라가다보면, wargame.kr에서 ps.php를 통해 암호화된 값을 가져우는 것을 확인할 수 있습니다.

이 값이 암호화된 flag값입니다.

또한 암호화된 값은 Base64로 인코딩 되어 있으며, 이는 위의 myEncrypt에서 설명하고 있습니다.



이제 알아낸 Key 값으로 위의 암호문을 복호화해보도록 하겠습니다.


복호화를 위해 따로 코드를 구현하지 않았고, online을 사용하였습니다.


이렇게 해서 Flag를 얻어낼 수 있었습니다.

저 Flag 값은 계속 바뀌게 됩니다.


만약 온라인이 별로라면?

import pyDes # Should install using pip module
import base64

class DES:
    def __init__(self, iv, key):
        self.iv  = iv
        self.key = key

    def encrypt(self, data):
        k    = pyDes.des(self.key, pyDes.ECB, self.iv, pad=None, padmode=pyDes.PAD_PKCS5)
        d    = k.encrypt(data)
        d    = base64.b64encode(d)
        return d

    def decrypt(self, data):
        k    = pyDes.des(self.key, pyDes.ECB, self.iv, pad=None, padmode=pyDes.PAD_PKCS5) 
        data = base64.b64decode(data)
        d    = k.decrypt(data)
        return d

if __name__ == '__main__':
    iv       = 'BluSH4G*'
    key      = 'BluSH4G*'
    des      = DES(iv, key)
    enc_data = b"kyxBF9rAKXBIGi5KmChr0v+xDhZV/5BFNpLzRs4/tLj/BSXG+NKIlxVDw6Z7BZik"
    
    dec_data = des.decrypt(enc_data)

    print(dec_data)
    




끝!


 

 P.S.


dnSpy는 dot peek + Visual Studio인데 겁나 가벼움...

님들 dnSpy 씁시다.


https://github.com/0xd4d/dnSpy/releases

+ Recent posts