1
0
mirror of https://github.com/nmap/nmap.git synced 2026-01-28 00:59:04 +00:00

removed scripts directory (which contains development/build helper tools) to tools, so that scripts can be used for NSE scripts)

This commit is contained in:
fyodor
2006-11-01 23:31:18 +00:00
parent d610bca354
commit b87a8f9803
20 changed files with 2 additions and 64503 deletions

View File

@@ -106,11 +106,11 @@ debug:
# Make the Nmap tarball
distro:
cd scripts && $(MAKE) distro
cd dev && $(MAKE) distro
# Update the web site
web:
cd scripts && $(MAKE) web
cd dev && $(MAKE) web
clean: @PCAP_CLEAN@ @PCRE_CLEAN@ @DNET_CLEAN@ nmapfe_clean nsock_clean nbase_clean my_clean

View File

@@ -1,215 +0,0 @@
CC=gcc
CXX=g++
CXXFLAGS=-g
INCLUDE_FLAGS= -I.. -I../nbase -I../libpcap -I../libdnet-stripped/include/
LINK_FLAGS=-L.. -L../nbase -L../libpcap
NMAP_OBJS=../osscan.o ../osscan2.o ../nmap_error.o ../utils.o ../tcpip.o ../output.o ../nmap.o ../scan_engine.o ../portlist.o ../timing.o ../nmap_rpc.o ../charpool.o ../services.o ../targets.o ../idle_scan.o ../MACLookup.o ../protocols.o ../FingerPrintResults.o ../NmapOps.o ../TargetGroup.o ../Target.o ../NmapOutputTable.o ../service_scan.o ../nmap_tty.o ../nmap_dns.o ../nsock/src/libnsock.a ../libdnet-stripped/src/.libs/libdnet.a
DEFINES=-DHAVE_CONFIG_H=1
DATAFILES = nmap-os-fingerprints nmap-os-db nmap-service-probes nmap-services nmap-rpc nmap-protocols nmap-mac-prefixes
SHTOOL = ../shtool
LIBPCAPDIR=libpcap
NBASEDIR=nbase
all: fingerfix fingermatch fingerdiff servicematch
dummy:
.cc.o: dummy
$(CXX) -c $(CXXFLAGS) $(INCLUDE_FLAGS) $(DEFINES) $< -o $@
fingerfix: dummy fingerlib.o
$(CXX) $(CXXFLAGS) -Wall $(INCLUDE_FLAGS) $(LINK_FLAGS) $(DEFINES) -o $@ $@.cc fingerlib.o $(NMAP_OBJS) -lm -lnbase -lpcap -lpcre -lssl -lcrypt
fingermatch: dummy fingerlib.o
$(CXX) $(CXXFLAGS) -Wall $(INCLUDE_FLAGS) $(LINK_FLAGS) $(DEFINES) -o $@ $@.cc fingerlib.o $(NMAP_OBJS) -lm -lnbase -lpcap -lpcre -lssl -lcrypt
fingerdiff: dummy fingerlib.o
$(CXX) $(CXXFLAGS) -Wall $(INCLUDE_FLAGS) $(LINK_FLAGS) $(DEFINES) -o $@ $@.cc fingerlib.o $(NMAP_OBJS) -lm -lnbase -lpcap -lpcre -lssl -lcrypt
servicematch: dummy
$(CXX) $(CXXFLAGS) -Wall $(INCLUDE_FLAGS) $(LINK_FLAGS) $(DEFINES) -o $@ $@.cc $(NMAP_OBJS) -lm -lnbase -lpcap -lpcre -lssl -lcrypt
web:
test x$(wroot) != x
make -C $(wroot)/nmapguide manhtml manxml man manxlate
cp $(wroot)/nmapguide/nmap.1 ../docs
cd ../docs && cp -a nmap_gpgkeys.txt nmap_manpage-*.html nmap*.1 \
xnmap.1 nmap.usage.txt nmap.dtd nmap.xsl \
leet-nmap-ascii-art.txt $(wroot)/nmap/data/
cp $(wroot)/nmapguide/build/nmap-man.xml $(wroot)/nmap/data/nmap-man.xml
./sort-prints.pl ../nmap-os-db > nos && mv nos ../nmap-os-db
./produceosclasschoosebox.pl ../nmap-os-fingerprints > $(wroot)/nmap/data/os-classes.txt
cd .. && cp -a CHANGELOG HACKING COPYING COPYING.OpenSSL INSTALL \
$(DATAFILES) README-WIN32 mswin32/nmap_performance.reg $(wroot)/nmap/data
./sign_release.pl $(wroot)/nmap/dist
find $(wroot)/nmap/data/ -type f -exec chmod 644 '{}' \;
find $(wroot)/nmap/dist/sigs -type f -exec chmod 644 '{}' \;
# This is unsafe on shared systems, should use mktemp
distro:
cd .. && autoconf
rm -f ../config.cache
cd .. && ./configure
cd ../$(LIBPCAPDIR) && ./configure
$(MAKE) -C .. clean
$(MAKE) -C .. -j3
../nmap -h > /dev/null #Make sure nmap exists
rm -f ../docs/nmap.usage.txt
../nmap -h > ../docs/nmap.usage.txt
make -C $(wroot)/nmapguide man manxlate
cp $(wroot)/nmapguide/nmap.1 ../docs
rm -rf /usr/tmp/nmap-$(NMAP_VERSION)
mkdir /usr/tmp/nmap-$(NMAP_VERSION)
# Make the RPM .spec file
sed -e s/\@VERSION\@/$(NMAP_VERSION)/g ../nmap.spec.in > ../nmap-$(NMAP_VERSION)-1.spec
# Canonicalize and sort Nmap OS fingerprint DB
# sort-prints.pl ../nmap-os-fingerprints > nos && mv nos ../nmap-os-fingerprints
$(MAKE) -C .. clean
cd .. && rm -f $(LIBPCAPDIR)/config.cache $(LIBPCAPDIR)/Makefile
cd .. && unix2dos README-WIN32
cd .. && cp -a $(SRCS) $(HDRS) $(DATAFILES) nmapfe.desktop \
configure.ac config.h.in aclocal.m4 Makefile.in \
configure shtool install-sh config.guess \
nmap-$(NMAP_VERSION)-1.spec config.sub INSTALL README-WIN32 COPYING \
COPYING.OpenSSL CHANGELOG HACKING /usr/tmp/nmap-$(NMAP_VERSION)
$(SHTOOL) mkdir /usr/tmp/nmap-$(NMAP_VERSION)/mswin32
cd ../mswin32; cp -a --parents ARPA/NAMESER.H ARPA/TFTP.H icon1.ico \
ifaddrlist.h IPExport.h lib/Packet.lib lib/Wpcap.lib \
libpcap-note.txt NET/if_arp.h NETINET/UDP.H NETINET/IF_ETHER.H \
NETINET/IP.H NETINET/TCPIP.H NETINET/IP_ICMP.H NETINET/IN_SYSTM.H \
NETINET/TCP.H NETINET/TCP_VAR.H NETINET/UDP_VAR.H NETINET/IP_VAR.H \
nmap_performance.reg nmap.rc nmap.sln nmap.vcproj packet_types.h \
pcap-include/remote-ext.h pcap-include/memory_t.h \
pcap-include/pcap-stdinc.h pcap-include/pcap.h \
pcap-include/semaphore.h pcap-include/Gnuc.h \
pcap-include/count_packets.h pcap-include/Devioctl.h \
pcap-include/bucket_lookup.h pcap-include/ip6_misc.h \
pcap-include/bittypes.h pcap-include/time_calls.h \
pcap-include/pthread.h pcap-include/Win32-Extensions.h \
pcap-include/Packet32.h pcap-include/normal_lookup.h \
pcap-include/pcap-bpf.h pcap-include/sched.h \
pcap-include/Ntddpack.h pcap-include/tme.h \
pcap-include/tcp_session.h pcap-include/pcap-int.h \
winpcap/daemon_mgm.exe winpcap/LICENSE winpcap/NetMonInstaller.exe \
winpcap/npf_mgm.exe winpcap/npf.sys winpcap/Packet.dll \
winpcap/pthreadVC.dll winpcap/rpcapd.exe winpcap/WanPacket.dll \
winpcap/winpcap-nmap.nsi winpcap/wpcap.dll nsis/AddToPath.nsh \
nsis/Nmap.nsi resource.h RPC/Rpc_cut.h winclude.h winfix.cc \
winfix.h Makefile /usr/tmp/nmap-$(NMAP_VERSION)/mswin32
$(SHTOOL) mkdir /usr/tmp/nmap-$(NMAP_VERSION)/$(LIBPCAPDIR)
cd ../$(LIBPCAPDIR); cp -dp --parents acconfig.h aclocal.m4 arcnet.h \
atmuni31.h bpf_dump.c bpf_image.c CHANGES \
config.guess config.h.in config.sub configure configure.ac \
CREDITS etherent.c ethertype.h fad-getad.c fad-gifc.c \
fad-glifc.c fad-null.c fad-win32.c FILES gencode.c gencode.h \
grammar.c grammar.y inet.c install-sh INSTALL.txt LICENSE \
llc.h Makefile.in mkdep nametoaddr.c net nlpid.h \
NMAP_MODIFICATIONS optimize.c pcap1.h pcap.3 pcap-bpf.c \
pcap-bpf.h pcap.c pcap-dag.c pcap-dag.h pcap-dlpi.c pcap-dos.c \
pcap-dos.h pcap-enet.c pcap.h pcap-int.h pcap-linux.c \
pcap-namedb.h pcap-nit.c pcap-nit.h pcap-null.c pcap-pf.c \
pcap-pf.h pcap-septel.c pcap-septel.h pcap-snit.c pcap-snoop.c \
pcap-stdinc.h pcap-win32.c pf.h ppp.h README README.aix \
README.dag README.hpux README.linux README.macosx README.septel \
README.tru64 README.Win32 savefile.c scanner.c scanner.l sll.h \
sunatmpos.h TODO tokdefs.h VERSION version.h \
ChmodBPF/ChmodBPF ChmodBPF/StartupParameters.plist \
doc/pcap.html doc/pcap.txt doc/pcap.xml lbl/os-aix4.h \
lbl/os-hpux11.h lbl/os-osf4.h lbl/os-osf5.h lbl/os-solaris2.h \
lbl/os-sunos4.h lbl/os-ultrix4.h missing/snprintf.c \
SUNOS4/nit_if.o.sparc \
SUNOS4/nit_if.o.sun3 SUNOS4/nit_if.o.sun4c.4.0.3c \
bpf/net/bpf_filter.c \
/usr/tmp/nmap-$(NMAP_VERSION)/$(LIBPCAPDIR)
$(SHTOOL) mkdir /usr/tmp/nmap-$(NMAP_VERSION)/docs
cd ../docs; cp -a README nmap_gpgkeys.txt \
nmap.usage.txt \
nmap.1 nmapfe.1 xnmap.1 nmap.dtd nmap.xsl \
leet-nmap-ascii-art.txt \
$(wroot)/nmap/data/nmap-man.xml \
/usr/tmp/nmap-$(NMAP_VERSION)/docs
$(SHTOOL) mkdir /usr/tmp/nmap-$(NMAP_VERSION)/nmapfe
cd ../nmapfe; cp -a Makefile.in aclocal.m4 configure configure.ac \
nmapfe.c nmapfe.h nmapfe_sig.c nmapfe_sig.h \
nmapfe_error.c nmapfe_error.h NmapFE.dsp nmapfe.dsw \
/usr/tmp/nmap-$(NMAP_VERSION)/nmapfe
$(SHTOOL) mkdir /usr/tmp/nmap-$(NMAP_VERSION)/nbase
cd ../$(NBASEDIR); cp -a Makefile.in aclocal.m4 configlocal.m4 \
nbase.vcproj configure configure.ac nbase_config.h.in \
*.c *.h CHANGELOG /usr/tmp/nmap-$(NMAP_VERSION)/nbase
$(SHTOOL) mkdir /usr/tmp/nmap-$(NMAP_VERSION)/libpcre
cd ../libpcre; cp -a AUTHORS config.guess config.h.in config.sub \
configure configure.ac dftables.c INSTALL install-sh \
libpcre.vcproj LICENCE Makefile.in makevp.bat mkinstalldirs \
NMAP_MODIFICATIONS NON-UNIX-USE pcre_chartables.c \
pcre_compile.c pcre_config.c pcre_dfa_exec.c pcre_exec.c \
pcre_fullinfo.c pcre_get.c pcre_globals.c pcre.h pcre.h.in \
pcre_info.c pcre_internal.h pcre_maketables.c pcreposix.c \
pcreposix.h pcre_printint.src pcre_refcount.c pcre_study.c \
pcre_tables.c pcre_try_flipped.c pcre_version.c \
pcre_winconfig.h pcre_xclass.c README ucp.h \
/usr/tmp/nmap-$(NMAP_VERSION)/libpcre
$(SHTOOL) mkdir /usr/tmp/nmap-$(NMAP_VERSION)/libdnet-stripped
cd ../$(LIBDNETDIR); cp -a --parents acconfig.h aclocal.m4 \
config/missing config/mkinstalldirs \
config/acinclude.m4 config/install-sh \
config/config.sub config/ltmain.sh config/config.guess \
configure configure.in dnet-config.in include/dnet/rand.h \
include/dnet/ip6.h include/dnet/ip.h include/dnet/route.h \
include/dnet/icmp.h include/dnet/blob.h include/dnet/udp.h \
include/dnet/os.h include/dnet/eth.h include/dnet/fw.h \
include/dnet/intf.h include/dnet/Makefile.in include/dnet/tcp.h \
include/dnet/arp.h include/dnet/Makefile.am include/dnet/tun.h \
include/dnet/addr.h include/Makefile.in include/dnet.h \
include/stamp-h1 include/dnet_winconfig.h include/Makefile.am \
include/queue.h include/stamp-h.in include/config.h.in \
include/err.h INSTALL libdnet-stripped.vcproj LICENSE \
Makefile.am Makefile.am.common Makefile.in NMAP_MODIFICATIONS \
README src/route-none.c src/ip-cooked.c \
src/arp-win32.c src/ip-util.c src/route-win32.c src/fw-none.c \
src/eth-linux.c src/route-bsd.c src/route-linux.c \
src/tun-bsd.c src/strlcat.c src/tun-none.c src/memcmp.c \
src/route-hpux.c src/addr-util.c src/eth-ndd.c src/ip6.c \
src/intf.c src/Makefile.in src/addr.c src/eth-dlpi.c \
src/rand.c src/tun-solaris.c src/intf-win32.c \
src/eth-none.c src/ip.c src/ip-win32.c \
src/arp-ioctl.c src/arp-none.c src/Makefile.am \
src/eth-bsd.c src/strsep.c src/err.c src/strlcpy.c src/blob.c \
src/eth-win32.c src/eth-snoop.c src/eth-pfilt.c src/tun-linux.c \
src/arp-bsd.c THANKS TODO \
/usr/tmp/nmap-$(NMAP_VERSION)/libdnet-stripped
$(SHTOOL) mkdir /usr/tmp/nmap-$(NMAP_VERSION)/nsock
$(SHTOOL) mkdir /usr/tmp/nmap-$(NMAP_VERSION)/nsock/include
$(SHTOOL) mkdir /usr/tmp/nmap-$(NMAP_VERSION)/nsock/src
cp ../nsock/nsock.vcproj /usr/tmp/nmap-$(NMAP_VERSION)/nsock/
cd ../nsock; cp -a --parents include/nsock.h nsock.vcproj \
src/nsock_utils.c src/aclocal.m4 src/error.h src/netutils.c \
src/gh_list.h src/nsock_internal.h src/nsock_write.c \
src/nsock_core.c src/nsock_pool.c src/configure src/Makefile.in \
src/filespace.h src/nsock_utils.h src/install-sh src/config.sub \
src/nsock_timers.c src/nsock_read.c src/nsock_iod.c \
src/nsock_ssl.c src/config.guess src/filespace.c src/nsock_ssl.h \
src/configure.ac src/nsock_config.h.in src/nsock_connect.c \
src/nsock_event.c src/gh_list.c src/error.c src/netutils.h TODO \
/usr/tmp/nmap-$(NMAP_VERSION)/nsock/
rm -f /usr/tmp/nmap-$(NMAP_VERSION)/nbase/nbase_config.h
# Kill the SVN/CVS crap
find /usr/tmp/nmap-$(NMAP_VERSION) -type d -name CVS | xargs rm -rf
find /usr/tmp/nmap-$(NMAP_VERSION) -type d -name .svn | xargs rm -rf
find /usr/tmp/nmap-$(NMAP_VERSION) -exec chmod go=u-w '{}' \;
cd /usr/tmp; tar cjf nmap-$(NMAP_VERSION).tar.bz2 nmap-$(NMAP_VERSION)
cd /usr/tmp; tar czf nmap-$(NMAP_VERSION).tgz nmap-$(NMAP_VERSION)
# Make the actual RPM
# rpmbuild -ta --define "buildfe 0" --define "static 1" /usr/tmp/nmap-$(NMAP_VERSION).tgz
rpmbuild -ta --define "static 1" /usr/tmp/nmap-$(NMAP_VERSION).tgz
cp -f $(RPMTDIR)/RPMS/x86_64/nmap-$(NMAP_VERSION)-1.x86_64.rpm /usr/tmp
# cp -f $(RPMTDIR)/RPMS/i386/nmap-$(NMAP_VERSION)-1.i386.rpm /usr/tmp
cp -f $(RPMTDIR)/RPMS/x86_64/nmap-frontend-$(NMAP_VERSION)-1.x86_64.rpm /usr/tmp
cp -f $(RPMTDIR)/SRPMS/nmap-$(NMAP_VERSION)-1.src.rpm /usr/tmp
rm -rf /usr/tmp/nmap-$(NMAP_VERSION)

