/* * WinfingerPrint 2 Development Code * Copyright (C) 1999-2000 Kirby Kuehl (vacuum@technotronic.com) * * Contributors: * vacuum@technotronic.com * mike@datanerds.net * hoglund@ieway.com * napster@napster.com * Jason_Jordan@omron.com * sfaust@hartco.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 1, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef UNICODE #define UNICODE #endif #include #include #include #include #include #include #include #include #include "getopt.h" #include /* Now we link the following libs automatically this should stop the "It won't compile for me emails :) */ #pragma comment( lib, "netapi32" ) #pragma comment( lib, "mpr" ) #pragma comment( lib, "advapi32" ) #pragma comment( lib, "shell32" ) using namespace std; //int (char *); int diskenum(LPWSTR); int diskenum95(LPWSTR); int querygroup(LPTSTR); int queryuser(LPTSTR); int queryservices(LPTSTR); int NullSession(LPTSTR); int NullDisconnect(LPTSTR); int RegConnection(LPTSTR); int winfingerprint(LPTSTR); int querytransport(LPTSTR); int querytime(LPTSTR); int DisplayEntries(LPTSTR); void getnetwork(LPNETRESOURCE, char *); void UnicodeToASCII(wchar_t *, char *); void DisplayUsage (char *); void options_launcher(int ,LPTSTR); wstring ErrorHandle(); #define SZ_ENUM_BUF 4096 #define VERSION "Winfingerprint 2.28" FILE *stream, *menu; struct option long_options[] = { {"shares", no_argument, 0, 'D'}, {"groups", no_argument, 0, 'G'}, {"users", no_argument, 0, 'U'}, {"null", no_argument, 0, 'N'}, {"registry", no_argument, 0, 'R'}, {"all", no_argument, 0, 'A'}, {"mass", no_argument, 0, 'M'}, {"services", no_argument, 0, 'S'}, {"host", required_argument, 0, 'T'}, {"output", required_argument, 0, 'O'}, {"transports",no_argument, 0, 'B'}, {"sessions", no_argument, 0, 'C'}, {"eventlog", no_argument, 0, 'E'}, {"time", no_argument, 0, 'F'}, {"help", no_argument, 0, 'H'}, {"usage", no_argument, 0, 'H'}, {0, 0, 0, 0} }; // I DECIDED TO PUT THE OPTIONS VAR GLOBALY /********************************************* The options will be split in the bits position Bits : 0 -> optdiskenum 1 -> optquerygroup 2 -> optqueryuser 3 -> optqueryservices 4 -> optnull 5 -> optservername 6 -> optreg 7 -> optmass -> Since the output option is not very related with the scanning methods and it is not use globally, we take it apart. **********************************************/ struct our_opts { unsigned int optdiskenum; unsigned int optquerygroup; unsigned int optqueryuser; unsigned int optqueryservices; unsigned int optnull; unsigned int optservername; unsigned int optreg; unsigned int optmass; unsigned int opttransport; unsigned int optevent; unsigned int opttime; unsigned int optsessions; unsigned int optshares; } options; int wmain(int argc, wchar_t *argv[], char *newargv[]){ LPTSTR pszServerName = NULL; LPNETRESOURCE cont_obj = NULL; // This is used when optmass is set int opt, j, option_index=0, output = 0; FILE *frame; char buffer[_MAX_PATH], cmd[_MAX_PATH], *filename; // Fill another argv[] but we use this for getopt() for(j = 0; j < argc; j++) UnicodeToASCII(argv[j], newargv[j]); if (argc <= 1) DisplayUsage(newargv[0]); while ((opt=getopt_long_only(argc, newargv,"T:O:BCEFDGUSNRMA?H",long_options, &option_index)) != EOF) { switch(toupper(opt)){ case 'B': // Enumerate Transports options.opttransport = 1; break; case 'C': // Enumerate Sessions options.optsessions = 1; break; case 'D': // Enumerate NetBIOS Shares. options.optshares = 1; break; case 'E': // Event Log options.optevent = 1; break; case 'F': // Date & Time options.opttime = 1; break; case 'G': // Enumerate Groups. options.optquerygroup = 1; break; case 'U': // Enumerate Users. options.optqueryuser = 1; break; case 'S': // Enumerate Services. options.optqueryservices = 1; break; case 'N': // Creates Null Session options.optnull = 1; break; case 'T': // Computer name is here. pszServerName = (unsigned short *)malloc(sizeof(unsigned short *)); MultiByteToWideChar(CP_ACP,0,optarg,-1,pszServerName,15); // Max Length of a machine name is 15 characters. options.optservername = 1; break; case 'R': // Registry Manipulation options.optreg = 1; break; case 'M': // 'Network Neighborhood' Scan options.optmass = 1; break; case 'A': // We do all. options.optdiskenum = 1; options.optquerygroup = 1; options.optqueryuser = 1; options.optqueryservices = 1; options.optreg = 1; options.opttransport = 1; options.optevent = 1; options.opttime = 1; options.optsessions = 1; options.optshares = 1; break; case 'O': // HTML Output filename output = 1; filename = optarg; break; case 'H': // Show usage. DisplayUsage(newargv[0]); break; case 0: case '?': // Show usage. DisplayUsage(newargv[0]); break; default: // We do all. DisplayUsage(newargv[0]); } } printf("%s by vacuum@technotronic.com & mike@datanerds.net 1999-2000\n", VERSION); if((!options.optmass) && (!options.optservername)){ fprintf(stderr, "You must specify a 'Network Neighboorhood' scan <-mass> or Computername. <-host \\\\computername>\n"); exit(1); } if((options.optmass) && (options.optservername)){ fprintf(stderr, "You specified a 'Network Neighboorhood' scan and a Computername.\nPlease choose one or the other.\n"); exit(1); } if(options.optnull && !options.optmass && !options.optservername){ fprintf(stderr, "You specified a 'Null Session' scan and did not choose a mass scan or a Servername.\nPlease choose one and try again.\n"); exit(1); } if(!output) filename = "winfingerprint.html"; if( (stream = fopen(filename, "w" )) == NULL ){ fprintf(stderr, "The file '%s' was not opened\n",filename); exit(-1); } fprintf(stream, "\n\n%s output\n\n", VERSION); fprintf(stream, "\n\n"); fprintf(stream, "
\"%s\"SRC
\n", VERSION); fprintf(stream, "by vacuum@technotronic.com\n"); fprintf(stream, "About %s
\n", VERSION); if( (menu = fopen("menu.html", "w" )) == NULL ){ fprintf(stderr, "The file 'menu.html' was not opened\n"); exit(-1); } fprintf(menu,"\n\nWinfingerprint Menu\n\n\n"); fclose(menu); if( (frame = fopen("frame.html", "w" )) == NULL ){ fprintf(stderr, "The file 'frame.html' was not opened\n"); exit(-1); } fprintf(frame, "\n\nWinfingerprint\n\n"); fprintf(frame, "\n"); fprintf(frame, "\n"); fprintf(frame, "\n",filename); fprintf(frame, "\n\n"); fclose(frame); fprintf(stdout, "Enumerating Available Servers, Please wait ...\n"); if(options.optmass) getnetwork(cont_obj, filename); else{ if( (menu = fopen("menu.html", "w" )) == NULL ){ fprintf(stderr, "The file 'menu.html' was not opened\n"); exit(-1); } fprintf(menu,"%S
\n", pszServerName + 2); fprintf(menu,"
  • Shares\n",filename, pszServerName + 2); fprintf(menu,"
  • Groups\n",filename, pszServerName + 2); fprintf(menu,"
  • Users\n",filename, pszServerName + 2); fprintf(menu,"
  • Services\n",filename, pszServerName + 2); fprintf(menu,"
  • Registry
