成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

符號(hào)執(zhí)行,從漏洞掃描到自動(dòng)化生成測(cè)試用例

安全 應(yīng)用安全 漏洞 自動(dòng)化
我們發(fā)現(xiàn),符號(hào)執(zhí)行也可以用來(lái)自動(dòng)化生成測(cè)試用例,為我們更加全面的編寫測(cè)試用例, 帶來(lái)新的思路。

[[401583]]

背景

ThoughtWorks安全團(tuán)隊(duì)曾經(jīng)在可信Frimware領(lǐng)域做了一些探索和研究。背景大概是這樣的:整車制造過(guò)程中,常常會(huì)引入供應(yīng)商的部分設(shè)備,如車載娛樂(lè)系統(tǒng),但是出于知識(shí)產(chǎn)權(quán)的原因,這些供應(yīng)商很難提供完整的源碼給整車制造方,因此二進(jìn)制的固件就成了整車制造環(huán)節(jié)中的安全隱患,各種漏洞都可能被供應(yīng)商的零部件引入,存在于車載系統(tǒng)之中,隨時(shí)可能被攻擊者利用而影響整車的安全性。

為了探測(cè)二進(jìn)制程序中的漏洞,經(jīng)過(guò)一段時(shí)間的探索和研究后,把核心技術(shù)鎖定到了符號(hào)執(zhí)行,利用該技術(shù)幫客戶搭建了一套自動(dòng)化的二進(jìn)制漏洞掃描平臺(tái)。并且,在后來(lái)不斷的研究中,我們發(fā)現(xiàn),符號(hào)執(zhí)行也可以用來(lái)自動(dòng)化生成測(cè)試用例,為我們更加全面的編寫測(cè)試用例, 帶來(lái)新的思路。

什么是符號(hào)執(zhí)行

Wikipedia上對(duì)符號(hào)執(zhí)行的解釋:是一種程序分析技術(shù),其可以通過(guò)分析程序來(lái)得到讓特定代碼區(qū)域執(zhí)行的輸入。使用符號(hào)執(zhí)行分析一個(gè)程序時(shí),該程序會(huì)使用符號(hào)值作為輸入,而非一般執(zhí)行程序時(shí)使用的具體值。在達(dá)到目標(biāo)代碼時(shí),分析器可以得到相應(yīng)的路徑約束,然后通過(guò)約束求解器來(lái)得到可以觸發(fā)目標(biāo)代碼的具體值。

講的比較繞,舉個(gè)通俗的例子來(lái)說(shuō)明:假設(shè)程序現(xiàn)在是一個(gè)王者榮耀中的英雄,這個(gè)英雄經(jīng)過(guò)一定的出裝就會(huì)有一定的戰(zhàn)力(攻速,物理傷害,防御等),符號(hào)執(zhí)行的技術(shù)就是,給出了一個(gè)英雄的戰(zhàn)力,可以反推出什么樣的出裝可以達(dá)到這樣的戰(zhàn)力。

再舉個(gè)實(shí)際的代碼例子來(lái)說(shuō)明符號(hào)執(zhí)行:

  1. void foo(int x, int y) 
  2.     int t = 0
  3.     if( x > y ){ 
  4.         t = x
  5.     }else{ 
  6.         t = y
  7.     } 
  8.     if (t < x ){ 
  9.         assert false; 
  10.     } 

假設(shè)當(dāng)t<x時(shí),是我們程序的漏洞,我們要使用符號(hào)執(zhí)行判斷是否有達(dá)到t<x這個(gè)分支的可能。符號(hào)執(zhí)行的方法就是在給定的時(shí)間內(nèi),生成一組輸入,以盡可能多的探索所有的執(zhí)行路徑,在分析時(shí),該程序會(huì)使用符號(hào)值作為輸入,而非具體的值,去探索每一條分支。比如該程序在符號(hào)執(zhí)行完后,會(huì)生成如下類似的方程組:

  1. (x>y) => t=x 
  2. (x<=y) => t=y 

接下來(lái),符號(hào)執(zhí)行會(huì)通過(guò)約束求解,去分析上述的每條路徑,通過(guò)約束求解分析得,如上的兩條路徑在任何情況下都不可能達(dá)到t

使用符號(hào)執(zhí)行進(jìn)行漏洞掃描

那我們是如何把符號(hào)執(zhí)行運(yùn)用在自動(dòng)化漏洞掃描的場(chǎng)景上?