View File

@@ -1,209 +0,0 @@
/***************************************************************************
* fingerdiff.c -- A relatively simple utility for determining the *
* differences between a "reference" fingerprint (which can have *
* expressions as attributes) and an observed fingerprint (no *
* expressions). *
* *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2006 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-fingerprints or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is just meant to *
* clarify our interpretation of derived works with some common examples. *
* These restrictions only apply when you actually redistribute Nmap. For *
* example, nothing stops you from writing and selling a proprietary *
* front-end to Nmap. Just distribute it by itself, and point people to *
* http://insecure.org/nmap/ to download Nmap. *
* *
* We don't consider these to be added restrictions on top of the GPL, but *
* just a clarification of how we interpret "derived works" as it applies *
* to our GPL-licensed Nmap product. This is similar to the way Linus *
* Torvalds has announced his interpretation of how "derived works" *
* applies to Linux kernel modules. Our interpretation refers only to *
* Nmap - we don't speak for any other GPL products. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included Copying.OpenSSL file, and distribute linked *
* combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to fyodor@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering Fyodor and Insecure.Com LLC the unlimited, non-exclusive right *
* to reuse, modify, and relicense the code. Nmap will always be *
* available Open Source, but this is important because the inability to *
* relicense code has caused devastating problems for other Free Software *
* projects (such as KDE and NASM). We also occasionally relicense the *
* code to third parties as discussed above. If you wish to specify *
* special license conditions of your contributions, just say so when you *
* send them. *
* *
* 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 at *
* http://www.gnu.org/copyleft/gpl.html , or in the COPYING file included *
* with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#include "nbase.h"
#include "nmap.h"
#include "osscan.h"
#include "fingerlib.h"
void usage(char *err_fmt, ...) {
va_list ap;
if (err_fmt) {
va_start(ap, err_fmt);
fflush(stdout);
vfprintf(stderr, err_fmt, ap);
fprintf(stderr, "\n");
va_end(ap);
}
printf("\nUsage: Use fingerdiff w/o any arguments to read the reference\n"
" FP front stdin, or give filename:lineno to read it from\n"
" nmap-os-fingerprints.\n\n");
exit(1);
}
int main(int argc, char *argv[]) {
FingerPrint *referenceFP;
FingerPrint *observedFP;
double accuracy;
char sourcefile[MAXPATHLEN];
int sourceline=-1;
FingerPrintDB *DB = NULL;
char referenceFPString[8192];
char observedFPString[8192];
char line[512];
char *p, *endptr;
int i, rc;
int done=0;
FILE *fp;
FingerPrint *MatchPoints = NULL;
if (argc < 1 || argc > 2)
usage(NULL);
referenceFPString[0] = observedFPString[0] = '\0';
if (argc == 2) {
Strncpy(sourcefile, argv[1], sizeof(sourcefile));
p = strchr(sourcefile, ':');
if (!p) usage("Filename must be followed by a colon and then line number");
*p++ = '\0';
if (!*p) usage(NULL);
sourceline = strtol(p, &endptr, 10);
if (*endptr) {
error("could not parse line number (trailing garbage?)");
}
fp = fopen(sourcefile, "r");
done = 0; i = 1;
while(i < sourceline) {
if (fgets(line, sizeof(line), fp) == NULL)
usage("Failed to read to line %d of %s", sourceline, sourcefile);
i++;
}
if (readFP(fp, referenceFPString, sizeof(referenceFPString)) == -1)
usage("Failed to read in supposed fingerprint in %s line %d\n", sourcefile, sourceline);
fclose(fp);
/* Try to parse the file as an nmap-DB to get the matchpoints */
DB = parse_fingerprint_file(sourcefile);
if (DB) MatchPoints = DB->MatchPoints;
printf("STEP ONE: Reading REFERENCE FINGERPRINT from %s line %d:\n%s\n"
,sourcefile, sourceline, referenceFPString);
} else {
printf("STEP ONE: Enter the **REFERENCE FINGERPRINT**, followed by a blank or single-dot line:\n");
if (readFP(stdin, referenceFPString, sizeof(referenceFPString)) == -1)
usage("Failed to read in supposed fingerprint from stdin\n");
}
referenceFP = parse_single_fingerprint(referenceFPString);
if (!referenceFP) fatal("Sorry -- failed to parse the so-called reference fingerprint you entered");
printf("STEP TWO: Enter the **OBSERVED FINGERPRINT**, followed by a blank or single-dot line:\n");
if (readFP(stdin, observedFPString, sizeof(observedFPString)) == -1)
usage("Failed to read in supposed observed fingerprint from stdin\n");
observedFP = parse_single_fingerprint(observedFPString);
if (!observedFP) fatal("Sorry -- failed to parse the so-called reference fingerprint you entered");
if ((rc = remove_duplicate_tests(observedFP))) {
printf("[WARN] Adjusted fingerprint due to %d duplicated tests (we only look at the first).\n", rc);
}
/* OK, now I've got the fingerprints -- I just need to compare them ... */
accuracy = compare_fingerprints(referenceFP, observedFP, MatchPoints, 1);
if (accuracy == 1)
printf("PERFECT MATCH!\n");
else printf("Accuracy of the two prints is %d%% -- see differences above.\n",
(int) (accuracy * 100));
return 0;
}

View File

