Creating a Nix Workflow to Fuzz netconsd

Michael Lynch

用 Nix 打造模糊測試 netconsd 的工作流程

原文由 Michael Lynch 發布,訂閱此部落格

最近睡不著的時候,我就會找一些軟體來做模糊測試。

本週稍早,我想起了 Fady Othman 的文章「Meta Bug Bounty — Fuzzing ’netconsd’ for fun and profit」。這是一篇關於如何徹底對程式碼進行模糊測試的不錯教學。

跟大多數關於模糊測試的部落格文章一樣,我覺得要重現他的成果有點困難,因為讀者得自己想辦法複製作者的環境與工具鏈。

我想試著用 Nix 做一個容易重現的 Othman 模糊測試器版本,就像我對 xpdf 做的那樣。我那篇關於 xpdf 的文章要完整、精緻得多。這裡只是給有興趣的人看的一些快速筆記。

fuzz-netconsd

這是我花了幾個小時為 netconsd 建立的模糊測試工作流程:

如果你已經安裝了 git 和 Nix,可以用以下指令來執行我的工作流程:

nix run gitlab:mtlynch/fuzz-netconsd

這是我寫的第一個模糊測試器,它的模糊測試工具是直接透過函式呼叫來呼叫受測程式碼,而不是透過 shell 去執行編譯好的二進位檔。在 honggfuzz 和 AFL++ 中,這被稱為「persistent mode」(持久模式),我想是因為模糊測試器可以讓同一個處理程序持續執行,而不需要為每一次模糊測試都產生一個新的處理程序。

透過函式呼叫來做模糊測試很有趣,因為即使目標程式碼根本沒有發布共享函式庫,你也能做到。我是在工作流程的 installPhase 階段這麼做的,做法是把包含我想呼叫的程式碼的 .o 檔和對應的 .h 標頭檔複製到該步驟的 Nix 輸出目錄中。

有了需要的標頭檔和目的檔之後,我寫了這個簡單的測試框架,裡面只有剛好足夠呼叫我要進行模糊測試的函式 ncrx_process 的程式碼:

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include "ncrx.h"

int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
  // Convert the random bytes of the payload to a null-terminated string.
  char *payload = (char *)malloc(len + 1);
  if (!payload) return 0;
  memcpy(payload, buf, len);
  payload[len] = '\0';

  struct timespec ts;
  if (clock_gettime(CLOCK_MONOTONIC, &ts)) {
    perror("clock_gettime");
    return 1;
  }

  uint64_t now = ts.tv_sec * 1000 + ts.tv_nsec / 1000000;

  struct ncrx *ncrx = ncrx_create(NULL);

  // Call the function that we're fuzzing.
  ncrx_process(payload, now, 0, ncrx);

  // Clean up the resources we allocated.
  ncrx_destroy(ncrx);
  free(payload);

  return 0;
}

我發現持久模式的模糊測試比我想像中簡單。我甚至不需要對 netconsd 有太多了解。我到現在還是不太清楚它確切是做什麼的,但已經足夠讓我能在模糊測試器底下呼叫它的其中一個解析函式了。

我大概不會有什麼發現

Othman 回報說他的模糊測試達到了 100% 涵蓋率,做得非常徹底。

我查看了 netconsd 的提交紀錄,自從 Othman 的研究之後,幾乎沒有什麼動靜。他在文章裡沒有明說,但我懷疑這個異動就是修掉了 Othman 發現的漏洞:

我懷疑在這個階段再做模糊測試也找不到什麼東西。我在跑了 12 小時都沒有當機後,就把模糊測試器停掉了。

未完成的工作

  • Othman 使用了 klee 工具來為模糊測試語料庫產生邊界案例的輸入。我沒有實作這部分,但它很適合放進工作流程中,因為 klee 已經有 Nix 套件了
  • 我用的是 honggfuzz,而不是 Othman 用的 AFL++。我偏好 honggfuzz 的簡潔,但 Othman 對 AFL++ 的各種參數夠了解,能取得更高的涵蓋率。
    • 我的初版實作用的是 AFL++,如果你想玩玩那個版本的話。

本文章由 muse-spark-1.2-contributor 進行翻譯

留言