首先要說(shuō)明的是,我們要掃描的對(duì)象是Linux kernel,對(duì)于kernel來(lái)說(shuō)有很多已知的CVE漏洞,我們的任務(wù)就是去發(fā)現(xiàn)二進(jìn)制的kernel上是否存在這些CVE漏洞。思路如下:

  • 通過(guò)一些簡(jiǎn)單的逆向,得到該內(nèi)核的版本。
  • 有了內(nèi)核版本,就可以得到內(nèi)核的源碼,以及該內(nèi)核版本對(duì)應(yīng)的所有CVE漏洞和補(bǔ)丁。
  • 給內(nèi)核源碼打上所有的CVE補(bǔ)丁,在二進(jìn)制層面diff前后的補(bǔ)丁,對(duì)每個(gè)補(bǔ)丁提取唯一的特征(漏洞指紋)。
  • 用漏洞指紋與目標(biāo)kernel進(jìn)行對(duì)比,掃描得到最終的漏洞列表。

由上述可知,提取漏洞的唯一特征是最重要的一步,接下來(lái)介紹如何使用符號(hào)執(zhí)行來(lái)提取漏洞指紋。

首先介紹兩個(gè)基本的概念BB(basic block)和CFG(control flow graph):BB是指從匯編的角度來(lái)看程序,一段連續(xù)的匯編指令就是一個(gè)BB,這段連續(xù)的匯編僅僅包含一個(gè)入口和一個(gè)出口,換句話說(shuō),BB內(nèi)部不會(huì)有分支和跳轉(zhuǎn)。由此我們可以得出,一個(gè)程序,是由一堆的bb組成的,它們之間有復(fù)雜的調(diào)用和跳轉(zhuǎn)關(guān)系,最終形成了一張圖,這個(gè)圖就是CFG。例如下圖是一個(gè)簡(jiǎn)單的CFG:

有了這兩個(gè)概念,我們就可以對(duì)漏洞進(jìn)行唯一的特征描述了。

漏洞指紋特征

由上面可知,CFG其實(shí)表示了一段程序執(zhí)行的所有路徑,而符號(hào)執(zhí)行的第一步就是去探索所有的執(zhí)行路徑。如果您了解過(guò)內(nèi)核的CVE漏洞,就會(huì)發(fā)現(xiàn)內(nèi)核很大一部分的CVE漏洞補(bǔ)丁,就是在一些關(guān)鍵的代碼上加了一些if分支和判斷。例如CVE-2019-19252的補(bǔ)丁如下:

  1. diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c 
  2. index 1f042346e7227..778f83ea22493 100644 
  3. --- a/drivers/tty/vt/vc_screen.c 
  4. +++ b/drivers/tty/vt/vc_screen.c 
  5. @@ -456,6 +456,9 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 
  6. size_t ret; 
  7. char *con_buf; 
  8. + if (use_unicode(inode)) 
  9. + return -EOPNOTSUPP; 
  10. con_buf = (char *) __get_free_page(GFP_KERNEL); 
  11. if (!con_buf) 
  12. return -ENOMEM; 

該補(bǔ)丁只是在vcs_write的函數(shù)中添加了一個(gè)if判斷,對(duì)于這類補(bǔ)丁,在使用符號(hào)執(zhí)行生成CFG的時(shí)候,前后肯定會(huì)出現(xiàn)一個(gè)明顯的差異,因?yàn)槎嗔艘粋€(gè)分支,整個(gè)的程序流圖也就多了一個(gè)分支。對(duì)于這種類型的補(bǔ)丁,使用CFG就可以作為漏洞的特征,通過(guò)對(duì)比發(fā)現(xiàn),前后的CFG不一樣,就說(shuō)明漏洞存在。

