automatic fuzz chromium from a easy way
2022-11-11 15:11:0 Author: paper.seebug.org(查看原文) 阅读量:27 收藏

作者:areuu
原文链接:https://mp.weixin.qq.com/s/UllCnLCF4XQIC5WxrZYJbQ

本文介绍一个简便的方法构建自动挖掘chromium 框架。主要的想法是自动去跑生成的testcase ,然后检测结果是否触发了ASAN,触发了的话自动邮件发送符号化的邮件。

单纯的挖chromium,看你怎么挖了,有些漏洞window.close() 再加上一些features 开关,配合用户操作就可以挖到一批,也有些poc 是直接是for 循环几个 js api,在event handler中来个postmessage 来detach 某内存,或者是gc 或者删除某个对象来释放对象。这poc 看起来构造也容易,想着如何fuzz 的话应该比较大概率可以通过fuzz 挖到。

首先需要个asan 编译的chromium 预编译文件,一般的可以从 https://alesandroortiz.com/articles/latest-chromium-asan-builds/ 来下载

或者通过查找chromium base position 然后通过gsutil 来下载

这里祭出本人使用的脚本query.sh

#!/usr/bin/env bash

BASE='https://omahaproxy.appspot.com/deps.json?version='
GSUTIL_LINUX='gsutil ls "gs://chromium-browser-asan/linux-release/asan-linux-release-'


if [ $# != 1 ]; then
  BASE_VERSION=`curl $BASE 2> /dev/null | jq -r ".chromium_version"`
  BASE_POSITION=`curl $BASE 2> /dev/null | jq -r ".chromium_base_position"`
  V8_VERSION=`curl $BASE$BASE_VERSION 2> /dev/null | jq -r ".v8_version"`
  echo "current stable version: $BASE_VERSION"
  echo "v8 version: $V8_VERSION"

#  show
  exit 1
fi


VERSION="$1"
DOWNLOAD_URL=$BASE$VERSION
BASE_POSITION=`curl $DOWNLOAD_URL 2> /dev/null | jq -r ".chromium_base_position"`
V8_VERSION=`curl $DOWNLOAD_URL 2> /dev/null | jq -r ".v8_version"`
echo ""
echo "chromium base position: $BASE_POSITION"

echo "v8 version: $V8_VERSION"

if [ "$2" = "win" ];
then
  echo "yes";
fi

ex:

➜  browser git:(master) query.sh 106.0.5249.119
chromium base position: 1036826
v8 version: 10.6.194.18
^C
➜  browser git:(master) gsutil ls "gs://chromium-browser-asan/linux-release/asan-linux-release-103682*.zip"
gs://chromium-browser-asan/linux-release/asan-linux-release-1036821.zip
gs://chromium-browser-asan/linux-release/asan-linux-release-1036825.zip
gs://chromium-browser-asan/linux-release/asan-linux-release-1036826.zip

之后cp 来下载

➜  browser git:(master) gsutil cp gs://chromium-browser-asan/win32-release_x64/asan-win32-release_x64-1036825.zip .

运行和检测ASAN 信息

asan chromium 在触发漏洞时会打印sanitize 信息来检测,将输出信息不断的进行检测sanitize 标头即可。

可以选择直接使用linux 脚本来跑,然后检测下返回码,最初也是这么跑的

...
export ASAN_OPTIONS=detect_leaks=0
export USE_ZEND_ALLOC=0

while true; do

  if [ $(ls $FUZZDIR/$NODE/ | wc -l) -eq 0 ]; then
    echo "Waiting for more tests..."
    sleep 2
    continue
  fi

  TEST=$(ls $FUZZDIR/$NODE/ | head -n1)

  echo -n "Testing $TEST: "

  OUTPUT=$(timeout -s SIGTERM $TIMEOUT $CHROMIUM/chrome --user-data-dir=$USERDIR --disable-gpu --headless --no-sandbox --js-flags='--expose_gc' --enable-blink-test-features --disable-popup-blocking --ignore-certificate-errors --enable-experimental-web-platform-features --enable-features=AutofillAddressProfileSavePrompt  $FUZZDIR/$NODE/$TEST 2>&1 | $MAIN_CHROMIUM/src/tools/valgrind/asan/asan_symbolize.py > $ASANLOG)
  RET=$?

  if [ $RET -ne 0 ]; then
  ...
    echo -e "\e[31;1mCRASH (ret:$RET)\e[0m"
    mv $FUZZDIR/$NODE/$TEST /mnt/fuzz/crashes/$TEST$(date)
    mv $ASANLOG /mnt/fuzz/crashes/$TEST$(date).asan.log
...

跑起来飞快,1秒可能跑1,2个吧

配合个某个generator,跑了一晚跑出了个asan,最后不出意外的还是出意外了:(

由于不满足测试速度,去寻找其他方案。一般的跑testcase 可以放在iframe 里面不断加载,像fuzz in sixty seconds 那样,也可以使用extensions 来不断开tab 来加载,或者在网页中open 个testcase ,然后关闭。

在github 上搜了一下mozila 开发了ffpuppet 来fuzz 他们的firefox,有现成的我就直接拿来用,这里做了一些修改,来适应chromium,同时添加一些自定义参数。

web server

这里选择使用了web server 来提供testcase ,通过访问一个url 然后返回testcase url 来测试。

直接使用php + redis,从redis 来获取有generator 生成的testcase。这样可以可以实现分布式测试,提高fuzz 效率。

<!doctype html>
<html>

<head>
  <script>
    var file = null;
    var run_count = 0;
    var bFinish = false;



    onload = function fLoad() {

      var xhr = new XMLHttpRequest();
      xhr.onload = function (e) {

        console.log(file);
        file = JSON.parse(xhr.response).file;

        if (bFinish == false)
          bFinish = true;

        document.title = "Loading " + file;
        console.log(">>>>> " + file);


      }
      xhr.open('GET', '/next.php?action=query');
      xhr.send(null);

      var oFrame = open("/testcase/" + file + ".html");
      console.log("<<<<<<< " + file);

      setTimeout(fCleanup, 200);

      function fCleanup() {
        //  setTimeout(function() {
        try {
          if (bFinish == true) {
            bFinish = false;

            oFrame.close();
          }
        } catch (e) { };
        //      }, 200);
        fLoad();
      }
    }
</script>
</head>

<body>
</body>

</html>%

testcase 生成

你猜

看你想fuzz 哪个组件,然后看规范,收集api,写规则。。。

自动化

开个cron job,自动从github pull写好的generator,以及不断检测是否有crash 文件生成,有的话直接发邮件过去。

最终

不过还是审计吧


Paper 本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/2012/



文章来源: https://paper.seebug.org/2012/
如有侵权请联系:admin#unsafe.sh