代码审计,大家估计见到最多的一般是web程序的代码审计。然而c/c++这种语言的代码审计估计就很少了。
今天我们要来学习一下,工欲善其事必先利其器,今天介绍一款审计的利器Flawfinder(当然同类的还有很多工具,比如
RATS,RIPS,VCG,Fortify SCA,GOLD,YASCA等等)。该工具我搭建运行在ubuntu16.0.4LTS系统之上。
Flawfinder是一个C/C++代码的开源安全审查工具,采用内建语法缺陷数据库,能够标记类似缓冲溢出、格式字符串、竞争条件、随
机数获取方面的问题。Flawfinder是一个非常简单的工具,采用的算法也不复杂,可以看做是一个基于词典的源代码静态分析器。
Flawfinder的开发者David Wheeler表示:很多软件开发者都在不断重复犯相同的错误,开发人员应当在软件部署前就
用Flawfinder审查代码。 官方地址http://www.dwheeler.com/flawfinder/
root@ubuntu:~/Desktop# flawfinder --h
*** getopt error: option --h not a unique prefix
flawfinder [--help | -h] [--version] [--listrules]
[--allowlink] [--followdotdir] [--nolink]
[--patch filename | -P filename]
[--inputs | -I] [--minlevel X | -m X]
[--falsepositive | -F] [--neverignore | -n]
[--context | -c] [--columns | -C] [--dataonly | -D]
[--html | -H] [--immediate | -i] [--singleline | -S]
[--omittime] [--quiet | -Q]
[--loadhitlist F] [--savehitlist F] [--diffhitlist F]
[--] [source code file or source root directory]+
The options cover various aspects of flawfinder as follows.
Documentation:
--help | -h Show this usage help.
--version Show version number.
--listrules List the rules in the ruleset (rule database).
Selecting Input Data:
--allowlink Allow symbolic links.
--followdotdir
Follow directories whose names begin with ".".
Normally they are ignored.
--nolink Skip symbolic links (ignored).
--patch F | -P F
Display information related to the patch F
(patch must be already applied).
Selecting Hits to Display:
--inputs | -I
Show only functions that obtain data from outside the program;
this also sets minlevel to 0.
-m X | --minlevel=X
Set minimum risk level to X for inclusion in hitlist. This
can be from 0 (``no risk'') to 5 (``maximum risk''); the
default is 1.
--falsepositive | -F
Do not include hits that are likely to be false positives.
Currently, this means that function names are ignored if
they're not followed by "(", and that declarations of char-
acter arrays aren't noted. Thus, if you have use a vari-
able named "access" everywhere, this will eliminate refer-
ences to this ordinary variable. This isn't the default,
because this also increases the likelihood of missing
important hits; in particular, function names in #define
clauses and calls through function pointers will be missed.
--neverignore | -n
Never ignore security issues, even if they have an ``ignore''
directive in a comment.
--regex PATTERN | -e PATTERN
Only report hits that match the regular expression PATTERN.
Selecting Output Format:
--columns | -C
Show the column number (as well as the file name and
line number) of each hit; this is shown after the line number
by adding a colon and the column number in the line (the first
character in a line is column number 1).
--context | -c
Show context (the line having the "hit"/potential flaw)
--dataonly | -D
Don't display the headers and footers of the analysis;
use this along with --quiet to get just the results.
--html | -H
Display as HTML output.
--immediate | -i
Immediately display hits (don't just wait until the end).
--singleline | -S
Single-line output.
--omittime Omit time to run.
--quiet | -Q
Don't display status information (i.e., which files are being
examined) while the analysis is going on.
Hitlist Management:
--savehitlist=F
Save all hits (the "hitlist") to F.
--loadhitlist=F
Load hits from F instead of analyzing source programs.
--diffhitlist=F
Show only hits (loaded or analyzed) not in F.
For more information, please consult the manpage or available
documentation.
代码
命令
flawfinder --columns --context main.c --html
也可以保存成文档
flawfinder --columns --context main.c --html > result.html
Flawfinder version 1.31, (C) 2001-2014 David A. Wheeler.
Number of rules (primarily dangerous function names) in C/C++ ruleset: 169
Examining main.c
Warning: Skipping non-existent file --html
FINAL RESULTS:
main.c:7:2: [5] (buffer) gets:
Does not check for buffer overflows (CWE-120, CWE-20). Use fgets() instead.
gets(ch,stdin);
main.c:6:2: [2] (buffer) char:
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119:CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
char ch[50];
ANALYSIS SUMMARY:
Hits = 2
Lines analyzed = 9 in approximately 0.01 seconds (1170 lines/second)
Physical Source Lines of Code (SLOC) = 9
Hits@level = [0] 0 [1] 0 [2] 1 [3] 0 [4] 0 [5] 1
Hits@level+ = [0+] 2 [1+] 2 [2+] 2 [3+] 1 [4+] 1 [5+] 1
Hits/KSLOC@level+ = [0+] 222.222 [1+] 222.222 [2+] 222.222 [3+] 111.111 [4+] 111.111 [5+] 111.111
Minimum risk level = 1
Not every hit is necessarily a security vulnerability.
There may be other security vulnerabilities; review your code!
See 'Secure Programming for Linux and Unix HOWTO'
(http://www.dwheeler.com/secure-programs) for more information.
main.c:7:2: [5] (buffer) gets: //第七行 没有检查buffer缓存会溢出。
Does not check for buffer overflows (CWE-120, CWE-20). Use fgets() instead.
gets(ch,stdin);
main.c:6:2: [2] (buffer) char: //第六行 静态分配的数组大小会被溢出。
Statically-sized arrays can be improperly restricted, leading to potential
overflows or other issues (CWE-119:CWE-120). Perform bounds checking, use
functions that limit length, or ensure that the size is larger than the
maximum possible length.
char ch[50];
ANALYSIS SUMMARY: //分析总结
Hits = 2 //两个可疑点
Lines analyzed = 9 in approximately 0.01 seconds (1170 lines/second) //总共9行代码用时0.01s
Physical Source Lines of Code (SLOC) = 9
Hits@level = [0] 0 [1] 0 [2] 1 [3] 0 [4] 0 [5] 1
Hits@level+ = [0+] 2 [1+] 2 [2+] 2 [3+] 1 [4+] 1 [5+] 1
Hits/KSLOC@level+ = [0+] 222.222 [1+] 222.222 [2+] 222.222 [3+] 111.111 [4+] 111.111 [5+] 111.111
Minimum risk level = 1
Not every hit is necessarily a security vulnerability. //注意此处,不是所有的可疑点都是安全漏洞
There may be other security vulnerabilities; review your code!
See 'Secure Programming for Linux and Unix HOWTO'
(http://www.dwheeler.com/secure-programs) for more information.
自动化的静态代码审计工具虽然可以在某种程度节省代码审计的人力成本,时间成本。
是提高代码审计效率的重要手段。然而需要注意的是,自动化工具并非是完全智能准确的,
跟所有的检测扫描工具一样,误报率的存在仍然是必须面对的现实问题。因此,检测结果
中显示的漏洞还是需要审计人员,手动验证或者手工进一步确认是否真的存在。