WebAssembly Binary Analizinde WABT

WebAssembly binary dosyaları PE veya ELF değildir ama tamamen opak da değildir. WABT ile section, import/export, opcode ve control-flow yapısı metinsel WAT gösterimine çevrilerek incelenebilir.

Bir .wasm dosyasını ilk kez hex editor'da açtığınızda PE alışkanlıkları pek işe yaramaz. DOS header yoktur, section table farklıdır, native instruction adreslerini takip edemezsiniz. Buna rağmen dosya opak değildir; format oldukça yapılandırılmıştır.

Tersine mühendislikte PE, ELF ve ham binary inceleme alışkanlığının en değerli tarafı araç isimlerini değil, katmanları ayırmayı öğretmesidir. WebAssembly için de aynı yaklaşım geçerli: önce container yapısı, sonra import/export sözleşmesi, sonra instruction akışı.

WABT bu iş için küçük ve doğrudan bir araç seti sunuyor.

WASM native executable değildir

WebAssembly stack tabanlı bir virtual instruction set kullanır. Binary modül runtime tarafından validate edilir ve engine'e göre interpreter, baseline JIT veya optimizing JIT üzerinden çalıştırılabilir.

Bu yüzden native reverse engineering'deki file offset -> virtual address -> machine instruction eşleştirmesi doğrudan yapılamaz.

WASM'da önce function index, type index, section ve structured control-flow kavramları anlaşılmalıdır. Native code daha sonra runtime tarafından üretilir.

Magic ve version

WASM binary \0asm magic değeriyle başlar. Ardından format version gelir.

Bundan sonrası section tabanlıdır.

Temel section türleri Type, Import, Function, Table, Memory, Global, Export, Start, Element, Code ve Data'dır. Custom section'lar da bulunabilir. Name section debug/isim bilgisini taşıyabilir.

Bu yapı adli analiz açısından değerlidir. Binary çalıştırılmadan önce hangi fonksiyonları import ettiği ve neleri export ettiği görülebilir.

wasm-objdump ilk bakış aracıdır

WABT içindeki wasm-objdump, native dünyadaki objdump mantığına yakın bir inceleme sunar.

Örneğin wasm-objdump -x module.wasm section ve metadata görünümünü çıkarabilir. Disassembly için wasm-objdump -d module.wasm kullanılabilir.

Ben bilinmeyen binary'de doğrudan tam decompilation'a geçmek yerine önce bu seviyede inventory çıkarmayı daha güvenli buluyorum. Import edilen host fonksiyonları çoğu zaman modülün yetenekleri hakkında kodun tamamından daha hızlı bilgi verir.

wasm2wat neden yararlı?

wasm2wat, binary representation'ı WebAssembly Text Format'a çevirir.

WAT yüksek seviyeli kaynak kod değildir. Decompiler çıktısı da değildir. Fakat instruction dizisini ve structured blocks'u okunabilir hale getirir.

Örneğin binary içindeki function şu yapıya dönüşebilir:

(func (param i32) (result i32)
  local.get 0
  i32.const 1
  i32.add)

Bu temsil stack davranışını takip etmeyi kolaylaştırır.

Değişken isimleri kaybolmuş olabilir; debug/name section varsa bazı isimler korunabilir. Optimized build'de semantic bilgi doğal olarak azalır.

Structured control flow

x86 assembly'de arbitrary branch target alışıldık bir şeydir. WebAssembly'de control flow block, loop, if, br gibi structured yapılara dayanır.

br çoğu zaman absolute address'e değil nesting depth'e göre hedef belirler.

Bu özellik validation'ı kolaylaştırır fakat reverse engineering sırasında zihinsel modeli değiştirir.

Control-flow graph üretirken native address bazlı algoritmayı doğrudan taşımak yerine block nesting çözülmelidir.

Import tablosu saldırı yüzeyini gösterir

WASM sandbox modeli modülün host ile hiç konuşmadığı anlamına gelmez. Yetkinlikler imports üzerinden sağlanır.

Browser ortamında JavaScript glue code, WASI ortamında system interface çağrıları önemlidir.

Bir modülü incelerken hangi memory'nin import/export edildiği, host function isimleri, WASI kullanımı, filesystem/network capability, indirect call table ve start function öncelikle incelenmelidir.

Bu inventory dynamic analysis planını da belirler.

Custom section'lar atlanmamalı

Custom section formatın genişletilebilir alanıdır.

Name, debug veya toolchain metadata'sı burada bulunabilir. Bazı build'lerde source map veya DWARF bilgisi ayrıca büyük miktarda bağlam sağlayabilir.

Tersine mühendislikte "çalışma için gerekli değil" diye custom section'ı atmak delil kaybetmek olabilir.

Adli kopya üzerinde section'ların hash ve offset bilgisini ayrıca tutmak karşılaştırma açısından faydalıdır.

Validation güvenlik analizi değildir

WABT wasm-validate ile binary'nin format ve WebAssembly kurallarına uyup uymadığını kontrol edebilir.

Geçerli bir modül güvenli bir modül demek değildir.

Validation type-safety ve format bütünlüğü gibi kuralları kontrol eder. Business logic, kötü niyetli algoritma, kaynak tüketimi veya host API'nin yanlış kullanımı ayrı problemdir.

PE dosyasının loader tarafından kabul edilmesi nasıl zararsız olduğunu göstermiyorsa WASM validation da aynı sınırlamaya sahiptir.

wasm2c ilginç bir köprü

WABT içindeki wasm2c, WASM modülünü C temsilimine çevirebilir.

Bu çıktı orijinal kaynak kod değildir. Yine de statik analiz araçlarının C üzerinde çalıştırılması, instrumentation veya algoritmik davranışın anlaşılması için yararlı bir ara temsil olabilir.

Özellikle kendi analiz araç zinciriniz native code odaklıysa bu köprü pratik değer taşır.

Dynamic analysis katmanı

Static WAT incelemesinden sonra runtime instrumentation gerekir.

Browser modülünde JavaScript glue code'u atlamamak önemlidir. Çünkü network, DOM ve storage erişiminin önemli kısmı WASM içinde değil host tarafında gerçekleşebilir.

WASI modülünde ise preopened directory ve runtime capability'leri incelenmelidir.

Yani analiz WASM binary + host imports + runtime configuration + external resources birlikte değerlendirilerek yapılır.

Araç zincirini küçük tutmak

WABT'nin benim hoşuma giden tarafı tek bir büyük decompiler olmaması. Her araç belirli bir soruya cevap veriyor: wasm-objdump yapı için, wasm2wat instruction akışı için, wasm-validate format için, wasm-interp kontrollü yürütme için, wasm2c ise C tabanlı analiz hattına aktarım için.

Bu parçalı yaklaşım adli ve tersine mühendislik süreçlerine daha iyi oturuyor. Çünkü her dönüşümün ne yaptığı ve hangi bilgiyi kaybettiği açık.

WebAssembly yeni bir binary format olsa da temel disiplin değişmiyor: önce formatı doğrula, metadata'yı çıkar, kontrol akışını çöz, dış bağımlılıkları belirle ve ancak sonra davranış hakkında hüküm ver.

Kaynakça

Bu sayfanın QR kodu