\n",filename, pszServerName + 2); options_launcher(winfingerprint(pszServerName), pszServerName); } fprintf(stdout,"\nDone.\n\n"); fprintf(stream,"
\n\n"); fclose(stream); fclose(menu); if( _getcwd( buffer, _MAX_PATH ) == NULL ) fprintf(stderr, "_getcwd error\n"); else{ strcat(buffer, "\\frame.html"); fprintf(stderr, "Launching explorer\n"); _snprintf(cmd, sizeof(cmd), "file://%s",buffer); ShellExecuteA(NULL, "open", cmd, NULL, NULL, SW_SHOWNORMAL); } return 0; } int diskenum(LPWSTR computername){ PSHARE_INFO_502 BufPtr,p; NET_API_STATUS res; DWORD i; DWORD entriesread=0, resume_handle=0, totalentries=0; fprintf(stream,"

NetBIOS Share Results:
\n"); res = NetShareEnum(computername, 502, (LPBYTE *) &BufPtr, 0xFFFFFFFF, &entriesread, &totalentries, &resume_handle); if(res == ERROR_SUCCESS || res == ERROR_MORE_DATA){ fprintf(stream, "\n",computername + 2); fprintf(stream, "\n", computername + 2); NetApiBufferFree(BufPtr); } do{ res = NetShareEnum(computername, 502, (LPBYTE *) &BufPtr, 0xFFFFFFFF, &entriesread, &totalentries, &resume_handle); if(res == ERROR_SUCCESS || res == ERROR_MORE_DATA){ p=BufPtr; for(i=1;i<=entriesread;i++){ // fprintf(stream,"",p->shi502_netname, p->shi502_path, p->shi502_current_uses); fprintf(stream,"",computername,p->shi502_netname,p->shi502_netname, p->shi502_path, p->shi502_current_uses); if (IsValidSecurityDescriptor(p->shi502_security_descriptor)) fprintf(stream,"\n"); else fprintf(stream,"\n"); p++; } NetApiBufferFree(BufPtr); fprintf(stream,"
Shares:Local Path:Uses:Descriptor:
%S's Shares:Local Path:Uses:Descriptor:
<%-20S%-30S%-8u
%-20S%-30S%-8uYes
No
"); return(0); } else { fprintf(stderr,"Share Enumeration Error (%d):\n %S\n" ,GetLastError(), ErrorHandle().begin()); return(3); // Return 3 on error so we can run diskenum95() } }while (res==ERROR_MORE_DATA); fprintf(stream,""); return(0); } int diskenum95(LPTSTR computername){ PSHARE_INFO_1 BufPtr,p; NET_API_STATUS res; DWORD i = 0; DWORD entriesread=0, resume_handle=0, totalentries=0; fprintf(stream, "

