日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于突变的模糊测试

發布時間:2024/3/12 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于突变的模糊测试 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 0. 前言
    • 1. 摘要
    • 2. 被測試程序
    • 3. 突變
    • 4. 突變的模糊測試
    • 5. 基于突變的覆蓋率引導的模糊測試
    • 6. 測試程序
    • 附錄

0. 前言


看論文The Art, Science, and Engineering of Fuzzing: A Survey 遇到一個名詞:動態符號執行。

The term white-box fuzzing was introduced by Godefroid [87] in 2007 and refers to dynamic symbolic execution (DSE), which is a variant of symbolic execution [39], [126], [108].

白盒模糊測試一詞是Godefroid [87]在2007年提出的,指動態符號執行(DSE),它是符號執行的一種變體[39],[126],[108]。

我閱讀了下這篇:符號執行入門

符號執行的概念早在1975年[4]就提出了,但是真正得到實用,卻是在一種方式提出之后,即混合實際執行和符號執行,稱為concolic execution,是真正意義上的動態符號執行。

Concolic執行維護一個實際狀態和一個符號化狀態:實際狀態將所有變量映射到實際值,符號狀態只映射那些有非實際值的變量。Concolic執行首先用一些給定的或者隨機的輸入來執行程序,收集執行過程中條件語句對輸入的符號化約束,然后使用約束求解器去推理輸入的變化,從而將下一次程序的執行導向另一條執行路徑。簡單地說來,就是在已有實際輸入得到的路徑上,對分支路徑條件進行取反,就可以讓執行走向另外一條路徑。這個過程會不斷地重復,加上系統化或啟發式的路徑選擇算法,直到所有的路徑都被探索,或者用戶定義的覆蓋目標達到,或者時間開銷超過預計。

不怎么明白符號測試,所以,我打算看下Symbolic Fuzzing 。而它需要挺多的前置要求。

所以,我不得不一個一個完成。第一個需要完成的是Mutation-Based Fuzzing

我希望可以簡單的理解符號測試的基本概念,然后跳過夯實基礎,直接可以使用符號測試的工具。

來源:Mutation-Based Fuzzing

建議閱讀原文,我這里僅僅整理下思路。我敲的相關代碼見:fuzzing倉庫

背景要求:模糊測試簡介| 代碼覆蓋率


1. 摘要


模糊測試中隨機生成的字符串大概率是無效的。這導致很多時間被浪費在無效的測試輸入中。

我們可以采用合法有效的輸入進行初期的測試。這些有效的輸入,我們稱之為種子。

我們對種子進行突變,將其中的bit(s)進行突變(翻轉、刪除、增加)。由于突變的部分相對于某個種子的整體,變化較小。那么突變之后的種子,也很可能是合法的。

種子突變的越多,不合法的可能性越大。那么如何控制突變呢?這里引入基于覆蓋率引導的模糊測試。當突變生成中輸入可以發現新路徑的時候,我們將該輸入放入倉庫中。其中,倉庫使用種子進行初始化。這樣,突變會向覆蓋率增大的方向突變。覆蓋率越大,觸發crash的可能性越大。


2. 被測試程序


URL由多個元素構成。

scheme://netloc/path?query#fragment
  • scheme is the protocol to be used, including http, https, ftp, file…
  • netloc is the name of the host to connect to, such as www.google.com
  • path is the path on that very host, such as search
  • query is a list of key/value pairs, such as q=fuzzing
  • fragment is a marker for a location in the retrieved document, such as #result

下面代碼用以檢查的URL的合法性。

如果是URL通過隨機的字符串來生成,那么生成的字符串大多數是無效的。

因而使用隨機生成字符串作為輸入的模糊測試,將會非常低效。

下文將會介紹,使用覆蓋率引導的模糊測試。

from urllib.parse import urlparsedef http_program(url):"""檢查url的合法性"""supported_schemes = ["http","https"]result = urlparse(url)if result.scheme not in supported_schemes:raise ValueError("scheme must be one of " + repr(supported_schemes))if result.netloc == '':raise ValueError("url netloc must not be empty")return Truedef is_valid_url(url):try:http_program(url)return Trueexcept ValueError:return False

3. 突變


因為以前數學建模的時候接觸過點遺傳算法的概念。所以,看到這里甚是熟悉。

下面實現了隨機刪除、插入、翻轉。

