「代码审计」哪些代码审计的思路
<h1 style="color: black; text-align: left; margin-bottom: 10px;">前言</h1>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">代码审计工具的实现都是基于代码审计经验<span style="color: black;">研发</span>出来用于优化工作效率的工具,<span style="color: black;">咱们</span>要学好代码审计就必须要<span style="color: black;">熟练</span>代码审计的思路。<span style="color: black;">况且</span>代码审计是基于PHP语言<span style="color: black;">基本</span>上学习的,学习代码审计最基本的<span style="color: black;">需求</span><span style="color: black;">便是</span>能读懂代码。<span style="color: black;">平常</span>的代码审计思路有以下四种:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">按照</span><span style="color: black;">敏锐</span>关键字回溯参数传递过程;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">查询</span>可控变量,正向<span style="color: black;">跟踪</span>变量传递过程;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">寻找<span style="color: black;">敏锐</span>功能点,通读功能点代码;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">直接通读全文代码。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">敏锐</span>函数回溯参数过程</p><span style="color: black;">按照</span><span style="color: black;">敏锐</span>函数来逆向<span style="color: black;">跟踪</span>参数的传递过程,是<span style="color: black;">日前</span><span style="color: black;">运用</span>的最多的一种方式,<span style="color: black;">由于</span>大<span style="color: black;">都数</span>漏洞是<span style="color: black;">因为</span>函数的<span style="color: black;">运用</span><span style="color: black;">欠妥</span><span style="color: black;">导致</span>的。<span style="color: black;">另一</span>非函数<span style="color: black;">运用</span><span style="color: black;">欠妥</span>的漏洞,如SQL注入,等以后学习再<span style="color: black;">仔细</span>介绍。这种方式的优缺点如下:
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">优点:只需搜索相应<span style="color: black;">敏锐</span>关键字,<span style="color: black;">就可</span>快速挖掘想要的漏洞,可定向挖掘,<span style="color: black;">有效</span>、高质量;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">缺点:<span style="color: black;">因为</span><span style="color: black;">无</span>通读代码,对程序整体架构<span style="color: black;">认识</span><span style="color: black;">不足</span>深入,在挖掘漏洞时定位利用会花点时间,<span style="color: black;">另一</span>对<span style="color: black;">规律</span>漏洞挖掘覆盖不到。</p>espcms注入挖掘案例:
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">下载网址:</span><span style="color: black;"><span style="color: black;"><span style="color: black;">http://down.chinaz.com/soft/27695.htm</span></span></span>
</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">下载espcms源程序</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">(ps:<span style="color: black;">有些</span>程序源代码<span style="color: black;">能够</span>在chinaz.com上面下载)</p>打开seay源代码审计系统,点击左上角新建项目,<span style="color: black;">选取</span>下载的espcms文件夹,点击自动审计,<span style="color: black;">起始</span>审计,得到可能存在漏洞,漏洞文件的路径,和漏洞代码列表。
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">咱们</span>挑选其中的一条代码</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">双击直接定位到这行代码,选中该变量后,<span style="color: black;">能够</span>看到变量的传递过程,在左侧点击parentid函数,在下面<span style="color: black;">仔细</span>信息的<span style="color: black;">地区</span><span style="color: black;">能够</span>看到</span><span style="color: black;">parentid</span><span style="color: black;">函数,在下面<span style="color: black;">仔细</span>信息的<span style="color: black;">地区</span><span style="color: black;">能够</span>看到parentid变量<span style="color: black;">得到</span>。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">右键选中这行代码,定位函数主体accept,点击右键,<span style="color: black;">选取</span>定位函数</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">能够</span>看到<span style="color: black;">转</span>到了class_function.php文件,代码如下:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">能够</span>看到这是一个获取GET、POST、COOKIE参数值得函数,<span style="color: black;">咱们</span>传入的变量是parentid和R,则<span style="color: black;">表率</span>在POST、GET中都<span style="color: black;">能够</span>获取parentid参数,最后经过一个daddslashes()函数,<span style="color: black;">实质</span>上是包装的addslashes()函数,对单引号等字符进行过滤。看前面的SQL语句是<span style="color: black;">这般</span>的:</p>$sql = “select * from db_table where parentid=<span style="color: black;">dbt</span><span style="color: black;">ablewhereparentid</span><span style="color: black;">
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">=parentid”;</p>并不需要单引号来闭合,<span style="color: black;">能够</span>直接注入。
</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">在citylist.php文件看到oncitylist()函数在important类中,选中该类名右键点击,<span style="color: black;">选取</span>全局搜索</p><span style="color: black;">能够</span>看到index.php文件有实例化该类,代码如下:$archive = indexget(‘archive’, ‘R’);
$archive = <span style="color: black;">empty</span>($archive) ? ‘adminuser’ : $archive;
$action = indexget(‘action’, ‘R’);
$action =<span style="color: black;">empty</span>($action) ? ‘login’ : $action;
$soft_MOD = <span style="color: black;">array</span>(‘admin’, ‘<span style="color: black;">public</span>’, ‘product’, ‘forum’, ‘filemanage’, ‘basebook’, ‘member’, ‘order’, ‘other’, ‘news’, ‘inc’, ‘cache’, ‘bann’, ‘logs’, ‘template’);<span style="color: black;">if</span> (in_array($point, $soft_MOD)) {
<span style="color: black;">include</span>admin_ROOT . adminfile . “/control/$archive.php”;
$control =<span style="color: black;">new</span> important();
$action = ‘on’ . $action;
<span style="color: black;">if</span> (method_exists($control, $action)) {
$control->$action();
} <span style="color: black;">else</span> {
<span style="color: black;">exit</span>(‘错误:系统<span style="color: black;">办法</span>错误!’);
}<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">这儿</span><span style="color: black;">能够</span>看到一个include文件的操作,可惜经过了addslashes()函数<span style="color: black;">没法</span>进行<span style="color: black;">周期</span>使其<span style="color: black;">包括</span>任意文件,只能<span style="color: black;">包括</span>本地的PHP文件,往下是实例化类并且调用函数的操作,<span style="color: black;">按照</span>代码<span style="color: black;">能够</span>构造出利用EXP:</span></p><span style="color: black;">http</span>:<span style="color: black;">//127.0.0.1/espcms/upload/adminsoft/index.php?archive=citylist&action=citylist&parentid=-1 union select 1,2,user(),4,5</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">通读全文代码</p>通读全文代码<span style="color: black;">亦</span>有<span style="color: black;">必定</span>的技巧,否则很难读懂Web程序的,<span style="color: black;">亦</span>很难理解代码的业务<span style="color: black;">规律</span>。<span style="color: black;">首要</span><span style="color: black;">咱们</span>要看程序的大体结构,如主目录有<span style="color: black;">那些</span>文件,模块目录有<span style="color: black;">那些</span>文件,插件目录有<span style="color: black;">那些</span>文件,<span style="color: black;">另一</span>还要<span style="color: black;">重视</span>文件的<span style="color: black;">体积</span>,创建时间,就<span style="color: black;">能够</span>大概<span style="color: black;">晓得</span>这个程序实现了<span style="color: black;">哪些</span>功能,核心文件有<span style="color: black;">那些</span>。
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">如discuz的主目录如下图所示:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">在看目录结构的时候,<span style="color: black;">尤其</span><span style="color: black;">重视</span>以下几个文件:</span></p><span style="color: black;">
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">函数集文件</p>函数集文件<span style="color: black;">一般</span>命名中<span style="color: black;">包括</span>functions<span style="color: black;">或</span>common等关键字,这些文件里面是<span style="color: black;">有些</span>公共的函数,<span style="color: black;">供给</span>给其他文件统一调用,<span style="color: black;">因此</span>大<span style="color: black;">都数</span>文件都会在文件头部<span style="color: black;">包括</span>到其他文件。寻找这些文件的一个技巧<span style="color: black;">便是</span>打开index.php<span style="color: black;">或</span><span style="color: black;">有些</span>功能性文件。
</span><span style="color: black;">
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">配置文件</p>配置文件<span style="color: black;">一般</span>命名中<span style="color: black;">包括</span>config关键字,配置文件<span style="color: black;">包含</span>Web程序运行必须的功能性配置选项以及数据库等配置信息。从这个文件<span style="color: black;">能够</span><span style="color: black;">认识</span>程序的小部分功能,<span style="color: black;">另一</span>看这个文件的时候<span style="color: black;">重视</span>观察配置文件中参数是用单引号还是双引号,<span style="color: black;">倘若</span>是双引号,则很可能会存在代码执行漏洞。
</span><span style="color: black;">
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">安全过滤文件</p>安全过滤文件对<span style="color: black;">咱们</span>做代码审计至关重要,<span style="color: black;">一般</span>命名中有filter、safe、check等关键字,这类文件<span style="color: black;">重点</span>是对参数进行过滤,比较<span style="color: black;">平常</span>的是针对SQL注入和XSS过滤,还有文件路径、执行的系统命令的参数。
</span><span style="color: black;">
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">index文件</p>index是一个程序的入口文件,<span style="color: black;">因此</span><span style="color: black;">咱们</span>只要读一遍index文件就<span style="color: black;">能够</span>大致<span style="color: black;">认识</span><span style="color: black;">全部</span>程序的架构、运行的流程、<span style="color: black;">包括</span>到的文件。
</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">骑士cms通读审计案例</p>(1)查看应用文件结构
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">首要</span><span style="color: black;">瞧瞧</span>有<span style="color: black;">那些</span>文件和文件夹,寻找名<span style="color: black;">叫作</span>里有<span style="color: black;">无</span>带api、admin、manage、include一类关键字的文件和文件夹。<span style="color: black;">能够</span>看到有一个include文件夹,<span style="color: black;">通常</span>比较核心的文件都会放在这个文件夹中。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">(2)查看关键文件代码</p>在这个文件夹里<span style="color: black;">能够</span>看多多个数十K的文件,弱common.fun.php<span style="color: black;">便是</span>本程序的核心文件,<span style="color: black;">基本</span>函数基本就在这个文件中实现。一打开文件,<span style="color: black;">马上</span>看多一大堆过滤函数,<span style="color: black;">首要</span>是一个SQL注入过滤函数:
<span style="color: black;"><span style="color: black;">function</span> <span style="color: black;">addslashes_deep</span><span style="color: black;">($value)</span>
</span>{
<span style="color: black;">if</span> (<span style="color: black;">empty</span>($value))
{
<span style="color: black;">return</span> $value;
}
<span style="color: black;">else</span>
{
<span style="color: black;">if</span>(!get_magic_quotes_gpc())
{
$value=is_array($value) ? array_map(‘addslashes_deep’, $value) : mystrip_tags(addslashes($value));
}<span style="color: black;">else</span>{
$value=is_array($value) ? array_map(‘addslashes_deep’, $value) : mystrip_tags($value);
}<span style="color: black;">return</span> $value;
}
}
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">该函数将传入的变量<span style="color: black;">运用</span>addslashes()函数进行过滤,过滤掉了单引号、双引号、NULL字符以及斜杠,要记住,在挖掘SQL注入漏洞时,只要参数在拼接到SQL语句前,除非有宽字节注入<span style="color: black;">或</span>其他特殊<span style="color: black;">状况</span>,否则使用了这个函数就<span style="color: black;">不可</span>注入了。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">再往下是一个XSS过滤的函数mystrip_tags(),代码如下:</span></p><span style="color: black;"><span style="color: black;">function</span> <span style="color: black;">mystrip_tags</span><span style="color: black;">($string)</span>
</span>{
$string = new_html_special_chars($string);
$string = remove_xss($string);<span style="color: black;">return</span> $string;
}
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">这个函数调用了new_html_special_chars()和remove_xss()函数来过滤XSS,代码如下:</span></p><span style="color: black;">function</span> new_html_special_chars(<span style="color: black;">$string</span>) {
<span style="color: black;">$string</span>= str_replace(array(‘&’, ‘<span style="color: black;">"’, ‘<’, ‘>’), array(‘&’, ‘“‘, ‘<’, ‘>’), <span style="color: black;">$string</span>);
<span style="color: black;">$string</span> = strip_tags(<span style="color: black;">$string</span>);
return <span style="color: black;">$string</span>;
}
function remove_xss(<span style="color: black;">$string</span>) {
<span style="color: black;">$string</span> = preg_replace(‘/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S’, ‘’, <span style="color: black;">$string</span>);
<span style="color: black;">$parm1</span>= Array(javascript, union,vbscript, expression, applet, xml, blink, link, script, embed, object, iframe, frame, frameset, ilayer, layer, bgsound, title, base);<span style="color: black;">$parm2</span>= Array(onabort, onactivate, onafterprint, onafterupdate, onbeforeactivate, onbeforecopy, onbeforecut, onbeforedeactivate, onbeforeeditfocus, onbeforepaste, onbeforeprint, onbeforeunload, onbeforeupdate, onblur, onbounce, oncellchange, onchange, onclick, oncontextmenu, oncontrolselect, oncopy, oncut, ondataavailable, ondatasetchanged, ondatasetcomplete, ondblclick, ondeactivate, ondrag, ondragend, ondragenter, ondragleave, ondragover, ondragstart, ondrop, onerror, onerrorupdate, onfilterchange, onfinish, onfocus, onfocusin, onfocusout, onhelp, onkeydown, onkeypress, onkeyup, onlayoutcomplete, onload, onlosecapture, onmousedown, onmouseenter, onmouseleave, onmousemove, onmouseout, onmouseover, onmouseup, onmousewheel, onmove, onmoveend, onmovestart, onpaste, onpropertychange, onreadystatechange, onreset, onresize, onresizeend, onresizestart, onrowenter, onrowexit, onrowsdelete, onrowsinserted, onscroll, onselect, onselectionchange, onselectstart, onstart, onstop, onsubmit, onunload,style,href,action,location,bac<span style="color: black;">公斤</span>round,src,poster);<span style="color: black;">$parm3</span>= Array(alert,sleep,load_file,confirm,prompt,benchmark,select,update,insert,delete,alter,drop,truncate,script,eval,outfile,dumpfile);<span style="color: black;">$parm</span> = array_merge(<span style="color: black;">$parm1</span>, <span style="color: black;">$parm2</span>, <span style="color: black;">$parm3</span>);
for (<span style="color: black;">$i</span> = 0; <span style="color: black;">$i</span> < sizeof(<span style="color: black;">$parm</span>); <span style="color: black;">$i</span>++) {
<span style="color: black;">$pattern</span> = /;
for (<span style="color: black;">$j</span> = 0; <span style="color: black;">$j</span> < strlen(<span style="color: black;">$parm</span>[<span style="color: black;">$i</span>]); <span style="color: black;">$j</span>++) {
if (<span style="color: black;">$j</span> > 0) {
<span style="color: black;">$pattern</span> .= (;
<span style="color: black;">$pattern</span>.= (&#0();?)?;<span style="color: black;">$pattern</span> .= |(�();?)?;
<span style="color: black;">$pattern</span> .= )?;
}
<span style="color: black;">$pattern</span> .= <span style="color: black;">$parm</span>[<span style="color: black;">$i</span>][<span style="color: black;">$j</span>];
}
<span style="color: black;">$pattern</span> .= /i;
<span style="color: black;">$string</span> = preg_replace(<span style="color: black;">$pattern</span>, ****,<span style="color: black;">$string</span>);
}
return <span style="color: black;">$string</span>;
}
</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">在new_html_special_chars()函数中<span style="color: black;">能够</span>看到,这个函数对&符号、双引号以及尖括号进行了html实体编码,并且<span style="color: black;">运用</span>strip_tags()函数进行了二次过滤。而remove_xss()函数则是对<span style="color: black;">有些</span>标签关键字、事件关键字以及<span style="color: black;">敏锐</span>函数关键字进行了替换。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">再往下有一个获取IP<span style="color: black;">位置</span>的函数getip(),是<span style="color: black;">能够</span>伪造IP<span style="color: black;">位置</span>的:</span></p><span style="color: black;"><span style="color: black;">function</span> <span style="color: black;">getip</span><span style="color: black;">()</span>
</span>{
<span style="color: black;">if</span> (getenv(‘HTTP_CLIENT_IP’) <span style="color: black;">and</span>strcasecmp(getenv(‘HTTP_CLIENT_IP’),’unknown’)) {
$onlineip=getenv(‘HTTP_CLIENT_IP’);
}<span style="color: black;">elseif</span> (getenv(‘HTTP_X_FORWARDED_FOR’) <span style="color: black;">and</span>strcasecmp(getenv(‘HTTP_X_FORWARDED_FOR’),’unknown’)) {
$onlineip=getenv(‘HTTP_X_FORWARDED_FOR’);
}<span style="color: black;">elseif</span> (getenv(‘REMOTE_ADDR’) <span style="color: black;">and</span>strcasecmp(getenv(‘REMOTE_ADDR’),’unknown’)) {
$onlineip=getenv(‘REMOTE_ADDR’);
}<span style="color: black;">elseif</span> (<span style="color: black;">isset</span>($_SERVER[‘REMOTE_ADDR’]) <span style="color: black;">and</span> $_SERVER[‘REMOTE_ADDR’] <span style="color: black;">and</span>strcasecmp($_SERVER[‘REMOTE_ADDR’],’unknown’)) {
$onlineip=$_SERVER[‘REMOTE_ADDR’];
}
preg_match(“/\d{<span style="color: black;">1</span>,<span style="color: black;">3</span>}.\d{<span style="color: black;">1</span>,<span style="color: black;">3</span>}.\d{<span style="color: black;">1</span>,<span style="color: black;">3</span>}.\d{<span style="color: black;">1</span>,<span style="color: black;">3</span>}/“,$onlineip,$match);
<span style="color: black;">return</span> $onlineip = $match[<span style="color: black;">0</span>] ? $match[<span style="color: black;">0</span>] : ‘unknown’;
}<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">非常多</span>应用都会<span style="color: black;">因为</span>在获取IP时<span style="color: black;">无</span>验证IP格式,而存在注入漏洞,<span style="color: black;">不外</span><span style="color: black;">这儿</span>只是<span style="color: black;">能够</span>伪造IP。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">再往下<span style="color: black;">能够</span>看到一个值得关注的<span style="color: black;">地区</span>,SQL<span style="color: black;">查找</span>统一操作函数inserttable()以及updatetable()函数,大<span style="color: black;">都数</span>SQL语句执行都会经过<span style="color: black;">这儿</span>,<span style="color: black;">因此</span><span style="color: black;">咱们</span>要关注这个<span style="color: black;">地区</span><span style="color: black;">是不是</span>还有过滤等问题。</span></p><span style="color: black;"><span style="color: black;">function</span> <span style="color: black;">inserttable</span><span style="color: black;">($tablename, $insertsqlarr, $returnid=<span style="color: black;">0</span>, $replace = false, $silent=<span style="color: black;">0</span>)</span> </span>{
<span style="color: black;">global</span>$db;
$insertkeysql = $insertvaluesql = $comma = ‘’;<span style="color: black;">foreach</span> ($insertsqlarr <span style="color: black;">as</span> $insert_key => $insert_value) {
$insertkeysql .= $comma.’<span style="color: black;">.$insert_key.</span>‘;
$insertvaluesql .= $comma.’\’’.$insert_value.’\’’;
$comma = ‘, ‘;
}
$method = $replace?’REPLACE’:’INSERT’;<span style="color: black;">// echo $method.” INTO $tablename ($insertkeysql) VALUES ($insertvaluesql)”, $silent?’SILENT’:’’;die;</span>
$state = $db->query($method.” INTO $tablename ($insertkeysql) VALUES ($insertvaluesql)”, $silent?’SILENT’:’’);
<span style="color: black;">if</span>($returnid && !$replace) {<span style="color: black;">return</span> $db->insert_id();
}<span style="color: black;">else</span> {
<span style="color: black;">return</span> $state;
}
}
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">再往下则是wheresql()函数,是SQL语句<span style="color: black;">查找</span>的Where<span style="color: black;">要求</span>拼接的<span style="color: black;">地区</span>,<span style="color: black;">咱们</span><span style="color: black;">能够</span>看到参数都<span style="color: black;">运用</span>了单引号进行包裹,代码如下:</span></p><span style="color: black;"><span style="color: black;">function</span> <span style="color: black;">wheresql</span><span style="color: black;">($wherearr=’’)</span>
</span>{
$wheresql=””;
<span style="color: black;">if</span> (is_array($wherearr))
{
$where_set=’ WHERE ‘;
<span style="color: black;">foreach</span> ($wherearr <span style="color: black;">as</span>$key => $value)
{
$wheresql .=$where_set. $comma.$key.’=”‘.$value.’”‘;
$comma = ‘<span style="color: black;">AND</span> ‘;
$where_set=’ ‘;
}
}
<span style="color: black;">return</span> $wheresql;
}
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">还有一个<span style="color: black;">拜访</span>令牌生成函数asyn_userkey(),拼接用户名、<span style="color: black;">秘码</span>salt以及<span style="color: black;">秘码</span>进行一次md5,<span style="color: black;">拜访</span>的时候只要在GET参数key的值里面加上生成的这个key<span style="color: black;">就可</span>验证<span style="color: black;">是不是</span>有权限,被用在注册、找回<span style="color: black;">秘码</span>等验证过程中,代码如下:</span></p><span style="color: black;"><span style="color: black;">function</span> <span style="color: black;">asyn_userkey</span><span style="color: black;">($uid)</span>
</span>{
<span style="color: black;">global</span>$db;
$sql = “select * from “.table(‘members’).” where uid = ‘“.intval($uid).”‘ LIMIT<span style="color: black;">1</span>”;
$user=$db->getone($sql);
<span style="color: black;">return</span>md5($user[‘username’].$user[‘pwd_hash’].$user[‘password’]);
}<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">(3)查看配置文件</p>上面<span style="color: black;">咱们</span>介绍到配置文件<span style="color: black;">一般</span>带有“config”<span style="color: black;">这般</span>的关键字,<span style="color: black;">咱们</span>只要搜索带有这个关键字的文件名<span style="color: black;">就可</span>:
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">在搜索结果中<span style="color: black;">咱们</span><span style="color: black;">能够</span>看到搜索到多个文件,结合经验<span style="color: black;">能够</span>判断config.php以及cache_config.php才是真正的配置文件,打开config.php查看代码:</span></p><?php
$dbhost = “localhost”;
$dbname =”<span style="color: black;">74</span>cms”;
$dbuser =”root”;
$dbpass =”<span style="color: black;">123456</span>”;
$pre =”qs<span style="color: black;">_</span>”;
$QS_cookiedomain = ‘’;
$QS_cookiepath = “/<span style="color: black;">74</span>cms/“;
$QS_pwdhash = “<span style="color: black;">K0ciF:</span>RkE4xNhu@S”;
define(‘QISHI_CHARSET’,’gb2312’);
define(‘QISHI_DBCHARSET’,’GBK’);
<span style="color: black;">?></span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">很<span style="color: black;">显著</span>看到,<span style="color: black;">特别有</span>可能存在<span style="color: black;">咱们</span>之前说过的双引号解析代码执行的问题,<span style="color: black;">一般</span>这个配置是在安装系统的时候设置的,<span style="color: black;">或</span>后台<span style="color: black;">亦</span>有设置的<span style="color: black;">地区</span>。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">瞧瞧</span>数据库连接时设置的编码,找到骑士cms连接MySQL的代码在include\mysql.class.php文件的connect()函数,代码如下:</span></p><span style="color: black;"><span style="color: black;">function</span> <span style="color: black;">connect</span><span style="color: black;">($dbhost, $dbuser, $dbpw, $dbname = ‘’, $dbcharset = ‘gbk’, $connect=<span style="color: black;">1</span>)</span></span>{
$func = <span style="color: black;">empty</span>($connect) ? ‘mysql_pconnect’ : ‘mysql_connect’;
<span style="color: black;">if</span>(!<span style="color: black;">$this</span>->linkid = @$func($dbhost, $dbuser, $dbpw,<span style="color: black;">true</span>)){
<span style="color: black;">$this</span>->dbshow(‘Can not connect to Mysql!’);
} <span style="color: black;">else</span> {
<span style="color: black;">if</span>(<span style="color: black;">$this</span>->dbversion() > ‘<span style="color: black;">4.1</span>’){
mysql_query( “SET NAMES gbk”);<span style="color: black;">if</span>(<span style="color: black;">$this</span>->dbversion() > ‘<span style="color: black;">5.0</span><span style="color: black;">.1</span>’){
mysql_query(“SET sql_mode = ‘’”,<span style="color: black;">$this</span>->linkid);
mysql_query(“SET character_set_connection=”.$dbcharset.”, character_set_results=”.$dbcharset.”, character_set_client=binary”,<span style="color: black;">$this</span>->linkid);
}
}
}
<span style="color: black;">if</span>($dbname){
<span style="color: black;">if</span>(mysql_select_db($dbname, <span style="color: black;">$this</span>->linkid)===<span style="color: black;">false</span>){
<span style="color: black;">$this</span>->dbshow(“Can’t select MySQL database($dbname)!”);
}
}
}
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">这段代码有个关键的<span style="color: black;">地区</span>,有安全隐患。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">代码<span style="color: black;">首要</span>判断MySQL版本<span style="color: black;">是不是</span>大于4.1,<span style="color: black;">倘若</span>是则执行下面代码:</p>
<span style="color: black;"><span style="color: black;">mysql_query( “SET NAMES gbk”);</span></span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">执行这个语句之后在判断,<span style="color: black;">倘若</span>版本大于5则执行下面代码:</p><span style="color: black;"><span style="color: black;">mysql_query(“SET character_set_connection=”.$dbcharset.”, character_set_results=”.$dbcharset.”, character_set_client=binary”, $this->linkid);</span></span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">亦</span><span style="color: black;">便是</span>说在MySQL版本<span style="color: black;">少于</span>5的<span style="color: black;">状况</span>下是不会执行这行代码的,</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">然则</span>执行了”set names gbk”,<span style="color: black;">咱们</span>在之前介绍过”set names gbk”其实干了三件事,等同于:</p><span style="color: black;"><span style="color: black;">SET character_set_connection=’gbk’, character_set_results=’gbk’, character_set_client=’gbk’</span></span><span style="color: black;">因此呢</span>在MySQL版本大于4.1<span style="color: black;">少于</span>5的<span style="color: black;">状况</span>下,基本所有跟数据库<span style="color: black;">相关</span>的操作都存在宽字节注入。
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">(4)跟读首页文件</p><span style="color: black;">经过</span>对系统文件大概的<span style="color: black;">认识</span>,<span style="color: black;">咱们</span>队这套程序的整体架构<span style="color: black;">已然</span>有了<span style="color: black;">必定</span>的<span style="color: black;">认识</span>,<span style="color: black;">然则</span>还<span style="color: black;">不足</span>,需要跟读一下index.php文件,<span style="color: black;">瞧瞧</span>程序运行的时候回调用<span style="color: black;">那些</span>文件和函数。
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">打开首页文件index.php<span style="color: black;">能够</span>看到如下代码:</span></p><span style="color: black;">if</span>(!file_exists(dirname(FILE).’/data/install.lock’))
header(“Location:install/index.php”);
define(‘IN_QISHI’,<span style="color: black;">true</span>);
$alias=”QS_index”;
<span style="color: black;">require_once</span>(dirname(FILE).’/<span style="color: black;">include</span>/common.inc.php’);
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">首要</span>判断安装锁文件<span style="color: black;">是不是</span>存在,<span style="color: black;">倘若</span>不存在则<span style="color: black;">转</span>到install\index.php</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">接下来是<span style="color: black;">包括</span>\include\common.inc.php文件,跟进文件查看</span></p>require_once(QISHI_ROOT_PATH.’<span style="color: black;">data</span>/config.php’);
header(“Content-Type:text/html;charset=”.QISHI_CHARSET);
require_once(QISHI_ROOT_PATH.’include/common<span style="color: black;">.<span style="color: black;">fun</span>.php’);</span>
require_once(QISHI_ROOT_PATH.’include/<span style="color: black;">74</span>cms_version.php’);
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">\include\common.inc.php文件在开头<span style="color: black;">包括</span>了三个文件,data\config.php为数据库配置文件,include\common.fun.php文件为<span style="color: black;">基本</span>函数库文件,include\74cms_version.php为应用版本文件。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">再看下面的代码:</span></p>f (!<span style="color: black;">empty</span>($_GET))
{
$_GET = addslashes_deep($_GET);
}<span style="color: black;">if</span> (!<span style="color: black;">empty</span>($_POST))
{
$_POST = addslashes_deep($_POST);
}
$_COOKIE = addslashes_deep($_COOKIE);
$_REQUEST = addslashes_deep($_REQUEST);<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">这段代码调用了include\common.fun.php文件里面的addslashes_deep()函数对GET、POST、COOKIE参数进行了过滤。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">再往下<span style="color: black;">能够</span>看到有一个<span style="color: black;">包括</span>文件的操作:</p>
<span style="color: black;"><span style="color: black;">require_once(QISHI_ROOT_PATH.’include/tpl.inc.php’);</span></span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">包括</span>了include\tpl.inc.php文件,跟进这个文件<span style="color: black;">瞧瞧</span>:</span></p>include_once(QISHI_ROOT_PATH.’<span style="color: black;">include</span>/template_lite/<span style="color: black;"><span style="color: black;">class</span>.<span style="color: black;">template</span>.<span style="color: black;">php</span>’);</span>$smarty = new Template_Lite;
$smarty -> cache_dir = QISHI_ROOT_PATH.’temp/caches/‘.$_CFG[‘template_dir’];
$smarty -> compile_dir = QISHI_ROOT_PATH.’temp/templates_c/‘.$_CFG[‘template_dir’];
$smarty -> template_dir = QISHI_ROOT_PATH.’templates/‘.$_CFG[‘template_dir’];
$smarty -> reserved_template_varname = “smarty”;
$smarty -> left_delimiter = “”;
$smarty -> force_compile =<span style="color: black;">false</span>;
$smarty -> assign(‘_PLUG’, $_PLUG);
$smarty -> assign(‘QISHI’, $_CFG);
$smarty -> assign(‘page_select’,$page_select);<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">首要</span>看到<span style="color: black;">包括</span>了include\template_lite\class.template.php文件,这是一个映射程序模板的类,继续往下看,<span style="color: black;">能够</span>看到这段代码实例化了这个类对象赋值给¥smarty变量。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">继续跟进则回到index.php文件代码:</span></p><span style="color: black;">if</span>(!$smarty->is_cached($mypage[‘tpl’],$cached_id))
{
require_once(QISHI_ROOT_PATH.’<span style="color: black;">include</span>/mysql<span style="color: black;">.<span style="color: black;">class</span>.<span style="color: black;">php</span>’);</span>$db = new mysql($dbhost,$dbuser,$dbpass,$dbname);
unset($dbhost,$dbuser,$dbpass,$dbname);
$smarty->display($mypage[‘tpl’],$cached_id);
}<span style="color: black;">else</span>
{
$smarty->display($mypage[‘tpl’],$cached_id);
}
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">判断<span style="color: black;">是不是</span><span style="color: black;">已然</span>缓存,<span style="color: black;">而后</span>调用display()函数输出页面。接下来像审计index.php文件<span style="color: black;">同样</span>跟进其他功能入口文件<span style="color: black;">就可</span>完成代码通读。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">按照</span>功能点定向审计</p><span style="color: black;">按照</span>经验<span style="color: black;">咱们</span>简单介绍几个功能点会<span style="color: black;">显现</span>的漏洞:<span style="color: black;">
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">文件上传功能</p><span style="color: black;">这儿</span>说的文件上传在<span style="color: black;">非常多</span>功能点都会<span style="color: black;">显现</span>,<span style="color: black;">例如</span>像<span style="color: black;">文案</span>编辑、资料编辑、头像上传、附件上传,这个功能最<span style="color: black;">平常</span>的漏洞<span style="color: black;">便是</span>任意文件上传了,后端程序<span style="color: black;">无</span>严格地限制上传的格式,<span style="color: black;">引起</span><span style="color: black;">能够</span>上传<span style="color: black;">或</span>存在绕过的<span style="color: black;">状况</span>,而除了文件上传功能外,还经常<span style="color: black;">出现</span>SQL注入漏洞。
</span><span style="color: black;">
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">文件管理功能</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">在文件管理功能中,如果程序将文件名<span style="color: black;">或</span>文件路径直接在参数中传递,则<span style="color: black;">特别有</span>可能会存在任意文件的操作漏洞,<span style="color: black;">例如</span>任意文件读取等,利用的<span style="color: black;">办法</span>是在路径中<span style="color: black;">运用</span>…/<span style="color: black;">或</span>…\<span style="color: black;">转</span>目录。</p>除了任意文件操作漏洞外,还可能会存在XSS漏洞,程序会在页面中输出文件名,而<span style="color: black;">一般</span>会疏忽对文件名进行过滤,<span style="color: black;">引起</span><span style="color: black;">能够</span>在数据库中存入带有尖括号等特殊符号的文件名,最后在页面<span style="color: black;">表示</span>的时候就会被执行。
</span><span style="color: black;">
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">登录认证功能</p>登录认证功能不<span style="color: black;">指的是</span>一个过程,而是<span style="color: black;">全部</span>操作过程中的认证,<span style="color: black;">日前</span>的认证方式大<span style="color: black;">大都是</span>基于Cookie和Session,不少程序会把当前登陆的用户账号等认证信息放到Cookie中,或许是加密方式。进行操作的时候直接从Cookie中读取当前用户信息,<span style="color: black;">这儿</span>就存在一个算法可信的问题,<span style="color: black;">倘若</span>这段Cookie信息<span style="color: black;">无</span>加salt一类的东西,就<span style="color: black;">能够</span><span style="color: black;">引起</span>任意用户登录漏洞,只要<span style="color: black;">晓得</span>用户的不扥信息,<span style="color: black;">就可</span>生成认证令牌,<span style="color: black;">乃至</span>有的程序会直接把用户名放到Cookie中,操作的时候直接读取这个用户名的数据,这<span style="color: black;">亦</span>是常说的越权漏洞。
</span><span style="color: black;">
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">找回<span style="color: black;">秘码</span>功能</p>找回<span style="color: black;">秘码</span>虽然看起来不像任意文件上传这种<span style="color: black;">能够</span><span style="color: black;">害处</span>到服务器安全的漏洞,<span style="color: black;">然则</span><span style="color: black;">倘若</span><span style="color: black;">能够</span>重置管理员的<span style="color: black;">秘码</span>,<span style="color: black;">亦</span>是<span style="color: black;">能够</span>间接<span style="color: black;">掌控</span>业务权限<span style="color: black;">乃至</span>拿到服务权限的。找回<span style="color: black;">秘码</span>功能的漏洞有<span style="color: black;">非常多</span>利用场景,最<span style="color: black;">平常</span>的是验证码爆破。<span style="color: black;">日前</span><span style="color: black;">尤其</span>是APP应用,请求后端验证码的时候大<span style="color: black;">大都是</span>4位,并且<span style="color: black;">无</span>限制验证码的错误次数和有效时间,于是就<span style="color: black;">显现</span>了爆破的漏洞。
</span>
页:
[1]