Google 開源 Atheris,Python 代碼安全掃描工具

Atheris 使用模糊測試技術掃描 Python 代碼中的漏洞

最近更新時間 2020-12-14 12:35:56

Atheris

2020年12月4日,Google 發佈了一款開源代碼安全掃描工具 Atheris Python Fuzzer。

模糊測試是一種軟件測試技術。其核心思想是將自動或半自動生成的隨機數據輸入到一個程序中,並監視程序異常,如崩潰,斷言失敗,以發現可能的程序錯誤,比如內存洩漏。模糊測試常常用於檢測軟件或計算機系統的安全漏洞。Google 使用此技術發現了數千個安全漏洞和其他錯誤。傳統上的模糊處理是在 C 或 C ++ 等本地語言上使用的。但是去年,Google 構建了一個新的 Python 模糊處理引擎。12月4日,Google 終於將 Atheris 模糊引擎作為開源發佈。

Atheris 能做什麼?

Atheris 可用於自動查找 Python 代碼和本機擴展中的錯誤。 Atheris 是一個“覆蓋率導向”的模糊器,這意味著 Atheris 將在觀察程序如何執行的同時反覆嘗試對程序的各種輸入,並嘗試找到有趣的代碼執行路徑。

Atheris 支持的版本?

Atheris 於去年10月在 Google 內部進行開發,並支持以 Python 2.7 和 Python 3.3+ 編寫的 Python 代碼和使用 CPython 創建的本機擴展。但在最新的申明中,Google 強烈建議使用 Python 3.8+,因為它可以提供更好的覆蓋率信息。在對本機擴展進行模糊處理時,可以將 Atheris 與 Address Sanitizer 或 Undefined Behavior Sanitizer 結合使用。

未來會在 OSS-Fuzz 中支持 Atheris。

怎樣安裝 Atheris?

Atheris 已經在 Github 上開源發佈。Atheris 支持 Linux (32- and 64-bit) and Mac OS X。

使用 pip3 命令安裝

yum install clang
使用 pip 3安裝
pip3 install atheris
Installing collected packages: atheris
    Running setup.py install for atheris ... done
Successfully installed atheris-1.0.7

注意:Atheris 依賴 Clang 發行的 libFuzzer。如果您已安裝 Clang 版本,則安裝非常簡單。如果您沒有安裝 Clang 或版本太舊,則需要下載並構建最新版本的 LLVM。

# coding=utf-8

# Python3 代碼
# 怎樣使用 Atheris

import atheris
import sys

def TestOneInput(data):
    if data == b"bad":
        raise RuntimeError("Badness!")

atheris.Setup(sys.argv, TestOneInput)
atheris.Fuzz()
INFO: Configured for Python tracing with opcodes.
WARNING: Failed to find function "__sanitizer_acquire_crash_state".
WARNING: Failed to find function "__sanitizer_print_stack_trace".
WARNING: Failed to find function "__sanitizer_set_death_callback".
INFO: Seed: 3042541424
INFO: Loaded 2 modules   (1024 inline 8-bit counters): 512 [0x2554460, 0x2554660), 512 [0x2556e90, 0x2557090), 
INFO: Loaded 2 PC tables (1024 PCs): 512 [0x2554e80,0x2556e80), 512 [0x25578b0,0x25598b0), 
INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes
	NEW_PY_FUNC[1/2]: TestOneInput() /data/python/code.py:9
INFO: A corpus is not provided, starting from an empty corpus
#2	INITED cov: 7 ft: 7 corp: 1/1b exec/s: 0 rss: 29Mb

 === Uncaught Python exception: ===
RuntimeError: Badness!
	NEW_PY_FUNC[1/2]: _find_and_load() :1002
	NEW_PY_FUNC[2/2]: __init__() :152
Traceback (most recent call last):
  File "/data/python/code/code.py", line 11, in TestOneInput
    raise RuntimeError("Badness!")

==64413== ERROR: libFuzzer: fuzz target exited
SUMMARY: libFuzzer: fuzz target exited
MS: 3 InsertByte-CMP-EraseBytes- DE: "bad"-; base unit: adc83b19e793491b1c6ea0fd8b46cd9f32e592fc
0x62,0x61,0x64,
bad
artifact_prefix='./'; Test unit written to ./crash-1902e3d6fc4e78a0bcc50ba12b882769afbf4a8c
Base64: YmFk
rss_feed