Description
Category: Reversing / Crypto
Source: wargame.kr
Points: 391
Author: Jisoon Park(js00n.park)
Description:
Simple Reverse Engineering.
Can you Reversing for C# Application?
Write-up
.Net 기반 C# 프로그램에 대한 reversing 문제이다.
일단 JetBrains dotPeek같은 .Net decompiler를 이용해서 decompile을 시도하여 아래와 같은 코드를 얻었다.
private static string myEncrypt(string strKey, string name)
{
DESCryptoServiceProvider cryptoServiceProvider = new DESCryptoServiceProvider();
cryptoServiceProvider.Mode = CipherMode.ECB;
cryptoServiceProvider.Padding = PaddingMode.PKCS7;
byte[] bytes1 = Encoding.ASCII.GetBytes(Program.mPadding(name));
cryptoServiceProvider.Key = bytes1;
cryptoServiceProvider.IV = bytes1;
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream((Stream) memoryStream, cryptoServiceProvider.CreateEncryptor(), CryptoStreamMode.Write);
byte[] bytes2 = Encoding.UTF8.GetBytes(strKey.ToCharArray());
cryptoStream.Write(bytes2, 0, bytes2.Length);
cryptoStream.FlushFinalBlock();
return Convert.ToBase64String(memoryStream.ToArray());
}
private static string mPadding(string s)
{
int length = s.Length;
if (length == 8)
return s;
if (length > 8)
return s.Substring(length - 8);
for (int index = 0; index < 8 - length; ++index)
s += "*";
return s;
}
private static bool myCmp(string s1, string s2)
{
return s1.Length == s2.Length && !(s1 != s2);
}
private static void Main(string[] args)
{
Console.Write("Input your name : ");
string name = Console.ReadLine();
Console.Write("Password : ");
string s1 = Program.myEncrypt(Console.ReadLine(), name);
if (name == "BluSH4G" && Program.myCmp(s1, Program.getps(name)))
Console.WriteLine("\n::Congratulation xD ::\n");
else
Console.WriteLine("\n:: WTF AUTH FAILED ::\n");
}
public static string getps(string name)
{
WebRequest webRequest = WebRequest.Create("http://wargame.kr:8084/prob/28/ps.php?n=" + name);
webRequest.Credentials = CredentialCache.DefaultCredentials;
HttpWebResponse response = (HttpWebResponse) webRequest.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader streamReader = new StreamReader(responseStream);
string end = streamReader.ReadToEnd();
streamReader.Close();
responseStream.Close();
response.Close();
return end;
}
Main() 함수를 보면, name과 password를 받고, 암호화 한 후에 getps()의 결과와 비교하도록 되어있다. if 구문으로부터 name은 BluSH4G 임을 쉽게 알 수 있었다.
우선, myEncrypt() 함수가 호출되는데, 내용을 보면 name에 padding을 한 것을 key로 하여 password를 DES ECB로 암호화하고 base64 encoding하도록 되어있다.
name이 뭔지 알고 있으니 mPadding() 함수를 보면 name에 "*" 하나를 붙이는 걸로 8바이트 padding이 적용되어 key로 사용될 것을 유추할 수 있다.
getps() 함수는 name을 이용해서 서버에서 필요한 값을 받아오는데, 실제로 요청해보면 base64로 인코딩된 문자열을 돌려준다.
Key를 알고 있으니, DES로 복호화 해보면 flag를 얻을 수 있다.
from Crypto.Cipher import DES
import base64
obj = DES.new('BluSH4G*', DES.MODE_ECB)
cipher = base64.b64decode('7A38V6xRUofPwAj1THUFmbqNgf9CeCR7Jcp1c4F1pe/g2Bzodq7delcwt7bsML8R')
plain = obj.decrypt(cipher)
print plain
Flag : c46426b4bef4ad5ec89f1f7cc6a71bde3e2bf4c2
'writeups > Reversing' 카테고리의 다른 글
Easyhaskell (0) | 2019.11.25 |
---|---|
EASY_CrackMe (0) | 2019.11.25 |
NoCCBytes (0) | 2019.11.23 |
Cr4ckZ33C0d3 (0) | 2019.11.23 |
Cheesy (0) | 2019.11.23 |