首页 > 代码库 > 代码审计基础知识

代码审计基础知识

代码审计函数篇

addslashed() 添加反斜杠

stripslashed() 去掉反斜杠

get_magic_quotes_gpc() 判断是否开启gpc

expode(".",$array) 分割成数组

is_numeric() 判断是否为数字

sizeof() 判断长度

trim() 去处字符串开头和末尾的空格或其他字符

exec() 不输出结果,返回最后一行shell结果,所以结果可以保存到一个返回的数组里面

passthru()只调用命令,把命令的运行结果原样地直接输出到标准输出设备上

EscapeShellCmd() 把一个字符串中所有可能瞒过Shell而去执行另外一个命令的字符转义.这些字符在Shell中是有特殊含义的,象分号(;),重定向(>)和从文件读入(<)等.

EscapeShellArg() 在给定的字符串两边加上单引号,并把字符串中的单引号转义,这样这个字符串就可以安全地作为命令参数.

extract() 函数从数组中把变量导入到当前的符号表中。对于数组中的每个元素,键名用于变量名,键值用于变量值。

parse_str() 函数把查询字符串解析到变量中。(常用于变量覆盖漏洞)

parse_str(string.array)

string 必需。规定要解析的字符串

array 可选。规定存储变量的数组名称。该参数指示变量存储到数组中。

eval() 函数把字符串按照PHP代码来计算。该字符串必须是合法的PHP代码,且必须以分号结尾。

preg_replace 执行一个正则表达式的搜索和替换

/e 参数执行代码

htmlspecialchars() 函数把预定义的字符串转换为HTML实体

strip_tags() 函数,去除html标签

empty() 函数---检查一个变量是否为空

bool empty(mixed $var) 如果var是非空或非零的值,则empty()返回FALSE,如果var为空,则返回True

很明显,""、0、"0"、NULL、FALSE、array()、var $var,以及没有任何属性的对象都将被认为是空的。

strtolower() 函数把所有字符转换为小写

str_replace() 函数以其他字符替换字符串中的一些字符(区分大小写)。

mysql_real_escape_string() 函数转义SQL语句中使用的字符串中的特殊字符

unset() 函数销毁指定变量

is_array()判断变量类型是否为数组类型

safe_mode_exec_dir() 指定可执行文件的路径

implode()函数返回由数组元素组合成的字符串

intval()函数将变量转换成int类型.

$_SERVER["QUERY_STRING"] 获取查询语句,获取的是?后面的值

intval() 变量转成整数类型

stripos() 查找字符串在另一个字符串中第一次出现的位置 

strlen() 函数返回字符串的长度 

stripslashes()函数删除由 addslashes()函数添加的反斜杠 

mysql_query() 函数执行一条MySQL查询 

 

 

2、输入验证和输出显示

2.1、 命令注入(执行)

函数:

system()、passthru()、popen()、exec()

数据库操作函数:

exec(),system(),popen(),passthru(),proc_open(),shell_exec()

执行命令的管道符 % | >

2.2、 跨站脚本(XSS)

挖掘XSS漏洞的关键在于寻找没有被过滤的参数,且这些参数传入到输出函数,常用的输出函数列表如下:print、print_r、echo、printf、sprintf、die、var_dump、var_export,所以我们只要寻找带有变量的这些函数即可。

XSS漏洞比SQL注入更多,而且在满足业务需求的情况下更加难防御。XSS漏洞经常出现在文章发表、评论回复、留言以及资料设置等地方。

反射型跨站常常出现在用户提交的变量接受以后经过处理,直接输出显示给客户端;

存储型跨站常常出现在用户提交的变量接受经过处理后,存储在数据库里,然后又从数据库中读取到此信息输出到客户端。

反射性XSS

反射性XSS也就是我们描述里面说直接通过外部输入然后在浏览器端输出触发的类型,这种类型的漏洞比较容易通过扫描器黑盒直接发现,只需要将尖括号、单双引号等提交到WEB服务器,检查返回的HTML页面有没有保留原来的特殊字符即可判断。

存储性XSS

存储性XSS,顾名思义也就是需要先把利用代码保存在比如数据库或文件中,当web程序读取利用代码并输出在页面上时执行利用代码。

2.3、文件包含

一般存在于模块加载、模板加载、cache调用

包括函数:include()/include_once()、require()/require_once()寻找可控变量

远程文件包含是指可以包含远程文件的包含漏洞,远程文件包含需要设置allow_url_include = On

条件:在allow_url_include = On且PHP >= 5.2.0的条件下 ,利用的时候采用data://或者php://input是一个不错的选择。

