├── .gitignore
├── Modules
└── Empire
│ ├── BlueCommandData.psm1
│ └── BlueCommandEmpire.psm1
├── Pages
├── AgentLogs.ps1
├── Configuration.ps1
├── Downloads.ps1
├── Execution.ps1
└── home.ps1
├── README.md
├── bluecommand.psd1
├── bluecommand.psm1
├── img
├── AgentDownload.gif
├── Credential_Manager.png
├── ExecuteModule.gif
├── HomePage.png
└── empire_rest.png
└── start.ps1
/.gitignore:
--------------------------------------------------------------------------------
1 | Tools/DomainPasswordSpray.ps1
2 | Tools/DomainPasswordSpray/DomainPasswordSpay.psd1
3 | Tools/DomainPasswordSpray/DomainPasswordSpray.psm1
4 | scan.json
5 | scratch.ps1
6 | Data/EmpireAgents.json
7 | Data/EmpireConfig.json
8 | Data/EmpireModules.json
9 | Data/NetworkScan.json
10 | Data/AuditLog.log
11 | test.ps1
12 | Data/Downloads/8BYZEAXN/screenshot/LEE-NUC1_2019-01-21_02-59-58.png
13 | Data/Downloads/
--------------------------------------------------------------------------------
/Modules/Empire/BlueCommandData.psm1:
--------------------------------------------------------------------------------
1 | #### All functions need to have proper function params, synopsis, help, etc....
2 | #### Also where my psd1 file at
3 |
4 | Function Get-BSJSONObject
5 | {
6 | Param(
7 | [Parameter(Mandatory=$true)] $BSFile
8 | )
9 |
10 | if(Test-Path($BSFile))
11 | {
12 | $FileContents = Get-Childitem -file $BSFile
13 | $Length = $FileContents.Length
14 |
15 | iF($Length -ne 0)
16 | {
17 | $JsonObject = ConvertFrom-Json -InputObject (Get-Content $BSFile -raw)
18 | return $JsonObject
19 | }
20 | else
21 | {
22 | # Empty File
23 | return $null
24 | }
25 |
26 |
27 | }
28 | else
29 | {
30 | # Does not Exist
31 | return $null
32 | }
33 | }
34 |
35 | Function Get-BSEmpireAgentData()
36 | {
37 |
38 | $Data = @()
39 | $ResourcesJsonContent = Get-BSJSONObject -BSFile $Cache:EmpireAgentFilePath
40 |
41 | #### Data Stuff
42 | foreach($Resource in $ResourcesJsonContent)
43 | {
44 | $Data = $Data +[PSCustomObject]@{
45 | id=($Resource.id);
46 | name=($Resource.name);
47 | checkin_time=($Resource.checkin_time);
48 | external_ip=($Resource.external_ip);
49 | hostname=($Resource.hostname);
50 | internal_ip=($Resource.internal_ip);
51 | langauge=($Resource.langauge);
52 | langauge_version=($Resource.langauge_version);
53 | lastseen_time=($Resource.lastseen_time);
54 | listener=($Resource.listener);
55 | os_details=($Resource.os_details);
56 | username=($Resource.username);
57 | }
58 | }
59 |
60 | return $Data
61 | }
62 |
63 |
64 |
65 | Function Get-BSEmpireConfigData()
66 | {
67 |
68 | $Data = @()
69 | $ResourcesJsonContent = Get-BSJSONObject -BSFile $Cache:EmpireConfigFilePath
70 |
71 | #### Data Stuff
72 | foreach($Resource in $ResourcesJsonContent)
73 | {
74 | $Data = $Data +[PSCustomObject]@{
75 | empire_host=($Resource.empire_host);
76 | empire_port=($Resource.empire_port);
77 | empire_token=($Resource.empire_token);
78 | api_username=($Resource.api_username);
79 | install_path=($Resource.install_path);
80 | version=($Resource.version);
81 | sync_time=($Resource.sync_time)
82 | }
83 | }
84 |
85 | return $Data
86 |
87 |
88 | }
89 |
90 |
91 | Function Get-BSEmpireModuleData()
92 | {
93 |
94 | $Data = @()
95 | $Options = @()
96 | $FirstPartOfDefinition = '^.*=@{Description='
97 | $SecondPartOfDefinition = ';.*;.*Value=.*}'
98 |
99 | $ResourcesJsonContent = Get-BSJSONObject -BSFile $Cache:EmpireModuleFilePath
100 |
101 | #### Data Stuff
102 | foreach($Module in $ResourcesJsonContent)
103 | {
104 |
105 | #Propertize the Module Objects
106 | $ModuleOptionsObject = @()
107 | $ModuleOptions = $Module.options
108 |
109 | $ModuleOptionsNotes = $ModuleOptions | Get-Member -MemberType NoteProperty
110 | ForEach($Note in $ModuleOptionsNotes)
111 | {
112 |
113 | $OptionDefinitionFormatted = $Note.Definition
114 | $OptionDefinitionFormatted = $OptionDefinitionFormatted -replace $FirstPartOfDefinition," "
115 | $OptionDefinitionFormatted = $OptionDefinitionFormatted -replace $SecondPartOfDefinition,""
116 |
117 | $ModuleOptionsObject = $ModuleOptionsObject +[PSCustomObject]@{
118 | Name=($Note.Name);
119 | Definition=($OptionDefinitionFormatted);
120 | }
121 | }
122 |
123 |
124 | $Data = $Data +[PSCustomObject]@{
125 | Name=($Module.name);
126 | Author=($Module.Author);
127 | Description=($Module.Description);
128 | Language=($Module.Language);
129 | NeedsAdmin=($Module.NeedsAdmin);
130 | OpsecSafe=($Module.OpsecSafe);
131 | Options=($ModuleOptionsObject);
132 | }
133 | }
134 |
135 |
136 |
137 | return $Data
138 |
139 |
140 | }
141 |
142 | Function Get-BSDownloadsCount
143 | {
144 | $Count = 0
145 | $BSDownloadsPath = $Cache:BSDownloadsPath
146 | $AgentFiles = ($BSDownloadsPath + '\') | Get-ChildItem -Recurse | where {! $_.PSIsContainer }
147 | $Count = $AgentFiles.Count
148 |
149 | return $Count
150 | }
151 |
152 |
153 | Function Get-BSDownloads
154 | {
155 | param(
156 | $AgentName = $null
157 | )
158 |
159 | $BSDownloadsPath = $Cache:BSDownloadsPath
160 |
161 | $DownloadedFiles = @()
162 |
163 | if($AgentName -ne $null)
164 | {
165 | $AgentFolderName = $Folder.Name
166 | $AgentFolderPath = $BSDownloadsPath + '\'+ $AgentName
167 | $AgentFiles = ($AgentFolderPath + '\') | Get-ChildItem -Recurse | where { ! $_.PSIsContainer }
168 | ForEach($File in $AgentFiles)
169 | {
170 | $FullPath = $File.FullName
171 | $ParentDirectory = $AgentFolderName
172 | $Directory = $File.Directory.FullName
173 | $DownloadedFiles += $File | Select-Object -Property Name, FullName, CreationTime, @{Name="Agent"; Expression = {$ParentDirectory}}, @{Name="Directory"; Expression = {$Directory}}, @{Name="FullPath"; Expression = {$FullPath}}
174 | }
175 |
176 | }
177 | else
178 | {
179 | $AgentFolders = ($Cache:BSDownloadsPath + '\') | Get-ChildItem | ?{ $_.PSIsContainer }
180 |
181 | Foreach($Folder in $AgentFolders)
182 | {
183 | $AgentFolderName = $Folder.Name
184 | $AgentFolderPath = $Folder.FullName
185 | $AgentFiles = ($AgentFolderPath + '\') | Get-ChildItem -Recurse | where { ! $_.PSIsContainer }
186 | ForEach($File in $AgentFiles)
187 | {
188 | $FullPath = $File.FullName
189 | $ParentDirectory = $AgentFolderName
190 | $Directory = $File.Directory.FullName
191 | $DownloadedFiles += $File | Select-Object -Property Name, FullName, CreationTime, @{Name="Agent"; Expression = {$ParentDirectory}},@{Name="Directory"; Expression = {$Directory}}, @{Name="FullPath"; Expression = {$FullPath}}
192 | }
193 | }
194 | }
195 |
196 | return ($DownloadedFiles)
197 |
198 | }
199 |
200 |
201 |
202 | Function Get-BSNetworkScanData()
203 | {
204 |
205 | $Data = @()
206 | $ResourcesJsonContent = Get-BSJSONObject -BSFile $Cache:NetworkScanFilePath
207 |
208 | #### Data Stuff
209 | foreach($Resource in $ResourcesJsonContent)
210 | {
211 | $Data = $Data +[PSCustomObject]@{
212 | HostName=($Resource.Hostname);
213 | IPv4=($Resource.IPv4);
214 | Status=($Resource.Status);
215 | Computer=(New-UDLink -Text "RDP" -Url "remotedesktop://$Resource.IPv4");
216 | Note="";
217 | LastScan=($Resource.ScanTime.DateTime);
218 | isEmpire=($Resource.EmpireServer);
219 | }
220 | }
221 |
222 | return $Data
223 |
224 | }
225 |
226 |
227 |
228 | Function Clear-BSJON
229 | {
230 | Param(
231 | [Parameter(Mandatory=$true)] $BSFile
232 | )
233 | if(Test-Path($BSFile))
234 | {
235 | # Clear Existings
236 | Clear-Content $BSFile -Force
237 | }
238 | else
239 | {
240 | # Does not Exist
241 | }
242 | }
243 |
244 |
245 | Function Write-BSJSON
246 | {
247 | Param (
248 | [Parameter(Mandatory=$true)] $BSFile = '',
249 | [Parameter(Mandatory=$true)] $BSObjectData
250 | )
251 |
252 | $BSObjectData | ConvertTo-Json | Out-File $BSFile -Append
253 |
254 |
255 | }
256 |
257 |
258 | Function Write-BSObjectToJSON
259 | {
260 | Param (
261 | [Parameter(Mandatory=$true)] $BSFile = '',
262 | [Parameter(Mandatory=$true)] $BSObjectData
263 | )
264 |
265 | $BSObjectData | ConvertTo-Json | Out-File $BSFile -Append
266 |
267 |
268 | }
269 |
270 |
271 |
272 |
273 | Function Write-BSEmpireAgentData
274 | {
275 | Param (
276 | [Parameter(Mandatory=$true)] $BSObjectData
277 | )
278 |
279 | Clear-BSJON -BSFile $Cache:EmpireAgentFilePath
280 | Write-BSJSON -BSFile $Cache:EmpireAgentFilePath -BSObjectData $BSObjectData
281 |
282 | }
283 |
284 |
285 | Function Write-BSEmpireConfigData
286 | {
287 | Param (
288 | [Parameter(Mandatory=$true)] $BSObjectData
289 | )
290 | Clear-BSJON -BSFile $Cache:EmpireConfigFilePath
291 | Write-BSJSON -BSFile $Cache:EmpireConfigFilePath -BSObjectData $BSObjectData
292 |
293 |
294 | }
295 |
296 | Function Write-BSEmpireModuleData
297 | {
298 | Param (
299 | [Parameter(Mandatory=$true)] $BSObjectData
300 | )
301 | Clear-BSJON -BSFile $Cache:EmpireModuleFilePath
302 | Write-BSJSON -BSFile $Cache:EmpireModuleFilePath -BSObjectData $BSObjectData
303 |
304 |
305 | }
306 |
307 |
308 |
309 | Function Write-BSNetworkScanData
310 | {
311 | Param (
312 | [Parameter(Mandatory=$true)] $BSObjectData
313 | )
314 | Clear-BSJON -BSFile $Cache:NetworkScanFilePath
315 | Write-BSJSON -BSFile $Cache:NetworkScanFilePath -BSObjectData $BSObjectData
316 |
317 | }
318 |
319 | Function Write-BSAuditLog
320 | {
321 | Param (
322 | [Parameter(Mandatory=$true)] $BSLogContent
323 | )
324 | $BSLogContentFormatted = ($(Get-Date -Format 'yyyy-MM-dd hh:mm:ss') + ' : ' + $BSLogContent)
325 | $BSLogContentFormatted | Out-File $Cache:BSLogFilePath -Append
326 | }
--------------------------------------------------------------------------------
/Modules/Empire/BlueCommandEmpire.psm1:
--------------------------------------------------------------------------------
1 | #### All functions need to have proper function params, synopsis, help, etc....
2 | #### Also where my psd1 file at
3 |
4 | Import-Module CredentialManager -force
5 |
6 | #[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
7 | add-type @"
8 | using System.Net;
9 | using System.Security.Cryptography.X509Certificates;
10 | public class TrustAllCertsPolicy : ICertificatePolicy {
11 | public bool CheckValidationResult(
12 | ServicePoint srvPoint, X509Certificate certificate,
13 | WebRequest request, int certificateProblem) {
14 | return true;
15 | }
16 | }
17 | "@
18 |
19 | [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
20 |
21 |
22 | function Get-EmpireModules
23 | {
24 | param(
25 | [Parameter(Mandatory=$true)] $EmpireBox,
26 | [Parameter(Mandatory=$true)] $EmpireToken,
27 | $EmpirePort = '1337'
28 | )
29 |
30 | #Get Agents
31 | $Modules = Invoke-WebRequest -Method Get -uri "https://$EmpireBox`:$EmpirePort/api/modules?token=$EmpireToken"
32 | $Modules = $Modules.Content | ConvertFrom-Json
33 |
34 | $ModuleObjects = @()
35 | ForEach($Module in $Modules.modules)
36 | {
37 |
38 | $ModuleObject = [PSCustomObject]@{
39 | Name = $Module.Name
40 | Author = $Module.Author
41 | Comments = $Module.Comments
42 | Description = $Module.Description
43 | Language = $Module.Language
44 | NeedsAdmin = $Module.NeedsAdmin
45 | OpsecSafe = $Module.OpsecSafe
46 | options = $Module.options
47 | }
48 | $ModuleObjects = $ModuleObjects + $ModuleObject
49 |
50 | }
51 |
52 | return $ModuleObjects
53 |
54 | }
55 |
56 |
57 |
58 | function Start-BSEmpireModuleOnAgent
59 | {
60 | Param(
61 | [Parameter(Mandatory=$true)] $EmpireBox,
62 | [Parameter(Mandatory=$true)] $EmpireToken,
63 | $EmpirePort = '1337',
64 | [Parameter(Mandatory=$true)] $AgentName,
65 | [Parameter(Mandatory=$true)] $ModuleName,
66 | $Options = $null
67 | )
68 |
69 | $moduleURI = "https://$EmpireBox`:$EmpirePort/api/modules/"+$ModuleName+"?token=$EmpireToken"
70 | $PostBody = '{"Agent":"'+$AgentName+'"}'
71 |
72 | if($Options)
73 | {
74 | $PostBodyWithOptions = '{"Agent":"'+$AgentName+'",'+$Options+'}'
75 | $PostBody = $PostBodyWithOptions
76 | }
77 |
78 | Write-BSAuditLog -BSLogContent ("Module URI: " + $moduleURI)
79 | Write-BSAuditLog -BSLogContent ("Post Body: " + $PostBody)
80 |
81 | # TODO : MODULE OPTIONS IMPLEMENTATION
82 | <#
83 | # Guessing this is like...
84 | # {
85 | "Agent": "WTN1LHHRYHFWHXU3",
86 | "OPtion1": "Test",
87 | "Option2": "Test2"
88 | }
89 | #>
90 |
91 | #Get Agents
92 | $ModuleExecution = Invoke-WebRequest -Method Post -uri $moduleURI -Body $PostBody -ContentType 'application/json'
93 |
94 | $ModuleExecutionStatusCode = $ModuleExecution.StatusCode
95 |
96 | Write-BSAuditLog -BSLogContent ("Execution Code: " + $ModuleExecutionStatusCode)
97 |
98 | if($ModuleExecutionStatusCode -eq '200')
99 | {
100 | $ModuleExecution = $ModuleExecution.Content | ConvertFrom-Json
101 | $Return = (($ModuleExecution.msg) + " - Execution Status: " + ($ModuleExecution.success))
102 | $ReturnTitleCase = (Get-Culture).textinfo.totitlecase($Return.tolower())
103 |
104 | return $ReturnTitleCase
105 | }
106 | else
107 | {
108 | return ("Execution Status: FAILED")
109 | }
110 |
111 | }
112 |
113 |
114 | function Get-AgentDownloads
115 | {
116 | Param(
117 | [Parameter(Mandatory=$true)] $CredentialName,
118 | [Parameter(Mandatory=$true)] $EmpireServer,
119 | [Parameter(Mandatory=$true)] $EmpireDirectory,
120 | [Parameter(Mandatory=$true)] $EmpireAgentName,
121 | [Parameter(Mandatory=$true)] $DownloadFolder
122 |
123 | )
124 |
125 |
126 | ### USER "CREDENTIAL MANAGER" TO CONNECT TO CRED MANAGER IN WINDERS
127 | $StoredCredential = Get-StoredCredential -Target $CredentialName
128 |
129 | $Credential = $StoredCredential
130 |
131 | $LocalDownloadFolder = ($DownloadFolder + $EmpireAgentName)
132 | $ExecutionResult = ""
133 |
134 | Try{
135 | Get-SCPFolder -LocalFolder $LocalDownloadFolder -RemoteFolder ($EmpireDirectory +'/downloads/'+$EmpireAgentName) -ComputerName $EmpireServer -Credential $Credential -Force
136 | $ExecutionResult = "OK"
137 | }
138 | Catch
139 | {
140 | $ExecutionResult = "FAIL"
141 | }
142 |
143 | return $ExecutionResult
144 | }
145 |
146 | Function Get-LocalAgentLogDetails
147 | {
148 |
149 | Param(
150 | [Parameter(Mandatory=$true)] $DownloadFolder,
151 | [Parameter(Mandatory=$true)] $EmpireAgentName
152 | )
153 |
154 | $LocalAgentDownloadFolder = $DownloadFolder + $EmpireAgentName
155 |
156 | $TimeStampRegex = '\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d :' #LOL - TODO wtf is this?
157 |
158 |
159 | IF(Test-Path $LocalAgentDownloadFolder)
160 | {
161 | $AgentLogContent = Get-Content -Path ($LocalAgentDownloadFolder + '\agent.log')
162 | $AgentResultObjects = @()
163 | $ObjectData = "";
164 | ForEach($Line in $AgentLogContent)
165 | {
166 | if($Line -match $TimeStampRegex)
167 | {
168 |
169 | IF($ObjectData -ne "")
170 | {
171 | $CompleteObjectData = $ObjectData
172 | $ResultObject.Message = $CompleteObjectData;
173 | $AgentResultObjects = $AgentResultObjects + $ResultObject
174 | $ObjectData = ""
175 | }
176 |
177 | $ResultObject = [PSCustomObject]@{
178 | TimeStamp = ($Line.ToString().Replace(' :',''))
179 | Message = "test"
180 | }
181 |
182 | }
183 | else
184 | {
185 | $ObjectData = $ObjectData + $Line;
186 |
187 | }
188 |
189 | }
190 |
191 |
192 |
193 | }
194 |
195 |
196 |
197 | Return $AgentResultObjects
198 |
199 |
200 |
201 |
202 |
203 | }
204 |
205 | Function Get-EmpireInformation
206 | {
207 | Param(
208 | [Parameter(Mandatory=$true)]$EmpireBox,
209 | [Parameter(Mandatory=$true)]$EmpireToken,
210 | $EmpirePort = '1337'
211 | )
212 |
213 |
214 | #Get Version
215 | $Verison = Invoke-WebRequest -Method Get -uri "https://$EmpireBox`:$EmpirePort/api/version?token=$EmpireToken"
216 | $Verison = $Verison.Content | ConvertFrom-Json
217 | $Verison = $Verison.version
218 |
219 | #Get Listeners
220 | $Listeners = Invoke-WebRequest -Method Get -uri "https://$EmpireBox`:$EmpirePort/api/listeners?token=$EmpireToken"
221 | $Listeners = $Listeners.Content | ConvertFrom-Json
222 |
223 | #Get Agents
224 | $Agents = Invoke-WebRequest -Method Get -uri "https://$EmpireBox`:$EmpirePort/api/agents?token=$EmpireToken"
225 | $Agents = $Agents.Content | ConvertFrom-Json
226 | ForEach($Agent in $Agents.agents)
227 | {
228 | #Write-Host $Agent.
229 | }
230 |
231 |
232 | #Start-Command
233 |
234 | #& "curl --insecure -i https://$EmpireBox`:$EmpirePort/api/version?token=$EmpireToken"
235 |
236 |
237 | }
238 |
239 | Function Get-EmpireAgentResults
240 | {
241 |
242 | Param(
243 | [Parameter(Mandatory=$true)]$EmpireBox,
244 | [Parameter(Mandatory=$true)]$EmpireToken,
245 | $EmpirePort = '1337',
246 | [Parameter(Mandatory=$true)]$AgentName
247 | )
248 |
249 | $uri = 'https://'+$EmpireBox+':'+$EmpirePort+'/api/agents/'+$AgentName+'/results?token='+$EmpireToken
250 |
251 | $AgentResults = Invoke-WebRequest -Method Get -uri $uri
252 | $AgentResults = $AgentResults.Content | ConvertFrom-Json
253 | $AgentResultObjects = @()
254 | ForEach($Result in $AgentResults.results.AgentResults)
255 | {
256 |
257 | $ResultObject = [PSCustomObject]@{
258 | agentname = $AgentName
259 | command = $Result.command
260 | results = $Result.results
261 | }
262 | $AgentResultObjects = $AgentResultObjects + $ResultObject
263 |
264 | }
265 |
266 | return $AgentResultObjects
267 | }
268 |
269 | Function Get-EmpireAgents
270 | {
271 | Param(
272 | [Parameter(Mandatory=$true)]$EmpireBox,
273 | [Parameter(Mandatory=$true)]$EmpireToken,
274 | $EmpirePort = '1337'
275 | )
276 |
277 |
278 | #Get Agents
279 | $Agents = Invoke-WebRequest -Method Get -uri "https://$EmpireBox`:$EmpirePort/api/agents?token=$EmpireToken"
280 | $Agents = $Agents.Content | ConvertFrom-Json
281 |
282 | $AgentObjects = @()
283 | ForEach($Agent in $Agents.agents)
284 | {
285 |
286 | $AgentObject = [PSCustomObject]@{
287 | id = $Agent.ID
288 | checkin_time = $Agent.checkin_time
289 | external_ip = $Agent.external_ip
290 | hostname = $Agent.hostname
291 | internal_ip = $Agent.internal_ip
292 | langauge = $Agent.language
293 | langauge_version = $Agent.language_version
294 | lastseen_time = $Agent.lastseen_time
295 | listener = $Agent.listener
296 | name = $Agent.name
297 | os_details = $Agent.os_details
298 | username = $Agent.username
299 | }
300 | $AgentObjects = $AgentObjects + $AgentObject
301 |
302 | }
303 |
304 | return $AgentObjects
305 | }
306 |
307 |
308 |
309 | Function Get-EmpireModules{
310 |
311 | Param(
312 | [Parameter(Mandatory=$true)] $EmpireBox,
313 | [Parameter(Mandatory=$true)] $EmpireToken,
314 | $EmpirePort = '1337'
315 | )
316 |
317 | #Get Agents
318 | $Modules = Invoke-WebRequest -Method Get -uri "https://$EmpireBox`:$EmpirePort/api/modules?token=$EmpireToken"
319 | $Modules = $Modules.Content | ConvertFrom-Json
320 |
321 | $ModuleObjects = @()
322 | ForEach($Module in $Modules.modules)
323 | {
324 |
325 | $ModuleObject = [PSCustomObject]@{
326 | Name = $Module.Name
327 | Author = $Module.Author
328 | Comments = $Module.Comments
329 | Description = $Module.Description
330 | Language = $Module.Language
331 | NeedsAdmin = $Module.NeedsAdmin
332 | OpsecSafe = $Module.OpsecSafe
333 | options = $Module.options
334 | }
335 | $ModuleObjects = $ModuleObjects + $ModuleObject
336 |
337 | }
338 |
339 | return $ModuleObjects
340 |
341 |
342 | }
343 |
344 |
345 | Function Get-EmpireStatus
346 | {
347 | Param(
348 | [Parameter(Mandatory=$true)] $EmpireBox,
349 | [Parameter(Mandatory=$true)] $EmpireToken,
350 | $EmpirePort = '1337'
351 | )
352 |
353 | #Get Configuration
354 | try{
355 | $ConfigurationInformation = Invoke-WebRequest -Method Get -uri "https://$EmpireBox`:$EmpirePort/api/config?token=$EmpireToken"
356 | $ConfigurationInformation = $ConfigurationInformation.Content | ConvertFrom-Json
357 | $ConfigurationInformation = $ConfigurationInformation.config
358 |
359 |
360 | $ConfigurationInformationObject = [PSCustomObject]@{
361 | empire_host = $EmpireBox
362 | empire_port = $EmpirePort
363 | empire_token = $EmpireToken
364 | api_username = $ConfigurationInformation.api_username
365 | install_path = $ConfigurationInformation.install_path
366 | version = $ConfigurationInformation.version
367 | sync_time = ($(Get-Date -Format 'yyyy-MM-dd hh:mm:ss'))
368 | }
369 |
370 | }
371 | catch
372 | {
373 | $ConfigurationInformationObject = $null
374 | }
375 |
376 | return $ConfigurationInformationObject
377 | }
378 |
379 | Function Get-EmpireReports
380 | {
381 | #https://github.com/EmpireProject/Empire/wiki/RESTful-API
382 |
383 | Param(
384 | [Parameter(Mandatory=$true)] $EmpireBox,
385 | [Parameter(Mandatory=$true)] $EmpireToken,
386 | $EmpirePort = '1337',
387 | [Parameter(Mandatory=$true)] $AgentName,
388 | $Options = "",
389 | $ReportType = "result" #task, result, checkin
390 | )
391 |
392 | ### AGENT - NOT WORKING
393 | $uri = 'https://'+$EmpireBox+':'+$EmpirePort+'/api/reporting/agent/'+$AgentName+'?token='+$EmpireToken
394 |
395 | ### ALL - WORKING
396 | #$uri = "https://$EmpireBox`:$EmpirePort/api/reporting?token="+$EmpireToken
397 |
398 | ### TYPE
399 | $uri = 'https://'+$EmpireBox+':'+$EmpirePort+'/api/reporting/type/'+$ReportType+'?token='+$EmpireToken
400 |
401 |
402 | $uri
403 | $Reports = Invoke-WebRequest -Method Get -uri $uri
404 | $Reports = $Reports.Content | ConvertFrom-Json
405 | $ReportObjects = @()
406 | ForEach($Report in $Reports.reporting)
407 | {
408 |
409 | $ReportObject = [PSCustomObject]@{
410 | id = $Report.ID
411 | agentname = $Report.agentname
412 | event_type = $Report.event_type
413 | message = $Report.message
414 | timestamp = $Report.timestamp
415 |
416 | }
417 | $ReportObjects = $ReportObjects + $ReportObject
418 |
419 | }
420 |
421 | return $ReportObjects
422 | }
--------------------------------------------------------------------------------
/Pages/AgentLogs.ps1:
--------------------------------------------------------------------------------
1 | New-UDPage -Name "EmpireAgentLogs" -Icon file -Endpoint {
2 |
3 | $EmpireAgents = Get-BSEmpireAgentData
4 | $EmpireModules = Get-BSEmpireModuleData
5 | $EmpireConfiguration = Get-BSEmpireConfigData
6 |
7 | $EmpireBox = $EmpireConfiguration.empire_host
8 | $EmpirePort = $EmpireConfiguration.empire_port
9 | $EmpireToken = $EmpireConfiguration.empire_token
10 |
11 |
12 | New-UDInput -Title "Retrieve Logs" -Id "AgentResultsRetrieval" -Content {
13 |
14 | New-UDInputField -Type 'select' -Name 'EmpireAgentName' -Values $EmpireAgents.name -DefaultValue (($EmpireAgents | Select-Object -First 1).Name) -Placeholder "Select an Agent"
15 | New-UDInputField -Type 'textbox' -Name 'WindowsCredentialName' -DefaultValue ($Cache:WindowsCredentialName) -Placeholder 'Name of Generic Windows Credential to Connect to Empire Server'
16 |
17 | } -Endpoint {
18 | param($EmpireAgentName, $WindowsCredentialName)
19 |
20 | $DownloadFolder = $Cache:BSDownloadsPath
21 |
22 | if($DownloadFolder -notlike '*\')
23 | {
24 | $DownloadFolder = $DownloadFolder + '\'
25 | }
26 |
27 | $LocalAgentDownloadFolder = $DownloadFolder + $EmpireAgentName
28 |
29 | New-UDInputAction -Toast "Getting Results for Agent: $EmpireAgentName"
30 | Write-BSAuditLog -BSLogContent "Empire Results: Getting Results for Agent: $EmpireAgentName"
31 |
32 | # EXECUTE DOWNLOAD LOGS FOR AGENT
33 | Write-BSAuditLog -BSLogContent "Empire Results: Attempting to Download Data from Agent: $EmpireAgentName to $DownloadFolder"
34 | $AgentLogDownloadStatus = Get-AgentDownloads -EmpireServer $Cache:EmpireServer -EmpireDirectory $Cache:EmpireDirectory -EmpireAgentName $EmpireAgentName -DownloadFolder $DownloadFolder -CredentialName $WindowsCredentialName
35 |
36 | Write-BSAuditLog -BSLogContent "Empire Results: Attempting to Read Downloaded Data from Agent: $EmpireAgentName"
37 | $AgentLogDetails = Get-LocalAgentLogDetails -EmpireAgentName $EmpireAgentName -DownloadFolder $DownloadFolder
38 |
39 |
40 |
41 | Show-UDModal -Content {
42 | New-UDHeading -Size 4 -Text "Agent Results Download"
43 | New-UDHeading -Size 6 -Text "Agent: $EmpireAgentName Results downloaded to: $LocalAgentDownloadFolder"
44 | New-UDGrid -Title "Agent Logs" -Headers @("TimeStamp", "Message") -Properties @("TimeStamp","Message") -Endpoint {
45 |
46 | #TODO - THIS IS BUG! TABLE WORKS FINE
47 | $AgentLogDetails | Out-UDGridData
48 | }
49 |
50 |
51 | }
52 |
53 |
54 |
55 | Write-BSAuditLog -BSLogContent "Empire Results: Retrieval and Display Completed"
56 |
57 | }
58 |
59 |
60 |
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/Pages/Configuration.ps1:
--------------------------------------------------------------------------------
1 | New-UDPage -Name "EmpireConfiguration" -Icon empire -Endpoint {
2 |
3 |
4 | $NetworkResources = Get-BSNetworkScanData
5 | $ValidEmpireNetworkResources = @()
6 |
7 | ForEach($Resource in $NetworkResources)
8 | {
9 | if($Resource.isEmpire -eq 'YES')
10 | {
11 | $ValidEmpireNetworkResources = $ValidEmpireNetworkResources + $Resource
12 |
13 | }
14 | else
15 | {
16 | #NOT EMPIRE SERVER
17 | }
18 | }
19 | $EmpireConfig = Get-BSEmpireConfigData
20 |
21 |
22 |
23 | New-UDInput -Title "Connect to New Empire Server" -Id "EmpireConfiguration" -SubmitText "Connect" -Content {
24 | New-UDInputField -Type 'textarea' -Name 'EmpireIP' -DefaultValue $Cache:EmpireServer
25 | New-UDInputField -Type 'textarea' -Name 'EmpirePort' -DefaultValue '1337'
26 | New-UDInputField -Type 'textarea' -Name 'EmpireToken' -DefaultValue $EmpireConfig.empire_token
27 | } -Endpoint {
28 | param($EmpireIP, $EmpirePort, $EmpireToken)
29 | New-UDInputAction -Toast "Retrieving Empire Configurations!"
30 |
31 | $EmpireComputer = $EmpireIP
32 |
33 | Write-BSAuditLog -BSLogContent "Empire Configuration: Attempting to Retrieve Configuration from: $EmpireComputer"
34 |
35 |
36 | $EmpireConfiguration = Get-EmpireStatus -EmpireBox $EmpireComputer -EmpireToken $EmpireToken -EmpirePort $EmpirePort
37 | Write-BSEmpireConfigData -BSObject $EmpireConfiguration
38 |
39 | $EmpireAgents = Get-EmpireAgents -EmpireBox $EmpireComputer -EmpireToken $EmpireToken -EmpirePort $EmpirePort
40 | Write-BSEmpireAgentData -BSObject $EmpireAgents
41 |
42 | $EmpireModules = Get-EmpireModules -EmpireBox $EmpireComputer -EmpireToken $EmpireToken -EmpirePort $EmpirePort
43 | Write-BSEmpireModuleData -BSObject $EmpireModules
44 |
45 | #Update Other Elements
46 | Sync-UDElement -Id "ExistingEmpireInstance" -Broadcast
47 | Sync-UDElement -Id "EmpireAgents" -Broadcast
48 | Sync-UDElement -Id "EmpireModules" -Broadcast
49 |
50 | Write-BSAuditLog -BSLogContent "Empire Configuration: Configuration Retrieval Complete"
51 |
52 | }
53 |
54 |
55 |
56 |
57 | New-UDGrid -Title "Existing Empire Instance" -Id "ExistingEmpireInstance" -Headers @("empire_host","version", "api_username", "install_path", "sync_time") -Properties @("empire_host","version", "api_username", "install_path", "sync_time") -Endpoint {
58 | $JsonData = Get-BSEmpireConfigData
59 | If ($JsonData.version)
60 | {
61 | $Text = 'Empire - Version: ' + ($JsonData.version) +' - User: ' + ($JsonData.api_username) + ' - Installed: ' + ($JsonData.install_path)
62 | }
63 | else
64 | {
65 | $Text = "No Empire Found - Run Config!"
66 | }
67 | $JsonData | Out-UDGridData
68 | }
69 |
70 |
71 | New-UDGrid -Title "Empire Agents" -Id "EmpireAgents" -Headers @("id", "name", "checkin_time","external_ip","hostname","langauge", "langauge_version", "lastseen_time","listener","os_details","username") -Properties @("id", "name", "checkin_time","external_ip","hostname","langauge", "langauge_version", "lastseen_time","listener","os_details","username") -AutoRefresh -Endpoint {
72 | $JsonData = Get-BSEmpireAgentData
73 | $JsonData | Out-UDGridData
74 | }
75 |
76 | New-UDGrid -Title "Empire Modules" -Id "EmpireModules" -Headers @("Name", "Description", "Author","Language","NeedsAdmin","OpsecSafe") -Properties @("Name", "Description", "Author","Language","NeedsAdmin","OpsecSafe") -AutoRefresh -Endpoint {
77 | $JsonData = Get-BSEmpireModuleData
78 | $JsonData | Out-UDGridData
79 | }
80 |
81 |
82 | }
--------------------------------------------------------------------------------
/Pages/Downloads.ps1:
--------------------------------------------------------------------------------
1 | New-UDPage -Name "EmpireDownloads" -Icon download -Endpoint {
2 |
3 | $EmpireAgents = Get-BSEmpireAgentData
4 | $EmpireModules = Get-BSEmpireModuleData
5 | $EmpireConfiguration = Get-BSEmpireConfigData
6 |
7 | $EmpireBox = $EmpireConfiguration.empire_host
8 | $EmpirePort = $EmpireConfiguration.empire_port
9 | $EmpireToken = $EmpireConfiguration.empire_token
10 |
11 |
12 |
13 | New-UDInput -Title "Retrieve Files" -Id "AgentResultsRetrieval" -Content {
14 |
15 | New-UDInputField -Type 'select' -Name 'EmpireAgentName' -Values $EmpireAgents.name -DefaultValue (($EmpireAgents | Select-Object -First 1).Name) -Placeholder "Select an Agent"
16 | New-UDInputField -Type 'textbox' -Name 'WindowsCredentialName' -DefaultValue 'empireserver' -Placeholder 'Name of Generic Windows Credential to Connect to Empire Server'
17 |
18 | } -Endpoint {
19 | param($EmpireAgentName, $WindowsCredentialName)
20 |
21 | $DownloadFolder = $Cache:BSDownloadsPath
22 |
23 | if($DownloadFolder -notlike '*\')
24 | {
25 | $DownloadFolder = $DownloadFolder + '\'
26 | }
27 |
28 | New-UDInputAction -Toast "Getting Results for Agent: $EmpireAgentName"
29 | Write-BSAuditLog -BSLogContent "Empire Results: Getting Results for Agent: $EmpireAgentName"
30 |
31 | # EXECUTE DOWNLOAD LOGS FOR AGENT
32 | Write-BSAuditLog -BSLogContent "Empire Results: Attempting to Download Data from Agent: $EmpireAgentName to $DownloadFolder"
33 | $AgentLogDownloadStatus = Get-AgentDownloads -EmpireServer $Cache:EmpireServer -EmpireDirectory $Cache:EmpireDirectory -EmpireAgentName $EmpireAgentName -DownloadFolder $DownloadFolder -CredentialName $WindowsCredentialName
34 |
35 | Sync-UDElement -Id 'DownloadedFilesGrid' -Broadcast
36 |
37 | Write-BSAuditLog -BSLogContent "Empire Results: Retrieval Completed"
38 |
39 | }
40 |
41 |
42 | New-UDGrid -Title "Downloaded Files" -Id "DownloadedFilesGrid" -Headers @("Name", "CreationTime", "Agent", "Download") -Properties @("Name", "CreationTime", "Agent","Download") -Endpoint {
43 | Get-BSDownloads | ForEach-Object {
44 |
45 | [PSCustomObject]@{
46 | Name = $_.Name
47 | CreationTime = $_.CreationTime
48 | Agent = $_.Agent
49 | Download = New-UDButton -Text "Download" -OnClick (New-UDEndpoint -Endpoint{
50 |
51 | $FileName = $ArgumentList[0]
52 | $AgentFolder = $ArgumentList[1]
53 | $FullPath = $ArgumentList[2]
54 |
55 | $FullPathWeb = $FullPath.Replace(($Cache:BlueCommandDataFolder+'\'),"")
56 | $FullPathWeb = $FullPathWeb.Replace('\',"/")
57 |
58 | $WebFileURL = 'http://localhost:'+ $Cache:BlueCommandPort + '/' + $FullPathWeb
59 | #Invoke-WebRequest $WebFileURL
60 | Invoke-UDRedirect -Url $WebFileURL -OpenInNewWindow
61 |
62 |
63 | } -ArgumentList $_.Name, $_.Agent, $_.FullPath)
64 | }
65 | } | Out-UDGridData
66 | }
67 |
68 |
69 | New-UDElement -Tag "ul" -Id "ExecutionResults2" -Content {
70 |
71 | }
72 |
73 | New-UDElement -Tag "ul" -Id "ButtonOpenLoot" -Content {
74 |
75 | }
76 |
77 |
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/Pages/Execution.ps1:
--------------------------------------------------------------------------------
1 | New-UDPage -Name "EmpireExecution" -Icon plane -Endpoint {
2 |
3 |
4 | $Session:CurrentlySelectedAgent = "NULL"
5 | $Session:EmpireModules = Get-BSEmpireModuleData
6 |
7 | ## If Only ONE Agent Availible Just Select the First Agent
8 | $Session:EmpireAgents = Get-BSEmpireAgentData
9 | if($Session:EmpireAgents)
10 | {
11 | $Session:CurrentlySelectedAgent = ($Session:EmpireAgents | Select-Object -First 1).name
12 | }
13 |
14 |
15 | #### Module "Package" Selection Box - With Boxes!
16 | New-UDGrid -Title "Package Selection" -Headers @("Name", "Description", " ") -Properties @("Name", "Description", "Execute") -Endpoint {
17 | $Session:EmpireModules | ForEach-Object {
18 |
19 | [PSCustomObject]@{
20 | Name = $_.Name
21 | Description = $_.Description
22 | Execute = New-UDButton -Text "Execute" -OnClick (New-UDEndpoint -Endpoint {
23 |
24 | $EmpireAgentName = $ArgumentList[0]
25 | $ModuleName = $ArgumentList[1]
26 | $ModuleDescription = $ArgumentList[2]
27 | $ModuleOptions = $ArgumentList[3]
28 |
29 | Write-BSAuditLog -BSLogContent "Empire Operations: Planning Execution for $ModuleName on Agent $EmpireAgentName"
30 |
31 | if ($EmpireAgentName -ne $null)
32 | {
33 |
34 | Show-UDModal -Content {
35 | New-UDTable -Title "Strike Package Details" -Headers @("Name", "Description") -Endpoint {
36 | @{
37 | 'Name' = $ModuleName
38 | 'Description' = $ModuleDescription
39 | } | Out-UDTableData -Property @("Name", "Description")
40 |
41 | }
42 |
43 | New-UDTable -Title "Module Options" -Headers @("Option Name", "Definition") -Endpoint {
44 | $ModuleOptions | Out-UDTableData -Property @("Name", "Definition")
45 | }
46 |
47 | New-UDInput -Title "Execute Strike Package" -Id "AgentModuleOperations" -SubmitText "Execute" -Content {
48 | New-UDInputField -Type 'select' -Name 'EmpireAgentName' -Values $Session:EmpireAgents.name -DefaultValue $Session:CurrentlySelectedAgent -Placeholder "Select an Agent"
49 | New-UDInputField -Type 'textbox' -Name 'OptionsJSON' -DefaultValue $null
50 | } -Endpoint {
51 |
52 | ## GET EMPIRE CONFIGO
53 |
54 | $EmpireConfiguration = Get-BSEmpireConfigData
55 |
56 | $EmpireBox = $EmpireConfiguration.empire_host
57 | $EmpirePort = $EmpireConfiguration.empire_port
58 | $EmpireToken = $EmpireConfiguration.empire_token
59 |
60 | ## TODO OPtions Parsing?
61 | If($OptionsJSON)
62 | {
63 | $ExecutuionLog = 'Empire Operations: Executing Action: ' + $ModuleName +' on: ' + $EmpireAgentName + " which lives on $EmpireBox"
64 | Write-BSAuditLog -BSLogContent $ExecutuionLog
65 | $EmpireModuleExecution = Start-BSEmpireModuleOnAgent -EmpireBox $EmpireBox -EmpireToken $EmpireToken -EmpirePort $EmpirePort -AgentName $EmpireAgentName -ModuleName $ModuleName
66 | }
67 | else
68 | {
69 | $ExecutuionLog = 'Empire Operations: Executing Action: ' + $ModuleName +' WITH OPTIONS: ' + $OptionsJSON + ' on: ' + $EmpireAgentName + " which lives on $EmpireBox"
70 | Write-BSAuditLog -BSLogContent $ExecutuionLog
71 | $EmpireModuleExecution = Start-BSEmpireModuleOnAgent -EmpireBox $EmpireBox -EmpireToken $EmpireToken -EmpirePort $EmpirePort -AgentName $EmpireAgentName -ModuleName $ModuleName -Options $OptionsJSON
72 | }
73 |
74 |
75 | Write-BSAuditLog -BSLogContent $EmpireModuleExecution
76 |
77 |
78 | Clear-UDElement -Id "StrikePackageExecution"
79 | Add-UDElement -ParentId "StrikePackageExecution" -Content {
80 | New-UDHtml -Markup ('STRIKE STATUS: EXECUTED
' + '' + $EmpireModuleExecution + '')
81 | }
82 |
83 | }
84 |
85 | New-UDElement -Id "StrikePackageExecution" -Tag "b" -Content {
86 | New-UDHtml -Markup ('STRIKE STATUS: DEPLOYMENT READY')
87 | }
88 |
89 |
90 | }
91 |
92 | }
93 | else{
94 |
95 | Show-UDModal -Content {
96 | New-UDHeading -Size 4 -Text "Invalid Selection!"
97 | New-UDHeading -Size 6 -Text "You must Select a VALID Agent First!"
98 | }
99 | }
100 |
101 | } -ArgumentList $Session:CurrentlySelectedAgent, $_.Name, $_.Description, $_.Options)
102 | }
103 |
104 | } | Out-UDGridData
105 |
106 |
107 | }
108 |
109 |
110 | }
111 |
--------------------------------------------------------------------------------
/Pages/home.ps1:
--------------------------------------------------------------------------------
1 | New-UDPage -Name "Home" -Icon home -Endpoint {
2 |
3 | ### CARD COUNTS
4 | $EmpireAgentsJsonData = Get-BSEmpireAgentData
5 | $EmpireModulesJsonData = Get-BSEmpireModuleData
6 | $NetworkResourcesJsonData = Get-BSNetworkScanData
7 |
8 | $NetworkResourcesCount = ($NetworkResourcesJsonData | Measure | Select-Object Count).Count
9 | $EmpireAgentsCount = ($EmpireAgentsJsonData | Measure | Select-Object Count).Count
10 | $EmpireModuleCount = $EmpireModulesJsonData.Count
11 |
12 | New-UDRow -Columns {
13 |
14 |
15 | New-UDColumn -Size 2 {
16 |
17 | New-UDCounter -Title "Empire Modules" -BackgroundColor '#4C9BF3' -FontColor '#FFFFFF' -Endpoint {
18 | $EmpireModuleCount | ConvertTo-Json
19 | }
20 |
21 | }
22 |
23 | New-UDColumn -Size 2 {
24 |
25 | New-UDCounter -Title "Active Agents" -BackgroundColor '#4CC6DB' -FontColor '#FFFFFF' -Endpoint {
26 | $EmpireAgentsCount | ConvertTo-Json
27 | }
28 |
29 | }
30 |
31 | New-UDColumn -Size 2 {
32 |
33 | New-UDCounter -Title "Agent Files" -BackgroundColor '#7561F1' -FontColor '#FFFFFF' -Endpoint {
34 | Get-BSDownloadsCount | ConvertTo-Json
35 | }
36 |
37 | }
38 | <#
39 | New-UDColumn -Size 2 {
40 |
41 | New-UDCounter -Title "Agent Files Downloaded" -BackgroundColor '#F2496A' -FontColor '#FFFFFF' -Endpoint {
42 | Get-BSDownloadsCount | ConvertTo-Json
43 | }
44 |
45 | }
46 | #>
47 |
48 |
49 | }
50 |
51 | New-UDTable -Title "Existing Empire Instance" -Id "ExistingEmpireInstance" -Headers @("Empire IP","Version", "Path", "Sync Time") -Endpoint {
52 | $JsonData = Get-BSEmpireConfigData
53 | $JsonData | Out-UDTableData -Property @("empire_host","version", "install_path", "sync_time")
54 | }
55 |
56 |
57 | $JsonData = Get-BSEmpireAgentData
58 | New-UDGrid -Title "Empire Agents" -Headers @("Name", "Created", "Last Seen","External IP","Hostname","Listener","OS","Username") -Properties @("name", "checkin_time","lastseen_time","external_ip","hostname","listener","os_details","username") -AutoRefresh -Endpoint {
59 |
60 | $JsonData | Out-UDGridData
61 | }
62 |
63 |
64 |
65 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | BlueCommand 🌌
2 | ==================
3 |
4 | **BlueCommand** is a dashboard and tooling front-end for [PowerShell Empire](https://github.com/EmpireProject/Empire) using [PowerShell Universal Dashboard](https://universaldashboard.io/) from [Adam Driscoll](https://github.com/adamdriscoll)
5 |
6 | 
7 |
8 |
9 | **WARNING**: This project does not nearly scratch the surface of interacting with all the capababilites of PowerShell Empire. This was a project to help my learn / play around with PowerShell Empire and its' REST API. You will be much better served in life but actually learning how to use PowerShell Empire :)
10 |
11 | # Features
12 | * Web Dashboard / Controller for PowerShell Empire!
13 | * Utilizes the Empire REST API and [PowerShell Universal Dashboard](https://universaldashboard.io/)
14 | * [PowerShell Empire](https://www.powershellempire.com/) Integration
15 | * Rest Integration to retrieve Empire Instance Information (Agents, Modules Downloads)
16 | * Rest Integration to Execute Modules on Agents.
17 | * SCP to Download Agent Results / Downloads
18 |
19 | **Searching and Executing Modules on Empire Agents**
20 | 
21 |
22 | **Retrieving Agent Downloads**
23 | 
24 |
25 | # Getting Started
26 |
27 | ## Prereqs
28 | 1. Install [Universal Dashboard](https://universaldashboard.io/) ``Install-Module UniversalDashboard -AccecptLicense``
29 | 2. Install [PoshSSH](https://github.com/darkoperator/Posh-SSH) ``Install-Module -Name Posh-SSH``
30 | * PoshSSH is used to run SCP commands to extract agent artifacts.
31 | 3. Install [PowerShell Credential Manager](https://github.com/davotronic5000/PowerShell_Credential_Manager) ``Install-Module -Name CredentialManager``
32 | * Credential Manager allows use to easily use Windows Credential Manager to auth to our Empire Server
33 | 4. Setup [PowerShell Empire](https://www.powershellempire.com/)
34 | + Run Empire with --rest command
35 | + Generate a Listener / Stager
36 | + Deploy Agents
37 | + Make a Note of Rest Key and Empire Server IP.
38 |
39 | ## Usage
40 | 1. Populate your environment variables in the ``start.ps1`` Script
41 | 2. Run the Start Script
42 | 3. Connect to your Empire Server on the Empire Configuration Page using your Empire Server IP, and Rest API Key.
43 | * 
44 | 4. BlueCommand will try and utilze POSH-SSH to SCP Download the Empire Agents Downloads/Logs - This requires a stored a "Generic Credential" in your windows credential manager to facilitate this. 
45 |
--------------------------------------------------------------------------------
/bluecommand.psd1:
--------------------------------------------------------------------------------
1 | @{
2 |
3 | # Script module or binary module file associated with this manifest.
4 | RootModule = '.\BlueCommand.psm1'
5 |
6 | # Version number of this module.
7 | ModuleVersion = '1.0'
8 |
9 | # Supported PSEditions
10 | # CompatiblePSEditions = @()
11 |
12 | # ID used to uniquely identify this module
13 | GUID = '7d9d3976-88eb-4c1c-af84-b8bf54cf3153'
14 |
15 | # Author of this module
16 | Author = 'Lee Berg'
17 |
18 | # Company or vendor of this module
19 | CompanyName = 'Berg Studios'
20 |
21 | # Copyright statement for this module
22 | Copyright = '(c) 2019 Lee Berg. All rights reserved.'
23 |
24 | # Description of the functionality provided by this module
25 | Description = 'A sec tool built on Universal Dashboard.'
26 |
27 | # Minimum version of the Windows PowerShell engine required by this module
28 | # PowerShellVersion = ''
29 |
30 | # Name of the Windows PowerShell host required by this module
31 | # PowerShellHostName = ''
32 |
33 | # Minimum version of the Windows PowerShell host required by this module
34 | # PowerShellHostVersion = ''
35 |
36 | # Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
37 | # DotNetFrameworkVersion = ''
38 |
39 | # Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
40 | # CLRVersion = ''
41 |
42 | # Processor architecture (None, X86, Amd64) required by this module
43 | # ProcessorArchitecture = ''
44 |
45 | # Modules that must be imported into the global environment prior to importing this module
46 | #RequiredModules = @()
47 |
48 | # Assemblies that must be loaded prior to importing this module
49 | # RequiredAssemblies = @()
50 |
51 | # Script files (.ps1) that are run in the caller's environment prior to importing this module.
52 | # ScriptsToProcess = @()
53 |
54 | # Type files (.ps1xml) to be loaded when importing this module
55 | # TypesToProcess = @()
56 |
57 | # Format files (.ps1xml) to be loaded when importing this module
58 | # FormatsToProcess = @()
59 |
60 | # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
61 | # NestedModules = @()
62 |
63 | # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
64 | FunctionsToExport = '*'
65 |
66 | # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
67 | CmdletsToExport = '*'
68 |
69 | # Variables to export from this module
70 | VariablesToExport = '*'
71 |
72 | # Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
73 | AliasesToExport = '*'
74 |
75 | # DSC resources to export from this module
76 | # DscResourcesToExport = @()
77 |
78 | # List of all modules packaged with this module
79 | # ModuleList = @()
80 |
81 | # List of all files packaged with this module
82 | # FileList = @()
83 |
84 |
85 | # HelpInfo URI of this module
86 | # HelpInfoURI = ''
87 |
88 | # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
89 | # DefaultCommandPrefix = ''
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/bluecommand.psm1:
--------------------------------------------------------------------------------
1 | function Start-BSDash {
2 | param(
3 | [Parameter(Mandatory=$true)] $EmpireServer,
4 | [Parameter(Mandatory=$true)] $EmpireDirectory,
5 | [Parameter(Mandatory=$true)] $EmpirePort,
6 | [Parameter(Mandatory=$true)] $BlueCommandFolder,
7 | [Parameter(Mandatory=$true)] $BlueCommandPort,
8 | [Parameter(Mandatory=$false)] $WindowsCredentialName
9 | )
10 |
11 | # This Caches the Connection Info so the other components and modules can utilze them
12 | $Cache:ConnectionInfo = @{
13 | Server = $EmpireServer
14 | Credential = $Credential
15 | }
16 |
17 | #Dashboard Port
18 | $Cache:BlueCommandPort = $BlueCommandPort
19 |
20 | # Empire Server
21 | $Cache:EmpireServer = $EmpireServer
22 | $Cache:EmpireDirectory = $EmpireDirectory
23 | $Cache:EmpirePort = $EmpirePort
24 |
25 | $Cache:WindowsCredentialName = $WindowsCredentialName
26 |
27 | $Pages = @()
28 | $Pages += . (Join-Path $PSScriptRoot "pages\home.ps1")
29 |
30 | Get-ChildItem (Join-Path $PSScriptRoot "pages") -Exclude "home.ps1" | ForEach-Object {
31 | $Pages += . $_.FullName
32 | }
33 |
34 |
35 | #### DATA FOLDER SETUP
36 |
37 | #Folder Pathes
38 | $Cache:BlueCommandFolder = $BlueCommandFolder
39 | $Cache:BlueCommandDataFolder = $Cache:BlueCommandFolder + '\Data'
40 |
41 | #File Paths
42 | $Cache:EmpireConfigFilePath = $Cache:BlueCommandFolder + '\Data\EmpireConfig.json'
43 | $Cache:EmpireModuleFilePath = $Cache:BlueCommandFolder + '\Data\EmpireModules.json'
44 | $Cache:EmpireAgentFilePath = $Cache:BlueCommandFolder + '\Data\EmpireAgents.json'
45 | $Cache:NetworkScanFilePath = $Cache:BlueCommandFolder + '\Data\NetworkScan.json'
46 | $Cache:BSLogFilePath = $Cache:BlueCommandFolder + '\Data\AuditLog.log'
47 | $Cache:BSDownloadsPath = $Cache:BlueCommandFolder + '\Data\Downloads'
48 |
49 |
50 |
51 | if((Test-Path -Path $Cache:BlueCommandFolder) -eq $false){throw 'The BlueCommand Data Folder does not exist!'}
52 | if((Test-Path -Path $Cache:BlueCommandDataFolder) -eq $false){New-Item -Path $Cache:BlueCommandDataFolder -ItemType Directory}
53 | if((Test-Path -Path $Cache:BSDownloadsPath) -eq $false){New-Item -Path $Cache:BSDownloadsPath -ItemType Directory}
54 | if((Test-Path -Path $Cache:BSLogFilePath) -eq $false){New-Item -Path $Cache:BSLogFilePath -ItemType File}
55 |
56 | #Downloads Folder
57 | $DownloadsFolder = Publish-UDFolder -Path ($Cache:BSDownloadsPath+'\') -RequestPath '/Downloads'
58 |
59 |
60 | #### THEME
61 |
62 | $DarkDefault = New-UDTheme -Name "Basic" -Definition @{
63 | UDDashboard = @{
64 | BackgroundColor = "#393F47"
65 | FontColor = "#FFFFFF"
66 | }
67 | UDNavBar = @{
68 | BackgroundColor = "#272C33"
69 | FontColor = "#FFFFFF"
70 | }
71 | UDFooter = @{
72 | BackgroundColor = "#272C33"
73 | FontColor = "#FFFFFF"
74 | }
75 | UDCard = @{
76 | BackgroundColor = "#272C33"
77 | FontColor = "#FFFFFF"
78 | }
79 | UDChart = @{
80 | BackgroundColor = "#272C33"
81 | FontColor = "#FFFFFF"
82 | }
83 | UDMonitor = @{
84 | BackgroundColor = "#272C33"
85 | FontColor = "#FFFFFF"
86 | }
87 | UDTable = @{
88 | BackgroundColor = "#272C33"
89 | FontColor = "#FFFFFF"
90 | }
91 | UDGrid = @{
92 | BackgroundColor = "#272C33"
93 | FontColor = "#FFFFFF"
94 | }
95 | UDCounter = @{
96 | BackgroundColor = "#272C33"
97 | FontColor = "#FFFFFF"
98 | }
99 | UDInput = @{
100 | BackgroundColor = "#272C33"
101 | FontColor = "#FFFFFF"
102 | }
103 | }
104 |
105 | $BSEndpoints = New-UDEndpointInitialization -Module @("Modules\Empire\BlueCommandData.psm1", "Modules\Empire\BlueCommandEmpire.psm1")
106 | $Dashboard = New-UDDashboard -Title "BlueCommand 🌌" -Pages $Pages -EndpointInitialization $BSEndpoints -Theme $DarkDefault
107 |
108 | Try{
109 | Start-UDDashboard -Dashboard $Dashboard -Port $Cache:BlueCommandPort -PublishedFolder $DownloadsFolder
110 | }
111 | Catch
112 | {
113 | Write-Error($_.Exception)
114 | }
115 |
116 |
117 |
118 |
119 | }
120 |
--------------------------------------------------------------------------------
/img/AgentDownload.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leeberg/BlueCommand/086e14687f96b30eaa0e337b59d7c49a5492c482/img/AgentDownload.gif
--------------------------------------------------------------------------------
/img/Credential_Manager.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leeberg/BlueCommand/086e14687f96b30eaa0e337b59d7c49a5492c482/img/Credential_Manager.png
--------------------------------------------------------------------------------
/img/ExecuteModule.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leeberg/BlueCommand/086e14687f96b30eaa0e337b59d7c49a5492c482/img/ExecuteModule.gif
--------------------------------------------------------------------------------
/img/HomePage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leeberg/BlueCommand/086e14687f96b30eaa0e337b59d7c49a5492c482/img/HomePage.png
--------------------------------------------------------------------------------
/img/empire_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leeberg/BlueCommand/086e14687f96b30eaa0e337b59d7c49a5492c482/img/empire_rest.png
--------------------------------------------------------------------------------
/start.ps1:
--------------------------------------------------------------------------------
1 | # BlueCommand Start Script
2 |
3 | # Set These Variables - and populate the Credential Object
4 | $BlueCommandFolder = 'C:\Users\lee\git\BlueCommand'
5 | $EmpireServerIP = '192.168.200.106'
6 | $WindowsCredentialName = 'empireserver'
7 | $EmpireDirectory = '/home/lee/Empire'
8 | $EmpirePort = '1337'
9 |
10 |
11 | Import-Module .\BlueCommand.psd1 -Force
12 |
13 | Get-UDDashboard | Stop-UDDashboard
14 | Get-UDRestApi | Stop-UDRestAPI
15 | Start-BSDash -EmpireServer $EmpireServerIP -EmpireDirectory $EmpireDirectory -EmpirePort $EmpirePort -BlueCommandFolder $BlueCommandFolder -BlueCommandPort 10001 -WindowsCredentialName $WindowsCredentialName
--------------------------------------------------------------------------------