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:
@@ -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
|
||||
|
||||
|
||||
215
scripts/Makefile
215
scripts/Makefile
@@ -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)
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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";
|
||||
@@ -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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
@@ -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 ). *
|
||||
* *
|
||||
***************************************************************************/
|
||||
@@ -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 = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
60807
scripts/oui.txt
60807
scripts/oui.txt
File diff suppressed because it is too large
Load Diff
@@ -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}";
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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}";
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user