\n"); if(computername == NULL) fprintf(stream,"\n"); else { fprintf(stream, "\n",computername + 2); fprintf(stream,"\n", computername + 2); } do{ res = NetShareEnum(computername, 1, (LPBYTE *) &BufPtr, 0xFFFFFFFF, &entriesread, &totalentries, &resume_handle); if(res == ERROR_SUCCESS || res == ERROR_MORE_DATA){ p = BufPtr; for(i=0;i",computername, p->shi1_netname, p->shi1_netname, p->shi1_type, p->shi1_remark); // fprintf(stream,"",computername,p->shi1_netname,p->shi1_netname, p->shi1_type, p->shi1_remark); p++; } NetApiBufferFree(BufPtr); } else{ fprintf(stderr,"Share Enumeration Error (%d):\n %S\n" ,GetLastError(), ErrorHandle().begin()); printf("Attempting to obtain NetBIOS shares using lower security setting\n"); return(-1); } }while (res==ERROR_MORE_DATA); fprintf(stream,"
Shares:Type:Comment:
%S's Shares:Type:Comment:
%S%u%S
%S%-30S%-8u
"); return(0); } int querygroup(LPTSTR szServer){ PNET_DISPLAY_GROUP pBuff, p; DWORD res, dwRec, i = 0; do{ res = NetQueryDisplayInformation(szServer, 3, i, 1000, 25, &dwRec, (PVOID *)&pBuff); if((res==ERROR_SUCCESS) || (res==ERROR_MORE_DATA)){ p = pBuff; fprintf(stream, "\n",szServer + 2); fprintf(stream, "

Group Query Results:
\n"); fprintf(stream, "\n"); for(;dwRec>0;dwRec--) { fprintf(stream,"\n" "\n" "\n" "\n" "\n", p->grpi3_name, p->grpi3_comment, p->grpi3_group_id, p->grpi3_attributes); i = p->grpi3_next_index; //if there is more then set the index p++; } NetApiBufferFree(pBuff); fprintf(stream, "
Name:Comment:Group ID:Attributes:
%S%S%u%u
\n"); return(0); } else{ if((res==ERROR_SUCCESS) || (res==ERROR_MORE_DATA)) fprintf(stderr,"Group Enumeration Error:(%u)\n %S\n" ,res, ErrorHandle().begin()); return(-1); } }while (res==ERROR_MORE_DATA); } int queryuser(LPTSTR szServer){ PNET_DISPLAY_USER pBuff, p; DWORD res, dwRec, i = 0; do{ res = NetQueryDisplayInformation(szServer, 1, i, 1000, 1000*sizeof(NET_DISPLAY_USER), &dwRec, (PVOID *)&pBuff); if((res==ERROR_SUCCESS) || (res==ERROR_MORE_DATA)){ p = pBuff; fprintf(stream, "
\n",szServer); fprintf(stream, "

