├── LICENSE ├── PowerMeta.ps1 ├── README.md └── exiftool.exe /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 dafthack 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PowerMeta.ps1: -------------------------------------------------------------------------------- 1 | # Disable cert checks 2 | add-type @" 3 | using System.Net; 4 | using System.Security.Cryptography.X509Certificates; 5 | public class TrustAllCertsPolicy : ICertificatePolicy { 6 | public bool CheckValidationResult( 7 | ServicePoint srvPoint, X509Certificate certificate, 8 | WebRequest request, int certificateProblem) { 9 | return true; 10 | } 11 | } 12 | "@ 13 | $AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12' 14 | [System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols 15 | [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy 16 | 17 | Function Invoke-PowerMeta{ 18 | 19 | <# 20 | .SYNOPSIS 21 | This function searches for publicly available files hosted on various sites for a particular domain by using specially crafted Google, and Bing searches. It then allows for the download of those files from the target domain. After retrieving the files, the metadata associated with them can be analyzed by PowerMeta. Some interesting things commonly found in metadata are usernames, domains, software titles, and computer names. 22 | 23 | PowerMeta Function: Invoke-PowerMeta 24 | Author: Beau Bullock (@dafthack) 25 | License: BSD 3-Clause 26 | Required Dependencies: None 27 | Optional Dependencies: None 28 | 29 | .DESCRIPTION 30 | This function searches for publicly available files hosted on various sites for a particular domain by using specially crafted Google, and Bing searches. It then allows for the download of those files from the target domain. After retrieving the files, the metadata associated with them can be analyzed by PowerMeta. Some interesting things commonly found in metadata are usernames, domains, software titles, and computer names. 31 | 32 | .PARAMETER TargetDomain 33 | The target domain to search for files. 34 | 35 | .PARAMETER FileTypes 36 | A comma seperated list of file extensions to search for. By default PowerMeta searches for "pdf, docx, xlsx, doc, xls, pptx, ppt". 37 | 38 | .PARAMETER OutputList 39 | A file to output the list of links discovered through web searching to. 40 | 41 | .PARAMETER OutputDir 42 | A directory to store all downloaded files in. 43 | 44 | .PARAMETER TargetFileList 45 | List of file links to download. 46 | 47 | .PARAMETER Download 48 | Instead of being prompted interactively pass this flag to auto-download files found. 49 | 50 | .PARAMETER Extract 51 | Instead of being prompted interactively pass this flag to extract metadata from found files pass this flag to auto-extract any metadata. 52 | 53 | .PARAMETER ExtractAllToCsv 54 | All metadata (not just the default fields) will be extracted from files to a CSV specified with this flag. 55 | 56 | .PARAMETER UserAgent 57 | Change the default User Agent used by PowerMeta. 58 | 59 | .PARAMETER MaxSearchPages 60 | The maximum number of pages to search on each search engine. 61 | 62 | .Example 63 | 64 | C:\PS> Invoke-PowerMeta -TargetDomain targetdomain.com 65 | Description 66 | ----------- 67 | This command will initiate Google and Bing searches for files on the 'targetdomain.com' domain ending with a file extension of pdf, docx, xlsx, doc, xls, pptx, or pptx. Once it has finished crafting this list it will prompt the user asking if they wish to download the files from the target domain. After downloading files it will prompt again for extraction of metadata from those files. 68 | 69 | .Example 70 | 71 | C:\PS> Invoke-PowerMeta -TargetDomain targetdomain.com -FileTypes "pdf, xml" -Download -Extract 72 | Description 73 | ----------- 74 | This command will initiate Google and Bing searches for files on the 'targetdomain.com' domain ending with a file extension of pdf, or xml. It will then automatically download them from the target domain and extract metadata. 75 | 76 | .Example 77 | 78 | C:\PS> Invoke-PowerMeta -TargetDomain targetdomain.com -TargetFileList target-domain-links.txt 79 | Description 80 | ----------- 81 | This command will initiate Google and Bing searches for files on the 'targetdomain.com' domain ending with a file extension of pdf, docx, xlsx, doc, xls, pptx, or pptx and write the links of files found to disk in a file called "target-domain-links.txt". 82 | 83 | .Example 84 | 85 | C:\PS> Invoke-PowerMeta -TargetDomain targetdomain.com -MaxSearchPages 2 -ExtractAllToCsv all-target-metadata.csv 86 | Description 87 | ----------- 88 | This command will initiate Google and Bing searches for files on the 'targetdomain.com' domain ending with a file extension of pdf, docx, xlsx, doc, xls, pptx, or pptx but only search the first to pages. All metadata (not just the default fields) will be saved in a CSV called all-target-metadata.csv. 89 | 90 | .Example 91 | 92 | C:\PS> ExtractMetadata -OutputDir .\2017-03-031-144953\ -ExtractAllToCsv all-target-metadata.csv 93 | Description 94 | ----------- 95 | This command will simply extract all the metadata from all the files in the folder "\2017-03-031-144953\" and save it in a CSV called all-target-metadata.csv 96 | 97 | #> 98 | 99 | Param 100 | ( 101 | [Parameter(Position = 0, Mandatory = $true)] 102 | [string] 103 | $TargetDomain = "", 104 | 105 | [Parameter(Position = 1, Mandatory = $false)] 106 | [string] 107 | $FileTypes = "pdf, docx, xlsx, doc, xls, pptx, ppt", 108 | 109 | [Parameter(Position = 2, Mandatory = $false)] 110 | [string] 111 | $OutputList = "", 112 | 113 | [Parameter(Position = 3, Mandatory = $false)] 114 | [string] 115 | $OutputDir = "", 116 | 117 | [Parameter(Position = 4, Mandatory = $false)] 118 | [string] 119 | $TargetFileList = "", 120 | 121 | [Parameter(Position = 5, Mandatory = $false)] 122 | [switch] 123 | $Download, 124 | 125 | [Parameter(Position = 6, Mandatory = $false)] 126 | [switch] 127 | $Extract, 128 | 129 | [Parameter(Position = 7, Mandatory = $false)] 130 | [string] 131 | $ExtractAllToCsv = "", 132 | 133 | [Parameter(Position = 8, Mandatory = $false)] 134 | [string] 135 | $UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko", 136 | 137 | [Parameter(Position = 9, Mandatory = $false)] 138 | [int] 139 | $MaxSearchPages = 5 140 | 141 | ) 142 | 143 | #If no target file list was provided we will perform searches and craft one. 144 | If ($TargetFileList -eq "") 145 | { 146 | 147 | $filetypearray = @() 148 | $filetypearray = $FileTypes -split ", " 149 | 150 | $validlinks = @() 151 | foreach ($filetype in $filetypearray) 152 | { 153 | 154 | #Performing a Google search first 155 | 156 | Write-Output "[*] Searching Google for 'site:$TargetDomain filetype:$filetype'" 157 | $googlesearch = "https://www.google.com/search?q=site:$TargetDomain+filetype:$filetype&num=100" 158 | $pagelinks = @() 159 | $pagelinks = (Invoke-WebRequest -Uri $googlesearch -UserAgent $UserAgent -UseBasicParsing).Links 160 | $hrefs = @() 161 | $hrefs = $pagelinks.href 162 | 163 | #Adding each valid url from page 1 to a list of valid links 164 | Write-Output "[*] Now Analyzing page 1 of Google search results (100 results per page)" 165 | foreach($url in $hrefs){ 166 | if (($url -like "*$TargetDomain*") -and ($url -like "*.$filetype*")) 167 | { 168 | if ($url -like "*http://*") 169 | { 170 | $strippedurl = [regex]::match($url,"http([^\)]+).$filetype").Value 171 | $validlinks += $strippedurl 172 | } 173 | elseif ($url -like "*https://*") 174 | { 175 | $strippedurl = [regex]::match($url,"https([^\)]+).$filetype").Value 176 | $validlinks += $strippedurl 177 | } 178 | } 179 | 180 | } 181 | #Determining if there are more than one page 182 | $otherpages = @() 183 | $otherpageslimit = @() 184 | foreach($url in $hrefs) 185 | { 186 | if ($url -like "*search?q*start=*") 187 | { 188 | $otherpages += "https://www.google.com$url" + "&num=100" 189 | } 190 | 191 | } 192 | 193 | $otherpages = $otherpages | sort | unique 194 | $pagecount = $otherpages.count 195 | if ($pagecount -gt $MaxSearchPages) 196 | { 197 | $totalpagelimit = $MaxSearchPages - 1 198 | for($j=0; $j -lt $totalpagelimit; $j++) 199 | { 200 | $otherpageslimit += $otherpages[$j] 201 | } 202 | } 203 | 204 | $otherpageslimit = $otherpageslimit -replace "&","&" 205 | $morepagelinks = @() 206 | $morehrefs = @() 207 | $i = 2 208 | #for each additional page in the Google search results find links 209 | foreach($page in $otherpageslimit) 210 | { 211 | Write-Output "[*] Now Analyzing page $i of Google search results (100 results per page)" 212 | $i++ 213 | $morepagelinks = (Invoke-WebRequest -Uri $page -UserAgent $UserAgent -UseBasicParsing).Links 214 | $morehrefs = $morepagelinks.href 215 | foreach($url in $morehrefs){ 216 | if (($url -like "*$TargetDomain*") -and ($url -like "*.$filetype*")) 217 | { 218 | if ($url -like "*http://*") 219 | { 220 | $strippedurl = [regex]::match($url,"http([^\)]+).$filetype").Value 221 | $validlinks += $strippedurl 222 | } 223 | elseif ($url -like "*https://*") 224 | { 225 | $strippedurl = [regex]::match($url,"https([^\)]+).$filetype").Value 226 | $validlinks += $strippedurl 227 | } 228 | } 229 | 230 | } 231 | } 232 | 233 | #Performing a Bing search second 234 | 235 | Write-Output "[*] Searching Bing for 'site:$TargetDomain filetype:$filetype'" 236 | $bingsearch = "http://www.bing.com/search?q=site:$TargetDomain%20filetype:$filetype&count=30" 237 | $bingpagelinks = @() 238 | $bingpagelinks = (Invoke-WebRequest -Uri $bingsearch -UserAgent $UserAgent -UseBasicParsing).Links 239 | $binghrefs = @() 240 | $binghrefs = $bingpagelinks.href 241 | 242 | #Adding each valid link from page 1 to an array 243 | Write-Output "[*] Now Analyzing page 1 of Bing search results (30 results per page)" 244 | foreach($url in $binghrefs){ 245 | if (($url -like "*$TargetDomain*") -and ($url -like "*.$filetype*")) 246 | { 247 | if ($url -like "*http://*") 248 | { 249 | $strippedurl = [regex]::match($url,"http([^\)]+).$filetype").Value 250 | $validlinks += $strippedurl 251 | } 252 | elseif ($url -like "*https://*") 253 | { 254 | $strippedurl = [regex]::match($url,"https([^\)]+).$filetype").Value 255 | $validlinks += $strippedurl 256 | } 257 | } 258 | } 259 | $bingotherpages = @() 260 | 261 | #Determining if there are more pages to search 262 | foreach($url in $binghrefs) 263 | { 264 | if ($url -like "*search?q*first=*") 265 | { 266 | $bingotherpages += "https://www.bing.com$url" + "&count=30" 267 | } 268 | 269 | } 270 | $bingotherpages = $bingotherpages | sort | unique 271 | $bingotherpages = $bingotherpages -replace "&","&" 272 | $morepagelinks = @() 273 | $morehrefs = @() 274 | $i = 2 275 | 276 | #for each additional page in the Bing search results find links 277 | foreach($page in $bingotherpages) 278 | { 279 | Write-Output "[*] Now Analyzing page $i of Bing search results (30 results per page)" 280 | $i++ 281 | $morepagelinks = (Invoke-WebRequest -Uri $page -UserAgent $UserAgent -UseBasicParsing).Links 282 | $morehrefs = $morepagelinks.href 283 | foreach($url in $morehrefs){ 284 | if (($url -like "*$TargetDomain*") -and ($url -like "*.$filetype*")) 285 | { 286 | if ($url -like "*http://*") 287 | { 288 | $strippedurl = [regex]::match($url,"http([^\)]+).$filetype").Value 289 | $validlinks += $strippedurl 290 | } 291 | elseif ($url -like "*https://*") 292 | { 293 | $strippedurl = [regex]::match($url,"https([^\)]+).$filetype").Value 294 | $validlinks += $strippedurl 295 | } 296 | } 297 | 298 | } 299 | } 300 | 301 | 302 | } 303 | 304 | $targetlinks = @() 305 | #getting rid of webcache links 306 | foreach ($link in $validlinks) 307 | { 308 | if ($link -notlike "*webcache.google*") 309 | { 310 | $targetlinks += $link 311 | } 312 | } 313 | $targetlinks = $targetlinks | sort | unique 314 | 315 | Write-Output ('[*] A total of ' + $targetlinks.count + ' files were discovered.') 316 | Write-Output "`n" 317 | 318 | #If an OutputList is specified write the results to disk 319 | If ($OutputList -ne "") 320 | { 321 | Write-Output "[*] Writing links to a file at $OutputList" 322 | $targetlinks | Out-File -Encoding ascii $OutputList 323 | } 324 | 325 | } 326 | #If a target list was specified let's use that. 327 | If ($TargetFileList -ne "") 328 | 329 | { 330 | $targetlinks = Get-Content $TargetFileList 331 | Write-Output "[*]Using the file list at $TargetFileList" 332 | Write-Output ('[*] A total of ' + $targetlinks.count + ' files were found.') 333 | } 334 | # If no output directory was named we will create one in with the current date/time. 335 | If($OutputDir -eq "") 336 | { 337 | $OutputDir = Get-Date -format yyyy-MM-dd-HHmmss 338 | } 339 | If ($Download) 340 | { 341 | Get-TargetFiles -targetlinks $targetlinks -OutputDir $OutputDir -UserAgent $UserAgent 342 | } 343 | elseif($Download -eq $false) 344 | { 345 | $title = "Download Files?" 346 | $message = "Would you like to download all of the files discovered?" 347 | 348 | $yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "Downloads all of the target files." 349 | $no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", "The files will not be downloaded." 350 | 351 | $options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no) 352 | 353 | $result = $host.ui.PromptForChoice($title, $message, $options, 0) 354 | 355 | switch ($result) 356 | { 357 | 0 { 358 | "[*] Now downloading the files." 359 | Get-TargetFiles -targetlinks $targetlinks -OutputDir $OutputDir -UserAgent $UserAgent 360 | } 361 | 1 {"[*] No files will be downloaded."} 362 | } 363 | 364 | } 365 | If ($Extract) 366 | { 367 | Write-Output "[*] Now extracting metadata from the files." 368 | If ($ExtractAllToCsv -ne "") 369 | { 370 | ExtractMetadata -OutputDir $OutputDir -ExtractAllToCsv $ExtractAllToCsv 371 | } 372 | else{ 373 | ExtractMetadata -OutputDir $OutputDir 374 | } 375 | } 376 | elseif($Extract -eq $false) 377 | { 378 | $title = "Extract Metadata?" 379 | $message = "Would you like to extract metadata from all of the files downloaded now?" 380 | 381 | $yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "Extracts metadata from downloaded files." 382 | $no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", "No metadata will be extracted at this time." 383 | 384 | $options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no) 385 | 386 | $result = $host.ui.PromptForChoice($title, $message, $options, 0) 387 | 388 | switch ($result) 389 | { 390 | 0 { 391 | Write-Output "[*] Now extracting metadata from the files." 392 | If ($ExtractAllToCsv) 393 | { 394 | ExtractMetadata -OutputDir $OutputDir -ExtractAllToCsv 395 | } 396 | else{ 397 | ExtractMetadata -OutputDir $OutputDir 398 | } 399 | } 400 | 1 {"[*] No metadata will be extracted at this time. If you wish to extract metadata later you can run the ExtractMetadata function on a directory of files like so: PS C:>ExtractMetadata -OutputDir `"C:\Users\username\directory-of-files\`""} 401 | } 402 | } 403 | } 404 | #Function to download files from a webserver 405 | Function Get-TargetFiles{ 406 | Param( 407 | 408 | [Parameter(Position = 0, Mandatory = $false)] 409 | [array] 410 | $targetlinks = "", 411 | 412 | [Parameter(Position = 1, Mandatory = $false)] 413 | [string] 414 | $OutputDir = "", 415 | 416 | [Parameter(Position = 2, Mandatory = $false)] 417 | [string] 418 | $UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko" 419 | 420 | ) 421 | 422 | Write-Output ('[*] Downloading ' + $targetlinks.count + ' files now.') 423 | 424 | 425 | # Testing to see if the output directory exists. If not, we'll create it. 426 | $TestOutputDir = Test-Path $OutputDir 427 | If($TestOutputDir -ne $True) 428 | { 429 | Write-Output "[*] The output directory $OutputDir does not exist. Creating directory $OutputDir." 430 | mkdir $OutputDir 431 | } 432 | 433 | # Getting the full path of the output dir. 434 | $OutputPath = Convert-Path $OutputDir 435 | #If the Download flag was set don't bother asking about downloading 436 | ## Choose to ignore any SSL Warning issues caused by Self Signed Certificates 437 | ## Code From http://poshcode.org/624 438 | 439 | ## Create a compilation environment 440 | $Provider=New-Object Microsoft.CSharp.CSharpCodeProvider 441 | $Compiler=$Provider.CreateCompiler() 442 | $Params=New-Object System.CodeDom.Compiler.CompilerParameters 443 | $Params.GenerateExecutable=$False 444 | $Params.GenerateInMemory=$True 445 | $Params.IncludeDebugInformation=$False 446 | $Params.ReferencedAssemblies.Add("System.DLL") > $null 447 | 448 | $TASource=@' 449 | namespace Local.ToolkitExtensions.Net.CertificatePolicy { 450 | public class TrustAll : System.Net.ICertificatePolicy { 451 | public TrustAll() { 452 | } 453 | public bool CheckValidationResult(System.Net.ServicePoint sp, 454 | System.Security.Cryptography.X509Certificates.X509Certificate cert, 455 | System.Net.WebRequest req, int problem) { 456 | return true; 457 | } 458 | } 459 | } 460 | '@ 461 | $TAResults=$Provider.CompileAssemblyFromSource($Params,$TASource) 462 | $TAAssembly=$TAResults.CompiledAssembly 463 | 464 | ## We now create an instance of the TrustAll and attach it to the ServicePointManager 465 | $TrustAll=$TAAssembly.CreateInstance("Local.ToolkitExtensions.Net.CertificatePolicy.TrustAll") 466 | [System.Net.ServicePointManager]::CertificatePolicy=$TrustAll 467 | 468 | ## end code from http://poshcode.org/624 469 | 470 | 471 | $k = 1 472 | foreach ($link in $targetlinks){ 473 | 474 | $filename = $link -replace "^.*\/" 475 | $testpath = ($OutputDir + "\" + $filename) 476 | if (!(Test-Path $testpath)) 477 | { 478 | Write-Output "Now Downloading $link" 479 | Invoke-WebRequest $link -UserAgent $UserAgent -UseBasicParsing -OutFile ($OutputPath + "\" + $(Split-Path $link -Leaf)) 480 | } 481 | Else{ 482 | #When downloading files if a file has the same name a number is prepended 483 | Write-Output "Now Downloading $link" 484 | Invoke-WebRequest $link -UserAgent $UserAgent -UseBasicParsing -OutFile ($OutputPath + "\" + $k + $(Split-Path $link -Leaf)) 485 | 486 | } 487 | $k++ 488 | } 489 | 490 | } 491 | 492 | #Use exiftool to extract metadata from each file 493 | Function ExtractMetadata{ 494 | Param( 495 | 496 | [Parameter(Position = 0, Mandatory = $false)] 497 | [string] 498 | $OutputDir = "", 499 | 500 | [Parameter(Position = 1, Mandatory = $false)] 501 | [string] 502 | $ExtractAllToCsv = "" 503 | ) 504 | #If "ExtractAllToCsv flag is set extract all metadata from files 505 | if ($ExtractAllToCsv -ne "") 506 | { 507 | $exifout = @() 508 | if (!(Test-Path $OutputDir)) 509 | { 510 | Write-Output "[*] $OutputDir does not exist! Canceling metadata extraction." 511 | break 512 | } 513 | else{ 514 | $OutputPath = Convert-Path $OutputDir 515 | Write-Output "[*] Now extracting metadata from $OutputDir" 516 | try{ 517 | $exiftool = Get-ChildItem "exiftool.exe" -ErrorAction Stop 518 | 519 | $exifpath = $exiftool.FullName | Out-String 520 | $exifpath = $exifpath -replace "`n" -replace "`r" 521 | $cmd = $exifpath + " " + $OutputPath + " -CSV > $ExtractAllToCsv" 522 | Invoke-Expression $cmd 523 | } 524 | catch 525 | { 526 | Write-Output "[*] Exiftool.exe was not found in the current directory! Exiting." 527 | } 528 | 529 | 530 | } 531 | } 532 | else{ 533 | #If we are not extracting all Metadata just get the Author and Creator for possible usernames. 534 | if (!(Test-Path $OutputDir)) 535 | { 536 | Write-Output "[*] $OutputDir does not exist! Canceling metadata extraction." 537 | break 538 | } 539 | else{ 540 | $OutputPath = Convert-Path $OutputDir 541 | $filearray = Get-ChildItem $OutputPath 542 | $output = @() 543 | try{ 544 | $exiftool = Get-ChildItem "exiftool.exe" -ErrorAction Stop 545 | $exifpath = $exiftool.FullName | Out-String 546 | $exifpath = $exifpath -replace "`n" -replace "`r" 547 | ForEach ($file in $filearray) { 548 | $filepath = $OutputPath + "\" + $file 549 | Write-Output "[*] Now extracting metadata from $filepath" 550 | 551 | 552 | $cmd = $exifpath + " " + $filepath + " -CSV -Author -Creator" 553 | $exifout = Invoke-Expression $cmd | Out-String 554 | $strippedout = $exifout -replace "SourceFile" -replace "Author" -replace "Creator" -replace "`n" -replace "`r" 555 | $modpath = $OutputPath -replace "\\", "\/" 556 | $output += $strippedout -replace "^.*$file," 557 | } 558 | $allmeta = @() 559 | $allmeta += $output -split "," 560 | $uniquemeta = $allmeta | sort | unique 561 | 562 | Write-Output "`n[*] Extracted 'Author' and 'Creator' metadata" 563 | $uniquemeta 564 | Write-Output "`n" 565 | } 566 | catch 567 | { 568 | Write-Output "[*] Exiftool.exe was not found in the current directory! Exiting." 569 | } 570 | 571 | } 572 | } 573 | } 574 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PowerMeta 2 | PowerMeta searches for publicly available files hosted on various websites for a particular domain by using specially crafted Google, and Bing searches. It then allows for the download of those files from the target domain. After retrieving the files, the metadata associated with them can be analyzed by PowerMeta. Some interesting things commonly found in metadata are usernames, domains, software titles, and computer names. 3 | 4 | ## Public File Discovery 5 | For many organizations it's common to find publicly available files posted on their external websites. Many times these files contain sensitive information that might be of benefit to an attacker like usernames, domains, software titles or computer names. PowerMeta searches both Bing and Google for files on a particular domain using search strings like "site:targetdomain.com filetype:pdf". By default it searches for "pdf, docx, xlsx, doc, xls, pptx, and ppt". 6 | 7 | ## Metadata Extraction 8 | PowerMeta uses Exiftool by Phil Harvey to extract metadata information from files. If you would prefer to download the binary from his site directly instead of using the one in this repo it can be found here: http://www.sno.phy.queensu.ca/~phil/exiftool/. Just make sure the exiftool executable is in the same directory as PowerMeta.ps1 when it is run. By default it just extracts the 'Author' and 'Creator' fields as these commonly have usernames saved. However all metadata for files can be extracted by passing PowerMeta the -ExtractAllToCsv flag. 9 | 10 | ## Requirements 11 | PowerShell version 3.0 or later 12 | 13 | ## Usage 14 | ### Import the Module 15 | ``` 16 | C:\> powershell.exe -exec bypass 17 | PS C:\> Import-Module PowerMeta.ps1 18 | ``` 19 | ### Basic Search 20 | This command will initiate Google and Bing searches for files on the 'targetdomain.com' domain ending with a file extension of pdf, docx, xlsx, doc, xls, pptx, or pptx. Once it has finished crafting this list it will prompt the user asking if they wish to download the files from the target domain. After downloading files it will prompt again for extraction of metadata from those files. 21 | ``` PowerShell 22 | PS C:\> Invoke-PowerMeta -TargetDomain targetdomain.com 23 | ``` 24 | ### Changing FileTypes and Automatic Download and Extract 25 | This command will initiate Google and Bing searches for files on the 'targetdomain.com' domain ending with a file extension of pdf, or xml. It will then automatically download them from the target domain and extract metadata. 26 | ``` PowerShell 27 | PS C:\> Invoke-PowerMeta -TargetDomain targetdomain.com -FileTypes "pdf, xml" -Download -Extract 28 | ``` 29 | ### Downloading Files From A List 30 | This command will initiate Google and Bing searches for files on the 'targetdomain.com' domain ending with a file extension of pdf, docx, xlsx, doc, xls, pptx, or pptx and write the links of files found to disk in a file called "target-domain-links.txt". 31 | ``` PowerShell 32 | PS C:\> Invoke-PowerMeta -TargetDomain targetdomain.com -TargetFileList target-domain-links.txt 33 | ``` 34 | ### Extract All Metadata and Limit Page Search 35 | This command will initiate Google and Bing searches for files on the 'targetdomain.com' domain ending with a file extension of pdf, docx, xlsx, doc, xls, pptx, or pptx but only search the first two pages. All metadata (not just the default fields) will be saved in a CSV called all-target-metadata.csv. 36 | ``` PowerShell 37 | PS C:\> Invoke-PowerMeta -TargetDomain targetdomain.com -MaxSearchPages 2 -ExtractAllToCsv all-target-metadata.csv 38 | ``` 39 | ### Extract Metadata From Files In A Directory 40 | This command will simply extract all the metadata from all the files in the folder "\2017-03-031-144953\" and save it in a CSV called all-target-metadata.csv 41 | ``` PowerShell 42 | PS C:\> ExtractMetadata -OutputDir .\2017-03-031-144953\ -ExtractAllToCsv all-target-metadata.csv 43 | ``` 44 | ## PowerMeta Options 45 | ``` 46 | TargetDomain - The target domain to search for files. 47 | FileTypes - A comma seperated list of file extensions to search for. By default PowerMeta searches for "pdf, docx, xlsx, doc, xls, pptx, ppt". 48 | OutputList - A file to output the list of links discovered through web searching to. 49 | OutputDir - A directory to store all downloaded files in. 50 | TargetFileList - List of file links to download. 51 | Download - Instead of being prompted interactively pass this flag to auto-download files found. 52 | Extract - Instead of being prompted interactively pass this flag to extract metadata from found files pass this flag to auto-extract any metadata. 53 | ExtractAllToCsv - All metadata (not just the default fields) will be extracted from files to a CSV specified with this flag. 54 | UserAgent - Change the default User Agent used by PowerMeta. 55 | MaxSearchPages - The maximum number of pages to search on each search engine. 56 | ``` 57 | -------------------------------------------------------------------------------- /exiftool.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dafthack/PowerMeta/17e963cfc62cc2aa8325c98b4ac47303d9edcffd/exiftool.exe --------------------------------------------------------------------------------