29 October, 2006

Hacker's friend: nmap, part two

Advanced scanning


Ping scan, List scan


Ping scan is used to scan large number of IP addresses for computers alive. As I mentioned in part one, by default every scan is preceded by a ping scan to see if the host is online.

$ nmap -sP 10.0.0.2

Starting Nmap 4.01 ( http://www.insecure.org/nmap/ ) at 2006-10-26 19:38 CEST
Host 10.0.0.2 appears to be up.
Nmap finished: 1 IP address (1 host up) scanned in 0.283 seconds


Ok, the scanned host is up, but this is not really interesting. Here's another scan.

$ nmap -sP 10.0.0.0/24

Starting Nmap 4.01 ( http://www.insecure.org/nmap/ ) at 2006-10-26 19:38 CEST
Host 10.0.0.2 appears to be up.
Host 10.0.0.138 appears to be up.
Nmap finished: 256 IP addresses (2 hosts up) scanned in 2.552 seconds


A little explanation about the address I specified in this scan: it features a /24 suffix, which denotes that it's not a single IP address but a range, it's called CIDR notation.
IP addresses are 32 bit numbers, usually presented as four 8 bit (0-255) numbers separated by dots for human consumption, this is called the dotted decimal notation. In the CIDR notation, the appended number after the slash is the number of significant bits in the address, these bits make up the prefix of the group: they are the same for every single address in the group. In my scan, it's 24, so there are 24 bits in the prefix, and 8 bits of the address are variable. This makes 10.0.0 the prefix, and leaves the last number variable, giving 256 possible addresses, from 10.0.0.0 to 10.0.0.255. If I scanned for 10.0.0.16/28, that would be only 2^4 = 16 hosts, ranging from 10.0.0.16 to 10.0.0.31. (16 is 00010000 in binary, the last 4 bits are variable, to it can range from 00010000 to 00011111.)
The list scan (-sL) is just the right tool to practice CIDR notation, as it does nothing but enumerates all the addresses in the given range.

A more straightforward way to supply IP ranges to nmap is like the port ranges: 10.0.0.0/24 is the same as 10.0.0.0-255.

FIN (-sF), Xmas tree (-sX) and Null (-sN) scans


In the previous part, I explained how SYN scan might just evade detection by not opening connections. However SYN scans are already looked for, so here are some more variation on the same, with more chance of being undetected and somewhat less chance of success.
When an endpoint decide to close it's TCP connection, it sends a packet with the FIN and ACK signals. The other end responds by sending an ACK+FIN packet, which is acknowledged with an ACK packet from the initiator, and at this moment the connection is fully closed. But what happens when a FIN packet is sent without an established connection? In this case, a packet with RST (reset) should sent back if the port is closed. Which makes sending FIN packets just the right tool to determine whether a port is closed or not. Well, almost, as Windows machines ignore these FIN packets, and never response to them.
Xmas tree and Null scans are quite similar in concept to FIN scan. Xmas tree scan has the URG (urgent) and PUSH flags also set along with the FIN, which make the flag bits alternating just like the lights on a Christmas tree, while Null scan has no flags set at all. Both of them supposed to get RST response in case a closed port is hit, and none of them get any response from a Windows box, just like FIN scans.
These scans used to be more stealth than a SYN scan, but nowadays IDSs do look out for them. For example every Null packet should raise suspicion as having no flags should not occur in normal traffic. This and the behavior of Windows systems make these less useful as port scanning techniques, and makes them more of a tool for OS fingerprinting, which will be taken care of in the next part of the series. These scans cannot make a difference between open and filtered ports, so the possible states reported by nmap are open|filtered and closed.

ACK scan (-sA) and Window scan (-sW)


These scans are used to learn about the firewalls ruleset. ACK scan sends ACK packets without anything to be acknowledged, so they should get RST replies from both open and closed ports. If there is no reply, it means the port is filtered. Otherwise it's reported as unfiltered.
Window scan takes this one step further, by examining the RST packet. Some systems has a behavior of setting TCP window size of it to zero in case a close port is hit and to non-zero for open ports. Actually this is quite rare, so just like FIN/Xmas/Null scans, it's more of a fingerprinting tool than a port scanning.


Staying under the radar


Every scan previously described might leave records in firewall/IDS logs along with our IP address, which is sometimes not desirable. But nmap offers quite a bunch of tricks to help evading detection.

Timing


There are lots of traffic on the Internet, and every host is hit by some random packets occasionally. IDSs can't log all of them, because it were just as useless as not logging anything: interesting events would be masked by the million lines of normal network noise. So instead of logging everything, they look for suspicious events, which look like intentional probing. If a thousand SYN packet arrives from a single host within a second, aimed at different ports, that looks quite like a SYN scan so it worth a line saying something like “[28-10-2006 20:11] Possible SYN scan from IP”. But if only one arrives from a host for minutes, that's quite normal. Tedious way to scan thousands of ports, but very hard to detect.
By default nmap sends many packets a second in parallel to achieve decent scan speed. But it also offers many options to change this. The most basic is the -Tn which sets a timing profile where n ranges from 0 to 5 (from slowest to fastest: Paranoid, Sneaky, Polite, Normal, Aggressive, Insane). -T1 might be slow enough, with 15 second waits between the probes, which gives 240 probes in an hour, while -T0 waits 5 minutes between each probe, and neither allows parallel scanning.

Decoys


In the previous section, I said that having too much noise compared to the useful records in IDS logs can be just as bad as having no records at all. Our IP address might appear in the log files, but if it's accompanied with dozens of other decoy IP addresses at the same, we will remain unidentified. We can accomplish this by sending the scanning packets with spoofed addresses along with the ones having our address. The list of addresses to be spoofed is supplied after the -D argument. Before blindly supplying random addresses, you might want to check if they are up, because if all entries in the IDS logs are down but one, it might be easy to figure out the culprit. Also, some ISPs filter out packets with spoofed addresses, so this may not work for you.

Fragmentation


Networking devices have an upper limit for transmission size, which is called MTU. If a packet exceeds this, it needs to be split into smaller chunks, this is called fragmentation. The receiving network stack notices that a packet is fragmented, waits till every piece arrives, then assemblies it to proceed. Generally MTU sizes ranges from hundreds of bytes to thousands, with a most common size of 1400-1500 bytes. What happens if we send packets using an MTU as small as 8 bytes? The TCP header is at least 20 bytes long, so it's fragmented into at least 3 pieces. These pieces alone do not contain enough information to determine their nature, and they might even arrive in the wrong order, so it makes hard to detect the probes. Also, having small fragments is quite ordinary: even normal internet traffic can generate small fragments for the trailing part of a packet.
Fragment size can also be set to an arbitrary multiple of 8 with the --mtu flag.

Idle scan


This one is truly ingenious. We will need a zombie host that fulfills some criteria. 1. It must be up. 2. It must have sequential IP id numbers. Sequential IPID means the sequence number in the IP header increases by 1 with each IP packet sent out. 3. It must not have network traffic during the scan. Nmap might handle zombies with occasional traffic, but the ideal zombie would have no traffic.
The scan works like this: 1. We probe the zombie for it's current IPID, which is N. Then we send a SYN packet to the target machine, but with the address spoofed to look like it's from the zombie. If the port is open, the target replies to the zombie with a SYN+ACK packet. As the zombie has no idea what that packet should mean (it didn't initiate connection), replies with a RST packet. If the port is closed or filtered, nothing happens. Now, we probe the zombie again to determine it's actual IPID. If it's N+2 it means the zombie sent out a packet since our last probe: as the zombie is supposedly idle, it must be RST reply, which means the port on the target is open. If the IPID is N+1, nothing happened since our last probe, so the port must be closed.
This scan is really stealthy, because we don't send a single packet to the target containing our own IP address. However, we need to be able to send out spoofed addresses, which might be filtered by our ISP. Also this scan is slower and less reliable: if the zombie has some other traffic, but not significant enough to be caught by nmap, this may result in closed ports reported being open.

23 October, 2006

Hacker's friend: nmap, part one

Nmap, the network mapper is a great tool for profiling whole networks, even ones as large as the Internet. It redefines the meaning of port scanner, while having much more other uses. This part of the series will discuss nmap's general port scanning capabilities.

Port scanner


TCP scan


TCP is the most widely used protocol on the Internet, so the default scanning mode for non-root users is the TCP scan. (Root can enforce it with the “-sT” switch.) It's the most simple scanning mode, tries to open a TCP connection to the selected ports, and then reports back the results.

$ nmap localhost

Starting Nmap 4.01 ( http://www.insecure.org/nmap/ ) at 2006-10-23 00:19 CEST
Interesting ports on localhost (127.0.0.1):
(The 1671 ports scanned but not shown below are in state: closed)
PORT STATE SERVICE
22/tcp open ssh

Nmap finished: 1 IP address (1 host up) scanned in 0.275 seconds


It found port 22 open, which is the default port for ssh. There are 1671 ports which were scanned, and found to be closed, thus not reported. By default, nmap scans for only “interesting” ports, we can override this behaviour by specifying a port range or list with the “-p” command, like this:

$ nmap -sT localhost -p 1-65535

Starting Nmap 4.01 ( http://www.insecure.org/nmap/ ) at 2006-10-23 00:30 CEST
Interesting ports on localhost (127.0.0.1):
(The 65534 ports scanned but not shown below are in state: closed)
PORT STATE SERVICE
22/tcp open ssh

Nmap finished: 1 IP address (1 host up) scanned in 3.874 seconds

The closed port count went up to 65534, meaning that there are no ports open other than 22. Port ranges are denoted n-m, where n is the starting port number, m is the ending. If either side of the range is missing, 1 is assumed for starting and 65535 for ending, thus “-p 1-65535” means the same range as “-p 1-”, “-p -65535” and even “-p -”. Port lists are formed by supplying port numbers and ranges separated by commas, like this: “-p 20-25,80,443”.

As this scan use an ordinary TCP connection to find open ports, there are three possible states reported back, depending on the outcome of the TCP handshake attempt. First, the initiating machine sends a packet with the SYN (Synchronize) flag set, this indicates that it wants to connect the specified port. If the port is closed, a ACK+RST (Acknowledge, Reset) packed is sent back, these ports are reported as closed by nmap. If the port is open, the target sends a SYN+ACK packet, and the initiator machine responds it with an ACK, acknowledging the acknowledge if the SYN. As soon as this ACK arrives to the target, the handshake is completed, the connection is established, and reported as open by nmap.
The third scenario is when the SYN packet has no replies at all, these ports are reported as “filtered” by nmap. This could mean a firewall set up to drop packets without notification or a machine offline. By default, nmap makes a ping probe before every scan to make sure the target is online so it won't bang nonexistent doors. If the machine does not respond to an ordinary ping packet, the scan does not start at all. This can be overridden with the “-P0” argument in case the machine is reachable but does not respond to pings.

Stealth scan


The problem with the TCP scan is that it opens a TCP connection, so the scan might appear in the log files of the programs listening on the scanned ports, and definitely appears in firewall/IDS logs, and we might just not want that. One solution might be the use of stealth (SYN) scan, which is the default scanning mode for root users, and can be enforced with the “-sS” argument. This scan (just like other, more advanced features offered by nmap) needs to create raw packets, which is generally available for root users only.

This scan starts with a SYN packet, just like a normal TCP handshake. No replies reported back as filtered, RST ones as closed, and SYN+ACK as open. However, the scanner never replies with ACK to the SYN+ACK packets, so the connection will not be established. After some waiting for the ACK packet, the target gives up and drops the half-opened connection.

By not making any TCP connections, this scan might just stay under the radar. However, most modern firewalls and every decent intrusion detection systems (IDSs) do detect SYN scans, so there's still a good chance the scan will get noticed. The next part will discuss what measurements nmap has to reduce this chance.

UDP scan


UDP is a connectionless protocol, thus it lacks the 3-way handshake TCP has. UDP packets are sent out without any initiation, and then forgot about. There are no acknowledge of acceptance or loss, the only response an UDP packet can generate is a “Port unreachable” ICMP packet, which roughly means “don't send any more UDP packets to this port, I'm not accepting it”.

Nmap does UDP scans if the -sU argument is specified.

$ sudo nmap -sU -P0 10.0.0.138

Starting Nmap 4.01 ( http://www.insecure.org/nmap/ ) at 2006-10-23 14:14 CEST
Interesting ports on 10.0.0.138:
(The 1477 ports scanned but not shown below are in state: closed)
PORT STATE SERVICE
53/udp open|filtered domain
67/udp open|filtered dhcps
68/udp open|filtered dhcpc
161/udp open|filtered snmp
1900/udp open|filtered UPnP
MAC Address: 00:90:D0:B0:5A:6E (Thomson Telecom Belgium)

Nmap finished: 1 IP address (1 host up) scanned in 3.314 seconds


Nmap reports closed state if it got “port unreachable” response and open|filtered if there was no response to the UDP packet sent, because there are no ways to know the reason for the lack of response. Possible reasons are: 1. the port is open and the packet was accepted; 2. the firewall dropped the UDP packet, so the port can be either open or closed; 3. the packet was lost before reaching the target computer; 4. the “port unreachable” ICMP response was lost before reaching the scanning computer.
This makes the scan very unreliable. Also, the rate at which the “port unreachable” packets are generated are generally limited, so a thorough UDP scan needs to wait a lot before giving up waiting for the response, which makes the scan slow too. These and the limited number of services using UDP make this scan less than useful for most of the cases.

One thing to notice is the MAC address line. On ethernet networks, nmap reports the MAC address, and the vendor which owns the address range it's in.

Part two

17 October, 2006

Exploit for NVIDIA binary graphics driver for Linux

An exploit has been published for the closed source graphics driver from NVIDIA. The buffer overflow bug can result in locally and probably remotely executed arbitrary code as root. FreeBSD and Solaris drivers could be affected too.

Closed source drivers


Having closed source drivers leaves the users at the mercy of the vendor. In this case, this very bug was reported back to NVIDIA 2 years ago. NVIDIA didn't want to fix that bug, and no one else had a chance to. And if you happen to have a pre-Geforce3 video card, tough luck. NVIDIA dropped support for those drivers, so no fixes for you. If the drivers were open source, this would be no problem. Only a single line of code is required, checking that the allocated buffer is big enough for the glyph data it supposed to contain. Nothing a friendly hacker next door couldn't do.

Closed source drivers as kernel modules


Closed source kernel modules not only break Linux's GPL license, but also impose a great security risk. Being closed source, the code cannot be audited and/or fixed in case a bug was found. Putting such insecure code into kernel space is a real threat. In case of a bug allowing arbitrary code execution, an exploit may gain privileges not available for user space code running as root.

Solution


The bug was fixed in the recently >=1.0-9625 drivers. For video cards <Geforce3 (and Geforce 4mx, of course), the only solution is to use the nv driver shipped with Xorg. Without 3D acceleration support, of course.

Bonus


At Kerneltrap, there is a comment with a proof-of-concept url http://nvidia.com/content/license/location_0605.asp?url=';a='a';i=18;while(i--)a%2b=a;location=a;//
Opening this url makes the browser (does not work on Konqueror) fill the URL line with the letter 'a', which is enough to exploit the bug and cause DoS. Having arbitrary code executed this way is of course harder, but this is bad enough already.

15 October, 2006

Linux, the real-time kernel

As of 2.6.18, the mainline Linux kernel has gained real-time features. But there are some confusion about the benefits and drawbacks of having real-time capabilities.

What's all the fuss about?


Real-time isn't about high throughput or low latencies. Real-time is about having predictability and consistency. The kernel must make good predictions about how long an operation will take, and meet those predictions under any circumstances. Even even if a certain application decides to eat up all memory and introduce massive swapping, or a device starts sending millions of hardware interrupts in every second. A real-time kernel must handle and schedule those events in a fashion so it can meet the promised execution times.

Ok, that sounds nice. Where are the drawbacks?


There's no such thing as free lunch. The price of these strict conditions is reduced speed. Most operations (like disk I/O) have the highest throughput if they are sustained without any interruptions, and the constant preemption and task switching interferes with this. Preemption has overhead. The scheduler, which decides what task should be taken care of has overhead.

So, do I need real-time kernel?


There are two categories of real-time. Hard real-time means strict schedule: a task finished late as bad as a task not done. Hard real-time is necessary in critical environments, like nuclear plants, or medical equipment. Take an X-ray machine, designed to fire 50ms pulses of Roentgen-radiation. It would be unacceptable to have 2-3 second long pulses because the kernel was busy processing the insane amount of interrupts sent by a malfunctioning component or stuck button. With soft real-time, occasionally violating the time constraints is allowed. For a TV station, the occasional loss of a single frame is acceptable if otherwise the video stream is fluid.
But for common desktop or server use, real-time capabilities are not necessary. Soft real-time can be useful for some video/audio professionals, but has no use for DVD-ripping/transcoding and makes it longer.

Conclusion


Having official support for real-time facilities in the Linux kernel is a great thing. It can reach now niche markets like some embedded systems where real-time is a must. And what about the rest of us, running our desktops and servers on Linux? All of us will benefit of the SMP/locking bugs found and fixed during the development of the rt patchset, without ever turning on the CONFIG_PREEMPT_RT option.

0-day exploits for FreeBSD <=6.1-RELEASE-p10

Two new local DoS exploits were publised for FreeBSD.
The first one use the ftruncate syscall to crash the system, and possibly screw the filesystem.

The second one is exploiting a bug in the scheduler.

Every FreeBSD releases are vulnerable.

14 October, 2006

Spamming the whois database

Every once in a while, someone's reporting that Whois gives back strange reports for queries like msn.com:
MSN.COM.TW
MSN.COM.SUCKS.FIND.CRACKZ.WITH.SEARCH.GULLI.COM
MSN.COM

Then speculations arise about possible MSN or DNS or Whois hacks. However, this is only the result of a not-so-thorough Whois implementation.

The Whois database is the place for recording information about TDLs (top level domains). Generally the records consist of the name and contact of the owner, the registrar, registration/modification/expiration dates and the name servers of the domain.

Now, let's say I register example.com, and I decide to set up some subdomains. So I have www.example.com, this.is.an.example.com and msn.com.hacked.as.an.example.com. As they are valid host names, I could use them as name servers, and even report them to the whois database as such. Then when doing a whois search for msn.com would turn up my name server's address, as whois uses only simple text matching.

See also:
Wikipedia entry on whois
RFC 3912, the current Whois protocol specification