User Query Results:
\n"); fprintf(stream, "\n"); for(;dwRec>0;dwRec--){ fprintf(stream, "\n" "\n" "\n" "\n" "\n", p->usri1_name, p->usri1_comment, p->usri1_full_name, p->usri1_user_id); if (p->usri1_flags & UF_SCRIPT) fprintf(stream,"\n"); if (p->usri1_flags & UF_ACCOUNTDISABLE) fprintf(stream,"\n"); if (p->usri1_flags & UF_HOMEDIR_REQUIRED) fprintf(stream,"\n"); if (p->usri1_flags & UF_PASSWD_NOTREQD) fprintf(stream,"\n"); if (p->usri1_flags & UF_PASSWD_CANT_CHANGE ) fprintf(stream,"\n"); if (p->usri1_flags & UF_LOCKOUT) fprintf(stream,"\n"); if (p->usri1_flags & UF_DONT_EXPIRE_PASSWD) fprintf(stream,"\n"); i = p->usri1_next_index; //if there is more then set the index p++; } NetApiBufferFree(pBuff); fprintf(stream,"
Name:Comment:Full Name:User ID:
%S%S%S%u
(The logon script executed. This value must be set for LAN Manager 2.0 or Windows NT.)
(The user's account is disabled.)
(The home directory is required. Windows NT ignores this value.)
(No password is required.)
(The user cannot change the password.)
(The Account is Locked)
(Password does not expire)
\n"); return(0); } else{ fprintf(stderr, "User Enumeration Error:(%u)\n %S\n" ,res, ErrorHandle().begin()); // break; return(-1); } }while (res==ERROR_MORE_DATA); } int queryservices(LPTSTR szServer){ SC_HANDLE scm; BOOL success; LPENUM_SERVICE_STATUS status; DWORD numServices=0, sizeNeeded=0, resume=0; char *svc = "W3SVC"; // Open a connection to the SCM scm = OpenSCManager(szServer, 0, SC_MANAGER_ALL_ACCESS); if (!scm){ fprintf(stderr,"Error with OpenSCManager\n"); return(-1); } // get the number of bytes to allocate success = EnumServicesStatus(scm, SERVICE_WIN32 | SERVICE_DRIVER, SERVICE_ACTIVE | SERVICE_INACTIVE, 0, 0, &sizeNeeded, &numServices, &resume); if (GetLastError() != ERROR_MORE_DATA){ fprintf(stderr,"Error with EnumServicesStatus\n"); return(-1); } // Allocate space status = (LPENUM_SERVICE_STATUS) LocalAlloc(LPTR, sizeNeeded); // Get the status records. Making an assumption // here that no new services get added during // the allocation (could lock the database to // guarantee that...) resume = 0; success = EnumServicesStatus(scm, SERVICE_WIN32 | SERVICE_DRIVER, SERVICE_ACTIVE, status, sizeNeeded, &sizeNeeded, &numServices, &resume); if (!success){ printf("Error with EnumServicesStatus\n"); return(-1); } DWORD i; fprintf(stream, "
\n",szServer + 2); fprintf(stream, "

Service Enumeration Results:
\n"); for (i=0; i < numServices; i++) fprintf(stream,"\n",i,status[i].lpServiceName,status[i].lpDisplayName); // Clean up LocalFree(status); CloseServiceHandle(scm); fprintf(stream, "
%d %S -- %S
\n"); return(0); } void UnicodeToASCII(wchar_t *wcs, char *mbs){ if (wcs) wcstombs (mbs, wcs, (wcslen (wcs) + 1) * sizeof (WCHAR)); else *mbs = '\0'; } int winfingerprint(LPTSTR pszServerName){ char *ip = NULL; DWORD dwLevel = 102; LPSERVER_INFO_101 pBuf = NULL; LPWKSTA_INFO_102 pwBuf = NULL; NET_API_STATUS nStatus; int errorFlag = 0; //The flag to determine the exit status for the function. UnicodeToASCII(pszServerName+2,ip); NullSession(pszServerName);//Establish a Null session to retreive information.This is required for Remote systems nStatus = NetServerGetInfo(pszServerName, dwLevel, (LPBYTE *)&pBuf); if (nStatus == NERR_Success){ fprintf(stream, "
\n",pBuf->sv101_name); fprintf(stream,"

SMB Query Results:
\n"); if (pBuf->sv101_type & SV_TYPE_DOMAIN_CTRL) fprintf(stream,"\n", pBuf->sv101_name); else if (pBuf->sv101_type & SV_TYPE_DOMAIN_BAKCTRL) fprintf(stream,"\n", pBuf->sv101_name); else if (pBuf->sv101_type & SV_TYPE_SERVER_NT ) fprintf(stream,"\n",pBuf->sv101_name); else if (pBuf->sv101_type & SV_TYPE_NT ) fprintf(stream,"\n",pBuf->sv101_name); else if (pBuf->sv101_type & SV_TYPE_SQLSERVER) fprintf(stream,"\n",pBuf->sv101_name); else if (pBuf->sv101_type & SV_TYPE_NOVELL ) fprintf(stream,"\n",pBuf->sv101_name); else if (pBuf->sv101_type & SV_TYPE_WINDOWS ) fprintf(stream,"\n",pBuf->sv101_name); else if (pBuf->sv101_type & SV_TYPE_WFW ) fprintf(stream,"\n",pBuf->sv101_name); fprintf(stream,"\n"); fprintf(stream,"\n"); fprintf(stream,"\n"); fprintf(stream, "\n", pBuf->sv101_platform_id); fprintf(stream, "\n", pBuf->sv101_name); fprintf(stream, "\n", pBuf->sv101_version_major, pBuf->sv101_version_minor); fprintf(stream, "\n", pBuf->sv101_type); fprintf(stream, "
%S is a PDC.
%S is a BDC.
%S is an NT MEMBER SERVER.
%S is an NT WORKSTATION.
%S is running SQL.
%S is a Novell Netware Server.
%S is running Windows 9x.
%S is Windows for Workgroups.
Platform:Name:Version:Type:Comment:
%d%S%d.%d%d%S
\n", pBuf->sv101_comment); } else{ fprintf(stderr, "OS Detection Error %d: %S\n" ,nStatus, ErrorHandle().begin()); if (pBuf != NULL) NetApiBufferFree(pBuf); errorFlag += 1; } nStatus = NetWkstaGetInfo(pszServerName, dwLevel, (LPBYTE *)&pwBuf); if (nStatus == NERR_Success) { fprintf(stream, "Domain: %S\n", pwBuf->wki102_langroup); fprintf(stream, "Lan Root: %S\n", pwBuf->wki102_lanroot); fprintf(stream, "# Logged On Users: %d
\n", pwBuf->wki102_logged_on_users); } else { fprintf(stderr, "OS Detection Error %d: %S\n" ,nStatus, ErrorHandle().begin()); if (pwBuf != NULL) NetApiBufferFree(pwBuf); errorFlag += 1; } if (errorFlag != 2){ if (pBuf->sv101_type & (SV_TYPE_NOVELL | SV_TYPE_WFW | SV_TYPE_WINDOWS)){ fprintf(stream,"Not running Group/User Enumeration. Machine does not support it.
"); return(5); // Have to flag Windows 9x machines } } else { if (pBuf != NULL) NetApiBufferFree(pBuf); NullDisconnect(pszServerName); return(-1); } if (pBuf != NULL) NetApiBufferFree(pBuf); NullDisconnect(pszServerName); return(0); } void getnetwork(LPNETRESOURCE cont_obj, char *filename){ // the concept is this is null for the first time. Then it is reused. HANDLE enumHandle; LPNETRESOURCE buffer; DWORD bufferSize = 16384; DWORD numEntries = 0xFFFFFFFF; DWORD result; buffer = (LPNETRESOURCE) GlobalAlloc( GPTR, bufferSize); result = WNetOpenEnum( RESOURCE_GLOBALNET, // scope of enumeration RESOURCETYPE_ANY, // resource types to list 0, // resource usage to list cont_obj, // pointer to resource structure &enumHandle); // pointer to enumeration handle buffer if (result != NO_ERROR){ fprintf(stderr,"WNetOpenEnum Error: %d\n",result); return; } result = WNetEnumResource( enumHandle, // handle to enumeration &numEntries, // pointer to entries to list buffer, // pointer to buffer for results &bufferSize); // pointer to buffer size variable if (result == NO_ERROR){ for(int i = 0; i < numEntries; i++){ // if the object is a server if(buffer[i].dwDisplayType == RESOURCEDISPLAYTYPE_SERVER){ printf("\nEnumerating [%S]. . .\n", buffer[i].lpRemoteName + 2); if( (menu = fopen("menu.html", "a" )) == NULL ){ fprintf(stderr, "The file 'menu.html' was not opened\n"); exit(-1); } fprintf(menu,"

  • %S
    \n",filename, buffer[i].lpRemoteName + 2, buffer[i].lpRemoteName + 2); fclose(menu); //fprintf(stderr,"
  • %S
    \n",filename, buffer[i].lpRemoteName + 2, buffer[i].lpRemoteName + 2); options_launcher(winfingerprint(buffer[i].lpRemoteName), buffer[i].lpRemoteName) ; } // if the object is a container ( and not a server ) if( (buffer[i].dwUsage & RESOURCEUSAGE_CONTAINER) && (buffer[i].dwDisplayType != RESOURCEDISPLAYTYPE_SERVER) ) getnetwork(&buffer[i], filename); // we found a container, we repass it to the filtering function } } GlobalFree(buffer); result = WNetCloseEnum(enumHandle); if (result != NO_ERROR) printf("WNetCloseEnum ERROR: %d\n",result); } int NullSession(LPTSTR Server){ LPCWSTR szIpc = L"\\IPC$"; WCHAR RemoteResource[UNCLEN + 5 + 1]; // UNC len + \IPC$ + NULL DWORD cchServer; NET_API_STATUS nas; NETRESOURCE nr; cchServer = lstrlenW( Server ); if(Server[0] != L'\\' && Server[1] != L'\\') { // // prepend slashes and NULL terminate // RemoteResource[0] = L'\\'; RemoteResource[1] = L'\\'; RemoteResource[2] = L'\0'; } else{ cchServer -= 2; // drop slashes from count RemoteResource[0] = L'\0'; } if(cchServer > CNLEN){ SetLastError(ERROR_INVALID_COMPUTERNAME); printf("Error in Null Session Routine\n"); return(-1); } if(lstrcatW(RemoteResource, Server) == NULL) printf("Error in Null Session Routine\n"); if(lstrcatW(RemoteResource, szIpc) == NULL) printf("Error in Null Session Routine\n"); nr.dwType = RESOURCETYPE_ANY; nr.lpLocalName = NULL; nr.lpProvider = NULL; nr.lpRemoteName = (LPTSTR) RemoteResource; nas = WNetAddConnection2(&nr, (LPTSTR) L"", (LPTSTR) L"", 0); if( nas == NERR_Success ){ return(0);} else{ fprintf(stderr,"Null Session NOT Established Error: %d.\n", nas); return(-1); } } int RegConnection(LPTSTR szServer){ LONG result; HKEY hKey, phkResult; DWORD dwType; WCHAR lpData[MAX_PATH]; DWORD dwBufLen; TCHAR lpName[1024]; DWORD lpcbName = 1024; FILETIME time; DWORD index ; result = RegConnectRegistry(szServer, // address of name of remote computer HKEY_LOCAL_MACHINE, // predefined registry handle &hKey); // address of buffer for remote registry handle if (result != ERROR_SUCCESS){ fprintf(stderr,"RegConnectRegistry ERROR: %d\n",result); return(-1); } result = RegOpenKeyEx(hKey, // handle to open key L"Software\\Microsoft\\Windows NT\\CurrentVersion",// address of name of subkey to open 0, // reserved KEY_QUERY_VALUE, // security access mask &phkResult); // address of handle to open key if (result != ERROR_SUCCESS){ fprintf(stderr,"RegOpenKeyEx ERROR: %d",result); FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &result, 0, NULL); fprintf(stderr, " %S\n", (LPCTSTR)result); return(-1); } else{ // // Determine how large of a buffer to allocate. // result = RegQueryValueEx(phkResult, // handle to key to query L"CSDVersion", // address of name of value to query NULL, // reserved &dwType, // address of buffer for value type (LPBYTE) lpData, // address of data buffer &dwBufLen); // address of data buffer size dwBufLen = sizeof(lpData); } result = RegQueryValueEx(phkResult, // handle to key to query L"CSDVersion", // address of name of value to query NULL, // reserved &dwType, // address of buffer for value type (LPBYTE) lpData, // address of data buffer &dwBufLen); // address of data buffer size if (result != ERROR_SUCCESS){ fprintf(stderr, "RegQueryValueEx ERROR %d: %S\n",result, ErrorHandle().begin()); return(-1); } else{ fprintf(stream, "\n",szServer + 2); fprintf(stream, "

    \n"); fprintf(stream, "\n",szServer +2, lpData); fprintf(stream, "\n"); } RegCloseKey(hKey); fprintf(stream, "
    Registry Query Results:
    \n"); result = RegConnectRegistry(szServer, // address of name of remote computer HKEY_LOCAL_MACHINE, // predefined registry handle &hKey); // address of buffer for remote registry handle if (result != ERROR_SUCCESS){ printf("RegConnectRegistry ERROR: %d\n",result); return(-1); } result = RegOpenKeyEx(hKey, // handle to open key L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix",// address of name of subkey to open 0, // reserved KEY_ENUMERATE_SUB_KEYS,// security access mask &phkResult); // address of handle to open key if (result == ERROR_SUCCESS){ index = 0; lpcbName = sizeof(lpName); result = RegEnumKeyEx(phkResult, // handle to key to enumerate index, // index of subkey to enumerate lpName, // address of buffer for subkey name &lpcbName, // address for size of subkey buffer NULL, // reserved NULL, // address of buffer for class string NULL, // address for size of class buffer &time); for(index = 0; result != ERROR_NO_MORE_ITEMS; index++){ lpcbName = sizeof(lpName); result = RegEnumKeyEx(phkResult, // handle to key to enumerate index, // index of subkey to enumerate lpName, // address of buffer for subkey name &lpcbName, // address for size of subkey buffer NULL, // reserved NULL, // address of buffer for class string NULL, // address for size of class buffer &time); if (result == ERROR_NO_MORE_ITEMS){ RegCloseKey(hKey); fprintf(stream, "
    %S %S
    Hotfix:Description
    \n"); return(0); } else{ HKEY hkey_q; int rval; DWORD lpType,lpcbData=8192; TCHAR result[8192]; rval=RegOpenKeyEx(phkResult,lpName,0,KEY_READ,&hkey_q); rval=RegQueryValueEx(hkey_q,TEXT("Comments"),NULL,&lpType,(LPBYTE) result,&lpcbData); fprintf(stream, "%S%S\n",lpName, result); } } fprintf(stream, "\n"); RegCloseKey(hKey); return(0); } return 0; } int NullDisconnect(LPTSTR Server) { LPCWSTR szIpc = L"\\IPC$"; WCHAR RemoteResource[UNCLEN + 5 + 1]; // UNC len + \IPC$ + NULL DWORD cchServer, result; cchServer = lstrlenW( Server ); if(Server[0] != L'\\' && Server[1] != L'\\') { // // prepend slashes and NULL terminate // RemoteResource[0] = L'\\'; RemoteResource[1] = L'\\'; RemoteResource[2] = L'\0'; } else { cchServer -= 2; // drop slashes from count RemoteResource[0] = L'\0'; } if(cchServer > CNLEN) { SetLastError(ERROR_INVALID_COMPUTERNAME); printf("Error in Null Session Routine\n"); return(-1); } if(lstrcatW(RemoteResource, Server) == NULL) printf("Error in Null Session Routine\n"); if(lstrcatW(RemoteResource, szIpc) == NULL) printf("Error in Null Session Routine\n"); result = WNetCancelConnection2( RemoteResource, // pointer to resource name to disconnect 0, // connection type flags 1); // flag for unconditional disconnect if(result == NO_ERROR ){ printf("Null IPC$ Session Terminated [%S].\n",Server +2); return(0);} else { fprintf(stderr,"Null Session NOT Terminated Error: %d.\n", result); return(-1);} } wstring ErrorHandle() { LPVOID lpMsgBuf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL); wstring str((LPCTSTR)lpMsgBuf); LocalFree(lpMsgBuf); return(str); } int querytransport(LPTSTR pszServerName){ LPSERVER_TRANSPORT_INFO_0 pBuf = NULL; LPSERVER_TRANSPORT_INFO_0 pTmpBuf; DWORD dwLevel = 0; DWORD dwPrefMaxLen = 256;//-1 DWORD dwEntriesRead = 0; DWORD dwTotalEntries = 0; DWORD dwResumeHandle = 0; DWORD dwTotalCount = 0; NET_API_STATUS nStatus; DWORD i; // // Call the NetServerTransportEnum function; specify level 0. // do // begin do { nStatus = NetServerTransportEnum(pszServerName, dwLevel, (LPBYTE *) &pBuf, dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle); // // If the call succeeds, // if ((nStatus == NERR_Success) || (nStatus == ERROR_MORE_DATA)) { if ((pTmpBuf = pBuf) != NULL) { // // Loop through the entries; // process access errors. // fprintf(stream, "Transports:
    \n"); fprintf(stream, "\n"); for (i = 0; i < dwEntriesRead; i++) { assert(pTmpBuf != NULL); if (pTmpBuf == NULL) { fprintf(stderr, "An access violation has occurred\n"); break; } // // Print the transport protocol name. // fwprintf(stream, L"\n", pTmpBuf->svti0_transportname); fwprintf(stream, L"\n", pTmpBuf->svti0_networkaddress); pTmpBuf++; dwTotalCount++; } fprintf(stream, "
    Transport:%s
    Network Address:"); for(i=0;isvti0_networkaddress);i++) if(i % 2 || i == 0) fprintf(stream, "%c", pTmpBuf->svti0_networkaddress[i]); else fprintf(stream ,":%c", pTmpBuf->svti0_networkaddress[i]); fwprintf(stream, L"
    \n"); } } // // Otherwise, indicate a system error. // else fprintf(stderr, "A system error has occurred: %d\n", nStatus); // // Free the allocated buffer. // if (pBuf != NULL) { NetApiBufferFree(pBuf); pBuf = NULL; } // // Continue to call NetServerTransportEnum while // there are more entries. // } while (nStatus == ERROR_MORE_DATA); // end do // Check again for an allocated buffer. // if (pBuf != NULL) NetApiBufferFree(pBuf); // // Print the final count of transports enumerated. // fprintf(stderr, "\nTotal of %d entries enumerated\n", dwTotalCount); return 0; } int querytime(LPTSTR pszServerName){ LPTIME_OF_DAY_INFO pBuf = NULL; NET_API_STATUS nStatus; // // Call the NetRemoteTOD function. // nStatus = NetRemoteTOD(pszServerName, (LPBYTE *)&pBuf); // // If the function succeeds, display the current date and time. // if (nStatus == NERR_Success) { if (pBuf != NULL) { fprintf(stream,"Date and Time:
    \n"); fprintf(stream, "\n", pBuf->tod_month, pBuf->tod_day, pBuf->tod_year); fprintf(stream, "
    The current date is:%d/%d/%d
    The current time is:%d:%d:%d
    \n", pBuf->tod_hours, pBuf->tod_mins, pBuf->tod_secs); } } // // Otherwise, display a system error. else fprintf(stderr, "A system error has occurred: %d\n", nStatus); // // Free the allocated buffer. // if (pBuf != NULL) NetApiBufferFree(pBuf); return 0; } int DisplayEntries(LPTSTR szServer) { HANDLE h; EVENTLOGRECORD *pevlr; BYTE bBuffer[4096]; DWORD dwRead, dwNeeded, dwThisRecord = 0; // Open the Application event log. h = OpenEventLog( NULL, // use local computer L"Security"); // source name if (h == NULL) printf("Could not open the Application event log.\n"); pevlr = (EVENTLOGRECORD *) &bBuffer; // Opening the event log positions the file pointer for this // handle at the beginning of the log. Read the records // sequentially until there are no more. fprintf(stream, "
    \n",szServer + 2); fprintf(stream,"Event Log:
    \n"); fprintf(stream, "\n"); while (ReadEventLog(h, // event log handle EVENTLOG_FORWARDS_READ | // reads forward EVENTLOG_SEQUENTIAL_READ, // sequential read 0, // ignored for sequential reads pevlr, // pointer to buffer 4096, // size of buffer &dwRead, // number of bytes read &dwNeeded)) // bytes in next record { while (dwRead > 0) { // Print the event identifier, type, and source name. // The source name is just past the end of the // formal structure. fprintf(stream,"", dwThisRecord++, pevlr->EventID); fprintf(stream, "\n", pevlr->EventType, (LPSTR) ((LPBYTE) pevlr + sizeof(EVENTLOGRECORD))); dwRead -= pevlr->Length; pevlr = (EVENTLOGRECORD *) ((LPBYTE) pevlr + pevlr->Length); } pevlr = (EVENTLOGRECORD *) &bBuffer; } CloseEventLog(h); fprintf(stream, "
    %02d Event ID: 0x%08X EventType: %d Source: %s
    \n"); return(0); } void DisplayUsage (char *arg){ printf("%s vacuum@technotronic.com & mike@datanerds.net\n\n", VERSION); printf("Usage: %s [-host \\\\COMPUTERNAME] [-all -groups -mass -null -output -registry -services -shares -users -help]\n", arg); printf(" -all Enumerates NetBIOS Shares, Users, Groups, Transports,\n Date & Time, and Services\n"); printf(" -groups Enumerates Groups\n"); printf(" -mass Scan entire 'Network Neighborhood'\n"); printf(" -null Establishes Null Session\n"); printf(" -registry Registry Querying\n"); printf(" -services Enumerates Services, Transports, Date & Time\n"); printf(" -shares Enumerates Shares\n"); printf(" -users Enumerates Users\n"); printf(" -output Output filename 'e.g. myscan.html'\n"); printf(" -help Shows Usage\n"); exit(1); } void options_launcher(int os_type, LPTSTR server){ int rdata; switch(os_type){ case 5: // 95, 98, Novell. if(options.optdiskenum) diskenum95(server); break; case -1: // An error occured. break; case 0: // NT box. if(options.optnull) NullSession(server); if(options.optreg) RegConnection(server); if(options.optdiskenum){ rdata = diskenum(server); // Try to get shares without Administrator access. if(rdata == 3) diskenum95(server); } if(options.optquerygroup) querygroup(server); if(options.optqueryuser) queryuser(server); if(options.optqueryservices) queryservices(server); querytransport(server); //Transport Enumeration querytime(server); // Query Time DisplayEntries(server); // Event Logs if(options.optnull) NullDisconnect(server); break; default: break; } }