├── .gitignore ├── ADIDNSRecords_License_and_Copyright.txt ├── LICENSE ├── README.md ├── arp.cs ├── auditpol.cs ├── check_sig.cs ├── create_process.cs ├── driver_list.cs ├── dsquery.cs ├── dump_dns.cs ├── env.cs ├── eventlog.cs ├── farm_dns.cs ├── freespace.cs ├── get_chrome_tab_info.cs ├── get_hotfix.cs ├── icacls.cs ├── lld.cs ├── make.ps1 ├── netstat.cs ├── pagegrab.cs ├── readfile.cs ├── taskkill.cs ├── tasklist_svc.cs ├── tasklist_wmi.cs ├── test_ad_creds.cs ├── window_list.cs └── wmi_query.cs /.gitignore: -------------------------------------------------------------------------------- 1 | .vs/ 2 | bin/ -------------------------------------------------------------------------------- /ADIDNSRecords_License_and_Copyright.txt: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2019, dev2null 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SharpUtils 2 | 3 | A collection of C# utilities intended to be used with Cobalt Strike's execute-assembly. 4 | 5 | When feasible, I have tried to emulate native Windows output formats for matching commands to aid potential text parsing and reduce the learning curve for users familiar with Windows commands. One caveat to this is that the word "DONE" is printed at the end of every execution; this is to provide confirmation that the command completed successfully and all data was received. 6 | 7 | ## Compilation 8 | 9 | Open a PowerShell prompt and run the included `make.ps1` script. This will create a `bin\` directory containing the compiled executables; no fancy IDE required. 10 | 11 | Whenever possible, the oldest version of .NET is used for compatibility with older systems. 12 | 13 | I opted to use the C# Command-Line Compiler (csc.exe) instead of Visual Studio to lower the barrier to entry. That is, users should be able to simply clone the repo and build the utilities with little to no configuration, rather than having to download, install, and configure a full development suite. 14 | 15 | ## Credits 16 | 17 | Much of this code is derived from online examples. Where applicable, sources are listed as comments in the code. 18 | 19 | ## Utilities 20 | 21 | --- 22 | 23 | ### arp.exe 24 | 25 | Displays cached mappings between IP addresses and MAC addresses 26 | 27 | #### Usage 28 | 29 | ```powershell 30 | arp.exe [/?] 31 | ``` 32 | 33 | --- 34 | 35 | ### auditpol.exe 36 | 37 | Displays the computer's auditing policy (i.e., what actions will be logged) 38 | 39 | **Requires administrative privileges** 40 | 41 | #### Usage 42 | 43 | ```powershell 44 | auditpol.exe [/?] 45 | ``` 46 | 47 | --- 48 | 49 | ### check_sig.exe 50 | 51 | Checks whether an EXE/DLL is signed and, if so, validates the signature. 52 | 53 | #### Usage 54 | 55 | ```powershell 56 | check_sig.exe [/online] [...] [/?] 57 | ``` 58 | 59 | #### Examples 60 | 61 | ```text 62 | PS> .\check_sig_4.0.exe "C:\Program Files\Google\Chrome\Application\chrome.exe" "C:\Windows\System32\cmd.exe" 63 | [*] [CheckSign] Checking 2 files 64 | 65 | [*] [CheckSign] File 1: C:\Program Files\Google\Chrome\Application\chrome.exe 66 | [*] Digital signature found 67 | Publisher : CN=Google LLC, O=Google LLC, L=Mountain View, S=California, C=US 68 | Valid From : 7/1/2021 20:00:00 PM 69 | Valid To : 7/10/2024 19:59:59 PM 70 | Issued By : CN=DigiCert Trusted G4 Code Signing RSA4096 SHA384 2021 CA1, O="DigiCert, Inc.", C=US 71 | [+] Signature valid! 72 | 73 | [*] [CheckSign] File 2: C:\Windows\System32\cmd.exe 74 | [-] [CheckSign] No digital signature found! 75 | 76 | 77 | DONE 78 | ``` 79 | 80 | --- 81 | 82 | ### create_process.exe 83 | 84 | Uses WMI to execute a command on the specified remote host 85 | 86 | **Uses WMI** 87 | 88 | **Requires administrative privileges on the remote host** 89 | 90 | #### Usage 91 | 92 | ```powershell 93 | create_process.exe 94 | ``` 95 | 96 | --- 97 | 98 | ### dsquery.exe 99 | 100 | Queries directory services (e.g., Active Directory). Only complex queries (dsquery *) are supported at this time, and the `-filter` option is required. 101 | 102 | - Can provide a space-delimited list of attributes to return or `*` to get all attributes. If the `-attr` argument is omitted, it defaults to `-attr *` 103 | - Can optionally limit the number of results returned using `-limit #` 104 | - Can optionally query a specified server (-s) or domain (-d); if both are provided, it will default to the specified server 105 | - Outputs in native table format by default (unless `-attr *` is specified, in which case list format is used); list format can be specified using the `-l` option. A `-t` option prints in table format with ASCII borders around each cell. 106 | - Can optionally provide a username and password to use for the query (-u and -p, respectively) 107 | - Can optionally provide a start node such as a specific OU; forestroot and domainroot are NOT supported at this time 108 | - Can optionally provide an output filepath (`-o`) where the results will be written; the `-b` option allows users to specify a buffer size in MB for the file writer 109 | 110 | The number of results returned by the search will be printed at the top of the output; while this deviates from the native output format, it can be very useful to help gauge the size of your query. Similarly the `-c` (count only) option was included for this reason. 111 | 112 | This can be run **without administrative privileges from any system that can communicate with directory services on the intended target**. If run from a domain-joined host, it will automatically run against the current domain unless the `-s` or `-d` options are specified. If run from a host that is not joined to a domain, the `-s` or `-d` options must be specified. The `-u` and `-p` options may be required as well if not running with domain credentials (e.g., from a runas session). 113 | 114 | #### Usage 115 | 116 | ```powershell 117 | dsquery * [startNode] -filter [-attr ] [-limit ] [-c | -l | -t] [[-s ] | [-d ]] [-u ] [-p ] [-b ] [-o ] [/?] 118 | 119 | [startNode] Optional start node (e.g., specific OU; forestroot and domainroot 120 | are NOT supported at this time) 121 | -filter Standard dsquery filter string 122 | -attr Space-delimited list of attributes; use '*' to return all attributes 123 | If omitted, defaults to '-attr *' 124 | -limit Limits query to records 125 | -c Count only; prints the number of records returned by a search and exits 126 | -l Print in list format 127 | -t Print in table format with ASCII borders around each cell 128 | -s Query the specified server 129 | -d Query the specified domain 130 | -u Authenticate using the specified username 131 | -p Authenticate using the specified password 132 | -o Write output to the specified file; will not overwrite an existing file 133 | -b Write to output file in 'buffer_size' chunks (specified in MB) 134 | /? Prints help 135 | ``` 136 | 137 | --- 138 | 139 | ### driver_list.exe 140 | 141 | Displays info about installed drivers. Name and signer are displayed by default; normal verbose flag (`/V`) adds version number and DeviceID, and the very verbose flag (`/VV`) lists all driver properties. 142 | 143 | **Uses WMI** 144 | 145 | #### Usage 146 | 147 | ```powershell 148 | driver_list.exe [/V | /VV] [/?] 149 | ``` 150 | 151 | --- 152 | 153 | ### dump_dns.exe 154 | 155 | Uses Active Directory Search Interface (ADSI) to dump DNS data from Active Directory. If the DNS records cannot be parsed, it will fallback to performing DNS requests for individual hostnames. 156 | 157 | It can be run with no arguments from a domain-joined host with normal user credentials. If running from a non-domain-joined host, use the `/s` option to specify a server to query. The `/d` and `/f` options can be used to specify specific domains and forests to dump. 158 | 159 | Users can optionally specify an output file using `/o`; if omitted, output will be written to STDOUT. 160 | 161 | Since it queries Active Directory, it may need to be run using domain user credentials (non-privileged will suffice). If necessary and missing, a `[-] ERROR: The user name or password is incorrect.` message will be displayed. 162 | 163 | #### Usage 164 | 165 | ```powershell 166 | dump_dns.exe [/S ] [/D ] [/F ] [/T] [/O ] [/?] 167 | 168 | /T Optionally include tombstoned values 169 | ``` 170 | 171 | --- 172 | 173 | ### env.exe 174 | 175 | Displays environment variables (in alphabetical order) 176 | 177 | #### Usage 178 | 179 | ```powershell 180 | env.exe [/?] 181 | ``` 182 | 183 | --- 184 | 185 | ### eventlog.exe 186 | 187 | Reads events from the specified log file; optionally limit by EventID and number of events returned 188 | 189 | #### Usage 190 | 191 | ```powershell 192 | eventlog.exe [/C ] [/E ] [/?] 193 | ``` 194 | 195 | --- 196 | 197 | ### farm_dns.exe 198 | 199 | Performs reverse DNS lookups on the specified range of IP addresses (IPv4 only). Opted to remove the output file support from the original design because all data was written at the end; if a user choose to end the farming early all data would be lost. Writing to STDOUT in real-time allows a user to end the farming and resume later with the IP address where they left off without losing any data. 200 | 201 | #### Usage 202 | 203 | ```powershell 204 | farm_dns.exe [/T ] [/?] 205 | ``` 206 | 207 | --- 208 | 209 | ### freespace.exe 210 | 211 | Lists logical drives, including total and available free space. Mapped drives will only be shown when freespace.exe is run within the same session or with the same credentials used to map the drive. 212 | 213 | #### Usage 214 | 215 | ```powershell 216 | freespace.exe [/?] 217 | ``` 218 | 219 | --- 220 | 221 | ### get_chrome_tab_info.exe 222 | 223 | Displays the URL of the current tab and the titles of all tabs in foremost Chrome window. Will NOT display information about other Chrome windows. 224 | 225 | **Currently Broken** 226 | 227 | #### Usage 228 | 229 | ```powershell 230 | get_chrome_tab_info.exe [/?] 231 | ``` 232 | 233 | --- 234 | 235 | ### get_hotfix.exe 236 | 237 | Lists patches, optionally including verbose information such as Description, InstalledBy, and InstalledOn. 238 | 239 | #### Usage 240 | 241 | ```powershell 242 | get_hotfix.exe [/S ] [/U [\] /P ] [/V] [/?] 243 | ``` 244 | 245 | --- 246 | 247 | ### icacls.exe 248 | 249 | Displays permissions, grouped by user/group, for each file or directory specified 250 | 251 | #### Usage 252 | 253 | ```powershell 254 | icacls.exe [...] [/?] 255 | ``` 256 | 257 | --- 258 | 259 | ### lld.exe 260 | 261 | Lists logical drives (using WMI), including total and available free space. Mapped drives will only be shown when lld.exe is run within the same session or with the same credentials used to map the drive. This differs from freespace.exe because it can be used against a remote system. 262 | 263 | **Uses WMI** 264 | **Requires administrative privileges when used against a remote host** 265 | 266 | #### Usage 267 | 268 | ```powershell 269 | lld.exe [system] [/?] 270 | ``` 271 | 272 | --- 273 | 274 | ### netstat.exe 275 | 276 | Lists listening TCP and UDP ports, and active TCP connections (equivalent to `netstat -ano`); optionally writes output to a file. TCP or UDP can be specified to show only the matching data. 277 | 278 | **Uses WMI** 279 | 280 | #### Usage 281 | 282 | ```powershell 283 | netstat.exe [/S [/U [\] /P ]] [/O ] [TCP | UDP] [/?] 284 | ``` 285 | 286 | #### Examples 287 | 288 | ```powershell 289 | netstat.exe 290 | 291 | netstat.exe udp 292 | 293 | netstat.exe -S DC01.MGMT.LOCAL tcp 294 | 295 | netstat.exe -S DC01.MGMT.LOCAL -U MGMT\Administrator -P password 296 | ``` 297 | 298 | --- 299 | 300 | ### pagegrab.exe 301 | 302 | **NOTE: This will fail against any HTTPS site that does not support SSL 3.0 or TLS 1.0**; this is due to the ancient .NET versions it targets. For newer TLS versions, use [SharpPageGrab](https://github.com/breakid/SharpPageGrab) instead. 303 | 304 | Makes a web request; can be used to check external connectivity or get the content of an internal web page without going through the trouble of setting up a SOCKS proxy. 305 | 306 | Can optionally specify the HTTP method, POST request data (if applicable), a proxy server/port, and an arbitrary number of headers. 307 | 308 | Custom headers are supported; however, `Date`, `Host`, and `If-Modified-Since` are not. Headers are case sensitive and will be sent the way they are specified on the command-line. Headers must be specified in key-value pairs (header name, header value). If no `User-Agent` is specified, a hardcoded User-Agent string using the current version of Edge will be used; this is not perfect since the current version of Edge will not match the Chrome version, but it's probably better than sending no user-agent. 309 | 310 | The `Proxy` header will always show in the printed output; however, if the value is `None`, no `Proxy` header was sent as part of the request. 311 | 312 | The `-c` flag displays info about the SSL / TLS certificate. The `-v` flag causes the HTML contents of the page to be printed; if omitted, only the response headers will be shown. 313 | 314 | #### Usage 315 | 316 | ```powershell 317 | pagegrab.exe [-p http(s)://:] [-m ] [-d ] [-h [-h ]] [-c] [-v] [/?] 318 | -c Display the SSL / TLS certificate 319 | -v Print the HTML contents of the response 320 | ``` 321 | 322 | #### Examples 323 | 324 | ```text 325 | pagegrab.exe https://google.com -h User-Agent "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36 Edg/89.0.774.75" 326 | 327 | GET https://example.com 328 | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36 Edg/89.0.774.75 329 | ``` 330 | 331 | ```text 332 | pagegrab.exe https://example.com -h Referer https://www.google.com -h DNT 1 -h Cache-Control no-cache 333 | 334 | GET https://example.com 335 | Proxy: None 336 | Referer: https://www.google.com 337 | DNT: 1 338 | Cache-Control: no-cache 339 | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36 Edg/92.0.902.67 340 | ``` 341 | 342 | --- 343 | 344 | ### readfile.exe 345 | 346 | Read the contents of a file; optionally limit to `X` number of lines from the beginning of the file or `Y` number of lines from the end 347 | 348 | #### Usage 349 | 350 | ```powershell 351 | readfile.exe [+X] [-Y] [/?] 352 | ``` 353 | 354 | --- 355 | 356 | ### tasklist_svc.exe 357 | 358 | Lists processes, their PIDs, and their associated services (if applicable) 359 | 360 | **Uses WMI** 361 | 362 | #### Usage 363 | 364 | ```powershell 365 | tasklist_svc.exe [/?] 366 | ``` 367 | 368 | --- 369 | 370 | ### tasklist_wmi.exe 371 | 372 | List processes on local or remote system, optionally filter by ID, name, or WQL query. 373 | 374 | When using `/FI`, you must provide a Win32_Process-compatible WMI query language (WQL) condition string rather than a standard tasklist filter. You may use `%` as a wildcard 375 | 376 | Verbose mode (`/V`) will return the user name under which the process is running; however, this uses .NET reflection (InvokeMethod) which can be slow. 377 | 378 | **Uses WMI** 379 | **Uses .NET Reflection** 380 | **Requires administrative privileges if used against a remote host and for some local tasks (i.e., retrieving user context for processes owned by other users)** 381 | 382 | #### Usage 383 | 384 | ```powershell 385 | tasklist_wmi.exe [/S [/U [\] /P ]] [ [/PID | /IM | /FI <"WQL where clause">] ] [/V] [/D ""] [/?] 386 | ``` 387 | 388 | #### Examples 389 | 390 | ```powershell 391 | tasklist_wmi.exe /v 392 | 393 | tasklist_wmi.exe /S 192.168.20.10 /FI "Name Like 'cmd%'" 394 | 395 | tasklist_wmi.exe /S 192.168.20.10 /FI "CommandLine Like '%svchost%'" 396 | 397 | tasklist_wmi.exe /S 192.168.20.10 /U Desktop-624L8K3\Administrator /P password /FI "CommandLine Like '%svchost%'" 398 | ``` 399 | 400 | --- 401 | 402 | ### taskkill.exe 403 | 404 | Kills one or more processes by PID or imagename; multiple PIDs should be provided as a comma-separated list. Optionally, target a remote host and/or provide plaintext username and password from the command-line. 405 | 406 | **Uses WMI** 407 | **Requires administrative privileges if used against a remote host and for some local tasks (i.e., killing processes with a different owner)** 408 | 409 | #### Usage 410 | 411 | ```powershell 412 | taskkill.exe [/S [/U [\] /P ]] { [/PID | /IM ] } [/?] 413 | ``` 414 | 415 | #### Examples 416 | 417 | ```powershell 418 | taskkill.exe /PID 964 419 | 420 | taskkill.exe /PID 340,1432 421 | 422 | taskkill.exe /IM Calculator.exe 423 | 424 | taskkill.exe /IM Calculator.exe /S 192.168.2.14 425 | ``` 426 | 427 | --- 428 | 429 | ### test_ad_creds.exe 430 | 431 | Authenticates against the specified Active Directory (AD) domain using the provided username and password; indicates whether the credentials are valid or not. Can optionally specify a specific server with `/S`. Does not work with local credentials, only AD creds. 432 | 433 | **This WILL create a failed logon event if the credentials are not valid; use sparingly to avoid account lockout** 434 | 435 | #### Usage 436 | 437 | ```powershell 438 | test_ad_creds.exe [/S ] [/?] 439 | ``` 440 | 441 | --- 442 | 443 | ### window_list.exe 444 | 445 | Displays a list of visible windows and their associated process. 446 | 447 | **BETA: Has only been tested locally under Medium and High Integrity accounts. SYSTEM-level access *may* provide information from multiple sessions, and remote access *may* provide results (initial testing resulted in "Network path not found" errors)** 448 | 449 | #### Usage 450 | 451 | ```powershell 452 | window_list.exe [/S ] [/?] 453 | ``` 454 | 455 | --- 456 | 457 | ### wmi_query.exe 458 | 459 | Runs the specified WMI query and displays properties in key-value pairs. The query string must be in quotes. The default server is localhost, and the default namespace is `root\cimv2`. 460 | 461 | **Uses WMI** (...obviously) 462 | 463 | #### Usage 464 | 465 | ```powershell 466 | wmi_query.exe [/S [/U [\] /P ]] [-N ] [/O ] [/V] "" [/?] 467 | ``` 468 | 469 | #### Examples 470 | 471 | ```powershell 472 | wmi_query.exe "Select * from win32_process" 473 | 474 | wmi_query.exe -S DC01.MGMT.LOCAL -N root\standardcimv2 "Select * from MSFT_NetTCPConnection" 475 | 476 | wmi_query.exe -S DC01.MGMT.LOCAL -U MGMT\Administrator -P password -N root\standardcimv2 "Select * from MSFT_NetTCPConnection" 477 | ``` 478 | 479 | --- 480 | 481 | ## Other Resources 482 | 483 | Below is a list of other utilities that I have collected (though not personally tested) that may be of interest. 484 | 485 | - [Covenant](https://github.com/cobbr/Covenant "Covenant") - a collaborative .NET C2 framework for red teamers 486 | - [GhostPack](https://github.com/GhostPack "GhostPack") - a collection of security tools from Specter Ops 487 | - [SharpView](https://github.com/tevora-threat/SharpView "SharpView") - C# implementation of harmj0y's PowerView 488 | - [SharpSploit](https://github.com/cobbr/SharpSploit "SharpSploit") - a .NET post-exploitation library and spiritual successor to PowerSploit 489 | - [SharpHound](https://github.com/BloodHoundAD/SharpHound3 "SharpHound") - C# Data Collector for the BloodHound Project, Version 3 490 | - [SharpClipHistory](https://github.com/FSecureLABS/SharpClipHistory "SharpClipHistory") - a .NET application written in C# that can be used to read the contents of a user's clipboard history in Windows 10 491 | - [SharpGPOAbuse](https://github.com/FSecureLABS/SharpGPOAbuse "SharpGPOAbuse") - a .NET application written in C# that can be used to take advantage of a user's edit rights on a Group Policy Object (GPO) in order to compromise the objects that are controlled by that GPO. 492 | - [SharpGPO-RemoteAccessPolicies](https://github.com/FSecureLABS/SharpGPO-RemoteAccessPolicies "SharpGPO-RemoteAccessPolicies") - a C# tool for enumerating remote access policies through group policy 493 | - [SharpRDPCheck](https://github.com/3gstudent/SharpRDPCheck "SharpRDPCheck") and [SharpRDPUploader](https://github.com/RDPUploader/RDPUploader "SharpRDPUploader") - tools for exploiting RDP 494 | - [autorunner](https://github.com/woanware/autorunner "autorunner") - emulates the Sysinternals Autoruns tool, using C# / .NET 495 | - [taskscheduler](https://github.com/dahall/taskscheduler "taskscheduler") - provides a .NET wrapper for the Windows Task Scheduler 496 | - .NET Binary Obfuscator / Packer 497 | - [ConfuserEx](https://github.com/mkaring/ConfuserEx "ConfuserEx") 498 | - [neo-ConfuserEx](https://github.com/XenocodeRCE/neo-ConfuserEx "neo-ConfuserEx") 499 | 500 | --- 501 | 502 | ## Contributors 503 | 504 | Many thanks to my contributors! 505 | 506 | - [r00t0v3rr1d3](https://github.com/r00t0v3rr1d3) 507 | - [CyberThulhu22](https://github.com/CyberThulhu22) 508 | -------------------------------------------------------------------------------- /arp.cs: -------------------------------------------------------------------------------- 1 | // Source: https://stackoverflow.com/questions/1148778/how-do-i-access-arp-protocol-information-through-net 2 | // Modified to more closely match the formatting of native arp 3 | 4 | // To Compile: 5 | // C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:exe /out:arp.exe arp.cs 6 | 7 | 8 | using System; 9 | using System.Runtime.InteropServices; 10 | using System.ComponentModel; 11 | using System.Net; 12 | 13 | namespace Arp 14 | { 15 | class Program 16 | { 17 | // The max number of physical addresses. 18 | const int MAXLEN_PHYSADDR = 8; 19 | 20 | // Define the MIB_IPNETROW structure. 21 | [StructLayout(LayoutKind.Sequential)] 22 | struct MIB_IPNETROW 23 | { 24 | [MarshalAs(UnmanagedType.U4)] 25 | public int dwIndex; 26 | [MarshalAs(UnmanagedType.U4)] 27 | public int dwPhysAddrLen; 28 | [MarshalAs(UnmanagedType.U1)] 29 | public byte mac0; 30 | [MarshalAs(UnmanagedType.U1)] 31 | public byte mac1; 32 | [MarshalAs(UnmanagedType.U1)] 33 | public byte mac2; 34 | [MarshalAs(UnmanagedType.U1)] 35 | public byte mac3; 36 | [MarshalAs(UnmanagedType.U1)] 37 | public byte mac4; 38 | [MarshalAs(UnmanagedType.U1)] 39 | public byte mac5; 40 | [MarshalAs(UnmanagedType.U1)] 41 | public byte mac6; 42 | [MarshalAs(UnmanagedType.U1)] 43 | public byte mac7; 44 | [MarshalAs(UnmanagedType.U4)] 45 | public int dwAddr; 46 | [MarshalAs(UnmanagedType.U4)] 47 | public int dwType; 48 | } 49 | 50 | // Declare the GetIpNetTable function. 51 | [DllImport("IpHlpApi.dll")] 52 | [return: MarshalAs(UnmanagedType.U4)] 53 | static extern int GetIpNetTable( 54 | IntPtr pIpNetTable, 55 | [MarshalAs(UnmanagedType.U4)] 56 | ref int pdwSize, 57 | bool bOrder); 58 | 59 | [DllImport("IpHlpApi.dll", SetLastError = true, CharSet = CharSet.Auto)] 60 | internal static extern int FreeMibTable(IntPtr plpNetTable); 61 | 62 | // The insufficient buffer error. 63 | const int ERROR_INSUFFICIENT_BUFFER = 122; 64 | 65 | private static void PrintUsage() 66 | { 67 | Console.WriteLine(@"Dumps a mapping of IP to hardware (MAC) addresses from the Address Resolution Protocol (ARP) cache 68 | 69 | USAGE: 70 | arp.exe [/?]"); 71 | } 72 | 73 | static void Main(string[] args) 74 | { 75 | // The number of bytes needed. 76 | int bytesNeeded = 0; 77 | 78 | // The result from the API call. 79 | int result = GetIpNetTable(IntPtr.Zero, ref bytesNeeded, false); 80 | 81 | // Allocate the memory, do it in a try/finally block, to ensure 82 | // that it is released. 83 | IntPtr buffer = IntPtr.Zero; 84 | 85 | // Try/finally. 86 | try 87 | { 88 | // Parse arguments 89 | for (int i = 0; i < args.Length; i++) 90 | { 91 | string arg = args[i]; 92 | 93 | switch (arg.ToUpper()) 94 | { 95 | case "/?": 96 | PrintUsage(); 97 | return; 98 | } 99 | } 100 | 101 | // Call the function, expecting an insufficient buffer. 102 | if (result != ERROR_INSUFFICIENT_BUFFER) 103 | { 104 | // Throw an exception. 105 | throw new Win32Exception(result); 106 | } 107 | 108 | // Allocate the memory. 109 | buffer = Marshal.AllocCoTaskMem(bytesNeeded); 110 | 111 | // Make the call again. If it did not succeed, then 112 | // raise an error. 113 | result = GetIpNetTable(buffer, ref bytesNeeded, false); 114 | 115 | // If the result is not 0 (no error), then throw an exception. 116 | if (result != 0) 117 | { 118 | // Throw an exception. 119 | throw new Win32Exception(result); 120 | } 121 | 122 | // Now we have the buffer, we have to marshal it. We can read 123 | // the first 4 bytes to get the length of the buffer. 124 | int entries = Marshal.ReadInt32(buffer); 125 | 126 | // Increment the memory pointer by the size of the int. 127 | IntPtr currentBuffer = new IntPtr(buffer.ToInt64() + 128 | Marshal.SizeOf(typeof(int))); 129 | 130 | // Allocate an array of entries. 131 | MIB_IPNETROW[] table = new MIB_IPNETROW[entries]; 132 | 133 | // Cycle through the entries. 134 | for (int index = 0; index < entries; index++) 135 | { 136 | // Call PtrToStructure, getting the structure information. 137 | table[index] = (MIB_IPNETROW)Marshal.PtrToStructure(new 138 | IntPtr(currentBuffer.ToInt64() + (index * 139 | Marshal.SizeOf(typeof(MIB_IPNETROW)))), typeof(MIB_IPNETROW)); 140 | } 141 | 142 | Console.WriteLine("\n Internet Address Physical Address Type"); 143 | 144 | for (int index = 0; index < entries; index++) 145 | { 146 | MIB_IPNETROW row = table[index]; 147 | IPAddress ip = new IPAddress(BitConverter.GetBytes(row.dwAddr)); 148 | 149 | string[] mac_arr = { 150 | row.mac0.ToString("X2"), 151 | row.mac1.ToString("X2"), 152 | row.mac2.ToString("X2"), 153 | row.mac3.ToString("X2"), 154 | row.mac4.ToString("X2"), 155 | row.mac5.ToString("X2") 156 | }; 157 | 158 | string ip_str = String.Format("{0,-22}", ip.ToString()); 159 | string mac_str = String.Format("{0,-22}", string.Join("-", mac_arr)); 160 | string type = "static"; 161 | 162 | if (mac_str == "00-00-00-00-00-00 ") 163 | { 164 | continue; 165 | } 166 | 167 | if (row.dwType == 3) 168 | { 169 | type = "dynamic"; 170 | } 171 | 172 | Console.WriteLine(" " + ip_str + mac_str + type); 173 | } 174 | } 175 | catch (Exception e) 176 | { 177 | Console.Error.WriteLine("[-] ERROR: {0}", e.Message.Trim()); 178 | } 179 | finally 180 | { 181 | // Release the memory. 182 | FreeMibTable(buffer); 183 | Console.WriteLine("\nDONE"); 184 | } 185 | } 186 | } 187 | } -------------------------------------------------------------------------------- /auditpol.cs: -------------------------------------------------------------------------------- 1 | // Source: https://david-homer.blogspot.com/2016/08/document-windows-advanced-audit-policy.html 2 | 3 | // To Compile: 4 | // C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:exe /out:auditpol.exe auditpol.cs 5 | 6 | 7 | using System; 8 | using System.Collections.Specialized; 9 | using System.ComponentModel; 10 | using System.Runtime.InteropServices; 11 | using System.Text; 12 | 13 | /// 14 | /// Provides management functions of the advanced audit policy (audit policy subcategory settings). 15 | /// 16 | public class AdvancedAuditPolicyWrapper 17 | { 18 | private static void PrintUsage() 19 | { 20 | Console.WriteLine(@"Enumerates the audit policy configuration of the current host. Requires administrative privileges. 21 | 22 | USAGE: 23 | auditpol.exe [/?]"); 24 | } 25 | 26 | public static void Main(string[] args) 27 | { 28 | try 29 | { 30 | // Parse arguments 31 | for (int i = 0; i < args.Length; i++) 32 | { 33 | string arg = args[i]; 34 | 35 | switch (arg.ToUpper()) 36 | { 37 | case "/?": 38 | PrintUsage(); 39 | return; 40 | } 41 | } 42 | 43 | string auditInfo; 44 | 45 | Console.WriteLine("System audit policy"); 46 | Console.WriteLine("Category/Subcategory Setting"); 47 | 48 | foreach (string category_guid_str in GetCategoryIdentifiers()) 49 | { 50 | Console.WriteLine(GetCategoryDisplayName(category_guid_str)); 51 | 52 | foreach (string subcat_guid_str in GetSubCategoryIdentifiers(category_guid_str)) 53 | { 54 | Console.Write(" " + String.Format("{0,-40}", GetSubCategoryDisplayName(subcat_guid_str))); 55 | 56 | try 57 | { 58 | auditInfo = GetSystemPolicy(subcat_guid_str).AuditingInformation.ToString(); 59 | 60 | // Post-process to make the output match the native tool 61 | if (auditInfo == "None") 62 | { 63 | auditInfo = "No Auditing"; 64 | } 65 | 66 | auditInfo = auditInfo.Replace(", ", " and "); 67 | 68 | Console.WriteLine(auditInfo); 69 | } 70 | catch (Exception e) 71 | { 72 | Console.Error.WriteLine(e.Message.Trim()); 73 | } 74 | } 75 | } 76 | } 77 | catch (Exception e) 78 | { 79 | Console.Error.WriteLine(e.Message.Trim()); 80 | } 81 | finally 82 | { 83 | Console.WriteLine("\nDONE"); 84 | } 85 | } 86 | 87 | /// 88 | /// Initializes a new instance of the CENTREL.XIA.Management.AdvancedAuditPolicyWrapper class. 89 | /// 90 | public AdvancedAuditPolicyWrapper() 91 | { 92 | 93 | } 94 | 95 | 96 | /// 97 | /// The AuditEnumerateCategories function enumerates the available audit-policy categories. 98 | /// 99 | /// A pointer to a single buffer that contains both an array of pointers to GUID structures and the structures themselves. 100 | /// A pointer to the number of elements in the ppAuditCategoriesArray array. 101 | /// A System.Boolean value that indicates whether the function completed successfully. 102 | /// https://msdn.microsoft.com/en-us/library/windows/desktop/aa375636(v=vs.85).aspx 103 | [DllImport("advapi32.dll", SetLastError = true)] 104 | private static extern bool AuditEnumerateCategories(out IntPtr ppAuditCategoriesArray, out uint pCountReturned); 105 | 106 | 107 | /// 108 | /// The AuditLookupCategoryName function retrieves the display name of the specified audit-policy category. 109 | /// 110 | /// A pointer to a GUID structure that specifies an audit-policy category. 111 | /// The address of a pointer to a null-terminated string that contains the display name of the audit-policy category specified by the pAuditCategoryGuid function. 112 | /// A System.Boolean value that indicates whether the function completed successfully. 113 | /// https://msdn.microsoft.com/en-us/library/windows/desktop/aa375687(v=vs.85).aspx 114 | [DllImport("advapi32.dll", SetLastError = true)] 115 | private static extern bool AuditLookupCategoryName(ref Guid pAuditCategoryGuid, out StringBuilder ppszCategoryName); 116 | 117 | 118 | /// 119 | /// The AuditEnumerateSubCategories function enumerates the available audit-policy subcategories. 120 | /// 121 | /// The GUID of an audit-policy category for which subcategories are enumerated. If the value of the bRetrieveAllSubCategories parameter is TRUE, this parameter is ignored. 122 | /// TRUE to enumerate all audit-policy subcategories; FALSE to enumerate only the subcategories of the audit-policy category specified by the pAuditCategoryGuid parameter. 123 | /// A pointer to a single buffer that contains both an array of pointers to GUID structures and the structures themselves. The GUID structures specify the audit-policy subcategories available on the computer. 124 | /// A pointer to the number of audit-policy subcategories returned in the ppAuditSubCategoriesArray array. 125 | /// A System.Boolean value that indicates whether the function completed successfully. 126 | /// https://msdn.microsoft.com/en-us/library/windows/desktop/aa375648(v=vs.85).aspx 127 | [DllImport("advapi32.dll", SetLastError = true)] 128 | private static extern bool AuditEnumerateSubCategories(ref Guid pAuditCategoryGuid, bool bRetrieveAllSubCategories, out IntPtr ppAuditSubCategoriesArray, out uint pCountReturned); 129 | 130 | 131 | /// 132 | /// The AuditLookupSubCategoryName function retrieves the display name of the specified audit-policy subcategory. 133 | /// 134 | /// A pointer to a GUID structure that specifies an audit-policy subcategory. 135 | /// The address of a pointer to a null-terminated string that contains the display name of the audit-policy subcategory specified by the pAuditSubCategoryGuid parameter. 136 | /// A System.Boolean value that indicates whether the function completed successfully. 137 | /// https://msdn.microsoft.com/en-us/library/windows/desktop/aa375693(v=vs.85).aspx 138 | [DllImport("advapi32.dll", SetLastError = true)] 139 | private static extern bool AuditLookupSubCategoryName(ref Guid pAuditSubCategoryGuid, out StringBuilder ppszSubCategoryName); 140 | 141 | 142 | /// 143 | /// The AuditFree function frees the memory allocated by audit functions for the specified buffer. 144 | /// 145 | /// A pointer to the buffer to free. 146 | /// https://msdn.microsoft.com/en-us/library/windows/desktop/aa375654(v=vs.85).aspx 147 | [DllImport("advapi32.dll")] 148 | private static extern void AuditFree(IntPtr buffer); 149 | 150 | 151 | /// 152 | /// The AuditQuerySystemPolicy function retrieves system audit policy for one or more audit-policy subcategories. 153 | /// 154 | /// A pointer to an array of GUID values that specify the subcategories for which to query audit policy. 155 | /// The number of elements in each of the pSubCategoryGuids and ppAuditPolicy arrays. 156 | /// A pointer to a single buffer that contains both an array of pointers to AUDIT_POLICY_INFORMATION structures and the structures themselves. 157 | /// https://msdn.microsoft.com/en-us/library/windows/desktop/aa375702(v=vs.85).aspx 158 | [DllImport("advapi32.dll", SetLastError = true)] 159 | private static extern bool AuditQuerySystemPolicy(Guid pSubCategoryGuids, uint PolicyCount, out IntPtr ppAuditPolicy); 160 | 161 | 162 | /// 163 | /// Gets the GUIDs of the audit categories. 164 | /// 165 | /// The GUIDs of the audit categories on the local machine. 166 | private static StringCollection GetCategoryIdentifiers() 167 | { 168 | StringCollection identifiers = new StringCollection(); 169 | IntPtr buffer; 170 | uint categoryCount; 171 | bool success = AuditEnumerateCategories(out buffer, out categoryCount); 172 | if (!success) { throw new Win32Exception(Marshal.GetLastWin32Error()); } 173 | for (int i = 0, elemOffs = (int)buffer; i < categoryCount; i++) 174 | { 175 | Guid guid = (Guid)Marshal.PtrToStructure((IntPtr)elemOffs, typeof(Guid)); 176 | identifiers.Add(Convert.ToString(guid)); 177 | elemOffs += Marshal.SizeOf(typeof(Guid)); 178 | } 179 | AuditFree(buffer); 180 | return identifiers; 181 | } 182 | 183 | 184 | /// 185 | /// Returns the display name of the audit category with the specified GUID. 186 | /// 187 | /// The GUID of the category for which the display name should be returned. 188 | /// The display name of the category - for example "Account Management". 189 | private static String GetCategoryDisplayName(String guid) 190 | { 191 | return GetCategoryDisplayName(new Guid(guid)); 192 | } 193 | 194 | 195 | /// 196 | /// Returns the display name of the audit category with the specified GUID. 197 | /// 198 | /// The GUID of the category for which the display name should be returned. 199 | /// The display name of the category - for example "Account Management". 200 | private static String GetCategoryDisplayName(Guid guid) 201 | { 202 | StringBuilder buffer = new StringBuilder(); 203 | bool success = AuditLookupCategoryName(ref guid, out buffer); 204 | if (!success) { throw new Win32Exception(Marshal.GetLastWin32Error()); } 205 | if (buffer == null) 206 | { 207 | throw new ArgumentException(String.Format("Category Display Name Not Found for {0}", guid)); 208 | } 209 | String categoryDisplayName = buffer.ToString(); 210 | buffer = null; 211 | return categoryDisplayName; 212 | } 213 | 214 | 215 | /// 216 | /// Gets the GUIDs of the audit subcategories of the specified category. 217 | /// 218 | /// The GUID of the category for which the subcategories should be returned. 219 | /// The GUIDs of the audit subcategories for the specified category. 220 | private static StringCollection GetSubCategoryIdentifiers(String categoryGuid) 221 | { 222 | return GetSubCategoryIdentifiers(new Guid(categoryGuid)); 223 | } 224 | 225 | 226 | /// 227 | /// Gets the GUIDs of the audit subcategories of the specified category. 228 | /// 229 | /// The GUID of the category for which the subcategories should be returned. 230 | /// The GUIDs of the audit subcategories for the specified category. 231 | private static StringCollection GetSubCategoryIdentifiers(Guid categoryGuid) 232 | { 233 | StringCollection identifiers = new StringCollection(); 234 | IntPtr buffer; 235 | uint subCategoryCount; 236 | bool success = AuditEnumerateSubCategories(ref categoryGuid, false, out buffer, out subCategoryCount); 237 | if (!success) { throw new Win32Exception(Marshal.GetLastWin32Error()); } 238 | for (int i = 0, elemOffs = (int)buffer; i < subCategoryCount; i++) 239 | { 240 | Guid guid = (Guid)Marshal.PtrToStructure((IntPtr)elemOffs, typeof(Guid)); 241 | identifiers.Add(Convert.ToString(guid)); 242 | elemOffs += Marshal.SizeOf(typeof(Guid)); 243 | } 244 | AuditFree(buffer); 245 | return identifiers; 246 | } 247 | 248 | 249 | /// 250 | /// Returns the display name of the audit subcategory with the specified GUID. 251 | /// 252 | /// The GUID of the subcategory for which the display name should be returned. 253 | /// The display name of the subcategory - for example "Audit Credential Validation". 254 | private static String GetSubCategoryDisplayName(String guid) 255 | { 256 | return GetSubCategoryDisplayName(new Guid(guid)); 257 | } 258 | 259 | 260 | /// 261 | /// Returns the display name of the audit subcategory with the specified GUID. 262 | /// 263 | /// The GUID of the subcategory for which the display name should be returned. 264 | /// The display name of the subcategory - for example "Audit Credential Validation". 265 | private static String GetSubCategoryDisplayName(Guid guid) 266 | { 267 | StringBuilder buffer = new StringBuilder(); 268 | bool success = AuditLookupSubCategoryName(ref guid, out buffer); 269 | if (!success) { throw new Win32Exception(Marshal.GetLastWin32Error()); } 270 | String subCategoryDisplayName = buffer.ToString(); 271 | buffer = null; 272 | return subCategoryDisplayName; 273 | } 274 | 275 | 276 | /// 277 | /// Gets the audit policy configured for the specified subcategory GUID. 278 | /// 279 | /// The GUID of the subcategory for which the policy should be returned. 280 | /// Returns an AUDIT_POLICY_INFORMATION that contains information about the policy. 281 | private static AUDIT_POLICY_INFORMATION GetSystemPolicy(String subCategoryGuid) 282 | { 283 | return GetSystemPolicy(new Guid(subCategoryGuid)); 284 | } 285 | 286 | 287 | /// 288 | /// Gets the audit policy configured for the specified subcategory GUID. 289 | /// 290 | /// The GUID of the subcategory for which the policy should be returned. 291 | /// Returns an AUDIT_POLICY_INFORMATION that contains information about the policy. 292 | private static AUDIT_POLICY_INFORMATION GetSystemPolicy(Guid subCategoryGuid) 293 | { 294 | StringCollection identifiers = new StringCollection(); 295 | IntPtr buffer; 296 | bool success = AuditQuerySystemPolicy(subCategoryGuid, 1, out buffer); 297 | if (!success) { throw new Win32Exception(Marshal.GetLastWin32Error()); } 298 | AUDIT_POLICY_INFORMATION policyInformation = new AUDIT_POLICY_INFORMATION(); 299 | try 300 | { 301 | policyInformation = (AUDIT_POLICY_INFORMATION)Marshal.PtrToStructure(buffer, typeof(AUDIT_POLICY_INFORMATION)); 302 | AuditFree(buffer); 303 | } 304 | catch 305 | { 306 | throw new Exception("ERROR 5: Insufficient privileges"); 307 | } 308 | 309 | return policyInformation; 310 | } 311 | } 312 | 313 | 314 | 315 | /// 316 | /// The AUDIT_POLICY_INFORMATION structure specifies a security event type and when to audit that type. 317 | /// 318 | /// https://msdn.microsoft.com/en-us/library/windows/desktop/aa965467(v=vs.85).aspx 319 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 320 | public struct AUDIT_POLICY_INFORMATION 321 | { 322 | 323 | /// 324 | /// A GUID structure that specifies an audit subcategory. 325 | /// 326 | public Guid AuditSubCategoryGuid; 327 | 328 | /// 329 | /// A set of bit flags that specify the conditions under which the security event type specified by the AuditSubCategoryGuid and AuditCategoryGuid members are audited. 330 | /// 331 | public AUDIT_POLICY_INFORMATION_TYPE AuditingInformation; 332 | 333 | /// 334 | /// A GUID structure that specifies an audit-policy category. 335 | /// 336 | public Guid AuditCategoryGuid; 337 | 338 | } 339 | 340 | 341 | 342 | /// 343 | /// Represents the auditing type. 344 | /// 345 | [Flags] 346 | public enum AUDIT_POLICY_INFORMATION_TYPE 347 | { 348 | /// 349 | /// Do not audit the specified event type. 350 | /// 351 | None = 0, 352 | 353 | /// 354 | /// Audit successful occurrences of the specified event type. 355 | /// 356 | Success = 1, 357 | 358 | /// 359 | /// Audit failed attempts to cause the specified event type. 360 | /// 361 | Failure = 2, 362 | } -------------------------------------------------------------------------------- /check_sig.cs: -------------------------------------------------------------------------------- 1 | // To Compile: 2 | // C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:check_sig.exe check_sig.cs 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.IO; 7 | using System.Security.Cryptography; 8 | using System.Security.Cryptography.X509Certificates; 9 | 10 | internal class CheckSign 11 | { 12 | public static void PrintUsage() 13 | { 14 | Console.WriteLine(@"Checks whether an EXE/DLL is signed and, if so, validates the signature. 15 | 16 | USAGE: 17 | check_sig [/online] [...] [/?]"); 18 | } 19 | 20 | private static void Main(string[] args) 21 | { 22 | try 23 | { 24 | List filepaths = new List(); 25 | bool onlineCheck = false; 26 | 27 | // Parse arguments 28 | for (int i = 0; i < args.Length; i++) 29 | { 30 | string arg = args[i]; 31 | 32 | switch (arg.ToUpper()) 33 | { 34 | case "-ONLINE": 35 | case "/ONLINE": 36 | // Peform an online revocation list check 37 | onlineCheck = true; 38 | break; 39 | case "/?": 40 | // Print usage and exit 41 | PrintUsage(); 42 | return; 43 | default: 44 | filepaths.Add(arg); 45 | break; 46 | } 47 | } 48 | 49 | // Check whether filepath(s) specified 50 | if (filepaths.Count == 0) 51 | { 52 | Console.Error.WriteLine("[!] [CheckSign] ERROR: No file(s) specified"); 53 | return; 54 | } 55 | 56 | // List the number of filepaths parsed 57 | Console.WriteLine("[*] [CheckSign] Checking {0} file{1}{2}", filepaths.Count, (filepaths.Count > 1) ? "s" : "", Environment.NewLine); 58 | 59 | // Process each file 60 | int fileNum = 0; 61 | 62 | foreach (string filepath in filepaths) 63 | { 64 | Console.WriteLine("[*] [CheckSign] File {0}: {1}", ++fileNum, filepath); 65 | 66 | if (!File.Exists(filepath)) 67 | { 68 | Console.WriteLine(" [-] [CheckSign] ERROR: File not found ({0})", filepath); 69 | continue; 70 | } 71 | 72 | // Check for Signature 73 | X509Certificate2 cert; 74 | try 75 | { 76 | X509Certificate theSigner = X509Certificate.CreateFromSignedFile(filepath); 77 | cert = new X509Certificate2(theSigner); 78 | } 79 | catch (CryptographicException) 80 | { 81 | Console.WriteLine(" [-] [CheckSign] No digital signature found!\n"); 82 | continue; 83 | } 84 | catch (Exception e) 85 | { 86 | Console.Error.WriteLine(" [-] [CheckSign] ERROR: {0}\n", e.Message.Trim()); 87 | continue; 88 | } 89 | 90 | Console.WriteLine(" [*] Digital signature found"); 91 | 92 | // Signature was Found, Gathering Chain information (if available). 93 | // This will not reach out to the internet to verify validity, instead will check the local system. 94 | bool chainIsValid = false; 95 | var certChain = new X509Chain(); 96 | certChain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot; 97 | certChain.ChainPolicy.RevocationMode = (onlineCheck) ? X509RevocationMode.Online : X509RevocationMode.Offline; 98 | certChain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0); 99 | certChain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag; 100 | chainIsValid = certChain.Build(cert); 101 | 102 | Console.WriteLine(" Publisher : " + cert.SubjectName.Name); 103 | Console.WriteLine(" Valid From : " + cert.GetEffectiveDateString()); 104 | Console.WriteLine(" Valid To : " + cert.GetExpirationDateString()); 105 | Console.WriteLine(" Issued By : " + cert.Issuer); 106 | 107 | if (chainIsValid) 108 | { 109 | Console.WriteLine(" [+] Signature valid!"); 110 | } 111 | else 112 | { 113 | DateTime expirationDate = DateTime.Parse(cert.GetExpirationDateString()); 114 | 115 | if (DateTime.Today > expirationDate) 116 | { 117 | Console.WriteLine(" [-] Signature expired"); 118 | } 119 | else 120 | { 121 | Console.WriteLine(" [-] Chain invalid or unable to verify chain; certificate may be self-signed"); 122 | } 123 | } 124 | 125 | Console.WriteLine(); 126 | } 127 | } 128 | catch (Exception e) 129 | { 130 | Console.Error.WriteLine("[-] [CheckSign] ERROR: {0}", e.Message.Trim()); 131 | } 132 | finally 133 | { 134 | Console.WriteLine("\nDONE"); 135 | } 136 | } 137 | } -------------------------------------------------------------------------------- /create_process.cs: -------------------------------------------------------------------------------- 1 | // Source 2 | // - Slice - https://www.dotnetperls.com/array-slice 3 | 4 | // TODO 5 | // - Add username/password option like taskkill.cs 6 | // - Populate other fields to blend in better - https://docs.microsoft.com/en-us/dotnet/api/system.management.managementobject.invokemethod?view=netframework-4.7.2 7 | 8 | // To Compile: 9 | // C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:create_process.exe create_process.cs 10 | 11 | 12 | using System; 13 | using System.Management; 14 | 15 | public static class Extensions 16 | { 17 | /// 18 | /// Get the array slice between the two indexes. 19 | /// ... Inclusive for start index, exclusive for end index. 20 | /// 21 | public static T[] Slice(this T[] source, int start, int end) 22 | { 23 | // Handles negative ends. 24 | if (end < 0) 25 | { 26 | end = source.Length + end; 27 | } 28 | int len = end - start; 29 | 30 | // Return new array. 31 | T[] res = new T[len]; 32 | for (int i = 0; i < len; i++) 33 | { 34 | res[i] = source[i + start]; 35 | } 36 | return res; 37 | } 38 | } 39 | 40 | public class CreateProcess 41 | { 42 | private static void PrintUsage() 43 | { 44 | Console.WriteLine(@"Executes the given command on the specified system 45 | 46 | USAGE: 47 | CreateProcess.exe 48 | 49 | Example: 50 | CreateProcess.exe 192.168.20.10 C:\Windows\System32\program.exe -Run"); 51 | } 52 | 53 | public static void Main(string[] args) 54 | { 55 | try 56 | { 57 | // Parse arguments 58 | for (int i = 0; i < args.Length; i++) 59 | { 60 | string arg = args[i]; 61 | 62 | switch (arg.ToUpper()) 63 | { 64 | case "/?": 65 | PrintUsage(); 66 | return; 67 | } 68 | } 69 | 70 | if (args.Length == 0) 71 | { 72 | PrintUsage(); 73 | return; 74 | } 75 | else if (args.Length > 1) 76 | { 77 | // Parse target system from first arg; strip \\ just in case 78 | string system = args[0].Trim(new Char[] { ' ', '\\' }); 79 | 80 | // Catenate remaining args into a command string 81 | string command = String.Join(" ", args.Slice(1, args.Length)); 82 | 83 | Console.WriteLine("[*] Running '" + command + "' on " + system); 84 | 85 | ManagementClass processClass = new ManagementClass(@"\\" + system + @"\root\cimv2:Win32_Process"); 86 | 87 | // Execute the method 88 | ManagementBaseObject inParams = processClass.GetMethodParameters("Create"); 89 | inParams["CommandLine"] = command; 90 | ManagementBaseObject result = processClass.InvokeMethod("Create", inParams, null); 91 | 92 | // Display results 93 | if (result["returnValue"].ToString() == "0") 94 | { 95 | Console.WriteLine("Process ID: " + result["processId"]); 96 | } 97 | else 98 | { 99 | throw new Exception(String.Format("Failed to start process; exit code: {0}", result["returnValue"])); 100 | } 101 | } 102 | else 103 | { 104 | throw new ArgumentException("No command specified"); 105 | } 106 | } 107 | catch (Exception e) 108 | { 109 | Console.Error.WriteLine("[-] ERROR: {0}", e.Message.Trim()); 110 | } 111 | finally 112 | { 113 | Console.WriteLine("\nDONE"); 114 | } 115 | } 116 | } -------------------------------------------------------------------------------- /driver_list.cs: -------------------------------------------------------------------------------- 1 | // Source: https://social.msdn.microsoft.com/Forums/vstudio/en-US/9c28a7b0-9ee1-425e-8aa0-afeac329a983/list-of-installed-devices-and-drivers-using-cnet?forum=csharpgeneral 2 | 3 | // TODO - find a better way to approximate driveryquery /v (esp location of driver) 4 | 5 | // To Compile: 6 | // C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:driver_list.exe driver_list.cs 7 | 8 | 9 | using System; 10 | using System.Collections.Generic; 11 | using System.Management; 12 | 13 | namespace DriverList 14 | { 15 | public class Driver 16 | { 17 | public string ID; 18 | public string Name; 19 | public string Version; 20 | public string Signer; 21 | public Driver(string id, string name, string version, string signer) 22 | { 23 | ID = id; 24 | Name = name; 25 | Version = version; 26 | Signer = signer; 27 | 28 | if (Name == "" && ID != "") 29 | { 30 | Name = ID; 31 | } 32 | } 33 | } 34 | 35 | public class Program 36 | { 37 | private static void PrintUsage() 38 | { 39 | Console.WriteLine(@"Lists data about installed drivers 40 | 41 | USAGE: 42 | driver_list.exe [/V | /VV] [/?] 43 | 44 | /V Verbose; lists driver ID, name, version, and signer 45 | /VV Very verbose; dumps all driver data in list format 46 | /? Prints help"); 47 | } 48 | 49 | public static void Main(string[] args) 50 | { 51 | try 52 | { 53 | string id; 54 | string name; 55 | string version; 56 | string signer; 57 | int name_len = 0; 58 | int signer_len = 0; 59 | bool verbose = false; 60 | bool very_verbose = false; 61 | Driver d; 62 | List driver_list = new List(); 63 | 64 | // Parse arguments 65 | for (int i = 0; i < args.Length; i++) 66 | { 67 | string arg = args[i]; 68 | 69 | switch (arg.ToUpper()) 70 | { 71 | case "-V": 72 | case "/V": 73 | verbose = true; 74 | break; 75 | case "-VV": 76 | case "/VV": 77 | very_verbose = true; 78 | break; 79 | case "/?": 80 | PrintUsage(); 81 | return; 82 | } 83 | } 84 | 85 | string fields = (very_verbose) ? "*" : "DeviceID,DeviceName,DriverVersion,Signer"; 86 | string query = String.Format("SELECT {0} FROM Win32_PnPSignedDriver", fields); 87 | 88 | ManagementObjectSearcher searcher = new ManagementObjectSearcher(query); 89 | 90 | foreach (ManagementObject obj in searcher.Get()) 91 | { 92 | if (very_verbose) 93 | { 94 | foreach (PropertyData prop in obj.Properties) 95 | { 96 | Console.WriteLine("{0,-24}: {1}", prop.Name, prop.Value); 97 | } 98 | 99 | // Add a new line to separate property groups 100 | Console.WriteLine(""); 101 | } 102 | else 103 | { 104 | id = String.IsNullOrEmpty((string)obj.GetPropertyValue("DeviceID")) ? "" : obj.GetPropertyValue("DeviceID").ToString(); 105 | name = String.IsNullOrEmpty((string)obj.GetPropertyValue("DeviceName")) ? "" : obj.GetPropertyValue("DeviceName").ToString(); 106 | version = String.IsNullOrEmpty((string)obj.GetPropertyValue("DriverVersion")) ? "" : obj.GetPropertyValue("DriverVersion").ToString(); 107 | signer = String.IsNullOrEmpty((string)obj.GetPropertyValue("Signer")) ? "" : obj.GetPropertyValue("Signer").ToString(); 108 | 109 | d = new Driver(id, name, version, signer); 110 | driver_list.Add(d); 111 | 112 | name_len = (d.Name.Length > name_len) ? d.Name.Length : name_len; 113 | signer_len = (d.Signer.Length > signer_len) ? d.Signer.Length : signer_len; 114 | } 115 | } 116 | 117 | if (very_verbose) 118 | { 119 | return; 120 | } 121 | 122 | if (verbose) 123 | { 124 | foreach (Driver driver in driver_list) 125 | { 126 | Console.WriteLine("{0,-8}: {1}", "ID", driver.ID); 127 | Console.WriteLine("{0,-8}: {1}", "Name", driver.Name); 128 | Console.WriteLine("{0,-8}: {1}", "Version", driver.Version); 129 | Console.WriteLine("{0,-8}: {1}\n", "Signer", driver.Signer); 130 | } 131 | } 132 | else 133 | { 134 | // Use the max length of the driver name to dynamically size the table 135 | name_len += 4; 136 | signer_len += 4; 137 | string format_str = "{0,-" + name_len + "}{1}"; 138 | Console.WriteLine(format_str, "Name", "Signer"); 139 | Console.WriteLine(new String('-', name_len + signer_len)); 140 | 141 | foreach (Driver driver in driver_list) 142 | { 143 | Console.WriteLine(format_str, driver.Name, driver.Signer); 144 | } 145 | } 146 | } 147 | catch (Exception e) 148 | { 149 | Console.Error.WriteLine(e.Message.Trim()); 150 | } 151 | finally 152 | { 153 | Console.WriteLine("\nDONE"); 154 | } 155 | } 156 | } 157 | } -------------------------------------------------------------------------------- /dump_dns.cs: -------------------------------------------------------------------------------- 1 | // Source: https://github.com/dev-2null/ADIDNSRecords 2 | // Source: https://stackoverflow.com/questions/1315758/specify-which-dns-servers-to-use-to-resolve-hostnames-in-net 3 | 4 | /* 5 | * Original code based on https://github.com/dev-2null/ADIDNSRecords 6 | * - Modified to allow the DNS server to be manually specified (such as if 7 | * running from a non-domain joined system or a host in a different DNS domain) 8 | * - Original auto-detection code maintained as default if no server is specified 9 | * - Modified to allow queries against specific domains or forests (each can be specified independently) 10 | * - Improved the fallback DNS resolution to resolve against the explicitly set DNS server 11 | * - Since there is no native .Net function to resolve hostnames against a custom DNS server, used code from 12 | * https://stackoverflow.com/questions/1315758/specify-which-dns-servers-to-use-to-resolve-hostnames-in-net 13 | * to manually create a DNS request and send via a raw socket 14 | * - Added an option to write output to a file (writes to STDOUT by default) 15 | */ 16 | 17 | // To Compile: 18 | // C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:bin\dump_dns.exe dump_dns.cs 19 | 20 | 21 | using System; 22 | using System.Collections.Generic; 23 | using System.DirectoryServices; 24 | using System.IO; 25 | using System.Net; 26 | using System.Net.Sockets; 27 | using System.Text; 28 | 29 | namespace DumpDNS 30 | { 31 | public class DumpDNS 32 | { 33 | public static IPAddress dnsAddr; 34 | 35 | public static void PrintUsage() 36 | { 37 | Console.WriteLine(@"Dumps DNS zone data 38 | 39 | USAGE: 40 | dump_dns.exe [/S ] [/D ] [/F ] [/T] [/O ] 41 | 42 | /T Optionally include Tombstoned records"); 43 | } 44 | 45 | public static void Main(string[] args) 46 | { 47 | try 48 | { 49 | //domain dns Dn 50 | string dDnsDn = "DC=DomainDnsZones,"; 51 | 52 | //forest dns Dn 53 | string fDnsDn = "DC=ForestDnsZones,"; 54 | 55 | // DNS server to query 56 | string server = ""; 57 | 58 | // X.500 Distinguished Name of domain and forest 59 | string dDomain = ""; 60 | string dForest = ""; 61 | 62 | // Fully-qualified domain and forest DNS names 63 | string domainName = ""; 64 | string forestName = ""; 65 | 66 | // Whether or not Tombstoned records should be included 67 | bool includeTombstoned = false; 68 | 69 | // File path where output should be written (optional) 70 | string outputFilepath = ""; 71 | 72 | // Parse arguments 73 | for (int i = 0; i < args.Length; i++) 74 | { 75 | string arg = args[i]; 76 | 77 | switch (arg.ToUpper()) 78 | { 79 | case "-S": 80 | case "/S": 81 | i++; 82 | 83 | try 84 | { 85 | server = args[i]; 86 | VerifyDNSAddr(server); 87 | } 88 | catch (IndexOutOfRangeException) 89 | { 90 | throw new ArgumentException("No server not specified"); 91 | } 92 | break; 93 | case "-D": 94 | case "/D": 95 | i++; 96 | 97 | try 98 | { 99 | domainName = args[i]; 100 | dDomain = "DC=" + domainName.Replace(".", ",DC="); 101 | } 102 | catch (IndexOutOfRangeException) 103 | { 104 | throw new ArgumentException("No domain specified"); 105 | } 106 | break; 107 | case "-F": 108 | case "/F": 109 | i++; 110 | 111 | try 112 | { 113 | forestName = args[i]; 114 | dForest = "DC=" + forestName.Replace(".", ",DC="); 115 | } 116 | catch (IndexOutOfRangeException) 117 | { 118 | throw new ArgumentException("No forest specified"); 119 | } 120 | break; 121 | case "-T": 122 | case "/T": 123 | includeTombstoned = true; 124 | break; 125 | case "-O": 126 | case "/O": 127 | i++; 128 | 129 | try 130 | { 131 | outputFilepath = args[i]; 132 | 133 | if (File.Exists(outputFilepath)) 134 | { 135 | throw new Exception("Output file already exists"); 136 | } 137 | } 138 | catch (IndexOutOfRangeException) 139 | { 140 | throw new ArgumentException("No output file specified"); 141 | } 142 | 143 | break; 144 | case "/?": 145 | PrintUsage(); 146 | return; 147 | } 148 | } 149 | 150 | // Auto-detect domain and forest name if not provided 151 | if (domainName == "" && forestName == "") 152 | { 153 | Console.WriteLine("[*] Auto-detecting domain and forest"); 154 | 155 | try 156 | { 157 | DirectoryEntry rootEntry = null; 158 | 159 | if (server != "") 160 | { 161 | rootEntry = new DirectoryEntry("LDAP://" + server); 162 | rootEntry.AuthenticationType = AuthenticationTypes.None; 163 | } 164 | else 165 | { 166 | rootEntry = new DirectoryEntry("LDAP://rootDSE"); 167 | } 168 | 169 | if (rootEntry.Properties.Contains("defaultNamingContext") && rootEntry.Properties.Contains("rootDomainNamingContext")) 170 | { 171 | // Current domain DN 172 | dDomain = (string)rootEntry.Properties["defaultNamingContext"].Value; 173 | 174 | // Current forest DN 175 | dForest = (string)rootEntry.Properties["rootDomainNamingContext"].Value; 176 | } 177 | else 178 | { 179 | // Current domain DN 180 | dDomain = (string)rootEntry.Properties["distinguishedName"].Value; 181 | 182 | // Current forest DN 183 | dForest = (string)rootEntry.Properties["distinguishedName"].Value; 184 | } 185 | 186 | // Convert Distinguished Name to DNS name 187 | domainName = dDomain.Replace("DC=", "").Replace(",", "."); 188 | forestName = dForest.Replace("DC=", "").Replace(",", "."); 189 | } 190 | catch (Exception e) 191 | { 192 | throw new Exception("Auto-detection failed; please specify a domain and/or forest name"); 193 | } 194 | } 195 | 196 | string dDnsRoot = dDnsDn + dDomain; 197 | string fDnsRoot = fDnsDn + dForest; 198 | 199 | if (outputFilepath == "") 200 | { 201 | // Allow Domain and Forest zones to be queried independently 202 | if (domainName != "") 203 | { 204 | Console.WriteLine("\n[*] Domain: {0}", domainName); 205 | GetDNS(server, domainName, dDnsDn, dDnsRoot, includeTombstoned); 206 | } 207 | 208 | if (forestName != "") 209 | { 210 | Console.WriteLine("\n[*] Forest: {0}", forestName); 211 | GetDNS(server, forestName, fDnsDn, fDnsRoot, includeTombstoned); 212 | } 213 | } 214 | else 215 | { 216 | // If outputFilepath specified, redirect standard output from the console to the output file 217 | 218 | // Set the buffer to 2MB 219 | int buffer = 2 * 1024 * 1024; 220 | 221 | // Source: https://stackoverflow.com/questions/61074203/c-sharp-performance-comparison-async-vs-non-async-text-file-io-operation-via-r 222 | using (FileStream stream = new FileStream(outputFilepath, FileMode.Create, FileAccess.Write, FileShare.Read, buffer, FileOptions.SequentialScan)) 223 | { 224 | using (StreamWriter writer = new StreamWriter(stream, Encoding.UTF8)) 225 | { 226 | Console.SetOut(writer); 227 | 228 | // Allow Domain and Forest zones to be queried independently 229 | if (domainName != "") 230 | { 231 | Console.WriteLine("\n[*] Domain: {0}", domainName); 232 | GetDNS(server, domainName, dDnsDn, dDnsRoot, includeTombstoned); 233 | } 234 | 235 | if (forestName != "") 236 | { 237 | Console.WriteLine("\n[*] Forest: {0}", forestName); 238 | GetDNS(server, forestName, fDnsDn, fDnsRoot, includeTombstoned); 239 | } 240 | 241 | // Source: https://docs.microsoft.com/en-us/dotnet/api/system.console.error?view=net-5.0 242 | // Recover the standard output stream so that a completion message can be displayed. 243 | StreamWriter stdout = new StreamWriter(Console.OpenStandardOutput()); 244 | stdout.AutoFlush = true; 245 | Console.SetOut(stdout); 246 | } 247 | } 248 | } 249 | } 250 | catch (Exception e) 251 | { 252 | Console.Error.WriteLine("[-] ERROR: {0}", e.Message.Trim()); 253 | } 254 | finally 255 | { 256 | Console.WriteLine("\nDONE"); 257 | } 258 | } 259 | 260 | 261 | public static void VerifyDNSAddr(string server) 262 | { 263 | // Resolve DNS server if it's not already an IP address 264 | if (!IPAddress.TryParse(server, out dnsAddr)) 265 | { 266 | try 267 | { 268 | server = GetIP(server); 269 | } 270 | catch 271 | { 272 | // Suppress error message 273 | } 274 | 275 | if (!IPAddress.TryParse(server, out dnsAddr)) 276 | { 277 | throw new Exception(String.Format("DNS server ({0}) could not be resolved; please specify an IP address", server)); 278 | } 279 | } 280 | } 281 | 282 | 283 | // FQN : domain.local 284 | // dnsDn : DC=ForestDnsZones, 285 | // dnsRoot : DC=ForestDnsZones,DC=domain,DC=local 286 | // bool : true (include tombstoned records or not) 287 | public static void GetDNS(string server, string FQN, string dnsDn, string dnsRoot, bool includeTombstoned) 288 | { 289 | // If no server was explicitly specified, default to the domain or forest being queried 290 | // Resolve IP so you know specifically which server was queried 291 | if (server == "") 292 | { 293 | server = GetIP(FQN); 294 | } 295 | 296 | //Console.WriteLine("GetDNS('{0}', '{1}', '{2}', '{3}', '{4}')", server, FQN, dnsDn, dnsRoot, includeTombstoned); // DEBUG 297 | 298 | Dictionary hostList = new Dictionary(); 299 | List privhostList = new List(); 300 | string hostname = null; 301 | 302 | DirectoryEntry entry = new DirectoryEntry("LDAP://" + server + "/" + dnsRoot); 303 | 304 | // Find DNS Zones 305 | String queryZones = @"(&(objectClass=dnsZone)(!(DC=*arpa))(!(DC=RootDNSServers)))"; 306 | 307 | DirectorySearcher searchZones = new DirectorySearcher(entry, queryZones); 308 | 309 | searchZones.SearchScope = SearchScope.Subtree; 310 | 311 | foreach (SearchResult zone in searchZones.FindAll()) 312 | { 313 | Console.WriteLine("----------------------------------------------------------"); 314 | Console.WriteLine(" * Querying Server: {0}", server); 315 | Console.WriteLine(" * DNS Zone: {0}", zone.Properties["Name"][0]); 316 | Console.WriteLine("----------------------------------------------------------"); 317 | 318 | DirectoryEntry zoneEntry = new DirectoryEntry(zone.Path); 319 | 320 | // Exclude objects that have been removed 321 | String queryRecord = @"(&(objectClass=*)(!(DC=@))(!(DC=*DnsZones))(!(DC=*arpa))(!(DC=_*))(!dNSTombstoned=TRUE))"; 322 | 323 | if (includeTombstoned) 324 | { 325 | queryRecord = @"(&(objectClass=*)(!(DC=@))(!(DC=*DnsZones))(!(DC=*arpa))(!(DC=_*)))"; 326 | } 327 | 328 | DirectorySearcher searchRecord = new DirectorySearcher(zoneEntry, queryRecord); 329 | 330 | searchRecord.SearchScope = SearchScope.OneLevel; 331 | 332 | foreach (SearchResult record in searchRecord.FindAll()) 333 | { 334 | if (record.Properties.Contains("dnsRecord")) 335 | { 336 | if (record.Properties["dnsRecord"][0] is byte[]) 337 | { 338 | var dnsByte = ((byte[])record.Properties["dnsRecord"][0]); 339 | var key = record.Properties["DC"][0] + "." + FQN; 340 | 341 | // Resolve every record in case there are duplicate mappings 342 | ResolveDNSRecord(key, server, dnsByte); 343 | } 344 | } 345 | // No permission to view records 346 | else 347 | { 348 | string DN = ",CN=MicrosoftDNS," + dnsDn; 349 | int end = record.Path.IndexOf(DN); 350 | string ldapheader = "LDAP://" + server + "/"; 351 | 352 | hostname = record.Path.Substring(0, end).Replace(ldapheader, "").Replace("DC=", "").Replace(",", "."); 353 | 354 | // Eliminate unnecessary entries that sometimes appear 355 | if (hostname.StartsWith("DomainDnsZones") || hostname.StartsWith("ForestDnsZones")) 356 | { 357 | continue; 358 | } 359 | 360 | if (!privhostList.Contains(hostname)) 361 | { 362 | privhostList.Add(hostname); 363 | } 364 | } 365 | } 366 | } 367 | 368 | // Iterating each entry 369 | foreach (KeyValuePair host in hostList) 370 | { 371 | ResolveDNSRecord(host.Key, server, host.Value); 372 | } 373 | foreach (var host in privhostList) 374 | { 375 | PrintIP(host, server, includeTombstoned); 376 | } 377 | } 378 | 379 | 380 | // Retrieve IP from LDAP dnsRecord 381 | public static void ResolveDNSRecord(string hostname, string server, byte[] dnsByte) 382 | { 383 | var rdatatype = dnsByte[2]; 384 | string ip = null; 385 | 386 | if (rdatatype == 1) 387 | { 388 | ip = dnsByte[24] + "." + dnsByte[25] + "." + dnsByte[26] + "." + dnsByte[27]; 389 | } 390 | 391 | // If ip is still null, fall back to normal DNS resolution 392 | if (ip == null) 393 | { 394 | ip = GetIP(hostname, server); 395 | } 396 | 397 | Console.WriteLine(" {0,-40} {1,-40}", hostname, ip); 398 | } 399 | 400 | 401 | // Save formatted strings to output list 402 | public static void PrintIP(string hostname, string server, bool includeTombstoned) 403 | { 404 | try 405 | { 406 | string ip = GetIP(hostname, server); 407 | 408 | Console.WriteLine(" {0,-40} {1,-40}", hostname, ip); 409 | } 410 | catch (Exception) 411 | { 412 | if (includeTombstoned) 413 | { 414 | Console.WriteLine(" {0,-40} {1,-40}", hostname, "Tombstone"); 415 | } 416 | } 417 | } 418 | 419 | 420 | // Retrieve IP from DNS 421 | public static string GetIP(string hostname) 422 | { 423 | return Dns.GetHostEntry(hostname).AddressList[0].ToString(); 424 | } 425 | 426 | 427 | // Resolve IP using custom DNS server 428 | // Unfortunately there is no native way to do this in C# so get ready to handcraft a DNS request... 429 | public static string GetIP(string hostname, string server) 430 | { 431 | // Credit where credit is due 432 | // Source: https://stackoverflow.com/questions/1315758/specify-which-dns-servers-to-use-to-resolve-hostnames-in-net 433 | 434 | // Ensure dnsAddr is set if the server was auto-detected 435 | VerifyDNSAddr(server); 436 | 437 | List addresses = new List(); 438 | 439 | using (MemoryStream ms = new MemoryStream()) 440 | { 441 | Random rnd = new Random(); 442 | // About the dns message:http://www.ietf.org/rfc/rfc1035.txt 443 | 444 | // Write message header. 445 | ms.Write(new byte[] { 446 | (byte)rnd.Next(0, 0xFF),(byte)rnd.Next(0, 0xFF), 447 | 0x01, 448 | 0x00, 449 | 0x00,0x01, 450 | 0x00,0x00, 451 | 0x00,0x00, 452 | 0x00,0x00 453 | }, 0, 12); 454 | 455 | // Write the hostname to query. 456 | foreach (string block in hostname.Split('.')) 457 | { 458 | byte[] data = Encoding.UTF8.GetBytes(block); 459 | ms.WriteByte((byte)data.Length); 460 | ms.Write(data, 0, data.Length); 461 | } 462 | 463 | // The end of query, must end with 0(null string) 464 | ms.WriteByte(0); 465 | 466 | //Query type:A 467 | ms.WriteByte(0x00); 468 | ms.WriteByte(0x01); 469 | 470 | //Query class:IN 471 | ms.WriteByte(0x00); 472 | ms.WriteByte(0x01); 473 | 474 | Socket socket = new Socket(SocketType.Dgram, ProtocolType.Udp); 475 | try 476 | { 477 | // Send request to DNS server 478 | byte[] buffer = ms.ToArray(); 479 | while (socket.SendTo(buffer, 0, buffer.Length, SocketFlags.None, new IPEndPoint(dnsAddr, 53)) < buffer.Length) ; 480 | buffer = new byte[0x100]; 481 | EndPoint ep = socket.LocalEndPoint; 482 | 483 | // Receive response 484 | int num = socket.ReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref ep); 485 | 486 | // The response message has the same header and question structure, so we can move the index directly to the answer section 487 | int index = (int)ms.Length; 488 | int length; 489 | 490 | while (index < num) 491 | { 492 | // The name of the record is useless, so we just need to get the next index after name. 493 | while (index < num) 494 | { 495 | length = buffer[index++]; 496 | if (length == 0) 497 | { 498 | break; 499 | } 500 | else if (length > 191) 501 | { 502 | break; 503 | } 504 | index += length; 505 | } 506 | 507 | byte type = buffer[index += 2]; 508 | 509 | // Skip class and ttl 510 | index += 7; 511 | 512 | // Get record data's length 513 | length = buffer[index++] << 8 | buffer[index++]; 514 | 515 | if (type == 0x01) // A record 516 | { 517 | // Parse record data to IPv4 518 | if (length == 4) 519 | { 520 | addresses.Add(new IPAddress(new byte[] { buffer[index], buffer[index + 1], buffer[index + 2], buffer[index + 3] }).ToString()); 521 | } 522 | } 523 | 524 | index += length; 525 | } 526 | } 527 | finally 528 | { 529 | socket.Dispose(); 530 | } 531 | } 532 | 533 | return String.Join(", ", addresses); 534 | } 535 | } 536 | } -------------------------------------------------------------------------------- /env.cs: -------------------------------------------------------------------------------- 1 | // Source: https://docs.microsoft.com/en-us/dotnet/api/system.environment.getenvironmentvariables?view=netframework-4.8 2 | // Added sorting to match the output of the native Windows "set" 3 | 4 | // To Compile: 5 | // C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:exe /out:env.exe env.cs 6 | 7 | 8 | using System; 9 | using System.Collections; 10 | using System.Collections.Generic; 11 | 12 | class Env 13 | { 14 | public static void Main(string[] args) 15 | { 16 | try 17 | { 18 | if (args.Length > 0 && args[0] == "/?") 19 | { 20 | Console.WriteLine(@"Displays environment variables (in alphabetical order) 21 | 22 | USAGE: 23 | env.exe [/?]"); 24 | return; 25 | } 26 | 27 | SortedDictionary envVars = new SortedDictionary(); 28 | 29 | foreach (DictionaryEntry de in Environment.GetEnvironmentVariables()) 30 | { 31 | envVars.Add((string)de.Key, (string)de.Value); 32 | } 33 | 34 | foreach (KeyValuePair kvp in envVars) 35 | { 36 | Console.WriteLine("{0}={1}", kvp.Key, kvp.Value); 37 | } 38 | } 39 | catch (Exception e) 40 | { 41 | Console.Error.WriteLine("[-] ERROR: {0}", e.Message.Trim()); 42 | } 43 | finally 44 | { 45 | Console.WriteLine("\nDONE"); 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /eventlog.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * USAGE: eventlog.exe [-c ] [e ] 3 | * 4 | * Examples: 5 | * eventlog.exe Security -e 4624 -c 5 6 | * 7 | * eventlog.exe Security -e 4648 -c 3 8 | */ 9 | 10 | // To Compile: 11 | // C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:eventlog.exe eventlog.cs 12 | 13 | 14 | using System; 15 | using System.Linq; 16 | using System.Diagnostics; 17 | using System.Collections; 18 | using System.Collections.Generic; 19 | 20 | public class ReadEventLog 21 | { 22 | private static void PrintUsage() 23 | { 24 | Console.WriteLine(@"Reads events from the specified log file; optionally limit by EventID and number of events returned 25 | 26 | USAGE: 27 | eventlog.exe [/C ] [/E ] [/?] 28 | 29 | EXAMPLES: 30 | eventlog.exe Security -e 4624 -c 5 31 | - Displays the most recent 5 'Logon' events from the Security log 32 | 33 | eventlog.exe Security -e 4648 -c 3 34 | - Displays the most recent 3 'Logon with explicit credentials' events from the Security log"); 35 | } 36 | 37 | public static void Main(string[] args) 38 | { 39 | try 40 | { 41 | string eventLogName = ""; 42 | int count = 0; 43 | List eventIDs = new List(); 44 | bool test; 45 | 46 | // Parse arguments 47 | for (int i = 0; i < args.Length; i++) 48 | { 49 | string arg = args[i]; 50 | 51 | switch (arg.ToUpper()) 52 | { 53 | case "/C": // Count 54 | case "-C": 55 | i++; 56 | 57 | try 58 | { 59 | // Catch error while attempting to parse the count to prevent exception 60 | test = int.TryParse(args[i], out count); 61 | if (test == false || count < 1) 62 | { 63 | throw new ArgumentException("Invalid count"); 64 | } 65 | } 66 | catch (IndexOutOfRangeException) 67 | { 68 | throw new ArgumentException("No count specified"); 69 | } 70 | break; 71 | 72 | case "-E": // EventID(s) 73 | case "/E": 74 | i++; 75 | 76 | try 77 | { 78 | foreach (string eventIdStr in args[i].Split(',')) 79 | { 80 | long eventId; 81 | 82 | // Catch error while attempting to parse the count to prevent exception 83 | test = long.TryParse(eventIdStr, out eventId); 84 | if (test == false) 85 | { 86 | throw new ArgumentException("Invalid EventID(s)"); 87 | } 88 | 89 | eventIDs.Add(eventId); 90 | } 91 | } 92 | catch (IndexOutOfRangeException) 93 | { 94 | throw new ArgumentException("No EventID specified"); 95 | } 96 | break; 97 | case "/?": 98 | PrintUsage(); 99 | return; 100 | default: // eventLogName 101 | eventLogName = arg; 102 | break; 103 | } 104 | } 105 | 106 | if (eventLogName != "") 107 | { 108 | EventLog eventLog = new EventLog(); 109 | eventLog.Log = eventLogName; 110 | 111 | int numEntries = 0; 112 | 113 | // Loop through the events in reverse order to get the most recent first 114 | foreach (EventLogEntry log in eventLog.Entries.Cast().Reverse()) 115 | { 116 | // Print entries whose eventID matches one of the ones specified; limit to the last "count" entries 117 | if (eventIDs.Count == 0 || eventIDs.IndexOf(log.InstanceId) != -1) 118 | { 119 | Console.WriteLine("Timestamp: {0}", log.TimeGenerated); 120 | Console.WriteLine("EventID: {0}", log.InstanceId); 121 | Console.WriteLine("Computer: {0}", log.MachineName); 122 | Console.WriteLine("Username: {0}", log.UserName); 123 | Console.WriteLine("Message: {0}\n", log.Message); 124 | //Console.WriteLine("--------------------"); 125 | numEntries++; 126 | } 127 | 128 | // Stop when "count" entries have been printed 129 | if (count > 0 && numEntries == count) 130 | { 131 | break; 132 | } 133 | } 134 | } 135 | else 136 | { 137 | PrintUsage(); 138 | return; 139 | } 140 | } 141 | catch (Exception e) 142 | { 143 | Console.Error.WriteLine("[-] ERROR: {0}", e.Message.Trim()); 144 | } 145 | finally 146 | { 147 | Console.WriteLine("\nDONE"); 148 | } 149 | } 150 | } -------------------------------------------------------------------------------- /farm_dns.cs: -------------------------------------------------------------------------------- 1 | // Source: https://stackoverflow.com/questions/4172677/c-enumerate-ip-addresses-in-a-range/4172982 2 | // Source: https://docs.microsoft.com/en-us/dotnet/api/system.net.dns.gethostbyaddress 3 | 4 | 5 | // To Compile: 6 | // C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:farm_dns.exe farm_dns.cs 7 | 8 | 9 | using System; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | using System.IO; 13 | using System.Linq; 14 | using System.Net; 15 | 16 | /* ==================================================================================== 17 | C# IP address range finder helper class (C) Nahum Bazes 18 | * Free for private & commercial use - no restriction applied, please leave credits. 19 | * DO NOT REMOVE THIS COMMENT 20 | * ==================================================================================== */ 21 | 22 | 23 | public class Program 24 | { 25 | public static IEnumerable GetIPRange(IPAddress startIP, IPAddress endIP) 26 | { 27 | uint sIP = ipToUint(startIP.GetAddressBytes()); 28 | uint eIP = ipToUint(endIP.GetAddressBytes()); 29 | 30 | while (sIP <= eIP) 31 | { 32 | yield return new IPAddress(reverseBytesArray(sIP)).ToString(); 33 | sIP++; 34 | } 35 | } 36 | 37 | 38 | /* reverse byte order in array */ 39 | protected static uint reverseBytesArray(uint ip) 40 | { 41 | byte[] bytes = BitConverter.GetBytes(ip); 42 | bytes = bytes.Reverse().ToArray(); 43 | return (uint)BitConverter.ToInt32(bytes, 0); 44 | } 45 | 46 | 47 | /* Convert bytes array to 32 bit long value */ 48 | protected static uint ipToUint(byte[] ipBytes) 49 | { 50 | ByteConverter bConvert = new ByteConverter(); 51 | uint ipUint = 0; 52 | 53 | int shift = 24; // indicates number of bits left for shifting 54 | foreach (byte b in ipBytes) 55 | { 56 | if (ipUint == 0) 57 | { 58 | ipUint = (uint)bConvert.ConvertTo(b, typeof(uint)) << shift; 59 | shift -= 8; 60 | continue; 61 | } 62 | 63 | if (shift >= 8) 64 | ipUint += (uint)bConvert.ConvertTo(b, typeof(uint)) << shift; 65 | else 66 | ipUint += (uint)bConvert.ConvertTo(b, typeof(uint)); 67 | 68 | shift -= 8; 69 | } 70 | 71 | return ipUint; 72 | } 73 | 74 | 75 | public static IPAddress ParseIP(string ip) 76 | { 77 | try 78 | { 79 | return IPAddress.Parse(ip); 80 | } 81 | catch 82 | { 83 | throw new ArgumentException(String.Format("{0} is not a valid IP address", ip)); 84 | } 85 | } 86 | 87 | 88 | protected static void GetHostname(string ip) 89 | { 90 | Console.WriteLine(ip); 91 | 92 | try 93 | { 94 | IPAddress ipAddr = ParseIP(ip); 95 | IPHostEntry hostInfo = Dns.GetHostEntry(ipAddr); 96 | 97 | Console.WriteLine(" Hostname: {0}", hostInfo.HostName); 98 | 99 | // Get the IP address list that resolves to the host names contained in 100 | // the Alias property. 101 | IPAddress[] address = hostInfo.AddressList; 102 | 103 | // Get the alias names of the addresses in the IP address list. 104 | String[] aliases = hostInfo.Aliases; 105 | 106 | if (aliases.Length > 0) 107 | { 108 | Console.WriteLine(" Aliases:"); 109 | for (int index = 0; index < aliases.Length; index++) 110 | { 111 | Console.WriteLine(" {0}", aliases[index]); 112 | } 113 | } 114 | 115 | if (address.Length > 1) 116 | { 117 | Console.WriteLine("\n Other IPs:"); 118 | for (int index = 0; index < address.Length; index++) 119 | { 120 | Console.WriteLine(" {0}", address[index]); 121 | } 122 | } 123 | 124 | // Create a new line to separate IPs 125 | Console.WriteLine(""); 126 | } 127 | catch (Exception e) 128 | { 129 | Console.Error.WriteLine(" [-] ERROR: {0}", e.Message.Trim()); 130 | } 131 | } 132 | 133 | private static void PrintUsage() 134 | { 135 | Console.WriteLine(@"Performs reverse DNS lookups on the specified range of IP addresses (IPv4 only) 136 | 137 | USAGE: 138 | farm_dns.exe [/T ] [/?]"); 139 | } 140 | 141 | public static void Main(string[] args) 142 | { 143 | try 144 | { 145 | if (args.Length >= 2) 146 | { 147 | int throttle = 0; 148 | IPAddress start = null; 149 | IPAddress end = null; 150 | 151 | // Parse arguments 152 | for (int i = 0; i < args.Length; i++) 153 | { 154 | string arg = args[i]; 155 | 156 | switch (arg.ToUpper()) 157 | { 158 | case "-T": 159 | case "/T": 160 | i++; 161 | 162 | try 163 | { 164 | // Catch error while attempting to parse the throttle time to prevent exception 165 | if (int.TryParse(args[i], out throttle) == false) 166 | { 167 | throw new ArgumentException("Invalid throttle"); 168 | } 169 | } 170 | catch (IndexOutOfRangeException) 171 | { 172 | throw new ArgumentException("No throttle specified"); 173 | } 174 | break; 175 | case "/?": 176 | PrintUsage(); 177 | return; 178 | default: 179 | try 180 | { 181 | start = ParseIP(args[i++]); 182 | 183 | if (i < args.Length) 184 | { 185 | end = ParseIP(args[i]); 186 | } 187 | } 188 | catch (Exception e) 189 | { 190 | throw new ArgumentException("Invalid start or end value"); 191 | } 192 | break; 193 | } 194 | } 195 | 196 | if (start != null && end != null) 197 | { 198 | Console.WriteLine("[*] Farming IPs from: {0} to {1}", start, end); 199 | 200 | foreach (string ip in GetIPRange(start, end)) 201 | { 202 | GetHostname(ip); 203 | 204 | // Sleep for throttle seconds 205 | if (throttle > 0) 206 | { 207 | System.Threading.Thread.Sleep(throttle * 1000); 208 | } 209 | } 210 | } 211 | else 212 | { 213 | throw new Exception("Start and/or end address not specified"); 214 | } 215 | return; 216 | } 217 | 218 | PrintUsage(); 219 | } 220 | catch (Exception e) 221 | { 222 | Console.Error.WriteLine("[-] ERROR: {0}", e.Message.Trim()); 223 | } 224 | finally 225 | { 226 | Console.WriteLine("\nDONE"); 227 | } 228 | } 229 | } 230 | -------------------------------------------------------------------------------- /freespace.cs: -------------------------------------------------------------------------------- 1 | // Source: https://docs.microsoft.com/en-us/dotnet/api/system.io.driveinfo.availablefreespace 2 | 3 | // To Compile: 4 | // C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:exe /out:freespace.exe freespace.cs 5 | 6 | 7 | using System; 8 | using System.IO; 9 | 10 | class FreeSpace 11 | { 12 | public static void Main(string[] args) 13 | { 14 | try 15 | { 16 | if (args.Length > 0 && args[0] == "/?") 17 | { 18 | Console.WriteLine(@"Lists logical drives, including total and available free space. Mapped drives will only be shown when freespace.exe is run within the same session or with the same credentials used to map the drive. 19 | 20 | USAGE: 21 | freespace.exe [/?]"); 22 | return; 23 | } 24 | 25 | DriveInfo[] allDrives = DriveInfo.GetDrives(); 26 | 27 | foreach (DriveInfo d in allDrives) 28 | { 29 | Console.WriteLine("\nDrive {0}", d.Name); 30 | Console.WriteLine(" Drive type: {0}", d.DriveType); 31 | if (d.IsReady == true) 32 | { 33 | Console.WriteLine(" Volume label: {0}", d.VolumeLabel); 34 | Console.WriteLine(" File system: {0}", d.DriveFormat); 35 | Console.WriteLine( 36 | " Available space to current user:{0, 22} bytes", 37 | String.Format("{0:n0}", d.AvailableFreeSpace)); 38 | 39 | Console.WriteLine( 40 | " Total available space: {0, 22} bytes", 41 | String.Format("{0:n0}", d.TotalFreeSpace)); 42 | 43 | Console.WriteLine( 44 | " Total size of drive: {0, 22} bytes ", 45 | String.Format("{0:n0}", d.TotalSize)); 46 | } 47 | } 48 | } 49 | catch (Exception e) 50 | { 51 | Console.Error.WriteLine("[-] ERROR: {0}", e.Message.Trim()); 52 | } 53 | finally 54 | { 55 | Console.WriteLine("\nDONE"); 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /get_chrome_tab_info.cs: -------------------------------------------------------------------------------- 1 | // Sources: 2 | // https://stackoverflow.com/questions/40070703/how-to-get-a-list-of-open-tabs-from-chrome-c-sharp 3 | // https://stackoverflow.com/questions/18897070/getting-the-current-tabs-url-from-google-chrome-using-c-sharp/ 4 | // https://social.msdn.microsoft.com/Forums/en-US/27236bd4-9c75-494b-b5e3-d3d52f660619/how-to-get-the-urls-of-all-tabs-in-a-chrome-browser?forum=csharpgeneral 5 | 6 | // To Compile: 7 | // C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /reference:"C:\Windows\Microsoft.NET\assembly\GAC_MSIL\UIAutomationTypes\v4.0_4.0.0.0__31bf3856ad364e35\UIAutomationTypes.dll" /reference:"C:\Windows\Microsoft.NET\assembly\GAC_MSIL\UIAutomationClient\v4.0_4.0.0.0__31bf3856ad364e35\UIAutomationClient.dll" /t:exe /out:get_chrome_tab_info.exe get_chrome_tab_info.cs 8 | 9 | 10 | using System; 11 | using System.Diagnostics; 12 | using System.Text.RegularExpressions; 13 | using System.Windows.Automation; 14 | 15 | class EnumChromeTabs 16 | { 17 | private static void PrintUsage() 18 | { 19 | Console.WriteLine(@"Displays the URL of the current tab and the titles of all tabs in foremost Chrome window. Will NOT display information about other Chrome windows. 20 | 21 | USAGE: 22 | get_chrome_tab_info.exe [/?]"); 23 | } 24 | 25 | public static void Main(string[] args) 26 | { 27 | try 28 | { 29 | // Parse arguments 30 | for (int i = 0; i < args.Length; i++) 31 | { 32 | string arg = args[i]; 33 | 34 | switch (arg.ToUpper()) 35 | { 36 | case "/?": // Help 37 | PrintUsage(); 38 | return; 39 | default: 40 | break; 41 | } 42 | } 43 | 44 | // there are always multiple chrome processes, so we have to loop through all of them to find the 45 | // process with a Window Handle and an automation element of name "Address and search bar" 46 | Process[] procsChrome = Process.GetProcessesByName("chrome"); 47 | 48 | if (procsChrome.Length <= 0) 49 | { 50 | Console.WriteLine("Chrome is not running"); 51 | } 52 | else 53 | { 54 | foreach (Process proc in procsChrome) 55 | { 56 | // the chrome process must have a window 57 | if (proc.MainWindowHandle == IntPtr.Zero) 58 | { 59 | continue; 60 | } 61 | 62 | try 63 | { 64 | Console.WriteLine("Process ID: " + proc.Id); 65 | Console.WriteLine("Session ID: " + proc.SessionId); 66 | 67 | // Get the main window 68 | AutomationElement root = AutomationElement.FromHandle(proc.MainWindowHandle); 69 | 70 | // Find the address bar and display the URL 71 | AutomationElement elmUrlBar = root.FindFirst(TreeScope.Descendants, 72 | new PropertyCondition(AutomationElement.NameProperty, "Address and search bar")); 73 | 74 | // if it can be found, get the value from the URL bar 75 | if (elmUrlBar != null) 76 | { 77 | AutomationPattern[] patterns = elmUrlBar.GetSupportedPatterns(); 78 | if (patterns.Length > 0) 79 | { 80 | ValuePattern val = (ValuePattern)elmUrlBar.GetCurrentPattern(patterns[0]); 81 | Console.WriteLine("Current URL: " + val.Current.Value); 82 | } 83 | } 84 | 85 | // to find the tabs we first need to locate something reliable - the 'New Tab' button 86 | AutomationElement elmNewTab = root.FindFirst(TreeScope.Descendants, 87 | new PropertyCondition(AutomationElement.NameProperty, "New Tab")); 88 | 89 | // get the tabstrip by getting the parent of the 'new tab' button 90 | TreeWalker treewalker = TreeWalker.ControlViewWalker; 91 | AutomationElement elmTabStrip = treewalker.GetParent(elmNewTab); 92 | 93 | // loop through all the tabs and get the names which is the page title 94 | Condition condTabItem = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.TabItem); 95 | 96 | Console.WriteLine("Tabs:"); 97 | 98 | foreach (AutomationElement tabitem in elmTabStrip.FindAll(TreeScope.Children, condTabItem)) 99 | { 100 | Console.WriteLine(" " + tabitem.Current.Name); 101 | } 102 | } 103 | catch 104 | { 105 | Console.WriteLine("Chrome is minimized"); 106 | } 107 | } 108 | } 109 | } 110 | catch (Exception e) 111 | { 112 | Console.Error.WriteLine("[-] ERROR: {0}", e.Message.Trim()); 113 | } 114 | finally 115 | { 116 | Console.WriteLine("\nDONE"); 117 | } 118 | } 119 | } -------------------------------------------------------------------------------- /get_hotfix.cs: -------------------------------------------------------------------------------- 1 | // To Compile: 2 | // C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:get_hotfix.exe get_hotfix.cs 3 | 4 | 5 | using System; 6 | using System.Management; 7 | 8 | class GetHotFix 9 | { 10 | public static int PrintUsage() 11 | { 12 | Console.WriteLine(@"List all patches on a system 13 | 14 | USAGE: 15 | get-hotfix [/S system] [/U [domain\]username /P password] [/V] [/?] 16 | 17 | /V Print additional information (Description, InstalledBy, InstalledOn) 18 | "); 19 | return 0; 20 | } 21 | 22 | public static int Main(string[] args) 23 | { 24 | string system = "."; 25 | string username = ""; 26 | string password = ""; 27 | bool verbose_set = false; 28 | 29 | try 30 | { 31 | // Parse arguments 32 | for (int i = 0; i < args.Length; i++) 33 | { 34 | string arg = args[i]; 35 | 36 | switch (arg.ToUpper()) 37 | { 38 | case "-S": 39 | case "/S": 40 | i++; 41 | try 42 | { 43 | system = args[i].Trim(new Char[] { '\\', ' ' }); 44 | } 45 | catch (IndexOutOfRangeException) 46 | { 47 | throw new ArgumentException("No system specified"); 48 | } 49 | break; 50 | case "-U": 51 | case "/U": 52 | i++; 53 | try 54 | { 55 | username = args[i]; 56 | } 57 | catch (IndexOutOfRangeException) 58 | { 59 | throw new ArgumentException("No username specified"); 60 | } 61 | 62 | break; 63 | case "-P": 64 | case "/P": 65 | i++; 66 | try 67 | { 68 | password = args[i]; 69 | } 70 | catch (IndexOutOfRangeException) 71 | { 72 | throw new ArgumentException("No password specified"); 73 | } 74 | break; 75 | case "-V": 76 | case "/V": 77 | verbose_set = true; 78 | break; 79 | case "/?": 80 | default: 81 | return PrintUsage(); 82 | } 83 | } 84 | 85 | ConnectionOptions conn_opts = new ConnectionOptions(); 86 | 87 | // Apply username and password if specified 88 | if (username.Length > 0 && password.Length > 0) 89 | { 90 | conn_opts.Username = username; 91 | conn_opts.Password = password; 92 | } 93 | else if (username.Length > 0 || password.Length > 0) 94 | { 95 | // Error out if username or password were specified, but not both 96 | throw new ArgumentException("Please specify username and password"); 97 | } 98 | 99 | ManagementScope scope = new ManagementScope("\\\\" + system + "\\root\\cimv2", conn_opts); 100 | 101 | string[] selectedProperties; 102 | 103 | if (verbose_set) 104 | { 105 | selectedProperties = new string[] { "HotFixID", "Description", "InstalledBy", "InstalledOn" }; 106 | } 107 | else 108 | { 109 | selectedProperties = new string[] { "HotFixID" }; 110 | } 111 | 112 | SelectQuery query = new SelectQuery("Win32_QuickFixEngineering", null, selectedProperties); 113 | 114 | // Execute query within scope and iterate through results 115 | using (var searcher = new ManagementObjectSearcher(scope, query)) 116 | { 117 | string line = "\n"; 118 | 119 | // Print a column header for each property 120 | foreach (string prop in selectedProperties) 121 | { 122 | line += prop.PadRight(22, ' '); 123 | } 124 | 125 | Console.WriteLine(line); 126 | 127 | line = ""; 128 | 129 | // Dynamically generate underlines based on the list of properties 130 | foreach (string prop in selectedProperties) 131 | { 132 | line += new String('-', prop.Length).PadRight(22, ' '); 133 | } 134 | 135 | Console.WriteLine(line); 136 | 137 | // Print the hotfix info 138 | foreach (ManagementObject proc in searcher.Get()) 139 | { 140 | if (proc != null) 141 | { 142 | line = ""; 143 | 144 | foreach (string prop in selectedProperties) 145 | { 146 | string val = proc.GetPropertyValue(prop).ToString(); 147 | 148 | if (val != null) 149 | { 150 | line += val.PadRight(22, ' '); 151 | } 152 | } 153 | Console.WriteLine(line); 154 | } 155 | } 156 | } 157 | 158 | return 0; 159 | } 160 | catch (Exception e) 161 | { 162 | Console.Error.WriteLine("ERROR: {0}", e.Message.Trim()); 163 | return 1; 164 | } 165 | finally 166 | { 167 | Console.WriteLine("\nDONE"); 168 | } 169 | } 170 | } -------------------------------------------------------------------------------- /icacls.cs: -------------------------------------------------------------------------------- 1 | // Derived from: https://stackoverflow.com/questions/3507862/duplicate-getaccessrules-filesystemaccessrule-entries 2 | 3 | // To Compile: 4 | // C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:exe /out:icacls.exe icacls.cs 5 | 6 | using System; 7 | using System.IO; 8 | using System.Security.AccessControl; 9 | 10 | 11 | namespace icacls 12 | { 13 | class Program 14 | { 15 | public static void Main(string[] args) 16 | { 17 | try 18 | { 19 | if (args.Length == 0 || (args.Length > 0 && args[0] == "/?")) 20 | { 21 | Console.WriteLine(@"Displays permissions, grouped by user/group, for each file or directory specified 22 | 23 | USAGE: 24 | icacls.exe [...] [/?] 25 | 26 | Example: 27 | icacls.exe passwords.txt users.txt"); 28 | } 29 | else 30 | { 31 | int i = 0; 32 | 33 | foreach (string path in args) 34 | { 35 | Console.WriteLine("Permissions for: " + path); 36 | 37 | FileSecurity fSecurity = new FileSecurity(path, AccessControlSections.Access); 38 | 39 | foreach (FileSystemAccessRule fsar in fSecurity.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount))) 40 | { 41 | Console.WriteLine(" {0}", fsar.IdentityReference.Value); 42 | Console.WriteLine(" Type: {0}", fsar.AccessControlType); 43 | Console.WriteLine(" Rights: {0}", fsar.FileSystemRights); 44 | Console.WriteLine(" Source: {0}", fsar.IsInherited ? "Inherited" : "Explicit"); 45 | Console.WriteLine(" Propagation: {0}", fsar.PropagationFlags); 46 | Console.WriteLine(" Inheritance: {0}", fsar.InheritanceFlags); 47 | } 48 | 49 | // Print extra space as a separator when multiple paths are specified 50 | if (i++ < args.Length - 1) 51 | { 52 | Console.WriteLine(""); 53 | } 54 | } 55 | } 56 | } 57 | catch (Exception e) 58 | { 59 | Console.Error.WriteLine("[-] ERROR: {0}", e.Message.Trim()); 60 | } 61 | finally 62 | { 63 | Console.WriteLine("\nDONE"); 64 | } 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /lld.cs: -------------------------------------------------------------------------------- 1 | // Source: https://stackoverflow.com/questions/14442960/getting-drive-info-from-a-remote-computer 2 | 3 | // To Compile: 4 | // C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:lld.exe lld.cs 5 | 6 | 7 | using System; 8 | using System.Management; 9 | 10 | class ListLogicalDrives 11 | { 12 | public static int PrintUsage() 13 | { 14 | Console.WriteLine(@"List logical drives on local or remote host 15 | 16 | USAGE: 17 | lld [system]"); 18 | return 1; 19 | } 20 | 21 | public static int Main(string[] args) 22 | { 23 | try 24 | { 25 | string[] DRIVE_TYPES = { "Unknown", "No Root Directory", "Removable Disk", "Local Disk", "Network Drive", "Compact Disc", "RAM Disk" }; 26 | 27 | string system = "."; 28 | 29 | foreach (string arg in args) 30 | { 31 | switch (arg.ToUpper()) 32 | { 33 | case "/?": 34 | return PrintUsage(); 35 | default: 36 | system = args[0].Trim(new Char[] { '\\', ' ' }); 37 | break; 38 | } 39 | } 40 | 41 | ManagementPath path = new ManagementPath() 42 | { 43 | NamespacePath = @"root\cimv2", 44 | Server = system 45 | }; 46 | 47 | ManagementScope scope = new ManagementScope(path); 48 | 49 | string[] selectedProperties = new string[] { "DeviceID", "DriveType", "ProviderName", "FreeSpace", "Size", "VolumeName" }; 50 | SelectQuery query = new SelectQuery("Win32_LogicalDisk", "", selectedProperties); 51 | 52 | // Execute query within scope and iterate through results 53 | using (var searcher = new ManagementObjectSearcher(scope, query)) 54 | { 55 | foreach (ManagementObject volume in searcher.Get()) 56 | { 57 | Console.WriteLine("\nDrive {0}\\", volume.GetPropertyValue("DeviceID")); 58 | 59 | if (String.Format("{0}", volume.GetPropertyValue("VolumeName")) != "") 60 | { 61 | Console.WriteLine(" Name: {0}", volume.GetPropertyValue("VolumeName")); 62 | } 63 | 64 | Console.WriteLine(" Type: {0}", DRIVE_TYPES[Convert.ToInt32(volume.GetPropertyValue("DriveType"))]); 65 | 66 | if (Convert.ToInt32(volume.GetPropertyValue("DriveType")) == 4) 67 | { 68 | Console.WriteLine(" Provider: {0}", volume.GetPropertyValue("ProviderName")); 69 | } 70 | 71 | if (Convert.ToInt64(volume.GetPropertyValue("Size")) > 0) 72 | { 73 | Console.WriteLine(" Free Space: {0}", String.Format("{0:n0}", Convert.ToInt64(volume.GetPropertyValue("FreeSpace"))) + " bytes"); 74 | Console.WriteLine(" Size: {0}", String.Format("{0:n0}", Convert.ToInt64(volume.GetPropertyValue("Size"))) + " bytes"); 75 | } 76 | } 77 | } 78 | 79 | return 0; 80 | } 81 | catch (Exception e) 82 | { 83 | Console.Error.WriteLine("[-] ERROR: {0}", e.Message.Trim()); 84 | return 1; 85 | } 86 | finally 87 | { 88 | Console.WriteLine("\nDONE"); 89 | } 90 | } 91 | } -------------------------------------------------------------------------------- /make.ps1: -------------------------------------------------------------------------------- 1 | # Pipe all stdout to $null to give nice clean output that still shows error messages 2 | 3 | Write-Output "[*] Building SharpUtils..." 4 | mkdir "bin" -ErrorAction SilentlyContinue 5 | 6 | Write-Output " [*] arp.exe" 7 | C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:exe /out:bin\arp_2.0.exe arp.cs | Select-String error 8 | C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:bin\arp_3.5.exe arp.cs | Select-String error 9 | C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:bin\arp_4.0.exe arp.cs | Select-String error 10 | 11 | Write-Output " [*] auditpol.exe" 12 | C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:exe /out:bin\auditpol_2.0.exe auditpol.cs | Select-String error 13 | C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:bin\auditpol_3.5.exe auditpol.cs | Select-String error 14 | C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:bin\auditpol_4.0.exe auditpol.cs | Select-String error 15 | 16 | Write-Output " [*] check_sig.exe" 17 | C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:bin\check_sig_4.0.exe check_sig.cs | Select-String error 18 | 19 | Write-Output " [*] create_process.exe" 20 | C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:bin\create_process_3.5.exe create_process.cs | Select-String error 21 | C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:bin\create_process_4.0.exe create_process.cs | Select-String error 22 | 23 | Write-Output " [*] driver_list.exe" 24 | C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:bin\driver_list_4.0.exe driver_list.cs | Select-String error 25 | 26 | Write-Output " [*] dsquery.exe" 27 | C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:bin\dsquery_4.0.exe dsquery.cs | Select-String error 28 | 29 | Write-Output " [*] dump_dns.exe" 30 | C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:bin\dump_dns_4.0.exe dump_dns.cs | Select-String error 31 | 32 | Write-Output " [*] env.exe" 33 | C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:exe /out:bin\env_2.0.exe env.cs | Select-String error 34 | C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:bin\env_3.5.exe env.cs | Select-String error 35 | C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:bin\env_4.0.exe env.cs | Select-String error 36 | 37 | Write-Output " [*] eventlog.exe" 38 | C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:bin\eventlog_3.5.exe eventlog.cs | Select-String error 39 | C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:bin\eventlog_4.0.exe eventlog.cs | Select-String error 40 | 41 | Write-Output " [*] farm_dns.exe" 42 | C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:bin\farm_dns_3.5.exe farm_dns.cs | Select-String error 43 | C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:bin\farm_dns_4.0.exe farm_dns.cs | Select-String error 44 | 45 | Write-Output " [*] freespace.exe" 46 | C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:exe /out:bin\freespace_2.0.exe freespace.cs | Select-String error 47 | C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:bin\freespace_3.5.exe freespace.cs | Select-String error 48 | C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:bin\freespace_4.0.exe freespace.cs | Select-String error 49 | 50 | Write-Output " [*] get_chrome_tab_info.exe" 51 | C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /reference:"C:\Windows\Microsoft.NET\assembly\GAC_MSIL\UIAutomationTypes\v4.0_4.0.0.0__31bf3856ad364e35\UIAutomationTypes.dll" /reference:"C:\Windows\Microsoft.NET\assembly\GAC_MSIL\UIAutomationClient\v4.0_4.0.0.0__31bf3856ad364e35\UIAutomationClient.dll" /t:exe /out:bin\get_chrome_tab_info_4.0.exe get_chrome_tab_info.cs | Select-String error 52 | 53 | Write-Output " [*] get_hotfix.exe" 54 | C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:bin\get_hotfix_3.5.exe get_hotfix.cs | Select-String error 55 | C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:bin\get_hotfix_4.0.exe get_hotfix.cs | Select-String error 56 | 57 | Write-Output " [*] icacls.exe" 58 | C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:exe /out:bin\icacls_2.0.exe icacls.cs | Select-String error 59 | C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:bin\icacls_3.5.exe icacls.cs | Select-String error 60 | C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:bin\icacls_4.0.exe icacls.cs | Select-String error 61 | 62 | Write-Output " [*] lld.exe" 63 | C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:bin\lld_3.5.exe lld.cs | Select-String error 64 | C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:bin\lld_4.0.exe lld.cs | Select-String error 65 | 66 | Write-Output " [*] netstat.exe" 67 | C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:bin\netstat_3.5.exe netstat.cs | Select-String error 68 | C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:bin\netstat_4.0.exe netstat.cs | Select-String error 69 | 70 | Write-Output " [*] pagegrab.exe" 71 | C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:exe /out:bin\pagegrab_2.0.exe pagegrab.cs | Select-String error 72 | C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:bin\pagegrab_3.5.exe pagegrab.cs | Select-String error 73 | C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:bin\pagegrab_4.0.exe pagegrab.cs | Select-String error 74 | 75 | Write-Output " [*] readfile.exe" 76 | C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:exe /out:bin\readfile_2.0.exe readfile.cs | Select-String error 77 | C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:bin\readfile_3.5.exe readfile.cs | Select-String error 78 | C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:bin\readfile_4.0.exe readfile.cs | Select-String error 79 | 80 | Write-Output " [*] taskkill.exe" 81 | C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:exe /out:bin\taskkill_2.0.exe taskkill.cs | Select-String error 82 | C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:bin\taskkill_3.5.exe taskkill.cs | Select-String error 83 | C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:bin\taskkill_4.0.exe taskkill.cs | Select-String error 84 | 85 | Write-Output " [*] tasklist_svc.exe" 86 | C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:bin\tasklist_svc_3.5.exe tasklist_svc.cs | Select-String error 87 | C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:bin\tasklist_svc_4.0.exe tasklist_svc.cs | Select-String error 88 | 89 | Write-Output " [*] tasklist_wmi.exe" 90 | C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:bin\tasklist_wmi_3.5.exe tasklist_wmi.cs | Select-String error 91 | C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:bin\tasklist_wmi_4.0.exe tasklist_wmi.cs | Select-String error 92 | 93 | Write-Output " [*] test_ad_creds.exe" 94 | C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /reference:"C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.DirectoryServices.Protocols\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.DirectoryServices.Protocols.dll" /t:exe /out:bin\test_ad_creds_4.0.exe test_ad_creds.cs | Select-String error 95 | 96 | Write-Output " [*] window_list.exe" 97 | C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:exe /out:bin\window_list_2.0.exe window_list.cs | Select-String error 98 | C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:bin\window_list_3.5.exe window_list.cs | Select-String error 99 | C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:bin\window_list_4.0.exe window_list.cs | Select-String error 100 | 101 | Write-Output " [*] wmi_query.exe" 102 | C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:bin\wmi_query_3.5.exe wmi_query.cs | Select-String error 103 | C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:bin\wmi_query_4.0.exe wmi_query.cs | Select-String error 104 | 105 | Write-Output "[+] Build Complete!" 106 | 107 | Write-Host -NoNewLine "Press any key to continue..." 108 | $host.ui.RawUI.ReadKey() | Out-Null -------------------------------------------------------------------------------- /netstat.cs: -------------------------------------------------------------------------------- 1 | // Source: https://docs.microsoft.com/en-us/dotnet/api/system.environment.getcommandlineargs?view=net-5.0 2 | // Source: https://social.msdn.microsoft.com/Forums/vstudio/en-US/9c28a7b0-9ee1-425e-8aa0-afeac329a983/list-of-installed-devices-and-drivers-using-cnet?forum=csharpgeneral 3 | // Source: https://docs.microsoft.com/en-us/dotnet/api/system.management.managementobjectsearcher.scope?view=dotnet-plat-ext-6.0#system-management-managementobjectsearcher-scope 4 | 5 | 6 | // To Compile: 7 | // C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:netstat.exe netstat.cs 8 | 9 | 10 | using System; 11 | using System.Collections.Generic; 12 | using System.IO; 13 | using System.Management; 14 | 15 | namespace Netstat 16 | { 17 | public class Program 18 | { 19 | private static void WriteOutput(string outputFilepath, List output) 20 | { 21 | if (outputFilepath != "") 22 | { 23 | Console.WriteLine("[*] Writing output to: {0}", outputFilepath); 24 | System.IO.File.WriteAllLines(outputFilepath, output.ToArray()); 25 | } 26 | else 27 | { 28 | foreach (string line in output) 29 | { 30 | Console.WriteLine(line); 31 | } 32 | } 33 | } 34 | 35 | private static void PrintUsage() 36 | { 37 | Console.WriteLine(@"Lists listening TCP and UDP ports, and active TCP connection (equivalent to 'netstat -ano'); optionally writes output to a file 38 | 39 | USAGE: 40 | netstat.exe [/S [/U [domain\]username /P password]] [/O ] [TCP | UDP] 41 | 42 | Examples: 43 | netstat.exe 44 | 45 | netstat.exe tcp 46 | 47 | netstat.exe -S DC01.MGMT.LOCAL 48 | 49 | netstat.exe -S DC01.MGMT.LOCAL -U MGMT\Administrator -P password"); 50 | } 51 | 52 | public static void Main() 53 | { 54 | try 55 | { 56 | string outputFilepath = ""; 57 | string system = "."; 58 | string username = ""; 59 | string password = ""; 60 | string protocol = ""; 61 | 62 | // Parse arguments 63 | string[] args = Environment.GetCommandLineArgs(); 64 | 65 | for (int i = 1; i < args.Length; i++) 66 | { 67 | string arg = args[i]; 68 | 69 | switch (arg.ToUpper()) 70 | { 71 | case "-O": 72 | case "/O": 73 | i++; 74 | 75 | try 76 | { 77 | outputFilepath = args[i]; 78 | 79 | if (File.Exists(outputFilepath)) 80 | { 81 | throw new ArgumentException("Output file already exists"); 82 | } 83 | } 84 | catch (IndexOutOfRangeException) 85 | { 86 | throw new ArgumentException("No output file specified"); 87 | } 88 | break; 89 | case "-S": 90 | case "/S": 91 | i++; 92 | 93 | try 94 | { 95 | system = args[i]; 96 | } 97 | catch (IndexOutOfRangeException) 98 | { 99 | throw new ArgumentException("No system specified"); 100 | } 101 | break; 102 | case "-U": 103 | case "/U": 104 | i++; 105 | 106 | try 107 | { 108 | username = args[i]; 109 | } 110 | catch (IndexOutOfRangeException) 111 | { 112 | throw new ArgumentException("No username specified"); 113 | } 114 | 115 | break; 116 | case "-P": 117 | case "/P": 118 | i++; 119 | 120 | try 121 | { 122 | password = args[i]; 123 | } 124 | catch (IndexOutOfRangeException) 125 | { 126 | throw new ArgumentException("No password specified"); 127 | } 128 | break; 129 | case "/?": 130 | PrintUsage(); 131 | return; 132 | default: 133 | protocol = args[i].ToUpper(); 134 | 135 | if (!(protocol.Equals("TCP") || protocol.Equals("UDP"))) 136 | { 137 | throw new ArgumentException("Invalid protocol specified"); 138 | } 139 | break; 140 | } 141 | } 142 | 143 | ConnectionOptions conn_opts = new ConnectionOptions(); 144 | 145 | // Apply username and password if specified 146 | if (username.Length > 0 && password.Length > 0) 147 | { 148 | conn_opts.Username = username; 149 | conn_opts.Password = password; 150 | } 151 | else if (username.Length > 0 || password.Length > 0) 152 | { 153 | // Throw an exception if username or password were specified, but not both 154 | throw new ArgumentException("Please specify username and password"); 155 | } 156 | 157 | // Keep track of the max length of each entry in order to dynamically space the columns 158 | int localAddrMaxSize = 13; // Length of "Local Address" 159 | int remoteAddrMaxSize = 15; // Length of "Foreign Address" 160 | int stateMaxSize = 5; // Length of "State" 161 | int colPadding = 4; 162 | Dictionary entry; 163 | List> entries = new List>(); 164 | 165 | // Lookup table for TCP connection states 166 | Dictionary tcpStates = new Dictionary(); 167 | tcpStates.Add("1", "Closed"); 168 | tcpStates.Add("2", "LISTENING"); 169 | tcpStates.Add("3", "SYN_SENT"); 170 | tcpStates.Add("4", "SYN_RECEIVED"); 171 | tcpStates.Add("5", "ESTABLISHED"); 172 | tcpStates.Add("6", "FIN_WAIT1"); 173 | tcpStates.Add("7", "FIN_WAIT2"); 174 | tcpStates.Add("8", "CLOSE_WAIT"); 175 | tcpStates.Add("9", "CLOSING"); 176 | tcpStates.Add("10", "LAST_ACK"); 177 | tcpStates.Add("11", "TIME_WAIT"); 178 | tcpStates.Add("12", "DELETE_TCB"); 179 | tcpStates.Add("100", "BOUND"); 180 | 181 | ManagementPath path = new ManagementPath() { NamespacePath = @"root\standardcimv2", Server = system }; 182 | ManagementScope scope = new ManagementScope(path, conn_opts); 183 | SelectQuery query; 184 | 185 | // Display TCP if it's specified or no protocol was specified 186 | if (protocol.Equals("TCP") || protocol.Equals("")) 187 | { 188 | // Query for TCP ports and connections; return specified attributes 189 | query = new SelectQuery("MSFT_NetTCPConnection", null, new string[] { "LocalAddress", "LocalPort", "RemoteAddress", "RemotePort", "State", "OwningProcess" }); 190 | 191 | using (var searcher = new ManagementObjectSearcher(scope, query)) 192 | { 193 | foreach (ManagementObject obj in searcher.Get()) 194 | { 195 | if (obj != null) 196 | { 197 | entry = new Dictionary(); 198 | 199 | entry.Add("protocol", "TCP"); 200 | // Use a lookup to convert the state code into a human-readable string 201 | entry.Add("state", tcpStates[obj.GetPropertyValue("State").ToString()]); 202 | entry.Add("pid", obj.GetPropertyValue("OwningProcess").ToString()); 203 | 204 | if (obj.GetPropertyValue("LocalAddress").ToString().Contains(":")) 205 | { 206 | // IPv6 address 207 | entry.Add("local_address", "[" + obj.GetPropertyValue("LocalAddress").ToString() + "]:" + obj.GetPropertyValue("LocalPort").ToString()); 208 | entry.Add("remote_address", "[" + obj.GetPropertyValue("RemoteAddress").ToString() + "]:" + obj.GetPropertyValue("RemotePort").ToString()); 209 | } 210 | else 211 | { 212 | // IPv4 address 213 | entry.Add("local_address", obj.GetPropertyValue("LocalAddress").ToString() + ":" + obj.GetPropertyValue("LocalPort").ToString()); 214 | entry.Add("remote_address", obj.GetPropertyValue("RemoteAddress").ToString() + ":" + obj.GetPropertyValue("RemotePort").ToString()); 215 | } 216 | 217 | entries.Add(entry); 218 | 219 | // Calculate the max length of each column (for dynamic spacing) 220 | if (entry["local_address"].Length > localAddrMaxSize) 221 | { 222 | localAddrMaxSize = entry["local_address"].Length; 223 | } 224 | 225 | if (entry["remote_address"].Length > remoteAddrMaxSize) 226 | { 227 | remoteAddrMaxSize = entry["remote_address"].Length; 228 | } 229 | 230 | if (entry["state"].Length > stateMaxSize) 231 | { 232 | stateMaxSize = entry["state"].Length; 233 | } 234 | } 235 | } 236 | } 237 | } 238 | 239 | // Display UDP if it's specified or no protocol was specified 240 | if (protocol.Equals("UDP") || protocol.Equals("")) 241 | { 242 | // Query for UDP ports; return specified attributes 243 | query = new SelectQuery("MSFT_NetUDPEndpoint", null, new string[] { "LocalAddress", "LocalPort", "OwningProcess" }); 244 | 245 | using (var searcher = new ManagementObjectSearcher(scope, query)) 246 | { 247 | foreach (ManagementObject obj in searcher.Get()) 248 | { 249 | if (obj != null) 250 | { 251 | entry = new Dictionary(); 252 | 253 | entry.Add("protocol", "UDP"); 254 | entry.Add("state", ""); 255 | entry.Add("remote_address", "*:*"); 256 | entry.Add("pid", obj.GetPropertyValue("OwningProcess").ToString()); 257 | 258 | if (obj.GetPropertyValue("LocalAddress").ToString().Contains(":")) 259 | { 260 | // IPv6 address 261 | entry.Add("local_address", "[" + obj.GetPropertyValue("LocalAddress").ToString() + "]:" + obj.GetPropertyValue("LocalPort").ToString()); 262 | } 263 | else 264 | { 265 | // IPv4 address 266 | entry.Add("local_address", obj.GetPropertyValue("LocalAddress").ToString() + ":" + obj.GetPropertyValue("LocalPort").ToString()); 267 | } 268 | 269 | entries.Add(entry); 270 | 271 | // Calculate the max length of the local address column (remote address and state and not populated) 272 | if (entry["local_address"].Length > localAddrMaxSize) 273 | { 274 | localAddrMaxSize = entry["local_address"].Length; 275 | } 276 | } 277 | } 278 | } 279 | } 280 | 281 | // Add extra padding to separate the columns 282 | localAddrMaxSize += colPadding; 283 | remoteAddrMaxSize += colPadding; 284 | stateMaxSize += colPadding; 285 | 286 | List output = new List(); 287 | string line; 288 | 289 | // Convert dictionary of network entries to a string with each column dynamically padded 290 | foreach (Dictionary row in entries) 291 | { 292 | line = " " + row["protocol"] + " "; 293 | line += row["local_address"].PadRight(localAddrMaxSize); 294 | line += row["remote_address"].PadRight(remoteAddrMaxSize); 295 | line += row["state"].PadRight(stateMaxSize); 296 | line += row["pid"]; 297 | 298 | output.Add(line); 299 | } 300 | 301 | // Sort the output to make it look cleaner 302 | output.Sort(); 303 | 304 | // Prepend table header after sorting 305 | line = "\nActive Connections\n\n Proto "; 306 | line += "Local Address".PadRight(localAddrMaxSize); 307 | line += "Foreign Address".PadRight(remoteAddrMaxSize); 308 | line += "State".PadRight(stateMaxSize); 309 | line += "PID"; 310 | 311 | output.Insert(0, line); 312 | 313 | WriteOutput(outputFilepath, output); 314 | } 315 | catch (Exception e) 316 | { 317 | Console.Error.WriteLine("[-] ERROR: {0}", e.Message.Trim()); 318 | } 319 | finally 320 | { 321 | Console.WriteLine("\nDONE"); 322 | } 323 | } 324 | } 325 | } -------------------------------------------------------------------------------- /pagegrab.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * USAGE: pagegrab.exe [-p http(s)://:] [-m ] [-d ] [-v] 3 | * 4 | * -v Print the HTML contents of the response 5 | * 6 | * EXAMPLES: 7 | * pagegrab.exe -m post https://postman-echo.com/post -d query=test -v -p http://127.0.0.1:8000 8 | */ 9 | 10 | // To Compile: 11 | // C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:exe /out:pagegrab.exe pagegrab.cs 12 | 13 | using Microsoft.Win32; 14 | using System; 15 | using System.Collections.Generic; 16 | using System.IO; 17 | using System.Net; 18 | using System.Text; 19 | using System.Text.RegularExpressions; 20 | 21 | // Needed for SSL / TLS certificate support 22 | using System.Security.Cryptography; 23 | using System.Security.Cryptography.X509Certificates; 24 | 25 | public class PageGrab 26 | { 27 | public static int Main(string[] args) 28 | { 29 | try 30 | { 31 | if (args.Length == 0 || (args.Length > 0 && args[0] == "/?")) 32 | { 33 | // Print usage 34 | Console.WriteLine(@"USAGE: pagegrab.exe [-p http(s)://:] [-m ] [-d ] [-h [-h ]] [-c] [-v] [/?] 35 | 36 | -c Display the SSL / TLS certificate 37 | -v Print the HTML contents of the response"); 38 | return 0; 39 | } 40 | 41 | string url = ""; 42 | string userAgent = ""; 43 | string proxyAddress = ""; 44 | string method = "GET"; 45 | string postData = ""; 46 | bool displaySSLCert = false; 47 | bool verbose = false; 48 | Dictionary headers = new Dictionary(); 49 | 50 | List unsupportedHeaders = new List(); 51 | unsupportedHeaders.Add("Date"); 52 | unsupportedHeaders.Add("Host"); 53 | unsupportedHeaders.Add("If-Modified-Since"); 54 | 55 | try 56 | { 57 | string edgeVersion = Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\EdgeUpdate\\Clients\\{56EB18F8-B008-4CBD-B6D2-8C97FE7E9062}", "pv", "").ToString(); 58 | userAgent = String.Format("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/{0} Safari/537.36 Edg/{0}", edgeVersion); 59 | } 60 | catch 61 | { 62 | // Ignore the error for now 63 | } 64 | 65 | // Parse arguments 66 | for (int i = 0; i < args.Length; i++) 67 | { 68 | string arg = args[i]; 69 | 70 | switch (arg.ToUpper()) 71 | { 72 | case "-C": // Display SSL / TLS certificate 73 | displaySSLCert = true; 74 | break; 75 | 76 | case "-D": // POST data 77 | i++; 78 | 79 | try 80 | { 81 | postData = args[i]; 82 | } 83 | catch (IndexOutOfRangeException) 84 | { 85 | throw new ArgumentException("No POST data specified"); 86 | } 87 | break; 88 | 89 | case "-H": // Header (multiples are allowed) 90 | i++; 91 | 92 | // Throw an error and exit if an unsupported header is specified 93 | if (i < args.Length && unsupportedHeaders.Contains(args[i])) 94 | { 95 | throw new ArgumentException("Unsupported header specified:" + args[i]); 96 | } 97 | else if (i + 1 < args.Length) 98 | { 99 | // Treat specified headers are a key-value pair 100 | headers.Add(args[i++], args[i]); 101 | } 102 | else 103 | { 104 | throw new ArgumentException("Incomplete header specified"); 105 | } 106 | break; 107 | 108 | case "-M": // HTTP Method 109 | i++; 110 | 111 | if (i < args.Length) 112 | { 113 | method = args[i].ToUpper(); 114 | } 115 | else 116 | { 117 | throw new ArgumentException("No HTTP Method specified"); 118 | } 119 | 120 | string[] methods = { "GET", "HEAD", "POST", "PUT", "DELETE", "CONNECT", "OPTIONS", "TRACE" }; 121 | 122 | // Verify the method is a valid 123 | if (Array.IndexOf(methods, method) == -1) 124 | { 125 | throw new ArgumentException(String.Format("Invalid method '{0}'", method)); 126 | } 127 | break; 128 | 129 | case "-P": // Proxy 130 | i++; 131 | 132 | if (i < args.Length) 133 | { 134 | proxyAddress = args[i]; 135 | } 136 | else 137 | { 138 | throw new ArgumentException("No Proxy info specified"); 139 | } 140 | 141 | Regex rex = new Regex(@"https?://.*:\d{1,5}", RegexOptions.IgnoreCase); 142 | 143 | if (!rex.IsMatch(proxyAddress)) 144 | { 145 | throw new ArgumentException("Invalid proxy configuration; use 'http(s)://:'"); 146 | } 147 | 148 | break; 149 | 150 | case "-Q": // Query user agent 151 | Console.WriteLine("[*] User-Agent: {0}", userAgent); 152 | return 0; 153 | 154 | case "-V": // Verbose output 155 | verbose = true; 156 | break; 157 | 158 | default: // URL 159 | url = arg; 160 | break; 161 | } 162 | } 163 | 164 | if (url.Length != 0) 165 | { 166 | // Initialize request 167 | HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 168 | request.Credentials = CredentialCache.DefaultCredentials; 169 | request.Method = method; 170 | 171 | // Add user-specified headers 172 | foreach (KeyValuePair header in headers) 173 | { 174 | switch (header.Key) 175 | { 176 | case "Accept": 177 | request.Accept = header.Value; 178 | break; 179 | case "Connection": 180 | request.Connection = header.Value; 181 | break; 182 | case "Content-Length": 183 | request.ContentLength = long.Parse(header.Value); 184 | break; 185 | case "Content-Type": 186 | request.ContentType = header.Value; 187 | break; 188 | case "Expect": 189 | request.Expect = header.Value; 190 | break; 191 | case "Range": 192 | string[] ranges = header.Value.Split('-'); 193 | 194 | if (ranges.Length >= 2) 195 | { 196 | if (ranges[0] == "") 197 | { 198 | // Specified range is negative 199 | request.AddRange(int.Parse("-" + ranges[1])); 200 | } 201 | else 202 | { 203 | // To and From are specified; additional ranges unsupported at this time 204 | request.AddRange(int.Parse(ranges[0]), int.Parse(ranges[1])); 205 | } 206 | } 207 | else 208 | { 209 | // Specified range is negative 210 | request.AddRange(int.Parse(ranges[0])); 211 | } 212 | 213 | break; 214 | case "Referer": 215 | request.Referer = header.Value; 216 | break; 217 | case "Transfer-Encoding": 218 | request.TransferEncoding = header.Value; 219 | break; 220 | case "User-Agent": 221 | userAgent = header.Value; 222 | break; 223 | default: 224 | request.Headers[header.Key] = header.Value; 225 | break; 226 | } 227 | } 228 | 229 | // Throw an exception if no user agent was specified and we weren't able to pull the version of Edge to use as a default 230 | // NOTE: This isn't perfect because the AppleWebKit / Safari version number won't match, but it's better probably better than sending nothing 231 | if (userAgent == "") 232 | { 233 | throw new Exception("Unable to auto-detect Edge version; please specify a user agent"); 234 | } 235 | 236 | request.UserAgent = userAgent; 237 | 238 | // Print request data 239 | Console.WriteLine("REQUEST"); 240 | Console.WriteLine("---------------"); 241 | Console.WriteLine(request.Method + " " + request.RequestUri); 242 | 243 | if (proxyAddress.Length != 0) 244 | { 245 | // Manually set the proxy 246 | WebProxy proxy = new WebProxy(); 247 | proxy.Address = new Uri(proxyAddress); 248 | proxy.Credentials = CredentialCache.DefaultCredentials; 249 | request.Proxy = proxy; 250 | Console.WriteLine("Proxy: " + proxyAddress); 251 | } 252 | else 253 | { 254 | // Detect the system proxy, if applicable 255 | Uri resource = new Uri(url); 256 | 257 | IWebProxy proxy = System.Net.WebRequest.GetSystemWebProxy(); 258 | Uri resourceProxy = proxy.GetProxy(resource); 259 | 260 | // Test to see whether a proxy was selected 261 | if (resourceProxy == resource) 262 | { 263 | Console.WriteLine("Proxy: None"); 264 | } 265 | else 266 | { 267 | Console.WriteLine("Proxy: " + resourceProxy.ToString()); 268 | } 269 | } 270 | 271 | // Add POST data, if applicable 272 | if (method == "POST") 273 | { 274 | request.ContentType = "application/x-www-form-urlencoded"; 275 | 276 | // Add the post data to the request 277 | byte[] byteArray = Encoding.UTF8.GetBytes(postData); 278 | 279 | request.ContentLength = byteArray.Length; 280 | 281 | Stream dataStream = request.GetRequestStream(); 282 | dataStream = request.GetRequestStream(); 283 | dataStream.Write(byteArray, 0, byteArray.Length); 284 | dataStream.Close(); 285 | } 286 | 287 | Console.WriteLine(request.Headers); 288 | 289 | // Print POST data after headers 290 | if (method == "POST") 291 | { 292 | Console.WriteLine(postData); 293 | } 294 | 295 | Console.WriteLine("\n\nRESPONSE"); 296 | Console.WriteLine("---------------"); 297 | 298 | // Get the response 299 | HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 300 | 301 | // Display the status and headers 302 | Console.WriteLine("Status: " + response.StatusDescription, Environment.NewLine); 303 | Console.WriteLine(response.Headers); 304 | 305 | // Optionally print the HTML from the response 306 | if (verbose) 307 | { 308 | // Get the stream containing content returned by the server. 309 | Stream dataStream = response.GetResponseStream(); 310 | 311 | // Open the stream using a StreamReader for easy access. 312 | StreamReader reader = new StreamReader(dataStream); 313 | 314 | // Read the content. 315 | string responseFromServer = reader.ReadToEnd(); 316 | 317 | Console.WriteLine(responseFromServer); 318 | 319 | // Cleanup the streams and the response. 320 | reader.Close(); 321 | dataStream.Close(); 322 | } 323 | 324 | response.Close(); 325 | 326 | if (displaySSLCert) 327 | { 328 | X509Certificate cert = request.ServicePoint.Certificate; 329 | 330 | Console.WriteLine("SSL / TLS Certificate"); 331 | Console.WriteLine("---------------------"); 332 | Console.WriteLine(" Subject: " + cert.Subject); 333 | Console.WriteLine(" Issuer: " + cert.Issuer); 334 | Console.WriteLine(" Valid From: " + cert.GetEffectiveDateString()); 335 | Console.WriteLine(" Valid To: " + cert.GetExpirationDateString()); 336 | Console.WriteLine(" Serial Number: " + cert.GetSerialNumberString()); 337 | Console.WriteLine(" SHA-1 Fingerprint: " + cert.GetCertHashString()); 338 | Console.WriteLine(" Public Key: " + cert.GetPublicKeyString()); 339 | Console.WriteLine(""); 340 | Console.WriteLine("Certificate PEM:"); 341 | Console.WriteLine("----BEGIN CERTIFICATE----"); 342 | Console.WriteLine(System.Convert.ToBase64String(cert.GetRawCertData())); 343 | Console.WriteLine("----END CERTIFICATE----"); 344 | } 345 | } 346 | else 347 | { 348 | throw new ArgumentException("No URL specified"); 349 | } 350 | 351 | return 0; 352 | } 353 | catch (Exception e) 354 | { 355 | Console.Error.WriteLine("[-] ERROR: {0}", e.Message.Trim()); 356 | return 1; 357 | } 358 | finally 359 | { 360 | Console.WriteLine("\nDONE"); 361 | } 362 | } 363 | } -------------------------------------------------------------------------------- /readfile.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Read the contents of a file; optionally limit to X number of lines from the beginning of the file or Y number of lines from the end 3 | * 4 | * USAGE: read.exe [+X] [-Y] 5 | */ 6 | 7 | // To Compile: 8 | // C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:exe /out:readfile.exe readfile.cs 9 | 10 | 11 | using System; 12 | using System.IO; 13 | 14 | class ReadFile 15 | { 16 | private static void PrintUsage() 17 | { 18 | string[] exePath = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName.Split('\\'); 19 | string exeName = exePath[exePath.Length - 1]; 20 | 21 | Console.WriteLine(@"Read the contents of a file; optionally limit to X number of lines from the beginning of the file or Y number of lines from the end 22 | 23 | USAGE: 24 | {0} [+X] [-Y] ", exeName); 25 | } 26 | 27 | public static void Main(string[] args) 28 | { 29 | try 30 | { 31 | if (args.Length == 0) 32 | { 33 | PrintUsage(); 34 | return; 35 | } 36 | 37 | int head = 0; 38 | int tail = 0; 39 | string filePath = ""; 40 | int lineCount = 0; 41 | 42 | // Parse arguments 43 | for (int i = 0; i < args.Length; i++) 44 | { 45 | string arg = args[i]; 46 | 47 | if (arg.StartsWith("+")) 48 | { 49 | arg = arg.Replace("+", ""); 50 | 51 | bool test = int.TryParse(arg, out head); 52 | 53 | if (test == false) 54 | { 55 | throw new ArgumentException("Invalid number of lines to read from head of file"); 56 | } 57 | } 58 | else if (arg.StartsWith("-")) 59 | { 60 | arg = arg.Replace("-", ""); 61 | 62 | bool test = int.TryParse(arg, out tail); 63 | if (test == false) 64 | { 65 | throw new ArgumentException("Invalid number of lines to read from head of file"); 66 | } 67 | } 68 | else 69 | { 70 | filePath = arg; 71 | } 72 | } 73 | 74 | if (File.Exists(filePath)) 75 | { 76 | // If tail is specified, determine line count 77 | if (tail > 0) 78 | { 79 | using (StreamReader file = new StreamReader(filePath)) 80 | { 81 | while (file.ReadLine() != null) 82 | { 83 | lineCount++; 84 | } 85 | } 86 | } 87 | 88 | // Use StreamReader so the entire files doesn't have to get read into memory at once 89 | using (StreamReader file = new StreamReader(filePath)) 90 | { 91 | int i = 0; 92 | string line; 93 | 94 | while ((line = file.ReadLine()) != null) 95 | { 96 | // Print the line if it's less than head, greater than tail, or neither head nor tail are specified 97 | if ((head > 0 && i < head) || (tail > 0 && i >= lineCount - tail) || (head == 0 && tail == 0)) 98 | { 99 | Console.WriteLine(line); 100 | } 101 | 102 | // Stop when head is reached if tail is not also specified (for efficiency) 103 | if (head > 0 && i == head && tail == 0) 104 | { 105 | break; 106 | } 107 | 108 | i++; 109 | } 110 | } 111 | } 112 | else 113 | { 114 | throw new Exception("File does not exist"); 115 | } 116 | } 117 | catch (Exception e) 118 | { 119 | Console.Error.WriteLine("[-] ERROR: {0}", e.Message.Trim()); 120 | } 121 | finally 122 | { 123 | Console.WriteLine("\nDONE"); 124 | } 125 | } 126 | } -------------------------------------------------------------------------------- /taskkill.cs: -------------------------------------------------------------------------------- 1 | // Sources: 2 | // - Kill Remote Process - https://stackoverflow.com/questions/25727323/kill-process-on-remote-machine 3 | 4 | // TODO: 5 | // - Kill child processes: https://kv4s.files.wordpress.com/2015/08/killserviceprocesses.jpg 6 | 7 | // To Compile: 8 | // C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:exe /out:taskkill.exe taskkill.cs 9 | 10 | 11 | using System; 12 | using System.Management; 13 | 14 | class TaskKill 15 | { 16 | public static void PrintUsage() 17 | { 18 | Console.WriteLine(@"Kill process by ID or name 19 | 20 | USAGE: 21 | taskkill [/S [/U [domain\] /P ]] { [/PID [,...] | /IM ] }"); 22 | } 23 | 24 | // Returns an appropriate singular or plural string based on the number of processes 25 | private static string GetNumProcStr(int numProcesses) 26 | { 27 | if (numProcesses == 1) 28 | { 29 | return "1 process"; 30 | } 31 | 32 | return numProcesses + " processes"; 33 | } 34 | 35 | public static void Main(string[] args) 36 | { 37 | try 38 | { 39 | if (args.Length == 0) 40 | { 41 | PrintUsage(); 42 | return; 43 | } 44 | 45 | string system = "127.0.0.1"; 46 | string username = ""; 47 | string password = ""; 48 | string pid_str = ""; 49 | string image = ""; 50 | bool pid_set = false; 51 | bool image_set = false; 52 | 53 | // Parse arguments 54 | for (int i = 0; i < args.Length; i++) 55 | { 56 | string arg = args[i]; 57 | 58 | switch (arg.ToUpper()) 59 | { 60 | case "-S": 61 | case "/S": 62 | i++; 63 | 64 | try 65 | { 66 | system = args[i].Trim(new Char[] { '\\', ' ' }); 67 | } 68 | catch (IndexOutOfRangeException) 69 | { 70 | throw new ArgumentException("No system specified"); 71 | } 72 | break; 73 | case "-PID": 74 | case "/PID": 75 | i++; 76 | 77 | try 78 | { 79 | pid_str = args[i]; 80 | } 81 | catch (IndexOutOfRangeException) 82 | { 83 | throw new ArgumentException("No PID(s) specified"); 84 | } 85 | 86 | pid_set = true; 87 | break; 88 | case "-IM": 89 | case "/IM": 90 | i++; 91 | 92 | try 93 | { 94 | image = args[i]; 95 | } 96 | catch (IndexOutOfRangeException) 97 | { 98 | throw new ArgumentException("No image specified"); 99 | } 100 | image_set = true; 101 | break; 102 | case "-U": 103 | case "/U": 104 | i++; 105 | 106 | try 107 | { 108 | username = args[i]; 109 | } 110 | catch (IndexOutOfRangeException) 111 | { 112 | throw new ArgumentException("No username specified"); 113 | } 114 | 115 | break; 116 | case "-P": 117 | case "/P": 118 | i++; 119 | 120 | try 121 | { 122 | password = args[i]; 123 | } 124 | catch (IndexOutOfRangeException) 125 | { 126 | throw new ArgumentException("No password specified"); 127 | } 128 | break; 129 | case "/?": 130 | default: 131 | PrintUsage(); 132 | return; 133 | } 134 | } 135 | 136 | // Error out if neither PID nor image are specified, or if both are specified 137 | if (!(pid_set || image_set)) 138 | { 139 | throw new ArgumentException("No process specified"); 140 | } 141 | else if (pid_set && image_set) 142 | { 143 | throw new ArgumentException("PID and image cannot both be set"); 144 | } 145 | 146 | ConnectionOptions conn_opts = new ConnectionOptions(); 147 | 148 | // Apply username and password if specified 149 | if (username.Length > 0 && password.Length > 0) 150 | { 151 | conn_opts.Username = username; 152 | conn_opts.Password = password; 153 | } 154 | else if (username.Length > 0 || password.Length > 0) 155 | { 156 | // Throw an exception if username or password were specified, but not both 157 | throw new ArgumentException("Please specify username and password"); 158 | } 159 | 160 | ManagementScope scope = new ManagementScope(@"\\" + system + @"\root\cimv2", conn_opts); 161 | 162 | // Initialize WMI query 163 | string queryStr = "select * from Win32_process where name = '" + image + "'"; 164 | string procID = image; 165 | 166 | // Override the query if PID was specified 167 | if (pid_set) 168 | { 169 | queryStr = "select * from Win32_process where ProcessId = " + pid_str.Replace(",", " OR ProcessID = "); 170 | procID = "PID: " + pid_str.Replace(",", ", "); 171 | } 172 | 173 | int numProcesses = 0; 174 | SelectQuery query = new SelectQuery(queryStr); 175 | 176 | // Execute query within scope and iterate through results 177 | using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query)) 178 | { 179 | ManagementObjectCollection collection = searcher.Get(); 180 | 181 | Console.WriteLine("Attempting to terminate " + GetNumProcStr(collection.Count)); 182 | 183 | foreach (ManagementObject process in collection) 184 | { 185 | try 186 | { 187 | process.InvokeMethod("Terminate", null); 188 | numProcesses++; 189 | } 190 | catch (Exception e) 191 | { 192 | throw new Exception(String.Format("PID {0} {1}", process.Properties["ProcessId"].Value, e.Message.Trim().ToLower())); 193 | } 194 | } 195 | } 196 | 197 | Console.WriteLine("Terminated " + GetNumProcStr(numProcesses) + " (" + procID + ") on " + system); 198 | } 199 | catch (Exception e) 200 | { 201 | // Catch errors like connection timeouts 202 | Console.Error.WriteLine("[-] ERROR: {0}", e.Message.Trim()); 203 | } 204 | finally 205 | { 206 | Console.WriteLine("\nDONE"); 207 | } 208 | } 209 | } -------------------------------------------------------------------------------- /tasklist_svc.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * USAGE: tasklist_svc.exe 3 | * 4 | * Lists processes, their PIDs, and their associated services (if applicable) 5 | */ 6 | // C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:test/tasklist_svc.exe tasklist_svc.cs 7 | 8 | 9 | using System; 10 | using System.Management; 11 | using System.Collections.Generic; 12 | using System.Linq; 13 | 14 | public class TaskListSVC 15 | { 16 | private static void PrintUsage() 17 | { 18 | Console.WriteLine(@"Lists processes, their PIDs, and their associated services (if applicable) 19 | 20 | USAGE: 21 | tasklist_svc.exe [/?]"); 22 | } 23 | 24 | public static void Main(string[] args) 25 | { 26 | try 27 | { 28 | // Parse arguments 29 | for (int i = 0; i < args.Length; i++) 30 | { 31 | string arg = args[i]; 32 | 33 | switch (arg.ToUpper()) 34 | { 35 | case "/?": 36 | PrintUsage(); 37 | return; 38 | } 39 | } 40 | 41 | Dictionary pid_proc_map = new Dictionary(); 42 | int max_proc_name = 0; 43 | int proc_id; 44 | string proc_name; 45 | 46 | // Get a process list; map PIDs to process names 47 | foreach (ManagementObject proc in (new ManagementClass("Win32_Process")).GetInstances()) 48 | { 49 | proc_id = Convert.ToInt32(proc["ProcessID"]); 50 | proc_name = proc["Name"].ToString(); 51 | 52 | pid_proc_map.Add(proc_id, proc_name); 53 | 54 | // Find the length of the longest process name, so the output can be formatted nicely 55 | if (proc_name.Length > max_proc_name) 56 | { 57 | max_proc_name = proc_name.Length; 58 | } 59 | } 60 | 61 | int max_pid = 8; 62 | int max_svc_name = 45; 63 | List svc_names; 64 | string svc_str; 65 | string query; 66 | 67 | // Print the table header, pad each column so they line up nicely 68 | Console.WriteLine("{0} {1} {2}", "Image Name".PadRight(max_proc_name), "PID".PadLeft(max_pid), "Services".PadRight(max_svc_name)); 69 | Console.WriteLine("{0} {1} {2}", new String('=', max_proc_name), new String('=', max_pid), new String('=', max_svc_name)); 70 | 71 | // Sort the PIDs for convenience (because why not be better than the native command...) 72 | List pids = pid_proc_map.Keys.ToList(); 73 | pids.Sort(); 74 | 75 | // Loop through each PID, search for any associated processes, and print 76 | foreach (int pid in pids) 77 | { 78 | svc_str = "N/A"; 79 | svc_names = new List(); 80 | 81 | if (pid != 0) 82 | { 83 | query = "SELECT NAME FROM WIN32_SERVICE WHERE PROCESSID = '" + pid.ToString() + "'"; 84 | ManagementObjectSearcher searcher = new ManagementObjectSearcher(query); 85 | 86 | foreach (ManagementObject svc in searcher.Get()) 87 | { 88 | svc_names.Add(svc["NAME"].ToString()); 89 | } 90 | } 91 | 92 | // Comma-separate the service names if there are multiples 93 | if (svc_names.Count > 0) 94 | { 95 | svc_str = String.Join(", ", svc_names.ToArray()); 96 | } 97 | 98 | Console.WriteLine("{0} {1} {2}", pid_proc_map[pid].PadRight(max_proc_name), pid.ToString().PadLeft(max_pid), svc_str); 99 | } 100 | } 101 | catch (Exception e) 102 | { 103 | Console.Error.WriteLine("[-] ERROR: {0}", e.Message.Trim()); 104 | 105 | } 106 | finally 107 | { 108 | Console.WriteLine("\nDONE"); 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /tasklist_wmi.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * USAGE: tasklist_wmi.exe 3 | * 4 | * List processes on local or remote system, optionally filter by ID, name, or WQL query 5 | * 6 | * Examples: 7 | * tasklist_wmi.exe /v 8 | * 9 | * tasklist_wmi.exe /S 192.168.20.10 /FI "Name Like 'cmd%'" 10 | * 11 | * tasklist_wmi.exe /S 192.168.20.10 /FI "CommandLine Like '%svchost%'" 12 | * 13 | * tasklist_wmi.exe /S 192.168.20.10 /U Desktop-624L8K3\Administrator /P password /FI "CommandLine Like '%svchost%'" 14 | */ 15 | // Source: 16 | // - https://stackoverflow.com/questions/777548/how-do-i-determine-the-owner-of-a-process-in-c 17 | 18 | // C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:bin\tasklist_wmi.exe tasklist_wmi.cs 19 | 20 | using System; 21 | using System.Collections.Generic; 22 | using System.Management; 23 | 24 | class TaskList 25 | { 26 | public static void PrintUsage() 27 | { 28 | Console.WriteLine(@"List processes on local or remote system, optionally filter by ID or name 29 | 30 | USAGE: 31 | tasklist_wmi.exe [/S system [/U [domain\]username /P password]] [ [/PID processid | /IM imagename | /FI ""WQL where clause""] ] [/V] [/D """"] [/?] 32 | 33 | *NOTE*: When using /FI, you must provide a Win32_Process-compatible WMI query language condition string rather than a standard tasklist filter. You may use '%' as a wildcard 34 | 35 | Examples: 36 | tasklist_wmi.exe /v 37 | 38 | tasklist_wmi.exe /S 192.168.20.10 /FI ""Name Like 'cmd%'"" 39 | 40 | tasklist_wmi.exe /S 192.168.20.10 /FI ""CommandLine Like '%svchost%'"" 41 | 42 | tasklist_wmi.exe /S 192.168.20.10 /U Desktop-624L8K3\Administrator /P password /FI ""CommandLine Like '%svchost%'"""); 43 | } 44 | 45 | public static void Main(string[] args) 46 | { 47 | try 48 | { 49 | int max_key_length = 15; 50 | string system = "."; 51 | string username = ""; 52 | string password = ""; 53 | string delimiter = ""; 54 | int pid = -1; 55 | string image = ""; 56 | string condition = ""; 57 | bool pid_set = false; 58 | bool image_set = false; 59 | bool condition_set = false; 60 | bool verbose_set = false; 61 | 62 | // Parse arguments 63 | for (int i = 0; i < args.Length; i++) 64 | { 65 | string arg = args[i]; 66 | 67 | switch (arg.ToUpper()) 68 | { 69 | case "-D": 70 | case "/D": 71 | i++; 72 | try 73 | { 74 | delimiter = args[i]; 75 | } 76 | catch (IndexOutOfRangeException) 77 | { 78 | throw new ArgumentException("No delimiter specified"); 79 | } 80 | break; 81 | case "-S": 82 | case "/S": 83 | i++; 84 | try 85 | { 86 | system = args[i].Trim(new Char[] { '\\', ' ' }); 87 | } 88 | catch (IndexOutOfRangeException) 89 | { 90 | throw new ArgumentException("No system specified"); 91 | } 92 | break; 93 | case "-PID": 94 | case "/PID": 95 | i++; 96 | 97 | bool test = int.TryParse(args[i], out pid); 98 | if (test == false) 99 | { 100 | throw new ArgumentException("Invalid PID"); 101 | } 102 | pid_set = pid > -1; 103 | break; 104 | case "-IM": 105 | case "/IM": 106 | i++; 107 | try 108 | { 109 | image = args[i]; 110 | } 111 | catch (IndexOutOfRangeException) 112 | { 113 | throw new ArgumentException("No image specified"); 114 | } 115 | image_set = true; 116 | break; 117 | case "-FI": 118 | case "/FI": 119 | i++; 120 | try 121 | { 122 | condition = args[i]; 123 | } 124 | catch (IndexOutOfRangeException) 125 | { 126 | throw new ArgumentException("No filter specified"); 127 | } 128 | condition_set = true; 129 | break; 130 | case "-U": 131 | case "/U": 132 | i++; 133 | try 134 | { 135 | username = args[i]; 136 | } 137 | catch (IndexOutOfRangeException) 138 | { 139 | throw new ArgumentException("No username specified"); 140 | } 141 | 142 | break; 143 | case "-P": 144 | case "/P": 145 | i++; 146 | try 147 | { 148 | password = args[i]; 149 | } 150 | catch (IndexOutOfRangeException) 151 | { 152 | throw new ArgumentException("No password specified"); 153 | } 154 | break; 155 | case "-V": 156 | case "/V": 157 | verbose_set = true; 158 | break; 159 | case "/?": 160 | PrintUsage(); 161 | return; 162 | } 163 | } 164 | 165 | // Error out if more than one of PID, image, and filter are specified 166 | if ((pid_set && image_set) || (pid_set && condition_set) || (image_set && condition_set)) 167 | { 168 | throw new ArgumentException("PID and image cannot both be set"); 169 | } 170 | 171 | var conn_opts = new ConnectionOptions(); 172 | 173 | // Apply username and password if specified 174 | if (username.Length > 0 && password.Length > 0) 175 | { 176 | conn_opts.Username = username; 177 | conn_opts.Password = password; 178 | } 179 | else if (username.Length > 0 || password.Length > 0) 180 | { 181 | // Throw an exception if username or password were specified, but not both 182 | throw new ArgumentException("Please specify username and password"); 183 | } 184 | 185 | ManagementPath path = new ManagementPath() { NamespacePath = @"root\cimv2", Server = system }; 186 | ManagementScope scope = new ManagementScope(path, conn_opts); 187 | 188 | if (pid_set) 189 | { 190 | condition = "PROCESSID = '" + pid + "'"; 191 | } 192 | else if (image_set) 193 | { 194 | condition = "NAME = '" + image + "'"; 195 | } 196 | 197 | List selectedProperties = new List(new string[] { "ProcessId", "ParentProcessId", "SessionId", "Name", "Handle", "ExecutablePath", "CommandLine" }); 198 | SelectQuery query = new SelectQuery("Win32_Process", condition, selectedProperties.ToArray()); 199 | 200 | Dictionary proc_info; 201 | List> processes = new List>(); 202 | 203 | // Execute query within scope and iterate through results 204 | using (var searcher = new ManagementObjectSearcher(scope, query)) 205 | { 206 | foreach (ManagementObject proc in searcher.Get()) 207 | { 208 | proc_info = new Dictionary(); 209 | 210 | foreach (string prop in selectedProperties) 211 | { 212 | if (proc != null) 213 | { 214 | object val = proc.GetPropertyValue(prop); 215 | 216 | if (val != null) 217 | { 218 | proc_info.Add(prop, val.ToString()); 219 | } 220 | } 221 | } 222 | 223 | // Try to get the process owner 224 | if (verbose_set) 225 | { 226 | try 227 | { 228 | string[] argList = new string[] { string.Empty, string.Empty }; 229 | int returnVal = Convert.ToInt32(proc.InvokeMethod("GetOwner", argList)); 230 | if (returnVal == 0) 231 | { 232 | // Store DOMAIN\user 233 | proc_info.Add("User Name", argList[1] + "\\" + argList[0]); 234 | } 235 | } 236 | catch (Exception e) 237 | { 238 | proc_info.Add("User Name", e.Message.ToString()); 239 | } 240 | } 241 | 242 | processes.Add(proc_info); 243 | } 244 | } 245 | 246 | if (processes.Count > 0) 247 | { 248 | // Replace or remove "Handle" property (only used by GetOwner when running in verbose mode) 249 | if (verbose_set) 250 | { 251 | selectedProperties[4] = "User Name"; 252 | } 253 | else 254 | { 255 | selectedProperties.RemoveAt(4); 256 | } 257 | 258 | foreach (Dictionary proc in processes) 259 | { 260 | // Loop through the properties in the order specified above 261 | foreach (string prop in selectedProperties) 262 | { 263 | if (proc.ContainsKey(prop)) 264 | { 265 | Console.WriteLine("{0} : {1}", prop.PadRight(max_key_length), proc[prop]); 266 | } 267 | } 268 | 269 | // Separate each process entry with the specified delimiter 270 | Console.WriteLine(delimiter); 271 | } 272 | } 273 | else 274 | { 275 | Console.WriteLine("No processes found matching the specified criteria\n"); 276 | } 277 | } 278 | catch (Exception e) 279 | { 280 | Console.Error.WriteLine("[-] ERROR: {0}", e.Message.Trim()); 281 | } 282 | finally 283 | { 284 | Console.WriteLine("\nDONE"); 285 | } 286 | } 287 | } -------------------------------------------------------------------------------- /test_ad_creds.cs: -------------------------------------------------------------------------------- 1 | // Source 2 | // - https://stackoverflow.com/questions/8949501/why-does-active-directory-validate-last-password 3 | // - LDAP Result Codes - https://ldapwiki.com/wiki/LDAP%20Result%20Codes 4 | 5 | // To Compile: 6 | // C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /reference:"C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.DirectoryServices.Protocols\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.DirectoryServices.Protocols.dll" /t:exe /out:.\test\TestAdCreds.exe .\TestAdCreds.cs 7 | 8 | 9 | using System; 10 | using System.Net; 11 | using System.DirectoryServices.Protocols; 12 | 13 | class TestADCreds 14 | { 15 | public static void PrintUsage() 16 | { 17 | Console.WriteLine(@"Given an Active Directory domain, username, and password, returns whether the credentials are valid. Can optionally specify a specific server with '/S'. Does not work on local accounts. 18 | 19 | USAGE: 20 | test_ad_creds.exe [/S ] [/?]"); 21 | } 22 | 23 | private const int ERROR_LOGON_FAILURE = 0x31; 24 | 25 | public static void Main(string[] args) 26 | { 27 | try 28 | { 29 | string domain = ""; 30 | string username = ""; 31 | string password = ""; 32 | string server = ""; 33 | string arg; 34 | int argCount = 0; 35 | 36 | // Parse arguments 37 | for (int i = 0; i < args.Length; i++) 38 | { 39 | arg = args[i]; 40 | 41 | switch (arg.ToUpper()) 42 | { 43 | case "-S": 44 | case "/S": 45 | i++; 46 | 47 | try 48 | { 49 | server = args[i].Trim(new Char[] { '\\', ' ' }); 50 | } 51 | catch (IndexOutOfRangeException) 52 | { 53 | throw new ArgumentException("No server specified"); 54 | } 55 | break; 56 | case "/?": 57 | PrintUsage(); 58 | return; 59 | default: 60 | // Handle positional arguments 61 | switch (argCount) 62 | { 63 | case 0: 64 | domain = arg; 65 | break; 66 | case 1: 67 | username = arg; 68 | break; 69 | case 2: 70 | password = arg; 71 | break; 72 | } 73 | argCount++; 74 | break; 75 | } 76 | } 77 | 78 | // Print help and abort if domain, username, or password are missing 79 | if (string.IsNullOrEmpty(domain) || string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password)) 80 | { 81 | PrintUsage(); 82 | return; 83 | } 84 | 85 | // Use the domain as the server if one is not specified 86 | if (string.IsNullOrEmpty(server)) 87 | { 88 | server = domain; 89 | } 90 | 91 | NetworkCredential credentials = new NetworkCredential(username, password, domain); 92 | LdapDirectoryIdentifier id = new LdapDirectoryIdentifier(server); 93 | 94 | // Automatically negotiates the best authentication type 95 | using (LdapConnection connection = new LdapConnection(id, credentials)) 96 | { 97 | try 98 | { 99 | connection.Bind(); 100 | } 101 | catch (LdapException e) 102 | { 103 | if (e.ErrorCode == ERROR_LOGON_FAILURE) 104 | { 105 | Console.WriteLine("Invalid"); 106 | return; 107 | } 108 | 109 | throw new Exception(String.Format("LDAP Error ({0}): {1}", e.ErrorCode.ToString("X"), e.Message)); 110 | } 111 | } 112 | 113 | Console.WriteLine("Valid"); 114 | } 115 | catch (Exception e) 116 | { 117 | Console.Error.WriteLine("[-] ERROR: {0}", e.Message.Trim()); 118 | } 119 | finally 120 | { 121 | Console.WriteLine("\nDONE"); 122 | } 123 | } 124 | } -------------------------------------------------------------------------------- /window_list.cs: -------------------------------------------------------------------------------- 1 | // A C# implementation of: 2 | // Get-Process | Where-Object {$_.MainWindowTitle -ne ""} | Select-Object MainWindowTitle 3 | 4 | 5 | // To Compile: 6 | // C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:exe /out:window_list.exe window_list.cs 7 | 8 | 9 | using System; 10 | using System.Diagnostics; 11 | using System.Collections.Generic; 12 | 13 | class WindowList 14 | { 15 | public static void PrintUsage() 16 | { 17 | Console.WriteLine(@"Displays a list of visible windows and their associated process 18 | 19 | USAGE: 20 | window_list.exe [/S ] [/?]"); 21 | } 22 | 23 | // Source: https://stackoverflow.com/questions/2776673/how-do-i-truncate-a-net-string 24 | private static string Truncate(string str, int maxLength) 25 | { 26 | if (string.IsNullOrEmpty(str)) return str; 27 | return str.Length <= maxLength ? str : str.Substring(0, maxLength - 3) + "..."; 28 | } 29 | 30 | private static void PrintDivider() 31 | { 32 | Console.WriteLine("\n" + new String('=', 78)); 33 | } 34 | 35 | private static void PrintHeader() 36 | { 37 | Console.WriteLine("\nProc ID Process Name Window Title"); 38 | Console.WriteLine("------- ------------ ------------"); 39 | } 40 | 41 | private static void PrintProcesses(List procs) 42 | { 43 | string line = ""; 44 | 45 | foreach (Process proc in procs) 46 | { 47 | line = proc.Id.ToString().PadRight(11, ' '); 48 | try 49 | { 50 | // Display the executable name 51 | line += Truncate(proc.MainModule.ModuleName, 30).PadRight(34, ' '); 52 | } 53 | catch 54 | { 55 | // Sometimes MainModule fails with "Access Denied", fall back to ProcessName 56 | line += Truncate(proc.ProcessName, 30).PadRight(34, ' '); 57 | } 58 | line += proc.MainWindowTitle; 59 | 60 | Console.WriteLine(line); 61 | } 62 | } 63 | 64 | public static void Main(string[] args) 65 | { 66 | try 67 | { 68 | string system = "."; 69 | 70 | // Parse arguments 71 | for (int i = 0; i < args.Length; i++) 72 | { 73 | string arg = args[i]; 74 | 75 | switch (arg.ToUpper()) 76 | { 77 | case "-S": 78 | case "/S": 79 | i++; 80 | 81 | try 82 | { 83 | system = args[i].Trim(new Char[] { '\\', ' ' }); 84 | } 85 | catch (IndexOutOfRangeException) 86 | { 87 | throw new ArgumentException("No system specified"); 88 | } 89 | break; 90 | case "/?": 91 | PrintUsage(); 92 | return; 93 | } 94 | } 95 | 96 | if (system != ".") 97 | { 98 | Console.WriteLine("Listing windows on: " + system + "\n"); 99 | } 100 | 101 | int session; 102 | IDictionary> process_map = new SortedDictionary>(); 103 | 104 | // Group processes in a dictionary by session ID 105 | // TODO: Test against remote system 106 | foreach (Process proc in Process.GetProcesses(system)) 107 | { 108 | if (proc.MainWindowTitle == "") 109 | { 110 | continue; 111 | } 112 | 113 | session = proc.SessionId; 114 | 115 | if (!process_map.ContainsKey(session)) 116 | { 117 | process_map[session] = new List(); 118 | } 119 | 120 | process_map[session].Add(proc); 121 | } 122 | 123 | PrintDivider(); 124 | 125 | foreach (KeyValuePair> kvp in process_map) 126 | { 127 | Console.WriteLine("Session ID: " + kvp.Key); 128 | PrintHeader(); 129 | PrintProcesses(kvp.Value); 130 | PrintDivider(); 131 | } 132 | } 133 | catch (Exception e) 134 | { 135 | Console.Error.WriteLine("[-] ERROR: {0}", e.Message.Trim()); 136 | } 137 | finally 138 | { 139 | Console.WriteLine("\nDONE"); 140 | } 141 | } 142 | } -------------------------------------------------------------------------------- /wmi_query.cs: -------------------------------------------------------------------------------- 1 | // Source: https://docs.microsoft.com/en-us/dotnet/api/system.environment.getcommandlineargs?view=net-5.0 2 | // Source: https://social.msdn.microsoft.com/Forums/vstudio/en-US/9c28a7b0-9ee1-425e-8aa0-afeac329a983/list-of-installed-devices-and-drivers-using-cnet?forum=csharpgeneral 3 | // Source: https://docs.microsoft.com/en-us/dotnet/api/system.management.managementobjectsearcher.scope?view=dotnet-plat-ext-6.0#system-management-managementobjectsearcher-scope 4 | 5 | 6 | // To Compile: 7 | // C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /t:exe /out:wmi_query.exe wmi_query.cs 8 | 9 | 10 | using System; 11 | using System.Collections.Generic; 12 | using System.IO; 13 | using System.Management; 14 | 15 | public class WMIQuery 16 | { 17 | private static void WriteOutput(string outputFilepath, List output) 18 | { 19 | if (outputFilepath != "") 20 | { 21 | Console.WriteLine("[*] Writing output to: {0}", outputFilepath); 22 | System.IO.File.WriteAllLines(outputFilepath, output.ToArray()); 23 | } 24 | else 25 | { 26 | foreach (string line in output) 27 | { 28 | Console.WriteLine(line); 29 | } 30 | } 31 | } 32 | 33 | private static void PrintUsage() 34 | { 35 | Console.WriteLine(@"Executes the specified WMI query; optionally writes output to a file 36 | 37 | USAGE: 38 | wmi_query.exe [/S [/U [domain\]username /P password]] [-N ] [/O ] [/V] 39 | 40 | /V Verbose; print all properties, including empty ones 41 | 42 | 43 | Examples: 44 | wmi_query.exe 'Select * from win32_process' 45 | 46 | wmi_query.exe -S DC01.MGMT.LOCAL -N root\standardcimv2 'Select * from MSFT_NetTCPConnection' 47 | 48 | wmi_query.exe -S DC01.MGMT.LOCAL -U MGMT\Administrator -P password -N root\standardcimv2 'Select * from MSFT_NetTCPConnection'"); 49 | } 50 | 51 | public static void Main() 52 | { 53 | try 54 | { 55 | string outputFilepath = ""; 56 | string query = ""; 57 | string namespace_path = @"root\cimv2"; 58 | string system = "."; 59 | string username = ""; 60 | string password = ""; 61 | bool verbose = false; 62 | List output = new List(); 63 | 64 | // Parse arguments 65 | string[] args = Environment.GetCommandLineArgs(); 66 | 67 | for (int i = 1; i < args.Length; i++) 68 | { 69 | string arg = args[i]; 70 | 71 | switch (arg.ToUpper()) 72 | { 73 | case "-N": 74 | case "/N": 75 | i++; 76 | 77 | try 78 | { 79 | namespace_path = args[i]; 80 | } 81 | catch (IndexOutOfRangeException) 82 | { 83 | throw new ArgumentException("No namespace specified"); 84 | } 85 | break; 86 | case "-O": 87 | case "/O": 88 | i++; 89 | 90 | try 91 | { 92 | outputFilepath = args[i]; 93 | 94 | if (File.Exists(outputFilepath)) 95 | { 96 | throw new Exception("Output file already exists"); 97 | } 98 | } 99 | catch (IndexOutOfRangeException) 100 | { 101 | throw new ArgumentException("No output file specified"); 102 | } 103 | break; 104 | case "-S": 105 | case "/S": 106 | i++; 107 | try 108 | { 109 | system = args[i].Trim(new Char[] { '\\', ' ' }); 110 | } 111 | catch (IndexOutOfRangeException) 112 | { 113 | throw new ArgumentException("No system specified"); 114 | } 115 | break; 116 | case "-U": 117 | case "/U": 118 | i++; 119 | try 120 | { 121 | username = args[i]; 122 | } 123 | catch (IndexOutOfRangeException) 124 | { 125 | throw new ArgumentException("No username specified"); 126 | } 127 | 128 | break; 129 | case "-P": 130 | case "/P": 131 | i++; 132 | try 133 | { 134 | password = args[i]; 135 | } 136 | catch (IndexOutOfRangeException) 137 | { 138 | throw new ArgumentException("No password specified"); 139 | } 140 | break; 141 | case "-V": 142 | case "/V": 143 | verbose = true; 144 | break; 145 | case "/?": 146 | PrintUsage(); 147 | return; 148 | default: 149 | query = args[i]; 150 | break; 151 | } 152 | } 153 | 154 | if (query == "") 155 | { 156 | PrintUsage(); 157 | return; 158 | } 159 | 160 | ConnectionOptions conn_opts = new ConnectionOptions(); 161 | 162 | // Apply username and password if specified 163 | if (username.Length > 0 && password.Length > 0) 164 | { 165 | conn_opts.Username = username; 166 | conn_opts.Password = password; 167 | } 168 | else if (username.Length > 0 || password.Length > 0) 169 | { 170 | // Throw an exception if username or password were specified, but not both 171 | throw new ArgumentException("Please specify username and password"); 172 | } 173 | 174 | ManagementPath path = new ManagementPath() { NamespacePath = namespace_path, Server = system }; 175 | ManagementScope scope = new ManagementScope(path, conn_opts); 176 | ManagementObjectSearcher searcher = new ManagementObjectSearcher(query); 177 | searcher.Scope = scope; 178 | 179 | foreach (ManagementObject obj in searcher.Get()) 180 | { 181 | foreach (PropertyData prop in obj.Properties) 182 | { 183 | if (verbose) 184 | { 185 | output.Add(String.Format("{0}: {1}", prop.Name, prop.Value)); 186 | } 187 | else if (prop.Value != null && !String.IsNullOrEmpty(prop.Value.ToString())) 188 | { 189 | output.Add(String.Format("{0}: {1}", prop.Name, prop.Value)); 190 | } 191 | } 192 | 193 | // Add empty string to create a new line between property groups 194 | output.Add(""); 195 | } 196 | 197 | WriteOutput(outputFilepath, output); 198 | } 199 | catch (Exception e) 200 | { 201 | Console.Error.WriteLine("[-] ERROR: {0}", e.Message.Trim()); 202 | } 203 | finally 204 | { 205 | Console.WriteLine("\nDONE"); 206 | } 207 | } 208 | } --------------------------------------------------------------------------------