├── AUTHORS ├── COPYING ├── ChangeLog ├── INSTALL ├── LICENSE ├── Makefile.am ├── NEWS ├── README ├── TODO ├── configure.ac ├── doc ├── Makefile.am └── honeytrap.8 ├── etc ├── honeytrap.conf.dist ├── ports.conf.dist └── responses │ ├── 110_tcp │ ├── 135_tcp │ ├── 139_tcp │ ├── 1433_tcp │ ├── 21000_tcp │ ├── 21_tcp │ ├── 25_tcp │ ├── 3306_tcp │ ├── 4444_tcp │ ├── 445_tcp │ ├── 4899_tcp │ ├── 5060_tcp │ ├── 5900_tcp │ ├── 8009_tcp │ └── 80_tcp ├── src ├── Makefile.am ├── attack.c ├── attack.h ├── conftree.c ├── conftree.h ├── connectmon.c ├── connectmon.h ├── ctrl.c ├── ctrl.h ├── dynsrv.c ├── dynsrv.h ├── event.c ├── event.h ├── honeytrap.c ├── honeytrap.h ├── ipqmon.c ├── ipqmon.h ├── logging.c ├── logging.h ├── md5.c ├── md5.h ├── modules │ ├── Makefile.am │ ├── htm_ClamAV.c │ ├── htm_ClamAV.h │ ├── htm_SaveFile.c │ ├── htm_SaveFile.h │ ├── htm_SpamSum.c │ ├── htm_SpamSum.h │ ├── htm_b64Decode.c │ ├── htm_b64Decode.h │ ├── htm_cpuEmu.c │ ├── htm_cpuEmu.h │ ├── htm_cspm │ │ ├── Makefile.am │ │ ├── connectback.c │ │ ├── connectback.h │ │ ├── htm_cspm.c │ │ ├── htm_cspm.h │ │ ├── sc_action.c │ │ ├── sc_action.h │ │ ├── sc_buffer.c │ │ ├── sc_buffer.h │ │ ├── sc_parser.h │ │ ├── sc_shellcode.c │ │ ├── sc_shellcodes.h │ │ ├── signature_parser.y │ │ └── signature_scanner.l │ ├── htm_deUnicode.c │ ├── htm_deUnicode.h │ ├── htm_ftpDownload.c │ ├── htm_ftpDownload.h │ ├── htm_httpDownload.c │ ├── htm_httpDownload.h │ ├── htm_logAttacker.c │ ├── htm_logJSON.c │ ├── htm_magicPE.c │ ├── htm_magicPE.h │ ├── htm_submitMWserv.c │ ├── htm_submitMWserv.h │ ├── htm_submitNebula.c │ ├── htm_submitNebula.h │ ├── htm_submitPostgres.c │ ├── htm_submitPostgres.h │ ├── htm_tftpDownload.c │ ├── htm_tftpDownload.h │ ├── htm_vncDownload.c │ ├── htm_vncDownload.h │ └── htm_xmatch.c ├── nfqmon.c ├── nfqmon.h ├── parseconf.c ├── parseconf.h ├── pcapmon.c ├── pcapmon.h ├── plughook.c ├── plughook.h ├── plugin.c ├── plugin.h ├── proxy.c ├── proxy.h ├── queue.c ├── queue.h ├── readconf.c ├── readconf.h ├── response.c ├── response.h ├── sha512.c ├── sha512.h ├── signals.c ├── signals.h ├── sock.c ├── sock.h ├── tcpip.h ├── util.c └── util.h └── tools ├── base64decode.c ├── bin2hex.c ├── edist.c ├── hex2bin.c ├── htprox.c ├── ngram.c └── ngtrie.c /AUTHORS: -------------------------------------------------------------------------------- 1 | Tillmann Werner, 2 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | Version 1.1.0 2 | - Fixed a memory leak in the httpDownload plugin 3 | - New xmatch plugin for automatic pattern-based decoding of XOR encoded data (requires libxmatch) 4 | - Fix: Don't reset port mode to default, keep configured mode 5 | - Fix: Default port mode 'ignore' was ignored (call it irony...) 6 | - reworked build process to be gcc 4.3 compatible 7 | - store download tries in attack record 8 | - magicPE plugin for identifying PE files that are submitted as attack strings 9 | - submitMWserv plugin for submissions to the mwcollect alliance 10 | - support for periodic events (resolution: 1 second) 11 | - 'bind_address' configuration option added for binding dynamic servers 12 | to a specific IP address to make it possible to run several honeytrap 13 | instances in parallel on a single machine 14 | - Code cleanup: asprintf() 15 | - Error handling for failed malloc()'s where it was missing 16 | - Fix: Improper logging of IP address pairs 17 | - Nebula submission plugin 18 | - reworked NFQ stream monitor hooking to prevent unbinding errors 19 | - hex2bin tool: Command line switch for byte order swapping added 20 | - reworked emu plugin 21 | Version 1.0.0 22 | - Improved configure script 23 | - New plugin: Basic http download wrapper 24 | - VNC plugin redesigned to generate virtual attacks 25 | - Safe signal delivery and handling using per-process pipes 26 | - New configuration concept with hierarchically organized file format 27 | - Default port configuration can be set to "ignore", "normal" or "mirror" 28 | - New plugin: libclamav-based virus scanner module 29 | - New plugin: Saving attack data in files is performed by a module now 30 | - malloc(NULL) segfault bug in tftpDownload plugin fixed 31 | - Try to download from the attacking host in case of failed ftp connect()s 32 | - Improved connection request handling in the nfq stream monitor 33 | - Reconfiguration on SIGHUP fixed 34 | - Log addressed destination 35 | Version 0.7.0 36 | - Plugins can be prioritized 37 | - x86 CPU emulation module for generic shellcode analysis 38 | based on libemu by Markus and Paul (unstable) 39 | - PostgreSQL module for commits into mwcollect database 40 | - SHA512 hash support 41 | - Performance improvements 42 | - Improved connection request handling in the nfq stream monitor 43 | - FTP download plugin is now source-based routing safe 44 | - Changed autotools process to make module builts optional 45 | Version 0.6.5 46 | - Introduced an nfnetlink_queue-based connection monitor 47 | - Some compile errors fixed 48 | - Configure script changed to run on MacOS X 49 | - Do not install htm_SpamSum by default 50 | Version 0.6.4 51 | - PoC plugin for locality sensitive hashing 52 | - Clean solution for giving packet control back to the kernel 53 | when using the ip_queue connection monitor 54 | - Fixed a segfault in the bpf filter string assembling routine 55 | - Failed mirror connections did not fall back to normal mode sometimes 56 | due to wrong return value handling for a non-blocking connect(). Fixed. 57 | - The dynamic server code was redesigned. 58 | - UDP support added. 59 | Version 0.6.3.1 60 | - The FTP download plugin supports explicit binding of data connections 61 | to ip addresses or hostnames to work on NAT'ed hosts 62 | - Modes of operation are already determined in network stream monitors 63 | to prevent gratuitous forking 64 | - Listener processes now have a backlog queue of size 10 65 | - BPF strings can include up to 2^32 characters instead of 2^8 66 | - Some changes and cleanups make the code more readable 67 | Version 0.6.3 68 | - A 10 second timeout is used for mirror connection attempts to prevent 69 | simultaneous timeouts after a blocking connect() returns 70 | - md5 checksum calculation snprintf size parameter corrected 71 | - Fixed a bug with config file lines with trailing blanks, thanks to Emre 72 | - DESTDIR is used in Makefiles now, thanks to kanedaaa for the patch 73 | - Plugin installation was wrong on non-Linux systems and is fixed now 74 | - Attack connections are closed after a configurable byte limit 75 | to prevent memory exhaustion - suggestion from kanedaaa 76 | - Added a plugin to decode and process base64 encoded attacks 77 | - Small pcap connection monitor changes 78 | - Fixed a segfault for zero lenght attacks in the htm_vncDownload plugin 79 | - Further small changes 80 | Version 0.6.2 81 | - Added a plugin for execution of HTTP downloads from VNC attacks via wget 82 | - Connection monitor can be chosen from "configure" parameter 83 | - Introduced an ip_queue based connection monitor 84 | (idea from the nepenthes honeytrap module) 85 | - Native OS dl implementations and libdl are both supported 86 | - Should compile on Free/OpenBSD now, thanks to Stephen and Gary 87 | - Network device handling is completely done with pcap functions 88 | for the pcap connection monitor 89 | - Trapping on device 'any' is now possible (if available) 90 | - Added support for other link types than ethernet 91 | - Logging of remote TCP port and IP address was faulty - fixed 92 | - Changed bpf string to filter RST packets to be more portable 93 | - Connections are closed before attack processor plugins are called 94 | - Configuration file supports includes of other files 95 | - Proxy mode introduced 96 | - Connection handling mode can be configured per port 97 | - Specific ports can be configured to ignore connection requests 98 | - Some minor bugfixes 99 | Version 0.6.1 100 | - Temporarily removed BDB stuff, a plugin will be available soon 101 | - Added plugin hooks 'unload_plugins' and 'process_attack' 102 | - Moved attack save code into a plugin 103 | - Moved ftp download code into a plugin 104 | - Moved tftp download code into a plugin 105 | - Establish mirror connection right after incoming SYN 106 | - Reload configuration on SIGHUP 107 | - Cleanup of TCP dynamic server code 108 | - Some file descriptors are closed earlier 109 | - Fixed bpf command line expression stuff 110 | - Some man page changes 111 | - Automake: shared libraries are only installed in plugin directory now 112 | Version 0.6.0 113 | - Support for configuration file added 114 | - Added a plugin interface (still a lot of work to do) 115 | - Mirrored connections are closed after a timeout 116 | Version 0.5.1 117 | - Fixed tftp bug - files bigger than 128k were corrupted during transfer 118 | - Many minor cosmetic fixes 119 | Version 0.5.0 120 | - Mirror mode added - get answers from mirror connection to the client 121 | - Partial rewrite of TCP server stuff 122 | Version 0.4.2 123 | - PID file will correctly be removed if startup fails 124 | - Improved tftp routine 125 | - Made ftp command string parser more sensitive 126 | - Invalid IP addresses in download ressources are recognized and filtered 127 | Version 0.4.1 128 | - Retransmission of tftp packets after timeout occured 129 | - Silly bug in tftp routine fixed - files may also be sent from server port != 69 130 | - Workaround for communication with buggy ftp servers included 131 | - Fixed minor bugs in ftp and tftp routines 132 | - Improved download command parsing routine, it shouldn't fail anymore 133 | - Attack string naming corrected 134 | - Added logfile and pidfile support 135 | - Switched to write() to improve logging performance 136 | Version 0.4.0 137 | - Auto download files via ftp using a fake Windows ftp dialogue 138 | - Auto download files via tftp 139 | - Improved signal handling to prevent zombie processes 140 | - Get IP address for bpf string from interface 141 | - Fixed error handling in db code 142 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | AUTOMAKE_OPTIONS = foreign 2 | 3 | LIBS = -ldl 4 | SUBDIRS = doc src 5 | 6 | EXTRA_DIST = ChangeLog LICENSE README doc/honeytrap.8 etc/ 7 | 8 | libtool: $(LIBTOOL_DEPS) 9 | $(SHELL) ./config.status --recheck 10 | 11 | install-data-local: 12 | $(mkinstalldirs) $(DESTDIR)/$(sysconfdir) 13 | $(mkinstalldirs) $(DESTDIR)/$(sysconfdir)/honeytrap 14 | $(mkinstalldirs) $(DESTDIR)/$(sysconfdir)/honeytrap/responses 15 | $(mkinstalldirs) $(DESTDIR)/$(localstatedir)/honeytrap 16 | 17 | install -d $(DESTDIR)/$(localstatedir)/honeytrap/attacks -g nogroup -m 775 18 | install -d $(DESTDIR)/$(localstatedir)/honeytrap/downloads -g nogroup -m 775 19 | 20 | $(INSTALL_DATA) etc/honeytrap.conf.dist $(DESTDIR)/$(sysconfdir)/honeytrap/honeytrap.conf.dist 21 | test -f $(DESTDIR)/$(sysconfdir)/honeytrap/honeytrap.conf || $(INSTALL_DATA) etc/honeytrap.conf.dist $(DESTDIR)/$(sysconfdir)/honeytrap/honeytrap.conf 22 | $(INSTALL_DATA) etc/ports.conf.dist $(DESTDIR)/$(sysconfdir)/honeytrap/ports.conf.dist 23 | $(INSTALL_DATA) etc/responses/* $(DESTDIR)/$(sysconfdir)/honeytrap/responses 24 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/armedpot/honeytrap/412c430b0b34f3345f40d752f4bf1c0e4f51b956/NEWS -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | README 2 | 3 | Honeytrap is a network security tool written to observe attacks 4 | against TCP or UDP services. It runs as a daemon and starts serv- 5 | er processes dynamically on requested ports. A server emulates a 6 | well-known service by simply sending captured network traffic to 7 | a connected host. 8 | 9 | Many clients and particularly attackers will be fooled and send 10 | responses to a honeytrap server process. The arriving data is as- 11 | sembled to a string and written to a database file. Such a string 12 | is called an attack string. 13 | 14 | Honeytrap can parse an attack string for commands advising the 15 | server to download a file from another host. If a download com- 16 | mand is found, the server tries to retrieve the corresponding 17 | file automatically. A downloaded file is stored locally with an 18 | md5 checksum in its name. Currently, only ftp and tftp are sup- 19 | ported. Honeytrap implements its own clients with the aim to be- 20 | have as similar as possible than Windows systems. Http URIs are 21 | recognized and logged. A http download routine may be added in 22 | future releases. 23 | 24 | INSTALLATION 25 | 26 | Installation of honeytrap is pretty straight forward. Just do a 27 | './configure --with-stream-mon= && make && make install' 28 | where '' is the connection monitor type of your choice. 29 | Please refer to the INSTALL file and to the output of './config- 30 | ure --help' for further information. 31 | 32 | WARNINGS 33 | 34 | Honeytrap is a low-interactive honeypot and therefore detectable. 35 | It is written in C and thus potentially vulnerable to buffer 36 | overflow attacks. Take care. Running in mirror mode is dangerous. 37 | Attacks may be directed to the attacker, appearing to come from 38 | your system. Use with caution. 39 | 40 | The program needs root privileges, but only for binding server 41 | processes to well-known ports. Use the -u and -g command line op- 42 | tions to drop privileges and switch to another user and group as 43 | early as possible. 44 | 45 | CONTACT 46 | 47 | If you have problems, questions, ideas or suggestions, please 48 | contact me at . If you would like to help 49 | making honeytrap better, you are welcome. 50 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | -- Small Changes ------------------------------------------------------ 2 | o Do fallback to default interface already in ip guessing phase 3 | 4 | -- Future plans ------------------------------------------------------- 5 | o add ipfw connection monitors 6 | -------------------------------------------------------------------------------- /doc/Makefile.am: -------------------------------------------------------------------------------- 1 | man_MANS = honeytrap.8 2 | -------------------------------------------------------------------------------- /doc/honeytrap.8: -------------------------------------------------------------------------------- 1 | .\" -*- nroff -*- --------------------------------------------------------- * 2 | .\" $Id: honeytrap.8.in,v 0.6.2 2006/08/05 16:00:00 Exp $ 3 | .\" 4 | .\" Copyright (c) 1987, 1988, 1989, 1990, 1991, 1992, 1994, 1995, 1996, 1997 5 | .\" The Regents of the University of California. All rights reserved. 6 | .\" All rights reserved. 7 | .\" 8 | .\" Copyright (c) 2005-2006 Tillmann Werner - All rights reserved. 9 | .\" 10 | .\" Redistribution and use in source and binary forms, with or without 11 | .\" modification, are permitted provided that: (1) source code distributions 12 | .\" retain the above copyright notice and this paragraph in its entirety, (2) 13 | .\" distributions including binary code include the above copyright notice and 14 | .\" this paragraph in its entirety in the documentation or other materials 15 | .\" provided with the distribution, and (3) all advertising materials mentioning 16 | .\" features or use of this software display the following acknowledgement: 17 | .\" ``This product includes software developed by the University of California, 18 | .\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 19 | .\" the University nor the names of its contributors may be used to endorse 20 | .\" or promote products derived from this software without specific prior 21 | .\" written permission. 22 | .\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 23 | .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 24 | .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 25 | .\" 26 | .\"----------------------------------------------------------------------- */ 27 | .TH HONEYTRAP 8 "5 August 2006" " " 28 | .SH NAME 29 | .B honeytrap 30 | \- trap attacks against network services 31 | .SH SYNOPSIS 32 | .B honeytrap 33 | [ 34 | .B \-Dpmv 35 | ] [ 36 | .B \-i 37 | .I interface 38 | ] [ 39 | .B \-a 40 | .I ip address 41 | ] 42 | .br 43 | .ti +10 44 | [ 45 | .B \-l 46 | .I listen timeout 47 | ] [ 48 | .B \-r 49 | .I read timeout 50 | ] 51 | .ti +10 52 | [ 53 | .B \-t 54 | .I loglevel 55 | ] [ 56 | .B \-L 57 | .I logfile 58 | ] [ 59 | .B \-P 60 | .I pidfile 61 | ] 62 | .br 63 | .ti +10 64 | [ 65 | .B \-C 66 | .I configfile 67 | ] [ 68 | .I expression 69 | ] 70 | .br 71 | .SH DESCRIPTION 72 | .I honeytrap 73 | is a network security tool written to observe attacks against network services. As a low-interactive honeypot, it collects information regarding known or unknown network-based attacks. It starts server processes dynamically at the time of incoming connection requests. This generic behavior makes it possible to respond to most network-based attacks. Observed data can be processed with plugins for automatic analysis. 74 | .LP 75 | Data capture is basically done by the core system. The master process uses a connection monitor to catch incoming requests. Currently, connection monitoring can be performed via a PCAP based sniffer or by hooking the ip_queue API, a userland interface to netfilter/iptables on Linux systems. The appropriate technique has to be built in during compile time. 76 | .LP 77 | Incoming connections are processed in one of the following modi: normal, ignore, proxy and mirror. The specific bevavior for a connection can be configured per tcp or udp port. If no explicit configuration is given, the default mode applies. It is possible to setup 78 | .I honeytrap 79 | as a meta-honeypot, forwarding some connections to different honeypot systems, handle some attacks with own routines or even route connections to different honeypots. 80 | .LP 81 | All data submitted to 82 | .I honeytrap 83 | or sent to the remote host can be analyzed with specialized plugins. All plugins are dynamically loaded at startup or during runtime at a reconfiguration initiation. Thus it is possible to add analysis functions without downtime of the honeypot. 84 | .LP 85 | .I honeytrap 86 | must be run by root or installed setuid to root, in order to bind to 87 | privileged ports. Always use the 88 | .B -u 89 | and 90 | .B -g 91 | flags to drop privileges early and switch to an unprivileged user and group as soon as possible. 92 | 93 | 94 | .SH OPTIONS 95 | .TP 96 | .B \-a 97 | Watch for rejected connections to 98 | .I ip 99 | .IR address . 100 | This is normally not needed as 101 | .I honeytrap 102 | tries to get the corresponding address for 103 | .IR interface 104 | automatically. Only availabe when using the pcap connection monitor. 105 | .TP 106 | .B \-g 107 | .IR group. 108 | Change the group/GID of dynamic server processes to 109 | .I group 110 | after initialization. 111 | .TP 112 | .B \-h 113 | Print usage information to standard output, then exit gracefully. 114 | .TP 115 | .B \-i 116 | Watch for rejected connections on 117 | .IR interface . 118 | Only available when using the pcap connection monitor. 119 | .TP 120 | .B \-l 121 | .I listen 122 | .IR timeout . 123 | Terminate dynamic servers after the specified number of seconds. Default is 30. 124 | .TP 125 | .B \-m 126 | Run in mirror mode. Mirror incoming connections back to remote hosts. 127 | .TP 128 | .B \-p 129 | Put 130 | .I interface 131 | into promiscuous mode. Only available when using the pcap connection monitor. 132 | .TP 133 | .B \-r 134 | .I read 135 | .IR timeout . 136 | Terminate connection handlers after the specified number of seconds. Default is 1. 137 | .TP 138 | .B \-t 139 | .I log 140 | .IR level. 141 | Log verbosity (0-6). Default is 3, 0 is off. 142 | .TP 143 | .B \-u 144 | .IR user. 145 | Run as 146 | .I user 147 | after initialization. 148 | .TP 149 | .B \-v 150 | Print version number to standard output, then exit gracefully. 151 | .TP 152 | .B \-C 153 | .I configuration 154 | .IR file . 155 | Read configuration from 156 | .I configuration 157 | .IR file . 158 | .TP 159 | .B \-D 160 | Don't daemonize. 161 | .TP 162 | .B \-L 163 | .I log 164 | .IR file . 165 | Log messages to 166 | .I log 167 | .IR file . 168 | .TP 169 | .B \-P 170 | .I pid 171 | .IR file . 172 | Write process ID of master process to 173 | .I pid 174 | .IR file . 175 | 176 | .IP "\fI expression\fP" 177 | To recognize rejected connections, 178 | .I honeytrap 179 | uses a berkeley packet filter (bpf) to catch connection requests. The filter can be restricted by adding a bpf 180 | .I expression. 181 | This only has an effect when using the pcap connection monitor. 182 | 183 | .SH EXAMPLE 184 | .LP 185 | Read configuration from 186 | .BR /etc/honeytrap.conf , 187 | run on 188 | .B eth0 189 | as 190 | .B nobody/nogroup 191 | and log to 192 | .BR /var/log/honeytrap.log . 193 | Set the log level to LOG_NOISY ( 194 | .BR 5 195 | ) and stay in foreground ( 196 | .BR -D 197 | ): 198 | .LP 199 | .RS 200 | .nf 201 | \fBhoneytrap -C /etc/honeytrap.conf -i eth0 -u nobody -g nogroup -L /var/log/honeytrap.log -t 5 -D\fP 202 | .fi 203 | .RE 204 | .SH NOTES 205 | As a honeypot, 206 | .I honeytrap 207 | is exposed to attacks that might compromise the software itself. Running it inside a hardened and secured environment is a good idea. Linking against a stack protection library might also improve security. The configure script supports the electric fence malloc debugger. Use it. 208 | .SH SEE ALSO 209 | .BR bpf (4), 210 | .BR iptables (8), 211 | .BR pcap (3), 212 | .BR udp(7). 213 | .BR tcp (7). 214 | .SH AUTHOR 215 | This version of 216 | .B honeytrap 217 | was written by Tillmann Werner . 218 | .SH BUGS 219 | Please report any bugs to . 220 | -------------------------------------------------------------------------------- /etc/honeytrap.conf.dist: -------------------------------------------------------------------------------- 1 | /* 2 | * honeytrap 1.0.1 configuration file template -- please adjust 3 | * (c) Tillmann Werner 4 | */ 5 | 6 | // log to this file 7 | logfile = "/opt/honeytrap/honeytrap.log" 8 | 9 | // store process ID in this file 10 | pidfile = "/var/run/honeytrap.pid" 11 | 12 | /* where to look for default responses 13 | * these are sent for connections handled in "normal mode" */ 14 | response_dir = "/opt/honeytrap/etc/honeytrap/responses" 15 | 16 | // replace rfc1918 IP addresses with attacking IP address 17 | replace_private_ips = "no" 18 | 19 | // bind dynamic servers to a specific address 20 | //bind_address = "127.0.0.1" 21 | 22 | /* put network interface into promiscuous mode 23 | * (only availabel when compiled with --with-stream-mon=pcap) */ 24 | //promisc = "on" 25 | 26 | /* the user and group under which honeytrap should run 27 | * should be set to non-root */ 28 | user = "nobody" 29 | group = "nogroup" 30 | 31 | // do not read more than 20 MB - used to prevent DoS attacks 32 | read_limit = "20971520" 33 | 34 | 35 | /* ----- plugin stuff below ----- */ 36 | 37 | /* where to look for plugins 38 | needs to be set before loading plugins */ 39 | plugin_dir = "/opt/honeytrap/etc/honeytrap/plugins" 40 | 41 | 42 | // include a plugin via plugin-[ModuleName] = "" 43 | 44 | // plugin-magicPE = "" 45 | plugin-ftpDownload = "" 46 | plugin-tftpDownload = "" 47 | plugin-b64Decode = "" 48 | plugin-deUnicode = "" 49 | plugin-vncDownload = "" 50 | 51 | 52 | // store attacks on disk 53 | plugin-SaveFile = { 54 | attacks_dir = "/opt/honeytrap/var/honeytrap/attacks" 55 | downloads_dir = "/opt/honeytrap/var/honeytrap/downloads" 56 | } 57 | 58 | 59 | // plugin for shellcode detection and emulation 60 | /* 61 | plugin-cpuEmu = { 62 | execute_shellcode = "no" 63 | createprocess_cmd = "/bin/sh -c \"cd /opt/honeytrap-libemu/.wine/drive_c/windows/system32; WINEPREFIX='/opt/honeytrap-libemu/.wine/' WINEDEBUG='-all' wine 'c:\\windows\\system32\\cmd_orig.exe'\"" 64 | } 65 | */ 66 | 67 | 68 | 69 | // scan downloaded samples with ClamAV engine 70 | /* 71 | plugin-ClamAV = { 72 | temp_dir = "/tmp" 73 | clamdb_path = "/var/lib/clamav" 74 | } 75 | */ 76 | 77 | 78 | // calculate locality sensitive hashes 79 | /* 80 | plugin-SpamSum = { 81 | md5sum_sigfile = "/opt/honeytrap/md5sum.sigs" 82 | spamsum_sigfile = "/opt/honeytrap/spamsum.sigs" 83 | } 84 | */ 85 | 86 | 87 | // store attacks in PostgeSQL database 88 | /* 89 | plugin-SavePostgres = { 90 | db_host = "localhost" 91 | db_name = "some_db" 92 | db_user = "some_user" 93 | db_pass = "some_pass" 94 | // db_port = "some_port" // defaults to 5432/tcp if not set 95 | } 96 | */ 97 | 98 | 99 | // invoke an external program (f.e. wget) to download files via http 100 | /* 101 | plugin-httpDownload = { 102 | http_program = "/usr/bin/wget" 103 | http_options = "-q -t1 -T1 -O-" 104 | } 105 | */ 106 | 107 | 108 | // submit downloaded malware samples to the mwcollect alliance 109 | /* 110 | plugin-submitMWserv = { 111 | mwserv_url = "https://submission-url/" 112 | guid = "your-guid" 113 | maintainer = "your-maintainer" 114 | secret = "your-secret" 115 | timeout = "120" 116 | } 117 | */ 118 | 119 | // log attacker connection information to a separate file, one entry per line 120 | /* 121 | plugin-logAttacker = { 122 | logfile = "/opt/honeytrap/attackers.log" 123 | } 124 | */ 125 | 126 | // log attack details in JSON format 127 | /* 128 | plugin-logJSON = { 129 | logfile = "/opt/honeytrap/attackers.json" 130 | } 131 | */ 132 | 133 | /* ----- port mode configuration below ----- */ 134 | 135 | // default port configuration (ignore, normal or mirror) 136 | // ignore: just ignore connection attempts 137 | // normal: send a default response 138 | // mirror: mirror connections back to the initiator (use with caution!) 139 | portconf_default = "normal" 140 | 141 | // explicit port configuration 142 | portconf = { 143 | // ignore connection requests on these ports 144 | ignore = { 145 | protocol = "tcp" 146 | port = "22" 147 | } 148 | } 149 | 150 | // include a file 151 | //include = "ports.conf" 152 | -------------------------------------------------------------------------------- /etc/ports.conf.dist: -------------------------------------------------------------------------------- 1 | /* 2 | * honeytrap 1.0 port configuration file template 3 | * should be included in main configuration file 4 | * (c) Tillmann Werner 5 | */ 6 | 7 | portconf = { 8 | /* ignore these ports */ 9 | ignore = { 10 | protocol = "tcp" 11 | port = ["25", "1433"] 12 | } 13 | /* process ports in normal mode */ 14 | normal = { 15 | protocol = ["tcp", "udp"] 16 | port = ["53"] 17 | } 18 | /* mirror ports back to the initiator */ 19 | mirror = { 20 | protocol = ["tcp"] 21 | port = ["23"] 22 | } 23 | /* proxy ports to a target */ 24 | proxy = { 25 | /* names for proxy maps can be chosen from [a-zA-Z0-9-_] */ 26 | proxy-http = { 27 | protocol = ["tcp"] 28 | port = ["80", "8080"] 29 | 30 | target_host = "127.0.0.1" 31 | target_protocol = "tcp" 32 | target_port = "8080" 33 | } 34 | proxy-tftp = { 35 | protocol = ["udp"] 36 | port = ["69"] 37 | 38 | target_host = "tftp.localhost" 39 | target_protocol = "udp" 40 | target_port = "69" 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /etc/responses/110_tcp: -------------------------------------------------------------------------------- 1 | +OK 2 | -------------------------------------------------------------------------------- /etc/responses/135_tcp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/armedpot/honeytrap/412c430b0b34f3345f40d752f4bf1c0e4f51b956/etc/responses/135_tcp -------------------------------------------------------------------------------- /etc/responses/139_tcp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/armedpot/honeytrap/412c430b0b34f3345f40d752f4bf1c0e4f51b956/etc/responses/139_tcp -------------------------------------------------------------------------------- /etc/responses/1433_tcp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/armedpot/honeytrap/412c430b0b34f3345f40d752f4bf1c0e4f51b956/etc/responses/1433_tcp -------------------------------------------------------------------------------- /etc/responses/21000_tcp: -------------------------------------------------------------------------------- 1 | Microsoft Windows XP [Version 5.1.2600] 2 | (C) Copyright 1985-2001 Microsoft Corp. 3 | 4 | C:\WINDOWS\system32> -------------------------------------------------------------------------------- /etc/responses/21_tcp: -------------------------------------------------------------------------------- 1 | 220 Welcome to localhost 2 | -------------------------------------------------------------------------------- /etc/responses/25_tcp: -------------------------------------------------------------------------------- 1 | 250 localhost ESMTP Postfix 2 | -------------------------------------------------------------------------------- /etc/responses/3306_tcp: -------------------------------------------------------------------------------- 1 | ; 2 | 4.0.24_Debian-10sarge1-logu3;n:u`b,  -------------------------------------------------------------------------------- /etc/responses/4444_tcp: -------------------------------------------------------------------------------- 1 | Microsoft Windows XP [Version 5.1.2600] 2 | (C) Copyright 1985-2001 Microsoft Corp. 3 | 4 | C:\WINDOWS\system32> -------------------------------------------------------------------------------- /etc/responses/445_tcp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/armedpot/honeytrap/412c430b0b34f3345f40d752f4bf1c0e4f51b956/etc/responses/445_tcp -------------------------------------------------------------------------------- /etc/responses/4899_tcp: -------------------------------------------------------------------------------- 1 | % -------------------------------------------------------------------------------- /etc/responses/5060_tcp: -------------------------------------------------------------------------------- 1 | SIP/2.0 200 OK 2 | Via: SIP/2.0/TCP 127.0.0.1:5060;branch=1234567890 3 | From: sip:1234567890@127.0.0.1;tag=bad-012345 4 | To: ;tag=bad-012345 5 | Call-ID: 1348979872-797979222304855 6 | Cseq: 15 INVITE 7 | Contact: sip:0987654321@127.0.0.1 8 | Content-Length: 401 9 | Content-Type: application/sdp 10 | 11 | v=0 12 | Anonymous 1234567890 9876543210 IN IP4 127.0.0.1 13 | s=SIGMA is the best 14 | s=gotcha 15 | c=IN IP4 127.0.0.1 16 | t=0 0 17 | m=audio 36952 RTP/AVP 107 119 100 106 6 0 97 105 98 8 18 3 5 101 18 | a=rtpmap:107 BV32/16000 19 | a=rtpmap:119 BV32-FEC/16000 20 | a=rtpmap:100 SPEEX/16000 21 | a=rtpmap:106 SPEEX-FEC/16000 22 | a=rtpmap:97 SPEEX/8000 23 | a=rtpmap:105 SPEEX-FEC/8000 24 | a=rtpmap:98 iLBC/8000 25 | a=rtpmap:101 telephone-event/8000 26 | a=fmtp:101 0-11 27 | -------------------------------------------------------------------------------- /etc/responses/5900_tcp: -------------------------------------------------------------------------------- 1 | RFB 003.008 2 | -------------------------------------------------------------------------------- /etc/responses/8009_tcp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/armedpot/honeytrap/412c430b0b34f3345f40d752f4bf1c0e4f51b956/etc/responses/8009_tcp -------------------------------------------------------------------------------- /etc/responses/80_tcp: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Connection: close 3 | Date: Sun, 27 Nov 2005 13:07:34 GMT 4 | Server: Microsoft-IIS/6.0 5 | X-Powered-By: ASP.NET 6 | X-AspNet-Version: 2.0.50727 7 | Accept-Ranges: bytes 8 | Content-Length: 30 9 | Cache-Control: private 10 | Content-Type: text/html; charset=utf-8 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | AUTOMAKE_OPTIONS=foreign no-dependencies 2 | 3 | AM_CFLAGS=-export-dynamic -Wall -Werror -Wno-stringop-truncation -Wno-stringop-overflow -Wno-format-overflow -fcommon 4 | 5 | sbin_PROGRAMS = honeytrap 6 | honeytrap_SOURCES = honeytrap.c honeytrap.h \ 7 | logging.c logging.h \ 8 | event.c event.h \ 9 | ctrl.c ctrl.h \ 10 | queue.c queue.h \ 11 | signals.c signals.h \ 12 | readconf.c readconf.h \ 13 | parseconf.c parseconf.h \ 14 | conftree.c conftree.h \ 15 | plugin.c plugin.h \ 16 | plughook.c plughook.h \ 17 | util.c util.h \ 18 | connectmon.c connectmon.h \ 19 | response.c response.h \ 20 | dynsrv.c dynsrv.h \ 21 | attack.c attack.h \ 22 | tcpip.h \ 23 | sock.c sock.h \ 24 | proxy.c proxy.h \ 25 | sha512.c sha512.h \ 26 | md5.c md5.h 27 | 28 | if PCAP_MON 29 | honeytrap_SOURCES += pcapmon.c pcapmon.h 30 | endif 31 | 32 | if IPQ_MON 33 | honeytrap_SOURCES += ipqmon.c ipqmon.h 34 | endif 35 | 36 | if NFQ_MON 37 | honeytrap_SOURCES += nfqmon.c nfqmon.h 38 | endif 39 | 40 | SUBDIRS = modules 41 | -------------------------------------------------------------------------------- /src/attack.h: -------------------------------------------------------------------------------- 1 | /* attack.h 2 | * Copyright (C) 2005-2008 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HONEYTRAP_ATTACK_H 14 | #define __HONEYTRAP_ATTACK_H 1 15 | 16 | #include 17 | 18 | struct s_payload { 19 | uint32_t size; /* length of attack string */ 20 | char md5sum[33]; /* md5 checksum */ 21 | char sha512sum[129]; /* sha512 checksum */ 22 | u_char *data; /* attack string */ 23 | }; 24 | 25 | struct s_conn { 26 | uint32_t l_addr; /* local ip address */ 27 | uint32_t r_addr; /* remote ip address */ 28 | uint16_t l_port; /* local (tcp/udp) port */ 29 | uint16_t r_port; /* remote (tcp/udp) port */ 30 | u_char protocol; /* IP protocol id (tcp/udp) */ 31 | struct s_payload payload; /* payload read from fd */ 32 | }; 33 | 34 | struct s_download { 35 | char *dl_type; /* (FTP, TFTP, VNC, ...) */ 36 | uint32_t r_addr; /* remote IP address */ 37 | uint32_t l_addr; /* local IP address */ 38 | uint16_t r_port; /* remote port */ 39 | uint16_t l_port; /* local port */ 40 | uint16_t protocol; /* protocol as in IP header */ 41 | char *user; /* username for download connection */ 42 | char *pass; /* user's password */ 43 | char *filename; /* filename of download */ 44 | char *uri; /* unified resource identifier */ 45 | struct s_payload dl_payload; /* downloaded data */ 46 | }; 47 | 48 | typedef struct s_attack { 49 | u_char virtual; /* flag for marking virtual attacks */ 50 | time_t start_time; /* time of attack start */ 51 | time_t end_time; /* time of attack end */ 52 | struct s_conn a_conn; /* attack connection */ 53 | struct s_conn p_conn; /* proxy/mirror connection */ 54 | u_char op_mode; /* mode of operation (none, ignore, normal, proxy, mirror) */ 55 | uint16_t dl_count; /* number of downloads */ 56 | uint16_t dl_tries; /* number of download tries */ 57 | struct s_download *download; /* array of download structs */ 58 | } Attack; 59 | 60 | 61 | Attack *new_virtattack(struct in_addr l_addr, struct in_addr r_addr, uint16_t l_port, uint16_t r_port, uint16_t proto); 62 | Attack *new_attack(struct in_addr l_addr, struct in_addr r_addr, uint16_t l_port, uint16_t r_port, uint16_t proto); 63 | void del_attack(Attack *a); 64 | int process_data(u_char *a_data, uint32_t a_size, u_char *p_data, uint32_t p_size, uint16_t port, Attack *a); 65 | int add_download(const char *dl_type, u_int16_t proto, const uint32_t r_addr, const uint16_t r_port, const char *user, const char *pass, const char *filename, const char *uri, const u_char *data, const u_int32_t size, Attack *a); 66 | int reassign_downloads(Attack *dst, Attack *src); 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /src/conftree.h: -------------------------------------------------------------------------------- 1 | /* conftree.h 2 | * Copyright (C) 2007 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HONEYTRAP_CONFTREE_H 14 | #define __HONEYTRAP_CONFTREE_H 1 15 | 16 | /* config file keyword configuration goes herei 17 | * don't forget to adjust the number */ 18 | 19 | 20 | typedef struct list_entry { 21 | ssize_t size; 22 | void *data; 23 | struct list_entry *next; 24 | } list_entry; 25 | 26 | 27 | typedef struct conf_node { 28 | char *keyword; 29 | list_entry *val; 30 | struct conf_node *first_leaf; 31 | struct conf_node *next; 32 | } conf_node; 33 | 34 | 35 | conf_node *config_keywords_tree; // tree for allowed keywords, initialized by core, extended by plugins 36 | conf_node *config_tree; // tree for actual configuration organized in a hierarchical manner 37 | 38 | 39 | void conftree_children_free(conf_node *tree); 40 | void print_conftree(conf_node *tree, int depth); 41 | conf_node *conf_subtree(conf_node *tree, const char *keyword); 42 | conf_node *check_keyword(conf_node *tree, const char *keyword); 43 | conf_node *add_keyword(conf_node **tree, const char *keyword, const void *data, ssize_t size); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/connectmon.c: -------------------------------------------------------------------------------- 1 | /* connectmon.c 2 | * Copyright (C) 2006-2007 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #include 14 | #include 15 | 16 | #include "honeytrap.h" 17 | #include "connectmon.h" 18 | #include "logging.h" 19 | #include "dynsrv.h" 20 | #include "ctrl.h" 21 | #include "pcapmon.h" 22 | #include "ipqmon.h" 23 | #include "nfqmon.h" 24 | 25 | 26 | int start_connection_monitor(void) { 27 | /* call connection monitor for activated type */ 28 | #ifdef USE_IPQ_MON 29 | start_ipq_mon(); 30 | #else 31 | #ifdef USE_PCAP_MON 32 | start_pcap_mon(); 33 | #else 34 | #ifdef USE_NFQ_MON 35 | start_nfq_mon(); 36 | #else 37 | #ifdef USE_IPFW_MON 38 | #endif 39 | #endif 40 | #endif 41 | #endif 42 | return(1); 43 | } 44 | -------------------------------------------------------------------------------- /src/connectmon.h: -------------------------------------------------------------------------------- 1 | /* connectmon.h 2 | * Copyright (C) 2006 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HONEYTRAP_CONNECTMON_H 14 | #define __HONEYTRAP_CONNECTMON_H 1 15 | 16 | int start_connection_monitor(void); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/ctrl.c: -------------------------------------------------------------------------------- 1 | /* ctrl.c 2 | * Copyright (C) 2006-2015 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include "ctrl.h" 23 | #include "honeytrap.h" 24 | #include "logging.h" 25 | #include "nfqmon.h" 26 | #include "pcapmon.h" 27 | #include "plugin.h" 28 | #include "response.h" 29 | #include "signals.h" 30 | 31 | void usage(char *progname) { 32 | #ifndef USE_PCAP_MON 33 | fprintf(stdout, "Usage: %s [ -Dmv ] [ -l seconds ] [ -r seconds ] [ -t log level ]\n\t\t[ -u user ] [ -g group ]\n", progname); 34 | #else 35 | fprintf(stdout, "Usage: %s [ -Dpmv ] [ -i interface ] [ -a ip address ] [ -l seconds ]\n\t\t[ -r seconds ] [ -t log level ] [ -u user ] [ -g group ]\n", progname); 36 | fprintf(stdout, "\t-a:\tip address or hostname (normally not needed)\n"); 37 | #endif 38 | fprintf(stdout, "\t-g:\tgroup\n"); 39 | fprintf(stdout, "\t-h:\tthis output\n"); 40 | #ifdef USE_PCAP_MON 41 | fprintf(stdout, "\t-i:\tinterface, defaults to first usable device\n"); 42 | #endif 43 | fprintf(stdout, "\t-l:\tlisten timeout (sec), default is 1\n"); 44 | fprintf(stdout, "\t-m:\tenable mirror mode\n"); 45 | #ifdef USE_PCAP_MON 46 | fprintf(stdout, "\t-p:\tenable promiscuous mode\n"); 47 | #endif 48 | fprintf(stdout, "\t-r:\tread timeout (sec), default is 30\n"); 49 | fprintf(stdout, "\t-t:\tlog level (0-6), default is 3 (LOG_NOTICE)\n"); 50 | fprintf(stdout, "\t-u:\tuser\n"); 51 | fprintf(stdout, "\t-v:\tprint version number\n"); 52 | fprintf(stdout, "\t-C:\tconfiguration file\n"); 53 | fprintf(stdout, "\t-D:\tdon't daemonize\n"); 54 | fprintf(stdout, "\t-L:\tlogfile\n"); 55 | fprintf(stdout, "\t-P:\tpid file\n"); 56 | exit(EXIT_SUCCESS); 57 | } 58 | 59 | 60 | void clean_exit(int status) { 61 | #ifdef USE_PCAP_MON 62 | // free bpf filter string 63 | logmsg(LOG_DEBUG, 1, "Freeing BPF filter string.\n"); 64 | free(bpf_filter_string); 65 | #endif 66 | #ifdef USE_NFQ_MON 67 | // unhook from netfilter-queue 68 | if (h) { 69 | logmsg(LOG_DEBUG, 1, "Destroying NFQ handle.\n"); 70 | if (qh && nfq_destroy_queue(qh) != 0) { 71 | logmsg(LOG_ERR, 1, "Error - Could not destroy NFQ handle: %m.\n"); 72 | } 73 | 74 | logmsg(LOG_DEBUG, 1, "Unhooking NFQ connection monitor.\n"); 75 | if (nfq_close(h) != 0) { 76 | logmsg(LOG_ERR, 1, "Error - Could not close NFQ connection monitor: %m.\n"); 77 | } 78 | } 79 | #endif 80 | 81 | logmsg(LOG_DEBUG, 1, "Unloading default responses.\n"); 82 | unload_default_responses(); 83 | 84 | /* unloading plugins */ 85 | logmsg(LOG_DEBUG, 1, "Unloading plugins.\n"); 86 | unload_plugins(); 87 | 88 | if (pidfile_fd >= 0) { 89 | logmsg(LOG_DEBUG, 1, "Unlocking pid file.\n"); 90 | if (lockf(pidfile_fd, F_ULOCK, 0) < 0) 91 | logmsg(LOG_ERR, 1, "Error - Unable to unlock pid file: %m.\n"); 92 | 93 | logmsg(LOG_DEBUG, 1, "Closing pid file.\n"); 94 | if (close(pidfile_fd) == -1) 95 | logmsg(LOG_ERR, 1, "Error - Unable to close pid file: %m.\n"); 96 | 97 | logmsg(LOG_DEBUG, 1, "Removing pid file.\n"); 98 | if (unlink(pidfile_name) == -1) 99 | logmsg(LOG_ERR, 1, "Error - Unable to remove pid file: %m.\n"); 100 | } else logmsg(LOG_DEBUG, 1, "No pid file installed.\n"); 101 | 102 | logmsg(LOG_NOTICE, 1, "---- honeytrap stopped ----\n"); 103 | 104 | if (close(logfile_fd) == -1) logmsg(LOG_ERR, 1, "Error - Unable to close logfile: %m.\n"); 105 | 106 | exit(status); 107 | } 108 | 109 | 110 | /* switch to daemon environment and fork */ 111 | int do_daemonize(void) { 112 | int i, fd0, fd1, fd2; 113 | pid_t pid; 114 | struct rlimit rl; 115 | 116 | if (logfile_fd == STDOUT_FILENO) { 117 | fprintf(stderr, " Error - Logging to stdout is not possible while running in daemon mode.\n"); 118 | clean_exit(EXIT_SUCCESS); 119 | } 120 | 121 | DEBUG_FPRINTF(stdout, " Setting up daemon environment.\n"); 122 | 123 | umask(0); 124 | 125 | if (getrlimit(RLIMIT_NOFILE, &rl) < 0) { 126 | fprintf(stderr, " Error - Unable to daemonize: %m.\n"); 127 | exit(EXIT_FAILURE); 128 | } 129 | 130 | /* become session leader and loose controlling TTY */ 131 | if ((pid = myfork()) < 0) { 132 | fprintf(stderr, " Error - Unable to daemonize: %m.\n"); 133 | exit(EXIT_FAILURE); 134 | } else if (pid != 0) exit(EXIT_SUCCESS); 135 | 136 | setsid(); 137 | 138 | /* fork again, future opens must not allocate controlling TTYs */ 139 | if ((pid = myfork()) < 0) { 140 | fprintf(stderr, " Error - Unable to daemonize: %m.\n"); 141 | exit(EXIT_FAILURE); 142 | } else if (pid != 0) { 143 | DEBUG_FPRINTF(stdout, " Successfully changed into daemon environment.\n"); 144 | fprintf(stdout, "\nhoneytrap v%s %s\n", VERSION, COPYRIGHT_STRING); 145 | fflush(NULL); 146 | exit(EXIT_SUCCESS); 147 | } 148 | 149 | 150 | /* change working directory to root directory */ 151 | DEBUG_FPRINTF(stdout, " Current working directory is %s, changing it to /.\n", old_cwd); 152 | if (chdir("/") < 0) { 153 | fprintf(stderr, " Error - Cannot change working directory: %m.\n"); 154 | exit(EXIT_FAILURE); 155 | } 156 | 157 | 158 | /* close open file descriptors, only keep logfile and signal pipe */ 159 | if (rl.rlim_max == RLIM_INFINITY) rl.rlim_max = 1024; 160 | for (i=0; i < rl.rlim_max; i++) 161 | if ((i != logfile_fd) && (i != sigpipe[0]) && (i != sigpipe[1]) && (close(i) == -1)) 162 | fprintf(stdout, " Warnging - Could not close file descriptor %d: %m.\n", i); 163 | 164 | /* attach file descriptors 0, 1 and 2 to /dev/null to prevent accidentally standard IO */ 165 | if ((fd0 = open("/dev/null", O_RDWR)) == -1) { 166 | fprintf(stderr, " Error - Unable to set stdin to /dev/null: %m.\n"); 167 | exit(EXIT_FAILURE); 168 | } 169 | if ((fd1 = dup(fd0)) == -1) { 170 | fprintf(stderr, " Error - Unable to set stdout to /dev/null: %m.\n"); 171 | exit(EXIT_FAILURE); 172 | } 173 | if ((fd2 = dup(fd0)) == -1) { 174 | fprintf(stderr, " Error - Unable to set stderr to /dev/null: %m.\n"); 175 | exit(EXIT_FAILURE); 176 | } 177 | fflush(NULL); 178 | 179 | return(1); 180 | } 181 | 182 | 183 | /* write master process id to pid file */ 184 | int create_pid_file(void) { 185 | char pid_str[6]; 186 | 187 | if ((pidfile_fd = open(pidfile_name, O_EXCL | O_CREAT | O_NOCTTY | O_RDWR, 0640)) == -1) { 188 | logmsg(LOG_ERR, 1, "Error - Unable to open pid file: %m.\n"); 189 | exit(EXIT_SUCCESS); 190 | } 191 | if (lockf(pidfile_fd, F_TLOCK, 0) < 0) { 192 | logmsg(LOG_ERR, 1, "Error - Unable to lock pid file: %m.\n"); 193 | clean_exit(EXIT_SUCCESS); 194 | } 195 | 196 | master_pid = getpid(); 197 | 198 | bzero(pid_str, 6); 199 | snprintf(pid_str, 6,"%d", master_pid); 200 | if (write(pidfile_fd, pid_str, strlen(pid_str)) != strlen(pid_str)) { 201 | logmsg(LOG_ERR, 1, "Error - Unable to write pid file: %m.\n"); 202 | return(0); 203 | } 204 | logmsg(LOG_DEBUG, 1, "Master process pid written to %s.\n", pidfile_name); 205 | 206 | return(1); 207 | } 208 | 209 | 210 | pid_t myfork(void) { 211 | pid_t pid; 212 | 213 | /* reopen signal pipe in child process */ 214 | if ((pid = fork()) == 0) create_sigpipe(); 215 | return(pid); 216 | } 217 | -------------------------------------------------------------------------------- /src/ctrl.h: -------------------------------------------------------------------------------- 1 | /* ctrl.h 2 | * Copyright (C) 2006-2007 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HONEYTRAP_CTRL_H 14 | #define __HONEYTRAP_CTRL_H 1 15 | 16 | void usage(char *progname); 17 | void clean_exit(int status); 18 | int do_daemonize(void); 19 | int create_pid_file(void); 20 | pid_t myfork(void); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/dynsrv.h: -------------------------------------------------------------------------------- 1 | /* dynsrv.h 2 | * Copyright (C) 2005-2006 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HONEYTRAP_DYNSRV_H 14 | #define __HONEYTRAP_DYNSRV_H 1 15 | 16 | #include 17 | #ifdef USE_PCAP_MON 18 | # include 19 | #endif 20 | 21 | #include "attack.h" 22 | #include "queue.h" 23 | #include "tcpip.h" 24 | 25 | int portinfopipe[2]; // IPC pipe, used by connection handlers to 'register' ports in the master process, these are then handled in ignore mode 26 | queue *portinfoq; // queue for registered port information 27 | 28 | typedef struct { 29 | u_int16_t port; 30 | u_char protocol; 31 | int mode; 32 | // struct in_addr host; 33 | } portinfo; 34 | 35 | 36 | int drop_privileges(void); 37 | void start_dynamic_server(struct in_addr ip_r, uint16_t port_r, struct in_addr ip_l, uint16_t port_l, uint16_t proto); 38 | int handle_connection_normal(int connection_fd, uint16_t port, uint16_t proto, u_char timeout, Attack *attack); 39 | int handle_connection_proxied(int connection_fd, u_char mode, int server_sock_fd, uint16_t dport, uint16_t sport, struct in_addr ipaddr, uint16_t proto, u_char timeout, u_char fb_timeout, Attack *attack); 40 | int check_portinfopipe(void); 41 | 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/event.c: -------------------------------------------------------------------------------- 1 | /* event.c 2 | * Copyright (C) 2008 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #include "event.h" 18 | #include "honeytrap.h" 19 | #include "logging.h" 20 | 21 | event *event_enqueue(time_t time, int (*handler)(void)) { 22 | event *e, *new; 23 | 24 | // put new element in event queue 25 | if ((new = calloc(1, sizeof(event))) == NULL) { 26 | logmsg(LOG_ERR, 1, "Error - Unable to ceate event: %s.\n", strerror(errno)); 27 | exit(EXIT_FAILURE); 28 | } 29 | new->time = time; 30 | new->handler = handler; 31 | 32 | for (e = eventlist; e && e->next && time > e->next->time; e = e->next); 33 | 34 | if (e) { 35 | new->next = e->next; 36 | e->next = new; 37 | } else eventlist = new; 38 | 39 | return NULL; 40 | } 41 | 42 | event *event_dequeue(void) { 43 | event *e = eventlist; 44 | 45 | if (e == NULL) return NULL; 46 | 47 | e = eventlist; 48 | eventlist = eventlist->next; 49 | 50 | return e; 51 | } 52 | 53 | time_t event_execute(void) { 54 | if (eventlist == NULL) 55 | // event list is empty, return 1 second as new timeout 56 | return 1; 57 | 58 | event *e = event_dequeue(); 59 | 60 | if (e) { 61 | if (!e->handler()) logmsg(LOG_WARN, 1, "Warning - Event execution failed.\n"); 62 | free(e); 63 | } 64 | 65 | // set timeout to (next_event - now) seconds 66 | return eventlist ? MAX(1, eventlist->time - time(0)) : 1; 67 | } 68 | -------------------------------------------------------------------------------- /src/event.h: -------------------------------------------------------------------------------- 1 | /* event.h 2 | * Copyright (C) 2008 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HONEYTRAP_EVENT_H 14 | #define __HONEYTRAP_EVENT_H 1 15 | 16 | typedef struct event { 17 | time_t time; 18 | struct event *next; 19 | int (*handler)(void); 20 | } event; 21 | 22 | event *eventlist; 23 | 24 | event *event_enqueue(time_t time, int (*handler)(void)); 25 | event *event_dequeue(void); 26 | time_t event_execute(void); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/honeytrap.c: -------------------------------------------------------------------------------- 1 | /* honeytrap.c 2 | * Copyright (C) 2005-2015 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "connectmon.h" 24 | #include "ctrl.h" 25 | #include "dynsrv.h" 26 | #include "event.h" 27 | #include "honeytrap.h" 28 | #ifdef USE_IPQ_MON 29 | #include "ipqmon.h" 30 | #endif 31 | #include "logging.h" 32 | #ifdef USE_PCAP_MON 33 | #include "pcapmon.h" 34 | #endif 35 | #include "plughook.h" 36 | #include "plugin.h" 37 | #include "queue.h" 38 | #include "readconf.h" 39 | #include "response.h" 40 | #include "signals.h" 41 | 42 | 43 | int main(int argc, char **argv) { 44 | /* initial configuration, will be overridden by config file and command line options */ 45 | 46 | first_init = 1; 47 | running = 0; // will be set to != 0 once honeytrap set up itself 48 | 49 | /* save command line arguments */ 50 | arg_c = argc; 51 | arg_v = argv; 52 | 53 | 54 | /* the following are default values - change them in your configuration file */ 55 | 56 | daemonize = 1; // default is to daemonize 57 | 58 | #ifdef USE_PCAP_MON 59 | promisc_mode = 0; // no promisc mode 60 | pcap_offset = 0; // will be set after link type is determined 61 | #endif 62 | 63 | log_level = LOG_NOTICE; // default log level 64 | logfile_fd = STDOUT_FILENO;// default logfile, stdout will be replaced by logfile_fd 65 | 66 | u_id = 0; // root privileges per default 67 | g_id = 0; 68 | 69 | conn_timeout = 120; // 2 minutes connect timeout 70 | read_timeout = 1; // 1 second read timeout 71 | m_read_timeout = 60; // 1 minute read timeout for mirror connections 72 | read_limit = 0; // 0 means no read limit 73 | 74 | conffile_name = strdup("/etc/honeytrap/honeytrap.conf"); 75 | pidfile_name = strdup("/var/run/honeytrap.pid"); 76 | logfile_name = strdup("/var/log/honeytrap.log"); 77 | response_dir = strdup("/etc/honeytrap/responses"); 78 | plugin_dir = strdup("/etc/honeytrap/plugins"); 79 | 80 | #ifdef USE_PCAP_MON 81 | dev = NULL; // network device pointer 82 | packet_sniffer = NULL; // pcap device pointer 83 | #endif 84 | 85 | portconf_default = PORTCONF_NONE; 86 | 87 | eventlist = NULL; // list of timer-based events 88 | 89 | 90 | /* configure honeytrap */ 91 | configure(arg_c, arg_v); 92 | 93 | 94 | /* daemonize (detach from console) */ 95 | if (daemonize) do_daemonize(); 96 | 97 | 98 | /* now initialize plugins */ 99 | init_plugins(); 100 | 101 | 102 | /* create pid file */ 103 | create_pid_file(); 104 | 105 | 106 | /* create IPC pipe and queue for port infos */ 107 | if (pipe(portinfopipe) == -1) { 108 | logmsg(LOG_ERR, 0, " Error - Unable to create port info IPC pipe: %m.\n"); 109 | exit(EXIT_FAILURE); 110 | } 111 | if ((portinfoq = queue_new()) == NULL) { 112 | logmsg(LOG_ERR, 0, " Error - Unable to create port info IPC pipe: %m.\n"); 113 | exit(EXIT_FAILURE); 114 | } 115 | 116 | 117 | /* watch out for incoming connection requests */ 118 | if (start_connection_monitor() < 0) clean_exit(EXIT_SUCCESS); 119 | 120 | return(0); 121 | } 122 | -------------------------------------------------------------------------------- /src/honeytrap.h: -------------------------------------------------------------------------------- 1 | /* honeytrap.h 2 | * Copyright (C) 2005-2015 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HONEYTRAP_MAIN_H 14 | #define __HONEYTRAP_MAIN_H 1 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #if HAVE_CONFIG_H 23 | # include 24 | #endif 25 | 26 | #if defined(__GNUG__) 27 | #define MY_COMPILER "g++" 28 | #elif defined(__CYGWIN__) 29 | #define MY_COMPILER "cygwin" 30 | #else 31 | #define MY_COMPILER "unknown Compiler" 32 | #endif 33 | 34 | #if defined(__FreeBSD__) 35 | # define MY_OS "FreeBSD" 36 | #elif defined(linux) || defined (__linux) 37 | # define MY_OS "Linux" 38 | #elif defined (__MACOSX__) || defined (__APPLE__) 39 | # define MY_OS "Mac OS X" 40 | #elif defined(__NetBSD__) 41 | # define MY_OS "NetBSD" 42 | #elif defined(__OpenBSD__) 43 | # define MY_OS "OpenBSD" 44 | #elif defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) 45 | # define MY_OS "Windows" 46 | #elif defined(CYGWIN) 47 | # define MY_OS "Cygwin\Windows" 48 | #else 49 | # define MY_OS "Unknown OS" 50 | #endif 51 | 52 | #if defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA) 53 | # define MY_ARCH "Alpha" 54 | #elif defined(__arm__) 55 | # if defined(__ARMEB__) 56 | # define MY_ARCH "ARMeb" 57 | # else 58 | # define MY_ARCH "ARM" 59 | # endif 60 | #elif defined(i386) || defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_X86_) || defined(__THW_INTEL) 61 | # define MY_ARCH "x86" 62 | #elif defined(__x86_64__) || defined(__amd64__) 63 | # define MY_ARCH "x86_64" 64 | #elif defined(__ia64__) || defined(_IA64) || defined(__IA64__) || defined(_M_IA64) 65 | # define MY_ARCH "Intel Architecture-64" 66 | #elif defined(__mips__) || defined(__mips) || defined(__MIPS__) 67 | # if defined(__mips32__) || defined(__mips32) 68 | # define MY_ARCH "MIPS32" 69 | # else 70 | # define MY_ARCH "MIPS" 71 | # endif 72 | #elif defined(__hppa__) || defined(__hppa) 73 | # define MY_ARCH "PA RISC" 74 | #elif defined(__powerpc) || defined(__powerpc__) || defined(__POWERPC__) || defined(__ppc__) || defined(_M_PPC) || defined(__PPC) || defined(__PPC__) 75 | # define MY_ARCH "PowerPC" 76 | #elif defined(__THW_RS6000) || defined(_IBMR2) || defined(_POWER) || defined(_ARCH_PWR) || defined(_ARCH_PWR2) 77 | # define MY_ARCH "RS/6000" 78 | #elif defined(__sparc__) || defined(sparc) || defined(__sparc) 79 | # define MY_ARCH "SPARC" 80 | #else 81 | # define MY_ARCH "Unknown Architecture" 82 | #endif 83 | 84 | 85 | #define COPYRIGHT_STRING "Copyright (C) 2005-2015 Tillmann Werner " 86 | 87 | #ifndef MAX 88 | # define MAX(a, b) ((a)>(b)?(a):(b)) 89 | #endif 90 | #ifndef MIN 91 | # define MIN(a, b) ((a)<(b)?(a):(b)) 92 | #endif 93 | 94 | #define EXCL_FILE_RW O_CREAT | O_NOCTTY | O_APPEND | O_WRONLY 95 | 96 | #define PORTCONF_NONE 0 97 | #define PORTCONF_NORMAL 1 98 | #define PORTCONF_IGNORE 2 99 | #define PORTCONF_MIRROR 4 100 | #define PORTCONF_PROXY 8 101 | #define MODE(m) (m == PORTCONF_NONE ? "none" : (m == PORTCONF_NORMAL ? "normal" : (m == PORTCONF_IGNORE ? "ignore" : (m == PORTCONF_MIRROR ? "mirror" : (m == PORTCONF_PROXY ? "proxy" : "unknown"))))) 102 | 103 | char *conffile_name, **arg_v; 104 | int arg_c; 105 | 106 | // global variables regarding configuration 107 | 108 | char *pidfile_name; 109 | char *logfile_name; 110 | char *dev; 111 | char *response_dir; 112 | char *plugin_dir; 113 | u_char running; 114 | u_char daemonize; 115 | u_char promisc_mode; 116 | u_char replace_private_ips; 117 | uid_t u_id; 118 | gid_t g_id; 119 | int32_t conn_timeout; 120 | int32_t read_timeout; 121 | int32_t m_read_timeout; 122 | int32_t read_limit; 123 | struct in_addr bind_address; 124 | 125 | /* explicit port configurations */ 126 | u_char portconf_default; 127 | 128 | typedef struct sport_flag { 129 | u_int8_t tcp; 130 | u_int8_t udp; 131 | } port_flag; 132 | 133 | port_flag port_flags[0x10000]; 134 | 135 | // end of global config variables 136 | 137 | int pidfile_fd, first_init; 138 | char old_cwd[1024]; 139 | 140 | 141 | #endif 142 | -------------------------------------------------------------------------------- /src/ipqmon.h: -------------------------------------------------------------------------------- 1 | /* ipqmon.h 2 | * Copyright (C) 2006 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifdef USE_IPQ_MON 14 | 15 | #ifndef __HONEYTRAP_IPQMON_H 16 | #define __HONEYTRAP_IPQMON_H 1 17 | 18 | #include 19 | #include 20 | 21 | struct ipq_handle *h; 22 | ipq_packet_msg_t *packet; 23 | 24 | int start_ipq_mon(void); 25 | 26 | #endif 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/logging.c: -------------------------------------------------------------------------------- 1 | /* logging.c 2 | * Copyright (C) 2005-2007 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include "honeytrap.h" 21 | #include "logging.h" 22 | 23 | 24 | void logmsg(int level, int add_time, const char *format, ...) { 25 | char logline[LOGLINE_SIZE]; 26 | va_list ap; 27 | int bytes_written, logline_size; 28 | time_t timeval; 29 | 30 | if(level <= log_level) { 31 | bzero(&logline, LOGLINE_SIZE); 32 | va_start(ap, format); 33 | if (add_time) { 34 | time(&timeval); 35 | strftime(logline, 23, "[%F %T] ", localtime(&timeval)); 36 | if (log_level == LOG_DEBUG) 37 | snprintf(logline + strlen(logline), LOGLINE_SIZE - strlen(logline), "%5d ", getpid()); 38 | } 39 | vsnprintf(logline + strlen(logline), LOGLINE_SIZE - strlen(logline), format, ap); 40 | logline_size = strlen(logline); 41 | 42 | if ((bytes_written = write(logfile_fd, logline, logline_size)) != logline_size) 43 | perror("Error while writing logfile"); 44 | 45 | /* log to stdout as well if we are not running as daemon */ 46 | if ((STDOUT_FILENO != logfile_fd) && (daemonize != 1)) { 47 | if ((bytes_written = write(STDOUT_FILENO, logline, logline_size)) != logline_size) 48 | perror("Error while logging to stdout"); 49 | } 50 | va_end(ap); 51 | } 52 | return; 53 | } 54 | -------------------------------------------------------------------------------- /src/logging.h: -------------------------------------------------------------------------------- 1 | /* logging.h 2 | * Copyright (C) 2005-2007 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HONEYTRAP_LOGGING_H 14 | #define __HONEYTRAP_LOGGING_H 1 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | typedef enum { 21 | LL_OFF = 0, 22 | LL_ERR = 1, 23 | LL_WARN = 2, 24 | LL_NOTICE = 3, 25 | LL_INFO = 4, 26 | LL_NOISY = 5, 27 | LL_DEBUG = 6, 28 | } s_log_level; 29 | 30 | s_log_level log_level; 31 | 32 | #define LOG_OFF 0 33 | #define LOG_ERR 1 34 | #define LOG_WARN 2 35 | #define LOG_NOTICE 3 // default 36 | #define LOG_INFO 4 37 | #define LOG_NOISY 5 38 | #define LOG_DEBUG 6 39 | 40 | /* 41 | u_char log_level; 42 | */ 43 | 44 | #define LOGLINE_SIZE 4069 /* truncates longer lines */ 45 | 46 | #define DEBUG_FPRINTF if (log_level == LOG_DEBUG) fprintf 47 | 48 | int logfile_fd; 49 | char portstr[16]; 50 | 51 | void logmsg(int level, int add_time, const char * format, ...) __attribute__ ((format (printf, 3, 4))); 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/md5.h: -------------------------------------------------------------------------------- 1 | /* md5.h 2 | * Copyright (C) 2005 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | * 12 | * This code is based on an OpenSSL-compatible implementation of the RSA 13 | * Data Security, * Inc. MD5 Message-Digest Algorithm, written by Solar 14 | * Designer in 2001, and placed in the public 15 | * domain. There's absolutely no warranty. See md5.c for more information. 16 | */ 17 | 18 | #ifndef __HONEYTRAP_MD5_H 19 | #define __HONEYTRAP_MD5_H 20 | 21 | /* Any 32-bit or wider unsigned integer data type will do */ 22 | typedef unsigned long MD5_u32plus; 23 | 24 | typedef struct { 25 | MD5_u32plus lo, hi; 26 | MD5_u32plus a, b, c, d; 27 | unsigned char buffer[64]; 28 | MD5_u32plus block[16]; 29 | } MD5_CTX; 30 | 31 | extern void MD5_Init(MD5_CTX *ctx); 32 | extern void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size); 33 | extern void MD5_Final(unsigned char *result, MD5_CTX *ctx); 34 | char *mem_md5sum(u_char *msg, u_int32_t size); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/modules/Makefile.am: -------------------------------------------------------------------------------- 1 | AUTOMAKE_OPTIONS = foreign no-dependencies 2 | 3 | AM_CFLAGS=-Wall -Werror -Wno-stringop-truncation -Wno-stringop-overflow -Wno-format-overflow -fcommon 4 | 5 | AM_CPPFLAGS= -I../ 6 | 7 | SUBDIRS= 8 | 9 | libdir=$(DESTDIR)/$(sysconfdir)/honeytrap/plugins 10 | 11 | lib_LTLIBRARIES = \ 12 | htm_SaveFile.la \ 13 | htm_ftpDownload.la \ 14 | htm_httpDownload.la \ 15 | htm_tftpDownload.la \ 16 | htm_vncDownload.la \ 17 | htm_deUnicode.la \ 18 | htm_b64Decode.la 19 | 20 | if BUILD_SPAMSUM_PLUGIN 21 | lib_LTLIBRARIES += htm_SpamSum.la 22 | endif 23 | 24 | if BUILD_CPUEMU_PLUGIN 25 | lib_LTLIBRARIES += htm_cpuEmu.la 26 | endif 27 | 28 | if BUILD_CLAMAV_PLUGIN 29 | lib_LTLIBRARIES += htm_ClamAV.la 30 | endif 31 | 32 | if BUILD_SUBMIT_MWSERV_PLUGIN 33 | lib_LTLIBRARIES += htm_submitMWserv.la 34 | endif 35 | 36 | if BUILD_SUBMIT_NEBULA_PLUGIN 37 | lib_LTLIBRARIES += htm_submitNebula.la 38 | endif 39 | 40 | if BUILD_SUBMIT_POSTGRES_PLUGIN 41 | lib_LTLIBRARIES += htm_submitPostgres.la 42 | endif 43 | 44 | if BUILD_XMATCH_PLUGIN 45 | lib_LTLIBRARIES += htm_xmatch.la 46 | endif 47 | 48 | 49 | htm_SaveFile_la_SOURCES = htm_SaveFile.c htm_SaveFile.h 50 | htm_SaveFile_la_LDFLAGS = -module -no-undefined -avoid-version 51 | 52 | htm_ftpDownload_la_SOURCES = htm_ftpDownload.c htm_ftpDownload.h 53 | htm_ftpDownload_la_LDFLAGS = -module -no-undefined -avoid-version 54 | 55 | htm_httpDownload_la_SOURCES = htm_httpDownload.c htm_httpDownload.h 56 | htm_httpDownload_la_LDFLAGS = -module -no-undefined -avoid-version 57 | 58 | htm_tftpDownload_la_SOURCES = htm_tftpDownload.c htm_tftpDownload.h 59 | htm_tftpDownload_la_LDFLAGS = -module -no-undefined -avoid-version 60 | 61 | htm_vncDownload_la_SOURCES = htm_vncDownload.c htm_vncDownload.h 62 | htm_vncDownload_la_LDFLAGS = -module -no-undefined -avoid-version 63 | 64 | htm_deUnicode_la_SOURCES = htm_deUnicode.c htm_deUnicode.h 65 | htm_deUnicode_la_LDFLAGS = -module -no-undefined -avoid-version 66 | 67 | htm_b64Decode_la_SOURCES = htm_b64Decode.c htm_b64Decode.h 68 | htm_b64Decode_la_LDFLAGS = -module -no-undefined -avoid-version 69 | 70 | if BUILD_MAGICPE_PLUGIN 71 | lib_LTLIBRARIES += htm_magicPE.la 72 | htm_magicPE_la_LDFLAGS = -module -no-undefined -avoid-version -lmagic 73 | endif 74 | 75 | if BUILD_SPAMSUM_PLUGIN 76 | htm_SpamSum_la_SOURCES = htm_SpamSum.c htm_SpamSum.h 77 | htm_SpamSum_la_LDFLAGS = -module -no-undefined -avoid-version 78 | endif 79 | 80 | if BUILD_CPUEMU_PLUGIN 81 | htm_cpuEmu_la_SOURCES = htm_cpuEmu.c htm_cpuEmu.h 82 | htm_cpuEmu_la_LDFLAGS = -module -no-undefined -avoid-version -lemu 83 | endif 84 | 85 | if BUILD_CLAMAV_PLUGIN 86 | htm_ClamAV_la = htm_ClamAV.c htm_ClamAV.h 87 | htm_ClamAV_la_LDFLAGS = -module -no-undefined -avoid-version 88 | endif 89 | 90 | if BUILD_SUBMIT_MWSERV_PLUGIN 91 | htm_submitMWserv_la = htm_submitMWserv.c htm_submitMWserv.h 92 | htm_submitMWserv_la_LDFLAGS = -module -no-undefined -avoid-version -lcurl 93 | endif 94 | 95 | if BUILD_SUBMIT_NEBULA_PLUGIN 96 | htm_submitNebula_la = htm_submitNebula.c htm_submitNebula.h 97 | htm_submitNebula_la_LDFLAGS = -module -no-undefined -avoid-version -lnebula 98 | endif 99 | 100 | if BUILD_SUBMIT_POSTGRES_PLUGIN 101 | htm_submitPostgres_la = htm_submitPostgres.c htm_submitPostgres.h 102 | htm_submitPostgres_la_LDFLAGS = -module -no-undefined -avoid-version -lpq 103 | endif 104 | 105 | if BUILD_XMATCH_PLUGIN 106 | htm_xmatch_la = htm_xmatch.c 107 | htm_xmatch_la_LDFLAGS = -module -no-undefined -avoid-version -lxmatch 108 | endif 109 | 110 | if BUILD_LOGATTACKER_PLUGIN 111 | lib_LTLIBRARIES += htm_logAttacker.la 112 | htm_logAttacker_la = htm_logAttacker.c 113 | htm_logAttacker_la_LDFLAGS = -module -no-undefined -avoid-version 114 | endif 115 | 116 | if BUILD_LOGJSON_PLUGIN 117 | lib_LTLIBRARIES += htm_logJSON.la 118 | htm_logJSON_la = htm_logJSON.c 119 | htm_logJSON_la_LDFLAGS = -module -no-undefined -avoid-version -ljson-c 120 | endif 121 | 122 | 123 | if BUILD_CSPM_PLUGIN 124 | SUBDIRS += htm_cspm 125 | endif 126 | 127 | 128 | install-exec-am: 129 | $(mkinstalldirs) $(libdir) 130 | for module in `find .libs -name htm_*.so`; do \ 131 | [ -h $$module ] || $(INSTALL_DATA) "$$module" $(libdir) ; \ 132 | done 133 | -------------------------------------------------------------------------------- /src/modules/htm_ClamAV.h: -------------------------------------------------------------------------------- 1 | /* htm_ClamAV.h 2 | * Copyright (C) 2007 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HT_MODULE_CLAMAV_H 14 | #define __HT_MODULE_CLAMAV_H 1 15 | 16 | #if HAVE_CONFIG_H 17 | # include 18 | #endif 19 | 20 | void plugin_init(void); 21 | void plugin_unload(void); 22 | void plugin_register_hooks(void); 23 | void plugin_register_confopts(void); 24 | conf_node *plugin_process_confopts(conf_node *tree, conf_node *node, void *opt_data); 25 | void load_clamdb(void); 26 | int clamscan(Attack *attack); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/modules/htm_SaveFile.h: -------------------------------------------------------------------------------- 1 | /* htm_SaveFile.h 2 | * Copyright (C) 2006-2007 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HT_MODULE_SAVEFILE_H 14 | #define __HT_MODULE_SAVEFILE_H 1 15 | 16 | #if HAVE_CONFIG_H 17 | # include 18 | #endif 19 | 20 | #include 21 | 22 | void plugin_init(void); 23 | void plugin_unload(void); 24 | void plugin_register_hooks(void); 25 | conf_node *plugin_process_confopts(conf_node *tree, conf_node *node, void *opt_data); 26 | int save_to_file(Attack *attack); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/modules/htm_SpamSum.h: -------------------------------------------------------------------------------- 1 | /* htm_SpamSum.h 2 | * Copyright (C) 2006 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HT_MODULE_SPAMSUM_H 14 | #define __HT_MODULE_SPAMSUM_H 1 15 | 16 | #if HAVE_CONFIG_H 17 | # include 18 | #endif 19 | 20 | void plugin_init(void); 21 | void plugin_unload(void); 22 | void plugin_register_hooks(void); 23 | void plugin_register_confopts(void); 24 | conf_node *plugin_process_confopts(conf_node *tree, conf_node *node, void *opt_data); 25 | int calc_spamsum(Attack *attack); 26 | char *spamsum(const u_char *in, size_t length, u_int32_t bsize); 27 | static inline u_int32_t roll_hash(u_char c); 28 | static u_int32_t roll_reset(void); 29 | static inline u_int32_t sum_hash(u_char c, u_int32_t h); 30 | u_int32_t spamsum_match(const char *str1, const char *str2); 31 | u_int32_t spamsum_match_db(const char *fname, const char *sum, u_int32_t threshold); 32 | static char *eliminate_sequences(const char *str); 33 | static unsigned score_strings(const char *s1, const char *s2, u_int32_t block_size); 34 | static int has_common_substring(const char *s1, const char *s2); 35 | int edit_distn(char *from, register int from_len, char *to, register int to_len); 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/modules/htm_b64Decode.c: -------------------------------------------------------------------------------- 1 | /* htm_b64Decode.c 2 | * Copyright (C) 2006-2015 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | * 12 | * 13 | * Description: 14 | * This honeytrap module looks for base64-encoded parts in attacks, decodes 15 | * them into a new attack string and calls other plugins for it. 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include "htm_b64Decode.h" 36 | 37 | const char module_name[]="b64Decode"; 38 | const char module_version[]="1.0.1"; 39 | 40 | 41 | void plugin_config(void) { 42 | return; 43 | } 44 | 45 | void plugin_init(void) { 46 | plugin_register_hooks(); 47 | return; 48 | } 49 | 50 | void plugin_unload(void) { 51 | unhook(PPRIO_PREPROC, module_name, "b64_decode"); 52 | return; 53 | } 54 | 55 | void plugin_register_hooks(void) { 56 | logmsg(LOG_DEBUG, 1, " Plugin %s: Registering hooks.\n", module_name); 57 | add_attack_func_to_list(PPRIO_PREPROC, module_name, "b64_decode", (void *) b64_decode); 58 | 59 | return; 60 | } 61 | 62 | struct dec *decode(const char* code, u_int32_t len) { 63 | u_char ch, inbuf[3]; 64 | u_int32_t charctr, bufctr, ign, eot, i; 65 | struct dec *ret; 66 | 67 | eot = 0; 68 | ign = 0; 69 | bufctr = 0; 70 | 71 | if ((ret = (struct dec *) malloc(sizeof(struct dec))) == NULL) { 72 | logmsg(LOG_ERR, 1, "Base64 decoder error - Unable to allocate memory: %s.\n", strerror(errno)); 73 | return(NULL); 74 | } 75 | ret->len = 0; 76 | ret->str = (u_char*) malloc(len*3/4+1); 77 | bzero(ret->str, len*3/4+1); 78 | 79 | for (i=0; istr[ret->len++] = (inbuf[0] << 2) | ((inbuf[0] & 0x30) >> 4); 103 | if (charctr > 0) ret->str[ret->len++] = ((inbuf[0] & 0x0F) << 4) | ((inbuf[1] & 0x3C) >> 2); 104 | if (charctr > 1) ret->str[ret->len++] = ((inbuf[1] & 0x03) << 6) | (inbuf[2] & 0x3F); 105 | } 106 | if (eot) return(ret); 107 | } 108 | } 109 | return(ret); 110 | } 111 | 112 | int b64_decode(Attack *attack) { 113 | char *code, *astr; 114 | struct dec *decoded; 115 | Attack dec_attack; 116 | 117 | /* no data - nothing todo */ 118 | if ((attack->a_conn.payload.size == 0) || (attack->a_conn.payload.data == NULL)) { 119 | logmsg(LOG_DEBUG, 1, "Base64 decoder - No data received, nothing to decode.\n"); 120 | return(0); 121 | } 122 | 123 | logmsg(LOG_DEBUG, 1, "Base64 decoder - Searching for base64 encoded attack string.\n"); 124 | 125 | /* zero-terminate attack string */ 126 | if ((astr = (char *) malloc(attack->a_conn.payload.size+1)) == NULL) { 127 | logmsg(LOG_ERR, 1, "Error - Unable to allocate memory: %s.\n", strerror(errno)); 128 | return(-1); 129 | } 130 | bzero(astr, attack->a_conn.payload.size+1); 131 | strncpy(astr, (char *) attack->a_conn.payload.data, attack->a_conn.payload.size); 132 | 133 | /* look for characteristic strings after which base64 encoded data starts */ 134 | if (((code = (char *) strstr(astr, "Negotiate ")) != NULL) 135 | /* add additional checks here 136 | || (code = strstr(astr, "[DUMMY_STRING]")) != NULL) */ 137 | ) { 138 | /* decode base64 code */ 139 | logmsg(LOG_INFO, 1, "Base64 decoder - Encoded attack string found, trying to decode.\n"); 140 | 141 | code += 10; 142 | if ((decoded = decode((char *)code, strlen(code))) != NULL) { 143 | /* base64 decoded, creating attack structure and call other plugins */ 144 | logmsg(LOG_INFO, 1, "Calling plugins for decoded attack.\n"); 145 | 146 | bzero(&dec_attack, sizeof(Attack)); 147 | dec_attack.a_conn.payload.data = decoded->str; 148 | dec_attack.a_conn.payload.size = decoded->len; 149 | 150 | plughook_process_attack(funclist_attack_preproc, &dec_attack); 151 | plughook_process_attack(funclist_attack_analyze, &dec_attack); 152 | 153 | // assign possible downloads to the original attack, 154 | // this must happen before PPRIO_SAVE plugins are called 155 | reassign_downloads(attack, &dec_attack); 156 | 157 | // plughook_process_attack(funclist_attack_savedata, &dec_attack); 158 | plughook_process_attack(funclist_attack_postproc, &dec_attack); 159 | 160 | free(decoded->str); 161 | } 162 | } else { 163 | logmsg(LOG_DEBUG, 1, "Base64 decoder - No base64 encoded attack string found.\n"); 164 | return(0); 165 | } 166 | return(1); 167 | } 168 | -------------------------------------------------------------------------------- /src/modules/htm_b64Decode.h: -------------------------------------------------------------------------------- 1 | /* htm_b64Decode.h 2 | * Copyright (C) 2006 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HT_MODULE_B64DECODE_H 14 | #define __HT_MODULE_B64DECODE_H 1 15 | 16 | #if HAVE_CONFIG_H 17 | # include 18 | #endif 19 | 20 | struct dec { 21 | u_char *str; 22 | u_int32_t len; 23 | }; 24 | 25 | void plugin_init(void); 26 | void plugin_unload(void); 27 | void plugin_register_hooks(void); 28 | struct dec *decode(const char* code, u_int32_t len); 29 | int b64_decode(Attack *attack); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/modules/htm_cpuEmu.h: -------------------------------------------------------------------------------- 1 | /* htm_cpuEmu.h 2 | * Copyright (C) 2007 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HT_MODULE_CPUEMU_H 14 | #define __HT_MODULE_CPUEMU_H 1 15 | 16 | #if HAVE_CONFIG_H 17 | # include 18 | #endif 19 | 20 | const char module_name[]="htm_cpuEmu"; 21 | const char module_version[]="1.0.1"; 22 | 23 | static const char *config_keywords[] = { 24 | "execute_shellcode", 25 | "createprocess_cmd" 26 | }; 27 | 28 | int execute_shellcode; 29 | char *createprocess_cmd; 30 | 31 | 32 | #define CODE_OFFSET 0x417001 33 | 34 | 35 | static struct run_time_options { 36 | int verbose; 37 | int nasm_force; 38 | uint32_t steps; 39 | unsigned char *scode; 40 | uint32_t size; 41 | int offset; 42 | 43 | struct { 44 | struct { 45 | char *host; 46 | int port; 47 | } connect, bind; 48 | struct { 49 | struct emu_hashtable *commands; 50 | } commands; 51 | } override; 52 | } opts; 53 | 54 | 55 | void plugin_init(void); 56 | void plugin_unload(void); 57 | void plugin_register_hooks(void); 58 | int find_shellcode(Attack *attack); 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /src/modules/htm_cspm/Makefile.am: -------------------------------------------------------------------------------- 1 | AUTOMAKE_OPTIONS = foreign no-dependencies 2 | 3 | AM_CFLAGS=-Wall -Werror -Wno-unused 4 | 5 | #AM_LDFLAGS = -lpcre -ly -lfl 6 | AM_LDFLAGS = -lpcre 7 | 8 | AM_YFLAGS = -d 9 | 10 | AM_CPPFLAGS= -I../../ 11 | 12 | BUILT_SOURCES = signature_parser.h 13 | 14 | libdir=$(DESTDIR)/$(sysconfdir)/honeytrap/plugins 15 | 16 | lib_LTLIBRARIES = htm_cspm.la 17 | 18 | htm_cspm_la_SOURCES = htm_cspm.c htm_cspm.h 19 | htm_cspm_la_SOURCES += signature_parser.y signature_scanner.l 20 | htm_cspm_la_SOURCES += signature_parser.h 21 | htm_cspm_la_SOURCES += sc_shellcode.c sc_shellcode.h 22 | htm_cspm_la_SOURCES += sf_preproc_info.h 23 | htm_cspm_la_SOURCES += sc_action.c sc_action.h 24 | htm_cspm_la_SOURCES += sc_buffer.c sc_buffer.h 25 | htm_cspm_la_SOURCES += connectback.c connectback.h 26 | htm_cspm_la_LDFLAGS = -module -no-undefined -avoid-version 27 | 28 | 29 | install-exec-am: 30 | $(mkinstalldirs) $(libdir) 31 | for module in `find .libs -name htm_*.so`; do \ 32 | [ -h $$module ] || $(INSTALL_DATA) "$$module" $(libdir) ; \ 33 | done 34 | -------------------------------------------------------------------------------- /src/modules/htm_cspm/connectback.c: -------------------------------------------------------------------------------- 1 | /* connectback.c 2 | * Copyright (C) 2007 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | #include "attack.h" 28 | #include "connectback.h" 29 | #include "honeytrap.h" 30 | #include "sc_action.h" 31 | #include "signals.h" 32 | #include "sock.h" 33 | #include "tcpip.h" 34 | 35 | 36 | int connectback(struct sc_action* sa, int haskey) { 37 | int sockfd, t, bytes_read, total_bytes; 38 | fd_set rfds; 39 | struct timeval st; 40 | struct sockaddr_in sock; 41 | u_char buffer[BUFSIZ], *attack_string; 42 | Attack *a; 43 | 44 | if ((a = new_virtattack(*(struct in_addr*) &sa->m_localhost, *(struct in_addr*) &sa->m_action.m_connectback.m_remotehost, 45 | 0, sa->m_action.m_connectback.m_remoteport, TCP)) == NULL) { 46 | logmsg(LOG_ERR, 1, "CSPM Error - Unable to create virtual attack for connectback session.\n"); 47 | exit(EXIT_FAILURE); 48 | } 49 | 50 | /* prepare connect socket */ 51 | if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { 52 | logmsg(LOG_ERR, 1, "CSPM Error - Could not create connectback socket: %s.\n", strerror(errno)); 53 | exit(1); 54 | } 55 | bzero(&sock, sizeof(sock)); 56 | sock.sin_family = AF_INET; 57 | sock.sin_addr.s_addr = *(&sa->m_action.m_connectback.m_remotehost); 58 | sock.sin_port = htons(sa->m_action.m_connectback.m_remoteport); 59 | 60 | logmsg(LOG_NOISY, 1, "CSPM - Connecting back to %s:%u/tcp.\n", 61 | inet_ntoa(*(struct in_addr*) &sa->m_action.m_connectback.m_remotehost), sa->m_action.m_connectback.m_remoteport); 62 | if (!nb_connect(sockfd, (struct sockaddr *) &sock, sizeof(sock), 6)) { 63 | logmsg(LOG_ERR, 1, "CSPM Error - Could not connect back to %s:%d: %s.\n", 64 | inet_ntoa(*(struct in_addr *)&sa->m_action.m_connectback.m_remotehost), 65 | sa->m_action.m_connectback.m_remoteport, strerror(errno)); 66 | errno = 0; 67 | return(0); 68 | } 69 | logmsg(LOG_INFO, 1, "CSPM - Successfully connected back to %s:%d.\n", 70 | inet_ntoa(*(struct in_addr *)&sa->m_action.m_connectback.m_remotehost), 71 | sa->m_action.m_connectback.m_remoteport); 72 | 73 | /* set virtual attack infos */ 74 | a->a_conn.l_addr = sa->m_localhost; 75 | a->a_conn.r_addr = sa->m_action.m_connectback.m_remotehost; 76 | a->a_conn.r_port = sa->m_action.m_connectback.m_remoteport; 77 | a->a_conn.protocol = TCP; 78 | 79 | /* send key */ 80 | if (haskey) { 81 | logmsg(LOG_INFO, 1, "CSPM - Sending key.\n"); 82 | if (write(sockfd, &sa->m_action.m_connectback.m_key, sizeof(sa->m_action.m_connectback.m_key)) < 83 | sizeof(sa->m_action.m_connectback.m_key)) { 84 | logmsg(LOG_ERR, 1, "CSPM Error - Unable to send connectback key: %s.\n", strerror(errno)); 85 | close(sockfd); 86 | return(0); 87 | } 88 | logmsg(LOG_NOISY, 1, "CSPM - Connectback key sent.\n"); 89 | } 90 | 91 | /* read data */ 92 | for(;;) { 93 | FD_ZERO(&rfds); 94 | FD_SET(sockfd, &rfds); 95 | 96 | st.tv_sec = 10; 97 | st.tv_usec = 0; 98 | 99 | switch (t = select(MAX(sigpipe[0], sockfd), &rfds, NULL, NULL, &st)) { 100 | case -1: 101 | fprintf(stderr, "Error with select(): %s.\n", strerror(errno)); 102 | exit(1); 103 | case 0: 104 | break; 105 | default: 106 | if (FD_ISSET(sigpipe[0], &rfds) && (check_sigpipe() == -1)) { 107 | logmsg(LOG_ERR, 1, "Error - Signal handling failed in dynamic server process.\n"); 108 | exit(EXIT_FAILURE); 109 | } 110 | if (FD_ISSET(sockfd, &rfds)) { 111 | if ((bytes_read = read(sockfd, buffer, BUFSIZ)) < 0) { 112 | logmsg(LOG_ERR, 1, "CSPM - Error while reading data from connectback socket: %s.\n", 113 | strerror(errno)); 114 | close(sockfd); 115 | return(0); 116 | } 117 | if (bytes_read == 0) { 118 | logmsg(LOG_INFO, 1, "CSPM - Connectback socket closed by remote host.\n"); 119 | close(sockfd); 120 | return(1); 121 | } 122 | break; 123 | /* handle data on connection */ 124 | if ((bytes_read = read(sockfd, buffer, BUFSIZ)) > 0) { 125 | logmsg(LOG_DEBUG, 1, "CSPM - %d bytes read.\n", bytes_read); 126 | total_bytes += bytes_read; 127 | if (!(attack_string = (u_char *) realloc(attack_string, total_bytes))) { 128 | logmsg(LOG_ERR, 1, "CSPM Error - Reallocating buffer size failed: %m.\n"); 129 | exit(EXIT_FAILURE); 130 | } 131 | memcpy(attack_string + total_bytes - bytes_read, buffer, bytes_read); 132 | /* check if read limit was hit */ 133 | if (read_limit) if (total_bytes < read_limit) continue; 134 | } else if (bytes_read == 0) 135 | logmsg(LOG_NOISY, 1, "CSPM - Connectback session closed by foreign host.\n"); 136 | else 137 | logmsg(LOG_WARN, 1, "CSPM - Could not read data from connectback session: %m.\n"); 138 | 139 | 140 | /* process attack string */ 141 | if (read_limit && total_bytes >= read_limit) 142 | logmsg(LOG_WARN, 1, "CSPM Warning - Read limit (%d bytes) hit. Closing connectback session.\n", read_limit); 143 | 144 | close(sockfd); 145 | // process data 146 | return(process_data(attack_string, total_bytes, NULL, 0, a->a_conn.l_port, a)); 147 | } 148 | } 149 | } 150 | close(sockfd); 151 | 152 | 153 | return(1); 154 | } 155 | -------------------------------------------------------------------------------- /src/modules/htm_cspm/connectback.h: -------------------------------------------------------------------------------- 1 | /* connectback.h 2 | * Copyright (C) 2007 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HT_MODULE_CSPM_CONNECTBACK_H 14 | #define __HT_MODULE_CSPM_CONNECTBACK_H 1 15 | 16 | #if HAVE_CONFIG_H 17 | # include 18 | #endif 19 | 20 | #include "sc_action.h" 21 | 22 | int connectback(struct sc_action* sa, int haskey); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/modules/htm_cspm/htm_cspm.c: -------------------------------------------------------------------------------- 1 | /* htm_cspm.c 2 | * Copyright (C) 2007-2015 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | * 12 | * 13 | * Description: 14 | * This honeytrap module tries to identifies common shellcodes 15 | * by performing a pattern matching procedure originally developed 16 | * by Paul Baecher and Markus Koetter for nepenthes. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include "htm_cspm.h" 34 | #include "sc_parser.h" 35 | #include "signature_parser.h" 36 | 37 | const char module_name[]="cspm"; 38 | const char module_version[]="1.0.1"; 39 | 40 | char *sc_sigfile = NULL; 41 | 42 | static const char *config_keywords[] = { 43 | "shellcode_sigfile" 44 | }; 45 | 46 | 47 | void plugin_config(void) { 48 | register_plugin_confopts(module_name, config_keywords, sizeof(config_keywords)/sizeof(char *)); 49 | if (process_conftree(config_tree, config_tree, plugin_process_confopts, NULL) == NULL) { 50 | fprintf(stderr, " Error - Unable to process configuration tree for plugin %s.\n", module_name); 51 | exit(EXIT_FAILURE); 52 | } 53 | if (load_shellcodes() == 0) { 54 | logmsg(LOG_ERR, 1, "Error - Unable to load shellcode signatures.\n"); 55 | exit(EXIT_FAILURE); 56 | } 57 | return; 58 | } 59 | 60 | void plugin_init(void) { 61 | plugin_register_hooks(); 62 | return; 63 | } 64 | 65 | void plugin_unload(void) { 66 | unhook(PPRIO_POSTPROC, module_name, "sc_match"); 67 | return; 68 | } 69 | 70 | void plugin_register_hooks(void) { 71 | logmsg(LOG_DEBUG, 1, " Plugin %s: Registering hooks.\n", module_name); 72 | add_attack_func_to_list(PPRIO_POSTPROC, module_name, "sc_match", (void *) sc_match); 73 | 74 | return; 75 | } 76 | 77 | conf_node *plugin_process_confopts(conf_node *tree, conf_node *node, void *opt_data) { 78 | char *value = NULL; 79 | conf_node *confopt = NULL; 80 | 81 | if ((confopt = check_keyword(tree, node->keyword)) == NULL) return(NULL); 82 | 83 | while (node->val) { 84 | if ((value = malloc(node->val->size+1)) == NULL) { 85 | perror(" Error - Unable to allocate memory"); 86 | exit(EXIT_FAILURE); 87 | } 88 | memset(value, 0, node->val->size+1); 89 | memcpy(value, node->val->data, node->val->size); 90 | 91 | node->val = node->val->next; 92 | 93 | if OPT_IS("shellcode_sigfile") { 94 | sc_sigfile = value; 95 | } else { 96 | fprintf(stderr, " Error - Invalid configuration option for plugin %s: %s\n", module_name, node->keyword); 97 | exit(EXIT_FAILURE); 98 | } 99 | } 100 | return(node); 101 | } 102 | 103 | int load_shellcodes(void) { 104 | struct sc_shellcode *sc; 105 | int num_of_shellcodes = 0, load_success = 1; 106 | 107 | if ((sc = (struct sc_shellcode *) sc_parse_file(sc_sigfile)) == NULL) { 108 | logmsg(LOG_ERR, 1, "Error - Could not parse shellcodes from file %s\n", sc_sigfile); 109 | logmsg(LOG_ERR, 1, "Error %s\n", (char *) sc_get_error()); 110 | return(0); 111 | } 112 | 113 | for (sclist = sc; sc && load_success == 1; sc = sc->next, num_of_shellcodes++) 114 | if (sc->name && (prepare_sc(sc) != 0)) load_success = 0; 115 | 116 | logmsg(LOG_DEBUG, 0, " %d shellcode signatures prepared.\n", num_of_shellcodes); 117 | return(1); 118 | } 119 | 120 | int sc_match(Attack *attack) { 121 | uint32_t rhost, lhost; 122 | 123 | /* no data - nothing todo */ 124 | if (!attack->a_conn.payload.size) { 125 | logmsg(LOG_DEBUG, 1, "No data received, won't start shellcode matching.\n"); 126 | return(0); 127 | } 128 | 129 | rhost = (uint32_t) attack->a_conn.r_addr; 130 | lhost = (uint32_t) attack->a_conn.l_addr; 131 | 132 | if (eval_sc_mgr(attack->a_conn.payload.data, attack->a_conn.payload.size, 133 | rhost, attack->a_conn.r_port, 134 | lhost, attack->a_conn.l_port) == SCH_DONE) { 135 | logmsg(LOG_DEBUG, 1, "Shellcode matching is done.\n"); 136 | } 137 | 138 | return(1); 139 | } 140 | -------------------------------------------------------------------------------- /src/modules/htm_cspm/htm_cspm.h: -------------------------------------------------------------------------------- 1 | /* htm_CSPM.h 2 | * Copyright (C) 2007 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | * 12 | * 13 | * Idea taken from CSPM snort plugin by Markus Koetter and Paul Baecher 14 | */ 15 | 16 | #ifndef __HT_MODULE_CSPM_H 17 | #define __HT_MODULE_CSPM_H 1 18 | 19 | #if HAVE_CONFIG_H 20 | # include 21 | #endif 22 | 23 | #include 24 | #include 25 | 26 | 27 | enum sc_namespace { 28 | sc_xor, 29 | sc_linkxor, 30 | sc_konstanzxor, 31 | sc_leimbachxor, 32 | sc_connectbackshell, 33 | sc_connectbackfiletransfer, 34 | sc_bindshell, 35 | sc_execute, 36 | sc_download, 37 | sc_url, 38 | sc_bindfiletransfer, 39 | sc_base64, 40 | sc_alphanumericxor 41 | }; 42 | 43 | enum sc_mapping { 44 | sc_key, 45 | sc_subkey, 46 | sc_size, 47 | sc_sizeinvert, 48 | sc_port, 49 | sc_host, 50 | sc_command, 51 | sc_uri, 52 | sc_decoder, 53 | sc_pre, 54 | sc_post, 55 | sc_none, 56 | sc_hostkey, 57 | sc_portkey, 58 | sc_payload 59 | }; 60 | 61 | #define MAP_MAX 8 62 | struct sc_shellcode { 63 | pcre *compiled_pattern; 64 | 65 | char *name; 66 | char *author; 67 | char *reference; 68 | char *pattern; 69 | int pattern_size; 70 | enum sc_namespace nspace; 71 | int map_items; 72 | enum sc_mapping map[MAP_MAX]; 73 | int flags; 74 | 75 | struct sc_shellcode *next; 76 | }; 77 | 78 | typedef enum { 79 | SCH_NOTHING=0, 80 | SCH_REPROCESS, // if something was changes f.e. xor decoder 81 | SCH_REPROCESS_BUT_NOT_ME, 82 | SCH_DONE, 83 | } sch_result; 84 | 85 | int prepare_sc(struct sc_shellcode *sc); 86 | 87 | sch_result eval_sc_mgr(void *data, uint32_t size, uint32_t remotehost, uint16_t remoteport, uint32_t localhost, uint16_t localport); 88 | 89 | sch_result eval_sc (struct sc_shellcode *nsch, void **data, uint32_t *size, uint32_t remotehost, uint16_t remoteport, uint32_t localhost, uint16_t localport); 90 | sch_result eval_engine_unicode (struct sc_shellcode *nsch, void **data, uint32_t *size, uint32_t remotehost, uint16_t remoteport, uint32_t localhost, uint16_t localport); 91 | uint32_t eval_engine_unicode_unicodeLength(uint8_t *unicode, uint32_t len); 92 | uint32_t eval_engine_unicode_unicodeTryDecode(uint8_t *unicode, uint32_t len, uint8_t **decoded, uint32_t *decodedLength); 93 | sch_result eval_alphanumericxor (struct sc_shellcode *nsch, void **data, uint32_t *size, uint32_t remotehost, uint16_t remoteport, uint32_t localhost, uint16_t localport); 94 | sch_result eval_base64 (struct sc_shellcode *nsch, void **data, uint32_t *size, uint32_t remotehost, uint16_t remoteport, uint32_t localhost, uint16_t localport); 95 | sch_result eval_bindfiletransfer (struct sc_shellcode *nsch, void **data, uint32_t *size, uint32_t remotehost, uint16_t remoteport, uint32_t localhost, uint16_t localport); 96 | sch_result eval_bindshell (struct sc_shellcode *nsch, void **data, uint32_t *size, uint32_t remotehost, uint16_t remoteport, uint32_t localhost, uint16_t localport); 97 | sch_result eval_connectbackfiletransfer (struct sc_shellcode *nsch, void **data, uint32_t *size, uint32_t remotehost, uint16_t remoteport, uint32_t localhost, uint16_t localport); 98 | sch_result eval_connectbackshell (struct sc_shellcode *nsch, void **data, uint32_t *size, uint32_t remotehost, uint16_t remoteport, uint32_t localhost, uint16_t localport); 99 | sch_result eval_execute (struct sc_shellcode *nsch, void **data, uint32_t *size, uint32_t remotehost, uint16_t remoteport, uint32_t localhost, uint16_t localport); 100 | sch_result eval_konstanzxor (struct sc_shellcode *nsch, void **data, uint32_t *size, uint32_t remotehost, uint16_t remoteport, uint32_t localhost, uint16_t localport); 101 | sch_result eval_linkxor (struct sc_shellcode *nsch, void **data, uint32_t *size, uint32_t remotehost, uint16_t remoteport, uint32_t localhost, uint16_t localport); 102 | sch_result eval_url (struct sc_shellcode *nsch, void **data, uint32_t *size, uint32_t remotehost, uint16_t remoteport, uint32_t localhost, uint16_t localport); 103 | sch_result eval_xor (struct sc_shellcode *nsch, void **data, uint32_t *size, uint32_t remotehost, uint16_t remoteport, uint32_t localhost, uint16_t localport); 104 | 105 | struct sc_shellcode *sclist; 106 | 107 | void plugin_init(void); 108 | void plugin_unload(void); 109 | void plugin_register_hooks(void); 110 | conf_node *plugin_process_confopts(conf_node *tree, conf_node *node, void *opt_data); 111 | int load_shellcodes(void); 112 | int sc_match(Attack *attack); 113 | 114 | #endif 115 | -------------------------------------------------------------------------------- /src/modules/htm_cspm/sc_action.c: -------------------------------------------------------------------------------- 1 | /* $Id */ 2 | 3 | /******************************************************************************** 4 | * 5 | * Copyright (C) 2006 Paul Baecher & Markus Koetter 6 | * 7 | * This program is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU General Public License 9 | * as published by the Free Software Foundation; either version 2 10 | * of the License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 | * 21 | * 22 | * contact nepenthesdev@users.sourceforge.net 23 | * 24 | *******************************************************************************/ 25 | 26 | /* 27 | * CSPM preprocessor 28 | * Authors: Markus Koetter, Paul Baecher 29 | */ 30 | 31 | #include 32 | 33 | #include 34 | #include 35 | #include 36 | 37 | #include 38 | 39 | #include 40 | 41 | #include "sc_action.h" 42 | #include "sc_parser.h" 43 | #include "sc_buffer.h" 44 | #include "sc_shellcodes.h" 45 | #include "connectback.h" 46 | 47 | struct sc_action *sc_action_new() 48 | { 49 | struct sc_action *sa = (struct sc_action *)malloc(sizeof(struct sc_action)); 50 | memset(sa,0,sizeof(struct sc_action)); 51 | return sa; 52 | } 53 | 54 | void sc_action_free(struct sc_action *sa) 55 | { 56 | switch (sa->m_shellcode->nspace) 57 | { 58 | case sc_bindfiletransfer: 59 | case sc_bindshell: 60 | case sc_connectbackfiletransfer: 61 | case sc_connectbackshell: 62 | break; 63 | 64 | case sc_execute: 65 | if (sa->m_action.m_execute.m_command != NULL) 66 | free(sa->m_action.m_execute.m_command); 67 | 68 | break; 69 | 70 | case sc_url: 71 | if (sa->m_action.m_url.m_link != NULL) 72 | free(sa->m_action.m_url.m_link); 73 | break; 74 | 75 | default: 76 | break; 77 | } 78 | free(sa); 79 | } 80 | 81 | void sc_action_shellcode_set(struct sc_action *sa, struct sc_shellcode *sc) 82 | { 83 | sa->m_shellcode = sc; 84 | return; 85 | } 86 | void sc_action_host_set_local(struct sc_action *sa, uint32_t localhost) 87 | { 88 | sa->m_localhost = localhost; 89 | return; 90 | } 91 | 92 | void sc_action_host_set_remote(struct sc_action *sa, uint32_t remotehost) 93 | { 94 | sa->m_remotehost = remotehost; 95 | return; 96 | } 97 | 98 | void sc_action_action_set_connectback(struct sc_action *sa, uint32_t remotehost, uint16_t remoteport) 99 | { 100 | sa->m_action.m_connectback.m_remotehost = remotehost; 101 | sa->m_action.m_connectback.m_remoteport = remoteport; 102 | return; 103 | } 104 | 105 | void sc_action_action_set_bind(struct sc_action *sa, uint16_t localport) 106 | { 107 | sa->m_action.m_bind.m_localport = localport; 108 | return; 109 | } 110 | 111 | void sc_action_action_set_execute(struct sc_action *sa, const char *command) 112 | { 113 | sa->m_action.m_execute.m_command = strdup(command); 114 | return; 115 | } 116 | 117 | void sc_action_action_set_url(struct sc_action *sa, const char *url) 118 | { 119 | sa->m_action.m_url.m_link = strdup(url); 120 | return; 121 | } 122 | 123 | 124 | void sc_action_debug_print(struct sc_action *sa) 125 | { 126 | int haskey = 0; 127 | int i = 0; 128 | 129 | for (i=0; i < sa->m_shellcode->map_items; i++) { 130 | if (sa->m_shellcode->map[i] == sc_key) { 131 | haskey = 1; 132 | break; 133 | } 134 | } 135 | 136 | switch (sa->m_shellcode->nspace) { 137 | case sc_bindfiletransfer: 138 | case sc_bindshell: 139 | // logmsg(LOG_INFO, 1, "CSPM - \tsa->m_action.m_bind.m_localport = %i\n",sa->m_action.m_bind.m_localport); 140 | logmsg(LOG_DEBUG, 1, "CSPM - Preparing local port %u/tcp for bindshell.\n", sa->m_action.m_bind.m_localport); 141 | 142 | break; 143 | 144 | case sc_connectbackfiletransfer: 145 | case sc_connectbackshell: 146 | // logmsg(LOG_INFO, 1, "CSPM - \tsa->m_action.m_connectback.m_remotehost = %s\n",inet_ntoa(*(struct in_addr *)&sa->m_action.m_connectback.m_remotehost));; 147 | // printf("\tsa->m_action.m_connectback.m_remoteport = %i\n",sa->m_action.m_connectback.m_remoteport); 148 | if (haskey == 1) 149 | { 150 | /* 151 | printf("\tsa->m_action.m_connectback.m_key = 0x%02x%02x%02x%02x\n", 152 | ((unsigned char *)&sa->m_action.m_connectback.m_key)[0], 153 | ((unsigned char *)&sa->m_action.m_connectback.m_key)[1], 154 | ((unsigned char *)&sa->m_action.m_connectback.m_key)[2], 155 | ((unsigned char *)&sa->m_action.m_connectback.m_key)[4] 156 | ); 157 | */ 158 | } 159 | break; 160 | 161 | case sc_execute: 162 | // printf("\tsa->m_action.m_execute.m_command = %s\n",sa->m_action.m_execute.m_command);; 163 | break; 164 | 165 | case sc_url: 166 | // printf("\tsa->m_action.m_url.m_link = %s\n",sa->m_action.m_url.m_link);; 167 | break; 168 | 169 | default: 170 | break; 171 | } 172 | return; 173 | } 174 | 175 | 176 | 177 | void sc_action_process(struct sc_action *sa) { 178 | sc_action_debug_print(sa); 179 | 180 | int haskey = 1; 181 | 182 | BUFFER *buffer = buffer_new(); 183 | 184 | buffer_write_u8(buffer,(uint8_t)sa->m_shellcode->nspace); 185 | switch (sa->m_shellcode->nspace) { 186 | case sc_bindfiletransfer: 187 | case sc_bindshell: 188 | buffer_write_u8(buffer, sc_port); 189 | buffer_write_u16(buffer,htons((uint16_t)sa->m_action.m_bind.m_localport)); 190 | 191 | if ( haskey ) { 192 | buffer_write_u8(buffer,sc_key); 193 | buffer_write_u32(buffer,htonl((uint32_t)sa->m_action.m_bind.m_key)); 194 | } 195 | break; 196 | 197 | case sc_connectbackfiletransfer: 198 | case sc_connectbackshell: 199 | buffer_write_u8(buffer,sc_host); 200 | buffer_write_u32(buffer,htonl((uint16_t)sa->m_action.m_connectback.m_remotehost)); 201 | buffer_write_u8(buffer,sc_port); 202 | buffer_write_u16(buffer,htons((uint16_t)sa->m_action.m_connectback.m_remoteport)); 203 | if ( haskey ) 204 | { 205 | buffer_write_u8(buffer,sc_key); 206 | buffer_write_u32(buffer,htonl((uint32_t)sa->m_action.m_connectback.m_key)); 207 | } 208 | connectback(sa, haskey); 209 | break; 210 | 211 | case sc_execute: 212 | buffer_write_u8(buffer,sc_command); 213 | buffer_write_u8(buffer,strlen(sa->m_action.m_execute.m_command)); 214 | buffer_write_string(buffer,sa->m_action.m_execute.m_command); 215 | break; 216 | 217 | case sc_url: 218 | buffer_write_u8(buffer,sc_uri); 219 | buffer_write_u8(buffer,strlen(sa->m_action.m_url.m_link)); 220 | buffer_write_string(buffer,sa->m_action.m_url.m_link); 221 | break; 222 | 223 | default: 224 | break; 225 | } 226 | 227 | // int size = buffer_write_size_get(buffer); 228 | 229 | // send here 230 | 231 | buffer_free(buffer); 232 | 233 | return; 234 | } 235 | 236 | -------------------------------------------------------------------------------- /src/modules/htm_cspm/sc_action.h: -------------------------------------------------------------------------------- 1 | /* $Id */ 2 | 3 | /******************************************************************************** 4 | * 5 | * Copyright (C) 2006 Paul Baecher & Markus Koetter 6 | * 7 | * This program is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU General Public License 9 | * as published by the Free Software Foundation; either version 2 10 | * of the License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 | * 21 | * 22 | * contact nepenthesdev@users.sourceforge.net 23 | * 24 | *******************************************************************************/ 25 | 26 | /* 27 | * CSPM preprocessor 28 | * Authors: Markus Koetter, Paul Baecher 29 | * 30 | */ 31 | 32 | #ifndef HAVE_SC_ACTION_H 33 | #define HAVE_SC_ACTION_H 34 | 35 | #include "sc_shellcodes.h" 36 | 37 | struct sc_action 38 | { 39 | struct sc_shellcode *m_shellcode; 40 | 41 | union 42 | { 43 | struct 44 | { 45 | uint32_t m_remotehost; 46 | uint16_t m_remoteport; 47 | uint32_t m_key; 48 | }m_connectback; 49 | 50 | struct 51 | { 52 | uint16_t m_localport; 53 | uint32_t m_key; 54 | }m_bind; 55 | 56 | struct 57 | { 58 | char *m_command; 59 | }m_execute; 60 | 61 | struct 62 | { 63 | char *m_link; 64 | }m_url; 65 | 66 | } m_action; 67 | 68 | uint32_t m_localhost; 69 | uint32_t m_remotehost; 70 | 71 | }; 72 | 73 | struct sc_action *sc_action_new(); 74 | void sc_action_free(struct sc_action *sa); 75 | 76 | void sc_action_shellcode_set(struct sc_action *sa,struct sc_shellcode *sc); 77 | void sc_action_host_set_local(struct sc_action *sa, uint32_t localhost); 78 | void sc_action_host_set_remote(struct sc_action *sa, uint32_t remotehost); 79 | void sc_action_action_set_connectback(struct sc_action *sa, uint32_t remotehost, uint16_t remoteport); 80 | void sc_action_action_set_bind(struct sc_action *sa, uint16_t localport); 81 | void sc_action_action_set_execute(struct sc_action *sa, const char *command); 82 | void sc_action_action_set_url(struct sc_action *sa, const char *url); 83 | void sc_action_debug_print(struct sc_action *sa); 84 | 85 | void sc_action_process(struct sc_action *sa); 86 | 87 | #endif // HAVE_SC_ACTION_H 88 | -------------------------------------------------------------------------------- /src/modules/htm_cspm/sc_buffer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "sc_buffer.h" 4 | 5 | BUFFER *buffer_new() 6 | { 7 | BUFFER *buffer=malloc(sizeof(BUFFER)); 8 | memset(buffer,0,sizeof(BUFFER)); 9 | return (buffer); 10 | } 11 | 12 | void buffer_free(BUFFER *buffer) 13 | { 14 | if ( buffer->m_data != NULL ) 15 | { 16 | free(buffer->m_data); 17 | } 18 | free(buffer); 19 | } 20 | 21 | static void realloc_buffer(BUFFER *buffer,int needed) 22 | { 23 | needed=(needed+0x7f) & ~0x7f; 24 | buffer->m_data=realloc(buffer->m_data,needed); 25 | buffer->m_alloc_size=needed; 26 | } 27 | 28 | void buffer_write(BUFFER *buffer,void *data,int len) 29 | { 30 | if ( buffer->m_alloc_size < buffer->m_offset_write+len ) 31 | realloc_buffer(buffer,buffer->m_offset_write+len); 32 | memcpy(buffer->m_data+buffer->m_offset_write,data,len); 33 | buffer->m_offset_write+=len; 34 | } 35 | 36 | void buffer_write_u32(BUFFER *buffer,uint32_t data) 37 | { 38 | buffer_write(buffer,&data,sizeof(uint32_t)); 39 | } 40 | 41 | void buffer_write_u16(BUFFER *buffer,uint16_t data) 42 | { 43 | buffer_write(buffer,&data,sizeof(uint16_t)); 44 | } 45 | 46 | 47 | void buffer_write_u8(BUFFER *buffer,uint8_t data) 48 | { 49 | buffer_write(buffer,&data,sizeof(uint8_t)); 50 | } 51 | 52 | 53 | void buffer_write_string(BUFFER *buffer,const char *data) 54 | { 55 | buffer_write(buffer,(void *)data,strlen(data)); 56 | } 57 | 58 | uint32_t buffer_write_size_get(BUFFER *buffer) 59 | { 60 | return buffer->m_offset_write; 61 | } 62 | -------------------------------------------------------------------------------- /src/modules/htm_cspm/sc_buffer.h: -------------------------------------------------------------------------------- 1 | #ifndef HAVE_SC_BUFFER_H 2 | #define HAVE_SC_BUFFER_H 3 | 4 | #include 5 | 6 | typedef struct 7 | { 8 | char *m_data; 9 | uint32_t m_alloc_size; 10 | // uint32_t m_offset_read; 11 | uint32_t m_offset_write; 12 | } BUFFER; 13 | 14 | BUFFER *buffer_new(); 15 | void buffer_free(BUFFER *buffer); 16 | //static void realloc_buffer(BUFFER *buffer,int needed); 17 | void buffer_write(BUFFER *buffer,void *data,int len); 18 | void buffer_write_u32(BUFFER *buffer,uint32_t data); 19 | void buffer_write_u16(BUFFER *buffer,uint16_t data); 20 | void buffer_write_u8(BUFFER *buffer,uint8_t data); 21 | void buffer_write_string(BUFFER *buffer,const char *data); 22 | uint32_t buffer_write_size_get(BUFFER *buffer); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/modules/htm_cspm/sc_parser.h: -------------------------------------------------------------------------------- 1 | /* $Id */ 2 | 3 | /******************************************************************************** 4 | * 5 | * Copyright (C) 2006 Paul Baecher & Markus Koetter 6 | * 7 | * This program is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU General Public License 9 | * as published by the Free Software Foundation; either version 2 10 | * of the License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 | * 21 | * 22 | * contact nepenthesdev@users.sourceforge.net 23 | * 24 | *******************************************************************************/ 25 | 26 | /* 27 | * CSPM preprocessor 28 | * Authors: Markus Koetter, Paul Baecher 29 | */ 30 | 31 | #ifndef HAVE_SC_PARSER_H 32 | #define HAVE_SC_PARSER_H 33 | 34 | 35 | 36 | extern struct sc_shellcode *sc_parse_file(const char *); 37 | extern int sc_free_shellcodes(struct sc_shellcode *s); 38 | extern char *sc_get_error(); 39 | 40 | extern char *sc_get_namespace_by_numeric(int num); 41 | extern char *sc_get_mapping_by_numeric(int num); 42 | 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/modules/htm_cspm/sc_shellcodes.h: -------------------------------------------------------------------------------- 1 | /* $Id */ 2 | 3 | /******************************************************************************** 4 | * 5 | * Copyright (C) 2006 Paul Baecher & Markus Koetter 6 | * 7 | * This program is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU General Public License 9 | * as published by the Free Software Foundation; either version 2 10 | * of the License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 | * 21 | * 22 | * contact nepenthesdev@users.sourceforge.net 23 | * 24 | *******************************************************************************/ 25 | 26 | /* 27 | * CSPM preprocessor 28 | * Authors: Markus Koetter, Paul Baecher 29 | * 30 | */ 31 | 32 | 33 | #ifndef HAVE_SC_SHELLCODES_H 34 | #define HAVE_SC_SHELLCODES_H 35 | 36 | #include 37 | #include 38 | 39 | 40 | enum sc_namespace 41 | { 42 | sc_xor, 43 | sc_linkxor, 44 | sc_konstanzxor, 45 | sc_leimbachxor, 46 | sc_connectbackshell, 47 | sc_connectbackfiletransfer, 48 | sc_bindshell, 49 | sc_execute, 50 | sc_download, 51 | sc_url, 52 | sc_bindfiletransfer, 53 | sc_base64, 54 | sc_alphanumericxor 55 | 56 | }; 57 | 58 | enum sc_mapping 59 | { 60 | sc_key, 61 | sc_subkey, 62 | sc_size, 63 | sc_sizeinvert, 64 | sc_port, 65 | sc_host, 66 | sc_command, 67 | sc_uri, 68 | sc_decoder, 69 | sc_pre, 70 | sc_post, 71 | sc_none, 72 | sc_hostkey, 73 | sc_portkey, 74 | sc_payload 75 | 76 | }; 77 | 78 | #define MAP_MAX 8 79 | struct sc_shellcode 80 | { 81 | pcre *compiled_pattern; 82 | 83 | char *name; 84 | char *author; 85 | char *reference; 86 | char *pattern; 87 | int pattern_size; 88 | enum sc_namespace nspace; 89 | int map_items; 90 | enum sc_mapping map[MAP_MAX]; 91 | int flags; 92 | 93 | struct sc_shellcode *next; 94 | }; 95 | 96 | typedef enum 97 | { 98 | SCH_NOTHING=0, 99 | SCH_REPROCESS, // if something was changes f.e. xor decoder 100 | SCH_REPROCESS_BUT_NOT_ME, 101 | SCH_DONE, 102 | } sch_result; 103 | 104 | int prepare_sc(struct sc_shellcode *sc); 105 | 106 | sch_result eval_sc_mgr(void *data, uint32_t size, uint32_t remotehost, uint16_t remoteport, uint32_t localhost, uint16_t localport); 107 | 108 | sch_result eval_sc (struct sc_shellcode *nsch, void **data, uint32_t *size, uint32_t remotehost, uint16_t remoteport, uint32_t localhost, uint16_t localport); 109 | sch_result eval_engine_unicode (struct sc_shellcode *nsch, void **data, uint32_t *size, uint32_t remotehost, uint16_t remoteport, uint32_t localhost, uint16_t localport); 110 | uint32_t eval_engine_unicode_unicodeLength(uint8_t *unicode, uint32_t len); 111 | uint32_t eval_engine_unicode_unicodeTryDecode(uint8_t *unicode, uint32_t len, uint8_t **decoded, uint32_t *decodedLength); 112 | sch_result eval_alphanumericxor (struct sc_shellcode *nsch, void **data, uint32_t *size, uint32_t remotehost, uint16_t remoteport, uint32_t localhost, uint16_t localport); 113 | sch_result eval_base64 (struct sc_shellcode *nsch, void **data, uint32_t *size, uint32_t remotehost, uint16_t remoteport, uint32_t localhost, uint16_t localport); 114 | sch_result eval_bindfiletransfer (struct sc_shellcode *nsch, void **data, uint32_t *size, uint32_t remotehost, uint16_t remoteport, uint32_t localhost, uint16_t localport); 115 | sch_result eval_bindshell (struct sc_shellcode *nsch, void **data, uint32_t *size, uint32_t remotehost, uint16_t remoteport, uint32_t localhost, uint16_t localport); 116 | sch_result eval_connectbackfiletransfer (struct sc_shellcode *nsch, void **data, uint32_t *size, uint32_t remotehost, uint16_t remoteport, uint32_t localhost, uint16_t localport); 117 | sch_result eval_connectbackshell (struct sc_shellcode *nsch, void **data, uint32_t *size, uint32_t remotehost, uint16_t remoteport, uint32_t localhost, uint16_t localport); 118 | sch_result eval_execute (struct sc_shellcode *nsch, void **data, uint32_t *size, uint32_t remotehost, uint16_t remoteport, uint32_t localhost, uint16_t localport); 119 | sch_result eval_konstanzxor (struct sc_shellcode *nsch, void **data, uint32_t *size, uint32_t remotehost, uint16_t remoteport, uint32_t localhost, uint16_t localport); 120 | sch_result eval_linkxor (struct sc_shellcode *nsch, void **data, uint32_t *size, uint32_t remotehost, uint16_t remoteport, uint32_t localhost, uint16_t localport); 121 | sch_result eval_url (struct sc_shellcode *nsch, void **data, uint32_t *size, uint32_t remotehost, uint16_t remoteport, uint32_t localhost, uint16_t localport); 122 | sch_result eval_xor (struct sc_shellcode *nsch, void **data, uint32_t *size, uint32_t remotehost, uint16_t remoteport, uint32_t localhost, uint16_t localport); 123 | 124 | #endif 125 | 126 | 127 | -------------------------------------------------------------------------------- /src/modules/htm_cspm/signature_scanner.l: -------------------------------------------------------------------------------- 1 | /* $Id: signature_scanner.l 591 2006-07-21 20:00:24Z common $ */ 2 | %{ 3 | #include 4 | #include "signature_parser.h" 5 | 6 | inline void string_reset(); 7 | inline char *string_get_buffer(); 8 | inline int string_get_len(); 9 | int line_number = 1; 10 | 11 | static inline void string_append(char *, int); 12 | static char *string_buffer = NULL; 13 | static int string_len = 0; 14 | static int string_cap = 0; 15 | 16 | %} 17 | 18 | LETTER [a-zA-Z] 19 | DIGIT [0-9] 20 | DELIM " "|"\t"|"\r" 21 | NEWLINE "\n" 22 | 23 | %x comment string 24 | 25 | %% 26 | 27 | 28 | "(" { return SC_LPAR; } 29 | ")" { return SC_RPAR; } 30 | "{" { return SC_LBR; } 31 | "}" { return SC_RBR; } 32 | 33 | ";" { return SC_SEMI; } 34 | ":" { return SC_COLON; } 35 | "," { return SC_COMMA; } 36 | 37 | "pattern" { return SC_PATTERN; } 38 | "type" { return SC_TYPE; } 39 | "mapping" { return SC_MAPPING; } 40 | "flags" { return SC_FLAGS; } 41 | 42 | "none" { return SC_NONE; } 43 | 44 | "xor" { return SC_XOR; } 45 | "linkxor" { return SC_LINKXOR; } 46 | "konstanzxor" { return SC_KONSTANZXOR; } 47 | "leimbachxor" { return SC_LEIMBACHXOR; } 48 | "bindshell" { return SC_BIND_SHELL; } 49 | "connectbackshell" { return SC_CONNECTBACK_SHELL; } 50 | "connectbackfiletransfer" { return SC_CONNECTBACK_FILETRANSFER; } 51 | "execute" { return SC_EXECUTE; } 52 | "download" { return SC_DOWNLOAD; } 53 | "url" { return SC_URL; } 54 | "bindfiletransfer" { return SC_BIND_FILETRANSFER; } 55 | "base64" { return SC_BASE64; } 56 | "alphanumericxor" { return SC_ALPHANUMERICXOR; } 57 | 58 | "hostkey" { return SC_HOSTKEY; } 59 | "portkey" { return SC_PORTKEY; } 60 | 61 | "subkey" { return SC_SUBKEY; } 62 | "key" { return SC_KEY; } 63 | "size" { return SC_SIZE; } 64 | "sizeinvert" { return SC_SIZEINVERT; } 65 | "host" { return SC_HOST; } 66 | "port" { return SC_PORT; } 67 | "command" { return SC_COMMAND; } 68 | "uri" { return SC_URI; } 69 | "decoder" { return SC_DECODER; } 70 | "pre" { return SC_PRELOAD; } 71 | "post" { return SC_POSTLOAD; } 72 | "payload" { return SC_PAYLOAD; } 73 | 74 | 75 | {LETTER}({LETTER}|{DIGIT}|"_")* { string_append(yytext, yyleng); return SC_ID; } 76 | 77 | 78 | "/*" { BEGIN(comment); } 79 | [^*\n]* { } 80 | "*"+"/" { BEGIN(INITIAL); } 81 | "*"* { } 82 | "\n" { line_number++; } 83 | 84 | "\"" { BEGIN(string); } 85 | "\"" { BEGIN(INITIAL); return SC_STRING; } 86 | "\\n" { string_append("\n", 1); } 87 | "\\r" { string_append("\r", 1); } 88 | "\\t" { string_append("\t", 1); } 89 | "\\\"" { string_append("\"", 1); } 90 | "\\0" { string_append("\0", 1); } 91 | "\\\\" { string_append("\\", 1); } 92 | "\\x"[0-9a-fA-F]{2} { 93 | char hexval[] = {'0', 'x', *(yytext + 2), *(yytext + 3), '\0'}; 94 | unsigned int c; 95 | 96 | sscanf(hexval, "%x", &c); 97 | string_append((char *)&c, 1); 98 | } 99 | [^\"\\]* { string_append(yytext, yyleng); } 100 | "\\" { } 101 | 102 | "//"[^\n]* { } 103 | 104 | {DELIM}* { } 105 | {NEWLINE} { line_number++; } 106 | 107 | . { /* catch all */ } 108 | 109 | %% 110 | 111 | void string_append(char *s, int len) 112 | { 113 | while( string_len + len > string_cap ) 114 | { 115 | if( string_cap == 0 ) 116 | string_cap = 0x10; 117 | else 118 | string_cap *= 2; 119 | 120 | string_buffer = realloc(string_buffer, string_cap); 121 | } 122 | 123 | memcpy(string_buffer + string_len, s, len); 124 | string_len += len; 125 | } 126 | 127 | char *string_get_buffer() 128 | { 129 | return string_buffer; 130 | } 131 | 132 | int string_get_len() 133 | { 134 | return string_len; 135 | } 136 | 137 | void string_reset() 138 | { 139 | string_len = 0; 140 | } 141 | -------------------------------------------------------------------------------- /src/modules/htm_deUnicode.c: -------------------------------------------------------------------------------- 1 | /* htm_deUnicode.c 2 | * Copyright (C) 2009-2015 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | * 12 | * 13 | * Description: 14 | * This honeytrap module performs a simple heuristic test for uniocde attack strings, 15 | * decodes them into a new attack string and calls other plugins for it. 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include "htm_deUnicode.h" 30 | 31 | const char module_name[]="deUnicode"; 32 | const char module_version[]="1.0.1"; 33 | 34 | void plugin_config(void) { 35 | return; 36 | } 37 | 38 | void plugin_init(void) { 39 | plugin_register_hooks(); 40 | return; 41 | } 42 | 43 | void plugin_unload(void) { 44 | unhook(PPRIO_PREPROC, module_name, "deunicode"); 45 | return; 46 | } 47 | 48 | void plugin_register_hooks(void) { 49 | logmsg(LOG_DEBUG, 1, " Plugin %s: Registering hooks.\n", module_name); 50 | add_attack_func_to_list(PPRIO_PREPROC, module_name, "deunicode", (void *) deunicode); 51 | 52 | return; 53 | } 54 | 55 | int deunicode(Attack *attack) { 56 | Attack *dec_attack; 57 | u_char offset; 58 | size_t i, bytecnt[256], offcheck[256], data_len; 59 | 60 | 61 | // no data - nothing todo 62 | if ((attack->a_conn.payload.size == 0) || (attack->a_conn.payload.data == NULL)) { 63 | logmsg(LOG_DEBUG, 1, "deUnicode - No data received, nothing to decode.\n"); 64 | return(0); 65 | } 66 | 67 | memset(bytecnt, 0, 256 * sizeof(size_t)); 68 | memset(offcheck, 0, 256 * sizeof(size_t)); 69 | 70 | for (i = 0; i < attack->a_conn.payload.size; ++i) { 71 | bytecnt[attack->a_conn.payload.data[i]]++; 72 | if (i%2) offcheck[attack->a_conn.payload.data[i]]++; 73 | } 74 | 75 | if (bytecnt[0] * 3 > attack->a_conn.payload.size) { 76 | logmsg(LOG_NOISY, 1, "deUnicode - Attack string seems to contain unicode encoded data, decoding it.\n"); 77 | 78 | // if the array for every second byte, starting with 1, contains at least half of all 0-bytes, 79 | // we're correctly aligned, otherwise we have to use an offset of 1 80 | offset = offcheck[0] * 2 > bytecnt[0] ? 0 : 1; 81 | 82 | // half the size (+1) of the original attack string is sufficient as we skip every second byte 83 | data_len = attack->a_conn.payload.size >> 1; 84 | if ((attack->a_conn.payload.size % 2 == 1) && (offset == 0)) data_len++; 85 | 86 | if (((dec_attack = calloc(1, sizeof(Attack))) == NULL) || 87 | ((dec_attack->a_conn.payload.data = calloc(1, data_len)) == NULL)) { 88 | logmsg(LOG_ERR, 1, "deUnicode error - Unable to allocate memory: %s.\n", strerror(errno)); 89 | return -1; 90 | } 91 | dec_attack->virtual = 1; 92 | dec_attack->a_conn.payload.size = data_len; 93 | 94 | for (i=0; i+offset < attack->a_conn.payload.size; i+=2) 95 | dec_attack->a_conn.payload.data[i>>1] = attack->a_conn.payload.data[i+offset]; 96 | 97 | logmsg(LOG_NOISY, 1, "deUnicode - Processing decoded attack.\n"); 98 | 99 | plughook_process_attack(funclist_attack_preproc, dec_attack); 100 | plughook_process_attack(funclist_attack_analyze, dec_attack); 101 | 102 | // assign possible downloads to the original attack, 103 | // this must happen before PPRIO_SAVE plugins are called 104 | reassign_downloads(attack, dec_attack); 105 | 106 | // plughook_process_attack(funclist_attack_savedata, dec_attack); 107 | plughook_process_attack(funclist_attack_postproc, dec_attack); 108 | 109 | del_attack(dec_attack); 110 | } else { 111 | logmsg(LOG_DEBUG, 1, "deUnicode - Attack string does not seem to be in unicode.\n"); 112 | return 0; 113 | } 114 | return 1; 115 | } 116 | -------------------------------------------------------------------------------- /src/modules/htm_deUnicode.h: -------------------------------------------------------------------------------- 1 | /* htm_deUnicode.h 2 | * Copyright (C) 2009 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HT_MODULE_DEUNICODE_H 14 | #define __HT_MODULE_DEUNICODE_H 1 15 | 16 | #if HAVE_CONFIG_H 17 | # include 18 | #endif 19 | 20 | void plugin_init(void); 21 | void plugin_unload(void); 22 | void plugin_register_hooks(void); 23 | 24 | int deunicode(Attack *attack); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/modules/htm_ftpDownload.h: -------------------------------------------------------------------------------- 1 | /* htm_ftpDownload.h 2 | * Copyright (C) 2006-2007 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HT_MODULE_FTPDOWNLOAD_H 14 | #define __HT_MODULE_FTPDOWNLOAD_H 1 15 | 16 | #if HAVE_CONFIG_H 17 | # include 18 | #endif 19 | 20 | void plugin_init(void); 21 | void plugin_unload(void); 22 | void plugin_register_hooks(void); 23 | void plugin_register_confopts(void); 24 | int cmd_parse_for_ftp(Attack *attack); 25 | int read_ftp_line(int control_sock_fd, char *rline, ssize_t len, int timeout); 26 | int ftp_quit(int control_sock_fd, int data_sock_fd); 27 | int get_ftp_resource(const char *user, const char* pass, struct in_addr *lhost, struct in_addr *rhost, const int port, const char *save_file, Attack *attack); 28 | int get_ftpcmd(char *attack_string, uint32_t string_size, struct in_addr lhost, Attack *attack); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/modules/htm_httpDownload.h: -------------------------------------------------------------------------------- 1 | /* htm_httpDownload.h 2 | * Copyright (C) 2007 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HT_MODULE_HTTPDOWNLOAD_H 14 | #define __HT_MODULE_HTTPDOWNLOAD_H 1 15 | 16 | #if HAVE_CONFIG_H 17 | # include 18 | #endif 19 | 20 | void plugin_init(void); 21 | void plugin_unload(void); 22 | void plugin_register_hooks(void); 23 | void plugin_register_confopts(void); 24 | conf_node *plugin_process_confopts(conf_node *tree, conf_node *node, void *opt_data); 25 | int cmd_parse_for_http_url(Attack *attack); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/modules/htm_logAttacker.c: -------------------------------------------------------------------------------- 1 | /* htm_logAttacker.c 2 | * Copyright (C) 2011-2015 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | * 12 | * 13 | * Description: 14 | * This module assumes that an input is xor-encoded and performs a 15 | * matching of known patterns in order to extract the key and decode the 16 | * data. Decoded attack strings are then further processed as virtual 17 | * attacks. An example application is getting URLs from self-modifying 18 | * shellcode without having to run any kind of emulation. 19 | */ 20 | 21 | #if HAVE_CONFIG_H 22 | # include 23 | #endif 24 | 25 | #define _GNU_SOURCE 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | 42 | const char module_name[]="logattacker"; 43 | const char module_version[]="1.0.2"; 44 | 45 | static const char *config_keywords[] = { 46 | "logfile", 47 | }; 48 | 49 | const char *logfile; 50 | FILE *f; 51 | 52 | 53 | int logattacker(Attack *a) { 54 | struct tm *tm; 55 | struct timeval tv; 56 | char tstr[20]; 57 | char shost[16], dhost[16]; 58 | struct protoent *pent; 59 | 60 | if (a->virtual) return 0; // do not log virtual attacks 61 | 62 | 63 | logmsg(LOG_DEBUG, 1, "logAttacker: logging attacker information\n"); 64 | 65 | if (gettimeofday(&tv, NULL) == -1) { 66 | logmsg(LOG_ERR, 1, "logAttacker error - Could not get system time.\n"); 67 | return -1; 68 | } 69 | 70 | tm = gmtime(&tv.tv_sec); 71 | if (strftime(tstr, 20, "%F %H:%M:%S", tm) == 0) { 72 | logmsg(LOG_ERR, 1, "logAttacker error - Unable to create time stamp.\n"); 73 | return -1; 74 | } 75 | 76 | if ((inet_ntop(AF_INET, &a->a_conn.r_addr, shost, 16) == NULL) || 77 | (inet_ntop(AF_INET, &a->a_conn.l_addr, dhost, 16) == NULL)) { 78 | logmsg(LOG_ERR, 1, "logAttacker error - Unable to convert IP address into string.\n"); 79 | return -1; 80 | } 81 | 82 | if ((pent = getprotobynumber(a->a_conn.protocol)) == NULL) { 83 | logmsg(LOG_ERR, 1, "logAttacker error - Unable to determine name for protocol %d.\n", a->a_conn.protocol); 84 | return -1; 85 | } 86 | 87 | if (fprintf(f, "[%s:%lu GMT] %s %s:%d -> %s:%d %s %s (%u bytes)\n", 88 | tstr, tv.tv_usec, pent->p_name, shost, a->a_conn.r_port, dhost, a->a_conn.l_port, a->a_conn.payload.md5sum, a->a_conn.payload.sha512sum, a->a_conn.payload.size) < 0) { 89 | logmsg(LOG_ERR, 1, "logAttacker error - Could not write to log file: %s.\n", strerror(errno)); 90 | return -1; 91 | } 92 | 93 | return 0; 94 | } 95 | 96 | conf_node *plugin_process_confopts(conf_node *tree, conf_node *node, void *opt_data) { 97 | char *value = NULL; 98 | conf_node *confopt = NULL; 99 | 100 | if ((confopt = check_keyword(tree, node->keyword)) == NULL) return(NULL); 101 | 102 | while (node->val) { 103 | if ((value = malloc(node->val->size+1)) == NULL) { 104 | perror(" Error - Unable to allocate memory"); 105 | exit(EXIT_FAILURE); 106 | } 107 | memset(value, 0, node->val->size+1); 108 | memcpy(value, node->val->data, node->val->size); 109 | 110 | node->val = node->val->next; 111 | 112 | if OPT_IS("logfile") { 113 | logfile = value; 114 | } else { 115 | fprintf(stderr, " Error - Invalid configuration option for plugin %s: %s\n", module_name, node->keyword); 116 | exit(EXIT_FAILURE); 117 | } 118 | } 119 | return(node); 120 | } 121 | 122 | void plugin_register_hooks(void) { 123 | logmsg(LOG_DEBUG, 1, " Plugin %s: Registering hooks.\n", module_name); 124 | add_attack_func_to_list(PPRIO_PREPROC, module_name, "logattacker", (void *) logattacker); 125 | 126 | return; 127 | } 128 | 129 | void plugin_config(void) { 130 | register_plugin_confopts(module_name, config_keywords, sizeof(config_keywords)/sizeof(char *)); 131 | if (process_conftree(config_tree, config_tree, plugin_process_confopts, NULL) == NULL) { 132 | fprintf(stderr, " Error - Unable to process configuration tree for plugin %s.\n", module_name); 133 | exit(EXIT_FAILURE); 134 | } 135 | return; 136 | } 137 | 138 | void plugin_init(void) { 139 | mode_t prevmode; 140 | 141 | // open log file 142 | logmsg(LOG_DEBUG, 1, " Plugin %s: Opening log file %s.\n", module_name, logfile); 143 | 144 | prevmode = umask(S_IWGRP | S_IWOTH); 145 | if ((f = fopen(logfile, "a")) == NULL) { 146 | fprintf(stderr, " Error - Unable to open attacker log file: %s.\n", strerror(errno)); 147 | exit(EXIT_FAILURE); 148 | } 149 | umask(prevmode); 150 | 151 | plugin_register_hooks(); 152 | 153 | return; 154 | } 155 | 156 | void plugin_unload(void) { 157 | unhook(PPRIO_PREPROC, module_name, "logattacker"); 158 | 159 | // close log file 160 | fclose(f); 161 | 162 | return; 163 | } 164 | -------------------------------------------------------------------------------- /src/modules/htm_magicPE.c: -------------------------------------------------------------------------------- 1 | /* htm_magicPE.c 2 | * Copyright (C) 2008-2015 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | * 12 | * 13 | * Description: 14 | * This module handles an attack string as download if its 15 | * file(1) signature sais it's a portable executable. 16 | * This is useful for malware submission. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include "htm_magicPE.h" 31 | 32 | const char module_name[]="magicPE"; 33 | const char module_version[]="1.0.1"; 34 | 35 | magic_t magicdb; 36 | 37 | 38 | void plugin_config(void) { 39 | return; 40 | } 41 | 42 | void plugin_init(void) { 43 | if (((magicdb = magic_open( MAGIC_NO_CHECK_APPTYPE | 44 | MAGIC_NO_CHECK_ASCII | 45 | MAGIC_NO_CHECK_ELF | 46 | MAGIC_NO_CHECK_FORTRAN | 47 | MAGIC_NO_CHECK_TROFF)) 48 | == NULL) || (magic_load(magicdb, NULL) == -1)) { 49 | fprintf(stderr, " Error - Unable to open magic database: %s.\n", magic_error(magicdb)); 50 | exit(EXIT_FAILURE); 51 | } 52 | 53 | plugin_register_hooks(); 54 | 55 | return; 56 | } 57 | 58 | void plugin_unload(void) { 59 | unhook(PPRIO_ANALYZE, module_name, "check_magic_string"); 60 | magic_close(magicdb); 61 | return; 62 | } 63 | 64 | void plugin_register_hooks(void) { 65 | logmsg(LOG_DEBUG, 1, " Plugin %s: Registering hooks.\n", module_name); 66 | add_attack_func_to_list(PPRIO_ANALYZE, module_name, "check_magic_string", (void *) check_magic_string); 67 | 68 | return; 69 | } 70 | 71 | int check_magic_string(Attack *attack) { 72 | const char *type = magic_buffer(magicdb, attack->a_conn.payload.data, attack->a_conn.payload.size); 73 | 74 | // check if it contains "MS-DOS executable" and if so, handle it as download 75 | if (strstr(type, "MS-DOS executable") != NULL) { 76 | logmsg(LOG_INFO, 1, "magicPE - Treating attack as malware because of type '%s'\n", type); 77 | add_download("raw", 78 | attack->a_conn.protocol, 79 | attack->a_conn.r_addr, 80 | attack->a_conn.r_port, 81 | NULL, NULL, NULL, NULL, 82 | attack->a_conn.payload.data, 83 | attack->a_conn.payload.size, 84 | attack); 85 | 86 | logmsg(LOG_NOTICE, 1, "magicPE - Attack string attached as download to attack record.\n"); 87 | } 88 | 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /src/modules/htm_magicPE.h: -------------------------------------------------------------------------------- 1 | /* htm_magicPE.h 2 | * Copyright (C) 2008 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HT_MODULE_MAGICPE_H 14 | #define __HT_MODULE_MAGICPRE_H 1 15 | 16 | #if HAVE_CONFIG_H 17 | # include 18 | #endif 19 | 20 | void plugin_init(void); 21 | void plugin_unload(void); 22 | void plugin_register_hooks(void); 23 | int check_magic_string(Attack *attack); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /src/modules/htm_submitMWserv.h: -------------------------------------------------------------------------------- 1 | /* htm_submitMWserv.h 2 | * Copyright (C) 2007 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HT_MODULE_SUBMITMWSERV_H 14 | #define __HT_MODULE_SUBMITMWSERV_H 1 15 | 16 | #if HAVE_CONFIG_H 17 | # include 18 | #endif 19 | 20 | void plugin_init(void); 21 | void plugin_unload(void); 22 | void plugin_register_hooks(void); 23 | conf_node *plugin_process_confopts(conf_node *tree, conf_node *node, void *opt_data); 24 | int submit_mwserv(Attack *attack); 25 | int send_heartbeat(void); 26 | 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/modules/htm_submitNebula.c: -------------------------------------------------------------------------------- 1 | /* htm_submitNebula.c 2 | * Copyright (C) 2008-2015 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | * 12 | * 13 | * Description: 14 | * This honeytrap module submits attacks to a nebula server. 15 | */ 16 | 17 | #define _GNU_SOURCE 1 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #include "htm_submitNebula.h" 44 | 45 | 46 | const char module_name[]="submitNebula"; 47 | const char module_version[]="1.0.1"; 48 | 49 | static const char *config_keywords[] = { 50 | "host", 51 | "port", 52 | "secret" 53 | }; 54 | 55 | nebula *n; 56 | 57 | 58 | void plugin_config(void) { 59 | register_plugin_confopts(module_name, config_keywords, sizeof(config_keywords)/sizeof(char *)); 60 | if (process_conftree(config_tree, config_tree, plugin_process_confopts, NULL) == NULL) { 61 | fprintf(stderr, " Error - Unable to process configuration tree for plugin %s.\n", module_name); 62 | exit(EXIT_FAILURE); 63 | } 64 | return; 65 | } 66 | 67 | void plugin_init(void) { 68 | if ((n = nebula_new()) == NULL) { 69 | fprintf(stderr, "Error - Unable to initialize nebula handle: %s.\n", strerror(errno)); 70 | exit(EXIT_FAILURE); 71 | } 72 | 73 | if (nebula_init(n) == 0) { 74 | fprintf(stderr, " Error - Could not initialize nebula instance: %s.\n", nebula_strerr(n)); 75 | exit(EXIT_FAILURE); 76 | } 77 | 78 | plugin_register_hooks(); 79 | 80 | return; 81 | } 82 | 83 | void plugin_unload(void) { 84 | nebula_cleanup(n); 85 | unhook(PPRIO_SAVEDATA, module_name, "submit_nebula"); 86 | return; 87 | } 88 | 89 | void plugin_register_hooks(void) { 90 | logmsg(LOG_DEBUG, 1, " Plugin %s: Registering hooks.\n", module_name); 91 | add_attack_func_to_list(PPRIO_SAVEDATA, module_name, "submit_nebula", (void *) submit_nebula); 92 | 93 | return; 94 | } 95 | 96 | conf_node *plugin_process_confopts(conf_node *tree, conf_node *node, void *opt_data) { 97 | char *value = NULL; 98 | conf_node *confopt = NULL; 99 | 100 | if ((confopt = check_keyword(tree, node->keyword)) == NULL) return(NULL); 101 | 102 | while (node->val) { 103 | if ((value = malloc(node->val->size+1)) == NULL) { 104 | perror(" Error - Unable to allocate memory"); 105 | exit(EXIT_FAILURE); 106 | } 107 | memset(value, 0, node->val->size+1); 108 | memcpy(value, node->val->data, node->val->size); 109 | 110 | node->val = node->val->next; 111 | 112 | if OPT_IS("host") { 113 | struct hostent *host; 114 | 115 | if ((host = gethostbyname(value)) == NULL) { 116 | fprintf(stderr, " Error - Unable to resolve %s: %s.\n", value, strerror(errno)); 117 | exit(EXIT_FAILURE); 118 | } 119 | n->server.sin_addr = *(struct in_addr*)host->h_addr; 120 | } else if OPT_IS("port") { 121 | if (value) n->server.sin_port = htons((u_int16_t) strtoull(value, NULL, 10)); 122 | } else if OPT_IS("secret") { 123 | if ((n->secret = strdup(value)) == NULL) { 124 | fprintf(stderr, " Error - Unable to allocate memory: %s.\n", nebula_strerr(n)); 125 | exit(EXIT_FAILURE); 126 | } 127 | } else { 128 | fprintf(stderr, " Error - Invalid configuration option for plugin %s: %s\n", module_name, node->keyword); 129 | exit(EXIT_FAILURE); 130 | } 131 | } 132 | return(node); 133 | } 134 | 135 | 136 | // submit attack to a Nebula server 137 | int submit_nebula(Attack *attack) { 138 | // no data - nothing to do 139 | if ((attack->a_conn.payload.size == 0) || (attack->a_conn.payload.data == NULL)) { 140 | logmsg(LOG_DEBUG, 1, "SubmitNebula - No data received.\n"); 141 | return(0); 142 | } 143 | 144 | logmsg(LOG_INFO, 1, "SubmitNebula - Submittint attack to nebula server.\n"); 145 | 146 | // connect to nebula server and submit attack 147 | if (nebula_connect(n, n->server.sin_addr, ntohs(n->server.sin_port), 0) == 0) { 148 | logmsg(LOG_ERR, 1, "SubmitNebula Error - Could not connect to nebula server: %s.\n", nebula_strerr(n)); 149 | exit(EXIT_FAILURE); 150 | } 151 | if (nebula_send(n, attack->a_conn.protocol, attack->a_conn.l_port, attack->a_conn.payload.data, attack->a_conn.payload.size) == 0) 152 | logmsg(LOG_ERR, 1, "SubmitNebula Error - File submission failed: %s.\n", nebula_strerr(n)); 153 | if (nebula_disconnect(n) == 0) 154 | logmsg(LOG_ERR, 1, "SubmitNebula Error - Could not disconnect from nebula server: %s.\n", nebula_strerr(n)); 155 | 156 | logmsg(LOG_NOISY, 1, "SubmitNebula - Submission complete.\n"); 157 | 158 | return 0; 159 | } 160 | -------------------------------------------------------------------------------- /src/modules/htm_submitNebula.h: -------------------------------------------------------------------------------- 1 | /* htm_submitNebula.h 2 | * Copyright (C) 2008 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HT_MODULE_SUBMIT_NEBULA_H 14 | #define __HT_MODULE_SUBMIT_NEBULA_H 1 15 | 16 | #if HAVE_CONFIG_H 17 | # include 18 | #endif 19 | 20 | #include 21 | 22 | void plugin_init(void); 23 | void plugin_unload(void); 24 | void plugin_register_hooks(void); 25 | conf_node *plugin_process_confopts(conf_node *tree, conf_node *node, void *opt_data); 26 | int submit_nebula(Attack *attack); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/modules/htm_submitPostgres.h: -------------------------------------------------------------------------------- 1 | /* htm_SavePostgres.h 2 | * Copyright (C) 2007 Tillman Werner , 3 | * Christoph Fuchs 4 | * 5 | * This file is free software; as a special exception the author gives 6 | * unlimited permission to copy and/or distribute it, with or without 7 | * modifications, as long as this notice is preserved. 8 | * 9 | * This program is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 11 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | */ 13 | 14 | #ifndef __HT_MODULE_SAVEPOSTGRES_H 15 | #define __HT_MODULE_SAVEPOSTGRES_H 1 16 | 17 | #if HAVE_CONFIG_H 18 | # include 19 | #endif 20 | 21 | #include 22 | #include 23 | 24 | void plugin_init(void); 25 | void plugin_unload(void); 26 | void plugin_register_hooks(void); 27 | conf_node *plugin_process_confopts(conf_node *tree, conf_node *node, void *opt_data); 28 | 29 | int db_submit(Attack *attack); 30 | int db_connect(void); 31 | void db_disconnect(void); 32 | char *build_url(struct s_download *download); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/modules/htm_tftpDownload.h: -------------------------------------------------------------------------------- 1 | /* htm_tftpDownload.h 2 | * Copyright (C) 2006 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HT_MODULE_TFTPDOWNLOAD_H 14 | #define __HT_MODULE_TFTPDOWNLOAD_H 1 15 | 16 | #if HAVE_CONFIG_H 17 | # include 18 | #endif 19 | 20 | void plugin_init(void); 21 | void plugin_unload(void); 22 | void plugin_register_hooks(void); 23 | int cmd_parse_for_tftp(Attack *attack); 24 | int get_tftpcmd(char *attack_string, int string_size, Attack *attack); 25 | int tftp_quit(int data_sock_fd); 26 | int get_tftp_resource(struct in_addr* host, const char *save_file, Attack *attack); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/modules/htm_vncDownload.c: -------------------------------------------------------------------------------- 1 | /* htm_vncDownload.c 2 | * Copyright (C) 2006-2015 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | * 12 | * 13 | * Description: 14 | * This honeytrap module invokes wget (or other external tools) to perform 15 | * http downloads triggerd by a VNC server exploit. 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include "htm_vncDownload.h" 29 | 30 | const char module_name[]="vncDownload"; 31 | const char module_version[] = "1.0.1"; 32 | 33 | 34 | void plugin_config(void) { 35 | return; 36 | } 37 | 38 | void plugin_init(void) { 39 | plugin_register_hooks(); 40 | return; 41 | } 42 | 43 | void plugin_unload(void) { 44 | unhook(PPRIO_ANALYZE, module_name, "cmd_parse_for_vnc"); 45 | return; 46 | } 47 | 48 | void plugin_register_hooks(void) { 49 | logmsg(LOG_DEBUG, 1, " Plugin %s: Registering hooks.\n", module_name); 50 | add_attack_func_to_list(PPRIO_ANALYZE, module_name, "cmd_parse_for_vnc", (void *) cmd_parse_for_vnc); 51 | 52 | return; 53 | } 54 | 55 | int cmd_parse_for_vnc(Attack *attack) { 56 | int i=0, len = 0; 57 | char vnc_str[] = "RFB 003.008"; 58 | char *readable_chars = NULL, *clean_str = NULL, *curchar = NULL; 59 | Attack dec_attack; 60 | 61 | /* no data - nothing todo */ 62 | if ((attack->a_conn.payload.size == 0) || (attack->a_conn.payload.data == NULL)) { 63 | logmsg(LOG_DEBUG, 1, "VNC download - No data received, nothing to analyze.\n"); 64 | return(0); 65 | } 66 | 67 | logmsg(LOG_DEBUG, 1, "VNC download - Checking for VNC session string in attack string.\n"); 68 | 69 | /* no data, nothing to do */ 70 | if ((attack->a_conn.payload.size == 0) || (attack->a_conn.payload.data == NULL)) return(1); 71 | 72 | /* parse for VNC session indicator - if found, search for url */ 73 | if (memcmp(attack->a_conn.payload.data, vnc_str, strlen(vnc_str)) == 0) { 74 | logmsg(LOG_DEBUG, 1, "VNC download - Found VNC session string, parsing attack string for HTTP URL.\n"); 75 | for (i=strlen(vnc_str); ia_conn.payload.size; i++) { 76 | if (isprint(attack->a_conn.payload.data[i])) { 77 | if ((readable_chars = realloc(readable_chars, len+2)) == NULL) { 78 | logmsg(LOG_ERR, 1, "VNC download error - Unable to allocate memory: %s.\n", strerror(errno)); 79 | return(0); 80 | } 81 | readable_chars[len] = attack->a_conn.payload.data[i]; 82 | readable_chars[len+1] = 0; 83 | len++; 84 | } 85 | } 86 | if (len) { 87 | /* piece together HTTP url from readable characters - really dirty */ 88 | curchar = readable_chars; 89 | 90 | /* skip leading 'r's */ 91 | for (i=0; i0; clean_str[i] = 0, i--); 96 | 97 | /* un-double chars */ 98 | for (i=0; i 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HT_MODULE_VNCDOWNLOAD_H 14 | #define __HT_MODULE_VNCDOWNLOAD_H 1 15 | 16 | #if HAVE_CONFIG_H 17 | # include 18 | #endif 19 | 20 | void plugin_init(void); 21 | void plugin_unload(void); 22 | void plugin_register_hooks(void); 23 | int cmd_parse_for_vnc(Attack *attack); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /src/nfqmon.h: -------------------------------------------------------------------------------- 1 | /* nfqmon.h 2 | * Copyright (C) 2007-2008 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifdef USE_NFQ_MON 14 | 15 | #ifndef __HONEYTRAP_NFQMON_H 16 | #define __HONEYTRAP_NFQMON_H 1 17 | 18 | #include 19 | #include 20 | 21 | int id; 22 | struct nfq_handle *h; 23 | struct nfq_q_handle *qh; 24 | 25 | int start_nfq_mon(void); 26 | 27 | #endif 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/parseconf.h: -------------------------------------------------------------------------------- 1 | /* parseconf.h 2 | * Copyright (C) 2007 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HONEYTRAP_PARSECONF_H 14 | #define __HONEYTRAP_PARSECONF_H 1 15 | 16 | 17 | #define LCFG_BUFSIZ 0xff 18 | 19 | struct lcfg { 20 | char error[LCFG_BUFSIZ]; 21 | struct lcfg_parser *parser; 22 | }; 23 | 24 | enum lcfg_status { 25 | lcfg_status_ok, 26 | lcfg_status_error 27 | }; 28 | 29 | typedef enum lcfg_status (* lcfg_visitor_function) (const char *key, void *data, size_t size, void *user_data); 30 | 31 | enum lcfg_token_type { 32 | lcfg_null_token = 0, 33 | lcfg_identifier, 34 | lcfg_equals, 35 | lcfg_string, 36 | lcfg_sbracket_open, 37 | lcfg_sbracket_close, 38 | lcfg_comma, 39 | lcfg_brace_open, 40 | lcfg_brace_close 41 | }; 42 | 43 | extern const char *lcfg_token_map[]; 44 | 45 | struct lcfg_token { 46 | enum lcfg_token_type type; 47 | struct lcfg_string *string; 48 | short line; 49 | short col; 50 | }; 51 | 52 | struct lcfg_string { 53 | char *str; 54 | unsigned int size; 55 | unsigned int capacity; 56 | }; 57 | 58 | struct lcfg_string *lcfg_string_new(); 59 | struct lcfg_string *lcfg_string_new_copy(struct lcfg_string *); 60 | int lcfg_string_set(struct lcfg_string *, const char *); 61 | int lcfg_string_cat_char(struct lcfg_string *, char); 62 | int lcfg_string_cat_cstr(struct lcfg_string *, const char *); 63 | int lcfg_string_cat_uint(struct lcfg_string *, unsigned int); 64 | int lcfg_string_find(struct lcfg_string *, char); 65 | int lcfg_string_rfind(struct lcfg_string *, char); 66 | void lcfg_string_trunc(struct lcfg_string *, unsigned int); 67 | void lcfg_string_delete(struct lcfg_string *); 68 | void lcfg_error_set(struct lcfg *c, const char *fmt, ...); 69 | enum lcfg_status lcfg_accept(struct lcfg *c, lcfg_visitor_function fn, void *user_data); 70 | void lcfg_delete(struct lcfg *c); 71 | struct lcfg *parse_config_file(const char *filename); 72 | 73 | static inline const char *lcfg_string_cstr(struct lcfg_string *s) { 74 | s->str[s->size] = '\0'; 75 | return s->str; 76 | } 77 | 78 | static inline unsigned int lcfg_string_len(struct lcfg_string *s) { 79 | return s->size; 80 | } 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /src/pcapmon.h: -------------------------------------------------------------------------------- 1 | /* pcapmon.h 2 | * Copyright (C) 2005-2006 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifdef USE_PCAP_MON 14 | 15 | #ifndef __HONEYTRAP_PCAPMON_H 16 | #define __HONEYTRAP_PCAPMON_H 1 17 | 18 | #include 19 | #include 20 | 21 | char *bpf_filter_string; 22 | bpf_u_int32 mask; 23 | bpf_u_int32 net; 24 | 25 | pcap_t *packet_sniffer; 26 | u_char pcap_offset; 27 | 28 | int start_pcap_mon(void); 29 | char *create_bpf(char *bpf_cmd_ext, struct hostent *ip_cmd_opt, const char *dev); 30 | 31 | #endif 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/plughook.h: -------------------------------------------------------------------------------- 1 | /* plughook.h 2 | * Copyright (C) 2006-2007 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HONEYTRAP_PLUGHOOK_H 14 | #define __HONEYTRAP_PLUGHOOK_H 1 15 | 16 | #include "attack.h" 17 | #include "conftree.h" 18 | #include "plugin.h" 19 | 20 | typedef enum { 21 | PPRIO_DYNSRV = 0, // functions of this prio get invoked before a dynamic server binds to a port 22 | PPRIO_PERREAD = 1, // for plugin functions that shall get called for every read on an attack connection 23 | PPRIO_PREPROC = 2, // attack preprocessing, e.g., decryption 24 | PPRIO_ANALYZE = 3, // attack analysis, e.g., ftp command parsing 25 | PPRIO_SAVEDATA = 4, // for data-saving plugins 26 | PPRIO_POSTPROC = 5, // attack postprocessing, e.g., IDS signature generation or other time complex tasks 27 | } func_prio; 28 | 29 | typedef struct plugin_func_list { 30 | int (*func)(void *arg[]); 31 | func_prio prio; 32 | char *plugnam; 33 | char *funcnam; 34 | struct plugin_func_list *next; 35 | } PlugFuncList; 36 | 37 | PlugFuncList *funclist_init_plugins; 38 | PlugFuncList *funclist_unload_plugins; 39 | PlugFuncList *funclist_attack_dynsrv; 40 | PlugFuncList *funclist_attack_perread; 41 | PlugFuncList *funclist_attack_preproc; 42 | PlugFuncList *funclist_attack_analyze; 43 | PlugFuncList *funclist_attack_savedata; 44 | PlugFuncList *funclist_attack_postproc; 45 | 46 | PlugFuncList *add_attack_func_to_list(const func_prio priority, const char *plugname, const char *funcname, int (*func)(struct s_attack)); 47 | void plughook_process_attack(PlugFuncList *func_list, Attack *attack); 48 | 49 | PlugFuncList *add_init_func_to_list(const char *plugname, const char *funcname, void (*func)(void)); 50 | void plughook_init_plugins(void); 51 | 52 | PlugFuncList *add_unload_func_to_list(const char *plugname, const char *funcname, void (*func)(void)); 53 | void plughook_unload_plugins(void); 54 | 55 | void init_plugin_hooks(void); 56 | conf_node *register_plugin_confopts(const char *plugname, const char **keywords, int num); 57 | void unhook(const func_prio priority, const char *plugname, const char *funcname); 58 | void unhook_from_list(PlugFuncList **hook_func_list, const char *plugname, const char *funcname); 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /src/plugin.h: -------------------------------------------------------------------------------- 1 | /* plugin.h 2 | * Copyright (C) 2006-2007 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HONEYTRAP_PLUGIN_H 14 | #define __HONEYTRAP_PLUGIN_H 1 15 | 16 | typedef struct plugin_struct { 17 | void *handle; 18 | char *name; 19 | char *version; 20 | char *filename; 21 | struct plugin_struct *next; 22 | } Plugin; 23 | 24 | 25 | char *plugin_error_str; 26 | 27 | Plugin *plugin_list; 28 | 29 | int load_plugin(const char *dir, const char *plugname); 30 | int config_plugin(char *plugin_name); 31 | void init_plugins(void); 32 | void unload_plugins(void); 33 | void unload_on_err(Plugin *plugin); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/proxy.c: -------------------------------------------------------------------------------- 1 | /* proxy.c 2 | * Copyright (C) 2006-2007 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include "honeytrap.h" 23 | #include "logging.h" 24 | #include "proxy.h" 25 | #include "signals.h" 26 | #include "sock.h" 27 | #include "tcpip.h" 28 | 29 | int proxy_connect(u_char mode, struct in_addr ipaddr, uint16_t l_port, u_int16_t port, uint16_t proto, Attack *attack) { 30 | int proxy_sock_fd, local_addr_len, sock_type, timeout; 31 | struct sockaddr_in proxy_socket, local_socket; 32 | char *logact=NULL, *logpre=NULL; 33 | 34 | sock_type = 0; 35 | 36 | if (attack == NULL) { 37 | logmsg(LOG_ERR, 1, "Error - No attack record to fill.\n"); 38 | return(-1); 39 | } 40 | 41 | if (mode == PORTCONF_PROXY) { 42 | logact = strdup("proxy"); 43 | logpre = strdup("=="); 44 | } else if (mode == PORTCONF_MIRROR) { 45 | logact = strdup("mirror"); 46 | logpre = strdup("<>"); 47 | } else { 48 | logmsg(LOG_ERR, 1, "%s %s Error - Mode %u for connection handling is not supported.\n", 49 | logpre, portstr, mode); 50 | return(-1); 51 | } 52 | 53 | /* prevent loops - disallow mirror connections to localhost */ 54 | if ((ntohl(ipaddr.s_addr) == 0x7F000001) && (mode == PORTCONF_MIRROR)) { 55 | logmsg(LOG_WARN, 1, "%s %s Warning - Connection to %s:%u suppressed for loop prevention.\n", 56 | logpre, portstr, inet_ntoa(ipaddr), port); 57 | return(-1); 58 | } 59 | 60 | /* prepare client socket */ 61 | 62 | logmsg(LOG_DEBUG, 1, "%s %s Creating client socket for %s connection.\n", logpre, portstr, logact); 63 | if (proto == TCP) sock_type = SOCK_STREAM; 64 | else if (proto == UDP) sock_type = SOCK_DGRAM; 65 | else { 66 | logmsg(LOG_ERR, 1, "%s %s Error - Protocol %d is not supported.\n", 67 | logpre, portstr, sock_type); 68 | return(-1); 69 | } 70 | if (!(proxy_sock_fd = socket(AF_INET, sock_type, 0))) { 71 | logmsg(LOG_ERR, 1, "%s %s Error - Unable to create client socket for %s connection: %m.\n", 72 | logpre, portstr, logact); 73 | return(-1); 74 | } else { 75 | logmsg(LOG_DEBUG, 1, "%s %s Client socket for %s connection created.\n", logpre, portstr, logact); 76 | 77 | // set keepalive option on connected socket 78 | int sockopt = 1; 79 | if (setsockopt(proxy_sock_fd, SOL_SOCKET, SO_KEEPALIVE, &sockopt, sizeof(sockopt)) < 0) 80 | logmsg(LOG_WARN, 1, "Warning - Unable to set SO_KEEPALIVE for socket.\n"); 81 | 82 | /* establish proxy connection */ 83 | logmsg(LOG_DEBUG, 1, "%s %s Establishing %s connection to %s:%u.\n", 84 | logpre, portstr, logact, inet_ntoa(ipaddr), port); 85 | 86 | bzero(&proxy_socket, sizeof(proxy_socket)); 87 | proxy_socket.sin_family = AF_INET; 88 | proxy_socket.sin_addr.s_addr = ipaddr.s_addr; 89 | proxy_socket.sin_port = htons(port); 90 | 91 | 92 | timeout = (proto == TCP && PORTCONF_MIRROR) ? FASTCONNTIMEOUT : CONNTIMEOUT; 93 | switch(nb_connect(proxy_sock_fd, (struct sockaddr *) &proxy_socket, 94 | sizeof(proxy_socket), timeout)) { 95 | case -1: 96 | switch(errno) { 97 | case EINPROGRESS: 98 | break; 99 | case EINTR: 100 | if (check_sigpipe() == -1) exit(EXIT_FAILURE); 101 | break; 102 | case ECONNREFUSED: 103 | logmsg(LOG_DEBUG, 1, "%s %s select() call failed: %m.\n", 104 | logpre, portstr); 105 | return(-1); 106 | default: 107 | logmsg(LOG_ERR, 1, "%s %s Error - select() call failed: %m.\n", 108 | logpre, portstr); 109 | return(-1); 110 | } 111 | case 0: 112 | logmsg(LOG_DEBUG, 1, "%s %s Unable to establish %s connection: %s.\n", 113 | logpre, portstr, logact, strerror(ETIMEDOUT)); 114 | return(-1); 115 | default: 116 | break; 117 | } 118 | 119 | local_addr_len = 0; 120 | if (getsockname(proxy_sock_fd, (struct sockaddr *) &local_socket, (socklen_t *) &local_addr_len) != 0) { 121 | logmsg(LOG_ERR, 1, "%s %s Error - Unable to get local address from %s socket: %m.\n", 122 | logpre, portstr, logact); 123 | return(-1); 124 | } 125 | memcpy(&(attack->p_conn.l_addr), &local_socket.sin_addr, sizeof(uint32_t)); 126 | memcpy(&(attack->p_conn.r_addr), &proxy_socket.sin_addr, sizeof(uint32_t)); 127 | attack->p_conn.l_port = local_socket.sin_port; 128 | attack->p_conn.r_port = proxy_socket.sin_port; 129 | } 130 | return(proxy_sock_fd); 131 | } 132 | 133 | /* copy_data - reads data from one fd and writes it to another * 134 | * also stores read data in 'save_string' at position 'offset' */ 135 | int copy_data(int to_fd, int from_fd, u_char **save_string, uint32_t offset, int *bytes_read, int *bytes_sent) { 136 | u_char buffer[BUFSIZ]; 137 | 138 | /* read from from_sock_fd */ 139 | if ((*bytes_read = read(from_fd, buffer, sizeof(buffer))) > 0) { 140 | /* write read bytes to save_string at offset */ 141 | if (!(*save_string = (u_char *) realloc(*save_string, offset+(*bytes_read)))) { 142 | logmsg(LOG_ERR, 1, "Error - Unable to allocate memory: %m.\n"); 143 | close(from_fd); 144 | close(to_fd); 145 | return(-1); 146 | } 147 | memcpy(*save_string + offset, buffer, (*bytes_read)); 148 | 149 | /* write read bytes to to_fd */ 150 | *bytes_sent = 0; 151 | if ((*bytes_sent = write(to_fd, buffer, *bytes_read)) == -1) { 152 | logmsg(LOG_ERR, 1, "Error - Unable to tcpcopy() %u bytes to target connection: %m.\n", *bytes_read); 153 | close(from_fd); 154 | close(to_fd); 155 | return(-1); 156 | } 157 | return(*bytes_sent); 158 | } 159 | return(0); 160 | } 161 | -------------------------------------------------------------------------------- /src/proxy.h: -------------------------------------------------------------------------------- 1 | /* proxy.h 2 | * Copyright (C) 2006 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HONEYTRAP_PROXY_H 14 | #define __HONEYTRAP_PROXY_H 1 15 | 16 | #include 17 | 18 | #include "attack.h" 19 | 20 | int proxy_connect(u_char mode, struct in_addr ipaddr, uint16_t l_port, u_int16_t port, uint16_t proto, Attack *attack); 21 | int copy_data(int to_fd, int from_fd, u_char **save_string, uint32_t offset, int *bytes_read, int *bytes_sent); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/queue.c: -------------------------------------------------------------------------------- 1 | /* queue.c 2 | * 3 | * Copyright (C) 2007 Tillmann Werner 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License Version 2 as 7 | * published by the Free Software Foundation. You may not use, modify or 8 | * distribute this program under any other version of the GNU General 9 | * Public License. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "queue.h" 27 | 28 | 29 | qelem *queue_ins(queue *q, void *data, ssize_t max_size) { 30 | qelem* tmp = NULL; 31 | 32 | if (!q || !data) return(NULL); 33 | 34 | /* need to cut off last queue element? */ 35 | if (q->size >= max_size) tmp = queue_cuttail(q); 36 | 37 | /* prepend new element */ 38 | queue_prepend(q, data); 39 | 40 | return(tmp); 41 | } 42 | 43 | 44 | void *queue_unlink(queue *q, qelem *e) { 45 | void *data; 46 | 47 | if (!q || !e) return(NULL); 48 | 49 | if (e == q->head) { 50 | e = queue_cuthead(q); 51 | } else if (e == q->tail) { 52 | e = queue_cuttail(q); 53 | } else { 54 | e->prev->next = e->next; 55 | e->next->prev = e->prev; 56 | if (!q->size--) q->head = q->tail = NULL; 57 | } 58 | 59 | data = e->data; 60 | free(e); 61 | 62 | return(data); 63 | } 64 | 65 | 66 | queue *queue_new(void) { 67 | queue *q = calloc(1, sizeof(queue)); 68 | 69 | return(q); 70 | } 71 | 72 | 73 | void queue_free(queue *q, void(*cbfn)(void *data)) { 74 | qelem *cur; 75 | 76 | if (!q) return; 77 | 78 | while (q->head) { 79 | cur = q->head; 80 | q->head = q->head->next; 81 | if (cbfn) cbfn(cur->data); 82 | free(cur); 83 | } 84 | 85 | free(q); 86 | 87 | return; 88 | } 89 | -------------------------------------------------------------------------------- /src/queue.h: -------------------------------------------------------------------------------- 1 | /* queue.h 2 | * 3 | * Copyright (C) 2007 Tillmann Werner 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License Version 2 as 7 | * published by the Free Software Foundation. You may not use, modify or 8 | * distribute this program under any other version of the GNU General 9 | * Public License. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 | */ 20 | 21 | #ifndef __HONEYTRAP_QUEUE_H 22 | #define __HONEYTRAP_QUEUE_H 1 23 | 24 | #if HAVE_CONFIG_H 25 | # include 26 | #endif 27 | 28 | typedef struct qelem { 29 | void *data; 30 | struct qelem *prev; 31 | struct qelem *next; 32 | } qelem; 33 | 34 | typedef struct queue { 35 | ssize_t size; 36 | qelem *head; 37 | qelem *tail; 38 | } queue; 39 | 40 | qelem *queue_ins(queue *q, void *data, ssize_t max_size); 41 | void *queue_unlink(queue *q, qelem *e); 42 | queue *queue_new(void); 43 | void queue_free(queue *q, void(*cbfn)(void *data)); 44 | 45 | static inline qelem *queue_prepend(queue *q, void *data) { 46 | qelem *new; 47 | 48 | if (!q || !data) return(NULL); 49 | 50 | if ((new = calloc(1, sizeof(qelem))) == NULL) return(NULL); 51 | new->data = data; 52 | 53 | if (q->head) { 54 | q->head->prev = new; 55 | new->next = q->head; 56 | } else q->tail = new; 57 | 58 | new->prev = NULL; 59 | q->head = new; 60 | q->size++; 61 | 62 | return(new); 63 | } 64 | 65 | static inline qelem *queue_append(queue *q, void *data) { 66 | qelem *new; 67 | 68 | if (!q || !data) return(NULL); 69 | 70 | if ((new = calloc(1, sizeof(qelem))) == NULL) return(NULL); 71 | new->data = data; 72 | 73 | if (q->tail) { 74 | q->tail->next = new; 75 | new->prev = q->tail; 76 | } else q->head = new; 77 | 78 | new->next = NULL; 79 | q->tail = new; 80 | q->size++; 81 | 82 | return(new); 83 | } 84 | 85 | static inline qelem *queue_cuthead(queue *q) { 86 | qelem *tmp; 87 | 88 | if (!q || q->head == NULL) return(NULL); 89 | 90 | tmp = q->head; 91 | q->head = q->head->next; 92 | if (q->head) q->head->prev = NULL; 93 | else q->tail = NULL; 94 | q->size--; 95 | 96 | return(tmp); 97 | } 98 | 99 | static inline qelem *queue_cuttail(queue *q) { 100 | qelem *tmp; 101 | 102 | if (!q || q->tail == NULL) return(NULL); 103 | 104 | tmp = q->tail; 105 | q->tail = q->tail->prev; 106 | if (q->tail) q->tail->next = NULL; 107 | else q->head = NULL; 108 | q->size--; 109 | 110 | return(tmp); 111 | } 112 | 113 | #endif 114 | -------------------------------------------------------------------------------- /src/readconf.h: -------------------------------------------------------------------------------- 1 | /* readconf.h 2 | * Copyright (C) 2006-2007 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HONEYTRAP_READCONF_H 14 | #define __HONEYTRAP_READCONF_H 1 15 | 16 | #include 17 | 18 | #include "conftree.h" 19 | 20 | char *user, *group; 21 | 22 | typedef struct proxy_dest { 23 | u_int16_t protocol; 24 | u_int16_t port; 25 | char *host; 26 | } proxy_dest; 27 | 28 | typedef struct portcfg { 29 | u_char mode; 30 | u_char *response; 31 | proxy_dest *target; 32 | u_int16_t port; 33 | u_int16_t protocol; 34 | } portcfg; 35 | 36 | struct protomap { 37 | u_char protocol; 38 | struct protomap *next; 39 | }; 40 | struct portmap { 41 | u_int16_t port; 42 | struct portmap *next; 43 | }; 44 | struct pconfmap { 45 | struct portmap *portmap; 46 | struct protomap *protomap; 47 | proxy_dest *target; 48 | struct pconfmap *next; 49 | }; 50 | 51 | portcfg *port_flags_tcp[0xffff]; // explicit port configuration for each tcp port 52 | portcfg *port_flags_udp[0xffff]; // explicit port configuration for each udp port 53 | 54 | #define OPT_IS(A) (strcmp(node->keyword, (A)) == 0) 55 | #define OPT_SET(A, B) { free(B); B = value; if (B) DEBUG_FPRINTF(stdout, A, B); } 56 | 57 | 58 | typedef conf_node *(*process_confopt_fn)(conf_node *tree, conf_node *node, void *opt_data); 59 | 60 | 61 | void *get_value(char *buf, const char delim); 62 | int configure(int argc, char *argv[]); 63 | conf_node *process_conftree(conf_node *conftree, conf_node *tree, process_confopt_fn proc_opt, void *opt_data); 64 | conf_node *process_confopt (conf_node *tree, conf_node *node, void *opt_data); 65 | conf_node *process_confopt_portconf (conf_node *tree, conf_node *node, void *opt_data); 66 | conf_node *process_confopt_portconf_simple (conf_node *tree, conf_node *node, void *mode); 67 | conf_node *process_confopt_portconf_proxy (conf_node *tree, conf_node *node, void *pmap); 68 | conf_node *process_confopt_portconf_proxy_map (conf_node *tree, conf_node *node, void *opt_data); 69 | conf_node *process_confopt_plugin (conf_node *tree, conf_node *node, void *opt_data); 70 | enum lcfg_status print_config(const char *key, void *data, size_t len, void *user_data); 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /src/response.c: -------------------------------------------------------------------------------- 1 | /* response.c 2 | * Copyright (C) 2006-2007 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | * 12 | * This code is based on an OpenSSL-compatible implementation of the RSA 13 | * Data Security, * Inc. MD5 Message-Digest Algorithm, written by Solar 14 | * Designer in 2001, and placed in the public 15 | * domain. There's absolutely no warranty. 16 | * 17 | * This implementation is meant to be fast, but not as fast as possible. 18 | * Some known optimizations are not included to reduce source code size 19 | * and avoid compile-time configuration. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "honeytrap.h" 32 | #include "tcpip.h" 33 | #include "logging.h" 34 | #include "response.h" 35 | 36 | 37 | void unload_default_responses(void) { 38 | def_resp *cur_response; 39 | 40 | while(response_list) { 41 | cur_response = response_list->next; 42 | free(response_list->response); 43 | free(response_list); 44 | response_list = cur_response; 45 | } 46 | return; 47 | } 48 | 49 | int prepare_default_response(char *filename, uint16_t port, uint16_t proto) { 50 | int answer_fd, ccopy; 51 | u_char buffer[100]; 52 | FILE* answer_file = NULL; 53 | def_resp *last_response, *new_response; 54 | 55 | /* allocate memory for new response */ 56 | if ((new_response = (def_resp *) malloc(sizeof(struct def_resp))) == NULL) { 57 | perror(" Error - Unable to allocate memory"); 58 | return(-1); 59 | } else { 60 | new_response->port = port; 61 | new_response->proto = proto; 62 | new_response->size = 0; 63 | new_response->response = NULL; 64 | new_response->next = NULL; 65 | } 66 | if (!response_list) response_list = new_response; 67 | else { 68 | /* spool to end of the list and attach new response */ 69 | last_response = response_list; 70 | while (last_response->next) last_response = last_response->next; 71 | last_response->next = new_response; 72 | } 73 | 74 | /* read response */ 75 | if ((proto != TCP) && (proto != UDP)) { 76 | fprintf(stderr, " Error - Protocol %u is not supported.\n", proto); 77 | return(-1); 78 | } 79 | DEBUG_FPRINTF(stdout, " Loading default response for port %u/%s.\n", port, PROTO(proto)); 80 | if (((answer_fd = open(filename, O_NOCTTY | O_RDONLY, 0640)) == -1) || (!(answer_file = fopen(filename, "rb")))) { 81 | DEBUG_FPRINTF(stdout, " Warning - Unable to open file '%s'\n", filename); 82 | } else { 83 | ccopy = 0; 84 | while((ccopy = fread(buffer, 1, 100, answer_file))) { 85 | if ((new_response->response = (u_char *) realloc(new_response->response, new_response->size + ccopy)) == NULL) { 86 | perror(" Error - Unable to allocate memory"); 87 | return(-1); 88 | } else { 89 | memcpy(new_response->response + new_response->size, buffer, ccopy); 90 | new_response->size += ccopy; 91 | } 92 | } 93 | if (new_response->size != 0) { 94 | DEBUG_FPRINTF(stdout, " Default response string for port %u/%s successfully loaded.\n", 95 | port, PROTO(proto)); 96 | } else DEBUG_FPRINTF(stdout, " Warning - Default response file '%s' is empty.\n", filename); 97 | } 98 | fclose(answer_file); 99 | close(answer_fd); 100 | return(0); 101 | } 102 | 103 | 104 | int load_default_responses(char *dir) { 105 | struct stat statbuf; 106 | struct dirent **namelist; 107 | int n; 108 | uint16_t port; 109 | char *full_path; 110 | DIR *respdir; 111 | 112 | full_path = NULL; 113 | 114 | if ((respdir = opendir(dir)) == NULL) { 115 | perror(" Error - Unable to open response directory"); 116 | exit(EXIT_FAILURE); 117 | } 118 | 119 | DEBUG_FPRINTF(stdout, " Searching for response files in %s\n", dir); 120 | if ((n = scandir(dir, &namelist, 0, alphasort)) < 0) { 121 | perror(" Error - Unable to scan response directory"); 122 | exit(EXIT_FAILURE); 123 | } else while(n--) { 124 | stat(namelist[n]->d_name, &statbuf); 125 | if ((fnmatch("*_tcp", namelist[n]->d_name, 0) == 0) || (fnmatch("*_udp", namelist[n]->d_name, 0) == 0)) { 126 | /* found a default response file */ 127 | if ((full_path = (char *) malloc(strlen(dir) + strlen(namelist[n]->d_name) + 2)) == NULL) { 128 | perror(" Error - Unable to allocate memory"); 129 | exit(EXIT_FAILURE); 130 | } 131 | snprintf(full_path, strlen(dir)+strlen(namelist[n]->d_name)+2, "%s/%s", dir, namelist[n]->d_name); 132 | DEBUG_FPRINTF(stdout, " Response file found: %s\n", full_path); 133 | port = atoi(namelist[n]->d_name); 134 | if (fnmatch("*_tcp", namelist[n]->d_name, 0) == 0) 135 | prepare_default_response(full_path, port, TCP); 136 | else if (fnmatch("*_udp", namelist[n]->d_name, 0) == 0) 137 | prepare_default_response(full_path, port, UDP); 138 | } 139 | free(namelist[n]); 140 | } 141 | free(namelist); 142 | 143 | return(0); 144 | } 145 | 146 | 147 | int send_default_response(int connection_fd, uint16_t port, uint16_t proto, u_char timeout) { 148 | def_resp *cur_response = NULL; 149 | 150 | if ((proto != TCP) && (proto != UDP)) { 151 | fprintf(stderr, " Error - Protocol %u is not supported.\n", proto); 152 | return(-1); 153 | } 154 | 155 | logmsg(LOG_DEBUG, 1, "Searching for default response for port %s.\n", portstr); 156 | 157 | /* advance through list to find response for port */ 158 | cur_response = response_list; 159 | while(cur_response && ((cur_response->port != port) || (cur_response->proto != proto))) 160 | cur_response = cur_response->next; 161 | 162 | if (cur_response && (cur_response->port == port) && (cur_response->proto == proto)) { 163 | /* default response for port found */ 164 | logmsg(LOG_NOISY, 1, " %s No data for %u second(s), sending default response.\n", 165 | portstr, (u_char) timeout); 166 | 167 | if (!(write(connection_fd, cur_response->response, cur_response->size))) return(-1); 168 | } else { 169 | logmsg(LOG_NOISY, 1, " %s No data for %d second(s), sending '\\n'.\n", portstr, timeout); 170 | if (!(write(connection_fd, "\n", 1))) return(-1); 171 | } 172 | return(0); 173 | } 174 | 175 | -------------------------------------------------------------------------------- /src/response.h: -------------------------------------------------------------------------------- 1 | /* response.h 2 | * Copyright (C) 2006 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | * 12 | * This code is based on an OpenSSL-compatible implementation of the RSA 13 | * Data Security, * Inc. MD5 Message-Digest Algorithm, written by Solar 14 | * Designer in 2001, and placed in the public 15 | * domain. There's absolutely no warranty. See md5.c for more information. 16 | */ 17 | 18 | #ifndef __HONEYTRAP_RESPONSE_H 19 | #define __HONEYTRAP_RESPONSE_H 20 | 21 | #include 22 | 23 | typedef struct def_resp { 24 | uint16_t port; 25 | uint16_t proto; 26 | uint32_t size; 27 | u_char *response; 28 | struct def_resp *next; 29 | } def_resp; 30 | 31 | def_resp *response_list; 32 | 33 | 34 | void unload_default_responses(void); 35 | int prepare_default_response(char *filename, uint16_t port, uint16_t proto); 36 | int load_default_responses(char *dir); 37 | int send_default_response(int connection_fd, uint16_t port, uint16_t proto, u_char timeout); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/sha512.h: -------------------------------------------------------------------------------- 1 | /* sha512.h 2 | * Copyright (C) 2007 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | * 12 | * This code is based on the SHA-512 code by Jean-Luc Cooke 13 | */ 14 | 15 | 16 | #ifndef SHA512_H 17 | #define SHA512_H 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | 25 | #define ROLuns64(a,b) ( ((a) << ((b) & 63)) | ((a) >> (64-((b) & 63))) ) 26 | #define RORuns64(a,b) ( ((a) >> ((b) & 63)) | ((a) << (64-((b) & 63))) ) 27 | 28 | 29 | typedef struct { 30 | u_int64_t state[8]; 31 | u_char buf[128]; 32 | u_int32_t count[4]; 33 | } sha512_context; 34 | 35 | 36 | extern void sha512_init(sha512_context *c); 37 | extern void sha512_update(sha512_context *c, u_char *input, unsigned int inLen); 38 | extern void sha512_final(u_char *digest, sha512_context *c); 39 | 40 | char *mem_sha512sum(u_char *msg, u_int32_t len); 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/signals.h: -------------------------------------------------------------------------------- 1 | /* signals.h 2 | * Copyright (C) 2005-2007 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HONEYTRAP_SIGNALS_H 14 | #define __HONEYTRAP_SIGNALS_H 1 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | int sigpipe[2]; 23 | 24 | pid_t master_pid; 25 | 26 | void get_signal(int sig); 27 | void handle_sigchld(int sig); 28 | void handle_sighup(int sig); 29 | void handle_termsig(int sig); 30 | void install_signal_handlers(void); 31 | void create_sigpipe(void); 32 | int check_sigpipe(void); 33 | int sleep_sigaware(struct timeval *tv); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/sock.c: -------------------------------------------------------------------------------- 1 | /* sock.c 2 | * Copyright (C) 2005-2008 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "honeytrap.h" 27 | #include "ipqmon.h" 28 | #include "logging.h" 29 | #include "nfqmon.h" 30 | #include "signals.h" 31 | #include "sock.h" 32 | #include "tcpip.h" 33 | 34 | 35 | /* returns a bound socket matching a connection request * 36 | * sets verdict on request packet if ipq or nfq was used and the port is already bound * 37 | * in the latter case, -1 is returned */ 38 | int get_boundsock(struct sockaddr_in *server_addr, uint16_t port, int type) { 39 | int fd, sockopt; 40 | #ifdef USE_IPQ_MON 41 | int status; 42 | #endif 43 | 44 | if ((type != SOCK_DGRAM) && (type != SOCK_STREAM)) { 45 | logmsg(LOG_ERR, 1, "Error - Socket type %d not supported.\n", type); 46 | exit(EXIT_FAILURE); 47 | } 48 | 49 | if (!(fd = socket(AF_INET, type, 0))) { 50 | logmsg(LOG_ERR, 1, "Error - Could not create socket: %m.\n"); 51 | exit(EXIT_FAILURE); 52 | } 53 | 54 | sockopt = 1; 55 | if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(sockopt)) < 0) 56 | logmsg(LOG_WARN, 1, "Warning - Unable to set SO_REUSEADDR for server socket.\n"); 57 | 58 | bzero((char *) server_addr, sizeof(struct sockaddr_in)); 59 | server_addr->sin_family = AF_INET; 60 | server_addr->sin_addr.s_addr = bind_address.s_addr; 61 | server_addr->sin_port = port; 62 | if ((bind(fd, (struct sockaddr *) server_addr, sizeof(struct sockaddr_in))) != 0) { 63 | /* we already got one server process */ 64 | logmsg(LOG_DEBUG, 1, "Unable to bind to port %u/tcp: %m.\n", ntohs(port)); 65 | #ifdef USE_IPQ_MON 66 | /* hand packet processing back to the kernel */ 67 | if ((status = ipq_set_verdict(h, packet->packet_id, NF_ACCEPT, 0, NULL)) < 0) { 68 | logmsg(LOG_ERR, 1, "Error - Could not set verdict on packet: %s.\n", ipq_errstr()); 69 | ipq_destroy_handle(h); 70 | exit(EXIT_FAILURE); 71 | } 72 | logmsg(LOG_DEBUG, 1, "IPQ - Successfully set verdict on packet.\n"); 73 | return(-1); 74 | #else 75 | #ifdef USE_NFQ_MON 76 | /* hand packet processing back to the kernel */ 77 | /* nfq_set_verdict()'s return value is undocumented, 78 | * but digging the source of libnetfilter_queue and libnfnetlink reveals 79 | * that it's just the passed-through value of a sendmsg() */ 80 | if (nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL) == -1) { 81 | logmsg(LOG_ERR, 1, "Error - Could not set verdict on packet.\n"); 82 | nfq_destroy_queue(qh); 83 | exit(EXIT_FAILURE); 84 | } 85 | logmsg(LOG_DEBUG, 1, "NFQ - Successfully set verdict on packet.\n"); 86 | 87 | /* a dynamic server is already present */ 88 | close(fd); 89 | return(-1); 90 | #else 91 | /* if bind() did not fail for 'port already in use' but for some other reason, 92 | * we're in troubles and want a verbose error message */ 93 | if (errno != 98) logmsg(LOG_NOISY, 1, "Warning - Could not bind to port %u/tcp: %m.\n", ntohs(port)); 94 | exit(EXIT_FAILURE); 95 | #endif 96 | #endif 97 | } 98 | logmsg(LOG_DEBUG, 1, "Socket created, file descriptor is %d.\n", fd); 99 | 100 | return(fd); 101 | } 102 | 103 | 104 | /* perform a non-blocking connect() with a given timeout 105 | * always use this function instead of connect() 106 | * or signal processing might get delayed */ 107 | int nb_connect(int sock_fd, const struct sockaddr * sockaddr, socklen_t slen, int sec) { 108 | int flags, rv, error; 109 | struct timeval timeout; 110 | fd_set rfds, wfds; 111 | socklen_t len; 112 | 113 | flags = 0; 114 | 115 | /* safe fd flags and set socket to non-blocking */ 116 | if ((flags = fcntl(sock_fd, F_GETFL, 0) < 0)) return(-1); 117 | if (fcntl(sock_fd, F_SETFL, flags | O_NONBLOCK) < 0) return(-1); 118 | 119 | /* try an immediate connect */ 120 | errno = 0; 121 | error = 0; 122 | if ((rv = connect(sock_fd, sockaddr, slen)) < 0) 123 | if (errno != EINPROGRESS) return(-1); 124 | 125 | if (rv != 0) { 126 | /* do a non-blocking connect */ 127 | FD_ZERO(&rfds); 128 | FD_SET(sigpipe[0], &rfds); 129 | FD_SET(sock_fd, &rfds); 130 | 131 | wfds = rfds; 132 | timeout.tv_sec = sec; 133 | timeout.tv_usec = 0; 134 | 135 | switch (select(MAX(sigpipe[0], sock_fd) + 1, &rfds, &wfds, NULL, &timeout)) { 136 | case -1: 137 | if (errno == EINPROGRESS) break; 138 | if (errno == EINTR) { 139 | if (check_sigpipe() == -1) exit(EXIT_FAILURE); 140 | break; 141 | } 142 | close(sock_fd); 143 | errno = ETIMEDOUT; 144 | return(-1); 145 | case 0: 146 | /* timeout */ 147 | close(sock_fd); 148 | errno = ETIMEDOUT; 149 | return(0); 150 | default: 151 | if (FD_ISSET(sigpipe[0], &rfds) && (check_sigpipe() == -1)) { 152 | logmsg(LOG_ERR, 1, "Error - Signal handling failed in dynamic server process.\n"); 153 | exit(EXIT_FAILURE); 154 | } 155 | if (FD_ISSET(sock_fd, &rfds) || FD_ISSET(sock_fd, &wfds)) { 156 | len = sizeof(error); 157 | if (getsockopt(sock_fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) return(-1); 158 | if (error) { 159 | errno = error; 160 | return(-1); 161 | } 162 | } 163 | } 164 | } 165 | if (fcntl(sock_fd, F_SETFL, flags) < 0) return(-1); 166 | if (error) { 167 | errno = error; 168 | return(-1); 169 | } 170 | 171 | return(sock_fd); 172 | } 173 | -------------------------------------------------------------------------------- /src/sock.h: -------------------------------------------------------------------------------- 1 | /* sock.h 2 | * Copyright (C) 2005-2007 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HONEYTRAP_SOCK_H 14 | #define __HONEYTRAP_SOCK_H 1 15 | 16 | #define CONNTIMEOUT 90 17 | #define FASTCONNTIMEOUT 3 18 | 19 | 20 | int get_boundsock(struct sockaddr_in *server_addr, uint16_t port, int type); 21 | int nb_connect(int sock_fd, const struct sockaddr * sockaddr, socklen_t slen, int sec); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/tcpip.h: -------------------------------------------------------------------------------- 1 | /* tcpip.h 2 | * Copyright (C) 2005-2007 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HONEYTRAP_TCPIP_H 14 | #define __HONEYTRAP_TCPIP_H 1 15 | 16 | #include 17 | 18 | 19 | /* IP header */ 20 | struct ip_header { 21 | u_char ip_hlen:4, /* header length */ 22 | ip_vers:4; /* version */ 23 | u_char ip_tos; /* type of service */ 24 | u_short ip_len; /* total length */ 25 | u_short ip_id; /* identification */ 26 | u_short ip_off; /* fragment offset field */ 27 | u_char ip_ttl; /* time to live */ 28 | u_char ip_p; /* protocol */ 29 | u_short ip_sum; /* checksum */ 30 | struct in_addr ip_src, ip_dst; /* source and dest address */ 31 | }; 32 | 33 | #define IP_RF 0x8000 /* reserved fragment flag */ 34 | #define IP_DF 0x4000 /* dont fragment flag */ 35 | #define IP_MF 0x2000 /* more fragments flag */ 36 | #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ 37 | 38 | #if BYTE_ORDER == BIG_ENDIAN 39 | #define ip_hl ip_vers 40 | #define ip_v ip_hlen 41 | #else 42 | #define ip_hl ip_hlen 43 | #define ip_v ip_vers 44 | #endif 45 | 46 | 47 | /* udp header */ 48 | struct udp_header{ 49 | uint16_t uh_sport; /* udp source port */ 50 | uint16_t uh_dport; /* udp dest port */ 51 | uint16_t uh_len; /* datagram length */ 52 | uint16_t uh_sum; /* udp checksum */ 53 | }; 54 | 55 | /* tcp header */ 56 | struct tcp_header{ 57 | uint16_t th_sport; /* tcp source port */ 58 | uint16_t th_dport; /* tcp dest port */ 59 | uint32_t th_seqno; /* tcp sequence number,identifies the byte in the stream of data */ 60 | uint32_t th_ackno; /* contains the next seq num that the sender expects to recieve */ 61 | u_char th_res:4, /* 4 reserved bits */ 62 | th_doff:4; /* data offset */ 63 | u_char th_flags; /* tcp flags */ 64 | uint16_t th_window; /* maxinum number of bytes able to recieve*/ 65 | uint16_t th_sum; /* checksum to cover the tcp header and data portion of the packet*/ 66 | uint16_t th_urp; /* vaild only if the urgent flag is set, used to transmit emergency data */ 67 | }; 68 | 69 | #define FIN 0x01 70 | #define SYN 0x02 71 | #define RST 0x04 72 | #define PUSH 0x08 73 | #define ACK 0x10 74 | #define URG 0x20 75 | #define ECE 0x40 76 | #define CWR 0x80 77 | #define FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR) 78 | 79 | 80 | #define RAW 0 81 | #define ICMP 1 82 | #define TCP 6 83 | #define UDP 17 84 | #define PROTO(p) (p == RAW ? "raw" : (p == ICMP ? "icmp" : (p == TCP ? "tcp" : (p == UDP ? "udp" : "unknown")))) 85 | 86 | 87 | const struct ip_header *ip; 88 | const struct udp_header *udp; 89 | const struct tcp_header *tcp; 90 | 91 | 92 | #endif 93 | -------------------------------------------------------------------------------- /src/util.c: -------------------------------------------------------------------------------- 1 | /* util.c 2 | * Copyright (C) 2005-2007 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include "honeytrap.h" 25 | #include "util.h" 26 | #include "signals.h" 27 | #include "logging.h" 28 | 29 | 30 | /* check if 'address' is an ip address with a reasonable value */ 31 | int valid_ipaddr(struct in_addr address) { 32 | u_char octet[4]; 33 | 34 | octet[0] = address.s_addr; 35 | octet[1] = address.s_addr >> 8; 36 | octet[2] = address.s_addr >> 16; 37 | octet[3] = address.s_addr >> 24; 38 | 39 | if (!octet[0] || !octet[3]) return(0); 40 | if (address.s_addr == 0xffffffff) return(0); 41 | 42 | return(1); 43 | } 44 | 45 | 46 | /* test if 'address' is a rfc1918 ip address */ 47 | int private_ipaddr(struct in_addr address) { 48 | int i; 49 | 50 | for (i=0; i<(sizeof(priv_prefixes)/4); i++) 51 | if ((ntohl(address.s_addr) & priv_prefixes[i]) == ntohl(address.s_addr)) return(1); 52 | 53 | return(0); 54 | } 55 | 56 | 57 | int read_line(int socket, char *line, ssize_t len, int timeout) { 58 | /* reads a line from 'socket' into buffer 'line' */ 59 | /* 'timeout' is optional, 0 means read without timeout */ 60 | 61 | int read_chars = 0; 62 | int rv = 0; 63 | fd_set rfds; 64 | struct timeval r_timeout; 65 | 66 | memset(line, 0, len); 67 | 68 | /* read line with timeout */ 69 | if (timeout) { 70 | FD_ZERO(&rfds); 71 | FD_SET(socket, &rfds); 72 | FD_SET(sigpipe[0], &rfds); 73 | r_timeout.tv_sec = timeout; 74 | r_timeout.tv_usec = 0; 75 | 76 | /* wait for incoming data, close connection on timeout */ 77 | logmsg(LOG_DEBUG, 1, "Trying to read a line from socket, timeout is %d seconds.\n", 78 | (uint16_t) r_timeout.tv_sec); 79 | 80 | for (;;) { 81 | switch (select(MAX(sigpipe[0], socket) + 1, &rfds, NULL, NULL, &r_timeout)) { 82 | case -1: 83 | if (errno == EINTR) { 84 | if (check_sigpipe() == -1) exit(EXIT_FAILURE); 85 | break; 86 | } 87 | logmsg(LOG_DEBUG, 1, "Error while reading a line from socket - select() failed.\n"); 88 | return(-1); 89 | case 0: 90 | logmsg(LOG_DEBUG, 1, "Error while reading a line from socket - Connection timed out.\n"); 91 | return(-1); 92 | default: 93 | if (FD_ISSET(sigpipe[0], &rfds) && (check_sigpipe() == -1)) exit(EXIT_FAILURE); 94 | if (FD_ISSET(socket, &rfds)) { 95 | if (read_chars >= len-1) { 96 | logmsg(LOG_DEBUG, 1, "Error while reading from socket - Line exceeds buffer.\n"); 97 | return(-2); 98 | } 99 | rv = recv(socket, &line[read_chars], 1, 0); 100 | if (rv == 0) return(read_chars); 101 | if (rv < 0) return(-1); 102 | if (line[read_chars] == '\n') { 103 | line[read_chars] = '\0'; 104 | logmsg(LOG_DEBUG, 1, "Line read: %s\n", line); 105 | return(read_chars); 106 | } 107 | read_chars++; 108 | } 109 | } 110 | } 111 | } 112 | 113 | /* read line without timeout */ 114 | while (1){ 115 | if (read_chars >= len-1) { 116 | logmsg(LOG_DEBUG, 1, "Error while reading from socket - Line exceeds buffer.\n"); 117 | return(-2); 118 | } 119 | rv = recv(socket, &line[read_chars], 1, 0); 120 | if (rv == 0) return(read_chars); 121 | if (rv < 0) return(-1); 122 | if (line[read_chars] == '\n') { 123 | line[read_chars] = '\0'; 124 | return(read_chars); 125 | } 126 | read_chars++; 127 | } 128 | return(0); 129 | } 130 | 131 | 132 | struct strtk extract_token(char *parse_string) { 133 | /* returns substring (string until next occurrence of '>', '&' or '\n' and its offset in a struct */ 134 | /* used to extract tokens from shell commands */ 135 | int length; 136 | struct strtk rv; 137 | 138 | rv.string = parse_string; 139 | rv.offset = 0; 140 | 141 | length = strlen(parse_string); 142 | 143 | while(isspace(*parse_string)) { 144 | rv.string++; 145 | rv.offset++; 146 | parse_string++; 147 | } 148 | 149 | while ( (rv.offset < length) && 150 | (!isspace(*parse_string)) && 151 | (*parse_string != '>') && 152 | (*parse_string != '&') && 153 | (*parse_string != '\n')) { 154 | rv.offset++; 155 | parse_string++; 156 | } 157 | *parse_string = 0; 158 | rv.offset++; 159 | 160 | return(rv); 161 | } 162 | 163 | 164 | char *get_next_line(FILE * file) { 165 | /* return next line from file */ 166 | 167 | char buf[BUFSIZ]; 168 | char *index; 169 | 170 | bzero((char *)buf, BUFSIZ); 171 | 172 | while(fgets(buf, BUFSIZ, file)) { 173 | index = buf; 174 | /* advance through whitespaces at the beginning of the line */ 175 | while (isspace((int) *index)) ++index; 176 | 177 | return((char *) strdup(index)); 178 | } 179 | return(NULL); 180 | } 181 | 182 | 183 | -------------------------------------------------------------------------------- /src/util.h: -------------------------------------------------------------------------------- 1 | /* util.h 2 | * Copyright (C) 2005-2006 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | #ifndef __HONEYTRAP_UTIL_H 14 | #define __HONEYTRAP_UTIL_H 1 15 | 16 | #define MAX_LINE 1024 17 | #define READ_SIZE 1440 18 | 19 | struct strtk { 20 | char *string; 21 | int offset; 22 | }; 23 | 24 | typedef struct { 25 | u_int32_t len; 26 | u_char *data; 27 | } bstr; 28 | 29 | /* rfc1918 prefixes */ 30 | static const uint32_t priv_prefixes[] = { 31 | 0x0affffff, // 10.x.x.x 32 | 0xac1fffff, // 172.16.x.x - 172.31.x.x 33 | 0xc0a8ffff // 192.168.x.x 34 | }; 35 | 36 | 37 | int valid_ipaddr(struct in_addr address); 38 | int private_ipaddr(struct in_addr address); 39 | int read_line(int socket, char *line, ssize_t len, int timeout); 40 | struct strtk extract_token(char *parse_string); 41 | char *get_next_line(FILE * file); 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /tools/base64decode.c: -------------------------------------------------------------------------------- 1 | /* base64decode.c 2 | * Copyright (C) 2006 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | * 12 | * 13 | * This file is part of the honeytrap tools collection. 14 | * 15 | * base64decode maps a file into memory, scans it for characteristic 16 | * strings and tries to base64-decode parts of it. 17 | * 18 | * The decoded message is printed to stdout. 19 | * 20 | * Use gcc and compile with -O -fforce-mem -frerun-loop-opti 21 | * to improve performace. 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | struct dec { 36 | char *str; 37 | u_int32_t len; 38 | }; 39 | 40 | struct dec decode(const char* code, int len) { 41 | u_char ch, inbuf[3], outbuf[4]; 42 | u_int32_t charctr, bufctr, ign, eot, i; 43 | struct dec ret; 44 | 45 | eot = 0; 46 | ign = 0; 47 | bufctr = 0; 48 | ret.len = 0; 49 | 50 | ret.str = (u_char*) malloc(len*3/4+1); 51 | bzero(ret.str, len*3/4+1); 52 | 53 | for (i=0; i> 4); 77 | if (charctr > 0) ret.str[ret.len++] = ((inbuf[1] & 0x0F) << 4) | ((inbuf[2] & 0x3C) >> 2); 78 | if (charctr > 1) ret.str[ret.len++] = ((inbuf[2] & 0x03) << 6) | (inbuf[3] & 0x3F); 79 | } 80 | if (eot) return(ret); 81 | } 82 | } 83 | return(ret); 84 | } 85 | 86 | int main(int argc, char *argv[]) { 87 | int fd, bytes_read, i; 88 | struct stat filestat; 89 | u_char *content, *code, v, in[4], out[3]; 90 | struct dec decoded; 91 | 92 | if (argc < 2) { 93 | fprintf(stderr, "Error - No filename given.\n"); 94 | exit(1); 95 | } 96 | 97 | /* open file */ 98 | if ((fd = open(argv[1], O_RDONLY)) == -1) { 99 | fprintf(stderr, "Error - Unable to open file: %s.\n", strerror(errno)); 100 | exit(1); 101 | } 102 | 103 | /* get file size */ 104 | if (fstat(fd, &filestat) != 0) { 105 | fprintf(stderr, "Error - Unable to get file size: %s.\n", strerror(errno)); 106 | exit(1); 107 | } 108 | if (filestat.st_size < 1) { 109 | fprintf(stdout, "File is empty.\n"); 110 | exit(0); 111 | } 112 | 113 | /* map file content into memory */ 114 | if ((content = (u_char *) malloc(filestat.st_size)) == NULL) { 115 | fprintf(stderr, "Error - Unable to allocate memory: %s.\n", strerror(errno)); 116 | exit(1); 117 | } 118 | bzero(content, filestat.st_size); 119 | bytes_read = 0; 120 | if ((bytes_read = read(fd, content+bytes_read, filestat.st_size)) < filestat.st_size) { 121 | if (bytes_read == -1) { 122 | fprintf(stderr, "Error - Unable to map file into memory: %s.\n", strerror(errno)); 123 | exit(1); 124 | } 125 | if (bytes_read == 0) { 126 | fprintf(stderr, "Error - EOF reached too early.\n"); 127 | exit(1); 128 | } 129 | } 130 | close(fd); 131 | 132 | /* look for 'Negotiate ' in content, base64 code starts after it */ 133 | /* checks for other characteristic strings can be done here as well */ 134 | if ((code = strstr(content, "Negotiate "))) code += 10; 135 | else code = content; 136 | 137 | /* decode base64 code */ 138 | decoded = decode((char *)code, bytes_read); 139 | 140 | /* print it to stdout */ 141 | for (i=0; i 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | * 12 | * 13 | * This file is part of the honeytrap tools collection. 14 | * 15 | * bin2hex reads a file bytewise and write its hex values to stdout. 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | int main(int argc, char *argv[]) { 24 | u_char byte; 25 | int retval; 26 | FILE *file; 27 | 28 | if (argc < 2) { 29 | fprintf(stderr, "Error - No filename given.\n"); 30 | exit(1); 31 | } 32 | 33 | /* open file */ 34 | if ((file = fopen(argv[1], "r")) == NULL) { 35 | fprintf(stderr, "Error - Unable to open file: %s.\n", strerror(errno)); 36 | exit(1); 37 | } 38 | 39 | errno = 0; 40 | while((retval = fscanf(file, "%c", &byte)) > 0) fprintf(stdout, "\\x%02x", byte); 41 | if ((retval = EOF) && errno) fprintf(stderr, "Error - Unable to read from file: %s.\n", strerror(errno)); 42 | 43 | fclose(file); 44 | return(0); 45 | } 46 | -------------------------------------------------------------------------------- /tools/edist.c: -------------------------------------------------------------------------------- 1 | /* edist.c 2 | * Copyright (C) 2006 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | * 12 | * 13 | * This file is part of the honeytrap tools collection. 14 | * 15 | * edist calculates the edit distance (aka levenshtein distance) for two 16 | * arbitrary (text or binary) files and tells the percentage of similarity 17 | * and the absolute value. The algorithm variant used here uses linear space. 18 | * 19 | * The edit distance can be used as a metric for binary file comparison. 20 | * Further information can be found on 21 | * . 22 | * 23 | * Use gcc and compile with -O -fforce-mem -frerun-loop-opti 24 | * to improve performace. 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #define COST_INS 1 36 | #define COST_DEL 1 37 | #define COST_REP 1 38 | #define min(a, b) ((a) < (b) ? a : b) 39 | #define max(a, b) ((a) > (b) ? a : b) 40 | 41 | 42 | struct bstr { 43 | u_char *str; 44 | u_int32_t len; 45 | }; 46 | 47 | 48 | /* load data into memory 49 | * faster than mmap() at least on Linux */ 50 | struct bstr file2string(const char *filename) { 51 | int bytes_read, fd; 52 | u_char buffer[BUFSIZ]; 53 | struct bstr bstring; 54 | 55 | bstring.len = 0; 56 | bstring.str = NULL; 57 | 58 | if ((fd = open(filename, 0)) == -1) { 59 | fprintf(stderr, "Unable to open %s: %s.\n", filename, strerror(errno)); 60 | exit(1); 61 | } 62 | while ((bytes_read = read(fd, buffer, BUFSIZ)) > 0) { 63 | if ((bstring.str = (void *) realloc(bstring.str, bstring.len + bytes_read)) == NULL) { 64 | fprintf(stderr, "Unable to allocate memory: %s.\n", strerror(errno)); 65 | exit(1); 66 | } 67 | memcpy(bstring.str + bstring.len, buffer, bytes_read); 68 | bstring.len += bytes_read; 69 | } 70 | if (bytes_read < 0) { 71 | fprintf(stderr, "Unable to read from %s: %s.\n", filename, strerror(errno)); 72 | exit(1); 73 | } 74 | close(fd); 75 | return(bstring); 76 | } 77 | 78 | 79 | /* calculate and return edit distance */ 80 | u_int32_t edit_dist(struct bstr str1, struct bstr str2) { 81 | register u_int32_t i, j; 82 | u_int32_t *p, *q, *r; 83 | 84 | if ((p = (uint *) calloc(str2.len, sizeof(uint))) == NULL) { 85 | fprintf(stderr, "Unable to allocate memory: %s.\n", strerror(errno)); 86 | exit(1); 87 | } 88 | if ((q = (uint *) calloc(str2.len, sizeof(uint))) == NULL) { 89 | fprintf(stderr, "Unable to allocate memory: %s.\n", strerror(errno)); 90 | exit(1); 91 | } 92 | 93 | p[0] = 0; 94 | for(j=1; j<=str2.len; ++j) p[j] = p[j-1] + COST_INS; 95 | 96 | for(i=1; i<=str1.len; ++i) { 97 | q[0] = p[0] + COST_DEL; 98 | for(j=1; j<=str2.len; ++j) 99 | q[j] = min(min(p[j]+COST_DEL, q[j-1]+COST_INS), 100 | p[j-1]+(str1.str[i-1] == str2.str[j-1] ? 0 : COST_REP)); 101 | 102 | r = p; 103 | p = q; 104 | q = r; 105 | } 106 | return(p[str2.len]); 107 | } 108 | 109 | 110 | /* calculate similarity of binary files (in percent) via edit distance */ 111 | int main(int argc, char *argv[]) { 112 | struct bstr bstr1, bstr2; 113 | u_int32_t dist; 114 | double eq, ed; 115 | 116 | if (argc < 3) printf("usage: %s file1 file2\n", argv[0]); 117 | else { 118 | bstr1 = file2string(argv[1]); 119 | bstr2 = file2string(argv[2]); 120 | 121 | // special cases: at least one input is empty 122 | if (!bstr1.len && !bstr2.len) { 123 | printf("Similarity: 100%% (edit distance: 0).\n"); 124 | return(EXIT_SUCCESS); 125 | } 126 | if (!bstr1.len || !bstr2.len) { 127 | printf("Similarity: 0%% (edit distance: %u).\n", abs(bstr1.len-bstr2.len)); 128 | return(EXIT_SUCCESS); 129 | } 130 | 131 | dist = edit_dist(bstr1, bstr2); 132 | 133 | ed = edit_dist(bstr1, bstr2) - abs(bstr1.len-bstr2.len); 134 | eq = bstr1.len + bstr2.len - abs(bstr1.len-bstr2.len); 135 | eq = 1 - (ed / eq); 136 | 137 | printf("Similarity: %.2f%% (edit distance: %u).\n", eq, dist); 138 | } 139 | return(EXIT_SUCCESS); 140 | } 141 | -------------------------------------------------------------------------------- /tools/hex2bin.c: -------------------------------------------------------------------------------- 1 | /* hex2bin.c 2 | * Copyright (C) 2006-2008 Tillmann Werner 3 | * 4 | * This file is free software; as a special exception the author gives 5 | * unlimited permission to copy and/or distribute it, with or without 6 | * modifications, as long as this notice is preserved. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 10 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | * 12 | * 13 | * This file is part of the honeytrap tools collection. 14 | * 15 | * hex2bin reads input in hexadecimal notion from a file, converts it into 16 | * binary data and writes it to stdout. This is useful for converting 17 | * exploit code or malware binaries that are submitted in hex. 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | int main(int argc, char *argv[]) { 27 | char option; 28 | u_char buf[4]; 29 | unsigned int chr[2]; 30 | int swap, retval; 31 | FILE *file; 32 | 33 | swap = 0; 34 | 35 | // process args 36 | while((option = getopt(argc, argv, "sh?")) > 0) { 37 | switch(option) { 38 | case 's': 39 | swap = 1; 40 | break; 41 | case 'h': 42 | case '?': 43 | default: 44 | printf("Usage: %s [-s] file (-s swaps byte order)\n", argv[0]); 45 | exit(EXIT_SUCCESS); 46 | } 47 | } 48 | 49 | // open file 50 | if (argc - optind < 1) { 51 | fprintf(stderr, "Error - No filename given.\n"); 52 | exit(EXIT_FAILURE); 53 | } 54 | if ((file = fopen(argv[optind++], "r")) == NULL) { 55 | fprintf(stderr, "Error - Unable to open file: %s.\n", strerror(errno)); 56 | exit(EXIT_FAILURE); 57 | } 58 | 59 | // process data 60 | errno = 0; 61 | for (;;) switch ((retval = fread(&buf, 2, 2, file))) { 62 | case 0: 63 | fclose(file); 64 | if ((retval = EOF) && errno) { 65 | fprintf(stderr, "Error - Unable to read from file: %s.\n", strerror(errno)); 66 | exit(EXIT_FAILURE); 67 | } 68 | exit(EXIT_SUCCESS); 69 | case 1: 70 | sscanf((char *) buf, "%2x", &chr[0]); 71 | fprintf(stdout, "%c", chr[0]); 72 | break; 73 | case 2: 74 | sscanf((char *) buf, "%2x%2x", &chr[0], &chr[1]); 75 | fprintf(stdout, "%c%c", swap ? chr[1] : chr[0], swap ? chr[0] : chr[1]); 76 | break; 77 | } 78 | 79 | exit(EXIT_SUCCESS); // never reached 80 | } 81 | -------------------------------------------------------------------------------- /tools/ngtrie.c: -------------------------------------------------------------------------------- 1 | /* ngtrie.c 2 | * Copyright (C) 2007 Tillmann Werner 3 | * Till Breuer 4 | * 5 | * This file is free software; as a special exception the author gives 6 | * unlimited permission to copy and/or distribute it, with or without 7 | * modifications, as long as this notice is preserved. 8 | * 9 | * This program is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 11 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * 13 | * 14 | * This file is part of the honeytrap tools collection. 15 | * 16 | * ngtrie calculates the similarity between two input files 17 | * using n-grams stored in a trie. 18 | * 19 | * The similarity in percent is printed to stdout. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | struct trie_node; 35 | typedef struct trie_node *trie; 36 | 37 | typedef struct trie_node { 38 | u_char key; 39 | u_int16_t array_size; 40 | u_int32_t freq1; 41 | u_int32_t freq2; 42 | trie childlist; 43 | } trie_node; 44 | 45 | 46 | double sqrnorm1, sqrnorm2, dotprod; 47 | 48 | 49 | trie find_node(trie t, u_int16_t size, u_char key) { 50 | u_int16_t i=0; 51 | u_int16_t high, low; 52 | 53 | if (t == NULL) return(NULL); 54 | 55 | for (low=0, high=(size-1); high-low>0; ) { 56 | i = (high+low)/2; 57 | if (key <= (t+i)->key) high = i; 58 | else{ 59 | i = (high+low+1)/2; 60 | low = i; 61 | } 62 | } 63 | return(t[i].key == key ? &t[i] : NULL); 64 | } 65 | 66 | trie insert_new_child_node(trie parent, u_char key, u_char snum) { 67 | u_int16_t i = 0; 68 | int high, low; 69 | trie t = NULL; 70 | 71 | if ((t = realloc(parent->childlist, sizeof(trie_node)*(parent->array_size+1))) == NULL) { 72 | fprintf(stderr, "Error - Unable to allocate memory: %s.\n", strerror(errno)); 73 | exit(EXIT_FAILURE); 74 | } 75 | parent->childlist = t; 76 | parent->array_size++; 77 | 78 | if (parent->array_size > 1) { 79 | /* multiple nodes, binary-search array position and memmove */ 80 | i = 0; 81 | for (low=0, high=(parent->array_size-1); high-low>0; ) { 82 | i = (high+low)/2; 83 | if (key <= (t+i)->key) high = i; 84 | else { 85 | i = (high+low+1)/2; 86 | low = i; 87 | } 88 | } 89 | if (key < t[i].key) memmove(&t[i+1], &t[i], (parent->array_size-i-1)*(sizeof(trie_node))); 90 | else { 91 | if (i != parent->array_size-2) { 92 | memmove(&t[i+2], &t[i+1], (parent->array_size-i-1)*(sizeof(trie_node))); 93 | } 94 | } 95 | t = &t[i]; 96 | 97 | } 98 | 99 | memset(t, 0, sizeof(trie_node)); 100 | t->key = key; // set first element 101 | if (snum) t->freq2=1; 102 | else t->freq1=1; 103 | 104 | return(t); 105 | } 106 | 107 | 108 | /* inserts an ngram into the trie or update its frequency */ 109 | void ngram_ins(trie t, const u_char *data, ssize_t n, u_char snum) { 110 | ssize_t k; 111 | trie target_node; 112 | 113 | if (t == NULL) { 114 | fprintf(stderr, "Error - Cannot insert into empty trie.\n"); 115 | exit(EXIT_FAILURE); 116 | } 117 | 118 | for (k=0; kchildlist, t->array_size, data[k])) == NULL) { 121 | if ((t = insert_new_child_node(t, data[k], snum)) == NULL) { 122 | fprintf(stderr, "Error - Unable to create new trie node: %s.\n", strerror(errno)); 123 | exit(EXIT_FAILURE); 124 | } 125 | } else { 126 | t = target_node; 127 | /* we're always at the right node here, update frequency */ 128 | (snum == 0) ? t->freq1++ : t->freq2++; 129 | } 130 | } 131 | return; 132 | } 133 | 134 | 135 | 136 | /* builds a trie of ngrams */ 137 | trie build_ngram_trie(trie t, int n, const u_char *data1, const u_char *data2, ssize_t len1, ssize_t len2) { 138 | ssize_t pos = 0; 139 | 140 | /* process data strings */ 141 | if (len1 < len2) { 142 | for (pos=0; pos < len1-n+1; pos++) ngram_ins(t, &data1[pos], n, 0); 143 | for (pos=0; pos < len2-n+1; pos++) ngram_ins(t, &data2[pos], n, 1); 144 | } else { 145 | for (pos=0; pos < len2-n+1; pos++) ngram_ins(t, &data2[pos], n, 0); 146 | for (pos=0; pos < len1-n+1; pos++) ngram_ins(t, &data1[pos], n, 1); 147 | } 148 | 149 | return(t); 150 | } 151 | 152 | 153 | void calc_and_del_trie(trie t, u_int16_t node_size, int depth) { 154 | u_int16_t i = 0; 155 | 156 | if (t == NULL) return; 157 | 158 | for (i=0; ichildlist == NULL) { 160 | sqrnorm1 += pow(t[i].freq1, 2); 161 | sqrnorm2 += pow(t[i].freq2, 2); 162 | dotprod += t[i].freq1 * t[i].freq2; 163 | } else calc_and_del_trie(t[i].childlist, t[i].array_size, depth+1); 164 | } 165 | free(t); 166 | 167 | return; 168 | } 169 | 170 | 171 | int main(int argc, char *argv[]) { 172 | int fd, bytes_read, n, i; 173 | struct stat fs[2]; 174 | u_char *content[2]; 175 | double result; 176 | trie_node ngtrie; 177 | 178 | n = 0; 179 | result = 0; 180 | dotprod = 0; 181 | sqrnorm1 = 0; 182 | sqrnorm2 = 0; 183 | result = 0; 184 | bytes_read = 0; 185 | content[0] = NULL; 186 | content[1] = NULL; 187 | 188 | if (argc < 4) { 189 | fprintf(stdout, "Usage: %s n file1 file2\n", argv[0]); 190 | exit(EXIT_SUCCESS); 191 | } 192 | 193 | if ((n = atoi(argv[1])) == 0) n = 3; 194 | 195 | /* mmap files */ 196 | for (i=0; i<2; i++) { 197 | if ((fd = open(argv[i+2], O_RDONLY)) == -1) { 198 | fprintf(stderr, "Error - Unable to open file: %s.\n", strerror(errno)); 199 | exit(EXIT_FAILURE); 200 | } 201 | if (fstat(fd, &fs[i]) != 0) { 202 | fprintf(stderr, "Error - Unable to get file size: %s.\n", strerror(errno)); 203 | exit(EXIT_FAILURE); 204 | } 205 | if (fs[i].st_size < 1) { 206 | fprintf(stdout, "File %s is empty.\n", argv[i+2]); 207 | exit(EXIT_SUCCESS); 208 | } 209 | if ((content[i] = mmap(0, fs[i].st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) { 210 | fprintf(stderr, "Error - Unable to map file into memory: %s.\n", strerror(errno)); 211 | exit(EXIT_FAILURE); 212 | } 213 | close(fd); 214 | } 215 | 216 | /* don't be shy, put in a trie */ 217 | memset(&ngtrie, 0, sizeof(trie_node)); 218 | if ((build_ngram_trie(&ngtrie, n, content[0], content[1], fs[0].st_size, fs[1].st_size)) == NULL) { 219 | printf("No trie built.\n"); 220 | exit(EXIT_SUCCESS); 221 | } 222 | 223 | /* calculate vector lenghts and delete trie */ 224 | result = dotprod = sqrnorm1 = sqrnorm2 = 0; 225 | calc_and_del_trie(ngtrie.childlist, ngtrie.array_size, 0); 226 | 227 | /* calculate similarity */ 228 | if (isnan(result = 100-(100*acos(dotprod/(sqrt(sqrnorm1)*sqrt(sqrnorm2)))/1.5707963))) result = 100; 229 | fprintf(stdout, "Similarity: %.2f%%.\n", result); 230 | 231 | if ((munmap(content[0], fs[0].st_size) != 0) || (munmap(content[1], fs[1].st_size) != 0)) { 232 | fprintf(stderr, "Unmapping files failed: %s.\n", strerror(errno)); 233 | exit(EXIT_FAILURE); 234 | } 235 | 236 | return(EXIT_SUCCESS); 237 | } 238 | 239 | --------------------------------------------------------------------------------