/* * Paglo Crawler * Copyright (C) 2006-2008 Paglo Labs Inc. All rights reserved. * www.paglo.com * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ //--------------------------------------------------------------------------- #ifndef NEED_PROBES #define NEED_PROBES #include "Probes.h" #include "ScanData.h" #include "ScanAgentUtils.h" #include "AnalysisManager.h" #include "EvidenceDescription.h" #include "Debug.h" #endif //--------------------------------------------------------------------------- using namespace std; extern TEventQueue _ScanReqQueue; int DispatchProbe(TNetworkDevice *NetDev, string Technique, string ProbeLabel, int Port, TEventQueue *ReplyQueue) { TScanRequest *ScanReq = NULL; TPEvent *OutEvent = NULL; string Request; char *EscapedString; TProbeData ProbeData; int ScanCnt = 0; list PortList; list::iterator CurrPort; /* * Identify what kind of probe we're sending and lookup its information and * crate an appropriate ScanRequest. */ if (_ProbeMap.empty()) { InitProbes(); } if (Technique == PT_TECHNIQUE_TCP) { /* * Check to see if the port is open. If it isn't, we do nothing. */ if (NetDev->HasPort(IPPROTO_TCP, Port)) { if (IsSSL(Port)) { /* * Send a separate SSL hello, so that we can grab the certificate data too. */ Request = _ProbeMap["ssl_hello"]; ScanReq = new TScanService(NetDev->GetIPAddress(), Port, IPPROTO_TCP, false, Request, "ssl_hello"); ScanReq->SetReplyQueue(ReplyQueue); ProbeData = TProbeData(Technique, "ssl_hello", Request, "", Port, ScanReq->GetID()); NetDev->AddEvidence(ProbeData); NetDev->AddScan(ScanReq->GetID(), ScanReq->TypeString()); OutEvent = new TPEvent(ScanReq); _ScanReqQueue.PutFront(OutEvent); /* * Now send the request through an SSL encrypted connection. */ EscapedString = EscapeString((unsigned char *)_ProbeMap[ProbeLabel.c_str()].c_str(), _ProbeMap[ProbeLabel.c_str()].length()); Request = EscapedString; free(EscapedString); ScanReq = new TScanService(NetDev->GetIPAddress(), Port, IPPROTO_TCP, true, Request, ProbeLabel); ScanReq->SetReplyQueue(ReplyQueue); ProbeData = TProbeData(Technique, ProbeLabel, Request, "", Port, ScanReq->GetID()); NetDev->AddEvidence(ProbeData); NetDev->AddScan(ScanReq->GetID(), ScanReq->TypeString()); OutEvent = new TPEvent(ScanReq); _ScanReqQueue.PutFront(OutEvent); ScanCnt = 2; } else { EscapedString = EscapeString((unsigned char *)_ProbeMap[ProbeLabel.c_str()].c_str(), _ProbeMap[ProbeLabel.c_str()].length()); Request = EscapedString; free(EscapedString); ScanReq = new TScanService(NetDev->GetIPAddress(), Port, IPPROTO_TCP, false, Request, ProbeLabel); ScanReq->SetReplyQueue(ReplyQueue); ProbeData = TProbeData(Technique, ProbeLabel, Request, "", Port, ScanReq->GetID()); NetDev->AddEvidence(ProbeData); NetDev->AddScan(ScanReq->GetID(), ScanReq->TypeString()); OutEvent = new TPEvent(ScanReq); _ScanReqQueue.PutFront(OutEvent); ScanCnt = 1; } } } else if (Technique == PT_TECHNIQUE_UDP) { /* * Check to see if the port is open, otherwise do nothing. */ /* * TODO: Just do the probe anyway. UDP port scanning can be flaky, * so the port may not show up as open. */ #if 0 if (NetDev->HasPort(IPPROTO_UDP, Port)) { #endif EscapedString = EscapeString((unsigned char *)_ProbeMap[ProbeLabel.c_str()].c_str(), _ProbeMap[ProbeLabel.c_str()].length()); Request = EscapedString; free(EscapedString); ScanReq = new TScanService(NetDev->GetIPAddress(), Port, IPPROTO_UDP, false /* Don't use SSL */, Request, ProbeLabel); ScanReq->SetReplyQueue(ReplyQueue); ProbeData = TProbeData(Technique, ProbeLabel, Request, "", Port, ScanReq->GetID()); NetDev->AddEvidence(ProbeData); NetDev->AddScan(ScanReq->GetID(), ScanReq->TypeString()); OutEvent = new TPEvent(ScanReq); _ScanReqQueue.PutFront(OutEvent); ScanCnt = 1; #if 0 } #endif } else if (Technique == PT_TECHNIQUE_TELNET) { /* * Check to see if the port is open, otherwise do nothing. */ if (NetDev->HasPort(IPPROTO_TCP, Port)) { EscapedString = EscapeString((unsigned char *)_ProbeMap[ProbeLabel.c_str()].c_str(), _ProbeMap[ProbeLabel.c_str()].length()); Request = EscapedString; free(EscapedString); ScanReq = new TScanTelnet(NetDev->GetIPAddress(), Port, Request); ScanReq->SetReplyQueue(ReplyQueue); ProbeData = TProbeData(Technique, ProbeLabel, Request, "", Port, ScanReq->GetID()); NetDev->AddEvidence(ProbeData); NetDev->AddScan(ScanReq->GetID(), ScanReq->TypeString()); OutEvent = new TPEvent(ScanReq); _ScanReqQueue.PutFront(OutEvent); ScanCnt = 1; } } else if (Technique == PT_TECHNIQUE_SNMP) { /* * Check to see if the port is open, otherwise do nothing. */ /* * TODO: Just do the probe anyway. UDP port scanning can be flaky, * so the port may not show up as open. */ #if 0 if (NetDev->HasPort(IPPROTO_UDP, Port)) { #endif Request = _ProbeMap[ProbeLabel.c_str()]; pthread_mutex_lock(&_CommunityStringsMutex); for (unsigned int i = 0; i < _CommunityStrings.size(); i++) { ScanReq = new TScanSNMP(NetDev->GetIPAddress(), Request, _CommunityStrings[i]); ScanReq->SetReplyQueue(ReplyQueue); ProbeData = TProbeData(Technique, ProbeLabel, Request, "", Port, ScanReq->GetID()); NetDev->AddEvidence(ProbeData); NetDev->AddScan(ScanReq->GetID(), ScanReq->TypeString()); OutEvent = new TPEvent(ScanReq); _ScanReqQueue.PutFront(OutEvent); ScanCnt++; } pthread_mutex_unlock(&_CommunityStringsMutex); #if 0 } #endif } return ScanCnt; } //--------------------------------------------------------------------------- void InitProbes(void) { /* * Setup probe payloads. */ _ProbeMap["null"]= ""; _ProbeMap["http_get"] = "GET / HTTP/1.1\r\nAccept: */*\r\nHost: 0.0.0.0\r\n\r\n"; _ProbeMap["snmp_sysdescr"] = "1.3.6.1.2.1.1.1.0"; _ProbeMap["snmp_sysname"] = "1.3.6.1.2.1.1.5.0"; _ProbeMap["ssl_hello"] = "\\x80\\x4C\\x01\\x03\\x00\\x00\\x33\\x00\\x00\\x00\\x10\\x00\\x00" "\\x04\\x00\\x00\\x05\\x00\\x00\\x0A\\x01\\x00\\x80\\x07\\x00\\xC0\\x03\\x00\\x80\\x00\\x00\\x09" "\\x06\\x00\\x40\\x00\\x00\\x64\\x00\\x00\\x62\\x00\\x00\\x03\\x00\\x00\\x06\\x02\\x00\\x80\\x04" "\\x00\\x80\\x00\\x00\\x13\\x00\\x00\\x12\\x00\\x00\\x63\\x6D\\x03\\xF7\\x63\\xB0\\x47\\xB9\\x55" "\\xE1\\x34\\x99\\xE4\\xA5\\x69\\x21\\x21"; _ProbeMap["http_sonos_url"] = "GET /xml/zone_player.xml HTTP/1.1\r\nAccept: */*\r\nHost: 0.0.0.0\r\n\r\n"; _ProbeMap["http_index.htm"] = "GET /index.htm HTTP/1.1\r\nAccept: */*\r\nHost: 0.0.0.0\r\n\r\n"; _ProbeMap["http_index.html"] = "GET /index.htm HTTP/1.1\r\nAccept: */*\r\nHost: 0.0.0.0\r\n\r\n"; _ProbeMap["http_logo.htm"] = "GET /logo.htm HTTP/1.1\r\nAccept: */*\r\nHost: 0.0.0.0\r\n\r\n"; /* * Add the default read community for SNMP probes. */ AddCommunity("public"); } //--------------------------------------------------------------------------- bool IsSSL(unsigned short Port) { for (int i = 0; _SSLPorts[i]; i++) { if (Port == _SSLPorts[i]) { return true; } } return false; } //--------------------------------------------------------------------------- void AddCommunity(const string &Community) { pthread_mutex_lock(&_CommunityStringsMutex); for (unsigned int i = 0; i < _CommunityStrings.size(); i++) { if (Community == _CommunityStrings[i]) { pthread_mutex_unlock(&_CommunityStringsMutex); return; } } _CommunityStrings.push_back(Community); pthread_mutex_unlock(&_CommunityStringsMutex); } //---------------------------------------------------------------------------