@@ -1,593 +0,0 @@
#include "nbase.h"
#include "nmap.h"
#include "osscan.h"
#include "MACLookup.h"
#include "fingerlib.h"
// attribute value length
#define AVLEN 128
void usage() {
printf("Usage: fingerdiff [filename:lineno]\n"
"If you pass a filename (e.g. ../nmap-os-db) and line number, that print will be merged with whatever you type as fingerprint data when prompted.\n\n");
exit(1);
}
typedef enum {
STR, DECNUM, HEXNUM
} SortAs;
static void sort_and_merge(struct AVal *result, char values[][AVLEN], int num, SortAs sortas) {
// sort and merge input values like 4,12,8 to 4|8|12. The sorting is
// firstly based on their length, and secondly based on their ascii
// order.
assert(num > 0);
int i, j;
char tmp[AVLEN];
int offset;
bool lt;
unsigned int val1, val2;
int base;
/* printf("MERGING %d values: ", num);
for (i = 0; i < num; i++) {
printf("%s ", values[i]);
}
printf("\n");
*/
// sort
for(i = 0; i < num; i++) {
for(j = 1; j < num - i; j++) {
lt = false;
if(sortas == STR) {
// sort as string
// string with less length is regarded as "smaller"
if((strlen(values[j-1]) > strlen(values[j])) ||
(strlen(values[j-1]) == strlen(values[j]) && strcmp(values[j-1], values[j]) > 0)) {
lt = true;
}
} else {
// sort as number
if(sortas == DECNUM) base = 10;
else if(sortas == HEXNUM) base = 16;
val1 = strtol(values[j-1], NULL, base);
val2 = strtol(values[j], NULL, base);
if(val1 > val2) lt = true;
}
if(lt) {
// printf("swap %s and %s\n", values[j-1], values[j]);
strcpy(tmp, values[j-1]);
strcpy(values[j-1], values[j]);
strcpy(values[j], tmp);
}
}
}
// merge.
offset = 0;
for(i = 0; i < num; i++) {
if(i > 0 && strcmp(values[i], tmp) == 0) {
// this is a duplicated value;
continue;
}
strcpy(tmp, values[i]);
offset += snprintf(result->value + offset, AVLEN - offset, "%s|", values[i]);
if(offset >= AVLEN) {
printf("[WARN] Attribute %s is too long and has been truncated\n", result->attribute);
return;
}
}
result->value[offset-1] = '\0'; // remove the final '|'
}
static void merge_gcd(struct AVal *result, char values[][AVLEN], int num) {
// When fingerfix gets a GCD like 0x32, it changes it to "GCD=<67".
// That seems kindof bogus. The GCD is only likely to be 0x32 or
// (in rare cases by coincidence) a small multiple of that. So I
// think it should give "GCD=32|64|96|C8|FA|12C". For the common
// case of GCD=1, still saying GCD=<7 is desirable because that is
// shorter than GCD=1|2|3|4|5|6 .
assert(num > 0);
const unsigned int LIM = 7;
int i, j;
char *p, *q, *endptr;
unsigned int val;
unsigned int curlim = 0;
bool haslim = false;
int newValueNum = 0;
char newValues[128][AVLEN];
// first let's find the limit
for(i = 0; i < num; i++) {
p = values[i];
q = strchr(p, '<');
if(q) {
val = strtol(q + 1, &endptr, 16);
if (q != p || *endptr) {
printf("[WARN] Invalid value (%s) occurs in attribute SEQ.GCD\n", p);
continue;
}
if(curlim < val) {
curlim = val;
haslim = true;
}
}
}
// Normally the limit should be the same with the LIM, since any limit
// exist in the fingerprint is supposed to be generated by this
// tool. Thus if it is not the case, print a warning.
if(haslim && curlim != LIM) {
printf("[WARN] Odd limit (%X) occurs in attribute SEQ.GCD", curlim);
if(curlim < LIM) curlim = LIM;
}
for(i = 0; i < num; i++) {
p = values[i];
q = strchr(p, '<');
if(q) continue; // let's skip those limit strings
val = strtol(p, &endptr, 16);
if (*endptr) {
printf("[WARN] Invalid value (%s) occurs in attribute SEQ.GCD\n", p);
continue;
} else if(val == 0) {
printf("[WARN] Zero value occurs in attribute SEQ.GCD\n");
}
if(haslim) {
if(val <= curlim) continue;
} else if(val <= LIM) {
curlim = LIM;
haslim = true;
continue;
}
for(j = 1; j < 7; j++)
snprintf(newValues[newValueNum++], AVLEN, "%X", val * j);
}
if(newValueNum == 0 && haslim) {
snprintf(result->value, AVLEN, "<%X", curlim);
} else if(newValueNum > 0 && !haslim) {
sort_and_merge(result, newValues, newValueNum, HEXNUM);
} else if(newValues > 0 && haslim) {
struct AVal semiresult;
int offset;
semiresult.attribute = "GCD";
sort_and_merge(&semiresult, newValues, newValueNum, HEXNUM);
// insert the limit string to the front of it
offset = snprintf(result->value, AVLEN, "<%X|%s", curlim, semiresult.value);
if(offset>=AVLEN) {
printf("[WARN] SEQ.GCD is too long and has been truncated\n");
}
} else {
result->value[0] = '\0';
}
}
/* The "R" tests designate whether a response was
received. These can be tricky because packets (probe
or response) may have been dropped on the network
between the source and target host. So in a merge
between an "N" and a "Y", the result is simply "Y".
But if we are given an "R=N|Y" (which would have been
done manually), we preserve it rather than dropping the
N. */
static void merge_response_element(const char *testname, struct AVal *result,
char values[][AVLEN], int num) {
bool yesrequired = false;
bool norequired = false;
bool foundno = false;
int i;
assert(num > 0);
// look at the values
for(i = 0; i < num; i++) {
if (strcmp(values[i], "Y") == 0)
yesrequired = true;
else if (strcmp(values[i], "N|Y") == 0 || strcmp(values[i], "Y|N") == 0)
yesrequired = norequired = true;
else if (strcmp(values[i], "N") == 0)
foundno = true;
else fatal("[ERRO] Bogus R value \"%s\" discuvered (should be N, Y, or N|Y)", values[i]);
}
// Now decide on the results
if (yesrequired && norequired)
Strncpy(result->value, "N|Y", AVLEN);
else if (yesrequired) {
Strncpy(result->value, "Y", AVLEN);
if (foundno)
printf("[WARN] Ignoring test %s.%s \"N\" value because it was found \"Y\" in another instance\n", testname, result->attribute);
}
else
Strncpy(result->value, "N", AVLEN);
return;
}
static void merge_sp_or_isr(struct AVal *result, char values[][AVLEN], int num) {
// Fingerfix should expand elements based on observed deviation.
// So if a fingerprint comes in with SP=0x9C (and that is the only
// SEQ line), that means that all 3 Nmap tries had SP=0x9C and so it
// may be OK to just use 0x9C in the reference fingerprint
// generated, or maybe expand it by 1 like 0x9B-0x9D. But if the
// fingerprint has 3 seq lines (which Nmap does when any elements in
// it differ) and they show SP values of 0x9C, 0x84, and 0xA7, you
// may want to handle them as: 1) You see 0x9C. Now your low and
// high values are 0x9c 2) You see 0x84. This makes for a low of
// 0x84 and a high of 0x9C you've seen. But you may want to double
// the size of this new range, so it is now 0x78-0xA8. Note that
// since your previous low and high values were equal, you expand in
// both directions rather than just expanding in one direction. But
// once you have developed a range, you'll start expanding only in
// the direction of the outlying value. 3) You see 0xA7. This fits
// into your range so you ignore it. 4) Suppose you then see 0xAA.
// This is 3 higher than the top of your range, so you double that
// and extend your upper range by 6 to 0x78-0xAD. It is important
// to be careful not to keep expanding already-expanded values. So
// if someone passes 0x78-0xAD in a reference FP to fingerfix, don't
// double that range again. But if you then see 0x77, you would
// change your range to 0x76-0xAD. This way we keep tight
// fingerprints where the SP doesn't differ so much, but we avoid
// having to constantly tweak fingerprints which differ
// dramatically.
assert(num > 0);
int i;
int low, high, val1, val2;
char *p, *q, *r, buf[AVLEN];
result->value[0] = '\0';
for(i = 0; i < num; i++) {
strncpy(buf, values[i], AVLEN);
p = strchr(buf, '-');
if(p) {
// an interval
*p = '\0';
val1 = (int)strtol(buf, &q, 16);
val2 = (int)strtol(p+1, &r, 16);
if(*q || *r || val1 >= val2) {
printf("[WARN] Invalid value (%s) occurs in attribute SEQ.%s\n", values[i], result->attribute);
return;
}
// do not expand an interval
if(i == 0) {
low = val1;
high = val2;
} else {
if(val1 < low) low = val1;
if(val2 > high) high = val2;
}
} else {
// a value
val1 = (int)strtol(buf, &p, 16);
if(*p) {
printf("[WARN] Invalid value (%s) occurs in attribute SEQ.%s\n", values[i], result->attribute);
return;
}
if(!val1) {
// a zero sp/isr value, this should
printf("[WARN] Zero value occurs in attribute SEQ.%s. A constant ISN sequence?\n", result->attribute);
}
if(i == 0) {
/* Start it out with a variance of five in each direction */
low = MAX(0, val1 - 5);
high = val1 + 5;
} else {
if(low == high && val1 != low) {
// expand it in both directions
if(val1 < low) {
low = val1 - (low - val1) / 2;
high = high + (high - val1) / 2;
} else {
low = low - (val1 - low) / 2;
high = high + (val1 - high) / 2;
}
if(low < 0) low = 0;
} else if(val1 < low) {
// expand in the left direction
low = val1 - (low - val1);
if(low < 0) low = 0;
} else if(val1 > high) {
// expand in the right direction
high = val1 + (val1 - high);
}
}
}
}
if(low == high && low == 0) {
snprintf(result->value, AVLEN, "0");
return;
}
if(low == high) {
// expanded it a little
low = low - 1;
if(low < 0) low = 0;
high = high + 1;
}
snprintf(result->value, AVLEN, "%X-%X", low, high);
}
int main(int argc, char *argv[]) {
FingerPrint *observedFP;
FingerPrint *resultFP;
FingerPrint *resultFPLine, *observedFPLine;
char observedFPString[8192];
char observedFPString2[8192];
char sourcefile[MAXPATHLEN];
int sourceline=-1;
char *p, *endptr;
FILE *fp;
int done = 0;
char line[512];
int i;
char resultTemplate[] = {"SEQ(SP=%GCD=%ISR=%TI=%II=%SS=%TS=)\n"
"OPS(O1=%O2=%O3=%O4=%O5=%O6=)\n"
"WIN(W1=%W2=%W3=%W4=%W5=%W6=)\n"
"ECN(R=%DF=%T=%TG=%W=%O=%CC=%Q=)\n"
"T1(R=%DF=%T=%TG=%S=%A=%F=%RD=%Q=)\n"
"T2(R=%DF=%T=%TG=%W=%S=%A=%F=%O=%RD=%Q=)\n"
"T3(R=%DF=%T=%TG=%W=%S=%A=%F=%O=%RD=%Q=)\n"
"T4(R=%DF=%T=%TG=%W=%S=%A=%F=%O=%RD=%Q=)\n"
"T5(R=%DF=%T=%TG=%W=%S=%A=%F=%O=%RD=%Q=)\n"
"T6(R=%DF=%T=%TG=%W=%S=%A=%F=%O=%RD=%Q=)\n"
"T7(R=%DF=%T=%TG=%W=%S=%A=%F=%O=%RD=%Q=)\n"
"U1(DF=%T=%TG=%TOS=%IPL=%UN=%RIPL=%RID=%RIPCK=%RUCK=%RUL=%RUD=)\n"
"IE(DFI=%T=%TG=%TOSI=%CD=%SI=%DLI=)\n"
};
if (argc != 1 && argc != 2)
usage();
observedFPString2[0] = '\0';
if (argc == 2) {
Strncpy(sourcefile, argv[1], sizeof(sourcefile));
p = strchr(sourcefile, ':');
if (!p) fatal("[ERRO] Filename must be followed by a colon and then line number");
*p++ = '\0';
if (!*p) fatal("[ERRO] Bad command-line arg");
sourceline = strtol(p, &endptr, 10);
if (*endptr) {
error("could not parse line number (trailing garbage?)");
}
fp = fopen(sourcefile, "r");
done = 0; i = 1;
while(i < sourceline) {
if (fgets(line, sizeof(line), fp) == NULL)
fatal("[ERRO] Failed to read to line %d of %s", sourceline, sourcefile);
i++;
}
if (readFP(fp, observedFPString2, sizeof(observedFPString2)) == -1)
fatal("[ERRO] Failed to read in supposed fingerprint in %s line %d\n", sourcefile, sourceline);
fclose(fp);
printf("Read in referenceFP:\n%s\n", observedFPString2);
}
observedFPString[0] = '\0';
printf("Enter the fingerprint(s) you want to fix, followed by a blank or single-dot line:\n");
if (readFP(stdin, observedFPString, sizeof(observedFPString)) == -1)
fatal("[ERRO] Failed to read in supposed fingerprint from stdin\n");
/* Now merge the observedFP and observedFP2 (if any). We want the
file version to come first as that makes a difference for things
like SEQ.SP and SEQ.ISR merging */
if (*observedFPString2) {
strncat(observedFPString2, observedFPString, sizeof(observedFPString2));
Strncpy(observedFPString, observedFPString2, sizeof(observedFPString));
}
observedFP = parse_single_fingerprint(observedFPString);
if (!observedFP) fatal("[ERRO] failed to parse the observed fingerprint you entered\n");
// printf("%s", fp2ascii(observedFP));
resultFP = parse_single_fingerprint(resultTemplate);
// printf("%s", fp2ascii(resultFP));
bool foundline;
struct AVal *resultAV, *observedAV, *tmpAV;
char values[16][AVLEN];
int avnum;
for(resultFPLine = resultFP; resultFPLine; resultFPLine = resultFPLine->next) {
// step 1:
//
// Check if this line is missing in the input fingerprint. If yes,
// replace the result line with a R=N.
foundline = false;
for(observedFPLine = observedFP; observedFPLine; observedFPLine = observedFPLine->next) {
if(observedFPLine->name && strcmp(resultFPLine->name, observedFPLine->name) == 0) {
// Found the corresponding line. If it doesn't begin with a
// R=N, then we take it as a good line.
if(observedFPLine->results &&
!(strcmp(observedFPLine->results->attribute, "R") == 0 &&
strcmp(observedFPLine->results->value, "N") == 0)) {
foundline = true;
break;
}
}
}
if(!foundline) {
// replace the fingerprint line with a R=N
free(resultFPLine->results);
tmpAV = (struct AVal *) safe_zalloc(sizeof(struct AVal));
tmpAV->attribute = "R";
strcpy(tmpAV->value, "N");
resultFPLine->results = tmpAV;
continue;
}
// step 2:
//
// For each AVal of this fingerprint line, merge all the
// counterpart values appeared in the input fingerprint.
for(resultAV = resultFPLine->results; resultAV; resultAV = resultAV->next) {
avnum = 0;
for(observedFPLine = observedFP; observedFPLine; observedFPLine = observedFPLine->next) {
if(strcmp(resultFPLine->name, observedFPLine->name) == 0) {
for(observedAV = observedFPLine->results; observedAV; observedAV = observedAV->next) {
// printf("Found %s.%s value: %s\n", observedFPLine->name, observedAV->attribute, observedAV->value);
if(strcmp(resultAV->attribute, observedAV->attribute) == 0) {
// check if we have stored the same attribute value if
// not, store it
bool stored;
char *p, *q;
p = observedAV->value;
do {
stored = false;
q = strchr(p, '|');
if(q) *q = '\0';
for(i = 0; i < avnum; i++) {
if(strcmp(values[i], p) == 0) {
stored = true;
break;
}
}
if(!stored) {
strcpy(values[avnum++], p);
}
if(q) p = q + 1;
else break;
} while (p && *p);
}
}
}
}
if(avnum == 0) {
// no value for this attribute, now handle the next attribute
continue;
}
// now we get all the values for this attribute, it's time to
// merge them. let's first handle some special attributes.
if(strcmp(resultFPLine->name, "SEQ") == 0 && strcmp(resultAV->attribute, "GCD") == 0) {
// SEQ.GCD
merge_gcd(resultAV, values, avnum);
} else if(strcmp(resultFPLine->name, "SEQ") == 0 &&
(strcmp(resultAV->attribute, "SP") == 0 ||
strcmp(resultAV->attribute, "ISR") == 0)) {
// SEQ.SP or SEQ.ISR
merge_sp_or_isr(resultAV, values, avnum);
} else if (strcmp(resultAV->attribute, "R") == 0) {
/* The "R" tests designate whether a response was
received. These can be tricky because packets (probe
or response) may have been dropped on the network
between the source and target host. So in a merge
between an "N" and a "Y", the result is simply "Y".
But if we are given an "R=N|Y" (which would have been
done manually), we preserve it rather than dropping the
N. */
merge_response_element(resultFPLine->name, resultAV, values, avnum);
} else {
// common merge
sort_and_merge(resultAV, values, avnum, STR);
}
}
// step 3:
// handle some special cases:
// o remove SEQ.SS if it is null
// o make up the TTL and TTL guess stuff
struct AVal *av1, *av2;
// remove SEQ.SS
if(strcmp(resultFPLine->name, "SEQ") == 0) {
av1 = resultFPLine->results;
while(av1) {
if(strcmp(av1->attribute, "SS") == 0 && strlen(av1->value) == 0) {
if(av1 == resultFPLine->results) {
resultFPLine->results = av1->next;
break;
} else {
av2->next = av1->next;
break;
}
}
av2 = av1;
av1 = av1->next;
}
}
// TTL and TTL Guess
av1 = NULL;
av2 = NULL;
if(strcmp(resultFPLine->name, "ECN") == 0 ||
strcmp(resultFPLine->name, "T1") == 0 ||
strcmp(resultFPLine->name, "T2") == 0 ||
strcmp(resultFPLine->name, "T3") == 0 ||
strcmp(resultFPLine->name, "T4") == 0 ||
strcmp(resultFPLine->name, "T5") == 0 ||
strcmp(resultFPLine->name, "T6") == 0 ||
strcmp(resultFPLine->name, "T7") == 0 ||
strcmp(resultFPLine->name, "U1") == 0 ||
strcmp(resultFPLine->name, "IE") == 0) {
for(tmpAV = resultFPLine->results; tmpAV; tmpAV = tmpAV->next ) {
if(strcmp(tmpAV->attribute, "T") == 0) {
av1 = tmpAV;
} else if(strcmp(tmpAV->attribute, "TG") == 0) {
av2 = tmpAV;
}
}
assert(av1&&av2);
if(strlen(av1->value) == 0 && strlen(av2->value) > 0) {
strcpy(av1->value, av2->value);
} else if(strlen(av2->value) == 0 && strlen(av1->value) > 0) {
strcpy(av2->value, av1->value);
}
}
}
// whew, we finally complete the job, now spit it out.
printf("\nADJUSTED FINGERPRINT:\n");
// OS Name
if(observedFP->OS_name) {
printf("# %s\nFingerprint %s\n", observedFP->OS_name, observedFP->OS_name);
} else {
// print an empty fingerprint
printf("Fingerprint\n");
}
// Class
if(observedFP->num_OS_Classifications > 0) {
for(i = 0; i<observedFP->num_OS_Classifications; i++) {
printf("Class %s | %s |",
observedFP->OS_class[i].OS_Vendor,
observedFP->OS_class[i].OS_Family);
if(observedFP->OS_class[i].OS_Generation) {
printf(" %s |", observedFP->OS_class[i].OS_Generation);
} else {
printf("|");
}
printf(" %s\n", observedFP->OS_class[i].Device_Type);
}
} else {
// print a empty class line
printf("Class\n");
}
// Fingerprint
printf("%s", fp2ascii(resultFP));
return 0;
}

View File

