• 検索結果がありません。

ソフトウェアのリスク分析 101

ドキュメント内 Sapidによるソフトウェア解析技法 (ページ 104-113)

解析対象プログラムか3 void func(char *arg){  char str[ 1 0]; 

strcpy(str arg);  priritf("%s¥nιstr);  int main(int argc, charav[]){

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. arid.funcName̲id;  StdObjld expr̲o>iLarrray{100]; 

iriti.k. argn=malloc(sizeof(int)); 

/ / 1

式 を 解 析 す る 解 析 対 象 の 引 数 が 定 数 の 場 合 は 解 析 終 了 if((idenCid = traVar(expr̲id.a培))== 0) 

retum; 

/ / 2 .

標 準 入 力 の 場 合 は 脆 弱 性 を 検 査

if((funcName̲id =geCA昭v(idenCid.an))!=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); 

rem;

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 atd

州、

pdGeのbText(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 ̲

Ar

gv

ーデータ依存パラメータのオブジェクト

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. "dLdeclγ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

tAr

gNum

ーデータ依存パラメータの位置を求める

int getArgNum(SpdObjld para̲id. SpdObjld dcUd){

SpdRelArray  rel̲array;  int i; 

rel̲array=spdGetRelSortedArray(para̲id. "funcparm". 

'any". NULL. spdCompareRelO'set); for (i = 0irel̲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句作xprid...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(spdGetAfValInt(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(typeid"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;  SpdOc0凹;

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̲aay.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");  00 

expr̲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.objectldargn)'identrefγany");  printf(

t¥tExpr = %s¥n"spdGetObjText(exprid));

//4.3.で取得した変数をトレース traceExpr(var̲id, expr̲id, argn); 

) r o s pe e r F }

サンプルプログラム6‑

4

#include <stdio.h> 

nclude<Sapid/Sapid.h> 

T t m

SpdOldArrayid̲aπ'ay; 

SPdObjld  pro~id, eicpr̲id, expr l̲id, var̲id, idenUd, arιid, funcName̲id;  SpdCursor

idenCcsr;

int  i, j = Ok= 0町gNum;

SpdDBld  dbld;  dbld = spdOpenSDBO; 

openMooellldbld); 

id̲array = s凶GetObjldArray("identifier"NUll, NULL); 

for (i 

0 ;  

< .  

id̲aπ'ay.se;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̲refany"); while ((expr.‑‑:id = sl'.<!~t~el2,bWden仁田r))!=SAPID̲NON̲ID){ 

e

xprld=spdCιGhetARe怠 ,elObj((expr̲

'̲Id"

expr̲

̲exprγ

argNum = 2; 

ar~id=geCN←arg(expr l̲id, 2); 

identid=spdGetARelObj(ar~id , "idenCrefany"); printf("¥n%dth‑Arg of¥'%s¥' at #%d‑>"

a

rNumspdGetOb, 切IjTIext(ωexprl̲id) spdllecline(expr 1id)); pnn("%s¥n" , spdGetObjText(arιid)); 

spdFreeObjldArray(id̲array);  return (EXIT̲SUCCESS); 

spdFreeCursor(idenccsr);  } 

tra田Expr(idenCidexpr Cid, argNum); 

106 

S a p i d

によるソフトウェア解析技法 実行結果(一部)

2lh‑Arg of 'scpy(sarg)'at #らー>arg Variab1e = ars: 

CalIing Function ー >maln  <‑関数にまたがる変数のトレース Expr = func(str 

Variable = str 1 

TraVariable‑‑>向 甘 < ‑ タ ー ゲ ッ ト 変 数 の ト レ ー ス Dependable Expression 

Expr= S廿cpy(strls)at#19  Variable = s

T岡 田Viable‑‑>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( chararglchar  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(buer2[i]"NULL");  17

18:  if (argc 1) 

19 S廿cpy(bu'erargv[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"); 

Fhu 

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

JUA

" 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(varlformat, paral 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 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 

printf  Printf(format, paral, ...)  Check if paraN 

write 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(ar1

arg2);  Function: main 

111 2: s剖tr,午~p:〆buffe町r,"吋' 1116: strini(buffer2[i)"NULL");  1119: strcpy(bufferav[1)); 1

1

  22: strcpy(buffer'nmy');

#2strcpy(buffer2[ 1)buffer); 

# 25: strcpY(buffer 1buffer 2[ 1));  1126: priritf("%d"strcpy(bufferbuffer1)); 

# 27: strcpy(buffer 3bu'er1); 

Function: strini 

リスク分析のドキュメント

(3)

関数

strcpy

の出現

(HTML

形式) 一一一一

OCCURRENCEof strcpy ‑‑‑‑‑‑‑‑

Target Expression: FILE: a.c FUNCfION:strini 

113 s廿cpy(arglarg2); 

SourVariable:argl  Function  IIl:char argl  Destination Variable: arg2  Function 

IIl:char

arg2 Con廿01Depend Expression 

Data 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(buer2[i]"NULL"); 

Source Variable: buer2 Local  119:char buffer2[20)[20]  stinationVariable:  Constant  "NULL" 

Con廿01Depend Exp四回ion: Data Depend Expression 

Target ExprSion:FILE:a‑CFUNCTION#:1m9asi廿ncpkbuHerarEVIlB; 

Source Variable: buffer  Lo回1 119:char buffer[80]  Destination Variable:  Function  117:char *argv[]  白,n~rolDepend Expr出向n:

Data Depend Exprsion

Target Expression:FILE:a‑C FUNCTION#:2m4asintrepkbu  er2[11.buer);

SourVariable:buffer2  Lo回1 :charbuffer2[20][20]  Destination Variable: buer Function 

~9:char buffe

! i 里

01 Con廿01Depend Exp問団ion:

Data Depend Expre on: 1122: scp:メbuffer"dummy");

6 ソフトウェアのリスク分析 109 

リスク分析のドキュメント

( 4 )

変数

b u f f e r

の出現

(vml 形式)

b u f f e r  

#12:.甘 叩 ポbuffJ);

24:strcpbuffer2[lIbufter); 

VMLの記述例:# 2 l:if(arg== 1)節の条件文の菱形

<v:shape type='osi'style='position:油 田lute;

le25;top: 245; width: 640~ height: 27 50; z‑index:‑l/>

<v:textbox style='position:absolute; le25;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 sle='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> 

ドキュメント内 Sapidによるソフトウェア解析技法 (ページ 104-113)