Tried to create a script that would be a little more efficient than greping one IP Address at a time from a long list provided:
#!/bin/bash
# Tried to make searching through logs more efficient with this script by batching the grep statements
arrayIPAddr=()
while read line
do
arrayIPAddr+=("$line")
arrayIPSize=${#arrayIPAddr[@]}
# Only issue is the last 1 to 14 records will not be looked at due to the hard cutoff at 15
if [ $arrayIPSize == 15 ]; then
cat logfile.txt | grep -e ${arrayIPAddr[0]} -e ${arrayIPAddr[1]} -e ${arrayIPAddr[2]} -e ${arrayIPAddr[3]} -e ${arrayIPAddr[4]} -e ${arrayIPAddr[5]} -e ${arrayIPAddr[6]} -e ${arrayIPAddr[7]} -e ${arrayIPAddr[8]} -e ${arrayIPAddr[9]} -e ${arrayIPAddr[10]} -e ${arrayIPAddr[11]} -e ${arrayIPAddr[12]} -e ${arrayIPAddr[13]} -e ${arrayIPAddr[14]}
arrayIPAddr=()
fi
done < "ipList.txt"
As far as results, with this I was able to cut the amount of time it took down to 5 seconds to search the log. Thought this would be a helpful script to hold onto for future reference.
Twitter: @lokut
This blog is for educational purposes only. The opinions expressed in this blog are my own and do not reflect the views of my employers.
Tuesday, October 29, 2013
Tuesday, August 27, 2013
Cisco Password 7 Decrypter
#!/usr/bin/perl
use File::Copy;
############################################################################
# Vigenere translation table
############################################################################
@V=(0x64, 0x73, 0x66, 0x64, 0x3b, 0x6b, 0x66, 0x6f, 0x41, 0x2c, 0x2e,
0x69, 0x79, 0x65, 0x77, 0x72, 0x6b, 0x6c, 0x64, 0x4a, 0x4b, 0x44,
0x48, 0x53, 0x55, 0x42, 0x73, 0x67, 0x76, 0x63, 0x61, 0x36, 0x39,
0x38, 0x33, 0x34, 0x6e, 0x63, 0x78, 0x76, 0x39, 0x38, 0x37, 0x33,
0x32, 0x35, 0x34, 0x6b, 0x3b, 0x66, 0x67, 0x38, 0x37);
############################################################################
############################################################################
# Usage guidelines
############################################################################
if ($ARGV[0] eq ""){
print "This script reveals the IOS passwords obfuscated using the Vigenere algorithm.n";
print "n";
print "Usage guidelines:n";
print " cdecrypt.pl 04480E051A33490E # Reveals a single passwordn";
print " # Original file stored with .bak extensionn";
}
############################################################################
# Process arguments and execute
############################################################################
print Decrypt($ARGV[0]) . " " . $ARGV[0] . "\n"; # Prints the plain text password and the encrypted one
############################################################################
# Vigenere decryption/deobfuscation function
############################################################################
sub Decrypt{
my $pw=shift(@_); # Retrieve input obfuscated password
my $i=substr($pw,0,2); # Initial index into Vigenere translation table
my $c=2; # Initial pointer
my $r=""; # Variable to hold cleartext password
while ($c<length($pw)){ # Process each pair of hex values
$r.=chr(hex(substr($pw,$c,2))^$V[$i++]); # Vigenere reverse translation
$c+=2; # Move pointer to next hex pair
$i%=53; # Vigenere table wrap around
} #
return $r; # Return cleartext password
}
use File::Copy;
############################################################################
# Vigenere translation table
############################################################################
@V=(0x64, 0x73, 0x66, 0x64, 0x3b, 0x6b, 0x66, 0x6f, 0x41, 0x2c, 0x2e,
0x69, 0x79, 0x65, 0x77, 0x72, 0x6b, 0x6c, 0x64, 0x4a, 0x4b, 0x44,
0x48, 0x53, 0x55, 0x42, 0x73, 0x67, 0x76, 0x63, 0x61, 0x36, 0x39,
0x38, 0x33, 0x34, 0x6e, 0x63, 0x78, 0x76, 0x39, 0x38, 0x37, 0x33,
0x32, 0x35, 0x34, 0x6b, 0x3b, 0x66, 0x67, 0x38, 0x37);
############################################################################
############################################################################
# Usage guidelines
############################################################################
if ($ARGV[0] eq ""){
print "This script reveals the IOS passwords obfuscated using the Vigenere algorithm.n";
print "n";
print "Usage guidelines:n";
print " cdecrypt.pl 04480E051A33490E # Reveals a single passwordn";
print " # Original file stored with .bak extensionn";
}
############################################################################
# Process arguments and execute
############################################################################
print Decrypt($ARGV[0]) . " " . $ARGV[0] . "\n"; # Prints the plain text password and the encrypted one
############################################################################
# Vigenere decryption/deobfuscation function
############################################################################
sub Decrypt{
my $pw=shift(@_); # Retrieve input obfuscated password
my $i=substr($pw,0,2); # Initial index into Vigenere translation table
my $c=2; # Initial pointer
my $r=""; # Variable to hold cleartext password
while ($c<length($pw)){ # Process each pair of hex values
$r.=chr(hex(substr($pw,$c,2))^$V[$i++]); # Vigenere reverse translation
$c+=2; # Move pointer to next hex pair
$i%=53; # Vigenere table wrap around
} #
return $r; # Return cleartext password
}
Saturday, August 10, 2013
Using aircrack-ng, airdecap-ng, tshark, and grep regex
Recently in a capture the flag event I had to utilize aircrack-ng to break the WEP key on a packet capture, then airdecap-ng to decrypt the contents of the WEP packets and export them to another packet capture, use tshark to output to text and then use a grep regular expression to extract base64 Authentication Basic username and passwords.
Below are the commands that I ran to accomplish this:
# aircrack-ng WIRELESS-C2.cap
Opening WIRELESS-C2.cap
Read 73650 packets.
# BSSID ESSID Encryption
1 00:40:10:20:00:03 Wireless Challenge Two WEP (25704 IVs)
Choosing first network as target.
Opening WIRELESS-C2.cap
Attack will be restarted every 5000 captured ivs.
Starting PTW attack with 25704 ivs.
Aircrack-ng 1.2 beta1
[00:00:00] Tested 397 keys (got 25082 IVs)
KB depth byte(vote)
0 2/ 4 DA(31232) C0(30976) 22(30720) E8(30720) 16(30208) 25(30208) D0(30208)
1 0/ 1 1C(35840) 03(32256) 7F(32000) B7(32000) F2(30464) 95(30208) 86(29952)
2 0/ 5 91(34048) CC(33792) 2D(32512) 58(31232) 84(31232) 2F(30720) 3D(30720)
3 5/ 26 0A(30208) 39(30208) 5B(30208) 62(29952) ED(29696) 02(29696) 2E(29696)
4 0/ 1 C4(35072) 19(31744) 31(30464) CD(30208) 10(29696) 6E(29696) D5(29696)
KEY FOUND! [ C0:1C:91:0A:C4 ]
Decrypted correctly: 100%
# airdecap-ng -w c01c910ac4 WIRELESS-C2.cap
## Open up in Wireshark the WIRELESS-C2-dec.cap
## Add filter for (http.request.method == "GET") || (http.request.method == "POST")
## After the filter is applied find the management.asp page
## Right-click and follow TCP stream
## In the open window you find the "Authorization: Basic cm9vdDphZG1pbg=="
## The base64 encoding is the admin username and password
## Decoded the username and password is root:admin
## OR you can use tshark and export the packet information to a file
# tshark -V -r WIRELESS-C2-dec.cap > WIRELESS-dec.txt
## Then wrote a short and sweet regex to extract base64 encoded strings
# cat WIRELESS-C2-dec.txt | grep '\+*[A-Za-z0-9]\{11,\}\+=' # Find base64 encoded text that is 11 characters or longer
## Walla! Authorization: Basic cm9vdDphZG1pbg==\r\n
## Then you can decode it from the command line by doing the following
echo "cm9vdDphZG1pbg==" | base64 -d
# Note on WPA2 packet captures
#aircrack-ng <file>.cap -w Wordlist.txt - This is to find the password used
# Then to decrypt the packet capture
# airdecap-ng <file>.pcap -e <SSID> -p <password>
Below are the commands that I ran to accomplish this:
# aircrack-ng WIRELESS-C2.cap
Opening WIRELESS-C2.cap
Read 73650 packets.
# BSSID ESSID Encryption
1 00:40:10:20:00:03 Wireless Challenge Two WEP (25704 IVs)
Choosing first network as target.
Opening WIRELESS-C2.cap
Attack will be restarted every 5000 captured ivs.
Starting PTW attack with 25704 ivs.
Aircrack-ng 1.2 beta1
[00:00:00] Tested 397 keys (got 25082 IVs)
KB depth byte(vote)
0 2/ 4 DA(31232) C0(30976) 22(30720) E8(30720) 16(30208) 25(30208) D0(30208)
1 0/ 1 1C(35840) 03(32256) 7F(32000) B7(32000) F2(30464) 95(30208) 86(29952)
2 0/ 5 91(34048) CC(33792) 2D(32512) 58(31232) 84(31232) 2F(30720) 3D(30720)
3 5/ 26 0A(30208) 39(30208) 5B(30208) 62(29952) ED(29696) 02(29696) 2E(29696)
4 0/ 1 C4(35072) 19(31744) 31(30464) CD(30208) 10(29696) 6E(29696) D5(29696)
KEY FOUND! [ C0:1C:91:0A:C4 ]
Decrypted correctly: 100%
# airdecap-ng -w c01c910ac4 WIRELESS-C2.cap
## Open up in Wireshark the WIRELESS-C2-dec.cap
## Add filter for (http.request.method == "GET") || (http.request.method == "POST")
## After the filter is applied find the management.asp page
## Right-click and follow TCP stream
## In the open window you find the "Authorization: Basic cm9vdDphZG1pbg=="
## The base64 encoding is the admin username and password
## Decoded the username and password is root:admin
## OR you can use tshark and export the packet information to a file
# tshark -V -r WIRELESS-C2-dec.cap > WIRELESS-dec.txt
## Then wrote a short and sweet regex to extract base64 encoded strings
# cat WIRELESS-C2-dec.txt | grep '\+*[A-Za-z0-9]\{11,\}\+=' # Find base64 encoded text that is 11 characters or longer
## Walla! Authorization: Basic cm9vdDphZG1pbg==\r\n
## Then you can decode it from the command line by doing the following
echo "cm9vdDphZG1pbg==" | base64 -d
# Note on WPA2 packet captures
#aircrack-ng <file>.cap -w Wordlist.txt - This is to find the password used
# Then to decrypt the packet capture
# airdecap-ng <file>.pcap -e <SSID> -p <password>
Thursday, August 8, 2013
Monday, June 24, 2013
Man-in-the-middle Testing of a Mobile Application
On initial tests of a mobile application that I was utilizing it sent the username and password in plain-text to a server for authentication. Upon working with the company they fixed the issue and asked me to test again.
I was very impressed with them fixing the mobile application so quickly. Here are my chicken scratches of how I tested the mobile application the second time.
Using my laptop I have a wireless interface (wlan0) and then a LAN connection (eth0). I connected a wireless access points internet side of the connection to eth0. The wireless access points IP is 192.168.3.5 and my eth0 is 192.168.3.1. Then the access points internal addressing was 192.168.5.1 with DHCP range of 192.168.5.100~. I then connected my mobile device to the DHCP range of that access point.
My wlan0 card was connected to 192.168.1.100~ with a router IP of 192.168.1.1.
So in essence the flow of outbound traffic would be:
192.168.5.100
to
192.168.5.1
to
192.168.3.5
to
192.168.3.1 (eth0)
to
192.168.1.100 (wlan0)
to
192.168.1.1
to
The Internet
To configure the laptop I did the following:
echo 1> /proc/sys/net/ipv4/ip_forward - To enable IP Forwarding
Then I setup iptables to do the NATing and Forwarding:
iptables --table nat --append POSTROUTING --out-interface wlan0 -j MASQUERADE
iptables --append FORWARD --in-interface eth0 -j ACCEPT
Then to further assess the mobile application from a network layer I utilized wireshark sniffing traffic on 192.168.3.1
Viola!
I was very impressed with them fixing the mobile application so quickly. Here are my chicken scratches of how I tested the mobile application the second time.
Using my laptop I have a wireless interface (wlan0) and then a LAN connection (eth0). I connected a wireless access points internet side of the connection to eth0. The wireless access points IP is 192.168.3.5 and my eth0 is 192.168.3.1. Then the access points internal addressing was 192.168.5.1 with DHCP range of 192.168.5.100~. I then connected my mobile device to the DHCP range of that access point.
My wlan0 card was connected to 192.168.1.100~ with a router IP of 192.168.1.1.
So in essence the flow of outbound traffic would be:
192.168.5.100
to
192.168.5.1
to
192.168.3.5
to
192.168.3.1 (eth0)
to
192.168.1.100 (wlan0)
to
192.168.1.1
to
The Internet
To configure the laptop I did the following:
echo 1> /proc/sys/net/ipv4/ip_forward - To enable IP Forwarding
Then I setup iptables to do the NATing and Forwarding:
iptables --table nat --append POSTROUTING --out-interface wlan0 -j MASQUERADE
iptables --append FORWARD --in-interface eth0 -j ACCEPT
Then to further assess the mobile application from a network layer I utilized wireshark sniffing traffic on 192.168.3.1
Viola!
Saturday, June 8, 2013
Create Windows User from the Command Prompt
To create a windows user from the command prompt:
net user /add <username> <password>
To add the user to the local administrators group:net localgroup administrators <username> /add
Sunday, May 19, 2013
SL4A Python Script - Built Simple Python Listener to Allow Remote Execution on Droid
I built this python script to take remote commands and execute them locally on the droid as if I had terminal access. It establishes a connection on port 21000 on the droid. Then you can connect using netcat or other clients. Then I added the functionality (since the 1st terminal emulator would not allow cat of files) to view the contents of files. With this I discovered the insecure storage of files on the sdcard that other researchers have also recognized.
import android
import os
from socket import *
droid = android.Android()
HOST=''
PORT=21000
BUFSIZE=1024
ADDR = (HOST, PORT)
tcpSrvSocket = socket(AF_INET, SOCK_STREAM)
tcpSrvSocket.bind(ADDR)
tcpSrvSocket.listen(5)
while True:
tcpClientSocket, addr = tcpSrvSocket.accept()
print 'Connected from:', addr
while True:
data = tcpClientSocket.recv(BUFSIZE)
if not data:
break
if "cat" in data:
# Remove the 'cat ' in the data
fileName = data[4:]
# Remove the newline character at the end
fileName2 = fileName[:-1]
fileContent = open(fileName2, 'r')
for line in fileContent:
tcpClientSocket.send('%s' % line)
else:
returnData = os.popen(data, 'r')
for eachLine in returnData:
tcpClientSocket.send('%s' % eachLine)
tcpClientSocket.close()
tcpSrvSocket.close()
import android
import os
from socket import *
droid = android.Android()
HOST=''
PORT=21000
BUFSIZE=1024
ADDR = (HOST, PORT)
tcpSrvSocket = socket(AF_INET, SOCK_STREAM)
tcpSrvSocket.bind(ADDR)
tcpSrvSocket.listen(5)
while True:
tcpClientSocket, addr = tcpSrvSocket.accept()
print 'Connected from:', addr
while True:
data = tcpClientSocket.recv(BUFSIZE)
if not data:
break
if "cat" in data:
# Remove the 'cat ' in the data
fileName = data[4:]
# Remove the newline character at the end
fileName2 = fileName[:-1]
fileContent = open(fileName2, 'r')
for line in fileContent:
tcpClientSocket.send('%s' % line)
else:
returnData = os.popen(data, 'r')
for eachLine in returnData:
tcpClientSocket.send('%s' % eachLine)
tcpClientSocket.close()
tcpSrvSocket.close()
Friday, May 17, 2013
SL4A Python Script - Delete SMS Messages from Phone based on Keyword
I developed this script to run on my droid to remove the SMS messages that are sent to me from the python script that logs into Twitter using OAUTH and sends me a text through an email account.
This was to assist in keeping my text messages cleaned out.
import android
droid = android.Android()
msgids = droid.smsGetMessages(False).result
for message in msgids:
if "14100" in message['address']:
#print message['_id']
#droid.ttsSpeak(message['body'])
droid.smsDeleteMessage(message['_id'])
The script also has the capability to speak the messages prior to deleting them.
This was to assist in keeping my text messages cleaned out.
import android
droid = android.Android()
msgids = droid.smsGetMessages(False).result
for message in msgids:
if "14100" in message['address']:
#print message['_id']
#droid.ttsSpeak(message['body'])
droid.smsDeleteMessage(message['_id'])
The script also has the capability to speak the messages prior to deleting them.
Friday, May 3, 2013
Great Book: Violent Python by TJ O'Conner - Geo Location Script Adapted
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Script was adapted from Violent Python by TJ O'Conner
import dpkt
import socket
import pygeoip
import optparse
# Geodatabase from Maxmind
gi = pygeoip.GeoIP('geo.dat')
def retKML(description, ip):
rec = gi.record_by_name(ip)
try:
longitude = rec['longitude']
latitude = rec['latitude']
kml = (
'<Placemark>\n'
'<name>%s</name>\n'
'<Point>\n'
'<coordinates>%6f,%6f</coordinates>\n'
'</Point>\n'
'</Placemark>\n'
) %(description, longitude, latitude)
return kml
except:
return ''
def main():
# logfile.log contains 2 columns consisting of the label and the IP Address
f = open('logfile.log', 'r')
kmlPoints = ''
count = 1
for line in f:
info = line.split()
for item in info:
if count == 1:
description = item
count = 2
else:
ip = item
count = 1
location = retKML(description, ip)
kmlPoints = kmlPoints + location
kmlheader = '<?xml version="1.0" encoding="UTF-8"?>\n<kml xmlns="http://www.opengis.net/kml/2.2">\n<Document>\n'
kmlfooter = '</Document>\n</kml>\n'
kmldoc = kmlheader + kmlPoints + kmlfooter
print kmldoc
if __name__ == '__main__':
main()
# -*- coding: utf-8 -*-
# Script was adapted from Violent Python by TJ O'Conner
import dpkt
import socket
import pygeoip
import optparse
# Geodatabase from Maxmind
gi = pygeoip.GeoIP('geo.dat')
def retKML(description, ip):
rec = gi.record_by_name(ip)
try:
longitude = rec['longitude']
latitude = rec['latitude']
kml = (
'<Placemark>\n'
'<name>%s</name>\n'
'<Point>\n'
'<coordinates>%6f,%6f</coordinates>\n'
'</Point>\n'
'</Placemark>\n'
) %(description, longitude, latitude)
return kml
except:
return ''
def main():
# logfile.log contains 2 columns consisting of the label and the IP Address
f = open('logfile.log', 'r')
kmlPoints = ''
count = 1
for line in f:
info = line.split()
for item in info:
if count == 1:
description = item
count = 2
else:
ip = item
count = 1
location = retKML(description, ip)
kmlPoints = kmlPoints + location
kmlheader = '<?xml version="1.0" encoding="UTF-8"?>\n<kml xmlns="http://www.opengis.net/kml/2.2">\n<Document>\n'
kmlfooter = '</Document>\n</kml>\n'
kmldoc = kmlheader + kmlPoints + kmlfooter
print kmldoc
if __name__ == '__main__':
main()
Powershell Script to Fix Unquoted Path Vulnerability
# This script is designed to fix an unquoted path vulnerability that could be detected as a vulnerability
# Designed for Powershell
$Username = 'username'
$Password = 'password'
$pass = ConvertTo-SecureString -AsPlainText $Password -Force
$Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$pass
# Resolve the IP Address to a Hostname
$hostName = [System.Net.DNS]::GetHostbyAddress("IP Address").HostName
# Created to change the unquoted path for "A Service"
$info = Invoke-Command -ComputerName $hostName -ScriptBlock {
(Get-ItemProperty "hklm:\SYSTEM\CurrentControlSet\Services\Service Name" -Name ImagePath).ImagePath
} -credential $Cred
if ($info -eq 'Z:\Path Name')
{
Write-Host "Service does not contain quotes adding them for Service"
Invoke-Command -ComputerName $hostName -ScriptBlock {
Set-ItemProperty "hklm:\SYSTEM\CurrentControlSet\Services\Service Name" -Name ImagePath -Value '"Z:\Path Name"'
} -credential $Cred
}
# Designed for Powershell
$Username = 'username'
$Password = 'password'
$pass = ConvertTo-SecureString -AsPlainText $Password -Force
$Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$pass
# Resolve the IP Address to a Hostname
$hostName = [System.Net.DNS]::GetHostbyAddress("IP Address").HostName
# Created to change the unquoted path for "A Service"
$info = Invoke-Command -ComputerName $hostName -ScriptBlock {
(Get-ItemProperty "hklm:\SYSTEM\CurrentControlSet\Services\Service Name" -Name ImagePath).ImagePath
} -credential $Cred
if ($info -eq 'Z:\Path Name')
{
Write-Host "Service does not contain quotes adding them for Service"
Invoke-Command -ComputerName $hostName -ScriptBlock {
Set-ItemProperty "hklm:\SYSTEM\CurrentControlSet\Services\Service Name" -Name ImagePath -Value '"Z:\Path Name"'
} -credential $Cred
}
Wednesday, April 24, 2013
Java IDX Notes from BSidesSLC
To find the files that are left behind by Java go to \\comp\c$\Users\*\AppData\LocalLow\Sun\Java\Deployment\cache\6.0 The path may vary.
In each numbered folder it will contain an IDX file and the actual file.
By utilizing https://github.com/Rurik/Java_IDX_Parser/blob/master/idx_parser.py you can evaluate the IDX file to see if the information contained could be malicious.
In each numbered folder it will contain an IDX file and the actual file.
By utilizing https://github.com/Rurik/Java_IDX_Parser/blob/master/idx_parser.py you can evaluate the IDX file to see if the information contained could be malicious.
Tuesday, April 23, 2013
Lifehacker - Supercharge your Command Line
To be able to search forward and backward based on keyword create a .inputrc file with the following contents:
"\e[A": history-search-backward
"\e[B": history-search-forward
set show-all-if-ambiguous on
set completion-ignore-case on
Then from the command line $ (keyword or letters) up or down to navigate!
Sweet!
"\e[A": history-search-backward
"\e[B": history-search-forward
set show-all-if-ambiguous on
set completion-ignore-case on
Then from the command line $ (keyword or letters) up or down to navigate!
Sweet!
Sunday, April 21, 2013
Twitter with OAuth - Download Tweets and Email
I have found that I can receive alerts of security advisories on Twitter quicker than going to news sites. So I started looking into building a python app to authenticate, download the last 20 tweets, and then send through an email the tweet based on the keyword identified.
To setup python for this:
apt-get install python-pip
pip install tweepy
pip install oauth
pip install oauth-python-twitter
I also had to log into the development side of Twitter and create an application and approve it for authentication to get the keys and secrets. Then the following python script came about:
#!/usr/bin/env python
import sys
import string
import tweepy
import smtplib
# Twitter account information
CONSUMER_KEY = 'xxxxx'
CONSUMER_SECRET = 'xxxxx'
ACCESS_KEY = 'xxxxx'
ACCESS_SECRET = 'xxxxx'
# Gmail Access for the sending of an email
server = smtplib.SMTP("smtp.gmail.com", 587)
server.starttls()
server.login('email@address.com', 'password')
auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(ACCESS_KEY, ACCESS_SECRET)
api = tweepy.API(auth)
info = api.home_timeline()
for i in info:
if "keyword" in i.text:
infoString = i.text
server.sendmail("fromemail", "toemail", infoString)
To setup python for this:
apt-get install python-pip
pip install tweepy
pip install oauth
pip install oauth-python-twitter
I also had to log into the development side of Twitter and create an application and approve it for authentication to get the keys and secrets. Then the following python script came about:
#!/usr/bin/env python
import sys
import string
import tweepy
import smtplib
# Twitter account information
CONSUMER_KEY = 'xxxxx'
CONSUMER_SECRET = 'xxxxx'
ACCESS_KEY = 'xxxxx'
ACCESS_SECRET = 'xxxxx'
# Gmail Access for the sending of an email
server = smtplib.SMTP("smtp.gmail.com", 587)
server.starttls()
server.login('email@address.com', 'password')
auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(ACCESS_KEY, ACCESS_SECRET)
api = tweepy.API(auth)
info = api.home_timeline()
for i in info:
if "keyword" in i.text:
infoString = i.text
server.sendmail("fromemail", "toemail", infoString)
De-obfuscating Malware (Subtracting Hex)
Recently I came across some webpages that were referring to the Redkit malware. The page that I was directed to contained some javascript like the following:
!40!12!f!25!25!25!25!25!25!25!25!69!74!68!7a!72
!6a!73!79!33!6c!6a!79!4a!71!6a!72!6a!73!79!47!7e
!4e!69!2d!2c!76
Then I noticed in the javascript that it was subtracting 5 from the hex values after the !40 was converted to a hex value.
So I built this quick python script to convert the hex to decimal subtract 5 and then back to hex. (I also noticed another webpage variation that would subtract 7)
#!/usr/bin/env python
ins = open("temp", "r")
array = []
for line in ins:
print hex(int(line, 16) - 5)
Then I used the hex to ASCII converter to pull the websites out that I was interested in seeing that were being obfuscated.
!40!12!f!25!25!25!25!25!25!25!25!69!74!68!7a!72
!6a!73!79!33!6c!6a!79!4a!71!6a!72!6a!73!79!47!7e
!4e!69!2d!2c!76
Then I noticed in the javascript that it was subtracting 5 from the hex values after the !40 was converted to a hex value.
So I built this quick python script to convert the hex to decimal subtract 5 and then back to hex. (I also noticed another webpage variation that would subtract 7)
#!/usr/bin/env python
ins = open("temp", "r")
array = []
for line in ins:
print hex(int(line, 16) - 5)
Then I used the hex to ASCII converter to pull the websites out that I was interested in seeing that were being obfuscated.
Tuesday, April 9, 2013
Scapy is Awesome
Created 2 scripts using scapy to analyze some packet captures. Just wanted to preserve what took some time to design.
This first capture takes a packet capture and displays the Destination, Source, data in the packet, and the time. A challenge was to identify a way to display the time in a readable format.
#!/usr/bin/env python
from scapy.all import *
import time
packets = rdpcap("file.pcap")
totalPackets = 0
totalDataSize = 0
for pkt in packets:
pktSrc = pkt.sprintf("%IP.src%")
pktDst = pkt.sprintf("%IP.dst%")
# Remember that the time is in UTC format
pktTime = time.strftime("%d %b %Y %H:%M:%S", time.gmtime(pkt.time))
pktHour = time.strftime("%H", time.gmtime(pkt.time))
pktMinute = time.strftime("%M", time.gmtime(pkt.time))
pktData = pkt.sprintf("%Raw.load%")
pktDataLength = len(pkt.sprintf("%Raw.load%"))
if pktHour == "7" and int(pktMinute) == 4:
totalPackets+=1
totalDataSize+=pktDataLength
print "Destination: %s" % pktDst
print "Source: %s" % pktSrc
print "Data Length: %s" % pktDataLength
print "Packet Time: %s" % pktTime
print pktData
print "\n"
print "Total number of packets analyzed: %s" % totalPackets
averageDataSize=totalDataSize/totalPackets
print "Average size of packets: %s" % averageDataSize
This second script was designed to look at packets from 2 different sources and compare minute to minute how many they sent to each other over a period of time. We broke it down minute to minute to determine if the 1:1 ratio of sent to received packets was being maintained.
#!/usr/bin/env python
from scapy.all import *
import time
packets = rdpcap("file.pcap")
totalPacketsSource1 = 0
totalPacketsSource2 = 0
startHour = 0
startMinute = 0
loopCount = 0
for pkt in packets:
pktSrc = pkt.sprintf("%IP.src%")
pktDst = pkt.sprintf("%IP.dst%")
# Remember that the time is in UTC format
pktTime = time.strftime("%d %b %Y", time.gmtime(pkt.time))
pktHour = time.strftime("%H", time.gmtime(pkt.time))
pktTimeZoneHour = int(pktHour)-2
pktMinute = time.strftime("%M", time.gmtime(pkt.time))
if loopCount == 0:
startHour = pktHour
startMinute = pktMinute
if pktHour == startHour and pktMinute == startMinute and pktSrc == "1.1.1.1":
totalPacketsSource1+=1
elif pktHour == startHour and pktMinute == startMinute and pktSrc == "2.2.2.2":
totalPacketsSource2+=1
elif pktHour == startHour and pktMinute != startMinute:
print "%s %s:%s Source1 Packets: %s Source2 Packets: %s" % (pktTime, str(pktTimeZoneHour), pktMinute, totalPacketsSource1, totalPacketsSource2)
startMinute = pktMinute
if pktSrc == "1.1.1.1":
totalPacketsSource1=1
totalPacketsSource2=0
else:
totalPacketsSource1=0
totalPacketsSource2=1
elif pktHour != startHour and pktMinute != startMinute:
print "%s %s:%s Source1 Packets: %s Source2 Packets: %s" % (pktTime, str(pktTimeZoneHour), pktMinute, totalPacketsSource1, totalPacketsSource2)
startMinute = pktMinute
startHour = pktHour
if pktSrc == "1.1.1.1":
totalPacketsSource1=1
totalPacketsSource2=0
else:
totalPacketsSource1=0
totalPacketsSource2=1
loopCount+=1
This first capture takes a packet capture and displays the Destination, Source, data in the packet, and the time. A challenge was to identify a way to display the time in a readable format.
#!/usr/bin/env python
from scapy.all import *
import time
packets = rdpcap("file.pcap")
totalPackets = 0
totalDataSize = 0
for pkt in packets:
pktSrc = pkt.sprintf("%IP.src%")
pktDst = pkt.sprintf("%IP.dst%")
# Remember that the time is in UTC format
pktTime = time.strftime("%d %b %Y %H:%M:%S", time.gmtime(pkt.time))
pktHour = time.strftime("%H", time.gmtime(pkt.time))
pktMinute = time.strftime("%M", time.gmtime(pkt.time))
pktData = pkt.sprintf("%Raw.load%")
pktDataLength = len(pkt.sprintf("%Raw.load%"))
if pktHour == "7" and int(pktMinute) == 4:
totalPackets+=1
totalDataSize+=pktDataLength
print "Destination: %s" % pktDst
print "Source: %s" % pktSrc
print "Data Length: %s" % pktDataLength
print "Packet Time: %s" % pktTime
print pktData
print "\n"
print "Total number of packets analyzed: %s" % totalPackets
averageDataSize=totalDataSize/totalPackets
print "Average size of packets: %s" % averageDataSize
This second script was designed to look at packets from 2 different sources and compare minute to minute how many they sent to each other over a period of time. We broke it down minute to minute to determine if the 1:1 ratio of sent to received packets was being maintained.
#!/usr/bin/env python
from scapy.all import *
import time
packets = rdpcap("file.pcap")
totalPacketsSource1 = 0
totalPacketsSource2 = 0
startHour = 0
startMinute = 0
loopCount = 0
for pkt in packets:
pktSrc = pkt.sprintf("%IP.src%")
pktDst = pkt.sprintf("%IP.dst%")
# Remember that the time is in UTC format
pktTime = time.strftime("%d %b %Y", time.gmtime(pkt.time))
pktHour = time.strftime("%H", time.gmtime(pkt.time))
pktTimeZoneHour = int(pktHour)-2
pktMinute = time.strftime("%M", time.gmtime(pkt.time))
if loopCount == 0:
startHour = pktHour
startMinute = pktMinute
if pktHour == startHour and pktMinute == startMinute and pktSrc == "1.1.1.1":
totalPacketsSource1+=1
elif pktHour == startHour and pktMinute == startMinute and pktSrc == "2.2.2.2":
totalPacketsSource2+=1
elif pktHour == startHour and pktMinute != startMinute:
print "%s %s:%s Source1 Packets: %s Source2 Packets: %s" % (pktTime, str(pktTimeZoneHour), pktMinute, totalPacketsSource1, totalPacketsSource2)
startMinute = pktMinute
if pktSrc == "1.1.1.1":
totalPacketsSource1=1
totalPacketsSource2=0
else:
totalPacketsSource1=0
totalPacketsSource2=1
elif pktHour != startHour and pktMinute != startMinute:
print "%s %s:%s Source1 Packets: %s Source2 Packets: %s" % (pktTime, str(pktTimeZoneHour), pktMinute, totalPacketsSource1, totalPacketsSource2)
startMinute = pktMinute
startHour = pktHour
if pktSrc == "1.1.1.1":
totalPacketsSource1=1
totalPacketsSource2=0
else:
totalPacketsSource1=0
totalPacketsSource2=1
loopCount+=1
Monday, March 4, 2013
Decode ASCII CharCode to ASCII
Needed to create an ASCII decoder thought I would set it aside for later use:
#!/bin/bash
cat $1 | sed 's/48,/0/g' | sed 's/49,/1/g' | sed 's/50,/2/g' | sed 's/51,/3/g' | sed 's/52,/4/g' | sed 's/53,/5/g' | \
sed 's/54,/6/g' | sed 's/55,/7/g' | sed 's/56,/8/g' | sed 's/57,/9/g' | sed 's/65,/A/g' | sed 's/66,/B/g' | \
sed 's/67,/C/g' | sed 's/68,/D/g' | sed 's/69,/E/g' | sed 's/70,/F/g' | sed 's/71,/G/g' | sed 's/72,/H/g' | \
sed 's/73,/I/g' | sed 's/74,/J/g' | sed 's/75,/K/g' | sed 's/76,/L/g' | sed 's/77,/M/g' | sed 's/78,/N/g' | \
sed 's/79,/O/g' | sed 's/80,/P/g' | sed 's/81,/Q/g' | sed 's/82,/R/g' | sed 's/83,/S/g' | sed 's/84,/T/g' | \
sed 's/85,/U/g' | sed 's/86,/V/g' | sed 's/87,/W/g' | sed 's/88,/X/g' | sed 's/89,/Y/g' | sed 's/90,/Z/g' | \
sed 's/97,/a/g' | sed 's/98,/b/g' | sed 's/99,/c/g' | sed 's/100,/d/g' | sed 's/101,/e/g' | sed 's/102,/f/g' | \
sed 's/103,/g/g' | sed 's/104,/h/g' | sed 's/105,/i/g' | sed 's/106,/j/g' | sed 's/107,/k/g' | sed 's/108,/l/g' | \
sed 's/109,/m/g' | sed 's/110,/n/g' | sed 's/111,/o/g' | sed 's/112,/p/g' | sed 's/113,/q/g' | sed 's/114,/r/g' | \
sed 's/115,/s/g' | sed 's/116,/t/g' | sed 's/117,/u/g' | sed 's/118,/v/g' | sed 's/119,/w/g' | sed 's/120,/x/g' | \
sed 's/121,/y/g' | sed 's/122,/z/g' | sed 's/32,/ /g' | sed 's/40,/(/g' | sed 's/41,/)/g' | sed 's/123,/{/g' | \
sed 's/125,/}/g' | sed 's/13,10,/\n/g' | sed 's/61,/=/g' | sed 's/46,/./g' | sed 's/44,/,/g' | \
sed 's/34,/"/g' | sed 's/59,/;/g' | sed 's/33,/!/g' | sed 's/45,/-/g' | sed 's/63,/?/g' | sed 's/38,/\&/g' | \
sed 's/58,/:/g' | sed 's/43,/+/g' | sed 's/124,/|/g' | sed 's/47,/\//g' | sed 's/36,/$/g' | sed 's/95,/_/g'
#!/bin/bash
cat $1 | sed 's/48,/0/g' | sed 's/49,/1/g' | sed 's/50,/2/g' | sed 's/51,/3/g' | sed 's/52,/4/g' | sed 's/53,/5/g' | \
sed 's/54,/6/g' | sed 's/55,/7/g' | sed 's/56,/8/g' | sed 's/57,/9/g' | sed 's/65,/A/g' | sed 's/66,/B/g' | \
sed 's/67,/C/g' | sed 's/68,/D/g' | sed 's/69,/E/g' | sed 's/70,/F/g' | sed 's/71,/G/g' | sed 's/72,/H/g' | \
sed 's/73,/I/g' | sed 's/74,/J/g' | sed 's/75,/K/g' | sed 's/76,/L/g' | sed 's/77,/M/g' | sed 's/78,/N/g' | \
sed 's/79,/O/g' | sed 's/80,/P/g' | sed 's/81,/Q/g' | sed 's/82,/R/g' | sed 's/83,/S/g' | sed 's/84,/T/g' | \
sed 's/85,/U/g' | sed 's/86,/V/g' | sed 's/87,/W/g' | sed 's/88,/X/g' | sed 's/89,/Y/g' | sed 's/90,/Z/g' | \
sed 's/97,/a/g' | sed 's/98,/b/g' | sed 's/99,/c/g' | sed 's/100,/d/g' | sed 's/101,/e/g' | sed 's/102,/f/g' | \
sed 's/103,/g/g' | sed 's/104,/h/g' | sed 's/105,/i/g' | sed 's/106,/j/g' | sed 's/107,/k/g' | sed 's/108,/l/g' | \
sed 's/109,/m/g' | sed 's/110,/n/g' | sed 's/111,/o/g' | sed 's/112,/p/g' | sed 's/113,/q/g' | sed 's/114,/r/g' | \
sed 's/115,/s/g' | sed 's/116,/t/g' | sed 's/117,/u/g' | sed 's/118,/v/g' | sed 's/119,/w/g' | sed 's/120,/x/g' | \
sed 's/121,/y/g' | sed 's/122,/z/g' | sed 's/32,/ /g' | sed 's/40,/(/g' | sed 's/41,/)/g' | sed 's/123,/{/g' | \
sed 's/125,/}/g' | sed 's/13,10,/\n/g' | sed 's/61,/=/g' | sed 's/46,/./g' | sed 's/44,/,/g' | \
sed 's/34,/"/g' | sed 's/59,/;/g' | sed 's/33,/!/g' | sed 's/45,/-/g' | sed 's/63,/?/g' | sed 's/38,/\&/g' | \
sed 's/58,/:/g' | sed 's/43,/+/g' | sed 's/124,/|/g' | sed 's/47,/\//g' | sed 's/36,/$/g' | sed 's/95,/_/g'
Saturday, January 26, 2013
Creation of a Simple CTF Scoreboard and DB
I created a simple PHP/MySQL Capture the Flag Scoreboard / Flag Submission web app. It is simple and vulnerable to web exploits. I designed this for a CS4740 class that I am teaching as we are learning Metasploitable.
Create MySQL Database and Tables for the CTF
Create MySQL Database and Tables for the CTF
create
database ctf;
create
table flagsFound(flagID VARCHAR(8) NOT NULL PRIMARY KEY, finderID
INT);
create
table students (studentID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(40));
create
table flagsDB(flagID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
studentID INT, flagChecksum VARCHAR(50));
Populate
Table with Participants
insert
into students VALUES (1,"Ann");
insert
into students VALUES (2,"Bob");
insert
into students VALUES (3,"Curt");
insert
into students VALUES (4,"Dan");
Create
Text File with Flags and Call it flags.txt
Make
it with 2 columns of data the owner of the flag and the keyword
1 Asteroid
2 You
3 Red
4 Blue
…
Create
and Run Simple Bash Script to Populate SQL File for flagsDB
#!/bin/bash
#
This script is used to generate the information to go into the
flagsDB
#
from a text file that has 2 columns. The column format is as
follows:
#
1st Column: studentID or Owner of the Flag
#
2nd Column: flag keyword to be transformed into a checksum
textFile=flags.txt
outputFile=temp.sql
checkSumAlg=sha256sum
echo
"USE ctf;" > $outputFile
while
read line
do
studentID=`echo
$line | awk '{print $1}'`
flagChecksum=`echo
$line | awk '{print $2}' | $checkSumAlg | awk '{print $1}'`
echo
"INSERT INTO flagsDB (studentID, flagChecksum) VALUES
($studentID,'$flagChecksum');" >> $outputFile
done
< $textFile
Input
the SQL File to the Database using the mysql username and password
that you have
mysql
-u root -p < temp.sql # Unless the output file has changed or the
user account is not root
#
Then at the next prompt put in your mysql users password
The following are files that are needed for the CTF PHP Page:
index.php, submitFlag.php, submitFlag_Submit.php, dbConnection.php, css/default.css, pageheader.php
The file of stats.php was not included and can be removed...
index.php File
<html>
<head>
<title>CTF</title>
<link rel="stylesheet" type="text/css" href="css/default.css">
<script type="text/JavaScript">
function timedRefresh(timeoutPeriod) {
setTimeout("location.reload(true);",timeoutPeriod);
}
</script>
</head>
<BODY BGCOLOR=white onload="JavaScript:timedRefresh(300000);">
<!-- Add connection to database by including dbConnection.php -->
<?php include 'dbConnection.php'; ?>
<!-- Add Page Header with Login Options -->
<?php include 'pageheader.php'; ?>
<FORM ACTION="search_for_project.php" METHOD="post">
<CENTER>
<BR>
<TABLE style="border:1px solid;" CELLPADDING=15>
<TR>
<TD colspan=2>
<CENTER>
<FONT SIZE=2>
<B>Scoreboard</B>
</FONT>
</CENTER>
</TD>
</TR>
<TR>
<TD>
<CENTER>
<FONT SIZE=2>
Student
</FONT>
</CENTER>
</TD>
<TD>
<CENTER>
<FONT SIZE=2>
Score
</FONT>
</CENTER>
</TD>
</TR>
<?php
$sqlScore = "SELECT s.name, count(f.finderID) as total FROM students s, flagsFound f WHERE s.studentID=f.finderID GROUP BY s.name ORDER BY total DESC";
$sqlScoreResults = mysql_query($sqlScore);
$numRows = mysql_num_rows($sqlScoreResults);
if ($numRows < 1) {
echo "<TR><TD COLSPAN=2><CENTER>No Scores to Report</CENTER></TD></TR>";
}
else {
while ($rowScore = mysql_fetch_array($sqlScoreResults)) {
$name = $rowScore['name'];
$total = $rowScore['total'] * 10;
echo "<TR><TD><CENTER><FONT COLOR=GRAY SIZE=2>$name</FONT></CENTER></TD>";
echo "<TD><CENTER><FONT COLOR=GRAY SIZE=2>$total</FONT></CENTER></TD></TR>";
}
}
?>
</TR>
</TABLE>
<BR>
<BR>
<BR>
<FONT SIZE=2 COLOR=GRAY>This page will refresh every 5 minutes.</FONT>
</CENTER>
<BR>
<BR>
<BR>
</FORM>
</BODY>
</html>
<head>
<title>CTF</title>
<link rel="stylesheet" type="text/css" href="css/default.css">
<script type="text/JavaScript">
function timedRefresh(timeoutPeriod) {
setTimeout("location.reload(true);",timeoutPeriod);
}
</script>
</head>
<BODY BGCOLOR=white onload="JavaScript:timedRefresh(300000);">
<!-- Add connection to database by including dbConnection.php -->
<?php include 'dbConnection.php'; ?>
<!-- Add Page Header with Login Options -->
<?php include 'pageheader.php'; ?>
<FORM ACTION="search_for_project.php" METHOD="post">
<CENTER>
<BR>
<TABLE style="border:1px solid;" CELLPADDING=15>
<TR>
<TD colspan=2>
<CENTER>
<FONT SIZE=2>
<B>Scoreboard</B>
</FONT>
</CENTER>
</TD>
</TR>
<TR>
<TD>
<CENTER>
<FONT SIZE=2>
Student
</FONT>
</CENTER>
</TD>
<TD>
<CENTER>
<FONT SIZE=2>
Score
</FONT>
</CENTER>
</TD>
</TR>
<?php
$sqlScore = "SELECT s.name, count(f.finderID) as total FROM students s, flagsFound f WHERE s.studentID=f.finderID GROUP BY s.name ORDER BY total DESC";
$sqlScoreResults = mysql_query($sqlScore);
$numRows = mysql_num_rows($sqlScoreResults);
if ($numRows < 1) {
echo "<TR><TD COLSPAN=2><CENTER>No Scores to Report</CENTER></TD></TR>";
}
else {
while ($rowScore = mysql_fetch_array($sqlScoreResults)) {
$name = $rowScore['name'];
$total = $rowScore['total'] * 10;
echo "<TR><TD><CENTER><FONT COLOR=GRAY SIZE=2>$name</FONT></CENTER></TD>";
echo "<TD><CENTER><FONT COLOR=GRAY SIZE=2>$total</FONT></CENTER></TD></TR>";
}
}
?>
</TR>
</TABLE>
<BR>
<BR>
<BR>
<FONT SIZE=2 COLOR=GRAY>This page will refresh every 5 minutes.</FONT>
</CENTER>
<BR>
<BR>
<BR>
</FORM>
</BODY>
</html>
submitFlag.php
<html>
<head>
<title>CTF</title>
<link rel="stylesheet" type="text/css" href="css/default.css">
</head>
<BODY BGCOLOR=white>
<!-- Add connection to database by including dbConnection.php -->
<?php include 'dbConnection.php'; ?>
<!-- Add Page Header with Login Options -->
<?php include 'pageheader.php'; ?>
<FORM ACTION="submitFlag_Submit.php" METHOD="post">
<CENTER>
<TABLE style="border:1px solid;" CELLPADDING=15>
<TR>
<TD colspan=2>
<CENTER>
<FONT SIZE=2>
<B>Submit Flag</B>
</FONT>
</CENTER>
</TD>
</TR>
<TR>
<TD>
<CENTER>
<FONT SIZE=2 COLOR=GRAY>
Identify Yourself
</FONT>
</CENTER>
</TD>
<TD>
<CENTER>
<SELECT name="finderID">
<?php
$sqlStudents = "SELECT studentID, name FROM students";
$sqlStudentsResults = mysql_query($sqlStudents);
while ($rowStudents = mysql_fetch_array($sqlStudentsResults)) {
$studentID = $rowStudents['studentID'];
$name = $rowStudents['name'];
echo "<option value=" . $studentID . ">" . $name . "</option>";
}
?>
</SELECT>
<FONT COLOR=RED SIZE=1><I>Choose wisely my friend.</I></FONT>
</CENTER>
</TD>
</TR>
<TR>
<TD>
<CENTER>
<FONT SIZE=2 COLOR=GRAY>
Flag Checksum
</FONT>
</CENTER>
</TD>
<TD>
<CENTER>
<INPUT TYPE=text NAME=checksum SIZE=50>
</CENTER>
</TD>
</TR>
<TR>
<TD COLSPAN=2>
<CENTER>
<INPUT TYPE=submit VALUE=Submit>
</CENTER>
</TD>
</TR>
</TABLE>
</CENTER>
<BR>
</FORM>
</BODY>
</html>
<head>
<title>CTF</title>
<link rel="stylesheet" type="text/css" href="css/default.css">
</head>
<BODY BGCOLOR=white>
<!-- Add connection to database by including dbConnection.php -->
<?php include 'dbConnection.php'; ?>
<!-- Add Page Header with Login Options -->
<?php include 'pageheader.php'; ?>
<FORM ACTION="submitFlag_Submit.php" METHOD="post">
<CENTER>
<TABLE style="border:1px solid;" CELLPADDING=15>
<TR>
<TD colspan=2>
<CENTER>
<FONT SIZE=2>
<B>Submit Flag</B>
</FONT>
</CENTER>
</TD>
</TR>
<TR>
<TD>
<CENTER>
<FONT SIZE=2 COLOR=GRAY>
Identify Yourself
</FONT>
</CENTER>
</TD>
<TD>
<CENTER>
<SELECT name="finderID">
<?php
$sqlStudents = "SELECT studentID, name FROM students";
$sqlStudentsResults = mysql_query($sqlStudents);
while ($rowStudents = mysql_fetch_array($sqlStudentsResults)) {
$studentID = $rowStudents['studentID'];
$name = $rowStudents['name'];
echo "<option value=" . $studentID . ">" . $name . "</option>";
}
?>
</SELECT>
<FONT COLOR=RED SIZE=1><I>Choose wisely my friend.</I></FONT>
</CENTER>
</TD>
</TR>
<TR>
<TD>
<CENTER>
<FONT SIZE=2 COLOR=GRAY>
Flag Checksum
</FONT>
</CENTER>
</TD>
<TD>
<CENTER>
<INPUT TYPE=text NAME=checksum SIZE=50>
</CENTER>
</TD>
</TR>
<TR>
<TD COLSPAN=2>
<CENTER>
<INPUT TYPE=submit VALUE=Submit>
</CENTER>
</TD>
</TR>
</TABLE>
</CENTER>
<BR>
</FORM>
</BODY>
</html>
submitFlag_Submit.php
<html>
<head>
<title>CTF</title>
<link rel="stylesheet" type="text/css" href="css/default.css">
</head>
<BODY BGCOLOR=white>
<!-- Add connection to database by including dbConnection.php -->
<?php include 'dbConnection.php'; ?>
<!-- Add Page Header with Login Options -->
<?php include 'pageheader.php'; ?>
<CENTER>
<TABLE style="border:1px solid;" CELLPADDING=15>
<TR>
<TD colspan=2>
<CENTER>
<FONT SIZE=2>
<B>Submitted the Following Flag</B>
</FONT>
</CENTER>
</TD>
</TR>
<TR>
<TD>
<CENTER>
<FONT SIZE=2 COLOR=GRAY>
And the finder was...
</FONT>
</CENTER>
</TD>
<TD>
<CENTER>
<?php
$finderID = $_POST['finderID'];
$sqlName = "SELECT name FROM students WHERE studentID=$finderID";
$sqlNameResults = mysql_query($sqlName);
while ($rowName = mysql_fetch_array($sqlNameResults)) {
$name = $rowName['name'];
echo $name;
}
?>
</CENTER>
</TD>
</TR>
<TR>
<TD>
<CENTER>
<FONT SIZE=2 COLOR=GRAY>
Flag Checksum
</FONT>
</CENTER>
</TD>
<TD>
<CENTER>
<?php
$checksum = $_POST['checksum'];
echo $checksum;
?>
</CENTER>
</TD>
</TR>
<TR>
<TD COLSPAN=2>
<CENTER>
<?php
$sqlValidChecksum = "SELECT flagID, studentID FROM flagsDB WHERE flagChecksum='$checksum'";
$sqlValidResults = mysql_query($sqlValidChecksum);
$sqlValidNumRows = mysql_num_rows($sqlValidResults);
if ($sqlValidNumRows < 1) {
echo "<FONT COLOR=RED>Sorry! This flag was not found in the database.</FONT>";
}
else {
echo "Congradulations!";
while ($rowValid = mysql_fetch_array($sqlValidResults)) {
$flagID = $rowValid['flagID'];
$studentID = $rowValid['studentID'];
}
$sqlInsertFinding = "INSERT INTO flagsFound VALUES ('$studentID-$flagID-$finderID',$finderID)";
mysql_query($sqlInsertFinding);
}
?>
</CENTER>
</TD>
</TR>
</TABLE>
</CENTER>
<BR>
</BODY>
</html>
<head>
<title>CTF</title>
<link rel="stylesheet" type="text/css" href="css/default.css">
</head>
<BODY BGCOLOR=white>
<!-- Add connection to database by including dbConnection.php -->
<?php include 'dbConnection.php'; ?>
<!-- Add Page Header with Login Options -->
<?php include 'pageheader.php'; ?>
<CENTER>
<TABLE style="border:1px solid;" CELLPADDING=15>
<TR>
<TD colspan=2>
<CENTER>
<FONT SIZE=2>
<B>Submitted the Following Flag</B>
</FONT>
</CENTER>
</TD>
</TR>
<TR>
<TD>
<CENTER>
<FONT SIZE=2 COLOR=GRAY>
And the finder was...
</FONT>
</CENTER>
</TD>
<TD>
<CENTER>
<?php
$finderID = $_POST['finderID'];
$sqlName = "SELECT name FROM students WHERE studentID=$finderID";
$sqlNameResults = mysql_query($sqlName);
while ($rowName = mysql_fetch_array($sqlNameResults)) {
$name = $rowName['name'];
echo $name;
}
?>
</CENTER>
</TD>
</TR>
<TR>
<TD>
<CENTER>
<FONT SIZE=2 COLOR=GRAY>
Flag Checksum
</FONT>
</CENTER>
</TD>
<TD>
<CENTER>
<?php
$checksum = $_POST['checksum'];
echo $checksum;
?>
</CENTER>
</TD>
</TR>
<TR>
<TD COLSPAN=2>
<CENTER>
<?php
$sqlValidChecksum = "SELECT flagID, studentID FROM flagsDB WHERE flagChecksum='$checksum'";
$sqlValidResults = mysql_query($sqlValidChecksum);
$sqlValidNumRows = mysql_num_rows($sqlValidResults);
if ($sqlValidNumRows < 1) {
echo "<FONT COLOR=RED>Sorry! This flag was not found in the database.</FONT>";
}
else {
echo "Congradulations!";
while ($rowValid = mysql_fetch_array($sqlValidResults)) {
$flagID = $rowValid['flagID'];
$studentID = $rowValid['studentID'];
}
$sqlInsertFinding = "INSERT INTO flagsFound VALUES ('$studentID-$flagID-$finderID',$finderID)";
mysql_query($sqlInsertFinding);
}
?>
</CENTER>
</TD>
</TR>
</TABLE>
</CENTER>
<BR>
</BODY>
</html>
pageheader.php
<table width=100% bgcolor="#EEEEEE">
<tr>
<td width=20%>
</td>
<td width=50%>
<center>
<FONT SIZE=5 COLOR="Gray">
<B>CTF</B>
</FONT>
<BR>
<FONT SIZE=2 COLOR="Gray">
Get the Flags - Get the Points
</FONT>
</center>
</td>
<td width-30%>
</td></tr>
<tr><td colspan=3>
<center>
<!-- Menu Bar Table -->
<table width=96% id="menuBar" cellspacing="1px" cellpadding="3px"><tr>
<td width=33% bgcolor="#485e49"><center>
<a href="index.php">Home</a>
</center></td>
<td width=33% bgcolor="#485e49"><center>
<a href="submitFlag.php">Submit Flag</a>
</center></td>
<td width=33% bgcolor="#485e49"><center>
<a href="stats.php">CTF Stats</a>
</center></td>
</tr>
</table>
</center>
<!-- End Table for Menu Bar -->
</td></tr>
</table>
<BR>
<tr>
<td width=20%>
</td>
<td width=50%>
<center>
<FONT SIZE=5 COLOR="Gray">
<B>CTF</B>
</FONT>
<BR>
<FONT SIZE=2 COLOR="Gray">
Get the Flags - Get the Points
</FONT>
</center>
</td>
<td width-30%>
</td></tr>
<tr><td colspan=3>
<center>
<!-- Menu Bar Table -->
<table width=96% id="menuBar" cellspacing="1px" cellpadding="3px"><tr>
<td width=33% bgcolor="#485e49"><center>
<a href="index.php">Home</a>
</center></td>
<td width=33% bgcolor="#485e49"><center>
<a href="submitFlag.php">Submit Flag</a>
</center></td>
<td width=33% bgcolor="#485e49"><center>
<a href="stats.php">CTF Stats</a>
</center></td>
</tr>
</table>
</center>
<!-- End Table for Menu Bar -->
</td></tr>
</table>
<BR>
dbConnection.php
<?php
$dbHost = "localhost";
$dbUser = "root";
$dbPass = "strongpassword";
$dbName = "ctf";
$db = mysql_connect($dbHost,$dbUser,$dbPass);
mysql_select_db($dbName,$db);
?>
$dbHost = "localhost";
$dbUser = "root";
$dbPass = "strongpassword";
$dbName = "ctf";
$db = mysql_connect($dbHost,$dbUser,$dbPass);
mysql_select_db($dbName,$db);
?>
css/default.css
a {text-decoration: none}
table#menuBar a {
text-decoration: none;
color:#eee;
}
table#menuBar a:hover {
color:lightblue
}
table#menuBar td {
width:12%;
background:#485e49;
}
#pageheaderDropDown
{ margin: 0;
padding: 0;
z-index: 30}
#pageheaderDropDown li
{ margin: 0;
padding: 0;
list-style: none;
float: left;}
#pageheaderDropDown li a
{ display: block;
margin: 0 1px 0 0;
padding: 4px 10px;
width: 60px;
color: #EEEEEE;
text-align: center;
text-decoration: none}
#pageheaderDropDown li a:hover
{ color: lightblue}
#pageheaderDropDown div
{ position: absolute;
visibility: hidden;
margin: 0;
padding: 0;
background: gray;
border: 1px solid #5970B2}
#pageheaderDropDown div a
{ position: relative;
display: block;
margin: 0;
padding: 5px 10px;
width: auto;
white-space: nowrap;
text-align: left;
text-decoration: none;
background: #EAEBD8;
color: #2875DE;
font: 11px arial}
#pageheaderDropDown div a:hover
{ background: #49A3FF;
color: #FFF}
table#menuBar a {
text-decoration: none;
color:#eee;
}
table#menuBar a:hover {
color:lightblue
}
table#menuBar td {
width:12%;
background:#485e49;
}
#pageheaderDropDown
{ margin: 0;
padding: 0;
z-index: 30}
#pageheaderDropDown li
{ margin: 0;
padding: 0;
list-style: none;
float: left;}
#pageheaderDropDown li a
{ display: block;
margin: 0 1px 0 0;
padding: 4px 10px;
width: 60px;
color: #EEEEEE;
text-align: center;
text-decoration: none}
#pageheaderDropDown li a:hover
{ color: lightblue}
#pageheaderDropDown div
{ position: absolute;
visibility: hidden;
margin: 0;
padding: 0;
background: gray;
border: 1px solid #5970B2}
#pageheaderDropDown div a
{ position: relative;
display: block;
margin: 0;
padding: 5px 10px;
width: auto;
white-space: nowrap;
text-align: left;
text-decoration: none;
background: #EAEBD8;
color: #2875DE;
font: 11px arial}
#pageheaderDropDown div a:hover
{ background: #49A3FF;
color: #FFF}
Python or Perl Quick Notes on Creating a String
To use python from the command line to create a string of characters:
python -c 'print "A"*5' - This will print a string of 5 A's
To use perl from the command line to create a string of characters:
perl -e 'print "A"x5 - This will print a string of 5 A's
python -c 'print "A"*5' - This will print a string of 5 A's
To use perl from the command line to create a string of characters:
perl -e 'print "A"x5 - This will print a string of 5 A's
Wednesday, January 23, 2013
Comparing 2 Nessus Scans
I had to face a challenge today of comparing 2 nessus reports and identifying the progress made towards fixing the vulnerabilities.
First, I used nessus to export each report respectively to a csv file.
Second, I removed the first line of the csv file.
Third, I built 2 tables to accept the input with the following sql respectively:
create table nessusScan1(pluginID INT, CVE VARCHAR(40), CVSS VARCHAR(40), risk VARCHAR(40), ip VARCHAR(40), protocol VARCHAR(40), port INT, name mediumblob, synopsis mediumblob, description mediumblob, solution mediumblob, pluginoutput mediumblob);
create table nessusScan2(pluginID INT, CVE VARCHAR(40), CVSS VARCHAR(40), risk VARCHAR(40), ip VARCHAR(40), protocol VARCHAR(40), port INT, name mediumblob, synopsis mediumblob, description mediumblob, solution mediumblob, pluginoutput mediumblob);
Forth, I inserted the data from the csv file into the respective table:
load data local infile 'Nessus1.csv' into table nessusScan1 fields terminated by ',' enclosed by '"' lines terminated by '\n';
load data local infile 'Nessus2.csv' into table nessusScan2 fields terminated by ',' enclosed by '"' lines terminated by '\n';
Fifth, I built 2 tables to collect the results of a query due to not wanting to wait for a join:
create table Totals1 (name mediumblob, risk VARCHAR(20), totals INT);
create table Totals2 (name mediumblob, risk VARCHAR(20), totals INT);
Sixth, I populated the table I created with the results of critical and high risk items:
INSERT INTO Totals1 (name, risk, totals) select name, risk, count(DISTINCT ip) AS total FROM nessusScan1 WHERE (risk='Critical' OR risk='High') GROUP BY name ORDER BY risk,total DESC;
INSERT INTO Totals2 (name, risk, totals) select name, risk, count(DISTINCT ip) AS total FROM nessusScan2 WHERE (risk='Critical' OR risk='High') GROUP BY name ORDER BY risk,total DESC;
Seventh, then I was able to do a join on the totals table to see the progress that had been made between the scans (This does not show the new vulnerabilities that were identified in the more recent scan):
SELECT a.name, a.risk, a.totals AS "Totals1", b.totals AS "Totals2" FROM Totals1 a, Totals2 b WHERE a.name=b.name;
There probably is an easier way to accomplish this, however I wanted to document this so I can use it in the future also.
Enjoy...
First, I used nessus to export each report respectively to a csv file.
Second, I removed the first line of the csv file.
Third, I built 2 tables to accept the input with the following sql respectively:
create table nessusScan1(pluginID INT, CVE VARCHAR(40), CVSS VARCHAR(40), risk VARCHAR(40), ip VARCHAR(40), protocol VARCHAR(40), port INT, name mediumblob, synopsis mediumblob, description mediumblob, solution mediumblob, pluginoutput mediumblob);
create table nessusScan2(pluginID INT, CVE VARCHAR(40), CVSS VARCHAR(40), risk VARCHAR(40), ip VARCHAR(40), protocol VARCHAR(40), port INT, name mediumblob, synopsis mediumblob, description mediumblob, solution mediumblob, pluginoutput mediumblob);
Forth, I inserted the data from the csv file into the respective table:
load data local infile 'Nessus1.csv' into table nessusScan1 fields terminated by ',' enclosed by '"' lines terminated by '\n';
load data local infile 'Nessus2.csv' into table nessusScan2 fields terminated by ',' enclosed by '"' lines terminated by '\n';
Fifth, I built 2 tables to collect the results of a query due to not wanting to wait for a join:
create table Totals1 (name mediumblob, risk VARCHAR(20), totals INT);
create table Totals2 (name mediumblob, risk VARCHAR(20), totals INT);
Sixth, I populated the table I created with the results of critical and high risk items:
INSERT INTO Totals1 (name, risk, totals) select name, risk, count(DISTINCT ip) AS total FROM nessusScan1 WHERE (risk='Critical' OR risk='High') GROUP BY name ORDER BY risk,total DESC;
INSERT INTO Totals2 (name, risk, totals) select name, risk, count(DISTINCT ip) AS total FROM nessusScan2 WHERE (risk='Critical' OR risk='High') GROUP BY name ORDER BY risk,total DESC;
Seventh, then I was able to do a join on the totals table to see the progress that had been made between the scans (This does not show the new vulnerabilities that were identified in the more recent scan):
SELECT a.name, a.risk, a.totals AS "Totals1", b.totals AS "Totals2" FROM Totals1 a, Totals2 b WHERE a.name=b.name;
There probably is an easier way to accomplish this, however I wanted to document this so I can use it in the future also.
Enjoy...
Subscribe to:
Posts (Atom)
Test Authentication from Linux Console using python3 pexpect
Working with the IT420 lab, you will discover that we need to discover a vulnerable user account. The following python3 script uses the pex...
-
Here is a quick walk through of GetBoo. The first item that I found was you can harvest the usernames of the existing users that are regist...
-
As I was glancing through the logs of my honeypots I spent some time to look at the following logs. In the past I have just overlooked them...
-
I thought I would work through a few of these web applications provided by OWASP on their broken web applications VM. The first one I th...
-
Today looking at the logs of the honeypots, I became curious based on the whois of the IP Addresses attempting to login to SSH which country...
-
Recently I was doing some scanning with a tool that is available on github called masscan. The tool allows you to configure a configuration...