解析対象プログラムか3 void func(char *arg){ char str[ 1 0];
strcpy(str ,arg); priritf("%s¥nιstr); int main(int argc, char骨a唱v[]){
chars仕[20],S廿1[20]; if(argc < 2) strcpy(str, "bbb");
else strcpy(str, argv[ 1]); strcpy(str 1, s甘);
func(s廿1); return; }
3.1 関数strcpy中の変数のトレース
102 Sapidによるソフトウェア解析技法
void traceExpr(SpdObjld var̲id. SpdO句Idexpr̲id. int arg){ SpdObjld prolLid. idenUd. var Lid. ar且ーid.funcName̲id; StdObjld expr̲o>iLarrray{100];
iriti.k. argn=malloc(sizeof(int));
/ / 1
式 を 解 析 す る 解 析 対 象 の 引 数 が 定 数 の 場 合 は 解 析 終 了 if((idenCid = tra田,Var(expr̲id.a培))== 0)retum;
/ / 2 .
標 準 入 力 の 場 合 は 脆 弱 性 を 検 査if((funcName̲id =geCA昭v(idenCid.a唱n))!=SAPID̲NON̲ID){
if(funcName̲id == O){
printfC'¥t¥t Standard Input¥n"); checkCorid(expr̲id);
else{
checkSize( exprーid.geCN̲arg(expr̲id.l)); retum:
printf(
ヘ
tArgument of ");/ / 3.関数のパラメータの場合は、関数にまたがる解析を行う 回 目Func(funcName̲id.骨argn+j);
re加m;
/ / 4.変数の場合』本当該変数を含む式を取得
k = getExpressionList(vacid. expr̲id. expr̲obLaπray); //5.4.で得られた各式に対し.関数甘aceExprを 得 層 的 に 呼 び 出 す if(k > O){
printf(..τ'race Variable‑‑>梢s¥n".spdGetName(var̲id)); for(i= O;i<k;i++){
printf(ヘn Dependable Exp四回ion¥n");
print質"¥tExpr=%s at州d
州、
pdGeのb目Text(expr̲obLarrray[i]). s同
l. , . g
eUine(expr̲obLarrray(i]));:;坊主品説綿貫 : 2 こ I d r : . t a お う
ef"九ny"); traceExpr(varl̲id. expr....obLarrray[i]. arg); }関数 g e t ̲
Argv
ーデータ依存パラメータのオブジェクトI d
を求めるSpdObjld geCArgv(SpdObjld var̲id. int* argn){
SpdObjld d自 にid.decr Lid. decl̲id. idenCid. para̲id;
~ec~-.i~ = sp~getA!te.19.bjS~ar_i~\ "~~cl.i~en~.:".:'c-N.:');
decUd = sPdGetARelObj(decr̲id. "d町Ldeclγc‑id・');
if((para̲id = spdGe仏RelObj(decUd.."func
一 例
rm...c‑id..))!= SAPID̲NON̲ID){梼argn= getA1"gNumlpara̲l咽 下 回eCJ̲IG)
} else
お 」 43 蕊山宮町邸主 J L J : 結 ; 1 1 7 よ M i b
・);if(!償 問p(spdGetName(叩Cid)."main")) retum 0;
else{
retum idenCid;
retum SAPID̲NON̲ID;
第6章 ソフトウェアのリスク分析 103
関数
g e
tArgNum
ーデータ依存パラメータの位置を求めるint getArgNum(SpdObjld para̲id. SpdObjld d困cUd){
SpdRelArray rel̲array; int i;
rel̲array=spdGetRelSortedArray(para̲id. "funcparm".
'any". NULL. spdCompareRelO仔'set); for (i = 0・i< rel̲array.size; i++) {
if(問La;':;y-:r~îiiY.~bJ;ctid .~; decUd) return 1;
}
3 . 2
標準入力からのデータ引き渡しチェック最終的に値を決定している式の中で、標準入力から値が得られている場合に、
入 力 値 の サ イ ズ チ ェ ッ ク が 行 わ れ て い る か 調 べ る 。 関 数
checkCond
は 、 当 該 式を含むi f
ブロックが存在するか調べ、存在した場合はその条件式を出力する。値が代入される側の文字型変数の配列サイズは関数
c h e c k S i z e
で調べる。関数
checkCond
一条件式を検査するvoid checkCond(SpdObjld expr̲id) { SpdObjld blk̲id. expr l̲id. cond̲id; expr l̲id = expr̲id;
while(spdGetARelO句作xprーid...expr̲expr...c‑id..)!=SAPID̲NON̲ID) expr Lid = spdGetARelObj(expo̲id. "expr̲expr...c‑id..); blk̲id = spdGetARelObj(expr
L i
d. "blk̲exprγc‑id");if((blk̲id = spdGetAReIO旬。lk̲id."blk̲blk・....c‑id..))!=SAPID̲NON̲ID) if(spdGetAf甘ValInt(blk....:id...sort..)== BLOCK̲I町
if【(cond̲id= spdGetARelObj(blk̲id. "blk̲expr".
、
ny"))!=SAPID̲NON̲ID) prinぜ"("¥n¥t¥tCondition‑> ¥'if( %s )¥.¥n" .spdGetObjText(cond̲id));関数
c h e c k S i z e
文字型変数の配列サイズを検査void checkSize(SpdObjld expr̲id. SpdObjld ar.且ーid){ SpdObjld argNarne ̲id. suffix̲id. decr̲id. type̲id; argName̲id= spdGetARelObj(al'lLid, "idencrefγany"); decr̲id= spd<白~e!QMl!rgNa.'!ie.~!d, "dectõ!~entγaoy");
type̲id= s凶qe~<;!~~~~悶_id! 屯開 typ~'.'''~.~t');.
ffix̲id= spdGetARelObj(typeーid,"type一 回xpr","any");
printf('¥n¥t¥:lSize of Array"¥'%s¥' is %s¥il・'.s
凶Ge
tNanIe(時 Name̲id). spdGetObjText(suffix̲id));104
S a p i d
によるソフトウェア解析技法 3.3 関 数 に ま た が る 変 数 の ト レ ー ス
関 数 に ま た が る 値 の 変 更 を 関 数 t r a c e F u n c で 調 べ る 。 関 数 宣 言 文 ご と に 、 当 該 関 数 の 呼 び 出 し 式 を 求 め る 。 そ の 式 の 中 で デ ー タ 依 存 関 係 の あ る 変 数 を 取 り 出 し 、 関 数 t r a c e E x p r で 解 析 す る 。 そ の 場 合 、 対 象 関 数 の デ ー タ 依 存 パ ラ メ ー タの位置は、 a r g n に保持されており、これを引き渡す。
はrcpy(s
骨; 加回
} k j
パラメータ引き渡し
関 数 t r a c e F u n c 関 数 に ま た が る 解 析 アルゴリズム
1.
当該関数を呼び出す関数と式(1立
PR̲SORT̲FUNCCALL)を求める
2.当該式を含む基本文を取得する
3.
当該式中のターゲットとなる変数を求める 4 . 2 . で取得した変数をトレース
void traceFunc(SpdObjld idenCid,凶targn){ SodCursor 田 町
S!>dObjldArray func̲array; SpdOcc 0凹;
S!>dObjld decr̲id, fname̲id, expr ̲id, var̲id; int 1;
/ / 1.当該関数を呼び出す関数と式を取得する
funcarray=spdGetObjldArray("optlonaldecI・"NULL, NULL);
for (i = 0; 1 < func̲aπay.size; 1++)
if(s凶GetA町ValInt(func̲array必[i],"sort") == DECL̲FUNCDEF) { csr=spdGetIncIudedOcclnit(func̲a町ay.id[i]
、 ,
xp陀 制on",
func̲aπay.id[i]); while((occ = spdGetIncIudedO目(csr)).relationld!=SAPID̲NON̲ID)if(spdGetAttrValInt(occ.objectld,"sort")==EXPR̲SORT̲FUNCCALL){
if(spd~tARe.l~bj~et=~_.'!.rg(occ.o句ectld, O)パdenCrefγany")== idenUd){
decI‑̲id= spdGet品iõb}:Cfu~è_array.iØ[iJ,';decI̲o
P t
γc‑id"); fname̲id ~ spdGetARelObj(decr̲id, "decUdentγany");pnnぜ("Funcfion:%s ¥n",spdGetName(fname̲id));
第6章 ソフトウェアのリスク分析 105
/ / 2.当該式を企む基本文を取得する
expr̲id = spdGetARelObj(idenUd
,
"idenCrefγc‑id"); 00expr̲id = spdGetARelObj(expr̲id, "expr̲exprγc‑id'・);
w函Ie(spdGetARelObj(éÌ<pr~.jd,"blk‑':expr":"c‑id") =;,; SAPID ̲NON̲ID);
/ / 3.当絞式中のターゲソトとなる変数を求める
var̲id = spdGetARelObj(geCN̲arg(occ.objectld,argn)・,'identrefγany"); printf(
ヘ
t¥tExpr = %s¥n",spdGetObjText(exprーid));//4.3.で取得した変数をトレース traceExpr(var̲id, expr̲id, argn); }
) r 田r o s r u pしe e r F }凶s
︑︾
} ﹂
サンプルプログラム6‑
4
#include <stdio.h>
制nclude<Sapid/Sapid.h>
T t m
州SpdO均ldArrayid̲aπ'ay;
SPdObjld pro~id, eicpr̲id, expr l̲id, var̲id, idenUd, ar,ιid, funcName̲id; SpdCursor
・
idenCcsr;int i, j = O,k= 0,町gNum;
SpdDBld dbld; dbld = spdOpenSDBO;
openMooellldbld);
id̲array = s凶GetObjldArray("identifier",NUll, NULL);
for (i =
0 ;
i< .
id̲aπ'ay.s阻e;i++){if(spdGetAttrValInt(id̲array.id(i]
,
"sort")==ID̲FUNCTION) if(strcmp(spdGetNanie(id̲array.id[i))九廿cpy")==O){idenCcsr = spdGetRelObjlnit(id̲array.id[i], "ident̲refブany"); while ((expr.‑‑:id = sl'.<!~t~el2,bWden仁田r))!=SAPID̲NON̲ID){
e
目xp戸rl凶d=s勾pdC協ιG白het凶ARe怠 ,elめObjメ((ex却pr̲
一
'̲I泊d"、
ex勾pr̲一
̲e目xprγargNum = 2;
ar~id=geCN←arg(expr l̲id, 2);
identーid=spdGetARelObj(ar~id , "idenCrefブany"); printf("¥n%dth‑Arg of¥'%s¥' at #%d‑一‑‑>ジ"
a
町r宮Nu山m,spdGetOb, 切IjT百Iex武t(ωe却xprl̲iのd), spd‑llecline(expr 1ーid)); pnnぜ("%s¥n" , spdGetObjText(arιid));
}
spdFreeObjldArray(id̲array); return (EXIT̲SUCCESS);
}
spdFreeCursor(idenccsr); }
tra田Expr(idenCid,expr Cid, argNum);
106
S a p i d
によるソフトウェア解析技法 実行結果(一部)2lh‑Arg of 's仕cpy(s甘,arg)'at #らー>arg Variab1e = ars:
CalIing Function ー >maln <‑関数にまたがる変数のトレース Expr = func(str U
Variable = str 1
Tra田Variable‑‑>向 甘 < ‑ タ ー ゲ ッ ト 変 数 の ト レ ー ス Dependable Expression
Expr= S廿cpy(strl,s甘)at#19 Variable = s甘
T岡 田V町iable‑‑>拘tr Dependable Expr回 目on
Expr = S廿cpy(str,"bbb") at # 15 Constant Value = "bbb"
Dependable Expression
Expr = s廿'cpy(str, 町gv[1]) at # 1 7 Variable = argv
Standard Input < 標 準 入 力 の 場 合 の 解 析 Condition ‑> 'if( argc < 2)' ← 条 件 式 の 検 査
Size of Array 'str・is20 ←文字列変数のサイズチェック
N リ ス ク 分 析 ツ ー ル の 実 装
第
5章で紹介した SDA4モデルの依存解析は、現行パージョンでは関数にま たがる解析は提供していない。そのため、ポインタ型の引数をもっs t r c p y
とい ったメモリ・文字列処理関数のデータ依存解析は、サンプルプログラム 6‑4の ようにS a p i d
アプリケーションとして実装する。リスク分析ツールを実現するため、脆弱性を持つ関数を含む式の一覧と属性 を関数ごとに求め、
p e r l
等を利用してデータの依存解析を行う。情報漏洩など の危険性の抽出も行う。データをXML
形式で扱い、ソースコード等とリンク したハイパードキュメント情報を生成する。セキュリティ・ポリシーの作成や、監査、ソフトウェア資産評価などのドキュメントとして、生成された情報を利 用する。
第6章 ソフトウェアのリスク分析 107
解析対象プログラム
( S P I Eドキュメント形式)
1: void strini( char静argl,char arg2){ 2:
3: strcpy(arg 1
,
arg 2); 4:5: } 6:
7: void main(int argc, char *argv[]){ 8:
9: char buffer[80],buffer I[ 1 OO],buffer 2[20][ 20]骨bu, 仔"r3; 10: mtl=l;
11: 12: 13: 14:
15: for(i = 1;i< 1 O;i++) 16: strini(bu仔er2[i],"NULL"); 17・
18: if (argc > 1)
19・ S廿cpy(bu仔'er,argv[1]); 20・
21: if(argc==I)
22: strcpy(buffer・',dummy");
23: 24 25・ 26 27: 28 29 30: }
strcpy(buffer,'''');
spriiuf(bu庄町I,"%s%d"," " ,"start",i,"end");
F且e 妊u hu
︑
Jn δ v rh
川河川日
1 V A
rJe; 2[E);
飴 ヨd
・ 1 パリ i t
‑
‑
; UEber) ゆ 必 泊 能 Au
h b ' c b h ι
山
内414伽
Uq δ
・ ︐
n u 町 町 点 世
. n h
山
路 銘 JU皿山A町
" s
mm%m%%
l i :
WY
償Y
副 市 川
q q n q n n
仕 甘 四 廿
. n . n
ssESEE
リスク分析のドキュメント(1) トップページ
(HTML
形式)一
‑SourceCode Level ‑‑‑S e c u r i t y Check R e p o r t 一 一 一 一
OCCURRENCEof strcpy‑ ‑ 一 一 一
Program: main
Vulnerabj1ity(O
Function Local Stack Over Flow Check Item Check strcpy Strcpy(varl, var2) Boundary size of varl, Size of var2
•
strncpy strncpy( var 1, var2, le ngth) Boundary size of varl, Size of length strcat strcat((varl, var2) Boundary size of varl, Size of var2 sprintf sprintf(varl,format, paral,…j Boundary size of varl, Size of paraN
•
sscanf Sscanf(varl, format, paralぃ...) Boundary size of varl, Size of paraN gets gets(varl) An Occurrence of this function scanf scanf(format, paral,…j Type of paraN is char
•
fscanf fscanf(varl, format, paral, ....) Type of paraN is char
VI!IMtabilHY{:l)
Function Format Strin2 Attack Check Item Check printf Printf(format, paral,…・) Check if・%'character is used
•
lnfor皿 屋tio.ilJ.;jJakage
Function Leakage Check Item Check
I
printf Printf(format, paral, ...) Check if paraNwrite骨 write(varl, var2) Check if var2 is significant informa!Ion
108 Sapidによるソフトウェア解析技法
Check if paraN
Check if var2 is significant information
リスク分析のドキュメント
(2)関数
strcpyの出現
(HTML形式)
一一一一
OCCURRENCEof strcpy ‑‑‑‑‑‑‑‑参3:strcpy(ar宮1
,
arg2); Function: main111 2: s剖tr,午~p:〆buffe町r,"吋' 1116: 坑strini吐(buf仔fer2[i,)日"NULL"); 1119: strcpy(buffer,a培v[1)); 1
1
22: strcpy(buffer,'古田nmy・');
#2生strcpy(buffer2[ 1),buffer);
# 25: strcpY(buffer 1,buffer 2[ 1)); 1126: priritf("%d",strcpy(buffer正buffer1));
# 27: strcpy(buffer ,3bu仔'er1);
Function: strini
リスク分析のドキュメント
(3)関数
strcpyの出現
(HTML形式) 一一一一
OCCURRENCEof strcpy ‑‑‑‑‑‑‑‑Target Expression: FILE: a.c FUNCfION:strini
113 s廿cpy(argl,arg2);
Sour,白Variable:argl Function IIl:char argl Destination Variable: arg2 Function
I
IIl:char・
arg2 Con廿01Depend ExpressionData Depend Expression:
Target Expression:FILE a‑C FUNCTION#‑m12asmt remdbufTer
Source Variable: buffer Local 119:char buffer[80) Destination Variable Constant ""
Control Depend Exp胞団ion: Data Depend Expression:
TMEethpression:FIIZ.a‑C FUNCTION #1z6riaSl廿n1ni(bu百er2[i],"NULL");
Source Variable: bu百er2 Local 119:char buffer2[20)[20] 民stinationVariable: Constant "NULL"
Con廿01Depend Exp四回ion: Data Depend Expression
Target Expr田Sion:FILE:a‑CFUNCTION#:1m9asi廿ncpkbuHer,arEVIlB;
Source Variable: buffer Lo回1 119:char buffer[80] Destination Variable: Function 117:char *argv[] 白,n~rolDepend Expr出向n:
Data Depend Expr,田sion
Target Expression:FILE:a‑C FUNCTION#:2m4asintrepkbu 釘er2[11.bu仔er);
Sour,田Variable:buffer2 Lo回1 刊:charbuffer2[20][20] Destination Variable: bu妊er Function
1
~9:char buffe! i 里
01 Con廿01Depend Exp問団ion:Data Depend Expre剖 on: 1122: s甘cp:メbuffer,"dummy");
第6章 ソフトウェアのリスク分析 109
リスク分析のドキュメント
( 4 )
変数b u f f e r
の出現(vml 形式)
b u f f e r
#12:.甘 叩 ポbuff町J刷);
相24:strcpポbuffer2[lI,bufter);
VMLの記述例:# 2 l:if(arg== 1)節の条件文の菱形
<v:shape type='柏osi'style='position:油 田lute;
le員25;top: 245; width: 640~ height: 27 50; z‑index:‑l・/>
<v:textbox style='position:absolute; le世25;top: 26~width: 240; height: 100 >
<table border= 0 cellpadding= 0 cellspacing=o width= 10
0 % >
<tr><td align=center>
<div align=center>
<p c1ass;'MsoNormal s旬le='text‑align:偲nter・><span style='font‑family:Century;mso‑ascii‑font‑
family':Century;~so,一hansi-font-fa凶ly:Centulず〉
1121:if(argc =; 1)</凹nd>
</span></p>
</div>
</td>
</tr>
</table>
</v:textbox>
</v:shape>