Hello all
I wrote a little file extractor that uses wowb.exe to extract files from the client. It features a file list from TOM_RUS that contains about 421k file names.
Usage:
1. Rename your wowb-64.exe to something else (like wowb-642.exe) if you are using an x64 system
2. Open wowb.exe
3. Launch extractor.exe
4. Select wowb.exe process
5. Choose the output directory where the files should get extracted to
6. Choose the file list
7. Choose the path to the dll (if its in the same folder than the extractor you can leave this like it is)
8. Hit Launch
9. Wait
10. Wait even more
11. Wait like 2 hours
12. ??
13. Profit
UPDATES:
DLL only for 18379 (you need to download V2 and replace the injected_32.dll with this one): http://www22.zippyshare.com/v/2607494/file.html
Download:
V2:
http://www.file-upload.net/download-...actor.rar.html
V1:
File-Upload.net - WoD_Extractor.rar
Image:
VS:
Extractor: https://www.virustotal.com/de/file/e...is/1396982391/
DLL: https://www.virustotal.com/de/file/c...is/1396982478/
The virus scan once more shows how useless they are. The Extractor opens a process and tries to inject a dll and call various functions from that dll in the remote process but still only one scanner triggers something suspicious as im calling native functions from .NET...
Source code for the DLL (for updates):
Code:
#include "stdafx.h"
#include <filesystem>
#include <fstream>
#include <string>
#include <iostream>
#include <vector>
#include <sstream>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
#define BUILD_18379
static unsigned int baseAddress = (unsigned int) GetModuleHandle(nullptr);
static std::string outDir;
static SOCKET connSocket;
static bool hasProgress = false;
static SOCKADDR_IN destAddr;
unsigned int GetWowBase() {
return baseAddress;
}
void extractFiles(const std::string& fileName) {
typedef DWORD CASFILE;
typedef BOOL(*pCASOpenFile)(char *srcfile, int srcline, const char *name, CASFILE *pFile, int flags);
typedef BOOL(*pCASReadFile)(CASFILE pFile, uint8_t *buffer, int size);
typedef void(*pCASCloseFile)(CASFILE pFile);
typedef DWORD(*pCASGetFileSize)(CASFILE pFile);
#ifdef BUILD_18322
pCASOpenFile CASOpenFile = pCASOpenFile(GetWowBase() + 0x12875);
pCASReadFile CASReadFile = pCASReadFile(GetWowBase() + 0x10FEF);
pCASCloseFile CASCloseFile = pCASCloseFile(GetWowBase() + 0x127BB);
pCASGetFileSize CASGetFileSize = pCASGetFileSize(GetWowBase() + 0x1125B);
#endif
#ifdef BUILD_18322
pCASOpenFile CASOpenFile = pCASOpenFile(GetWowBase() + 0x12CB5);
pCASReadFile CASReadFile = pCASReadFile(GetWowBase() + 0x11445);
pCASCloseFile CASCloseFile = pCASCloseFile(GetWowBase() + 0x12BFB);
pCASGetFileSize CASGetFileSize = pCASGetFileSize(GetWowBase() + 0x11747);
#endif
#ifdef BUILD_18379
pCASOpenFile CASOpenFile = pCASOpenFile(GetWowBase() + 0x12AA6);
pCASReadFile CASReadFile = pCASReadFile(GetWowBase() + 0x114E6);
pCASCloseFile CASCloseFile = pCASCloseFile(GetWowBase() + 0x129EC);
pCASGetFileSize CASGetFileSize = pCASGetFileSize(GetWowBase() + 0x117E8);
#endif
if (hasProgress) {
std::vector<uint8_t> data(3 + fileName.length() + 1);
data[0] = 1;
uint16_t lenName = fileName.length() + 1;
*(uint16_t*) &data[1] = lenName;
memcpy(&data[3], fileName.c_str(), fileName.length());
send(connSocket, (char*) data.data(), data.size(), 0);
}
CASFILE file = 0;
if (CASOpenFile(__FILE__, __LINE__, fileName.c_str(), &file, 0)) {
DWORD size = CASGetFileSize(file);
if (size > 0) {
std::vector<uint8_t> content(size);
if (CASReadFile(file, content.data(), size)) {
std::stringstream strm;
strm << outDir << fileName.c_str();
auto path = std::tr2::sys::path(strm.str());
std::tr2::sys::create_directories(path.branch_path());
std::ofstream os(path.string(), std::ios::binary);
os.write((const char*)content.data(), content.size());
os.close();
} else {
std::cout << "Reading failed" << std::endl;
}
} else {
std::cout << "File empty" << std::endl;
}
CASCloseFile(file);
}
else {
std::cout << "Extracting: " << fileName << "... ";
std::cout << " failed!" << std::endl;
}
}
static std::ifstream inFile;
static std::string line;
struct InitParams
{
char outDir[1024];
char fileList[1024];
bool hasProgress;
};
void loadParams(InitParams* ip) {
outDir = std::tr2::sys::path(ip->outDir).string();
if (outDir[outDir.length() - 1] != '/') {
outDir += "/";
}
}
extern "C" {
__declspec(dllexport) LRESULT WINAPI ExtractThread(LPVOID params) {
InitParams* ip = (InitParams*) params;
loadParams(ip);
if (ip->hasProgress) {
connSocket = socket(AF_INET, SOCK_STREAM, 0);
if (connSocket != INVALID_SOCKET) {
hasProgress = true;
memset(&destAddr, 0, sizeof(SOCKADDR_IN));
destAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
destAddr.sin_port = htons(56789);
destAddr.sin_family = AF_INET;
int rc = connect(connSocket, (const sockaddr*) &destAddr, sizeof(destAddr));
if (rc < 0) {
hasProgress = false;
}
}
}
inFile.open(ip->fileList);
while (std::getline(inFile, line)) {
__try {
extractFiles(line);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
}
}
if (hasProgress) {
char fin = 0;
send(connSocket, &fin, 1, 0);
closesocket(connSocket);
}
ExitThread(0);
}
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
Greetings
Cromon