<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Icewall&#039;s blog &#187; python</title>
	<atom:link href="http://www.icewall.pl/tag/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.icewall.pl</link>
	<description>IT Security</description>
	<lastBuildDate>Thu, 29 Jul 2010 23:19:16 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>pl</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Algorytmy (de)szyfrowania wykorzystywane przez twórców trojanów bankowych – PART II</title>
		<link>http://www.icewall.pl/2009/08/29/algorytmy-deszyfrowania-wykorzystywane-przez-tworcow-trojanow-bankowych-%e2%80%93-part-ii/</link>
		<comments>http://www.icewall.pl/2009/08/29/algorytmy-deszyfrowania-wykorzystywane-przez-tworcow-trojanow-bankowych-%e2%80%93-part-ii/#comments</comments>
		<pubDate>Sat, 29 Aug 2009 13:17:02 +0000</pubDate>
		<dc:creator>Icewall</dc:creator>
				<category><![CDATA[Analiza]]></category>
		<category><![CDATA[Malware]]></category>
		<category><![CDATA[RE]]></category>
		<category><![CDATA[decryption]]></category>
		<category><![CDATA[deszyfrowanie]]></category>
		<category><![CDATA[encryption]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[szyfrowanie]]></category>
		<category><![CDATA[trojan]]></category>
		<category><![CDATA[trojan bankowy]]></category>
		<category><![CDATA[trojan delphi]]></category>

		<guid isPermaLink="false">http://icewall.wordpress.com/?p=250</guid>
		<description><![CDATA[Tak jak wspominałem w poprzednim poście niniejszy będzie o sposobach (de)szyfrowania stosowanych w pewnej rodzinie trojanów bankowych pisanych w delphi.
Oczywiście tradycyjnie zaczniemy od przedstawienia naszego bohatera:
[=]Dane[=]

Antivirus	Version	Last Update	Result
a-squared	4.5.0.24	2009.08.28	Trojan-Spy.Win32.Bancos!IK
AhnLab-V3	5.0.0.2	2009.08.28	-
AntiVir	7.9.1.7	2009.08.28	TR/Spy.Banker.DS.5102592
Antiy-AVL	2.0.3.7	2009.08.24	-
Authentium	5.1.2.4	2009.08.28	-
Avast	4.8.1335.0	2009.08.28	Win32:Spyware-gen
AVG	8.5.0.406	2009.08.28	PSW.Banker5.IQR
BitDefender	7.2	2009.08.28	DeepScan:Generic.Banker.OT.4CC5D1C8
CAT-QuickHeal	10.00	2009.08.28	-
ClamAV	0.94.1	2009.08.28	Trojan.Agent-119128
Comodo	2125	2009.08.28	-
DrWeb	5.0.0.12182	2009.08.28	Trojan.PWS.Banker.based
eSafe	7.0.17.0	2009.08.27	-
eTrust-Vet	31.6.6706	2009.08.28	-
F-Prot	4.5.1.85	2009.08.27	-
F-Secure	8.0.14470.0	2009.08.28	-
Fortinet	3.120.0.0	2009.08.28	W32/Banker.B!tr.pws
GData	19	2009.08.28	DeepScan:Generic.Banker.OT.4CC5D1C8
Ikarus	T3.1.1.68.0	2009.08.28	Trojan-Spy.Win32.Bancos
Jiangmin	11.0.800	2009.08.28	-
K7AntiVirus	7.10.830	2009.08.28	-
Kaspersky	7.0.0.125	2009.08.28	-
McAfee	5723	2009.08.28	PWS-Banker.gen.b
McAfee+Artemis	5723	2009.08.28	Artemis!504F1C591479
McAfee-GW-Edition	6.8.5	2009.08.28	Trojan.Spy.Banker.DS.5102592
Microsoft	1.5005	2009.08.28	TrojanSpy:Win32/Bancos.gen!C
NOD32	4378	2009.08.28	probably a variant of Win32/Spy.Banker.QEO
Norman		2009.08.28	W32/Banker.EKFF
nProtect	2009.1.8.0	2009.08.28	-
Panda	10.0.2.2	2009.08.28	Trj/CI.A
PCTools	4.4.2.0	2009.08.28	-
Prevx	3.0	2009.08.28	-
Rising	21.44.40.00	2009.08.28	Trojan.PSW.Win32.Banker.dnl
Sophos	4.45.0	2009.08.28	Mal/Generic-A
Sunbelt	3.2.1858.2	2009.08.28	-
Symantec	1.4.4.12	2009.08.28	Infostealer.Bancos
TheHacker	6.3.4.3.389	2009.08.27	-
TrendMicro	8.950.0.1094	2009.08.28	-
VBA32	3.12.10.10	2009.08.28	-
ViRobot	2009.8.28.1907	2009.08.28	-
VirusBuster	4.6.5.0	2009.08.28	TrojanSpy.Banker.CDVF
Additional information
File size: 5102592 bytes
MD5   : 504f1c5914799e5122c69620c0b892e2
SHA1  : 32980745998151bda4a9e3bab767201ebc52fc0a
SHA256: 54d974192dd53aba186d56803087224ff8f8b0aba9687604332891842bb5ef58

[=]Prolog[=]
Tak jak pewnie udało wam się zauważyć w poprzednim poście malware ten posiada [...]]]></description>
			<content:encoded><![CDATA[<p>Tak jak wspominałem w poprzednim poście niniejszy będzie o sposobach (de)szyfrowania stosowanych w pewnej rodzinie trojanów bankowych pisanych w delphi.</p>
<p>Oczywiście tradycyjnie zaczniemy od przedstawienia naszego bohatera:<br />
<font color="blue"><b>[=]Dane[=]</b></font></p>
<pre>
Antivirus	Version	Last Update	Result
a-squared	4.5.0.24	2009.08.28	Trojan-Spy.Win32.Bancos!IK
AhnLab-V3	5.0.0.2	2009.08.28	-
AntiVir	7.9.1.7	2009.08.28	TR/Spy.Banker.DS.5102592
Antiy-AVL	2.0.3.7	2009.08.24	-
Authentium	5.1.2.4	2009.08.28	-
Avast	4.8.1335.0	2009.08.28	Win32:Spyware-gen
AVG	8.5.0.406	2009.08.28	PSW.Banker5.IQR
BitDefender	7.2	2009.08.28	DeepScan:Generic.Banker.OT.4CC5D1C8
CAT-QuickHeal	10.00	2009.08.28	-
ClamAV	0.94.1	2009.08.28	Trojan.Agent-119128
Comodo	2125	2009.08.28	-
DrWeb	5.0.0.12182	2009.08.28	Trojan.PWS.Banker.based
eSafe	7.0.17.0	2009.08.27	-
eTrust-Vet	31.6.6706	2009.08.28	-
F-Prot	4.5.1.85	2009.08.27	-
F-Secure	8.0.14470.0	2009.08.28	-
Fortinet	3.120.0.0	2009.08.28	W32/Banker.B!tr.pws
GData	19	2009.08.28	DeepScan:Generic.Banker.OT.4CC5D1C8
Ikarus	T3.1.1.68.0	2009.08.28	Trojan-Spy.Win32.Bancos
Jiangmin	11.0.800	2009.08.28	-
K7AntiVirus	7.10.830	2009.08.28	-
Kaspersky	7.0.0.125	2009.08.28	-
McAfee	5723	2009.08.28	PWS-Banker.gen.b
McAfee+Artemis	5723	2009.08.28	Artemis!504F1C591479
McAfee-GW-Edition	6.8.5	2009.08.28	Trojan.Spy.Banker.DS.5102592
Microsoft	1.5005	2009.08.28	TrojanSpy:Win32/Bancos.gen!C
NOD32	4378	2009.08.28	probably a variant of Win32/Spy.Banker.QEO
Norman		2009.08.28	W32/Banker.EKFF
nProtect	2009.1.8.0	2009.08.28	-
Panda	10.0.2.2	2009.08.28	Trj/CI.A
PCTools	4.4.2.0	2009.08.28	-
Prevx	3.0	2009.08.28	-
Rising	21.44.40.00	2009.08.28	Trojan.PSW.Win32.Banker.dnl
Sophos	4.45.0	2009.08.28	Mal/Generic-A
Sunbelt	3.2.1858.2	2009.08.28	-
Symantec	1.4.4.12	2009.08.28	Infostealer.Bancos
TheHacker	6.3.4.3.389	2009.08.27	-
TrendMicro	8.950.0.1094	2009.08.28	-
VBA32	3.12.10.10	2009.08.28	-
ViRobot	2009.8.28.1907	2009.08.28	-
VirusBuster	4.6.5.0	2009.08.28	TrojanSpy.Banker.CDVF
Additional information
File size: 5102592 bytes
MD5   : 504f1c5914799e5122c69620c0b892e2
SHA1  : 32980745998151bda4a9e3bab767201ebc52fc0a
SHA256: 54d974192dd53aba186d56803087224ff8f8b0aba9687604332891842bb5ef58
</pre>
<p><font color="blue"><b>[=]Prolog[=]</b></font><br />
Tak jak pewnie udało wam się zauważyć w poprzednim poście malware ten posiada np. zaszyfrowane ścieżki, do których zostaną wykonana jego kopie. Przykładowy zaszyfrowany ciąg wygląda tak:<br />
<strong>GpfSH6zZTMrbRdHp865kP21JPNHqQMvdSrn1R6mWLNDbSdDSJMLkTI19RcbZQM5oN51oRsToOMrXSrn9RcbZQM5iQNfXSbnNQMvaRtTpCp8kPNXb</strong></p>
<p>gdzie po deszyfrowaniu otrzymujemy łańcuch:<br />
<strong>C:\Documents and Settings\All Users\Menu Iniciar\Programas\Inicializar\Windows32.exe</strong></p>
<p>W jaki  sposób funkcjonuje ten algorytm ? Tego dowiemy się już za chwilę.<br />
Wcześniej jednak sprecyzuje  „elementy”, które w tym malware’e wymagają deszyfrowania:</p>
<p><strong>- ścieżki, do który kopiowany jest malware<br />
- tytuły okien IE(malware używa tytułów okien do rozpoznania czy user znajduje się obecnie na stronie,  dla której trojan ma przygotowany np. fałszywy panel logowania)<br />
- treść fałszywych komunikatów mówiących o tym, że np. Internet Explorer wykonał<br />
nieprawidłową operacje i zostanie zamknięty.</strong></p>
<p>w niektórych wersjach także:<br />
<strong>- login&amp;hasło do serwera ftp/mysql używanego jako drop host<br />
- adresy email na które mają zostać przesłane skradzione dane</strong></p>
<p>Warto tutaj wspomnieć o różnicy, która występuje w podejściu autorów trojana obecnego i tego z poprzedniego postu. Jak pamiętamy tam autor nie dość, że stosował różnego rodzaju klucze xor’ujące to jeszcze zmieniały się w nieznacznym stopniu same procedury szyfrowania. Tutaj spoglądając na wygląd ciągów reprezentujących zaszyfrowane dane:<br />
<a href="http://icewall.files.wordpress.com/2009/08/encrypted_strings.jpg"><img src="http://icewall.files.wordpress.com/2009/08/encrypted_strings.jpg" alt="encrypted_strings" title="encrypted_strings" width="497" height="266" class="aligncenter size-full wp-image-251" /></a></p>
<p>Można zakładać, że procedura deszyfrująca jest jedna, globalna. Po dokładnej analizie okazuje się, że faktycznie tak jest i nadszedł czas żeby przyjrzeć się jej bliżej.<br />
Oczywiście jej lokalizację można w prosty sposób ustalić po przez przejście do kawałka kodu, który odwołuje się do jednego z zaszyfrowanych ciągów:<br />
<a href="http://icewall.files.wordpress.com/2009/08/decryption_routine_call.jpg"><img src="http://icewall.files.wordpress.com/2009/08/decryption_routine_call.jpg" alt="decryption_routine_call" title="decryption_routine_call" width="497" height="182" class="aligncenter size-full wp-image-253" /></a><br />
<em>Wywołanie funkcji deszyfrującej. Oczywiście argumenty, są przekazywane zgodnie z konwencja __fastcall typową dla Borlanda.</em></p>
<p><font color="blue"><b>[=]Analiza[=]</b></font><br />
Procka deszyfrująca przedstawia się następująco:<br />
<a href="http://icewall.files.wordpress.com/2009/08/decryption_routine.jpg"><img src="http://icewall.files.wordpress.com/2009/08/decryption_routine.jpg" alt="decryption_routine" title="decryption_routine" width="497" height="236" class="aligncenter size-full wp-image-252" /></a><br />
gdzie:<br />
<strong>ESI  &#8211; długość zaszyfrowanego ciągu<br />
Local.1 – pointer na zaszyfrowany ciąg</strong><br />
Jak widać procka jest o wiele pokaźniejsza od tych, które mogliśmy obserwować w poprzednim malware’e.<br />
<font color="blue"><b>[=]Deszyfrowanie[=]</b></font><br />
Bez większe zastanawiania się tworzymy decryptor, który w pythonie przedstawia się następująco:</p>
<pre class="brush: python">
import sys
#Delephant decryption script 

ascii_table = &quot;0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/&quot;

def decrypt(encrypted):
    decrypted = []
    local_4 = 0
    edi     = 0
    for index in range(0,len(encrypted)):
        pos = ascii_table.find(encrypted[index])
        if pos &lt; 0:
            return &quot;Encrypted string is in unproper format&quot;
        pos = pos + (local_4 &lt;&lt; 6)
        local_4 = pos
        edi = edi + 6
        if edi &lt; 8:
            continue
        edi = edi - 8
        local_4 = local_4 % ( 1 &lt;&lt; (edi &amp; 0xff ) )
        pos = ( pos &gt;&gt; (edi &amp; 0xff) ) &amp; 0x800000ff
        if pos &lt; 0:
            pos = ( (pos - 1) &amp; 0xffffff00 ) + 1
        decrypted.append( chr(pos) )
    return &quot;&quot;.join(decrypted)

if __name__ == &quot;__main__&quot;:
    if len(sys.argv) &lt; 2:
        print &quot;Usage: %s encrypted_string&quot; % sys.argv[0]
        sys.exit(0)
    print decrypt(sys.argv[1])
</pre>
<p>Rezultat deszyfrowania losowo wybranych stringów:<br />
<a href="http://icewall.files.wordpress.com/2009/08/result_of_decryption.jpg"><img src="http://icewall.files.wordpress.com/2009/08/result_of_decryption.jpg" alt="result_of_decryption" title="result_of_decryption" width="496" height="244" class="aligncenter size-full wp-image-254" /></a></p>
<p>Warto tutaj zauważyć jedną znacząco różnice:<br />
<font color="gree"><b><br />
MOV EAX,[Local.5] ; kolejny znak z zaszyfrowanego ciagu<br />
MOV EDX,zloavgtr.00480BAC ;     ASCI „0123456789ABCD….”<br />
CALL StrPos<br />
MOV EBX,EAX<br />
DEC EBX<br />
</b></font><br />
i odpowiednik tego kodu w Python’e:<br />
<font color="gree"><b><br />
pos = ascii_table.find(encrypted[index])<br />
</b></font><br />
Trzeba być tutaj świadomym jednej rzeczy, a mianowicie tego ze <strong>StrPos Borlandowy</strong> indexuje pozycje znaków w stringu od 1 a <strong>find Pythonowy od 0</strong>. Dlatego też w kodzie pythona nie pojawia się dekrementacja wartości pozycji znaku do odszyfrowania.</p>
<p><font color="blue"><b>[=]Epilog[=]</b></font><br />
Jak można zauważyć, procedura deszyfrująca tego trojana jest objętościowa ok.3 razy większa od tych, z którymi mieliśmy do czynienie w poprzednim sampel’u co jednak nie przeszkodziło nam w stworzeniu python’ego decryptor’a.<br />
Jeżeli chodzi o algorytmy wykorzystywanego przez ten malware’u do „szyfrowania„ skradzionych danych to są to przeważnie:<br />
<strong>- URL Encode<br />
- Base64</strong><br />
ze względu na powszechność nie zostały one tutaj opisane.</p>
<p>Na sam koniec dla ciekawych, chcących przeanalizować krok po kroku działanie decryptor’a pare stringów do deszyfracji:<br />
<strong><br />
&#8220;IKLuS6nlScK&#8221;<br />
&#8220;IMvcRt9jOUVZRo1fRcDlSd9bT64X851oPMLkOsXX86DlSd9bT65jPMvqPI1l86DXRN1l84HfPsbqRou&#8221;<br />
&#8220;H65aRtCWIMvZRt9oPNHlSomWK6zo86PXTczo86HfPsbqPI1kRtPXRMLkT6Kk&#8221;<br />
&#8220;K6zo86PXTczoB21fRcPlScrb86baPMvqQMPfOs7dusyi865dPMvZQM4i86DlRdHX&#8221;<br />
&#8220;Kt8eOIak84PXTczo86HfPsbqON8WOI1pTM4WSsLkQ64WP64WT65YPMnX86DlSd9bT65jPMvqPIu&#8221;<br />
&#8220;LNDruN9fRoukBYukBYukBYukBZe&#8221;<br />
&#8220;K6zo86rlT6bsRo1aPI1JPMTrSc5kvs4WSsLr84D1KbJ3Jo14HI1JHKTLKa5Enq4WP6LsPI1pPN8WKcLZOMHXStHoOMHlB21JRsnfOsbqOMrlSo1nTMKWLczZwY18OM9fR6bqPI1pPNKWGs5oTEDl86Hb85DbPtLoOMxdOI1ERtPXRMLkT6Kk&#8221;<br />
&#8220;Gc5kOsyWINHX+Y0j84PbQNHl851XSc4WLczZwY0WBI1DQMDoRtDlPdGWIMvqPN9kPNGWHNXmR6zoPN8&#8243;<br />
</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.icewall.pl/2009/08/29/algorytmy-deszyfrowania-wykorzystywane-przez-tworcow-trojanow-bankowych-%e2%80%93-part-ii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Algorytmy (de)szyfrowania wykorzystywane przez twórców trojanów bankowych.</title>
		<link>http://www.icewall.pl/2009/07/23/algorytmy-deszyfrowania-wykorzystywane-przez-tworcow-trojanow-bankowych/</link>
		<comments>http://www.icewall.pl/2009/07/23/algorytmy-deszyfrowania-wykorzystywane-przez-tworcow-trojanow-bankowych/#comments</comments>
		<pubDate>Thu, 23 Jul 2009 16:12:16 +0000</pubDate>
		<dc:creator>Icewall</dc:creator>
				<category><![CDATA[Analiza]]></category>
		<category><![CDATA[Malware]]></category>
		<category><![CDATA[RE]]></category>
		<category><![CDATA[bho]]></category>
		<category><![CDATA[decryption]]></category>
		<category><![CDATA[deszyfrowanie]]></category>
		<category><![CDATA[encryption]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[szyfrowanie]]></category>
		<category><![CDATA[trojan]]></category>
		<category><![CDATA[trojan bankowy]]></category>
		<category><![CDATA[xor]]></category>

		<guid isPermaLink="false">http://icewall.wordpress.com/?p=197</guid>
		<description><![CDATA[Post otwierający serie postów traktujących o sposobie szyfrowania i deszyfrowania czy to:
- plików konfiguracyjnych
- skradzionych danych
- ciągów znaków reprezentujących np. nazwę winapi 
wykorzystywanym przez twórców trojanów bankowych.
	Przedstawiając kolejne rodziny trojanów  postaram się je ułożyć w kolejności zaczynając od tych stosujących najmniej skomplikowany sposób szyfrowania do tych prezentujących coraz to bardziej złożony rodzaj algorytmów ( [...]]]></description>
			<content:encoded><![CDATA[<p>Post otwierający serie postów traktujących o sposobie szyfrowania i deszyfrowania czy to:<br />
<strong>- plików konfiguracyjnych<br />
- skradzionych danych<br />
- ciągów znaków reprezentujących np. nazwę winapi </strong><br />
wykorzystywanym przez twórców trojanów bankowych.<br />
	Przedstawiając kolejne rodziny trojanów  postaram się je ułożyć w kolejności zaczynając od tych stosujących najmniej skomplikowany sposób szyfrowania do tych prezentujących coraz to bardziej złożony rodzaj algorytmów ( o ile ,którykolwiek z nich można tak określić <img src='http://www.icewall.pl/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> ).<br />
	Pierwszy twór, któremu się przyjrzymy na <strong>VirusTotal</strong> przedstawia się w sposób następujący: <a href="http://www.virustotal.com/analisis/7050369f20acdb4587872ff1eccf43f3cccddf5dc03c7cd6a936a383a6863aac-1240741483">7050369f20acdb4587872ff1eccf43f3cccddf5dc03c7cd6a936a383a6863aac</a><br />
<font color="blue"><b>[=]Dane[=]</b></font></p>
<pre>
Antivirus	Version	Last Update	Result
AhnLab-V3	5.0.0.2	2009.04.26	Dropper/Agent.61440.AF
AntiVir	7.9.0.156	2009.04.25	TR/BHO.gcw
Authentium	5.1.2.4	2009.04.25	W32/Dropper.AHBB
Avast	4.8.1335.0	2009.04.25	Win32:Trojan-gen {Other}
AVG	8.5.0.287	2009.04.26	Dropper.Agent.LCJ
BitDefender	7.2	2009.04.26	Trojan.Generic.1252968
CAT-QuickHeal	10.00	2009.04.25	TrojanDropper.Agent.abjf
Comodo	1130	2009.04.25	TrojWare.Win32.Trojan.Agent.Gen
DrWeb	4.44.0.09170	2009.04.26	Trojan.Fakealert.3764
F-Prot	4.4.4.56	2009.04.25	W32/Dropper.AHBB
F-Secure	8.0.14470.0	2009.04.25	Trojan-Dropper.Win32.Agent.abjf
Fortinet	3.117.0.0	2009.04.26	PossibleThreat
GData	19	2009.04.26	Trojan.Generic.1252968
Ikarus	T3.1.1.49.0	2009.04.26	Trojan-Dropper.Agent
K7AntiVirus	7.10.716	2009.04.25	Trojan-Dropper.Win32.Agent.abjn
Kaspersky	7.0.0.125	2009.04.26	Trojan-Dropper.Win32.Agent.abjf
McAfee	5596	2009.04.25	Generic.dx
McAfee+Artemis	5596	2009.04.25	Generic.dx
McAfee-GW-Edition	6.7.6	2009.04.26	Trojan.BHO.gcw
Microsoft	1.4602	2009.04.26	Trojan:Win32/Relbma.A
NOD32	4035	2009.04.25	Win32/BHO.NDB
Norman		2009.04.24	W32/Agent.KPCN
nProtect	2009.1.8.0	2009.04.26	Trojan-Dropper/W32.Agent.61440.AW
Panda	10.0.0.14	2009.04.26	Generic Trojan
Prevx1	3.0	2009.04.26	High Risk Worm
Sophos	4.41.0	2009.04.26	Mal/Generic-A
Sunbelt	3.2.1858.2	2009.04.24	Trojan-Downloader.Win32.FraudLoad.vdxo
Symantec	1.4.4.12	2009.04.26	Trojan Horse
TheHacker	6.3.4.1.314	2009.04.26	Trojan/Dropper.Agent.abjf
TrendMicro	8.700.0.1004	2009.04.25	TROJ_AGENT.PRPR
VBA32	3.12.10.3	2009.04.25	Trojan-Dropper.Win32.Agent.abjf
VirusBuster	4.6.5.0	2009.04.25	Trojan.DR.Agent.IMHD

Additional information
File size: 61440 bytes
MD5   : fa1faad9a5db4f33173ee0b439e410f6
SHA1  : 5aea25ef14f52930ebc3520a1bf43b1b74573899
SHA256: 7050369f20acdb4587872ff1eccf43f3cccddf5dc03c7cd6a936a383a6863aac
PEiD  : Armadillo v1.71
</pre>
<p>Jak widać nazwy sygnatur, są bardzo ogólne co może wskazywać jedynie na wieeeeele mutacji tej rodziny pojawiających się w sieci.</p>
<p><font color="blue"><b>[=]Prolog[=]</b></font><br />
Tak jak wspominałem wcześniej będziemy się przyglądać trojanom stosującym coraz to bardziej wyrafinowane metody szyfrowania, więc zgodnie z nasza konwencją niniejszy<br />
sampel, a dokładnie metody stosowane przez niego nie powinny szokować( no chyba, że prostotą <img src='http://www.icewall.pl/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> ).<br />
Jakie elementy będą „wymagały” tu deszyfrowania:<br />
<strong>- plik konfiguracyjny<br />
- dll’ka, która jest instalowana w systemie jako <a href="http://en.wikipedia.org/wiki/Browser_Helper_Object">BHO</a><br />
- adres url wskazujący na drop host</strong></p>
<p>Napisałem „wymagały” ,ponieważ tak na dobrą sprawę akurat w tym konkretnym samplu np.autor postanowił ułatwić badaczowi sprawę i plik konfiguracyjny jest dropowany do filesystem’u już po deszyfrowaniu <img src='http://www.icewall.pl/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> . Inna kwestią jest to, że zamiast deszyfrować konkretne elementy, można zrobić dump’a całego procesu i np. w przypadku kiedy config jest deszyfrowany przez trojana tylko i wyłącznie na czas użycia, liczyć na to, że w dump’e znajdziemy go już w <strong>plain-text</strong>’e. Podejść do sprawy jest wiele, ale  w naszych badaniach zależeć nam będzie na tym, żeby poznać algorytm szyfrowania i w miarę możliwości  go odwrócić. Oczywiście zdarzają się przypadki gdzie:<br />
<strong>- nie zależy nam na poznawaniu algorytmu używanego przez trojana, bo jest to sampel należący do rodziny, która widzimy pierwszy raz i nie koniecznie będzie dla nas użyteczny z różnych względów. Wtedy oczywiście idziemy po najmniejsze lini oporu.<br />
- procedura deszyfrująca jest na tyle duża, a my na tyle leniwi ;], lub mało zainteresowani jej odwracaniem nie podejmujemy się pisania dekryptora od zera, ale np. wykorzystujemy prockę używaną przez trojana w charakterze shellcode’u (o tym więcej w dalszych postach).</strong></p>
<p><font color="blue"><b>[=] Analiza [=]</b></font><br />
Ok., pora na analizę naszego celu. Jako, że zależy nam tylko na procedurach (de)szyfrującyh to bezpośrednio będę wskazywał elementy oraz ich lokalizacje, które będą wymagały naszej interwencji. Ewentualne pokaże sposoby na znalezienie interesujących nas części kodu procedur.<br />
Tak na dobrą sprawę wszystkich istotne elementy, które postaramy się deszyfrować znajdują się w zasobach(<strong>‘Resource Directory’</strong>) pliku wykonywalnego. Może podejrzeć zasoby używając do tego celu np.<br />
<strong>CFF Explorer’a:</strong><br />
<a href="http://icewall.files.wordpress.com/2009/07/resource_dirview.jpg"><img src="http://icewall.files.wordpress.com/2009/07/resource_dirview.jpg" alt="resource_dirView" title="resource_dirView" width="497" height="130" class="aligncenter size-full wp-image-201" /></a></p>
<p>Jak widać na powyższym screen’e dane w takiej postaci niczego nam nie mówią, ale w miarę wykonywanej przez nas deszyfracji wszystko stanie się bardziej klarowne. Deszyfrować zwartość zasobów zaczniemy od końca czyli od „WFP”.Zanim zaczniemy, wykonajmy dump zasobu do plik np.<br />
<strong>C:\config i sprawdźmy jego entropię:</strong><br />
<a href="http://icewall.files.wordpress.com/2009/07/config_entropy.jpg"><img src="http://icewall.files.wordpress.com/2009/07/config_entropy.jpg" alt="config_entropy" title="config_entropy" width="497" height="268" class="aligncenter size-full wp-image-202" /></a></p>
<p>Już spieszę z wyjaśnieniami. Skala, którą widać po prawej reprezentuje poziom entropii w zakresie od <strong>0-8</strong>. Tak jak obiecywałem algorytm(y) szyfrowania użyty w tym trojanie będzie prosty o czym już teraz możemy się przekonać analizując wykres. Wartości funkcji, są dość nie regularne i rozciągają się <strong>w zakresie od 4,2 do 5,4.</strong> Od razu wspomnę, że ciekawszych procek szyfrujących można się spodziewać w przypadku entropii na poziomie 7-8.<br />
Dla porównania wykres entropii dump’a traffic’u zawierającego dll’ki, ściągane przez <strong>Mebroot’a:</strong><br />
<a href="http://icewall.files.wordpress.com/2009/07/cc_response_entropy.jpg"><img src="http://icewall.files.wordpress.com/2009/07/cc_response_entropy.jpg" alt="C&amp;C_response_entropy" title="C&amp;C_response_entropy" width="443" height="275" class="aligncenter size-full wp-image-203" /></a></p>
<p><font color="blue"><b>[=]Analiza procedur szyfrujących[=]</b></font><br />
Jak już wiemy interesujące nas bloki danych znajdują się w resource directory. Teraz rodzi się pytanie w jaki sposób odnaleźć funkcje (de)szyfrującą/e? Każdy kto pisał aplikacje z użyciem winapi, korzystającą z katalogu zasobów skojarzył od razu  funkcje <strong>„FindResourceA/W”,</strong> która zwraca uchwyt do zasobu, którego nazwę podamy jako jeden z parametrów tego api.<br />
Więc nasuwają się tutaj dwa podejścia, a tak naprawdę jedno chyba najbardziej logiczne ;].<br />
<strong>- wyszukać wszystkie referencje do wywołań api FindResourceA/W<br />
albo odnaleźć wszystkie referencje do stringu „WFP” .</strong></p>
<p>Oczywiście  posłużymy się tutaj podejściem drugim które najprawdopodobniej od razu wskaże nam okolice kodu zawierającego procedurę deszyfrującą.<br />
<a href="http://icewall.files.wordpress.com/2009/07/wfp_resource.jpg"><img src="http://icewall.files.wordpress.com/2009/07/wfp_resource.jpg" alt="wfp_resource" title="wfp_resource" width="497" height="294" class="aligncenter size-full wp-image-204" /></a></p>
<p>Ohoo…wygląda na strzał w dziesiątkę, co prawda na razie nie widać jakichkolwiek manipulacji na uzyskanym pointerze do zasobu, zerknijmy jednak do procedury :<br />
<strong>CALL zly_troj.0040155F</strong><br />
mając na uwadze, że argumentami tej procki są:<br />
<strong>arg1 : pointer do zasobu „WFP”<br />
arg2 : rozmiar zasobu „WFP”</strong></p>
<p><a href="http://icewall.files.wordpress.com/2009/07/wfp_decryption_proc.jpg"><img src="http://icewall.files.wordpress.com/2009/07/wfp_decryption_proc.jpg" alt="wfp_decryption_proc" title="wfp_decryption_proc" width="497" height="272" class="aligncenter size-full wp-image-205" /></a><br />
Ahhh udało nam się zlokalizować prockę deszyfrującą!(zielona ramka).<br />
Jak widać okazała się nią prosta operacja xorująca każdy bajt z kluczem o wartości:<br />
<strong>0&#215;13.</strong></p>
<p><font color="blue"><b>[=]Deszyfrowanie[=]</b></font><br />
Oczywiście po tym co właśnie zobaczyliśmy stworzenie własnego deszyfratora, który „sksoruje”, każdy bajt dumpu zasobu, który wcześniej wykonaliśmy z kluczem <strong>0&#215;13</strong>.<br />
Świetnie się do tego nada <strong>JEDNOLINIJKOWY</strong> skrypt w python’e:</p>
<pre class="brush: python">&quot;&quot;.join(map(lambda x: chr(ord(x)^0x13),file(r&#039;C:\config&#039;,&#039;rb&#039;).read()))</pre>
<p>, a oto rezultat:<br />
<a href="http://icewall.files.wordpress.com/2009/07/decrypted_wfp.jpg"><img src="http://icewall.files.wordpress.com/2009/07/decrypted_wfp.jpg" alt="decrypted_wfp" title="decrypted_wfp" width="497" height="532" class="aligncenter size-full wp-image-206" /></a><br />
widać teraz, że rzeczywiście jest to plik konfiguracyjny zapisany w <strong>xml’u.</strong></p>
<p>Przejdźmy do następnego zasobu.<br />
<strong>„REM”</strong><br />
Rzućmy okiem na entropię:<br />
<a href="http://icewall.files.wordpress.com/2009/07/rem_entropy.jpg"><img src="http://icewall.files.wordpress.com/2009/07/rem_entropy.jpg" alt="rem_entropy" title="rem_entropy" width="497" height="266" class="aligncenter size-full wp-image-207" /></a><br />
Mhmm…tutaj już entropia wygląda ciekawiej, więc z pewnością możemy się spodziewać czegoś więcej niż tylko prostego xor’owania.<br />
Oczywiście, miejsce z istotną dla nas procką znajdujemy analogicznie do poprzedniego przypadku, a naszym oczom ukazuje się taki o to kod:<br />
<a href="http://icewall.files.wordpress.com/2009/07/rem_decryption_routine1.jpg"><img src="http://icewall.files.wordpress.com/2009/07/rem_decryption_routine1.jpg" alt="rem_decryption_routine" title="rem_decryption_routine" width="497" height="415" class="aligncenter size-full wp-image-209" /></a></p>
<p>Jak widzimy, w tym przypadku klucz xor’ujący nie jest stały. Jego wartość będzie zmieniała się cyklicznie po każdej iteracji, stąd też widoczne na wykresie entropii zmiany w kierunku wyższego zbioru wartości.<br />
Warto zwrócić uwagę na dwie istotne kwestie, które są wykonywane przed wejściem do pętli:</p>
<pre>
ESI – pointer na zaalokowaną pamięć, która będzie zawierać deszyfrowane dane.
004013CD  |.  C606 4D       MOV BYTE PTR DS:[ESI],4D
004013D3  |.  C646 01 5A    MOV BYTE PTR DS:[ESI+1],5A
</pre>
<p><strong>4D5A</strong> ,czy coś wam to mówi ?:D. Oczywiście jest to magic number, który zawsze powinien znaleźć się na początku pliku <strong>PE</strong>.<br />
Jak widać autor trojana dodaje magic number dopiero w momencie deszyfrowania. Takie podejście może świadczyć jedynie o tym iż autor chciał utrudnić wykrycie potencjalnie niebezpiecznego zasobu antywirusą czy innym skanerą. Drugą kwestią jest wyliczenie stałej która będzie wykorzystywana do indexowania zaszyfrowanych danych. Jej wyliczenie wygląda następująco:</p>
<pre>
004013D9  |.  895D FC       MOV [LOCAL.1],EBX ; EBX = encrypted_data
004013DC  |.  2975 FC       SUB [LOCAL.1],ESI     ; ESI   = decrypted_data
</pre>
<p>następnie w pętli mamy: (stale wartości odpowiednie do pierwszej iteracji)</p>
<pre>
EDI = 2 ;
004013E5  |.  8D0C37        |LEA ECX,DWORD PTR DS:[EDI+ESI]
…
004013EA  |.  8B45 FC       |MOV EAX,[LOCAL.1]
…
004013EF  |.  321408        |XOR DL,BYTE PTR DS:[EAX+ECX]
</pre>
<p>widzimy, że w momencie xor’owania :<br />
<strong>DL – cyklicznie zmieniający się klucz</strong><br />
<strong>a na co wskazuje BYTE PTR DS:[EAX+ECX]?</strong><br />
Prosty zapis matematyczny wszystko wyjaśnia:</p>
<pre>
LOCAL.1 = encrypted_data - decrypted_data
ECX = decrypted_data + 2
EAX = LOCAL.1
I w momencie xor’owania:
XOR DL,BYTE PTR DS:[LOCAL.1+decrypted_data+2]
podstawiajac za LOCAL.1
XOR DL,BYTE PTR DS:[ encrypted_data - decrypted_data
+decrypted_data+2]
,więc w ostateczności mamy
XOR DL,BYTE PTR DS:[ encrypted_data + 2]
</pre>
<p>ot taki troszeczkę nie intuicyjny sposób indexowania <img src='http://www.icewall.pl/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .<br />
Przykładowy skrypt deszyfrujący:</p>
<pre class="brush: python">
def decrypt(encrypted):
    decrypted = []
    edi = 2
    decrypted.append(&#039;M&#039;)# 0x4d
    decrypted.append(&#039;Z&#039;)# 0x5a

    while edi != len(encrypted):
        edx = edi % 0x78
        edx = (edx &lt;&lt; 1) &amp; 0xFF
        decrypted.append(chr( (ord(encrypted[edi])^edx)&amp;0xFF ))
        edi = edi + 1
    return &quot;&quot;.join(decrypted)

if __name__ == &quot;__main__&quot;:

    f = file(r&quot;c:\evil_dll&quot;,&#039;rb&#039;)
    fw = file(r&quot;c:\decrypted_evil_dll&quot;,&#039;wb&#039;)
    fw.write(decrypt(f.read()))
    f.close()
    fw.close()
</pre>
<p><strong>i rezultat deszyfrowania:</strong><br />
<a href="http://icewall.files.wordpress.com/2009/07/decrypted_dll.jpg"><img src="http://icewall.files.wordpress.com/2009/07/decrypted_dll.jpg" alt="decrypted_dll" title="decrypted_dll" width="497" height="376" class="aligncenter size-full wp-image-210" /></a><br />
Jak widać na screen’e w katalogu zasobów <strong>„REM”</strong> ukrywała się dll’ka.</p>
<p>Ostatni już katalog zasobów <strong>„CAS”</strong>. Jako, że danych w każdej pozycji katalogu <strong>CAS</strong> jest niewiele, trudno tutaj mówić/prezentować wykres rozkładu entropii. Przejdziemy więc od razu do sposobu ich deszyfrowania. Co prawda dane z tego zasobu, są ekstraktowane do systemu , (a dokładnie do rejestru )lecz w formie nie zmienionej. Dopiero dll’ka , która wcześniej mieliśmy przyjemność deszyfrować(a która jest dropowana do  <strong>C:\WINDOWS\system32\sxmg4.dll</strong> i rejestrowana jako <strong>BHO</strong>)<br />
będzie pobierała te dane i deszyfrowała tylko w momencie zaistniałem potrzeby.</p>
<p>Zaszyfrowane dane w rejestrze prezentują się w następujący sposób(i<strong>nteresują nas tylko wartości Ad i Ad2</strong>):<br />
<a href="http://icewall.files.wordpress.com/2009/07/cas_encrypted.jpg"><img src="http://icewall.files.wordpress.com/2009/07/cas_encrypted.jpg" alt="cas_encrypted" title="cas_encrypted" width="497" height="163" class="aligncenter size-full wp-image-211" /></a><br />
<em>HKEY_LOCAL_MACHINE\SOFTWARE\TSoft</em></p>
<p>Ok, weźmy pod lupę więc dll’ke: Stosując identyczne podejście jak w dwóch poprzednich przypadkach znajdujemy następujący kod:<br />
<a href="http://icewall.files.wordpress.com/2009/07/cas_decryption.jpg"><img src="http://icewall.files.wordpress.com/2009/07/cas_decryption.jpg" alt="cas_decryption" title="cas_decryption" width="465" height="380" class="aligncenter size-full wp-image-212" /></a><br />
Kolejna różna od pozostałych procedura bazująca wciąż na xor’owaniu, lecz tym razem użyto stałego klucza o długości <strong>3 bytów</strong>. Warto wspomnieć jakie konsekwencje niesie za sobą takie podejście oraz jak to rozwiązano w niniejszej implementacji:</p>
<pre>
ECX = ilość odczytanych(zaszyfrowanych) bajtów z wartości rejestru
100053B0  |.  6A 02         PUSH 2
100053B2  |.  33C0          XOR EAX,EAX
100053B4  |.  5A            POP EDX
100053B5  |.  889C0D F0FDFF&gt;MOV BYTE PTR SS:[EBP+ECX-210],BL
100053BC  |.  3BCA          CMP ECX,EDX
100053BE  |.  76 31         JBE SHORT sxmg4.100053F1
</pre>
<p>Jak widać sprawdzane jest tutaj czy ilość bajtów które mają być odszyfrowane przekracza 2, ponieważ przy mniejszej ilości, w pętli już po pierwszej iteracji dostalibyśmy błędne dane (<strong>akurat przy tej implementacji nie wystąpi ,ani BO ani Off-by-One</strong>). To jedna kwestia, kolejną jest to, że długość danych do rozszyfrowania może nie być wielokrotnością 3’ki.<br />
Więc należy tutaj zadbać o sprawdzanie czy w kolejnym kroku deszyfrowania mamy przynajmniej 3 bajt do przetworzenia. Jeśli nie, pętla powinna się zakończyć a pozostałe bajty(<strong> max 2</strong>) należy deszyfrować indywidualnie.<br />
Sprawdźmy jak to zostało tu zaimplementowane:<br />
Przed wejściem do pętli mamy :</p>
<pre>
EDX = 2
100053C0  |.  8DB5 F1FDFFFF LEA ESI,DWORD PTR SS:[EBP-20F]
100053C6  |.  2BD6                     SUB EDX,ESI
EBP – 210h = encrypted_data
,więc EBP – 20Fh == encrypted_data +1
</pre>
<p>w pętli:</p>
<pre>
…
100053E3  |.  8D3402        |LEA ESI,DWORD PTR DS:[EDX+EAX]
100053E6  |.  8DB435 F1FDFF&gt;|LEA ESI,DWORD PTR SS:[EBP+ESI-20F]
100053ED  |.  3BF1          |CMP ESI,ECX
100053EF  |.^ 72 D7         \JB SHORT sxmg4.100053C8
</pre>
<p>kiedy przyjrzymy się temu kawałkowi kodu mamy:</p>
<pre>
ECX = encrypted_data_length
EAX = index
EDX = 2 – (encrypted_data+1)
ESI = EDX + EAX
ESI &lt;-  EBP + ESI – 20F == EBP -20F + ESI ==
(encrypted_data+1) + 2 –(encrypted_data+1)+ index
czyli ostatecznie
ESI = 2+index
</pre>
<p>,więc co iteracje w pętli(<strong> a jest to pętla do while</strong>) sprawdzane jest czy<br />
<strong>index+2 &lt; encrypted_data_length</strong>, jeżeli tak to pętla jest kontynuowana.<br />
Po zakończeniu pętli możemy zauważyć to o czym wspominałem, a mianowicie indywidualne xor’owanie bajtów, które pozostały lub w przypadku kiedy długość zaszyfrowanych danych <strong>&lt; 3</strong>:</p>
<pre>
100053F1  |&gt; \3BC1          CMP EAX,ECX
100053F3  |.  73 08         JNB SHORT sxmg4.100053FD
100053F5  |.  80B405 F0FDFF&gt;XOR BYTE PTR SS:[EBP+EAX-210],0F
100053FD  |&gt;  8D50 01       LEA EDX,DWORD PTR DS:[EAX+1]
10005400  |.  3BD1          CMP EDX,ECX
10005402  |.  73 0F         JNB SHORT sxmg4.10005413
10005404  |.  80B405 F1FDFF&gt;XOR BYTE PTR SS:[EBP+EAX-20F],10
</pre>
<p><strong>Prosty kod który powinien działać <img src='http://www.icewall.pl/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />   przy dowolnej długości klucza:</strong></p>
<pre class="brush: python">
def decrypt(buffer,key):
    decrypted = []
    notAligned = len(buffer) % len(key)
    secureLen  = len(buffer) - notAligned
    for i in range(0,secureLen,len(key)):
        for j in range(0,len(key)):
            decrypted.append( chr( ord(buffer[i+j])^key[j] ) )
    #dekrypcja pozostalych NIE odszyfrowanych bajtow o ile takie istnieja
    if notAligned:
        for i in range(secureLen,len(buffer)):
            decrypted.append( chr( ord(buffer[i])^ key[-secureLen+i]) )

    return &quot;&quot;.join(decrypted)

if __name__ == &quot;__main__&quot;:
    key  = [0xf,0x10,0x11]
    print decrypt(file(&quot;c:\\evil_host1&quot;).read(),key)
    print decrypt(file(&quot;c:\\evil_host2&quot;).read(),key)
</pre>
<p>oto rezultat działania kodu:<br />
<strong>(evil_host1 i evil_host2 to oczywiście wartości z rejestru Ad1 i Ad2)</strong><br />
<a href="http://icewall.files.wordpress.com/2009/07/decrypted_hosts_cas.jpg"><img src="http://icewall.files.wordpress.com/2009/07/decrypted_hosts_cas.jpg" alt="decrypted_hosts_cas" title="decrypted_hosts_cas" width="497" height="344" class="aligncenter size-full wp-image-213" /></a><br />
Jak widać zaszyfrowane dane przedstawiają najprawdopodobniej adresy drop hostów, albo hostów z których mają być pobierane dodatkowe moduły, nowe plik konfiguracyjne ,etc.</p>
<p><font color="blue"><b>[=]Epilog[=]</b></font><br />
To już wszystko odnośnie tego trojana, jak mieliśmy okazje zobaczyć jego autor „nie ograniczał” swojej fantazji jeżeli chodzi o rożnego typu algorytmy szyfrowania choć bazowały one na prostym xor’owaniu to jednak zobaczyliśmy parę mutacji;]. Wspomnę jeszcze, że trojan ten zawiera jeszcze parę zaszyfrowanych bloków danych jednak ze względu na identyczne metody dekodowania ( zmienia się np. klucz xor’ujacy z 0&#215;13 na 0xc) postanowiłem je pominąć. W następnych postach (o ile czas w najbliższym okresie wakacyjnym pozwoli <img src='http://www.icewall.pl/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> ) zajmiemy się trochę bardziej złożonymi algorytmami, sposobami ustalania formatu pliku konfiguracyjnego ,etc.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.icewall.pl/2009/07/23/algorytmy-deszyfrowania-wykorzystywane-przez-tworcow-trojanow-bankowych/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
