Posted on

『Black Hat Rust』 読書メモ

cover

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

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 日本語版

800

  • Arc is safe to share across threads.
  • +mutable = Arc<Mutex<T>>

Chapter 6: Multi-threaded attack surface discovery

software used to map attack surfaces is called "scanners"

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を待つ)みたいな
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;

スクレイピングツールをつくる

書くかぁ…って言って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 の脆弱性

  • Python でexploitコード書いた

CVE-2021-3156

$ 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

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

#![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)]

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

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

.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();
}

~/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: 被害者コンピュータから攻撃者のコンピュータに対してシェルを提供する仕組みのこと

  • シェルコード書いてみた - Qiita

  • syscall dup2: fdをコピーする

  • syscall connect

  • yew(ユー): イチイ(植物)

13 Phising with WebAssembly

13.1

  • 説得の3原則: アリストテレスが弁護論で記した

    • ロゴス: 理論立てて説明
    • パトス: 熱く語って説得
    • エトス: 信頼してもらって説得
  • neocortex: 大脳新皮質

  • hypothalamus: 視床下部

14. A modern RAT

  • Remote Access Tool (ex. TeamViewer)
      1. dropper (alias: stager, downloader) をダウンロード
      1. RATをダウンロード
    • でウイルス検知を免れる

14.1 Architecture of a RAT

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

Optimization Level

Chapter 15 Securing communications with end-to-end encryption

15.1 The C.I.A triad

  • cyber worldはadversarial and unpardonable.

  • confidentiality

  • integrity

  • availability

15.3.1 Primitives and protocols

  • primitives: 部品
    • ex. SHA3
  • protocols: 合わせたもの
    • ex. TLS, Signal = (Curve25519, AES-256, HMAC-SHA256)
    • ex. WhatsAppは Signal 使っている

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

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, outputXChaCha20-Poly1305
      • stream cipher ChaCha20 と MAC Poly1305 を組み合わせたもの
      • X は extended nonce
  • 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

single_instance - Rust

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

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

実行ファイルとかを分割してメモリ上で完結させて証拠をのこさない

Macros