@@ -1,798 +0,0 @@
#!/usr/bin/perl
sub max($$) {
my ($a, $b) = @_;
if ($a >= $b) { return $a;}
return $b;
}
sub min($$) {
my ($a, $b) = @_;
if ($a <= $b) { return $a;}
return $b;
}
sub fpunwrap($) {
my $fp = shift();
$fp =~ s/^\s*OS://mg;
$fp =~ s/\n//g;
$fp =~ s/\s+$//g;
$fp =~ s/\)/\)\n/g;
return $fp;
}
# first read in the fingerprint
my $printbuf = "";
my $wrapped = 0;
while(<>) {
chomp;
$line = $_;
if (($line eq "." || $line eq "")) {
if ($printbuf) { last; }
} else { $printbuf .= "$line\n"; }
if ($line =~ /^\s*OS:/) { $wrapped = 1; }
}
if ($wrapped) {
$printbuf = fpunwrap($printbuf);
print "UNWRAPPED FINGERPRINT:\n$printbuf\n";
}
# At this point I have an unwrapped FP in $printbuf
foreach $line (split /\n/, $printbuf) {
chomp($line);
# Itemize the lines we know how to deal with
if (!$line =~ /(Fingerprint\s+\S)|(Class\s+\S)|(^SEQ)|(^OPS)|(^WIN)|(^ECN)|(^T[1-7])|(^U1)|(^IE)|(^Contributed by)/i) { next; }
# If this is coming from the submission form, there may already be a Contributor attached
if ($line =~ /Contributed by (.*)/) {
if (!$fp{contrib}) {
$fp{contrib} = $1;
} else { $fp{contrib} .= ", $1"; }
}
# We also get a Fingerprint line describing what this system (supposedly) is if it is coming from
# the submission CGI.
elsif ($line =~ /Fingerprint\s+(.*)/i) {
$fp{os} = $1;
}
# If the submitter gave a classification, we have a Class line
elsif ($line =~ /Class\s+(.*)/i) {
if (!$fp{class} or !($fp{class} =~ /\Q$line\E/)) {
$fp{class} .= $line . "\n";
}
}
# OK, time for the first real fingerprint line! The SEQ line
elsif ($line =~ /SEQ\(SP=([^%]+)%GCD=([^%\)]+)%ISR=([^%\)]+)(%TI=([^%\)]+))?(%II=([^%\)]+))?(%SS=([^%\)]+))?(%TS=([^%\)]+))?\)/) {
# SEQ
$sp = $1;
$gcd = hex($2);
$isr = $3;
$ti = $5;
$ii = $7;
$ss = $9;
$ts = $11;
if ($fp{seq}{gcd} =~ /<([0-9A-F]+)/) {
$oldgcd = hex($1);
} else { $oldgcd = 3; }
$newgcd = max($oldgcd, $gcd * 2 + 3);
$fp{seq}{gcd} = sprintf ("<%X", $newgcd);
$newhighlim = $newlowlim = -1;
if ($sp =~ /([0-9A-F]+)-([0-9A-F]+)/) {
$newlowlim = hex($1);
$newhighlim = hex($2);
} elsif ($sp =~ /<([0-9A-F]+)/) {
$newhighlim = hex($1);
}
# print "newhighlim: $newhighlim newlowlim: $newlowlim\n";
$oldhighlim = $oldlowlim = 0;
if ($fp{seq}{sp} =~ /([0-9A-F]+)-([0-9A-F]+)/) {
$oldlowlim = hex($1);
$oldhighlim = hex($2);
} elsif ($fp{seq}{sp} =~ /<([0-9A-F]+)/) {
$oldhighlim = hex($1);
} elsif ($fp{seq}{sp} =~ /^([0-9A-F]+)/) {
$oldhighlim = $oldlowlim = hex($1);
}
# print "oldhighlim: $oldhighlim oldlowlim: $oldlowlim\n";
if ($oldlowlim) {
if ($newlowlim != -1) { $newlowlim = max(0, min($oldlowlim, $newlowlim)); }
else { $newlowlim = max(0, min($oldlowlim, hex($sp))); }
} else {
if ($newlowlim == -1) { $newlowlim = max(0, hex($sp)); }
}
if ($newhighlim == -1) {
$newhighlim = max($oldhighlim, hex($sp));
} else {
$newhighlim = max($oldhighlim, $newhighlim);
}
# print "oldhighlim: $oldhighlim oldlowlim: $oldlowlim newhighlim: $newhighlim newlowlim: $newlowlim oldsp: $fp{seq}{sp}";
if ($newlowlim eq $newhighlim) {
$fp{seq}{sp} = sprintf("%X", $newhighlim);
} elsif ($newlowlim > 0) {
$fp{seq}{sp} = sprintf("%X-%X", $newlowlim, $newhighlim);
} else {
$fp{seq}{sp} = sprintf("<%X", $newhighlim);
}
# print " newsp: $fp{seq}{sp}\n";
# Treat ISR the same way as sp
$newhighlim = $newlowlim = -1;
if ($isr =~ /([0-9A-F]+)-([0-9A-F]+)/) {
$newlowlim = hex($1);
$newhighlim = hex($2);
} elsif ($isr =~ /<([0-9A-F]+)/) {
$newhighlim = hex($1);
}
# print "newhighlim: $newhighlim newlowlim: $newlowlim\n";
$oldhighlim = $oldlowlim = 0;
if ($fp{seq}{isr} =~ /([0-9A-F]+)-([0-9A-F]+)/) {
$oldlowlim = hex($1);
$oldhighlim = hex($2);
} elsif ($fp{seq}{isr} =~ /<([0-9A-F]+)/) {
$oldhighlim = hex($1);
} elsif ($fp{seq}{isr} =~ /^([0-9A-F]+)/) {
$oldhighlim = $oldlowlim = hex($1);
}
# print "oldhighlim: $oldhighlim oldlowlim: $oldlowlim\n";
if ($oldlowlim) {
if ($newlowlim != -1) { $newlowlim = max(0, min($oldlowlim, $newlowlim)); }
else { $newlowlim = max(0, min($oldlowlim, hex($isr))); }
} else {
if ($newlowlim == -1) { $newlowlim = max(0, hex($isr)); }
}
if ($newhighlim == -1) {
$newhighlim = max($oldhighlim, hex($isr));
} else {
$newhighlim = max($oldhighlim, $newhighlim);
}
# print "oldhighlim: $oldhighlim oldlowlim: $oldlowlim newhighlim: $newhighlim newlowlim: $newlowlim oldisr: $fp{seq}{isr}";
if ($newlowlim eq $newhighlim) {
$fp{seq}{isr} = sprintf("%X", $newhighlim);
} elsif ($newlowlim > 0) {
$fp{seq}{isr} = sprintf("%X-%X", $newlowlim, $newhighlim);
} else {
$fp{seq}{isr} = sprintf("<%X", $newhighlim);
}
# print " newisr: $fp{seq}{isr}\n";
if (!($fp{seq}{ti} =~ /(^|\|)$ti($|\|)/)) {
if ($fp{seq}{ti}) {
$fp{seq}{ti} = $fp{seq}{ti} . qq^|$ti^;
} else {
$fp{seq}{ti} = $ti;
}
}
if (!($fp{seq}{ii} =~ /(^|\|)$ii($|\|)/)) {
if ($fp{seq}{ii}) {
$fp{seq}{ii} = $fp{seq}{ii} . qq^|$ii^;
} else {
$fp{seq}{ii} = $ii;
}
}
if (!($fp{seq}{ss} =~ /(^|\|)$ss($|\|)/)) {
if ($fp{seq}{ss}) {
$fp{seq}{ss} = $fp{seq}{ss} . qq^|$ss^;
} else {
$fp{seq}{ss} = $ss;
}
}
if (!($fp{seq}{ts} =~ /(^|\|)$ts($|\|)/)) {
if ($fp{seq}{ts}) {
$fp{seq}{ts} = $fp{seq}{ts} . qq^|$ts^;
} else {
$fp{seq}{ts} = $ts;
}
}
} elsif ($line =~ /^OPS/) {
# Time for the second test line -- Ops (Options)
foreach $num (1 .. 6) {
$o = "";
$oi = "o$num";
if ($line =~ /[\(%]O$num=([0-9A-Z|]*)/) {
$o = $1;
if (!$o) { $o = "NULL"; }
}
if (!($fp{ops}{$oi} =~ /(^|\|)$o($|\|)/)) {
if ($fp{ops}{$oi}) {
$fp{ops}{$oi} = $fp{ops}{$oi} . qq^|$o^;
} else {
$fp{ops}{$oi} = $o;
}
}
}
} elsif ($line =~ /^WIN/) {
# WIN - Window values
foreach $num (1 .. 6) {
$w = "";
$wi = "w$num";
if ($line =~ /[\(%]W$num=([0-9A-F|]*)/) {
$w = $1;
if (!$w) { $w = "NULL"; }
}
if (!($fp{win}{$wi} =~ /(^|\|)$w($|\|)/)) {
if ($fp{win}{$wi}) {
$fp{win}{$wi} = $fp{win}{$wi} . qq^|$w^;
} else {
$fp{win}{$wi} = $w;
}
}
}
} elsif ($line =~ /^ECN/) {
# ECN - Explicit Congestion Notification probe response
$resp = $df = $ttl = $win = $ops = $cc = $quirk = "";
if ($line =~ /R=([NY])/) {
$resp = $1;
}
if ($line =~ /[\(%]DF=([NY])/) {
$df = $1;
}
if ($line =~ /[\(%]TG?=([0-9A-F]+)/) {
$ttl = $1;
if (!$ttl) { $ttl = "NULL"; }
}
if ($line =~ /[\(%]W=([0-9A-F|]*)/) {
$win = $1;
if (!$win) { $win = "NULL"; }
}
if ($line =~ /[\(%]O=([0-9A-Z|]*)/) {
$ops = $1;
if (!$ops) { $ops = "NULL"; }
}
if ($line =~ /[\(%]CC=([NY])/) {
$cc = $1;
}
if ($line =~ /[\(%]Q=(R?U?)/) {
$quirk = $1;
if (!$quirk) { $quirk = "NULL"; }
}
if ($resp eq "Y" or !$resp) {
$fp{ecn}{resp} = "Y";
if ($df and !($fp{ecn}{df} =~ /(^|\|)$df($|\|)/)) {
if ($fp{ecn}{df}) {
$fp{ecn}{df} .= qq^|$df^;
} else {
$fp{ecn}{df} = $df;
}
}
if (!($fp{ecn}{ttl} =~ /(^|\|)$ttl($|\|)/)) {
if ($fp{ecn}{ttl}) {
$fp{ecn}{ttl} = $fp{ecn}{ttl} . qq^|$ttl^;
} else {
$fp{ecn}{ttl} = $ttl;
}
}
if (!($fp{ecn}{win} =~ /(^|\|)$win($|\|)/)) {
if ($fp{ecn}{win}) {
$fp{ecn}{win} = $fp{ecn}{win} . qq^|$win^;
} else {
$fp{ecn}{win} = $win;
}
}
if (!($fp{ecn}{ops} =~ /(^|\|)$ops($|\|)/)) {
if ($fp{ecn}{ops}) {
$fp{ecn}{ops} = $fp{ecn}{ops} . qq^|$ops^;
} else {
$fp{ecn}{ops} = $ops;
}
}
if ($cc and !($fp{ecn}{cc} =~ /(^|\|)$cc($|\|)/)) {
if ($fp{ecn}{cc}) {
$fp{ecn}{cc} .= qq^|$cc^;
} else {
$fp{ecn}{cc} = $cc;
}
}
if (!($fp{ecn}{quirk} =~ /(^|\|)$quirk($|\|)/)) {
if ($fp{ecn}{quirk}) {
$fp{ecn}{quirk} .= qq^|$quirk^;
} else {
$fp{ecn}{quirk} = $quirk;
}
}
} elsif ($fp{ecn}{resp} ne "Y") {
$fp{ecn}{resp} = "N";
}
} elsif ($line =~ /^T([1-7])/) {
$num = $1;
$test = "T$num";
$resp = $df = $ttl = $win = $seq = $ack = $flags = $ops = $rd = $quirk = "";
if ($line =~ /R=([NY])/) {
$resp = $1;
}
if ($line =~ /[\(%]DF=([NY])/) {
$df = $1;
}
if ($line =~ /[\(%]TG?=([0-9A-F]+)/) {
$ttl = $1;
if (!$ttl) { $ttl = "NULL"; }
}
if ($num != 1 and $line =~ /[\(%]W=([0-9A-F|]*)/) {
$win = $1;
if (!$win) { $win = "NULL"; }
}
if ($line =~ /[\(%]S=([^%]+)/) {
$seq = $1;
}
if ($line =~ /[\(%]A=([^%]+)/) {
$ack = $1;
}
if ($line =~ /[\(%]F=([^%]*)/) {
$flags = $1;
if (!$flags) { $flags = "NULL"; }
}
if ($num != 1 and $line =~ /[\(%]O=([0-9A-Z|]*)/) {
$ops = $1;
if (!$ops) { $ops = "NULL"; }
}
if ($line =~ /[\(%]RD=([0-9A-F]*)/) {
$rd = $1;
if (!$rd) { $rd = "NULL"; }
}
if ($line =~ /[\(%]Q=(R?U?)/) {
$quirk = $1;
if (!$quirk) { $quirk = "NULL"; }
}
if ($resp eq "Y" or !$resp) {
$fp{$test}{resp} = "Y";
if ($df and !($fp{$test}{df} =~ /(^|\|)$df($|\|)/)) {
if ($fp{$test}{df}) {
$fp{$test}{df} .= qq^|$df^;
} else {
$fp{$test}{df} = $df;
}
}
if (!($fp{$test}{ttl} =~ /(^|\|)$ttl($|\|)/)) {
if ($fp{$test}{ttl}) {
$fp{$test}{ttl} = $fp{$test}{ttl} . qq^|$ttl^;
} else {
$fp{$test}{ttl} = $ttl;
}
}
if ($num != 1 and !($fp{$test}{win} =~ /(^|\|)$win($|\|)/)) {
if ($fp{$test}{win}) {
$fp{$test}{win} = $fp{$test}{win} . qq^|$win^;
} else {
$fp{$test}{win} = $win;
}
}
if ($seq and !($fp{$test}{seq} =~ /(^|\|)$seq($|\|)/)) {
if ($fp{$test}{seq}) {
$fp{$test}{seq} .= qq^|$seq^;
} else {
$fp{$test}{seq} = $seq;
}
}
# Quick hack to stop S+ from repeating endlessly ...
$acktmp = $ack;
$acktmp =~ s/\+/\\+/g;
if ($acktmp and !($fp{$test}{ack} =~ /(^|\|)$acktmp($|\|)/)) {
if ($fp{$test}{ack}) {
$fp{$test}{ack} .= qq^|$ack^;
} else {
$fp{$test}{ack} = $ack;
}
}
if (!($fp{$test}{flags} =~ /(^|\|)$flags($|\|)/)) {
if ($fp{$test}{flags}) {
$fp{$test}{flags} = $fp{$test}{flags} . qq^|$flags^;
} else {
$fp{$test}{flags} = $flags;
}
}
if ($num != 1 and !($fp{$test}{ops} =~ /(^|\|)$ops($|\|)/)) {
if ($fp{$test}{ops}) {
$fp{$test}{ops} = $fp{$test}{ops} . qq^|$ops^;
} else {
$fp{$test}{ops} = $ops;
}
}
if (!($fp{$test}{rd} =~ /(^|\|)$rd($|\|)/)) {
if ($fp{$test}{rd}) {
$fp{$test}{rd} = $fp{$test}{rd} . qq^|$rd^;
} else {
$fp{$test}{rd} = $rd;
}
}
if (!($fp{$test}{quirk} =~ /(^|\|)$quirk($|\|)/)) {
if ($fp{$test}{quirk}) {
$fp{$test}{quirk} .= qq^|$quirk^;
} else {
$fp{$test}{quirk} = $quirk;
}
}
} elsif ($fp{$test}{resp} ne "Y") {
$fp{$test}{resp} = "N";
}
} elsif ($line =~ /^U1/) {
$resp = $df = $ttl = $tos = $ipl = $un = $ripl = $rid = $ripck = $ruck = $rul = $rud = "";
if ($line =~ /R=([NY])/) {
$resp = $1;
}
if ($line =~ /[\(%]DF=([NY])/) {
$df = $1;
}
if ($line =~ /[\(%]TG?=([0-9A-F]+)/) {
$ttl = $1;
if (!$ttl) { $ttl = "NULL"; }
}
if ($line =~ /[\(%]TOS=([^%]+)/) {
$tos = $1;
if (!$tos) { $tos = "NULL"; }
}
if ($line =~ /[\(%]IPL=([^%]+)/) {
$ipl = $1;
}
if ($line =~ /[\(%]UN=([0-9A-F]*)/) {
$un = $1;
if (!$un) { $un = "NULL"; }
}
if ($line =~ /[\(%]RIPL=([^%]+)/) {
$ripl = $1;
}
if ($line =~ /[\(%]RID=([^%]+)/) {
$rid = $1;
}
if ($line =~ /[\(%]RIPCK=([^%]+)/) {
$ripck = $1;
if (!$ripck) { $ripck = "NULL"; }
}
if ($line =~ /[\(%]RUCK=([^%]+)/) {
$ruck = $1;
if (!$ruck) { $ruck = "NULL"; }
}
if ($line =~ /[\(%]RUL=([^%]+)/) {
$rul = $1;
}
if ($line =~ /[\(%]RUD=([A-Z|]+)/) {
$rud = $1;
}
if ($resp eq "Y" or !$resp) {
$fp{u1}{resp} = "Y";
if ($df and index($fp{u1}{df}, $df) == -1) {
if ($fp{u1}{df}) {
$fp{u1}{df} = $fp{u1}{df} . qq^|$df^;
} else {
$fp{u1}{df} = $df;
}
}
if (!($fp{u1}{ttl} =~ /(^|\|)$ttl($|\|)/)) {
if ($fp{u1}{ttl}) {
$fp{u1}{ttl} = $fp{u1}{ttl} . qq^|$ttl^;
} else {
$fp{u1}{ttl} = $ttl;
}
}
if ($tos and index($fp{u1}{tos}, $tos) == -1) {
if ($fp{u1}{tos}) {
$fp{u1}{tos} = $fp{u1}{tos} . qq^|$tos^;
} else {
$fp{u1}{tos} = $tos;
}
}
if ($ipl and index($fp{u1}{ipl}, $ipl) == -1) {
if ($fp{u1}{ipl}) {
$fp{u1}{ipl} = $fp{u1}{ipl} . qq^|$ipl^;
} else {
$fp{u1}{ipl} = $ipl;
}
}
if ($un and index($fp{u1}{un}, $un) == -1) {
if ($fp{u1}{un}) {
$fp{u1}{un} = $fp{u1}{un} . qq^|$un^;
} else {
$fp{u1}{un} = $un;
}
}
if ($ripl and index($fp{u1}{ripl}, $ripl) == -1) {
if ($fp{u1}{ripl}) {
$fp{u1}{ripl} = $fp{u1}{ripl} . qq^|$ripl^;
} else {
$fp{u1}{ripl} = $ripl;
}
}
if ($rid and index($fp{u1}{rid}, $rid) == -1) {
if ($fp{u1}{rid}) {
$fp{u1}{rid} = $fp{u1}{rid} . qq^|$rid^;
} else {
$fp{u1}{rid} = $rid;
}
}
if ($ripck and index($fp{u1}{ripck}, $ripck) == -1) {
if ($fp{u1}{ripck}) {
$fp{u1}{ripck} = $fp{u1}{ripck} . qq^|$ripck^;
} else {
$fp{u1}{ripck} = $ripck;
}
}
if ($ruck and index($fp{u1}{ruck}, $ruck) == -1) {
if ($fp{u1}{ruck}) {
$fp{u1}{ruck} = $fp{u1}{ruck} . qq^|$ruck^;
} else {
$fp{u1}{ruck} = $ruck;
}
}
if ($rul and index($fp{u1}{rul}, $rul) == -1) {
if ($fp{u1}{rul}) {
$fp{u1}{rul} = $fp{u1}{rul} . qq^|$rul^;
} else {
$fp{u1}{rul} = $rul;
}
}
if ($rud and index($fp{u1}{rud}, $rud) == -1) {
if ($fp{u1}{rud}) {
$fp{u1}{rud} = $fp{u1}{rud} . qq^|$rud^;
} else {
$fp{u1}{rud} = $rud;
}
}
} elsif ($fp{u1}{resp} ne "Y") {
$fp{u1}{resp} = "N";
}
} elsif ($line =~ /^IE/) {
$resp = $dfi = $ttl = $tosi = $cd = $si = $dli = "";
if ($line =~ /R=([NY])/) {
$resp = $1;
}
if ($line =~ /[\(%]DFI=([^%]+)/) {
$dfi = $1;
}
if ($line =~ /[\(%]TG?=([0-9A-F]+)/) {
$ttl = $1;
if (!$ttl) { $ttl = "NULL"; }
}
if ($line =~ /[\(%]TOSI=([^%]+)/) {
$tosi = $1;
if (!$tosi) { $tosi = "NULL"; }
}
if ($line =~ /[\(%]CD=([^%]+)/) {
$cd = $1;
}
if ($line =~ /[\(%]SI=([^%]+)/) {
$si = $1;
}
if ($line =~ /[\(%]DLI=([A-Z|]+)/) {
$dli = $1;
}
if ($resp eq "Y" or !$resp) {
$fp{ie}{resp} = "Y";
if ($dfi and index($fp{ie}{dfi}, $dfi) == -1) {
if ($fp{ie}{dfi}) {
$fp{ie}{dfi} = $fp{ie}{dfi} . qq^|$dfi^;
} else {
$fp{ie}{dfi} = $dfi;
}
}
if (!($fp{ie}{ttl} =~ /(^|\|)$ttl($|\|)/)) {
if ($fp{ie}{ttl}) {
$fp{ie}{ttl} = $fp{ie}{ttl} . qq^|$ttl^;
} else {
$fp{ie}{ttl} = $ttl;
}
}
if ($tosi and index($fp{ie}{tosi}, $tosi) == -1) {
if ($fp{ie}{tosi}) {
$fp{ie}{tosi} = $fp{ie}{tosi} . qq^|$tosi^;
} else {
$fp{ie}{tosi} = $tosi;
}
}
if ($cd and index($fp{ie}{cd}, $cd) == -1) {
if ($fp{ie}{cd}) {
$fp{ie}{cd} = $fp{ie}{cd} . qq^|$cd^;
} else {
$fp{ie}{cd} = $cd;
}
}
if ($si and index($fp{ie}{si}, $si) == -1) {
if ($fp{ie}{si}) {
$fp{ie}{si} = $fp{ie}{si} . qq^|$si^;
} else {
$fp{ie}{si} = $si;
}
}
if ($dli and index($fp{ie}{dli}, $dli) == -1) {
if ($fp{ie}{dli}) {
$fp{ie}{dli} = $fp{ie}{dli} . qq^|$dli^;
} else {
$fp{ie}{dli} = $dli;
}
}
} elsif ($fp{ie}{resp} ne "Y") {
$fp{ie}{resp} = "N";
}
}
}
# OK, now it is time to print out the merged Fprint ...
# Printing contributed by line was like a magnet for spammers and took
# up a substantial amount of space in the file.
# if ($fp{contrib}) { print "# Contributed by $fp{contrib}\n"; }
print "ADJUSTED FINGERPRINT:\n";
print "Fingerprint $fp{os}\n";
if ($fp{class}) { print $fp{class}; }
else { print "Class \n"; }
# SEQ
if ($fp{seq}{sp}) {
print("SEQ(SP=$fp{seq}{sp}");
if ($fp{seq}{gcd}) {
print "%GCD=$fp{seq}{gcd}";
}
if ($fp{seq}{isr}) { print "%ISR=$fp{seq}{isr}"; }
if ($fp{seq}{ti}) { print "%TI=$fp{seq}{ti}"; }
if ($fp{seq}{ii}) { print "%II=$fp{seq}{ii}"; }
if ($fp{seq}{ss}) { print "%SS=$fp{seq}{ss}"; }
if ($fp{seq}{ts}) { print "%TS=$fp{seq}{ts}"; }
print ")\n";
}
# OPS
if ($fp{ops}{o1}) {
$fp{ops}{o1} =~ s/NULL//;
print "OPS(O1=$fp{ops}{o1}";
foreach $num (2 .. 6) {
$oi = "o$num";
$fp{ops}{$oi} =~ s/NULL//;
print "%O$num=$fp{ops}{$oi}";
}
print ")\n";
}
# WIN
if ($fp{win}{w1}) {
$fp{win}{w1} =~ s/NULL/0/;
print "WIN(W1=$fp{win}{w1}";
foreach $num (2 .. 6) {
$wi = "w$num";
$fp{win}{$wi} =~ s/NULL/0/;
print "%W$num=$fp{win}{$wi}";
}
print ")\n";
}
# ECN
if ($fp{ecn}{resp} eq "Y") {
print "ECN(R=Y%";
$fp{ecn}{ttl} =~ s/NULL/0/;
$fp{ecn}{win} =~ s/NULL/0/;
$fp{ops}{win} =~ s/NULL//;
$fp{ecn}{quirk} =~ s/NULL//;
print "DF=$fp{ecn}{df}%T=$fp{ecn}{ttl}%TG=$fp{ecn}{ttl}%W=$fp{ecn}{win}%O=$fp{ecn}{ops}%CC=$fp{ecn}{cc}%Q=$fp{ecn}{quirk})\n";
} else {
print "ECN(R=N)\n";
}
# T1-T7
foreach $t (1 .. 7) {
$test = "T$t";
if ($fp{$test}{resp} eq "Y") {
print "$test(R=Y%";
$fp{$test}{ttl} =~ s/NULL/0/;
$fp{$test}{win} =~ s/NULL/0/;
$fp{$test}{flags} =~ s/NULL//;
$fp{$test}{ops} =~ s/NULL//;
$fp{$test}{rd} =~ s/NULL/0/;
$fp{$test}{quirk} =~ s/NULL//;
if ($t == 1) {
print "DF=$fp{$test}{df}%T=$fp{$test}{ttl}%TG=$fp{$test}{ttl}%S=$fp{$test}{seq}%A=$fp{$test}{ack}%F=$fp{$test}{flags}%RD=$fp{$test}{rd}%Q=$fp{$test}{quirk})\n";
} else {
print "DF=$fp{$test}{df}%T=$fp{$test}{ttl}%TG=$fp{$test}{ttl}%W=$fp{$test}{win}%S=$fp{$test}{seq}%A=$fp{$test}{ack}%F=$fp{$test}{flags}%O=$fp{$test}{ops}%RD=$fp{$test}{rd}%Q=$fp{$test}{quirk})\n";
}
} else {
print "$test(R=N)\n";
}
}
# U1
if ($fp{u1}{resp} eq "Y") {
print "U1(";
$fp{u1}{ttl} =~ s/NULL/0/;
$fp{u1}{tos} =~ s/NULL/0/;
$fp{u1}{uck} =~ s/NULL/0/;
$fp{u1}{un} =~ s/NULL/0/;
$fp{u1}{ripck} =~ s/NULL/0/;
$fp{u1}{ruck} =~ s/NULL/0/;
if ($fp{u1}{rid}) {
$rid = "RID=$fp{u1}{rid}\%";
} else { $ridwarning = 1; $rid = "RID=G\%"; }
print "DF=$fp{u1}{df}%T=$fp{u1}{ttl}%TG=$fp{u1}{ttl}%TOS=$fp{u1}{tos}%IPL=$fp{u1}{ipl}%UN=$fp{u1}{un}%RIPL=$fp{u1}{ripl}%${rid}RIPCK=$fp{u1}{ripck}%RUCK=$fp{u1}{ruck}%RUL=$fp{u1}{rul}%RUD=$fp{u1}{rud})\n";
} else {
print "U1(R=N)\n";
}
# IE
if ($fp{ie}{resp} eq "Y") {
print "IE(";
$fp{ie}{ttl} =~ s/NULL/0/;
$fp{ie}{tosi} =~ s/NULL/0/;
print "DFI=$fp{ie}{dfi}%T=$fp{ie}{ttl}%TG=$fp{ie}{ttl}%TOSI=$fp{ie}{tosi}%CD=$fp{ie}{cd}%SI=$fp{ie}{si}%DLI=$fp{ie}{dli})\n";
} else {
print "IE(R=N)\n";
}
if ($ridwarning == 1) {
$ridwarning = 0;
print "*******************************************************\n" .
"* WARNING: Missing U1 RID value -- this is normal for *\n" .
"* hosts submitted by Solaris or Windows boxes. You *\n" .
"* may want to get RID from similar fingerprints *\n" .
"*******************************************************\n";
}

View File

@@ -1,334 +0,0 @@
/***************************************************************************
* fingerlib.cc/.h -- Some misc. functions related to fingerprint parsing *
* and the like to be used by integration-related programs such as *
* fingerfix, fingermatch, and fingerdiff *
* *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2006 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-fingerprints or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is just meant to *
* clarify our interpretation of derived works with some common examples. *
* These restrictions only apply when you actually redistribute Nmap. For *
* example, nothing stops you from writing and selling a proprietary *
* front-end to Nmap. Just distribute it by itself, and point people to *
* http://insecure.org/nmap/ to download Nmap. *
* *
* We don't consider these to be added restrictions on top of the GPL, but *
* just a clarification of how we interpret "derived works" as it applies *
* to our GPL-licensed Nmap product. This is similar to the way Linus *
* Torvalds has announced his interpretation of how "derived works" *
* applies to Linux kernel modules. Our interpretation refers only to *
* Nmap - we don't speak for any other GPL products. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included Copying.OpenSSL file, and distribute linked *
* combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to fyodor@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering Fyodor and Insecure.Com LLC the unlimited, non-exclusive right *
* to reuse, modify, and relicense the code. Nmap will always be *
* available Open Source, but this is important because the inability to *
* relicense code has caused devastating problems for other Free Software *
* projects (such as KDE and NASM). We also occasionally relicense the *
* code to third parties as discussed above. If you wish to specify *
* special license conditions of your contributions, just say so when you *
* send them. *
* *
* 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 at *
* http://www.gnu.org/copyleft/gpl.html , or in the COPYING file included *
* with Nmap. *
* *
***************************************************************************/
#include "nbase.h"
#include "nmap.h"
#include "fingerlib.h"
#include "MACLookup.h"
static int checkFP(char *FP) {
char *p;
char macbuf[16];
u8 macprefix[3];
char tmp;
bool founderr = false;
int i;
// SCAN
p = strstr(FP, "SCAN(");
if(!p) {
founderr = true;
printf("[WARN] SCAN line is missing");
} else {
// SCAN.G: whether the fingerprint is good
p = strstr(FP, "%G=");
if(!p) p = strstr(FP, "(G=");
if(!p) {
printf("[WARN] Attribute G is missing in SCAN line\n");
founderr = true;
} else {
tmp = *(p+3);
if(tmp != 'Y') {
printf("[WARN] One fingerprint is NOT GOOD (G=N)\n");
founderr = true;
}
}
// SCAN.M: mac prefix of the target.
// if there is a MAC prefix, print the vendor name
p = strstr(FP, "%M=");
if(!p) p = strstr(FP, "(M=");
if(p) {
p = p + 3;
for(i = 0; i < 6; i++) {
if(!p[i] || !isxdigit(p[i])) {
printf("[WARN] Invalid value (%s) occurs in SCAN.M\n", p);
founderr = true;
break;
}
}
if(!founderr) {
strncpy(macbuf, p, 6);
i = strtol(macbuf, NULL, 16);
macprefix[0] = i >> 16;
macprefix[1] = (i >> 8) & 0xFF;
macprefix[2] = i & 0xFF;
printf("[INFO] Vendor Info: %s\n", MACPrefix2Corp(macprefix));
}
}
}
/* Now we validate that all elements are present */
p = FP;
if (!strstr(p, "SEQ(") || !strstr(p, "OPS(") || !strstr(p, "WIN(") ||
!strstr(p, "ECN(") || !strstr(p, "T1(") || !strstr(p, "T2(") ||
!strstr(p, "T3(") || !strstr(p, "T4(") || !strstr(p, "T5(") ||
!strstr(p, "T6(") || !strstr(p, "T7(") || !strstr(p, "U1(") ||
!strstr(p, "IE(")) {
/* This ought to get my attention :) */
founderr = true;
printf("[WARN] Fingerprint is missing at least 1 element\n");
}
if(founderr) return -1;
return 0;
}
/* Reads a fingerprint in from the filep file descriptor. The FP may
be in wrapped or unwrapped format. Wrapped prints are unrapped
before being returned in FP. Returns -1 or exits if it fails. */
int readFP(FILE *filep, char *FP, int FPsz ) {
char line[512];
int linelen = 0;
int lineno = 0;
char *p, *q;
char *oneFP;
char *dst = FP;
char tmp[16];
int i;
bool isInWrappedFP = false; // whether we are currently reading in a
// wrapped fingerprint
if(FPsz < 50) return -1;
FP[0] = '\0';
while((fgets(line, sizeof(line), filep))) {
lineno++;
linelen = strlen(line);
p = line;
if (*p == '\n' || *p == '.') {
// end of input
*dst = '\0';
if(isInWrappedFP) {
// We have just completed reading in a wrapped fp. Because a
// wrapped fp is submitted by user, so we check if there is a
// SCAN line in it. If yes, look inside the scan line.
checkFP(oneFP);
isInWrappedFP = false;
}
break;
}
while(*p && isspace(*p)) p++;
if (*p == '#')
continue; // skip the comment line
if (dst - FP + linelen >= FPsz - 5)
fatal("[ERRO] Overflow!\n");
if(strncmp(p, "OS:", 3) == 0) {
// the line is start with "OS:"
if(!isInWrappedFP) {
// just enter a wrapped fp area
oneFP = dst;
isInWrappedFP = true;
}
p += 3;
while(*p != '\r' && *p != '\n') {
*dst++ = toupper(*p);
if(*p == ')') *dst++ = '\n';
p++;
}
continue;
}
// this line is not start with "OS:"
if(isInWrappedFP) {
// We have just completed reading in a wrapped fp. Because a
// wrapped fp is submitted by user, so we check if there is a
// SCAN line in it. If yes, look inside the scan line.
*dst = '\0';
checkFP(oneFP);
isInWrappedFP = false;
}
q = p; i = 0;
while(q && *q && i<12)
tmp[i++] = toupper(*q++);
tmp[i] = '\0';
if(strncmp(tmp, "FINGERPRINT", 11) == 0) {
q = p + 11;
while(*q && isspace(*q)) q++;
if (*q) { // this fingeprint line is not empty
strncpy(dst, "Fingerprint", 11);
dst += 11;
p += 11;
while(*p) *dst++ = *p++;
}
continue;
} else if(strncmp(tmp, "CLASS", 5) == 0) {
q = p + 5;
while(*q && isspace(*q)) q++;
if (*q) {// this class line is not empty
strncpy(dst, "Class", 5);
dst += 5;
p += 5;
while(*p) *dst++ = *p++;
}
continue;
} else if(strchr(p, '(')) {
while(*p) *dst++ = toupper(*p++);
} else {
printf("[WARN] Skip bogus line: %s\n", p);
continue;
}
}
// Now we validate that all elements are present. Though this maybe
// redundant because we have checked it for those wrapped FPs, it
// doesn't hurt to give a duplicated warning here.
p = FP;
if (!strstr(p, "SEQ(") || !strstr(p, "OPS(") || !strstr(p, "WIN(") ||
!strstr(p, "ECN(") || !strstr(p, "T1(") || !strstr(p, "T2(") ||
!strstr(p, "T3(") || !strstr(p, "T4(") || !strstr(p, "T5(") ||
!strstr(p, "T6(") || !strstr(p, "T7(") || !strstr(p, "U1(") ||
!strstr(p, "IE(")) {
/* This ought to get my attention :) */
printf("[WARN] Fingerprint is missing at least 1 element\n");
}
if (dst - FP < 1)
return -1;
return 0;
}
static int count_attributes(struct AVal *res) {
int count = 0;
while(res) {
count++;
res = res->next;
}
return count;
}
/* When Nmap prints a fingerprint for submission, it sometimes
includes duplicates of tests because 1 or more elements of that
test differ. While this is important for things like fingerfix
(submission), other scripts can't handle it. So this function
removes the duplicates. Maybe it should have more smarts, but
currently it just keeps the first instance of each test. Returns
the number of duplicate tests (0 if there were none). The function
quits and prints the problem if there is an error. */
int remove_duplicate_tests(FingerPrint *FP) {
FingerPrint *outer = FP, *inner, *tmp;
int dupsfound = 0;
if (!FP) { fatal("NULL FP passed to %s", __FUNCTION__); }
for(outer = FP; outer; outer = outer->next) {
/* We check if this test has any duplicates forward in the list,
and if so, remove them */
for(inner = outer; inner->next; inner = inner->next) {
if (strcmp(outer->name, inner->next->name) == 0) {
/* DUPLICATE FOUND! REMOVE THE ONE W/THE FEWEST ATTRIBUTES */
int outeratts = count_attributes(outer->results);
int inneratts = count_attributes(inner->next->results);
if (inneratts > outeratts) {
/* We do a swap of members because we can't change the address of 'FP' */
outer->results = inner->next->results; /* MEMORY LEAK BUT THATS OK */
}
dupsfound++;
inner->next = inner->next->next; /* MEMORY LEAK, BUT THATS OK */
}
if (!inner->next) break;
}
}
return dupsfound;
}

View File

@@ -1,119 +0,0 @@
/***************************************************************************
* fingerlib.cc/.h -- Some misc. functions related to fingerprint parsing *
* and the like to be used by integration-related programs such as *
* fingerfix, fingermatch, and fingerdiff *
* *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2006 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-fingerprints or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is just meant to *
* clarify our interpretation of derived works with some common examples. *
* These restrictions only apply when you actually redistribute Nmap. For *
* example, nothing stops you from writing and selling a proprietary *
* front-end to Nmap. Just distribute it by itself, and point people to *
* http://insecure.org/nmap/ to download Nmap. *
* *
* We don't consider these to be added restrictions on top of the GPL, but *
* just a clarification of how we interpret "derived works" as it applies *
* to our GPL-licensed Nmap product. This is similar to the way Linus *
* Torvalds has announced his interpretation of how "derived works" *
* applies to Linux kernel modules. Our interpretation refers only to *
* Nmap - we don't speak for any other GPL products. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included Copying.OpenSSL file, and distribute linked *
* combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to fyodor@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering Fyodor and Insecure.Com LLC the unlimited, non-exclusive right *
* to reuse, modify, and relicense the code. Nmap will always be *
* available Open Source, but this is important because the inability to *
* relicense code has caused devastating problems for other Free Software *
* projects (such as KDE and NASM). We also occasionally relicense the *
* code to third parties as discussed above. If you wish to specify *
* special license conditions of your contributions, just say so when you *
* send them. *
* *
* 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 at *
* http://www.gnu.org/copyleft/gpl.html , or in the COPYING file included *
* with Nmap. *
* *
***************************************************************************/
#ifndef FINGERLIB_H
#define FINGERLIB_H
/* Reads a fingerprint in from the filep file descriptor. The FP may
be in wrapped or unwrapped format. Wrapped prints are unrapped
before being returned in FP. Returns -1 or exits if it fails. */
int readFP(FILE *filep, char *FP, int FPsz );
/* When Nmap prints a fingerprint for submission, it sometimes
includes duplicates of tests because 1 or more elements of that
test differ. While this is important for things like fingerfix
(submission), other scripts can't handle it. So this function
removes the duplicates. Maybe it should have more smarts, but
currently it just keeps the first instance of each test. Returns
the number of duplicate tests (0 if there were none). The function
quits and prints the problem if there is an error. */
int remove_duplicate_tests(FingerPrint *FP);
#endif /* FINGERLIB_H */

View File

@@ -1,187 +0,0 @@
/***************************************************************************
* fingermatch.cc -- A relatively simple utility for determining whether a *
* given Nmap fingerprint matches (or comes close to matching) any of the *
* fingerprints in a collection such as the nmap-os-fingerprints file that *
* ships with Nmap. *
* *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2006 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-fingerprints or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is just meant to *
* clarify our interpretation of derived works with some common examples. *
* These restrictions only apply when you actually redistribute Nmap. For *
* example, nothing stops you from writing and selling a proprietary *
* front-end to Nmap. Just distribute it by itself, and point people to *
* http://insecure.org/nmap/ to download Nmap. *
* *
* We don't consider these to be added restrictions on top of the GPL, but *
* just a clarification of how we interpret "derived works" as it applies *
* to our GPL-licensed Nmap product. This is similar to the way Linus *
* Torvalds has announced his interpretation of how "derived works" *
* applies to Linux kernel modules. Our interpretation refers only to *
* Nmap - we don't speak for any other GPL products. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included Copying.OpenSSL file, and distribute linked *
* combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to fyodor@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering Fyodor and Insecure.Com LLC the unlimited, non-exclusive right *
* to reuse, modify, and relicense the code. Nmap will always be *
* available Open Source, but this is important because the inability to *
* relicense code has caused devastating problems for other Free Software *
* projects (such as KDE and NASM). We also occasionally relicense the *
* code to third parties as discussed above. If you wish to specify *
* special license conditions of your contributions, just say so when you *
* send them. *
* *
* 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 at *
* http://www.gnu.org/copyleft/gpl.html , or in the COPYING file included *
* with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#include "nbase.h"
#include "nmap.h"
#include "osscan.h"
#include "fingerlib.h"
#define FINGERMATCH_GUESS_THRESHOLD 0.80 /* How low we will still show guesses for */
void usage() {
printf("Usage: fingermatch <fingerprintfilename>\n"
"(You will be prompted for the fingerprint data)\n"
"\n");
exit(1);
}
int main(int argc, char *argv[]) {
char *fingerfile = NULL;
FingerPrintDB *reference_FPs = NULL;
FingerPrint *testFP;
struct FingerPrintResults FPR;
char fprint[8192];
int i, rc;
char gen[128]; /* temporary buffer for os generation part of classification */
if (argc != 2)
usage();
/* First we read in the fingerprint file provided on the command line */
fingerfile = argv[1];
reference_FPs = parse_fingerprint_file(fingerfile);
if (reference_FPs == NULL)
fatal("Could not open or parse Fingerprint file given on the command line: %s", fingerfile);
/* Now we read in the user-provided fingerprint */
printf("Enter the fingerprint you would like to match, followed by a blank single-dot line:\n");
if (readFP(stdin, fprint, sizeof(fprint)) == -1)
fatal("[ERROR] Failed to read in supposed fingerprint from stdin\n");
testFP = parse_single_fingerprint(fprint);
if (!testFP) fatal("Sorry -- failed to parse the so-called fingerprint you entered");
if ((rc = remove_duplicate_tests(testFP))) {
printf("[WARN] Adjusted fingerprint due to %d duplicated tests (we only look at the one with the most attributes).\n", rc);
}
/* Now we find the matches! */
match_fingerprint(testFP, &FPR, reference_FPs, FINGERMATCH_GUESS_THRESHOLD);
switch(FPR.overall_results) {
case OSSCAN_NOMATCHES:
printf("**NO MATCHES** found for the entered fingerprint in %s\n", fingerfile);
break;
case OSSCAN_TOOMANYMATCHES:
printf("Found **TOO MANY EXACT MATCHES** to print for entered fingerprint in %s\n", fingerfile);
break;
case OSSCAN_SUCCESS:
if (FPR.num_perfect_matches > 0) {
printf("Found **%d PERFECT MATCHES** for entered fingerprint in %s:\n", FPR.num_perfect_matches, fingerfile);
printf("Accu Line# OS (classification)\n");
for(i=0; i < FPR.num_matches && FPR.accuracy[i] == 1; i++) {
if (FPR.prints[i]->OS_class[0].OS_Generation)
snprintf(gen, sizeof(gen), " %s ", FPR.prints[i]->OS_class[0].OS_Generation);
else gen[0] = '\0';
printf("100%% %5d %s (%s | %s |%s| %s)\n", FPR.prints[i]->line, FPR.prints[i]->OS_name, FPR.prints[i]->OS_class[0].OS_Vendor, FPR.prints[i]->OS_class[0].OS_Family, gen, FPR.prints[i]->OS_class[0].Device_Type );
}
} else {
printf("No perfect matches found, **GUESSES AVAILABLE** for entered fingerprint in %s:\n", fingerfile);
printf("Accu Line# OS (classification)\n");
for(i=0; i < 10 && i < FPR.num_matches; i++) {
if (FPR.prints[i]->OS_class[0].OS_Generation)
snprintf(gen, sizeof(gen), " %s ", FPR.prints[i]->OS_class[0].OS_Generation);
else gen[0] = '\0';
printf("%3d%% %5d %s (%s | %s |%s| %s)\n", (int) (FPR.accuracy[i] * 100), FPR.prints[i]->line, FPR.prints[i]->OS_name, FPR.prints[i]->OS_class[0].OS_Vendor, FPR.prints[i]->OS_class[0].OS_Family, gen, FPR.prints[i]->OS_class[0].Device_Type );
}
}
printf("\n");
break;
default:
fatal("Bogus error.");
break;
}
return 0;
}

View File

@@ -1,78 +0,0 @@
#!/usr/bin/perl -w
use POSIX;
# A simple perl script that takes a MAC address database as distribted
# by the IEEE at http://standards.ieee.org/regauth/oui/oui.txt and
# creates an nmap-mac-prefixes file, which is just a bunch of lines
# like this (but without the initial "# ":
#
# 000072 Miniware Technology
# 00012E PC Partner Ltd.
# 080023 Panasonic Communications Co., Ltd.
#
sub usage() {
print "usage: make-mac-prefixis.pl [infile] [outfile]\n" .
"where infile is usually oui.txt as distributed from\n" .
"http://standards.ieee.org/regauth/oui/oui.txt and outfile is usually\n" .
"nmap-mac-prefixes. The output file will be overwritten if it already exists.\n";
exit 1;
}
# Un-capitalize an all-caps company name;
sub decap($) {
my $oldcomp = shift();
my $newcomp = "";
my @words = split /\s/, $oldcomp;
foreach $word (@words) {
if (length($word) > 3 && (length($word) > 5 or !($word =~ /[.,\!\$]/))) {
$word = "\L$word\E";
$word = "\u$word";
}
if ($newcomp) { $newcomp .= " $word"; }
else {$newcomp = $word; }
}
return $newcomp;
}
# Rules to shorten the names a bit, such as eliminating Inc.
sub shorten($) {
my $comp = shift();
$comp =~ s/,.{1,6}$//;
$comp =~ s/ (Corporation|Inc|Ltd|Corp|S\.A\.|Co\.|llc|pty|l\.l\.c\.|s\.p\.a\.|b\.v\.)(\.|\b)//gi;
# Fix stupid entries like "DU PONT PIXEL SYSTEMS ."
$comp =~ s/\s+.$//;
return $comp;
}
my $infile = shift() || usage();
my $outfile = shift() || usage();
if (! -f $infile) { print "ERROR: Could not find input file $infile"; usage(); }
open INFILE, "<$infile" or die "Could not open input file $infile";
open OUTFILE, ">$outfile" or die "Could not open output file $outfile";
print OUTFILE "# \$Id" . ": \$ generated with make-mac-prefixes.pl\n";
print OUTFILE "# Original data comes from http://standards.ieee.org/regauth/oui/oui.txt\n";
print OUTFILE "# These values are known as Organizationally Unique Identifiers (OUIs)\n";
print OUTFILE "# See http://standards.ieee.org/faqs/OUI.html\n";
print OUTFILE "# We have added a few unregistered OUIs at the end.\n";
while($ln = <INFILE>) {
if ($ln =~ /\s*([0-9a-fA-F]{2})-([0-9a-fA-F]{2})-([0-9a-fA-F]{2})\s+\(hex\)\s+(\S.*)$/) {
my $prefix = "$1$2$3";
my $compname= $4;
# This file often over-capitalizes company names
if (!($compname =~ /[a-z]/) || $compname =~ /\b[A-Z]{4,}/) {
$compname = decap($compname);
}
$compname = shorten($compname);
print OUTFILE "$prefix $compname\n";
}
# else { print "failed to match: $ln"; }
}
# Now add a few extras which aren't oficially registered ...
print OUTFILE "525400 QEMU Virtual NIC\nB0C420 Bochs Virtual NIC\nDEADCA PearPC Virtual NIC\n";

View File

@@ -1,93 +0,0 @@
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2006 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-fingerprints or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is just meant to *
* clarify our interpretation of derived works with some common examples. *
* These restrictions only apply when you actually redistribute Nmap. For *
* example, nothing stops you from writing and selling a proprietary *
* front-end to Nmap. Just distribute it by itself, and point people to *
* http://insecure.org/nmap/ to download Nmap. *
* *
* We don't consider these to be added restrictions on top of the GPL, but *
* just a clarification of how we interpret "derived works" as it applies *
* to our GPL-licensed Nmap product. This is similar to the way Linus *
* Torvalds has announced his interpretation of how "derived works" *
* applies to Linux kernel modules. Our interpretation refers only to *
* Nmap - we don't speak for any other GPL products. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included Copying.OpenSSL file, and distribute linked *
* combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to fyodor@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering Fyodor and Insecure.Com LLC the unlimited, non-exclusive right *
* to reuse, modify, and relicense the code. Nmap will always be *
* available Open Source, but this is important because the inability to *
* relicense code has caused devastating problems for other Free Software *
* projects (such as KDE and NASM). We also occasionally relicense the *
* code to third parties as discussed above. If you wish to specify *
* special license conditions of your contributions, just say so when you *
* send them. *
* *
* 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 at *
* http://www.gnu.org/copyleft/gpl.html , or in the COPYING file included *
* with Nmap. *
* *
***************************************************************************/

View File

@@ -1,50 +0,0 @@
***********************IMPORTANT NSOCK LICENSE TERMS***********************
* *
* The nsock parallel socket event library is (C) 1999-2006 Insecure.Com *
* LLC This library is free software; you may redistribute and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation; Version 2. This guarantees *
* your right to use, modify, and redistribute this software under certain *
* conditions. If this license is unacceptable to you, Insecure.Com LLC *
* may be willing to sell alternative licenses (contact *
* sales@insecure.com ). *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included Copying.OpenSSL file, and distribute linked *
* combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement stating *
* terms other than the (GPL) terms above, then that alternative license *
* agreement takes precedence over this comment. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to fyodor@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one the *
* insecure.org development mailing lists, it is assumed that you are *
* offering Fyodor and Insecure.Com LLC the unlimited, non-exclusive right *
* to reuse, modify, and relicense the code. Nmap will always be *
* available Open Source, but this is important because the inability to *
* relicense code has caused devastating problems for other Free Software *
* projects (such as KDE and NASM). We also occasionally relicense the *
* code to third parties as discussed above. If you wish to specify *
* special license conditions of your contributions, just say so when you *
* send them. *
* *
* 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 ( *
* http://www.gnu.org/copyleft/gpl.html ). *
* *
***************************************************************************/

View File

@@ -1,29 +0,0 @@
#!/usr/bin/perl -w
# For now, this script just un-wordwraps all the OS fingerprints found
# in a file (or set of files, or stdin) and prints them out. It also
# adds an IP element if it obtains that info from the Nmap log file.
my $lineno = 0;
my $nextline;
my $fp = "";
# First remove the OS: prefix and extra newlines
while(<>) {
$nextline = $_;
$lineno++;
if ($nextline =~ /^\s*OS:/) {
chomp($nextline);
$nextline =~ s/^\s*OS://;
$nextline =~ s/\s+$//;
$fp .= $nextline;
} else {
if ($fp) {
# I've just finished reading in an FP, apparently. Process and
# print it out. First add appropriate line breaks
$fp =~ s/\)/\)\n/g;
print "New Fingerprint:\n$fp\n";
$fp = "";
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,203 +0,0 @@
#!/usr/bin/perl -w
sub usage() {
print STDERR "Usage: $0 <nmap os fingerprint submission file>\n" .
"Slurps up the given nmap-os-fingerprints file, sorts it appropriately (Class, then name string), then spits it out to stdout. Some minor canonicalization is done too.\n\n";
exit(0);
}
sub osprep($) {
my $ln = shift;
chomp ($ln);
$ln =~ s/^\s+//;
$ln =~ s/\s+$//;
return $ln;
}
sub finalfpprep($) {
my $ln = shift;
$ln =~ s/\)/\)\n/g;
return $ln;
}
sub fprintsort() {
lc($a->{fpClass}) cmp lc($b->{fpClass})
or
lc($a->{fpName}) cmp lc($b->{fpName})
or
$b->{fpGood} <=> $a->{fpGood}
;
}
if ($#ARGV != 0) {
print STDERR "ERROR: Wrong number of command-line arguments (must be exactly 1)\n";
usage();
}
my $osfile = shift();
open(OSFILE, "<$osfile") or die "Failed to open purported os fingerprint submission file: $osfile\n";
my $state = "null";
my $lineno = 0;
my @mails;
my %msg = ();
my $bodylines = -1;
my $fpstate = "null";
my $fpstr = "";
my @fplines;
my %fp;
my $fptestname = "";
my $fptestnum = 0;
while ($line = <OSFILE>) {
$lineno++;
if ($state eq "null") {
if ($line =~ /^\s*$/) {
next;
} else {
$state = "msg_header";
}
}
if ($state eq "msg_header") {
if ($line =~ /^\s*$/) {
# A blank line ends a mail header
if ($bodylines == -1) {
die "ERROR: Parse error on $osfile:$lineno -- expected a Lines field in mail header";
}
$state = "msg_body";
} else {
if ($line =~ /^lines:\s*([0-9]+)/i) {
$bodylines = $1;
}
$msg{header} .= $line;
}
next;
} elsif ($state eq "msg_body") {
if ($bodylines > 0) {
$bodylines--;
$msg{body} .= $line;
if ($line =~ /^\s*Fingerprint (\S.*\S)\s*$/) {
$msg{fpName} = $1;
}
if ($line =~ /^\s*Class (\S.*\S)$/) {
$msg{fpClass} = $1;
}
if ($line =~ /^\s*OS:/i) {
$line = osprep($line);
$line =~ s/^\s*OS://i;
$fpstr .= $line;
$fpstate = "fp";
} elsif ($fpstate eq "fp") {
$fpstate = "null";
}
}
if ($bodylines == 0) {
if (!$msg{fpName}) {
$msg{fpName} = "NULL";
}
if (!$msg{fpClass}) {
$msg{fpClass} = "NULL";
}
$msg{fpGood} = 0;
if ($fpstr) {
$fpstr = finalfpprep($fpstr);
# print $fpstr . "\n";
@fplines = split /\n/, $fpstr;
$fptestnum = 0;
foreach $fpline (@fplines) {
# print $fpline . "\n";
if ($fpline =~ /^SCAN.*%OT=([0-9]*)%CT=([0-9]*)%CU=([0-9]*)%PV=([YN])(%DS=([0-9]+))?%G=([YN])(%M=([0-9A-F]+))?.*/i) {
$fptestnum++;
# $fp_ot = $1;
# $fp_ct = $2;
$fp_cu = $3;
$fp_pv = $4;
# if($5) {
# $fp_ds = $6;
# } else {
# $fp_ds = -1;
# }
$fp_good = $7;
if($8) {
$fp_mac = $9;
} else {
$fp_mac = "";
}
if ($fp_cu) {
$msg{fpGood} += 1;
}
if ($fp_pv eq "Y") {
$msg{fpGood} += 1;
}
if ($fp_good eq "Y") {
$msg{fpGood} += 2;
}
if ($fp_mac) {
$msg{fpGood} += 1;
}
} elsif ($fpline =~ /^((SEQ)|(OPS)|(WIN)|(ECN)|(T[1-7])|(U1)|(IE))/i) {
$fptestname = $1;
if (!$fp{$fptestname}) {
$fptestnum++;
}
$fp{$fptestname} .= $line;
}
}
if ($fptestnum == 14) {
# This submission has all the fp fields
$msg{fpGood} += 5;
}
}
# print $msg{fpGood} . "\n";
my %copy = %msg;
push @mails, \%copy;
$state = "null";
%msg = ();
$bodylines = -1;
$fpstate = "null";
$fpstr = "";
%fp = ();
}
next;
}
}
my @sortedmails = sort fprintsort @mails;
my $firstline = 1;
my $currentFpClass = "";
foreach $mail (@sortedmails) {
if ($firstline) {
$firstline = 0;
} else { print "\n"; }
if ($currentFpClass ne $mail->{fpClass}) {
print 'From anonymous@core.lnxnet.net Mon Jul 04 00:00:01 2006', "\n",
'To: fyodor@insecure.org', "\n",
'From: nmap-submission-cgi@core.lnxnet.net', "\n",
"Subject: ====== $mail->{fpClass} ======\n",
"Status: O\n",
"Lines: 1\n\n";
print "## Separator ##\n\n";
$currentFpClass = $mail->{fpClass};
}
print "$mail->{header}\n";
print "$mail->{body}";
}

View File

@@ -1,48 +0,0 @@
#!/usr/bin/perl -w
if (!$ARGV[0]) {
print "Usage: produceosclasschoosebox.pl <nmap-os-fingerprints-filepath>\n\n"; exit;
}
# Kill leading and trailing whitespace
sub killws($) {
$str = shift;
$str =~ s/^\s+//g;
$str =~ s/\s+$//g;
return $str;
}
my @optionar;
my %unique_optvals;
while(<>) {
my %infohash;
if (/^Class /) {
s/Class //;
# Kill leading and trailing whitespace
my ($vendor, $osfam, $osgen, $type) = split /\|/;
$vendor = killws($vendor);
$osfam = killws($osfam);
$osgen = killws($osgen);
$type = killws($type);
$infohash{opval} = "$vendor|$osfam|$osgen|$type";
if (!$unique_optvals{$infohash{opval}}) {
$unique_optvals{$infohash{opval}} = 1;
$infohash{vendor} = $vendor;
$infohash{osfam} = $osfam;
$infohash{osgen} = $osgen;
$infohash{type} = $type;
if ($osgen) { $osgen = " $osgen"; }
if ($vendor eq $osfam) { $vendor = ""; } else {$vendor = "$vendor "; }
$infohash{fullname} = "$vendor$osfam$osgen $type";
push @optionar, \%infohash;
}
}
}
@optionar = sort { lc($a->{fullname}) cmp lc($b->{fullname}) } @optionar;
foreach $opt (@optionar) {
print qq|<option value="| . $opt->{opval} . qq|">| . $opt->{fullname} . "\n";
}

View File

@@ -1,333 +0,0 @@
/***************************************************************************
* servicematch.cc -- A relatively simple utility for determining whether *
* a given Nmap service fingerprint matches (or comes close to any of the *
* fingerprints in a collection such as the nmap-service-probes file that *
* ships with Nmap. *
* *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2006 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-fingerprints or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is just meant to *
* clarify our interpretation of derived works with some common examples. *
* These restrictions only apply when you actually redistribute Nmap. For *
* example, nothing stops you from writing and selling a proprietary *
* front-end to Nmap. Just distribute it by itself, and point people to *
* http://insecure.org/nmap/ to download Nmap. *
* *
* We don't consider these to be added restrictions on top of the GPL, but *
* just a clarification of how we interpret "derived works" as it applies *
* to our GPL-licensed Nmap product. This is similar to the way Linus *
* Torvalds has announced his interpretation of how "derived works" *
* applies to Linux kernel modules. Our interpretation refers only to *
* Nmap - we don't speak for any other GPL products. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included Copying.OpenSSL file, and distribute linked *
* combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to fyodor@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering Fyodor and Insecure.Com LLC the unlimited, non-exclusive right *
* to reuse, modify, and relicense the code. Nmap will always be *
* available Open Source, but this is important because the inability to *
* relicense code has caused devastating problems for other Free Software *
* projects (such as KDE and NASM). We also occasionally relicense the *
* code to third parties as discussed above. If you wish to specify *
* special license conditions of your contributions, just say so when you *
* send them. *
* *
* 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 at *
* http://www.gnu.org/copyleft/gpl.html , or in the COPYING file included *
* with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#include "nbase.h"
#include "nmap.h"
#include "service_scan.h"
#include <ctype.h>
void usage() {
printf("Usage: servicematch <fingerprintfilename>\n"
"(You will be prompted for the fingerprint data)\n"
"\n");
exit(1);
}
// This function parses the read-in fprint, compares the responses to the
// given tests as if they had been read from a remote system, and prints out
// the first match if any, followed by the fingerprint in single-line format.
// The 'ipaddystr' is either a string of the form " on www.xx.y.zzz" containing the IP
// address of the target from which fprint was obtained, or it is empty (meaning we don't know).
int doMatch(AllProbes *AP, char *fprint, int fplen, char *ipaddystr) {
u16 portno;
int proto;
char *p;
char *currentprobe = NULL;
char probename[128];
char resptext[3048];
char *endp = NULL;
unsigned long fullrlen;
bool trunc = false; // Was at least one response truncated due to length?
unsigned int resptextlen;
char *dst;
ServiceProbe *SP = NULL;
char softmatch[32] = {0};
const struct MatchDetails *MD = NULL;
bool nullprobecheat = false; // We cheated and found a match in the NULL probe to a non-null-probe response
// First lets find the port number and protocol
assert(fplen > 10);
assert(strncmp(fprint, "SF-Port", 7) == 0);
portno = atoi(fprint + 7);
p = strchr(fprint, ':');
assert(p);
p -= 3;
if (strncmp(p, "TCP", 3) == 0)
proto = IPPROTO_TCP;
else proto = IPPROTO_UDP;
currentprobe = strstr(p, "%r(");
while(currentprobe) {
// move to the probe name
p = currentprobe + 3;
dst = probename;
while(*p && *p != ',') {
assert((unsigned int) (dst - probename) < sizeof(probename) - 1);
*dst++ = *p++;
}
*dst++ = '\0';
// Grab
assert(*p == ',');
p++;
assert(isxdigit(*p));
fullrlen = strtoul(p, &endp, 16);
p = endp;
assert(*p == ',');
p++;
assert(*p == '"');
p++;
dst = resptext;
while(*p && (*p != '"' || (*(p-1) == '\\' && *(p-2) != '\\'))) {
assert((unsigned int) (dst - resptext) < sizeof(resptext) - 1);
*dst++ = *p++;
}
*dst++ = '\0';
// Now we unescape the response into plain binary
cstring_unescape(resptext, &resptextlen);
if (resptextlen < fullrlen)
trunc = true;
// Finally we try to match this with the appropriate probe from the
// nmap-service-probes file.
SP = AP->getProbeByName(probename, proto);
if (!SP) {
error("WARNING: Unable to find probe named %s in given probe file.", probename);
} else {
nullprobecheat = false;
MD = SP->testMatch((u8 *) resptext, resptextlen);
if (!MD && !SP->isNullProbe() && SP->getProbeProtocol() == IPPROTO_TCP && AP->nullProbe) {
MD = AP->nullProbe->testMatch((u8 *) resptext, resptextlen);
nullprobecheat = true;
}
if (MD && MD->serviceName) {
if (MD->isSoft) {
// We'll just squirrel it away for now
if (*softmatch && strcmp(softmatch, MD->serviceName) != 0) {
fprintf(stderr, "WARNING: Soft match for service %s, followed by (ignored) soft match for service %s\n", softmatch, MD->serviceName);
} else Strncpy(softmatch, MD->serviceName, sizeof(softmatch));
} else {
// YEAH! Found a hard match!
if (MD->product || MD->version || MD->info || MD->hostname || MD->ostype || MD->devicetype) {
printf("MATCHED %ssvc %s", nullprobecheat? "(NULLPROBE CHEAT) " : "", MD->serviceName);
if (MD->product) printf(" p|%s|", MD->product);
if (MD->version) printf(" v|%s|", MD->version);
if (MD->info) printf(" i|%s|", MD->info);
if (MD->hostname) printf(" h|%s|", MD->hostname);
if (MD->ostype) printf(" o|%s|", MD->ostype);
if (MD->devicetype) printf(" d|%s|", MD->devicetype);
printf(" %s: %s\n", ipaddystr, fprint);
} else
printf("MATCHED %ssvc %s (NO VERSION)%s: %s\n", nullprobecheat? "(NULLPROBE CHEAT) " : "", MD->serviceName, ipaddystr, fprint);
return 0;
}
}
}
// Lets find the next probe, if any
currentprobe = strstr(p, "%r(");
}
if (trunc) printf("WARNING: At least one probe response was truncated\n");
if (*softmatch) printf("SOFT MATCH svc %s (SOFT MATCH)%s: %s\n", softmatch, ipaddystr, fprint);
else printf("FAILED to match%s: %s\n", ipaddystr, fprint);
return 1;
}
int cleanfp(char *fprint, int *fplen) {
char *src = fprint, *dst = fprint;
while(*src) {
if (strncmp(src, "\\x20", 4) == 0) {
*dst++ = ' ';
src += 4;
/* } else if (*src == '\\' && (*(src+1) == '"' || *(src+1) == '\\')) {
*dst++ = *++src;
src++; */ // We shouldn't do this yet
} else if (src != dst) {
*dst++ = *src++;
} else { dst++; src++; }
}
*dst++ = '\0';
*fplen = dst - fprint - 1;
return 0;
}
int main(int argc, char *argv[]) {
AllProbes *AP = new AllProbes();
char *probefile = NULL;
char fprint[16384];
int fplen = 0; // Amount of chars in the current fprint
char line[512];
unsigned int linelen;
char *dst = NULL;
int lineno;
char *p, *q;
bool isInFP = false; // whether we are currently reading in a fingerprint
struct in_addr ip;
char lastipbuf[64];
if (argc != 2)
usage();
lastipbuf[0] = '\0';
/* First we read in the fingerprint file provided on the command line */
probefile = argv[1];
parse_nmap_service_probe_file(AP, probefile);
/* Now we read in the user-provided service fingerprint(s) */
printf("Enter the service fingerprint(s) you would like to match. Will read until EOF. Other Nmap output text (besides fingerprints) is OK too and will be ignored\n");
while(fgets(line, sizeof(line), stdin)) {
lineno++;
linelen = strlen(line);
p = line;
while(*p && isspace(*p)) p++;
if (isInFP) {
if (strncmp(p, "SF:", 3) == 0) {
p += 3;
assert(sizeof(fprint) > fplen + linelen + 1);
dst = fprint + fplen;
while(*p != '\r' && *p != '\n' && *p != ' ')
*dst++ = *p++;
fplen = dst - fprint;
*dst++ = '\0';
} else {
fatal("Fingerprint incomplete ending on line #%d", lineno);
}
}
if (strncmp(p, "SF-Port", 7) == 0) {
if (isInFP)
fatal("New service fingerprint started before the previous one was complete -- line %d", lineno);
assert(sizeof(fprint) > linelen + 1);
dst = fprint;
while(*p != '\r' && *p != '\n' && *p != ' ')
*dst++ = *p++;
fplen = dst - fprint;
*dst++ = '\0';
isInFP = true;
} else if (strncmp(p, "Interesting port", 16) == 0) {
q = line + linelen - 1;
while(*q && (*q == ')' || *q == ':' || *q == '\n'|| *q == '.' || isdigit((int) (unsigned char) *q))) {
if (*q == ')' || *q == ':' || *q == '\n') *q = '\0';
q--;
}
q++;
assert(isdigit((int)(unsigned char) *q));
if (inet_aton(q, &ip) != 0) {
snprintf(lastipbuf, sizeof(lastipbuf), " on %s", inet_ntoa(ip));
}
}
// Now we test if the fingerprint is complete
if (isInFP && fplen > 5 && strncmp(fprint + fplen - 3, "\");", 3) == 0) {
// Yeah! We have read in the whole fingerprint
isInFP = false;
// Cleans the fingerprint up a little, such as replacing \x20 with space and unescaping characters like \\ and \"
cleanfp(fprint, &fplen);
doMatch(AP, fprint, fplen, lastipbuf);
}
}
return 0;
}

View File

@@ -1,61 +0,0 @@
#!/usr/bin/perl -w
# For now, this script just un-wordwraps all the service fingerprints
# found in a file (or set of files) and prints them out. It also adds
# an IP element if it obtains that info from the Nmap log file.
sub osprep($) {
my $ln = shift;
chomp ($ln);
$ln =~ s/^\s+//;
$ln =~ s/\s+$//;
return $ln;
}
sub finalfpprep($) {
my $ln = shift;
$ln =~ s/\\x20/ /g;
return $ln;
}
my $infp = 0;
my $lineno = 0;
my $currentfp = "";
my $nextline;
my $lastip = "";
while(<>) {
$nextline = $_;
$lineno++;
if ($infp) {
if (!($nextline =~ /^ [^ ]+$/)) {
# Yay, just finished reading in an FP
print finalfpprep($currentfp) . "\n";
$infp = 0;
$currentfp = "";
} else {
$nextline = osprep($nextline);
$currentfp .= $nextline;
if (length($currentfp) > 10000) {
die "Fingerprint too long on line $lineno of input file(s)";
}
}
}
if ($nextline =~ /^Interesting ports on.*\D(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/) {
$lastip = $1;
}
if ($nextline =~ /^\s*SF-Port\d+-...:/) {
$nextline = osprep($nextline);
if ($lastip) {
$nextline =~ s/(SF-Port\d+-...:)/$1TIP=$lastip%/;
}
$currentfp .= $nextline;
$infp = 1;
}
}
if ($infp and $currentfp) {
print finalfpprep($currentfp) . "\n";
}

View File

@@ -1,45 +0,0 @@
#!/usr/bin/perl -w
sub usage() {
print "sign_release.pl <distdir>\n";
print "Cycles through every file in <distdir>, looking for corresponding gpg detached signature (<distdir>/$file.gpg.txt) and message digest (<distdir>/$file.digest.txt) files. If either are both are missing for a given $file, they are recreated by calling gpg appropriately.\n\n";
exit(1);
}
if ($#ARGV != 0) {
print STDERR "ERROR: Wrong number of command-line arguments (must be exactly 1)\n";
usage();
}
my $distdir = shift();
if ($distdir =~ m|/$|) { chop $distdir; }
if (! -d $distdir) {
print STDERR "ERROR: Dist dir ($distdir) doesn't exist\n";
}
if (! -d "$distdir/sigs/" ) {
print STDERR "ERROR: You must create sig directory ($distdir/sigs) before calling this script\n";
}
# Now go through each file generating sigs if neccessary
opendir DISTDIR, $distdir or die "Could not open distdir: $distdir\n";
foreach $file (readdir DISTDIR) {
if ($file eq "favicon.ico") { next; }
if (-f "$distdir/$file") {
my $sigfile = "$distdir/sigs/$file.gpg.txt";
my $digfile = "$distdir/sigs/$file.digest.txt";
if (!-f $sigfile) {
my $command = "gpg --detach-sign -u 6B9355D0 --armor -o $sigfile $distdir/$file; chmod 644 $sigfile";
print "Running: $command\n";
system($command);
}
if (!-f $digfile) {
my $command = "cd $distdir && gpg --print-mds $file > $digfile; chmod 644 $digfile";
print "Running: $command\n";
system($command);
}
}
}

View File

@@ -1,147 +0,0 @@
#!/usr/bin/perl -w
sub usage() {
print STDERR "Usage: sort-prints.pl <nmap-os-fingerprints file>\n" .
"Slurps up the given nmap-os-fingerprints file, sorts it appropriately (headertext, then MatchPoints, then fingerprintes sorted by first class, then name string), then spits it out to stdout. Some minor canonicalization is done too.\n\n";
exit(0);
}
sub fprintsort {
if ($a->{type} eq "MatchPoints") {
if ($b->{type} eq "MatchPoints") {
print STDERR "ERROR: More than one MatchPoints section found in fingerprint DB\n";
usage();
}
return -1;
}
if ($b->{type} eq "MatchPoints") {
return 1;
}
lc($a->{firstClass}) cmp lc($b->{firstClass})
or
lc($a->{name}) cmp lc($b->{name});
}
if ($#ARGV != 0) {
print STDERR "ERROR: Wrong number of command-line arguments (must be exactly 1)\n";
usage();
}
my $osfile = shift();
open(OSFILE, "<$osfile") or die "Failed to open purported nmap-os-fingerprints file: $osfile\n";
my $state = "headertxt";
my $lineno = 0;
my $headertxt = "";
my @prints;
my %newFP = ();
while($nxtline = <OSFILE>) {
$lineno++;
if ($state eq "headertxt") {
if ($nxtline =~ /^\#/) {
$headertxt .= $nxtline;
} else {
$state = "fprint-comments";
}
next;
}
if ($nxtline =~ /^\s*$/) {
# REMEMBER TO COPY ANY TEXT HERE TO THE FINAL PRINT CAPTURE BELOW THIS LOOP
if ($state eq "fprint-tests") {
# A blank line ends a fingerprint
my %copy = %newFP;
push @prints, \%copy;
# print "Read in an FP! There are now " . ($#prints + 1) . "\n";
%newFP = ();
$state = "fprint-comments";
}
next;
}
if ($state eq "fprint-comments") {
if ($nxtline =~ /^\#/) {
if (!($nxtline =~ /^\# /)) {
$nxtline =~ s/^\#/\# /;
}
$newFP{comments} .= $nxtline;
next;
} else {
$state = "fprint-name";
}
}
if ($state eq "fprint-name") {
if ($nxtline =~ /^Fingerprint (\S.*\S)\s*$/i) {
$newFP{name} = $1;
$newFP{type} = "Fingerprint";
$state = "fprint-class";
next;
} elsif ($nxtline =~ /^MatchPoints/) {
$newFP{type} = "MatchPoints";
$state = "fprint-tests";
next;
}
die "ERROR: Parse error on $osfile:$lineno -- expected Fingerprint directive";
}
if ($state eq "fprint-class") {
if ($nxtline =~ /^Class (\S.*\S)$/) {
if (!$newFP{firstClass}) {
$newFP{firstClass} = $1;
}
$newFP{data} .= "$nxtline";
next;
} else {
if (!$newFP{firstClass}) {
die "ERROR: Parse error on $osfile:$lineno -- expected Class directive";
}
$state = "fprint-tests";
}
}
if ($state eq "fprint-tests") {
if ($nxtline =~ /^(SEQ|OPS|WIN|ECN|T[1-7]|U1|IE)\(.*\)(\s*\#.*)?$/) {
$newFP{data} .= "$nxtline";
next;
}
die "ERROR: Parse error on $osfile:$lineno -- expected a SEQ, OPS, WIN, ECN, T1-T7, U1 or IE test line";
}
}
# Capture the final print
if ($state eq "fprint-tests") {
# A blank line ends a fingerprint
my %copy = %newFP;
push @prints, \%copy;
# print "Read final FP! There are now " . ($#prints + 1) . "\n";
} elsif ($state ne "fprint-comments") {
die "ERROR: $osfile appears to have ended in mid-fingerprint";
}
# print "Successfully read in " . ($#prints + 1) . " fingerprints from $osfile\n";
my @sortedprints = sort fprintsort @prints;
# print "The first name is $prints[0]->{name} and the second is $prints[1]->{name}\n";
# print "The sorted first name is $sortedprints[0]->{name} and the second is $sortedprints[1]->{name}\n";
print $headertxt;
print "\n";
my $firstline = "true";
foreach $print (@sortedprints) {
if ($firstline) {
$firstline = 0;
} else { print "\n"; }
if ($print->{comments}) {
print $print->{comments};
}
if ($print->{type} eq "MatchPoints") {
print "MatchPoints\n";
} else {
print "Fingerprint $print->{name}\n";
}
print "$print->{data}";
}

View File

@@ -1,152 +0,0 @@
#!/usr/bin/perl -w
my $usage = <<EOUSAGE;
Usage: templatereplace.pl [ops] <templatefile> <subjectfile1> ...
The idea behind this simple script is to replace blocks of text in one
or more files with a standard block provided in a "template file".
This script first reads in the template file, making special note of
the first and last lines. It then reads in the subject files, one by
one. If it sees the first template file line in one of the files, it
deletes text in the subject file until it finds the last template
line. Then it replaces the deleted text with the verbatim contents of
the template file. Files that don't contain the first template line
are unchanged.
Example usage:
find . -name '*.[ch]' -o -name '*.cc' -o -name COPYING -o -iname '*.in' | xargs scripts/templatereplace.pl -v scripts/nmap.header.tmpl
find . -name '*.[ch]' -o -name '*.cc' -o -name COPYING -o -iname '*.in' | xargs scripts/templatereplace.pl -v scripts/nsock.header.tmpl
EOUSAGE
use Getopt::Std;
use English;
my $verbose = 0;
sub usage() { print $usage; exit(1); }
# This function processes a template file by reading in all the data
# from $tmpldata->{name} and filling in $tmpldata->{firstline},
# $tmpldata->{lastline}, and $tmpldata->{content} (the latter does
# not include firstline and lastline). This function will give an
# error and exit the program if there are problems.
sub process_tmpl($) {
my $tdata = shift();
my $line;
my $lastline;
my $lineno = 1;
if ($verbose) {
print "Reading in template file: " . $tdata->{fname} . "\n";
}
if (!open TMPL, "<" . $tdata->{fname}) {
print "FAILED to read in template file: " . $tdata->{fname} . "\n";
usage();
}
$tdata->{content} = "";
while($line = <TMPL>) {
if ($lineno == 1) {
$tdata->{firstline} = $line;
} else {
if ($lineno != 2) { $tdata->{content} .= $lastline; }
}
$lastline = $line;
$lineno++;
}
if ($lineno < 3) {
print "Template file " . $tdata->{fname} . " is not long enough! Muts be at least 3 lines (first, content, and last)\n";
}
$tdata->{lastline} = $lastline;
close TMPL;
}
sub process_subj($$) {
my ($subjectfile, $tmpl) = @_;
my $newfile = "";
my $state = 0;
my $line;
if (!open SUB, "<$subjectfile") {
print "FAILED to read in subject file ($subjectfile) - skipping\n";
return;
}
# No need to worry about perms since we are overwriting existing file.
# my $perm = (stat $subjectfile)[2];
# $perm = $perm & 0777; # We ONLY want mode (not type too) and no suid bits
while($line = <SUB>) {
if ($state == 0) {
# Haven't found the match begin yet
if ($line eq $tmpl->{firstline}) { $state = 1; }
else { $newfile .= $line; }
} elsif ($state == 1) {
# Am between the match begin and end
if ($line eq $tmpl->{lastline}) {
$state = 2;
$newfile .= $tmpl->{firstline};
$newfile .= $tmpl->{content};
$newfile .= $tmpl->{lastline};
}
# Otherwise do nothing
} else {
# Already did the match, now we just copy the lines verbatim.
$newfile .= $line;
}
}
close SUB;
if ($state == 0) {
if ($verbose) { print "$subjectfile -> no replacement\n"; }
} elsif ($state == 1) {
print "WARNING: $subjectfile had begin line but never ended - skipping\n";
} else {
# Yeah - we did the replacement so now lets write back the file.
if (!open SUBWRITE, ">$subjectfile") {
print "FAILED to write to subject file ($subjectfile) - $! - skipping\n";
return;
}
print SUBWRITE $newfile;
close SUBWRITE;
if ($verbose) {
print "$subjectfile -> replacement succeeded\n";
}
}
}
# MAIN
use vars qw($opt_h $opt_v);
if (!getopts("vh")) {
print STDERR "Invalid arguments\n";
usage();
}
if ($opt_h) {
usage();
}
if ($opt_v) {
$verbose = 1;
}
$tmpldata{fname} = shift();
process_tmpl(\%tmpldata);
if ($verbose) {
printf "Processed template:" . $tmpldata{fname} . "\nSeeking Start: " . $tmpldata{firstline} . " End: " . $tmpldata{lastline} . "\n";
}
# Now it is time to handle each subject file, one at a time.
my $subjectfile;
while($subjectfile = shift()) {
process_subj($subjectfile, \%tmpldata);
}