那么,僅僅通過(guò)CFG是否就可以唯一的確定這個(gè)漏洞嗎?請(qǐng)看下面的CVE-2019-8956的例子:

  1. diff --git a/net/sctp/socket.c b/net/sctp/socket.c 
  2. index f93c3cf9e5674..65d6d04546aee 100644 
  3. --- a/net/sctp/socket.c 
  4. +++ b/net/sctp/socket.c 
  5. @@ -2027,7 +2027,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len) 
  6. struct sctp_endpoint *ep = sctp_sk(sk)->ep; 
  7. struct sctp_transport *transport = NULL
  8. struct sctp_sndrcvinfo _sinfo, *sinfo; 
  9. - struct sctp_association *asoc; 
  10. + struct sctp_association *asoc, *tmp; 
  11. struct sctp_cmsgs cmsgs; 
  12. union sctp_addr *daddr; 
  13. bool new = false
  14. @@ -2053,7 +2053,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len) 
  15. /* SCTP_SENDALL process */ 
  16. if ((sflags & SCTP_SENDALL) && sctp_style(sk, UDP)) { 
  17. - list_for_each_entry(asoc, &ep->asocs, asocs) { 
  18. + list_for_each_entry_safe(asoc, tmp, &ep->asocs, asocs) { 
  19. err = sctp_sendmsg_check_sflags(asoc, sflags, msg, 
  20. msg_len); 
  21. if (err == 0) 

對(duì)于這種漏洞補(bǔ)丁,沒有分支上的增減,只是改變了一個(gè)函數(shù)的入?yún)€(gè)數(shù),那么補(bǔ)丁前后的CFG可能是一樣的,所以我們就不能僅僅通過(guò)CFG來(lái)判斷補(bǔ)丁是否存在,必須加上在語(yǔ)義上的分析,語(yǔ)義即這個(gè)參數(shù)對(duì)函數(shù)的整體影響。這就引出了符號(hào)執(zhí)行的另一步:約束求解,前面我們提到符號(hào)執(zhí)行會(huì)對(duì)所有路徑形成類似方程組的概念,然后使用約束求解器求出到達(dá)每個(gè)路徑的解的集合。如果其中某些變量發(fā)生了改變,其最終的解一定是不一樣的,以此作為漏洞標(biāo)識(shí)的另一個(gè)特征。

漏洞掃描總結(jié)

所以最終,我們是采用符號(hào)執(zhí)行從CFG和語(yǔ)義分析兩個(gè)維度來(lái)唯一的確定一個(gè)漏洞的特征,然后用這個(gè)唯一的特征去目標(biāo)的kernel中對(duì)比。以此來(lái)確定補(bǔ)丁是否已經(jīng)存在。這個(gè)就是我們檢測(cè)二進(jìn)制漏洞的關(guān)鍵技術(shù),大致流程如下圖:

在整個(gè)過(guò)程中,我們會(huì)使用開源的符號(hào)執(zhí)行引擎和約束求解器,比如Angr和Z3。

符號(hào)執(zhí)行的其他應(yīng)用場(chǎng)景

前面是符號(hào)執(zhí)行在漏洞提取和掃描的一個(gè)案例,除此之外,符號(hào)執(zhí)行在漏洞挖掘,CTF等方面也有比較廣泛的應(yīng)用。例如如下程序是我用Ghidra逆向的一道CTF的題目:

  1. int verify(EVP_PKEY_CTX *ctx, uchar *sig, size_t siglen, uchar *tbs, size_t tbslen) 
  2. byte bvar1; 
  3. int local_c; 
  4. local_c = 0
  5. while(true) { 
  6. if(ctx[(long)local_c] == (EVP_PKEY_CTX)0x0) { 
  7. return (int)(uint)(local_c == 0x17); 
  8. bVar1 = (byte)local_c; 
  9. if(encrypted{(long)local_c} != (byte)(((byte)((int)(uint)(bVar1 ^ (byte)ctx[(log)local_c]) \ 
  10. >> (8-((bVar1 ^9)&3) & 0x1f)) | (bVar1 ^ (byte)ctx[(long)local_c]) << ((bVar1 ^9) & 3))+8)){ 
  11. break; 
  12. local_clocal_c = local_c + 1 
  13. return 0; 

可以發(fā)現(xiàn),其核心關(guān)鍵是去破解這個(gè)加解密的算法(異或,加減等操作),如果人工逆向,可能需要很長(zhǎng)時(shí)間的推算和嘗試,而符號(hào)執(zhí)行則可以自動(dòng)的去不斷嘗試每個(gè)路徑的解,直到算出一個(gè)自己需要的值。有興趣的讀者,可以使用angr和z3去做一下這個(gè)CTF的破解,非常容易,這里不再贅述。需要說(shuō)明的是,在破解和CTF中,符號(hào)執(zhí)行往往和IDA/Ghidra等工具來(lái)配合使用。

另一方面是在測(cè)試領(lǐng)域,在單元測(cè)試中代碼覆蓋率往往被用于評(píng)估代碼的測(cè)試充分性水平,在軟件工業(yè)界,人工設(shè)計(jì)測(cè)試用例的方法被廣泛使用,即依靠人對(duì)程序代碼的理解設(shè)計(jì)測(cè)試用例,但對(duì)應(yīng)的人力成本很高,有時(shí)候?yàn)榱私档腿肆Τ杀厩姨岣咦詣?dòng)化程度,隨機(jī)測(cè)試的方法也被常常使用,但一般只能檢測(cè)到有限的程序行為,容易遺漏軟件錯(cuò)誤。

在單元測(cè)試中,常用的白盒測(cè)試的充分性準(zhǔn)則大多屬于基于控制流的覆蓋準(zhǔn)則,如語(yǔ)句覆蓋,分支覆蓋和MC/DC覆蓋等。而測(cè)試準(zhǔn)則的選取一般根據(jù)實(shí)際的測(cè)試需求而確定,比如,傳統(tǒng)軟件的測(cè)試一般要求實(shí)現(xiàn)盡可能高的語(yǔ)句覆蓋和分支覆蓋,而對(duì)于航天,軌交等控制軟件一般要求代碼滿足100%的分支覆蓋。而這種同時(shí)實(shí)施多種測(cè)試標(biāo)準(zhǔn)的需求,進(jìn)一步加大了單元測(cè)試的工作量和難度, 使得單元測(cè)試在實(shí)際軟件開發(fā)中往往被忽略,最終導(dǎo)致軟件缺陷沒有在早期被及時(shí)發(fā)現(xiàn)。

而符號(hào)執(zhí)行的特點(diǎn)是會(huì)盡可能的遍歷每條路徑,每一次符號(hào)執(zhí)行的結(jié)果等價(jià)于大量的測(cè)試案例。符號(hào)執(zhí)行為軟件的各種情況自動(dòng)生成了有效的輸入,覆蓋率高,可以更加容易檢測(cè)到程序是否存在缺陷和錯(cuò)誤。所以,其實(shí)我們可以運(yùn)用符號(hào)執(zhí)行生成測(cè)試用例。

目前學(xué)術(shù)界有不少的論文研究如何使用符號(hào)執(zhí)行自動(dòng)化生成更好的測(cè)試用例。也有一些有意思的demo,可以讓您體驗(yàn):

  • C語(yǔ)言:https://github.com/Sajed49/C-Path-Finder
  • Java語(yǔ)言:https://github.com/kaituo/sedge

總結(jié)

以上是我們對(duì)符號(hào)執(zhí)行的一些探索,歡迎您與我們一起進(jìn)行更加深入的研究。隨著大家對(duì)安全的越來(lái)越重視,基于符號(hào)執(zhí)行的漏洞掃描,自動(dòng)測(cè)試,fuzz測(cè)試等越來(lái)越受到人們的重視。2019年美國(guó)《國(guó)防法》National Defense Act的H.R.5515—517 就推薦使用二進(jìn)制分析和符號(hào)執(zhí)行工具來(lái)增強(qiáng)關(guān)鍵軟件系統(tǒng)的安全。

【本文是51CTO專欄作者“ThoughtWorks”的原創(chuàng)稿件,微信公眾號(hào):思特沃克,轉(zhuǎn)載請(qǐng)聯(lián)系原作者】

戳這里,看該作者更多好文

 

責(zé)任編輯:趙寧寧 來(lái)源: 51CTO專欄
相關(guān)推薦

2011-09-01 10:05:24

PhoneGap應(yīng)用程序測(cè)試

2021-04-21 10:01:18

漏洞KLEE網(wǎng)絡(luò)攻擊

2021-11-07 14:33:48

算法Pairwise功能

2022-01-14 11:51:00

測(cè)試工具自動(dòng)化

2025-05-14 02:22:00

符號(hào)工具Angr

2025-05-27 01:45:00

DeepSeekPython測(cè)試

2017-01-23 08:40:33

動(dòng)態(tài)符號(hào)代碼覆蓋測(cè)試

2011-10-11 09:56:59

PhoneGapSelenium

2022-06-13 09:00:00

Selenium測(cè)試Web

2021-09-30 09:00:00

漏洞安全工具

2014-03-03 10:20:15

IPA分發(fā)iOS開發(fā)

2024-09-29 15:26:53

MySQLPython

2021-03-04 15:43:29

前端測(cè)試工具開發(fā)

2024-09-29 15:32:13

自動(dòng)化測(cè)試開發(fā)

2017-10-21 21:58:18

符號(hào)執(zhí)行AngrCTF

2024-02-27 09:00:00

2011-05-16 15:18:18

測(cè)試用例

2011-06-08 17:23:12

測(cè)試用例

2021-05-18 05:59:45

自動(dòng)化測(cè)試TestNgGroup

2023-04-02 13:48:24

軟件測(cè)試NLP自動(dòng)化測(cè)試
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 国产在线精品区 | 四虎国产 | 日韩视频精品在线 | 亚洲午夜av久久乱码 | 亚洲精品乱码久久久久久9色 | 黄色日本视频 | 久草福利 | 日韩精品在线看 | 一级做a爰片性色毛片16美国 | 国产精品成人在线 | 精品在线一区二区 | av一区二区三区四区 | 日韩精品免费 | 精品久久久久久久久亚洲 | 国产一级黄色网 | 丁香一区二区 | 国产成人网 | 欧日韩不卡在线视频 | 国产日韩精品一区 | 欧美激情一区二区三区 | 欧美成年网站 | 五月天国产视频 | 午夜私人影院在线观看 | 人人九九精 | 亚洲网址 | 亚洲国内精品 | av中文字幕在线 | 99在线免费观看 | 国产精品1区2区3区 欧美 中文字幕 | 欧美黑人一区 | 国产成人一区二区 | 中文字幕视频一区二区 | 亚洲精品一二区 | 操操操日日日 | 久久合久久 | 欧美福利视频 | 欧美一区2区三区4区公司二百 | 手机av网 | 日本一区精品 | 黄a网站 | 日本在线一区二区三区 |