x.php?path=data://text/plain;base64,PD9waHBpbmZvKCk7Lyo=
x.php?path=data:;base64,PD9waHBpbmZvKCk7Lyo=
x.php?inc=data:;base64,PD9waHAgZWNobyBwaHBpbmZvKCk7Pz4= //phpinfo()
截断方式:
%00(GPC开启时会转义) 长文件名(///////)
注:php5.3.4以后已经修复了%00漏洞

 

2.4、代码注入

2.5、SQL注入

SQL注入漏洞的原理非常简单,由于开发者在编写操作系统数据库代码时,直接将外部可控的参数拼接到SQL语句中,没有经过任何过滤就直接放入数据库引擎执行。

concat()函数是将两个字符串连接器起来,形成一个单一的字符串。

1、注入点类似id=1这种整型的参数就会完全无视GPC的过滤

  传入的参数未做intval转换、构造的sql语句没有单引号的保护

2、注入点包含键值对的,那么这里只检测了value,对key的过滤就没有防护

 

3、有时候全局过滤只过滤掉GET、POST、和COOKIE,但是没过滤SERVER等变量。常见的SERVER变量(QUERY_STRING,X_FORWARDED_FOE,CLIENT_IP、HTTP_HOST、ACCEPT_LANGUAGE)

 

挖掘漏洞参考

变量

$_GET[""],$_POST[""],$_COOKIE[""],$SERVER[""]

数据库操作函数

mysql_query()

数字型注入防范:

1、is_numeric() ctype_digit() intval()

2、str_length()确定长度

字符型注入防范:

1、mysql_real_escape_string()

2、数据库查询语句前加@防爆错

3、str_length() 确定长度

//字符型sql注入过滤
$id = stripslashes($id);
$id = mysql_real_escape_string($id);

 

<?php
if (!get_magic_quotes_gpc()) {
$lastname = addslashes($_POST[‘lastname’]);
} else {
$lastname = $_POST[‘lastname’];
}
//字符型sql注入过滤
$id = stripslashes($id);
$id = mysql_real_escape_string($id);

//str_replace()
echo $_GET[‘id‘]."<br/>";
echo addslashes(urldecode($_SERVER[‘QUERY_STRING‘]));
?>

 

2.6、XPath注入

2.7、HTTP响应拆分

HTTP响应拆分漏洞,也叫CRLF注入攻击。CR、LF分别对应回车(%0d)、换行(%0a)字符。HTTP头由很多被CRLF组合分离的行构成,每行的结构都是"键:值"。如果用户输入的值部分注入了CELF字符,它有可能改变的HTTP报头结构。

2.8、文件管理

2.9、文件上传

2.10、变量覆盖

2.11、动态函数

3、会话安全

3.1、HTTPOnly设置

3.2、domain设置

3.3、path设置

3.4、cookies持续时间

3.5、secure设置

3.6、session固定

3.7 CSRF

4、加密

4.1、明文存储密码

4.2、密码弱加密

4.3、密码存储在攻击者能访问到的文件

5 认证和授权

5.1、用户认证

5.2、函数或文件的未认证调用

5.3、密码硬编码

6、随机函数

6.1、rand()

6.2、mt_srand()和mt_rand()

7、特殊字符和多字节编码

7.1、多字节编码

8、PHP危险函数

8.1、缓冲区溢出

8.2、session_destroy()删除文件漏洞

8.3、unset() zend_hash_del_key_or_index漏洞

9、 信息泄露

9.1、phpinfo

10、PHP环境

10.1、 open_basedir设置

10.2、 allow_url_fopen设置

10.3、 allow_url_include设置

10.4、 safe_mode_exec_dir设置

10.5、 magic_quote_gpc设置

10.6、 register_globals设置

10.7、 safe_mode设置

10.8、 session_use_trans_sid设置

10.9、 display_errors设置

10.10、expose_php设置

 

代码审核,是对应用程序源代码进行系统性检查的工作。它的目的是为了找到并且修复应用程序在开发阶段存在的一些漏洞或者程序逻辑错误,避免程序漏洞被非法利用给企业带来不必要的风险。

代码审核不是简单的检查代码,审核代码的原因是确保代码能安全的做到对信息和资源进行保护,所以熟悉整个应用程序的业务流程对于控制潜在的风险非常重要的。审核人员可以使用类似下面的问题对开发者进行访谈,来收集应用程序信息。

应用程序中包含什么类型的敏感信息,应用程序怎么保护这些信息的?

应用程序对内提供服务,还有对外?哪些人会使用,他们都是可信用户么?

应用程序部署在哪里?

应用程序对于企业的重要性?

2、输入验证和输出显示

大多数漏洞形成原因主要都是未对输入数据进行安全验证或输出数据未经过安全处理,比较严格的数据验证方式为:

1、对数据进行精确匹配

2、接受白名单的数据

3、拒绝黑名单的数据

4、对匹配黑名单的数据进行编码

 

在PHP中可由用户输入的变量列表如下:

$_SERVER

$_GET

$_POST

$_COOKIE

$_REQUEST

$_FILES

$_ENV

$_HTTP_COOKIE_VARS

$_HTTP_ENV_VARS

$_HTTP_GET_VARS

$_HTTP_POST_FILES

$_HTTP_POST_VARS

$_HTTP_SERVER_VARS

代码审计基础知识