『Black Hat Rust』 読書メモ
Rustでoffensive securityを実践する本として『Black Hat Rust』を読みました.
注意: 読みながら本文中で自分が知らなかった英単語, 知識をメモするので整理されてはいない.
公式ページ: Black Hat Rust
- 現在は $35程らしいです
公式GitHub repo: https://github.com/skerkour/black-hat-rust
5. Introduction
“Any sufficiently advanced cyberattack is indistinguishable from magic”, unknown
- plagued: 悩まされた
- unsolicited: 押し付けがましい
5.1 Types of attacks
pentest stands for "penetration testing" for security audits.
- phishing: フィッシング
- Reconnaissance: 偵察
- exploit (zero-day)
- exfiltration: 不正な転送
5.3.3 The Developer
The role of the developer is to build custom tools (credential dumpers, proxies...) and implants used during the attack. These are the skills we will learn and practice in the next chapters.
5.9 A SHA-1 hash cracker
- meticulous: 細心の注意
- RAII: Resource Acquisition Is Initialization.
Drop
trait だよ- メモリ解放 - Rust By Example 日本語版
Rust(に限らず?)あるあるはじまった
- Fail. Learn. Repeat.
- KISS: Keep It Simple, Stupid 原則のやつ
- コストの前払い
- imperative: 命令型
- lerning curveが穏やか
Lifetime Elision
- Elision: 脱落
smart-pointers for long-lived or shared? or mutable? references
Rc<Refcell<T>>
interior mutability pattern
RefCellと内部可変性パターン - The Rust Programming Language 日本語版
Arc
is safe to share across threads.- +mutable =
Arc<Mutex<T>>
Chapter 6: Multi-threaded attack surface discovery
-
OSINT
-
Assets discovery
- e.g. subdomains enumeration
software used to map attack surfaces is called "scanners"
-
error handling =
anyhow
+thiserror
-
subdomains enumerationやってみた -> 次回
-
GitHub - rayon-rs/rayon: Rayon: A data parallelism library for Rust
- 基本
par_iter()
するだけ
- 基本
-
Amass
Chapter7: Going full speed with async
- preemptive scheduring
- Go lang relies on it
- cooperative scheduling
7.4 Streams
- ex. Rx
Vec<Future<>> -> Future<Vec<>>
はfutures::future::try_join_all()
で
8.
log
crate は traitとかだけ提供でenv_logger
とかが実装, Javaとか同じくIFと実装が分かれている.
9. crawling the web for OSINT
- OSINTツールで有名なのは Maltego
- ブラックハットハッカー: 悪意を持ったハッカーのこと
- Google dorks: ちょっとしたクエリが使える
- github dorks:
気をつけよう
- Associated Types 関連型
- Atomic types
- Barrier
- golangの
sync.WaitGroup
(複数のgoroutineを待つ)みたいな
- golangの
let barrier = Arc::new(Barrier::new(3));
let b2 = barrier.clone()
tokio::spawn(async move {
// do things
b2.wait().await;
});
let b3 = barrier.clone()
tokio::spawn(async move {
// do things
b3.wait().await;
});
barrier.wait().await;
スクレイピングツールをつくる
- CVE security vulnerability database の情報をスクレイピングするツールを書くらしい
書くかぁ…って言ってLive Shareの画面見たらこれで笑った. スクレイピングするだけだし, お互いやる気が無さすぎたのでskip
- CWE: 脆弱性の分類
10. Finding vulnerabilities
10.9 XSS
- Reflected XSS: リクエスト時に
- Stored XSS: 良くないデータを保存
- DOM based XSS: 危険なHTMLを渡す
10.10 SSRF
10.11 CSRF
- benign: 良性
10.12 Open redirect
- 見るだけでアウトはないけど
10.13 (Sub) Domain takeover
URLが悪意のある人のものになっていた
10.14 Arbitrary file read
- directory traversal
11. Exploit development
extern C
内でのみ可変長引数かける
libc使ってみる
use std::ffi::CString;
fn main() {
unsafe {
let msg = CString::new("Hello").unwrap();
libc::write(1, msg.as_ptr() as *const _, 5);
}
}
strace ../target/debug/sandbox
execve("../target/debug/sandbox", ["../target/debug/sandbox"], 0x7fffae2c3b70 /* 33 vars */) = 0
brk(NULL) = 0x55f103b90000
...
write(1, "Hello", 5Hello) = 5
sigaltstack({ss_sp=NULL, ss_flags=SS_DISABLE, ss_size=8192}, NULL) = 0
munmap(0x7fd075480000, 12288) = 0
exit_group(0) = ?
+++ exited with 0 +++
CVE-11229
-
Gitリポジトリホスト gitea の脆弱性
- NVD - CVE-2019-11229
mirror-sync
時に任意コマンド実行できる
-
Python でexploitコード書いた
CVE-2021-3156
- script modeで
sudo
時の脆弱性
$ apt info sudo | grep Version
Version: 1.8.31-1ubuntu1.2
sudo
aptパッケージだったのか
https://github.com/sudo-project/sudo
https://github.com/sudo-project/sudo/releases/tag/SUDO_1_9_5p2
https://github.com/sudo-project/sudo/compare/SUDO_1_9_5p1...SUDO_1_9_5p2
https://github.com/sudo-project/sudo/commit/1f8638577d0c80a4ff864a2aad80a0d95488e9a8
-
exploit code
-
#todo Pythonのコード何やっているかわからなかった
- single backslash
\
でその後に null terminatorだと超えてしまいbuffer overflowする?
- single backslash
-
余談:
sudo vim
よりsudoedit
使ったほうが良い?
Writing shellcodes in Rust
echo '...' | xxd -r -p > hoge.bin
objdump -D -b binary -mi386 -Mx86-64 -Mintel hoge.bin
-m, --architecture=MACHINE
:Specify the target architecture as MACHINE
-M, --disassembler-options=OPT
: Pass text OPT on to the disassembler
0: 48 8d 35 14 00 00 00 lea rsi,[rip+0x14] # 0x1b
7: 6a 01 push 0x1
1b: 68 65 6c 6c 6f push 0x6f6c6c65
20: 20 77 6f and BYTE PTR [rdi+0x6f],dh
23: 72 6c jb 0x91
25: 64 fs
26: 0a .byte 0xa
- 実行可能ファイルはセクションに別れている
.text
: はプログラム,data
は文字列とか- ELF: Executable and Linkable Format
12.3 compile process
-
AST -> High-level IR -> Mid-level IR -> Type Info & MIR -(optimization, codegen)> Object files -(link)> binary
-
#![no_std]
: nightlyらしい -
Optimizations: The speed size tradeoff - The Embedded Rust Book
[profile.release] opt-level = "z"
#![no_std]
#![no_main]
#![feature(start)]
#[start]
fn start(_argc: isize, _argv: *const *const u8) -> isize {
0
}
#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
loop {}
}
#![feature(asm)]
write
はsyscall 4
0000000000401000 <_start>:
401000: 48 8d 35 f9 0f 00 00 lea 0xff9(%rip),%rsi # 402000 <_start+0x1000>
401007: b8 01 00 00 00 mov $0x1,%eax
40100c: bf 01 00 00 00 mov $0x1,%edi
401011: ba 0c 00 00 00 mov $0xc,%edx
401016: 0f 05 syscall
401018: c3 retq
$ readelf -h target/release/nostd
Entry point address: 0x401000
lea
ってなんだpushq
ってなんだ- #cheatsheet x64_cheatsheet.pdf
pushq $0x6f6c6c6 // olle
- disassembleがおかしかっただけだった
cargo +nightly rustc --release -- --emit asm
.text
.file "nostd.e2aa644f-cgu.0"
.section .text._start,"ax",@progbits
.globl _start
.p2align 4, 0x90
.type _start,@function
_start:
.cfi_startproc
leaq .L__unnamed_1(%rip), %rsi
movl $1, %eax
movl $1, %edi
movl $12, %edx
#APP
syscall
#NO_APP
retq
.Lfunc_end0:
.size _start, .Lfunc_end0-_start
.cfi_endproc
.section .text.rust_begin_unwind,"ax",@progbits
.hidden rust_begin_unwind
.globl rust_begin_unwind
.p2align 4, 0x90
.type rust_begin_unwind,@function
rust_begin_unwind:
.cfi_startproc
.p2align 4, 0x90
.LBB1_1:
jmp .LBB1_1
.Lfunc_end1:
.size rust_begin_unwind, .Lfunc_end1-rust_begin_unwind
.cfi_endproc
.section .text.rust_eh_personality,"ax",@progbits
.hidden rust_eh_personality
.globl rust_eh_personality
.p2align 4, 0x90
.type rust_eh_personality,@function
rust_eh_personality:
.cfi_startproc
retq
.Lfunc_end2:
.size rust_eh_personality, .Lfunc_end2-rust_eh_personality
.cfi_endproc
.type .L__unnamed_1,@object
.section .rodata..L__unnamed_1,"a",@progbits
.L__unnamed_1:
.ascii "hello world\n"
.size .L__unnamed_1, 12
.section ".note.GNU-stack","",@progbits
12.6 never type
!
: 到達しない型 ex.exit()
とかの戻り値
12.7 executing shellcodes
- memory の instruction を実行する方法は3つある
.text
section に埋め込むmmap
crate (mmap) を使う- mprotect を使う
12.7.1 Emvedding a shellcode in the .text
section
-
include_bytes!
macroを使う -
普通にやろうとすると
.rodata
section に追加されてしまうのでトリックをする -
.len()
が const fn なので -
const fn
- コンパイル時に評価されるやつ, C++でいう
constexpr
- 悪用するとこういうことが出来るやつ コンパイル中にコンパイルする「コンパイル時Cコンパイラ」をつくった話 - kw-udonの日記
- コンパイル時に評価されるやつ, C++でいう
.PHONY: shell
shell:
cd shell && cargo +nightly build --release
strip -s shell/target/release/shell
objcopy -O binary shell/target/release/shell shellcode.bin
use std::mem;
const SHELLCODE_BYTES: &[u8] = include_bytes!("../shellcode.bin");
const SHELLCODE_LENGTH: usize = SHELLCODE_BYTES.len();
#[no_mangle]
#[link_section = ".text"]
static SHELLCODE: [u8; SHELLCODE_LENGTH] = *include_bytes!("../shellcode.bin");
fn main() {
let exec_shellcode: extern "C" fn() -> ! =
unsafe { mem::transmute(&SHELLCODE as *const _ as *const ()) };
exec_shellcode();
}
-
mem::transmute
: 値を再解釈する- C++の
reinterpret_cast
ってこと?
- C++の
-
strip
command: シンボルテーブルとかを消す
~/D/g/i/b/executor ❯❯❯ hexyl shellcode.bin
│00000000│ 48 8d 35 13 00 00 00 6a ┊ 01 58 6a 0c 5a 48 89 c7 │H×5•000j┊•Xj_ZH××│
│00000010│ 0f 05 6a 3c 58 31 ff 0f ┊ 05 c3 68 65 6c 6c 6f 20 │••j<X1ו┊•×hello │
nm
: シンボルテーブルを見るコマンド
2000: 2f (bad)
2001: 62 (bad)
2002: 69 6e 2f 73 68 00 01 imul ebp,DWORD PTR [rsi+0x2f],0x1006873 // "/bin/sh"
12.11 Reverse TCP shellcode
-
TCPをlistenする(攻撃側)
-
revshellを実行する(される側)
-
nc -vnlp 1234
:-v
: verbose-n
: no resolve dns-l
: listen-p
: port
-
Reverse Shell: 被害者コンピュータから攻撃者のコンピュータに対してシェルを提供する仕組みのこと
-
syscall
dup2
: fdをコピーする -
syscall
connect
-
yew(ユー): イチイ(植物)
13 Phising with WebAssembly
13.1
-
説得の3原則: アリストテレスが弁護論で記した
- ロゴス: 理論立てて説明
- パトス: 熱く語って説得
- エトス: 信頼してもらって説得
-
neocortex: 大脳新皮質
-
hypothalamus: 視床下部
14. A modern RAT
- Remote Access Tool (ex. TeamViewer)
-
- dropper (alias: stager, downloader) をダウンロード
-
- RATをダウンロード
- でウイルス検知を免れる
-
14.1 Architecture of a RAT
- An agent (target の中に入れる
- A C&C (Command & Control server: C2) (agentとやりとり)
- ex. Turning Telegram toxic: ‘ToxicEye’ RAT is the latest to use Telegram for command & control - Check Point Software は Telegram(メッセージが暗号化されるSNS) をC&C channelとして利用
- client (C2とやりとり) に分かれている
14.2.3 DNS
DNSを介すのはブロックされるので厳しい
14.2.4 Peer-to-peer
no server super node: 一時的に選出され全てのノードがそこに接続する -> ここに指示を出す(with end 2 end encryption) ex. ZeroAccess, Zeus
14.2.5 Domain generatio algorithms
- 攻撃された時の C&Cの可用性を向上させる技術
- C&Cが停止した時にドメインを作って引っ越す(?)
14.5 Designing the server
プロトコルはHTTP使うのが現実的, 機能的
14.5.2 Real-time communications
- short polling
- websockets
- server-sent events (sse)
- long polling
rust web libraries
14.5.6.1 database access
- diesel
- tokio-postgres
- sqlx
14.6.1 choosing an HTTP library
- hyper
- reqwest
- awc
- ureq (recommended)
- surf
14.7 Docker for offensive security
- 軽量な仮想コンテナベース
- Dockerfileというようなレシピ
14.8 Let's code
git restore <path>
他のコミットからファイルを取り込める stagingされていないのをリセット
binを変える
[[bin]]
name = "cool-tool"
test = false
bench = false
sqlx
- #idea mvをundo出来るCLI
14.9 Optimizing Rust's binary size
- workspace の member 単位で
profile
を有効にする. release
ビルドで3
なのでz
は含まれている?
Optimization Level
- lto: オブジェクトファイルをまたいだバイナリサイズ最適化
Chapter 15 Securing communications with end-to-end encryption
-
fdehau/tui-rs: Build terminal user interfaces and dashboards using Rust
-
holy grail: 聖杯
-
bulletproof: 防弾にする
15.1 The C.I.A triad
-
cyber worldはadversarial and unpardonable.
-
confidentiality
-
integrity
-
availability
15.3.1 Primitives and protocols
- primitives: 部品
- ex.
SHA3
- ex.
- protocols: 合わせたもの
- ex.
TLS
,Signal
= (Curve25519
,AES-256
,HMAC-SHA256
) - ex. WhatsAppは
Signal
使っている
- ex.
15.6 Key derivation function
- 鍵導出関数 - Wikipedia
-
暗号理論でいう、鍵導出関数(かぎどうしゅつかんすう)は、パスワード、パスフレーズなどといった秘密の値を、あたかも「マスターキー」のごとく用い、pseudorandom function(PRF)を使って鍵を導出する関数である。
- ex.
Blake2b
SHA-3
の最終選考まで残ったハッシュ関数(64bit version)- BLAKE2s - Qiita
-
15.8 Authenticated encryption
- [[AEAD]]
15.9 Asymmetric encryption
- a.k.a 公開鍵暗号
- ps, sk のペアをkey pair
- 現実では鍵交換や署名と合わせて用いられる
15.10 Diffie-Hellman key exchange
- 今は楕円曲線DH ex.
X25519
が有名
15.11 Signatures
- 署名, ex.
ed25519
, $2^{255}-19$ から
15.12 End-to-end encryption
- サーバーは公開鍵を保持して, メッセージは復号せずただやりとりするだけ
Reality is quite different: public-key encryption is limited in the length of the messages it can encrypt and is painfully slow.
15.12.2 Hybrid encryption
- エフェメラル(儚い)
15.12.2 DH key exchange
- key ex + AEADだとskが漏れたらずっと見れてしまう
- これはPGPの仕組みなのでPGP良くない
15.12.4 Forward Secrecy
ばれる前の情報の秘匿を保証するprotocol
15.12.5 Signatures
15.12.6 E2E encryption
- identity keypair: 署名のため
- prekey: kex
15.20.1
- signature:
identity_keypairs
- encryption(AEAD): encrypt job, output
XChaCha20-Poly1305
- stream cipher
ChaCha20
と MACPoly1305
を組み合わせたもの X
は extended nonce
- stream cipher
- encryption(AEAD): encrypt job, output
- key exchange:
prekey
,ephemeral keys
X25519
- kdf
signature: Ed25519
encryption: XChaCha20Poly1305
key exchange: X25519
key derivation function: blake2b
zeroize
crate
(Rust) Zeroize memory - LayerX Research
kexで交換してchacha20で
client::register
identity_keypair
: 署名の為のkey pair を作り,
private_prekey
:
15.22 Some limitation
- Replay attacks: まるごと盗聴される -> どうしようもなさそう
- Agents- config is not encrypted
- Prekey rotations, prekey bundles
Chapter 16: Going multi-platforms
16.4 Cross-compilation
platform tierの話 Platform Support - The rustc book
cross
: 使うと簡単にcross compileが出来る
cross build --target x86_64-pc-windows-gnu
16.10.1
systemd
: linux で常駐化
windows: registry
macOS: launchd
17. Turing our RAT into a worm to increate reach
17.1 What is a worm
自身を含まれる
discord malware https://togetter.com/li/1845235
vmかどうか判別できるらしい, エミュ上でゲームやる話
17.2 Spreading techniques
- bruteforcing a networked service ex. SSH
~/.ssh/config
をstoleする
- exploit such as. RCE or XSS
17.6
- installerを作ろう
upx
でzipにbundleしよう- jaemk/self_update: Self updates for rust executables: autoupdate出来る
- UnityにSQLCipherを導入して暗号化DBを使う: SQLCipher, 暗号化出来るSQLiteらしい
17.9.4 Anti-Anti-Virus tric
- signature based detection: プログラムのハッシュを登録しておく
- shape analysis: 疑わしい文字列がうめこまれているか
- behaviour based: サンドボックスで実行して挙動を確かめる
17.9.5 Privileges escalation
exploitにはprivilegeが必要になるかもなのでexploitを使うといい
17.9.7 Anti-debugging tricks
プログラムを動的解析されるのを遅くする
17.9.9 Stagers
実行ファイルとかを分割してメモリ上で完結させて証拠をのこさない