先看张代码审计的图
代码审计对于小白来说可能比较陌生,但实际上也就是拿到某网站的源码进行审计,从而发现漏 洞。但是在审计的过程中不可能一行一行的去看,不仅浪费时间,看的久了也可能有些遗漏点,所以使用工具进行协助,就会快很多,比如“Seay源代码审计系统2.1”就很方便,可以查找定位代码,但误报很高。
在做代码审计的时候建议先把审计的cms看看,熟悉下功能,也可以先进行黑盒测试,知道哪里有问题,然后去找会容易很多。
代码审计漏洞类型
1、SQL注入
2、文件上传(上传/写入/读取/删除)
3、文件包含
4、命令执行
5、XSS
6、cookie欺骗
7、逻辑漏洞等
XSS漏洞分析
审计环境:windows环境(Apache+MYSQL+php),可以使用集成的wampserver,phpstudy等。
XSS漏洞
XSS有叫CSS(Cross Site Script),跨站脚本攻击。是恶意攻击者往web页面里插入恶意html代码,当用户浏览该页时,嵌入其中Web里面的html代码会被执行,从而达到恶意用户的特殊目的。XSS分为存储型xss和反射型,基于DOM的跨站脚本XSS。
【反射型】
反射型xss审计的时候基本的思路都一样,通过寻找可控没有过滤(或者可以绕过)的参数,通过echo等输出函数直接输出。寻找的一般思路就是寻找输出函数,再去根据函数寻找变量。一般的输出函数有这些:
print,print_r,echo,printf,sprintf,die,var_dump,var_export。
XSS漏洞
分析如下,首先看下源码
<?php
// Is there any input?
if( array_key_exists("name",
// Feedback for end user
echo '<pre>Hello ' . $_GET[ 'name'] . '</pre>';
}
?>
这里能看到if里面的php函数array_key_exists,百度就可以查到他的用法等。
array_key_exists()函数检查某个数组中是否存在指定的键名,如果键名存在则返回true,如果键名不存在则返回false。
输入的值也就是GET得到的值是以数组的形式,然后判断GET得到的name是不是空,如果满足if语句,这里就会进行if括号里面的,echo '<pre>Hello ' . $_GET[ 'name' ] . '</pre>';我们可以清楚的看到,这里直接输出传的name参数,并没有任何的过滤与检查,存在明显的XSS漏洞。
这里可以看下medium中等难度下的代码
<?php
// Is there any input?
if( array_key_exists( "name",
// Get input
name = str_replace( '<script>', '',
// Feedback for end user
echo "<pre>Hello ${name}</pre>";
}
?>
可以看到有一点上low的代码是不一样的,那就是进行了一次过滤,用的str_replace()函数,这个函数的功能是:以其他字符替换字符串中的一些字符(区分大小写)。
这里的作用是替换<script>,也就是把<script>替换成空格,然后再进行输出。
这里对输入进行了过滤,基于黑名单的思想,使用str_replace函数将输入中的<script>删除,这种防护机制是可以被轻松绕过的。
双写绕过:输入<sc<script>ript>alert(/xss/)</script>,成功弹框。
大小写混淆绕过:输入<ScRipt>alert(/xss/)</script>,成功弹框。这里就不截图了。
High等级也是基于黑名单思想,进行过滤。但是我们可以通过其他标签来进行XSS。
name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '',
代码如上。
【存储型】
存储型XSS审计和反射型XSS审计思路差不多,不过存储型XSS会在数据库“中转”一下,主要审计sql语句update,insert更新和插入。
进行审计前,先进行黑盒测试。
<?php
if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
message = trim( _POST[ 'mtxMessage' ] );
name = trim( _POST[ 'txtName' ] );
// Sanitize message input
message = stripslashes( message );
message = mysql_real_escape_string( message );
// Sanitize name input
name = mysql_real_escape_string( name );
// Update database
query = "INSERT INTO guestbook ( comment, name ) VALUES ( '
result = mysql_query( query ) or die( '<pre>' . mysql_error() . '</pre>' );
//mysql_close();
}
?>
可以看到接收POST过来的参数,trim()函数是移除字符串两侧的空白字符或其他预定义字符。
这里先进行过滤一下,把我们输入字符串两侧的空白字符和其他预定义字符给过滤掉。预定义字符包括:\t,\n,\x0B,\r以及空格。
message = stripslashes( message );
然后stripslashes()函数:删除反斜杠
然后message参数再经过mysql_real_escape_string()函数进行转义。
mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符
受影响字符
\x00
\n
\r
\
'
"
\x1a
如果成功,则该函数返回被转义的字符串。如果失败,则返回 false。
最后给插入数据库。这个时候我们去数据库看一下,如下图,可以看到xss代码已经插入数据库了,这也就是存储型XSS与反射性XSS的区别。
因为我们在前端看到的都是经由数据库传过来的数据,所以会弹出框框。
还有medium,high,这里就不做分析了,这里解决XSS漏洞的方法就是用htmlspecialchars函数进行编码。但是要注意的是,如果htmlspecialchars函数使用不当,攻击者就可以通过编码的方式绕过函数进行XSS注入,尤其是DOM型的XSS。