import randomdef delete_random_character(s):"""在原字符串的基礎上隨機刪除一個字符,并返回;原字符串不變"""if s == "":return spos = random.randint(0,len(s)-1)return s[:pos] + s[pos+1:]def insert_random_character(s):"""在原字符串的基礎上隨機插入一個字符,并返回;原字符串不變"""pos = random.randint(0,len(s)-1)# randint 左右閉區間,randrange左閉右開# randrange()功能相當于 choice(range(start, stop, step))random_char = chr(random.randrange(32,127)) return s[:pos] + random_char + s[pos:]def flip_random_character(s):"""在原字符串的基礎上隨機翻轉一個bit,并返回;原字符串不變"""if s == "":return spos = random.randint(0,len(s)-1)c = s[pos]bit = 1 << random.randint(0,6) # 注意這里只有七個位置可能翻轉new_c = chr(ord(c)^bit)return s[:pos] + new_c + s[pos+1:]def mutate(s):"""隨機選擇一個突變方式"""mutators = [delete_random_character,insert_random_character,flip_random_character]# print(type(mutators[0])) # 這里面存儲的是函數類型,有意思matator = random.choice(mutators)return matator(s)

4. 突變的模糊測試


在Fuzzer類的基礎上,fuzz方法使用突變的方式,生成字符串。

from fuzzingbook.fuzzingbook_utils.Fuzzer import Fuzzerclass MutationFuzzer(Fuzzer):def __init__(self,seed, min_mutations=2,max_mutations=10):self.seed = seedself.min_mutations = min_mutationsself.max_mutations = max_mutationsself.reset()def reset(self):self.population = self.seedself.seed_index = 0def mutate(self,inp):return mutate(inp)# 從倉庫中隨機選擇一個進行突變;# 倉庫使用種子進行初始化(__init__中完成)# 這里并沒有將突變生成的內容放入populationdef create_candidate(self):candidate = random.choice(self.population)trails = random.randint(self.min_mutations,self.max_mutations)for i in range(trails):candidate = self.mutate(candidate)return candidatedef fuzz(self):if self.seed_index < len(self.seed):# 使用種子self.inp = self.seed[self.seed_index]self.seed_index += 1else:# 使用突變生成的內容self.inp = self.create_candidate()return self.inp

5. 基于突變的覆蓋率引導的模糊測試


模糊測試的輸入,仍然使用上面突變的方式生成。

這里需要解決的是,如何判斷突變生成的輸入,是否發現了新的路徑。

下面是在繼承Runner類的類的一個對象中,統計覆蓋率。

class MutationCoverageFuzzer(MutationFuzzer):def reset(self):super().reset()self.coverages_seen = set()# Now empty; we fill this with seed in the first fuzz runsself.population = []def run(self, runner):"""Run function(inp) while tracking coverage.If we reach new coverage,add inp to population and its coverage to population_coverage"""result, outcome = super().run(runner)new_coverage = frozenset(runner.coverage())if outcome == Runner.PASS and new_coverage not in self.coverages_seen:# We have new coverageself.population.append(self.inp)self.coverages_seen.add(new_coverage)return result

6. 測試程序

現在可以開始著手測試上面的URL代碼了。

首先,我們需要一個類,這個類可以運行上面的URL代碼,并統計覆蓋率。

from fuzzingbook.fuzzingbook_utils.Fuzzer import Runner from fuzzingbook.fuzzingbook_utils.Coverage import Coverage,population_coverageclass FunctionRunner(Runner):def __init__(self,function):self.function = functiondef run_function(self,inp):return self.function(inp)def run(self,inp):try:result = self.run_function(inp)outcome = self.PASSexcept Exception:result = Noneoutcome = self.FAILreturn result,outcomeclass FunctionCoverageRunner(FunctionRunner):def run_function(self,inp):with Coverage() as cov:try:result = super().run_function(inp)except Exception as exc:self._coverage = cov.coverage()raise excself._coverage = cov.coverage()return resultdef coverage(self):return self._coverage

測試下

http_runner = FunctionCoverageRunner(http_program) seed_input = "http://www.google.com/search?q=fuzzing" mutation_fuzzer = MutationCoverageFuzzer(seed=[seed_input]) mutation_fuzzer.runs(http_runner, trials=10000) mutation_fuzzer.population

看下結果

all_coverage, cumulative_coverage = population_coverage(mutation_fuzzer.population, http_program)import matplotlib.pyplot as plt plt.plot(cumulative_coverage) plt.title('Coverage of urlparse() with random inputs') plt.xlabel('# of inputs') plt.ylabel('lines covered')

附錄

類的UML圖代碼見倉庫

(導出來的圖像清晰度不夠)

總結

以上是生活随笔為你收集整理的基于突变的模糊测试的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。