Post by Pesimistyle on Nov 21, 2017 18:16:39 GMT
Öncelikle merhabalar, sn. Arkadaşlarım, ~ crack.me 3 sahibine ithafen ;
Yazmış olduğunuz uygulama için her şeyden evvel minnettar kaldığımı belirtip, izninizle alışılagelmiş bir yöntem ile çözümü yazmak istiyorum. Her zamanki gibi, rekabet için oldukça geç kaldım - en azından bunu yapayım. Oncelikle, küçük bir one-liner ile uygulamanın .NET Framework bünyesindeki bir dil ile yazılıp yazılmadığını, yazılmış ise versiyonunu teyit edelim.
~ PS .NET Verification.
.NET olduğundan emin olduğumuza göre, sırada konunda da belirttiğin gibi 'obfuscate' işlemini uyguladığın yazılıma göz atmak var. Doğrusunu söylemek gerekir ise, izlediğim adımlarda bunun pek de bir önemi olmamakla beraber, tamamen bilgi elde safhasında izlediğim adımları barındırmak maksatlı yer veriyorum. Bildiğimiz üzere bu tarz yazılımların, PE (bu durumda.) veyahut herhangi bir başka dosya formatı üzerinde yaptıkları birtakım karakteristik düzenlemeler vardır. Misal, .NET Reactor 4.8/4.9 tespitinde bu karakteristik özellikler, aşağıdaki kod parçacığında olduğu gibi belirlenmiştir:
~ Detect It Easy - .NET Reactor
Bu bakımdan, manuel olarak kontrol etmek ile uğraşmaksızın, tespiti direkt olarak "Detect It Easy (v0.94)" adlı yazılıma bırakıyorum. Ayrıyeten, aşağıdaki sonuçtan da görebileceğiniz üzere uygulamanın .NET v2.0.50727 bünyesinde olduğunu doğruladık. Her ne ise.. Bu yazılımı de-obfuscate etmek ile uğraşmaksızın daha pratik bir yoldan ilerleyeceğim. Öncelikle hata ayıklama ortamımı başlatıp, uygulamaya attach olarak ihtiyacım olan modülleri barındıran DLL'leri içe aktarıyor, .NET2.x olduğundan ötürü 'mscorwks.dll' adlı dosyanın içe aktarılmasından evvel uygulamayı software-bp düzeyinde kırıyorum.
Uygulamanı açtığımızda bizi bir MessageBox çağrısı karşılıyor, uygulamanın başlangıç event'i yerine fantezi yapıp bu çağrıları yakalayacak şekilde bir break-point yerleştiriyorum ki gerekli olan diğer DLL kütüphaneleri de içeri aktarılsın.
Buraya kadar, hazırlığımız bitti. Önceki uygulamalarında da karşılaştığım üzere (bkz. crack_me<=2), doğal olarak kullandığın derleyicinin desteklediği operatörleri kullanmaktasın. Ben de bu zaafından faydalandım, önceki uygulamandan bir MSIL kesiti;
Dikkat çekmek istediğim nokta, CompilerServices.Operators::ConditionalCompareObjectEqual([..]) çağrısı. Hiç uğraşmadan, bu uygulamanda da bu tarz bir çağrı yapmış olma ihtimalini kafamda oluşturarak, MSDN'de tanımlanmış bu tarz çağrılara (bkz. msdn.microsoft.com/en-us/library/microsoft.visualbasic.compilerservices.operators.comparestring(v=vs.110).aspx) CompareString, ConditionalCompareObjectEqual, ConditionalCompareObjectNotEqual birer adet breakpoint yerleştirip, uygulamayı tekrardan sürdürüyorum. Methodların tamamı, "Microsoft.VisualBasic.dll" içerisinde tanımlanmakta.
Tahmin edebileceğiniz gibi, kendimce bir değer sallayıp (bu durumda, "DAMN".) karşılaştırma maksatlı butona tıklamamla beraber, uygulama software-bp düzeyinde kırılıyor. "SOS.DLL"nin nimetlerinden olan, manuel olarak araştırmaya lüzum bırakmaksızın süregelmekte olan Thread'ın stack konumunda barınan obje referanslarını listeleyen "!DumpStackObjects", veya "!dso" adlı çağrıyı kullanıp, bir göz atıyorum.
Özellikle "ecx" ve "edx" registerlarında barındırılmakta olan objeler ilgimi çekiyor. System.String veritipinde tanımlanmış, 32 karakter barındıran ve hexadecimal karakterlerden oluşan 2 adet string objem var. Hemen altta da, kendi girdiğim "DAMN" stringini görüyorum. Bu da aklıma, karşılaştırılan verilerin MD5 formatına çevrilip teyit edildiği olasılığını getiriyor. Kontrol edelim.
Hell? Yukarıdaki değer ile aynı sonucu elde ettim doğal olarak. Şimdi ise, küçük bir araştırma yapıp "820A6F1CC143693309337F32E502F886" olarak hashlenmiş arkadaşın plain-text karşılığını bulalım.
Böylelikle, istenen verinin "813964" olduğunu öğrendim. Test edelim.
~ pwn3d, huh!?
Çözerken gayet eğlendiğim, kısa ama dolu dolu geçen bir soru idi. Ellerine sağlık, devamını bekliyorum.
Yazmış olduğunuz uygulama için her şeyden evvel minnettar kaldığımı belirtip, izninizle alışılagelmiş bir yöntem ile çözümü yazmak istiyorum. Her zamanki gibi, rekabet için oldukça geç kaldım - en azından bunu yapayım. Oncelikle, küçük bir one-liner ile uygulamanın .NET Framework bünyesindeki bir dil ile yazılıp yazılmadığını, yazılmış ise versiyonunu teyit edelim.
PS> [System.Reflection.Assembly]::LoadFrom("{0}\Crackme 3.exe" -f $pwd)
[..]
Version: v2.0.50727
~ PS .NET Verification.
.NET olduğundan emin olduğumuza göre, sırada konunda da belirttiğin gibi 'obfuscate' işlemini uyguladığın yazılıma göz atmak var. Doğrusunu söylemek gerekir ise, izlediğim adımlarda bunun pek de bir önemi olmamakla beraber, tamamen bilgi elde safhasında izlediğim adımları barındırmak maksatlı yer veriyorum. Bildiğimiz üzere bu tarz yazılımların, PE (bu durumda.) veyahut herhangi bir başka dosya formatı üzerinde yaptıkları birtakım karakteristik düzenlemeler vardır. Misal, .NET Reactor 4.8/4.9 tespitinde bu karakteristik özellikler, aşağıdaki kod parçacığında olduğu gibi belirlenmiştir:
else if(PE.isNET())
{
[..]
else if(PE.section.length>=2)
{
if(PE.section[1].Characteristics==0xc0000040)
{
if(PE.isSignatureInSectionPresent(1,"5266686E204D182276B5331112330C6D0A204D18229EA129611C76B505190158"))
{
sVersion="4.8-4.9";
[..]
}
}
}
}
~ Detect It Easy - .NET Reactor
Bu bakımdan, manuel olarak kontrol etmek ile uğraşmaksızın, tespiti direkt olarak "Detect It Easy (v0.94)" adlı yazılıma bırakıyorum. Ayrıyeten, aşağıdaki sonuçtan da görebileceğiniz üzere uygulamanın .NET v2.0.50727 bünyesinde olduğunu doğruladık. Her ne ise.. Bu yazılımı de-obfuscate etmek ile uğraşmaksızın daha pratik bir yoldan ilerleyeceğim. Öncelikle hata ayıklama ortamımı başlatıp, uygulamaya attach olarak ihtiyacım olan modülleri barındıran DLL'leri içe aktarıyor, .NET2.x olduğundan ötürü 'mscorwks.dll' adlı dosyanın içe aktarılmasından evvel uygulamayı software-bp düzeyinde kırıyorum.
0:000> sxe ld:mscorwks
0:000> g
[..]
ModLoad: 5f030000 5f5de000 C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll
[..]
ntdll!KiFastSystemCallRet:
76dc6c74 c3 ret
0:000> .load C:\Windows\Microsoft.NET\Framework\v4.0.30319\sosex.dll
0:000> .load C:\Windows\Microsoft.NET\Framework\v4.0.30319\sos.dll
0:000> .load C:\blw\x86\blwdbgue.dll
0:000> .loadby sos mscorwks
0:000> !EEVersion
2.0.50727.5485 retail
Uygulamanı açtığımızda bizi bir MessageBox çağrısı karşılıyor, uygulamanın başlangıç event'i yerine fantezi yapıp bu çağrıları yakalayacak şekilde bir break-point yerleştiriyorum ki gerekli olan diğer DLL kütüphaneleri de içeri aktarılsın.
0:000> bm user32!MEssageBox*
1: 7564e8f1 @!"USER32!MessageBoxIndirectA"
2: 7564ea75 @!"USER32!MessageBoxExW"
3: 7564e417 @!"USER32!MessageBoxWorker"
4: 7564ea51 @!"USER32!MessageBoxExA"
5: 7564e9eb @!"USER32!MessageBoxIndirectW"
6: 7564ea99 @!"USER32!MessageBoxA"
7: 7564eae7 @!"USER32!MessageBoxW"
8: 7564e81d @!"USER32!MessageBoxTimeoutA"
9: 7564e795 @!"USER32!MessageBoxTimeoutW"
0:000> g
[..]
Breakpoint 7 hit
[..]
USER32!MessageBoxW:
7564eae7 8bff mov edi,edi
0:000> bc *; bl
Buraya kadar, hazırlığımız bitti. Önceki uygulamalarında da karşılaştığım üzere (bkz. crack_me<=2), doğal olarak kullandığın derleyicinin desteklediği operatörleri kullanmaktasın. Ben de bu zaafından faydalandım, önceki uygulamandan bir MSIL kesiti;
IL_0000: nop
IL_0001: ldarg.0
IL_0002: callvirt instance class [System.Windows.Forms]System.Windows.Forms.TextBox Crack.me_1.Form1::get_TextBox1()
IL_0007: callvirt instance string [System.Windows.Forms]System.Windows.Forms.TextBox::get_Text()
IL_000c: ldarg.0
IL_000d: ldstr ".."
IL_0012: call instance object Crack.me_1.Form1::BXdLRYgEmDMQDlogQVkdkGA(string)
IL_0017: ldc.i4.0
IL_0018: call bool [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.Operators::ConditionalCompareObjectEqual(object, object, bool)
Dikkat çekmek istediğim nokta, CompilerServices.Operators::ConditionalCompareObjectEqual([..]) çağrısı. Hiç uğraşmadan, bu uygulamanda da bu tarz bir çağrı yapmış olma ihtimalini kafamda oluşturarak, MSDN'de tanımlanmış bu tarz çağrılara (bkz. msdn.microsoft.com/en-us/library/microsoft.visualbasic.compilerservices.operators.comparestring(v=vs.110).aspx) CompareString, ConditionalCompareObjectEqual, ConditionalCompareObjectNotEqual birer adet breakpoint yerleştirip, uygulamayı tekrardan sürdürüyorum. Methodların tamamı, "Microsoft.VisualBasic.dll" içerisinde tanımlanmakta.
0:000> !bpmd microsoft.visualbasic.dll Microsoft.VisualBasic.CompilerServices.Operators.CompareString
MethodDesc = 0017947c
[..]
0:000> !bpmd microsoft.visualbasic.dll Microsoft.VisualBasic.CompilerServices.Operators.ConditionalCompareObjectNotEqual
MethodDesc = 00179380
[..]
0:000> !bpmd microsoft.visualbasic.dll Microsoft.VisualBasic.CompilerServices.Operators.ConditionalCompareObjectEqual
MethodDesc = 00179368
[..]
0:000> g
[..]
Breakpoint 0 hit
[..]
014eea10 55 push ebp
Tahmin edebileceğiniz gibi, kendimce bir değer sallayıp (bu durumda, "DAMN".) karşılaştırma maksatlı butona tıklamamla beraber, uygulama software-bp düzeyinde kırılıyor. "SOS.DLL"nin nimetlerinden olan, manuel olarak araştırmaya lüzum bırakmaksızın süregelmekte olan Thread'ın stack konumunda barınan obje referanslarını listeleyen "!DumpStackObjects", veya "!dso" adlı çağrıyı kullanıp, bir göz atıyorum.
0:000> !dso
OS Thread Id: 0x558 (0)
ESP/REG Object Name
ebx 018feb0c System.Windows.Forms.MouseEventArgs
ecx [b]0190175c[/b] System.String
edx [b]019017d0[/b] System.String
esi 018de170 System.EventHandler
edi 018ddfb4 System.Windows.Forms.Button
0031e9d0 018feb0c System.Windows.Forms.MouseEventArgs
0031e9d4 [b]019017d0[/b] System.String 820A6F1CC143693309337F32E502F886
0031e9d8 [b]0190175c[/b] System.String 8FB8DA1B215082DC639776D1A2EF0B50
[..]
0031ea68 01900ab4 System.String DAMN
[..]
0:000> r
eax=0017947c ebx=018feb0c ecx=0190175c edx=019017d0 esi=018de170 edi=018ddfb4
[..]
Özellikle "ecx" ve "edx" registerlarında barındırılmakta olan objeler ilgimi çekiyor. System.String veritipinde tanımlanmış, 32 karakter barındıran ve hexadecimal karakterlerden oluşan 2 adet string objem var. Hemen altta da, kendi girdiğim "DAMN" stringini görüyorum. Bu da aklıma, karşılaştırılan verilerin MD5 formatına çevrilip teyit edildiği olasılığını getiriyor. Kontrol edelim.
C:\PS> "DAMN" | Get-Hash -Algorithm MD5
Algorithm: MD5
HashString : [COLOR="red"]8FB8DA1B215082DC639776D1A2EF0B50[/COLOR]
Hell? Yukarıdaki değer ile aynı sonucu elde ettim doğal olarak. Şimdi ise, küçük bir araştırma yapıp "820A6F1CC143693309337F32E502F886" olarak hashlenmiş arkadaşın plain-text karşılığını bulalım.
MD5([COLOR="red"]813964[/COLOR]): [COLOR="red"]820a6f1cc143693309337f32e502f886[/COLOR]
Böylelikle, istenen verinin "813964" olduğunu öğrendim. Test edelim.
~ pwn3d, huh!?
Çözerken gayet eğlendiğim, kısa ama dolu dolu geçen bir soru idi. Ellerine sağlık, devamını bekliyorum.