"red team wuz here"./etc/sudoers.d/.| Tab | Name | Contents |
|---|---|---|
| 1 | Dashboard | Owner per server. 🟢/🔴 status. Flags captured. Blockers. |
| 2 | Server 1 — Redis | IP, user, all accounts, ports, hashes, actual service discovered, patch status |
| 3 | Server 2 — Node | IP, user, accounts, ports, .js file paths, actual service, patch status |
| 4 | Server 3 — FTP | IP, user, accounts, ports, config file path, daemon version, patch status |
| 5 | Server 4 — SMB | IP, user, accounts, sudoers.d findings, share names, patch status |
| 6 | Config Backups | Paste raw text of smb.conf, redis.conf, vsftpd.conf, /etc/passwd — immediately at game start |
| 7 | IOC Tracker | Suspicious files, new users, crontab entries, modified lines, encoded strings found |
| 8 | CTF Notes | Flag hunting progress, encoded strings, hash values, stego findings, cracked passwords |
# Run on your Kali workstation before competition starts mkdir -p ~/targets/{s1_redis,s2_node,s3_ftp,s4_smb}/backups mkdir -p ~/tools ~/flags ~/analysis ~/hashes ~/stego # Verify cracking tools exist on Kali which john hashcat steghide binwalk strings xxd base64 file which scp ssh nmap 2>/dev/null # Pre-paste LinPEAS into a file before competition nano ~/tools/linpeas.sh chmod +x ~/tools/linpeas.sh
# Generate keys (do this before 12pm) ssh-keygen -t ed25519 -N "" -f ~/.ssh/id_ed25519 ssh-keygen -t rsa -b 2048 -N "" -f ~/.ssh/id_rsa_legacy # === AT GAME START — push keys to each target === # Replace USER and TARGET_IP with actual values from briefing ssh-copy-id -i ~/.ssh/id_ed25519 USER@TARGET_IP # If ed25519 rejected (older SSH daemon): ssh-copy-id -i ~/.ssh/id_rsa_legacy USER@TARGET_IP # After key push, SSH in without password: ssh USER@TARGET_IP # Add to ~/.ssh/config for shorthand (optional) # Host s1 # HostName TARGET_IP # User USER # IdentityFile ~/.ssh/id_ed25519
SSH in → run these → dump to Google Sheet Tab for that server:
# Paste this entire block on each target server:
echo "=== IP ===" && (ip a 2>/dev/null || ifconfig)
echo "=== USERS ===" && cat /etc/passwd
echo "=== SUDO ===" && getent group sudo
echo "=== UID0 ===" && awk -F: '$3==0{print $1}' /etc/passwd
echo "=== PORTS ===" && (ss -tulpn 2>/dev/null || netstat -tulpn)
echo "=== SERVICES ===" && (systemctl list-units --type=service \
--state=running 2>/dev/null || service --status-all 2>/dev/null)
echo "=== CRONTAB ===" && crontab -l 2>/dev/null; cat /etc/crontab 2>/dev/null
echo "=== AUTH_KEYS ===" && find /home /root -name "authorized_keys" \
-exec cat {} + 2>/dev/null
echo "=== OS VERSION ===" && cat /etc/os-release 2>/dev/null || uname -a
# === From Kali, SSH in and run: === # Layer 1a: Find any flag.txt files find / -name "flag*.txt" -o -name "*.flag" -o -name "flag" \ -type f 2>/dev/null | xargs cat 2>/dev/null # Layer 1b: Grep for SKY- format across all readable paths grep -r "SKY-" /var/www /home /etc /tmp /opt /root /srv 2>/dev/null # Layer 1c: Broader grep across entire filesystem grep -rnw '/' -e 'SKY-' 2>/dev/null | head -50 # Layer 1d: Check if Red Team already overwrote them grep -rnw '/' -e 'red team wuz here' 2>/dev/null # Layer 1e: Check environment variables (flags sometimes loaded here) env | grep -i "SKY\|flag\|ctf" cat /proc/1/environ 2>/dev/null | tr '\0' '\n' | grep -i "flag\|SKY"
If Layer 1 finds nothing or flags are overwritten — escalate here before giving up.
# === PULL suspicious files to Kali for analysis === # (See SCP Ref section for full syntax) # Layer 2a: Check for base64-encoded flags find / -name "flag*" -o -name "*.enc" -o -name "*.b64" \ 2>/dev/null | xargs cat 2>/dev/null | base64 -d 2>/dev/null | strings # On Kali — decode any suspicious base64 string: echo "SGVsbG8gV29ybGQ=" | base64 -d # Layer 2b: Search for base64 patterns in all text files grep -rE "[A-Za-z0-9+/]{20,}={0,2}" /var/www /home /etc /tmp 2>/dev/null \ | grep -v "\.pyc\|\.so\|Binary" # Layer 2c: strings on any compiled/binary files in web dirs # On target — find candidates: find /var/www /opt /home -type f ! -name "*.js" ! -name "*.py" \ ! -name "*.txt" ! -name "*.conf" 2>/dev/null # Pull to Kali and run strings: # scp user@TARGET_IP:/path/to/binary ~/analysis/ strings ~/analysis/binary | grep -i "SKY-\|flag\|password" # Layer 2d: Check databases for flag values # Redis (if accessible): redis-cli KEYS '*flag*' 2>/dev/null redis-cli KEYS '*' 2>/dev/null | xargs -I{} redis-cli GET {} # SQLite: find / -name "*.db" -o -name "*.sqlite" 2>/dev/null sqlite3 /path/to/db.sqlite ".tables" 2>/dev/null sqlite3 /path/to/db.sqlite "SELECT * FROM flags;" 2>/dev/null # Layer 2e: Check image/media files for steganography # Find images on target: find /var/www /home /opt -name "*.jpg" -o -name "*.png" \ -o -name "*.bmp" 2>/dev/null # Pull to Kali, run steghide and binwalk (see CTF Depth section)
# === On target server (via SSH) === mkdir -p ~/safe_backups cp -a /etc/passwd ~/safe_backups/ 2>/dev/null cp -a /etc/shadow ~/safe_backups/ 2>/dev/null cp -a /etc/sudoers ~/safe_backups/ 2>/dev/null cp -a /etc/sudoers.d ~/safe_backups/ 2>/dev/null cp -a /etc/crontab ~/safe_backups/ 2>/dev/null cp -a /etc/ssh/sshd_config ~/safe_backups/ 2>/dev/null cp -a ~/.ssh/authorized_keys ~/safe_backups/ 2>/dev/null # Service-specific configs (grab whatever exists) for f in /etc/redis/redis.conf /etc/samba/smb.conf \ /etc/vsftpd.conf /etc/proftpd/proftpd.conf \ /etc/nginx/nginx.conf /etc/apache2/apache2.conf \ /etc/mysql/mysql.conf.d/mysqld.cnf \ /etc/postgresql/*/main/postgresql.conf; do [ -f "$f" ] && cp -a "$f" ~/safe_backups/ && echo "Backed up: $f" done
# From your Kali terminal — pull all backups FROM target # Full syntax: scp user@IP:/remote/path ~/local/path scp -r USER@TARGET_IP:~/safe_backups/ \ ~/targets/s1_redis/backups/ # Pull individual critical files: scp USER@TARGET_IP:/etc/passwd ~/targets/s1_redis/backups/ scp USER@TARGET_IP:/etc/shadow ~/targets/s1_redis/backups/ scp USER@TARGET_IP:/etc/sudoers ~/targets/s1_redis/backups/
# All UID 0 accounts (should only be root) awk -F: '$3 == 0 {print $1}' /etc/passwd # Users with valid login shells (attack surface) awk -F: '$7 !~ /(nologin|false|sync|halt|shutdown)/ {print $1, $7}' /etc/passwd # Sudo group getent group sudo 2>/dev/null || grep "^sudo:" /etc/group # All sudoers.d entries ls -la /etc/sudoers.d/ && cat /etc/sudoers.d/* 2>/dev/null # Backdoor SSH keys find /home /root -name "authorized_keys" -exec echo "=== {} ===" \; \ -exec cat {} \; 2>/dev/null # Recent account creation (high UID = recently added) awk -F: '{print $1, $3}' /etc/passwd | sort -t' ' -k2 -n | tail -10
# DISABLE (not delete) — preserves hash for rollback sudo usermod -L <unauthorized_user> sudo usermod -s /usr/sbin/nologin <unauthorized_user> # Remove rogue sudoers file sudo rm /etc/sudoers.d/<rogue_file> # Clean authorized_keys — compare to backup, remove rogue key lines diff ~/safe_backups/authorized_keys ~/.ssh/authorized_keys nano ~/.ssh/authorized_keys # Immutable lock on critical files AFTER hardening is complete sudo chattr +i /etc/passwd /etc/shadow /etc/sudoers sudo chattr +i /etc/ssh/sshd_config # Undo if you need to make further changes: chattr -i /etc/passwd
# Lock account via passwd command (works on very old systems) sudo passwd -l <username> sudo passwd -u <username> # unlock # If chattr not available, restrict with permissions instead sudo chmod 444 /etc/passwd sudo chmod 000 /etc/shadow
## CHANGE ROOT AND USER PASSWORDS ## sudo passwd root sudo passwd <your_assigned_user> ## VERIFY sky_scorebot is untouched ## id sky_scorebot grep sky_scorebot /etc/passwd # Confirm account is active and NOT locked sudo passwd -S sky_scorebot
# View sudoers safely sudo cat /etc/sudoers ls -la /etc/sudoers.d/ && cat /etc/sudoers.d/* # Remove rogue entry sudo rm /etc/sudoers.d/<rogue_entry> # Validate sudoers syntax before closing sudo visudo --check 2>/dev/null || sudo visudo -c # Lock sudoers directory sudo chmod 750 /etc/sudoers.d/
# If usermod not found: sudo passwd -l <user> # lock password sudo passwd -u <user> # unlock sudo chsh -s /bin/false <user> # deny shell # If getent not available: grep "^sudo:" /etc/group grep "^wheel:" /etc/group # some distros use wheel for sudo # If visudo not available, edit directly (risky): sudo nano /etc/sudoers # careful — syntax error = lockout # Find who can run sudo via config search: grep -r "ALL" /etc/sudoers /etc/sudoers.d/ 2>/dev/null
# From Kali — push LinPEAS to target scp ~/tools/linpeas.sh USER@TARGET_IP:/tmp/linpeas.sh # On target (via SSH): chmod +x /tmp/linpeas.sh /tmp/linpeas.sh 2>/dev/null | tee /tmp/scan.txt # Review with color less -R /tmp/scan.txt
# Pull LinPEAS output back to Kali for review
scp USER@TARGET_IP:/tmp/scan.txt \
~/targets/s1_redis/scan_results.txt
less -R ~/targets/s1_redis/scan_results.txt
# Quick LinPEAS grep for high-value findings
grep -iE "sudo|suid|writable|crontab|\
passwd|key|password|token|secret|flag" \
/tmp/scan.txt | head -60
# View current rules sudo iptables -L -v -n --line-numbers # Allow established connections first (do this before adding restrictions) sudo iptables -I INPUT 1 -m state --state ESTABLISHED,RELATED -j ACCEPT # Whitelist scoring server (get IP from network diagram / briefing) sudo iptables -I INPUT 2 -s <SCORING_IP> -j ACCEPT # Restrict Redis to localhost only sudo iptables -A INPUT -p tcp --dport 6379 -s 127.0.0.1 -j ACCEPT sudo iptables -A INPUT -p tcp --dport 6379 -j DROP # Rate-limit SSH brute force (does NOT block scorebot) sudo iptables -A INPUT -p tcp --dport 22 \ -m limit --limit 5/min --limit-burst 10 -j ACCEPT # Save rules sudo iptables-save | sudo tee /etc/iptables/rules.v4 # Legacy save method (older Debian/Ubuntu): sudo sh -c 'iptables-save > /etc/iptables.rules'
# Start new tmux session on Kali tmux new-session -s defense # Split layout: Ctrl+B % (vertical) | Ctrl+B " (horizontal) # Move panes: Ctrl+B arrow # ── PANE 1: Network connections on target ── ssh USER@TARGET_IP "watch -n 2 'ss -tulpn 2>/dev/null || netstat -tulpn'" # ── PANE 2: Sudo group + UID0 watch ── ssh USER@TARGET_IP "watch -n 10 'getent group sudo 2>/dev/null \ || grep sudo /etc/group; \ echo ---; awk -F: \$3==0 /etc/passwd'" # ── PANE 3: Auth log tail ── ssh USER@TARGET_IP "sudo tail -f /var/log/auth.log 2>/dev/null \ || sudo tail -f /var/log/secure 2>/dev/null" # ── PANE 4: Recent file modifications ── ssh USER@TARGET_IP "watch -n 30 'find / -type f -mmin -5 \ ! -path /proc/\* ! -path /sys/\* ! -path /run/\* 2>/dev/null'"
# === Files modified in last 10 minutes === find / -type f -mmin -10 \ ! -path "/proc/*" ! -path "/sys/*" \ ! -path "/run/*" ! -path "/var/log/*" 2>/dev/null # === Red Team IOC string === grep -rnw '/' -e 'red team wuz here' 2>/dev/null # === New SUID binaries === find / -perm /4000 -type f 2>/dev/null | sort # === Unexpected crontab === crontab -l 2>/dev/null; sudo crontab -l 2>/dev/null ls /etc/cron.d/ /etc/cron.daily/ 2>/dev/null # === Live diff config against Kali backup (run from Kali) === ssh USER@TARGET_IP "cat /etc/passwd" | \ diff - ~/targets/s1_redis/backups/passwd # === Suspicious listening ports (exclude known good) === ss -tulpn 2>/dev/null | grep -vE ":22|:21|:80|:443|:445|:6379|:3000|127.0.0" # === Packet capture on target (if Wireshark unavailable) === sudo tcpdump -i any port 80 -nn -A -c 200 2>/dev/null
# Lock critical system files sudo chattr +i /etc/passwd /etc/shadow /etc/sudoers sudo chattr +i /etc/ssh/sshd_config # Lock service configs (after patching each server) for f in /etc/redis/redis.conf /etc/samba/smb.conf \ /etc/vsftpd.conf /etc/proftpd/proftpd.conf; do [ -f "$f" ] && sudo chattr +i "$f" && echo "Locked: $f" done # Verify immutable flags: lsattr /etc/passwd /etc/shadow /etc/sudoers /etc/ssh/sshd_config # Unlock (when you need to make changes): sudo chattr -i /etc/passwd
# Use permissions instead of immutable flag sudo chmod 444 /etc/passwd # read-only for all sudo chmod 400 /etc/shadow # root read-only # To restore: chmod 644 /etc/passwd; chmod 640 /etc/shadow
# === Full service fingerprint — run on each target ===
echo "=== OS ===" && cat /etc/os-release 2>/dev/null || uname -a
echo "=== LISTENING PORTS ===" && (ss -tulpn 2>/dev/null || netstat -tulpn)
echo "=== ALL SERVICES ===" && \
(systemctl list-units --type=service --state=running 2>/dev/null \
|| service --status-all 2>&1 \
|| ls /etc/init.d/)
echo "=== INSTALLED PACKAGES (Debian/Ubuntu) ===" && \
dpkg -l | grep -E "redis|ftp|samba|smb|nginx|apache|mysql|postgres|node|express" 2>/dev/null
echo "=== INSTALLED PACKAGES (RHEL/CentOS) ===" && \
rpm -qa 2>/dev/null | grep -E "redis|ftp|samba|http|mysql|node" 2>/dev/null
echo "=== PROCESS LIST ===" && ps aux | grep -v "^USER\|grep" | sort -k3 -rn | head -30
echo "=== CONFIG FILE HUNT ===" && \
find /etc -name "*.conf" -type f 2>/dev/null | head -40
If the service running isn't what the PIR described, use this pivot table to find the right remediation approach.
| If You See... | Port | Instead Of... | Pivot Action |
|---|---|---|---|
| PostgreSQL / MySQL | 5432 / 3306 | Redis 6379 | Check for no-auth, default creds, world-readable data dirs. See DB pivot card below. |
| Apache / Nginx | 80/443 | Node.js 3000 | Check .htaccess, php files for exec/system, CGI scripts. Check /var/www for flags. |
| NFS | 2049 | SMB 445 | Check /etc/exports for no_root_squash, world-readable exports. Lock down permissions. |
| SFTP / SCP only | 22 | FTP 21 | Audit SSH config for PermitRootLogin, AllowUsers. Check chroot jail configs. |
| Memcached | 11211 | Redis 6379 | Bind to 127.0.0.1 only. No auth by default — firewall at the port. |
| MongoDB | 27017 | Redis 6379 | Enable auth, bind to localhost. Check /etc/mongod.conf for security.authorization. |
| PHP / Python / Ruby app | varies | Node.js | Hunt for eval(), exec(), shell_exec(), system() calls. Check framework version for known CVEs. |
| Telnet | 23 | SSH 22 | Credentials sent plaintext. Disable if possible: sudo systemctl stop telnet or inetd entry. |
| SNMP | 161 | — | Check community string (default "public"). Change or firewall if not needed by scorebot. |
=== MySQL / MariaDB === # Test no-auth login (root with no password) mysql -u root 2>/dev/null mysql -u root -p'' 2>/dev/null # Fix: set root password sudo mysqladmin -u root password 'StrongPass2024' # Or in MySQL: ALTER USER 'root'@'localhost' IDENTIFIED BY 'StrongPass2024'; # Hunt for flags in DB: mysql -u root -p -e "SHOW DATABASES;" 2>/dev/null mysql -u root -p -e "SELECT * FROM flags;" DB_NAME 2>/dev/null === PostgreSQL === sudo -u postgres psql -c "\l" 2>/dev/null sudo -u postgres psql -c "SELECT * FROM flags;" 2>/dev/null # Bind PostgreSQL to localhost: grep "listen_addresses" /etc/postgresql/*/main/postgresql.conf # Set: listen_addresses = 'localhost'
=== Apache pivot === find /var/www /srv/www -type f 2>/dev/null | head -30 # Hunt for command injection in PHP: grep -rn "exec\|shell_exec\|system\|passthru\|eval\|\`" \ /var/www/ 2>/dev/null | grep "\.php" # Disable directory listing: grep -r "Options.*Indexes" /etc/apache2/ 2>/dev/null # Remove "Indexes" from Options line === Nginx pivot === cat /etc/nginx/sites-enabled/* 2>/dev/null # Check for proxy_pass to internal services === Check for web shell drops (Red Team IOC): find /var/www -name "*.php" -newer /etc/passwd 2>/dev/null grep -rn "base64_decode\|gzinflate\|str_rot13" /var/www/ 2>/dev/null
If LinPEAS doesn't immediately surface the vuln and the PIR doesn't match — systematic triage:
# 1. World-writable files in sensitive locations find /etc /var/www /opt /srv -type f -perm -o+w 2>/dev/null # 2. World-writable directories find /etc /var/www /opt /srv -type d -perm -o+w 2>/dev/null # 3. Files owned by nobody/unknown users find / -nouser -o -nogroup 2>/dev/null | head -20 # 4. Services running as root that shouldn't be ps aux | awk '$1=="root" && $11!~/sshd|cron|init|kernel/' | head -20 # 5. SUID/SGID binaries not in typical list find / -perm /6000 -type f 2>/dev/null | \ grep -vE "ping|sudo|su|passwd|mount|newgrp|wall|write|chfn|chsh" # 6. Open ports with no obvious service name ss -tulpn 2>/dev/null | awk 'NR>1{print $5}' | sort -u # 7. Environment variables with secrets env && cat /proc/1/environ 2>/dev/null | tr '\0' '\n' # 8. Recently modified configs find /etc -name "*.conf" -mmin -60 2>/dev/null
2023: No auth, directory traversal, ACL ignored, Node.js config pointed here as a pivot entry.
# Find redis.conf (may not be /etc/redis/) find / -name "redis.conf" 2>/dev/null find / -name "redis*.conf" 2>/dev/null # Test: does Redis respond without auth? redis-cli PING # PONG without password = CRITICAL VULN. NOAUTH = already protected. # Check bind address grep "^bind" /etc/redis/redis.conf 2>/dev/null # Check requirepass grep "requirepass" /etc/redis/redis.conf 2>/dev/null # Check for ACL file grep "aclfile" /etc/redis/redis.conf 2>/dev/null # Dump all Redis keys (check for flag data) redis-cli KEYS '*' redis-cli KEYS '*flag*' | xargs -I{} redis-cli GET {} # Check Redis version (older = different config syntax) redis-cli INFO server | grep redis_version
# Edit redis.conf — add requirepass sudo nano /etc/redis/redis.conf # Find: # requirepass foobared # Change to (uncomment and set): requirepass StrongRedisPass2024 ## CRITICAL: Update Node.js connection BEFORE restarting Redis ## See Node tab — update Redis client config with new password first ## Otherwise you'll break the web service and lose scoring points # Restart Redis sudo systemctl restart redis 2>/dev/null || \ sudo service redis restart 2>/dev/null || \ sudo /etc/init.d/redis-server restart # Test auth required redis-cli PING # Expected: NOAUTH Authentication required redis-cli -a StrongRedisPass2024 PING # Expected: PONG
# Older Redis uses same requirepass but no ACL system # Also check for /etc/redis.conf vs /etc/redis/redis.conf find / -name "redis*.conf" 2>/dev/null # Apply requirepass in whichever file the running instance uses: redis-cli CONFIG GET requirepass redis-cli CONFIG SET requirepass "StrongPass2024" # Note: CONFIG SET is live but survives only until restart # Must edit the .conf file for persistence
# Bind Redis to localhost only sudo nano /etc/redis/redis.conf # Find: bind 0.0.0.0 OR bind 127.0.0.1 ::1 # Set to: bind 127.0.0.1 # If Node is on SAME machine: 127.0.0.1 only is correct # If Node is on DIFFERENT machine: bind 127.0.0.1 <NODE_SERVER_IP> # Disable dangerous commands (prevent directory traversal) # Add to redis.conf: rename-command CONFIG "" rename-command SLAVEOF "" rename-command DEBUG "" rename-command FLUSHALL "" rename-command FLUSHDB "" # Restart sudo systemctl restart redis 2>/dev/null || sudo service redis restart # Verify cannot connect from outside: # From Kali: redis-cli -h TARGET_IP -p 6379 PING # Expected: Could not connect / Connection refused
# Lock down file permissions sudo chown root:redis /etc/redis/redis.conf 2>/dev/null || \ sudo chown root:root /etc/redis/redis.conf sudo chmod 640 /etc/redis/redis.conf # Lock data directory find /var/lib/redis -type d -exec sudo chmod 750 {} \; 2>/dev/null sudo chown -R redis:redis /var/lib/redis/ 2>/dev/null # Immutable lock on config after hardening sudo chattr +i /etc/redis/redis.conf lsattr /etc/redis/redis.conf
# Full verification checklist echo "=== Service Status ===" && sudo systemctl status redis 2>/dev/null || \ sudo service redis status echo "=== Bind Address ===" && grep "^bind" /etc/redis/redis.conf echo "=== Auth ===" && grep "^requirepass" /etc/redis/redis.conf echo "=== Permissions ===" && ls -la /etc/redis/redis.conf echo "=== Immutable ===" && lsattr /etc/redis/redis.conf # Functional tests: redis-cli PING # Should: NOAUTH required redis-cli -a StrongRedisPass2024 PING # Should: PONG # From Kali (test external block): # redis-cli -h TARGET_IP PING — Should: Connection refused
# Quick identification ss -tulpn | grep -E "3306|5432|27017|11211|6379" ps aux | grep -E "mysql|postgres|mongo|memcache|redis" # MySQL/MariaDB — add root password sudo mysqladmin -u root password 'StrongPass2024' 2>/dev/null mysql -u root -e "UPDATE mysql.user SET \ authentication_string=PASSWORD('StrongPass2024') \ WHERE User='root'; FLUSH PRIVILEGES;" 2>/dev/null # Bind MySQL to localhost grep "bind-address" /etc/mysql/mysql.conf.d/mysqld.cnf 2>/dev/null # Set: bind-address = 127.0.0.1 sudo systemctl restart mysql 2>/dev/null || sudo service mysql restart
2023: Command injection backdoor (exec/eval), Redis pivot via connection config, directory traversal.
# === STEP 1: Find the application root === find /var/www /opt /home /srv -name "*.js" -type f 2>/dev/null | head -20 find /var/www /opt /home /srv -name "package.json" 2>/dev/null # === STEP 2: Hunt for command injection backdoors === grep -rn "require('child_process')\|require(\"child_process\")" \ /var/www/ /opt/ 2>/dev/null grep -rn "exec\|eval\|spawn\|execSync\|spawnSync" \ /var/www/ /opt/ 2>/dev/null | grep "\.js" # === STEP 3: Find Redis connection config === grep -rn "redis\|createClient\|6379\|REDIS" \ /var/www/ /opt/ 2>/dev/null | grep "\.js" # === STEP 4: Pull the app files to Kali for safe review ===
# Pull entire web app directory to Kali for analysis scp -r USER@TARGET_IP:/var/www/ ~/targets/s2_node/www_backup/ scp -r USER@TARGET_IP:/opt/ ~/targets/s2_node/opt_backup/ 2>/dev/null # Review locally on Kali with grep: grep -rn "exec\|eval\|spawn" ~/targets/s2_node/www_backup/ 2>/dev/null
# === STEP 5: Update Redis connection to use new password === # Find: redis.createClient() or createClient({host:'...'}) # Update to: # const client = redis.createClient({host:'127.0.0.1',password:'StrongRedisPass2024'}) # If using env variable: grep -rn "REDIS_URL\|REDIS_PASS\|REDIS_AUTH" /var/www/ /opt/ 2>/dev/null cat /etc/environment 2>/dev/null | grep -i redis # === STEP 6: Comment out backdoor exec/eval calls === # Do NOT delete the file — comment out the dangerous lines nano /path/to/app.js # add // before exec() lines # === STEP 7: Restart Node service === sudo systemctl restart node 2>/dev/null sudo pm2 restart all 2>/dev/null # Identify PID manually: ps aux | grep -E "node|npm" | grep -v grep # sudo kill -HUP <PID> — graceful restart # === STEP 8: Watch web logs for Red Team activity === sudo tail -f /var/log/nginx/access.log 2>/dev/null sudo tail -f /var/log/apache2/access.log 2>/dev/null # Older systems: /var/log/httpd/access_log
exec()/shell_exec()/system() in .php files or Python subprocess calls. Same principle — find the injection point and neutralize it. Check the Pivot Table in Recon section.2023: Anonymous read/write enabled. Red Team created multiple logins and uploaded arbitrary files.
# Which FTP daemon is running? systemctl status vsftpd proftpd 2>/dev/null ps aux | grep -E "vsftpd|proftpd|ftpd|pure-ftpd" ss -tulpn | grep :21 # Find the config file find /etc -name "vsftpd.conf" -o -name "proftpd.conf" \ -o -name "pure-ftpd.conf" 2>/dev/null # Check for anonymous login vulnerability: ftp localhost <<'EOF' anonymous anonymous@ ls bye EOF # If you get a file listing = VULN # Check FTP directories for Red Team file drops find /var/ftp /srv/ftp /home/ftp -type f 2>/dev/null ls -laR /var/ftp/ 2>/dev/null
=== vsftpd (/etc/vsftpd.conf) === sudo nano /etc/vsftpd.conf # Critical settings: anonymous_enable=NO # DISABLE anonymous login anon_upload_enable=NO # No anonymous uploads anon_mkdir_write_enable=NO # No anonymous dir creation local_enable=YES # Allow system user logins write_enable=YES # Authenticated users can write chroot_local_user=YES # Jail users to their home dir allow_writeable_chroot=YES # May need for chroot to work # Restart vsftpd sudo systemctl restart vsftpd 2>/dev/null || \ sudo service vsftpd restart 2>/dev/null || \ sudo /etc/init.d/vsftpd restart # Immutable lock sudo chattr +i /etc/vsftpd.conf
=== ProFTPD (/etc/proftpd/proftpd.conf) === sudo nano /etc/proftpd/proftpd.conf # Find the <Anonymous> block and add DenyAll: <Anonymous ~ftp> DenyAll </Anonymous> # OR remove the entire <Anonymous> block # Also set: DefaultRoot ~ # Chroot to home dir RootLogin off # No root FTP login # Restart sudo systemctl restart proftpd 2>/dev/null || \ sudo service proftpd restart 2>/dev/null || \ sudo /etc/init.d/proftpd restart sudo chattr +i /etc/proftpd/proftpd.conf
# Pure-FTPd config is split into files under /etc/pure-ftpd/conf/ ls /etc/pure-ftpd/conf/ # Disable anon: echo "no" > /etc/pure-ftpd/conf/NoAnonymous echo "yes" > /etc/pure-ftpd/conf/ChrootEveryone sudo service pure-ftpd restart
# Verify anon login is disabled ftp localhost <<'EOF' anonymous anonymous@ bye EOF # Expected: 530 Login incorrect / Permission denied # Verify service is up (scorebot needs port 21) ss -tulpn | grep :21 sudo systemctl status vsftpd 2>/dev/null || sudo service vsftpd status # Check FTP directories are clean (no Red Team files) find /var/ftp /srv/ftp /home/ftp -type f 2>/dev/null | xargs ls -la # Remove any unexpected files placed by Red Team
2023: World-writable shares (arbitrary file injection), rogue sudoer in /etc/sudoers.d/.
# === STEP 1: Find and audit smb.conf === find / -name "smb.conf" 2>/dev/null # Usually: /etc/samba/smb.conf # Show all configured shares: testparm -s 2>/dev/null || grep -A5 "\[" /etc/samba/smb.conf # === STEP 2: Fix each share — make read-only === sudo nano /etc/samba/smb.conf # For each [share_name] section: writable = no # or: read only = yes public = no guest ok = no browseable = no # hide from network browsers valid users = <your_user> sky_scorebot # whitelist only # === STEP 3: Audit sudoers.d — CRITICAL === ls -la /etc/sudoers.d/ cat /etc/sudoers.d/* # Remove any file not created by your team: sudo rm /etc/sudoers.d/<rogue_file> # === STEP 4: Check for Red Team file drops in shares === find /var/lib/samba /home /srv -type f -newer /etc/samba/smb.conf 2>/dev/null # === STEP 5: Restart Samba === sudo systemctl restart smbd nmbd 2>/dev/null || \ sudo service smbd restart 2>/dev/null || \ sudo /etc/init.d/samba restart # === STEP 6: Lock config === sudo chattr +i /etc/samba/smb.conf # === ONGOING — run every 5 min (King of the Hill) === watch -n 30 'ls -la /etc/sudoers.d/; echo "---"; getent group sudo'
# Older Samba uses "writable" but restart command differs sudo /etc/init.d/samba restart # old-style init # OR: stop individual daemons sudo killall -HUP smbd nmbd # Verify version: smbd --version
# === Identify any suspicious file — run on Kali after SCP pull === # 'file' command ignores extension and reads magic bytes file suspicious_file file ~/analysis/* # Check for hidden data appended to a file xxd suspicious_file | head -50 # hex dump top xxd suspicious_file | tail -50 # hex dump bottom (hidden data often appended) # Strings — extract all printable strings from any file type strings suspicious_file | grep -i "SKY-\|flag\|pass\|key\|secret" strings -n 8 suspicious_file # strings of 8+ chars # Check if a file is actually a different type (e.g., image with wrong extension) file image.jpg # might return "data" or "ZIP archive" binwalk suspicious_file # scan for embedded files and signatures
=== Base64 === echo "U0tZLUFCQ0QtMTIzNA==" | base64 -d # Decode a file: base64 -d encoded_file.txt # Find base64 patterns in files: grep -rE "[A-Za-z0-9+/]{24,}={0,2}" \ /var/www /home /etc 2>/dev/null | head -20 === Hex / URL encoding === # Decode hex string: echo "534b592d41424344" | xxd -r -p # URL decode (Python on Kali): python3 -c "import urllib.parse; \ print(urllib.parse.unquote('SKY%2DABCD%2D1234'))" === ROT13 === echo "FXL-NOPQ-1234" | tr 'A-Za-z' 'N-ZA-Mn-za-m' === XOR (common CTF encoding) === python3 -c " data=open('encoded_file','rb').read() key=0x41 # guess common XOR keys: 0x41, 0xFF, 0x13 print(''.join(chr(b^key) for b in data if 32<=(b^key)<127))"
=== steghide (JPEG/BMP) — on Kali === # Pull image from target first: # scp USER@TARGET_IP:/path/image.jpg ~/stego/ steghide info image.jpg # check for embedded data steghide extract -sf image.jpg # extract (prompts for passphrase) steghide extract -sf image.jpg -p "" # try empty passphrase steghide extract -sf image.jpg -p "password" -f === binwalk — extract embedded files === binwalk image.jpg # show embedded file signatures binwalk -e image.jpg # extract embedded files binwalk --dd='.*' image.jpg # extract everything === strings on images === strings image.jpg | grep -i "SKY-\|flag" === exiftool (metadata) === exiftool image.jpg | grep -i "comment\|description\|flag\|SKY" === zsteg (PNG LSB steganography) === zsteg image.png 2>/dev/null zsteg -a image.png 2>/dev/null # all modes
# From Kali — pull shadow file scp USER@TARGET_IP:/etc/shadow ~/hashes/shadow_s1 scp USER@TARGET_IP:/etc/passwd ~/hashes/passwd_s1 # Combine for John The Ripper: unshadow ~/hashes/passwd_s1 ~/hashes/shadow_s1 > ~/hashes/combined_s1.txt === John The Ripper === # Quick run with default wordlist: john ~/hashes/combined_s1.txt # With rockyou wordlist (most effective): john --wordlist=/usr/share/wordlists/rockyou.txt ~/hashes/combined_s1.txt # Rules-based mangling (catches password1, Password!, etc): john --wordlist=/usr/share/wordlists/rockyou.txt \ --rules ~/hashes/combined_s1.txt # Show cracked passwords: john --show ~/hashes/combined_s1.txt === Hashcat (faster with GPU) === # Identify hash type from shadow file: # $1$ = MD5, $5$ = SHA-256, $6$ = SHA-512, $y$ = yescrypt hashcat -m 1800 ~/hashes/shadow_s1 /usr/share/wordlists/rockyou.txt # SHA-512 hashcat -m 500 ~/hashes/shadow_s1 /usr/share/wordlists/rockyou.txt # MD5 hashcat -m 7400 ~/hashes/shadow_s1 /usr/share/wordlists/rockyou.txt # SHA-256 # Attack modes: hashcat -a 0 # dictionary hashcat -a 3 # brute force: hashcat -a 3 hash ?u?l?l?l?d?d hashcat -a 6 # wordlist + mask # Show results: hashcat --show ~/hashes/shadow_s1
| Prefix in shadow | Hash Type | Hashcat -m | john format |
|---|---|---|---|
$1$ | MD5 crypt | 500 | md5crypt |
$5$ | SHA-256 crypt | 7400 | sha256crypt |
$6$ | SHA-512 crypt | 1800 | sha512crypt |
$y$ | yescrypt | — (john only) | auto |
$2b$ | bcrypt | 3200 | bcrypt |
$apr1$ | Apache MD5 | 1600 | md5crypt-long |
| plain 32 hex chars | MD5 | 0 | raw-md5 |
| plain 40 hex chars | SHA-1 | 100 | raw-sha1 |
| plain 64 hex chars | SHA-256 | 1400 | raw-sha256 |
=== Redis === redis-cli -a <pass> KEYS '*' redis-cli -a <pass> KEYS '*flag*' redis-cli -a <pass> KEYS '*' | xargs -I{} redis-cli -a <pass> GET {} === SQLite (pull to Kali first) === find / -name "*.db" -o -name "*.sqlite" -o -name "*.sqlite3" 2>/dev/null
scp USER@TARGET_IP:/path/to/app.db ~/analysis/ # On Kali: sqlite3 ~/analysis/app.db ".tables" sqlite3 ~/analysis/app.db ".dump" | grep -i "SKY-\|flag\|password" sqlite3 ~/analysis/app.db "SELECT * FROM users;" === MySQL — query on target === mysql -u root -p -e "SHOW DATABASES;" 2>/dev/null mysql -u root -p -e "USE app; SHOW TABLES; SELECT * FROM flags;" 2>/dev/null === PostgreSQL === sudo -u postgres psql -c "\l" sudo -u postgres psql -c "SELECT * FROM flags;" app 2>/dev/null
| Modern Command | Legacy / Fallback | Notes |
|---|---|---|
ss -tulpn | netstat -tulpn | Install net-tools if missing: apt install net-tools (if internet available) |
ip a | ifconfig | ifconfig is in net-tools package |
ip route | route -n | Also: netstat -rn |
systemctl status X | service X status or /etc/init.d/X status | Check ls /etc/init.d/ for available services |
systemctl restart X | service X restart or /etc/init.d/X restart | Some need full stop + start |
journalctl -xe | tail /var/log/syslog or /var/log/messages | Auth logs: /var/log/auth.log or /var/log/secure |
chattr +i | chmod 444 file | Immutable flag not available on all FS — chmod is the fallback |
lsattr | Try touch file 2>&1 | If touch fails with "Operation not permitted" = immutable |
getent group sudo | grep "^sudo:" /etc/group | Also check wheel group: grep "^wheel:" /etc/group |
usermod -L | passwd -l <user> | Both lock the account; passwd -l is more universal |
visudo --check | visudo -c | If both fail, grep sudoers manually |
find -mmin | find -newer /tmp/ref | Create reference file: touch -t 202406121200 /tmp/ref |
lsof -i :PORT | netstat -tlnp | grep PORT | Or: fuser PORT/tcp |
watch -n 2 'cmd' | while true; do clear; cmd; sleep 2; done | watch may not be installed on minimal systems |
tmux | screen | screen is almost universally installed; use Ctrl+A % to split |
redis-cli | Telnet: telnet localhost 6379 then type PING | Older systems may not have redis-cli in PATH — check /usr/bin/redis-cli |
iptables-save | sh -c 'iptables-save > /etc/iptables.rules' | On old Debian: /etc/network/if-pre-up.d/ script to restore |
smbclient / testparm | Read smb.conf directly + grep -E "writable|write|public|guest" | testparm may not be installed separately from samba |
# Quick OS and tool availability check — paste on any target
echo "=== OS ===" && cat /etc/os-release 2>/dev/null || \
cat /etc/redhat-release 2>/dev/null || uname -a
echo "=== Tool Availability ==="
for tool in ss netstat ip ifconfig systemctl service \
chattr lsattr getent usermod visudo \
tmux screen watch redis-cli; do
which $tool 2>/dev/null && echo " [OK] $tool" || echo " [MISSING] $tool"
done
echo "=== Init System ==="
[ -d /run/systemd/system ] && echo "systemd" || \
[ -f /sbin/upstart ] && echo "upstart" || echo "SysV init"
# Syntax: scp [options] USER@TARGET_IP:/remote/path ~/local/path # Pull single file: scp USER@TARGET_IP:/etc/passwd ~/targets/s1_redis/backups/passwd # Pull directory recursively: scp -r USER@TARGET_IP:~/safe_backups/ ~/targets/s1_redis/backups/ # Pull LinPEAS results: scp USER@TARGET_IP:/tmp/scan.txt ~/targets/s1_redis/scan.txt # Pull shadow file for cracking: scp USER@TARGET_IP:/etc/shadow ~/hashes/shadow_s1 # Pull suspicious image for stego analysis: scp USER@TARGET_IP:/var/www/images/logo.jpg ~/stego/logo_s2.jpg # Pull database file for analysis: scp USER@TARGET_IP:/var/lib/app/app.db ~/analysis/app_s2.db # Pull entire web app directory: scp -r USER@TARGET_IP:/var/www/ ~/targets/s2_node/www/ # Pull with specific SSH key: scp -i ~/.ssh/id_ed25519 USER@TARGET_IP:/etc/shadow ~/hashes/
# Syntax: scp [options] ~/local/path USER@TARGET_IP:/remote/path/ # Push LinPEAS to target: scp ~/tools/linpeas.sh USER@TARGET_IP:/tmp/linpeas.sh # Push custom script to target: scp ~/tools/baseline_snapshot.sh USER@TARGET_IP:/tmp/ # Push directory to target: scp -r ~/tools/ USER@TARGET_IP:/tmp/tools/ # Push a known-good config to restore from: scp ~/targets/s4_smb/backups/smb.conf USER@TARGET_IP:/etc/samba/smb.conf # Push with specific SSH key: scp -i ~/.ssh/id_ed25519 ~/tools/linpeas.sh USER@TARGET_IP:/tmp/
Use when SCP is blocked, SSH port is non-standard, or permissions prevent normal transfer.
Step 1 — On Kali (listener):
# Listen for incoming file nc -l -p 9001 > ~/analysis/received_file # For a directory (tar over nc): nc -l -p 9001 | tar xz -C ~/targets/s1_redis/
Step 2 — On Target (sender via SSH):
# Send file to Kali listener cat /etc/passwd | nc KALI_IP 9001 # Send directory as tar: tar czf - ~/safe_backups/ | nc KALI_IP 9001
#!/bin/bash
# baseline_snapshot.sh — paste and run on each target immediately at game start
echo "=== BASELINE: $(hostname) @ $(date) ==="
echo ""
echo "[IP]"
ip a 2>/dev/null || ifconfig 2>/dev/null
echo ""
echo "[USERS]"
cat /etc/passwd
echo ""
echo "[SHADOW - first chars only for hash ID]"
sudo awk -F: '{print $1, substr($2,1,4)}' /etc/shadow 2>/dev/null
echo ""
echo "[SUDO GROUP]"
getent group sudo 2>/dev/null || grep "^sudo:\|^wheel:" /etc/group
echo ""
echo "[UID 0 ACCOUNTS]"
awk -F: '$3 == 0 {print $1}' /etc/passwd
echo ""
echo "[PORTS]"
ss -tulpn 2>/dev/null || netstat -tulpn 2>/dev/null
echo ""
echo "[SERVICES]"
systemctl list-units --type=service --state=running 2>/dev/null \
|| service --status-all 2>/dev/null || ls /etc/init.d/
echo ""
echo "[CRONTAB]"
crontab -l 2>/dev/null; sudo crontab -l 2>/dev/null
cat /etc/crontab 2>/dev/null; ls /etc/cron.d/ 2>/dev/null
echo ""
echo "[AUTHORIZED KEYS]"
find /home /root -name "authorized_keys" -exec echo "FILE: {}" \; \
-exec cat {} \; 2>/dev/null
echo ""
echo "[SUDOERS.D]"
ls -la /etc/sudoers.d/ 2>/dev/null
cat /etc/sudoers.d/* 2>/dev/null
echo ""
echo "[CONFIGS FOUND]"
find /etc -name "*.conf" -type f 2>/dev/null | head -30
echo ""
echo "[FLAG HUNT]"
find / -name "flag*" -type f 2>/dev/null | xargs cat 2>/dev/null
grep -r "SKY-" /var/www /home /etc /tmp /opt /root 2>/dev/null
echo ""
echo "[OS VERSION]"
cat /etc/os-release 2>/dev/null || uname -a
echo ""
echo "[TOOL CHECK]"
for t in ss netstat ip ifconfig systemctl service chattr lsattr \
getent redis-cli tmux screen watch; do
which "$t" 2>/dev/null && echo " OK: $t" || echo " MISSING: $t"
done
echo "=== END BASELINE ==="
#!/bin/bash
# ioc_hunt.sh — find Red Team activity
echo "=== IOC HUNT @ $(date) ==="
echo ""
echo "[Red Team IOC String]"
grep -rnw '/' -e 'red team wuz here' 2>/dev/null
echo ""
echo "[Files Modified Last 15 min]"
find / -type f -mmin -15 \
! -path "/proc/*" ! -path "/sys/*" \
! -path "/run/*" ! -path "/var/log/*" \
! -path "/tmp/scan*" 2>/dev/null
echo ""
echo "[New SUID Binaries]"
find / -perm /4000 -type f 2>/dev/null | sort
echo ""
echo "[Unexpected Listening Ports]"
ss -tulpn 2>/dev/null || netstat -tulpn
echo ""
echo "[Unauthorized Sudoers]"
ls -la /etc/sudoers.d/ 2>/dev/null
cat /etc/sudoers.d/* 2>/dev/null
echo ""
echo "[UID 0 Check]"
awk -F: '$3 == 0 {print $1}' /etc/passwd
echo ""
echo "[Crontab Check]"
crontab -l 2>/dev/null; sudo crontab -l 2>/dev/null
cat /etc/cron.d/* 2>/dev/null
echo ""
echo "[World-Writable in Sensitive Dirs]"
find /etc /var/www /opt /home -type f -perm -o+w 2>/dev/null | head -20
echo ""
echo "[New User Accounts (UID >= 1000)]"
awk -F: '$3 >= 1000 && $3 != 65534 {print $1, $3}' /etc/passwd
#!/bin/bash
# diff_check.sh — Kali side. Usage: ./diff_check.sh USER TARGET_IP SERVER_NAME
# Example: ./diff_check.sh admin 10.0.0.5 s1_redis
USER="$1"; TARGET_IP="$2"; SERVER="$3"
BACKUP="$HOME/targets/$SERVER/backups"
echo "=== DIFF CHECK: $SERVER ($TARGET_IP) @ $(date) ==="
for file in passwd shadow sudoers sshd_config; do
[ -f "$BACKUP/$file" ] || continue
echo ""
echo "--- /etc/$file ---"
ssh "$USER@$TARGET_IP" "cat /etc/$file 2>/dev/null" | \
diff --color=always "$BACKUP/$file" - && \
echo " [OK] No changes" || \
echo " [!!] TAMPERING DETECTED"
done
echo "=== END DIFF ==="
#!/bin/bash
# ctf_hunt.sh — Run on Kali against pulled files
# Usage: ./ctf_hunt.sh ~/targets/s1_redis/
SEARCH_DIR="${1:-.}"
echo "=== CTF DEEP HUNT in $SEARCH_DIR ==="
echo ""
echo "[Plaintext SKY- flags]"
grep -r "SKY-" "$SEARCH_DIR" 2>/dev/null
echo ""
echo "[Base64-encoded strings (20+ chars)]"
grep -rEo "[A-Za-z0-9+/]{24,}={0,2}" "$SEARCH_DIR" 2>/dev/null | \
while read enc; do
dec=$(echo "$enc" | base64 -d 2>/dev/null)
echo "$dec" | grep -qi "SKY-\|flag" && echo " DECODED: $enc => $dec"
done
echo ""
echo "[Strings in binary files]"
find "$SEARCH_DIR" -type f ! -name "*.txt" ! -name "*.conf" ! -name "*.log" \
2>/dev/null | while read f; do
strings "$f" 2>/dev/null | grep -i "SKY-\|flag\|password\|secret" && \
echo " (in: $f)"
done
echo ""
echo "[Image files — run steghide manually on these]"
find "$SEARCH_DIR" -name "*.jpg" -o -name "*.png" \
-o -name "*.bmp" -o -name "*.gif" 2>/dev/null
echo ""
echo "[Database files — run sqlite3 manually on these]"
find "$SEARCH_DIR" -name "*.db" -o -name "*.sqlite" \
-o -name "*.sqlite3" 2>/dev/null
echo "=== END CTF HUNT ==="
| Category | Command | Purpose | Legacy Alt |
|---|---|---|---|
| Users | awk -F: '$3==0{print $1}' /etc/passwd | All root-level accounts | — |
| Users | getent group sudo | Sudo group members | grep ^sudo: /etc/group |
| Users | usermod -L <user> | Lock/disable account | passwd -l <user> |
| Users | usermod -s /usr/sbin/nologin <u> | Remove shell | chsh -s /bin/false <u> |
| Network | ss -tulpn | Listening ports + processes | netstat -tulpn |
| Network | lsof -i :<PORT> | What owns a port | fuser PORT/tcp |
| Network | ip a | Interface addresses | ifconfig |
| Network | tcpdump -i any port 80 -nn -A | Capture traffic (ASCII) | — |
| Files | find / -mmin -10 -type f ! -path "/proc/*" | Modified last 10 min | find / -newer /tmp/ref |
| Files | chattr +i <file> | Immutable lock | chmod 444 <file> |
| Files | lsattr <file> | Check immutable flag | Try touch file |
| Files | find / -perm /4000 -type f | All SUID binaries | — |
| Files | find / -type d -perm -o+w | World-writable dirs | — |
| Logs | tail -f /var/log/auth.log | Live auth attempts | tail -f /var/log/secure |
| Services | systemctl restart <svc> | Restart service | service <svc> restart |
| Services | systemctl status <svc> | Service health | service <svc> status |
| Firewall | iptables -L -v -n --line-numbers | All rules | — |
| Firewall | iptables-save | Export rules | — |
| IOC | grep -rnw '/' -e 'red team wuz here' | Red Team string | — |
| IOC | grep -r "SKY-" /var /home /etc /tmp | Flag search | — |
| CTF | strings file | grep -i SKY | Strings in binary | — |
| CTF | echo "..." | base64 -d | Decode base64 | — |
| CTF | file <filename> | Identify file type | — |
| CTF | xxd file | head -30 | Hex dump | hexdump -C file | head |
| CTF | binwalk file | Embedded files | — |
| CTF | steghide extract -sf img.jpg | Extract stego | — |
| Crack | unshadow passwd shadow > combined | Prep for John | — |
| Crack | john --wordlist=rockyou.txt combined | Dictionary crack | — |
| Crack | john --show combined | Show cracked | — |
| Crack | hashcat -m 1800 shadow rockyou.txt | SHA-512 crack | — |
| Redis | redis-cli PING | Test auth | telnet localhost 6379 |
| SMB | testparm /etc/samba/smb.conf | Validate config | grep -E "writable|public|guest" smb.conf |
| SCP Pull | scp USER@IP:/remote/path ~/local/ | Pull file from target | nc -l listener method |
| SCP Push | scp ~/local/file USER@IP:/remote/ | Push file to target | nc sender method |
# Preferred — ED25519 key ssh -i ~/.ssh/id_ed25519 USER@TARGET_IP # RSA fallback for older SSH daemon ssh -i ~/.ssh/id_rsa_legacy USER@TARGET_IP # Run command inline (no interactive shell) ssh USER@TARGET_IP "cat /etc/passwd" # Persistent multiplexed connection (faster repeated commands) ssh -o ControlMaster=auto \ -o ControlPath=~/.ssh/ctrl_%r@%h:%p \ -o ControlPersist=10m \ USER@TARGET_IP # Non-standard port: ssh -p 2222 USER@TARGET_IP
# Add to ~/.ssh/config on Kali for old hardware Host s1_legacy HostName TARGET_IP User USER IdentityFile ~/.ssh/id_rsa_legacy KexAlgorithms +diffie-hellman-group14-sha1,diffie-hellman-group1-sha1 Ciphers +aes128-cbc,aes256-cbc,3des-cbc HostKeyAlgorithms +ssh-rsa PubkeyAcceptedKeyTypes +ssh-rsa MACs +hmac-sha1,hmac-sha1-96,hmac-md5 StrictHostKeyChecking no # Then: ssh s1_legacy # And: scp ~/file s1_legacy:/tmp/
sudo nano /etc/ssh/sshd_config # Whitelist only necessary users: AllowUsers <your_user> sky_scorebot # No root password login: PermitRootLogin prohibit-password # Slow brute force: MaxAuthTries 3 LoginGraceTime 30 # Validate then restart (CRITICAL — test in new terminal first): sudo sshd -t && sudo systemctl restart sshd 2>/dev/null || \ sudo sshd -t && sudo service sshd restart # Lock config after hardening: sudo chattr +i /etc/ssh/sshd_config