OK well Since thier was a lack of a profficient port 445 fingerprinter, and no one was openly willing to share source code, I wrote this real quick. It's worked on about the 5 boxs I've tested on, and works where the other checker does not (TMS A) etc. If it has an error detecting OS, it most likely is win2k3, when I get home today I'll add that scan vector as well. With this code you can easily incorporate this checking routine into any lsass exploit you use.
CODE
/******************************************************************************* Windows LSASS OS fingerprinter v1.0 Written by nolimit @ COREiSO 2004. ******************************************************************************** /
long gimmeip(char *hostname); //First basic request, authenticating with the machine. char req1[] = "\x00\x00\x00\x85\xff\x53\x4d\x42\x72\x00\x00\x00\x00\x18\x53\xc8" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xfe" "\x00\x00\x00\x00\x00\x62\x00\x02\x50\x43\x20\x4e\x45\x54\x57\x4f" "\x52\x4b\x20\x50\x52\x4f\x47\x52\x41\x4d\x20\x31\x2e\x30\x00\x02" "\x4c\x41\x4e\x4d\x41\x4e\x31\x2e\x30\x00\x02\x57\x69\x6e\x64\x6f" "\x77\x73\x20\x66\x6f\x72\x20\x57\x6f\x72\x6b\x67\x72\x6f\x75\x70" "\x73\x20\x33\x2e\x31\x61\x00\x02\x4c\x4d\x31\x2e\x32\x58\x30\x30" "\x32\x00\x02\x4c\x41\x4e\x4d\x41\x4e\x32\x2e\x31\x00\x02\x4e\x54" "\x20\x4c\x4d\x20\x30\x2e\x31\x32"; //Second request, querying the system for OS. char req2[] = "\x00\x00\x00\xa4\xff\x53\x4d\x42\x73\x00\x00\x00\x00\x18\x07\xc8" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xfe" "\x00\x00\x10\x00\x0c\xff\x00\xa4\x00\x04\x11\x0a\x00\x00\x00\x00" "\x00\x00\x00\x20\x00\x00\x00\x00\x00\xd4\x00\x00\x80\x69\x00\x4e" "\x54\x4c\x4d\x53\x53\x50\x00\x01\x00\x00\x00\x97\x82\x08\xe0\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x57\x00\x69\x00\x6e\x00\x64\x00\x6f\x00\x77\x00\x73\x00\x20\x00" "\x32\x00\x30\x00\x30\x00\x30\x00\x20\x00\x32\x00\x31\x00\x39\x00" "\x35\x00\x00\x00\x57\x00\x69\x00\x6e\x00\x64\x00\x6f\x00\x77\x00" "\x73\x00\x20\x00\x32\x00\x30\x00\x30\x00\x30\x00\x20\x00\x35\x00" "\x2e\x00\x30\x00\x00\x00\x00"; char buffer[1000];
int main(int argc,char *argv[]) { WSADATA wsaData; //some of this is ripped from previous exploit shit i wrote previous struct sockaddr_in targetTCP; int sockTCP; unsigned short port = 445; long ip; if(argc != 2) { printf("Windows LSASS remote OS fingerprinter v1.0.\n" "Usage: %s [Target] \n" "Coded by nolimit@CiSO.\n",argv[0]); return 1; } WSAStartup(0x0202, &wsaData); ip=gimmeip(argv[1]); targetTCP.sin_family = AF_INET; targetTCP.sin_addr.s_addr = ip; targetTCP.sin_port = htons(port);
if ((sockTCP = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("[x] Socket not initialized! Exiting...\n"); WSACleanup(); return 1; } if(connect(sockTCP,(struct sockaddr *)&targetTCP, sizeof(targetTCP)) != 0) { printf("[*] Connection to host failed! Exiting...\n"); WSACleanup(); exit(1); } if (send(sockTCP, req1, sizeof(req1),0) == -1) { printf("[x] Failed to send! Exiting...\n"); WSACleanup(); return 1; } if (recv(sockTCP, buffer, sizeof (buffer), 0) == 0) { printf("[*] Recieve Failure. Exiting...\n"); WSACleanup(); exit(1); } if (send(sockTCP, req2, sizeof(req2),0) == -1) { printf("[x] Failed to send! Exiting...\n"); WSACleanup(); return 1; } if (recv(sockTCP, buffer, sizeof (buffer), 0) == 0) { printf("[*] Recieve Failure. Exiting...\n"); WSACleanup(); exit(1); } //Null chars really (filtered) up most string searching functions, lets just change the buffer to spaces. for(int i=0;i<sizeof(buffer);i++) { if (buffer[i] == '\x00') { buffer[i] = '\x20'; } } //now just a simple string search for the OS numbers if(strstr(buffer,"5 . 1")) { printf("%s: Windows XP",argv[1]); } else if(strstr(buffer,"5 . 0")) { printf("%s: Windows 2K",argv[1]); } else { printf("%s: Error detecting OS"); } closesocket(sockTCP); WSACleanup(); return 0;
}
/ ******************************************************************************** */ long gimmeip(char *hostname) { struct hostent *he; long ipaddr;
Anyone is free to comment on the code writing, on perhaps how to improve it. this was a rush job.
F34R
May 19 2004, 12:28 PM
Good Job... thanks for the post and the code dude! peace!
Refused
May 19 2004, 04:08 PM
Pretty nice man.
BlaStA
May 19 2004, 04:13 PM
Nice work, compiles fine, I had to do just one change in Dev-Cpp:
CODE
for(int i=0;i<sizeof(buffer);i++)
You have to add the declaration of i outside of the for-parameters.
nolimit
May 20 2004, 06:09 PM
Fixed some little quirks, and added detection of windows 2k3.
CODE
/******************************************************************************* Windows LSASS OS fingerprinter v1.1 Written by nolimit @ COREiSO 2004. ******************************************************************************** /
long gimmeip(char *hostname); //First basic request, authenticating with the machine. char req1[] = "\x00\x00\x00\x85\xff\x53\x4d\x42\x72\x00\x00\x00\x00\x18\x53\xc8" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xfe" "\x00\x00\x00\x00\x00\x62\x00\x02\x50\x43\x20\x4e\x45\x54\x57\x4f" "\x52\x4b\x20\x50\x52\x4f\x47\x52\x41\x4d\x20\x31\x2e\x30\x00\x02" "\x4c\x41\x4e\x4d\x41\x4e\x31\x2e\x30\x00\x02\x57\x69\x6e\x64\x6f" "\x77\x73\x20\x66\x6f\x72\x20\x57\x6f\x72\x6b\x67\x72\x6f\x75\x70" "\x73\x20\x33\x2e\x31\x61\x00\x02\x4c\x4d\x31\x2e\x32\x58\x30\x30" "\x32\x00\x02\x4c\x41\x4e\x4d\x41\x4e\x32\x2e\x31\x00\x02\x4e\x54" "\x20\x4c\x4d\x20\x30\x2e\x31\x32"; //Second request, querying the system for OS. char req2[] = "\x00\x00\x00\xa4\xff\x53\x4d\x42\x73\x00\x00\x00\x00\x18\x07\xc8" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xfe" "\x00\x00\x10\x00\x0c\xff\x00\xa4\x00\x04\x11\x0a\x00\x00\x00\x00" "\x00\x00\x00\x20\x00\x00\x00\x00\x00\xd4\x00\x00\x80\x69\x00\x4e" "\x54\x4c\x4d\x53\x53\x50\x00\x01\x00\x00\x00\x97\x82\x08\xe0\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x57\x00\x69\x00\x6e\x00\x64\x00\x6f\x00\x77\x00\x73\x00\x20\x00" "\x32\x00\x30\x00\x30\x00\x30\x00\x20\x00\x32\x00\x31\x00\x39\x00" "\x35\x00\x00\x00\x57\x00\x69\x00\x6e\x00\x64\x00\x6f\x00\x77\x00" "\x73\x00\x20\x00\x32\x00\x30\x00\x30\x00\x30\x00\x20\x00\x35\x00" "\x2e\x00\x30\x00\x00\x00\x00"; char buffer[1000];
int main(int argc,char *argv[]) { WSADATA wsaData; //some of this is ripped from previous exploit shit i wrote previous struct sockaddr_in targetTCP; int sockTCP; unsigned short port = 445; long ip; if(argc != 2) { printf("Windows LSASS remote OS fingerprinter v1.0.\n" "Usage: %s [Target] \n" "Coded by nolimit@CiSO.\n",argv[0]); return 1; } WSAStartup(0x0202, &wsaData); ip=gimmeip(argv[1]); targetTCP.sin_family = AF_INET; targetTCP.sin_addr.s_addr = ip; targetTCP.sin_port = htons(port);
if ((sockTCP = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("%s: Socket not initialized! Exiting...\n",argv[1]); WSACleanup(); return 1; } if(connect(sockTCP,(struct sockaddr *)&targetTCP, sizeof(targetTCP)) != 0) { printf("%s: Connection to host failed!\n",argv[1]); WSACleanup(); exit(1); } if (send(sockTCP, req1, sizeof(req1),0) == -1) { printf("%s: Failed to send! Exiting...\n",argv[1]); WSACleanup(); return 1; } if (recv(sockTCP, buffer, sizeof (buffer), 0) == 0) { printf("%s: Recieve Failure. Exiting...\n",argv[1]); WSACleanup(); exit(1); } if (send(sockTCP, req2, sizeof(req2),0) == -1) { printf("%s: Failed to send! Exiting...\n",argv[1]); WSACleanup(); return 1; } if (recv(sockTCP, buffer, sizeof (buffer), 0) == 0) { printf("%s: Recieve Failure. Exiting...\n",argv[1]); WSACleanup(); exit(1); } //Null chars really (filtered) up most string searching functions, lets just change the buffer to spaces. for(int i=0;i<sizeof(buffer);i++) { if (buffer[i] == '\x00') { buffer[i] = '\x20'; } } //now just a simple string search for the OS numbers if(strstr(buffer,"5 . 2")) { printf("%s: Windows 2003\n",argv[1]); } if(strstr(buffer,"5 . 1")) { printf("%s: Windows XP\n",argv[1]); } else if(strstr(buffer,"5 . 0")) { printf("%s: Windows 2K\n",argv[1]); } else { printf("%s: Error detecting OS\n"); } closesocket(sockTCP); WSACleanup(); return 0;
}
/ ******************************************************************************** */ long gimmeip(char *hostname) { struct hostent *he; long ipaddr;
Wouldn't it be possible to make it to read the port 1025/135/139 or any other ports for that matter, such that the same routine could be used ?
I can compile myself, so that's not the problem, I'm just wondering if the code would work if we changed the port used (445 by another one)
thanks for the work so far, pretty good
nolimit
May 20 2004, 06:39 PM
135/139 Use different protocols, but seeing as I already coded a OS fingerprinter into the workstation exploit, I can post that after making it standalone. Although I think this version is even better then mine..(attached)
toska
May 20 2004, 10:07 PM
very nice, thanks guys!
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.