对pikachu靶场进行代码审计,审计分析文件上传、命令执行漏洞,越权漏洞,sql注入,xxe漏洞
文件上传
client:
并未对后缀进行判断,只对大小做了验证
后端并未进行文件的类型校验,仅仅是生成了一个目录去保存上传的文件
同时对文件的保存路径暴露
MIME Type
只对mime进行了验证,很容易绕过,没使用白名单机制,过滤的不够严谨
getimagesize
对文件的类型和mime都进行了校验,但是还是可以执行,php的代码,可以上传图片马,使用文件包含一起梭哈。主要问题还是回显了upload的保存路径,这样前面生成的随机数毫无意义!
命令执行漏洞
ping远程执行漏洞
包含了header文件
header文件,并未有啥过滤,就是获取访问者的头信息等
判断是否有输入,并将传输进来的参数赋值给ip变量,判断当前电脑是什么类型,直接shell_exec执行了命令
未对$ip进行验证,就直接将变量拼接,不安全,同时调用shell_exec等函数也有极大的风险
eval远程代码执行漏洞
对用户的输入没有校验,而且使用了eval函数,攻击者可以直接使用system执行系统命令。因对用户的输入进行检查,同时少使用或者不使用eval函数。
越权漏洞
水平越权
先看login界面,使用了escape函数转义查询语句很安全,然后使用了session确定登录的人是谁。
看信息页面,第一个判断是否登录,第二个直接判断了username是否为空,但是此处并未使用session来确定用户的输入,导致了水平越权的漏洞。
垂直越权
和上面相同使用了,escape函数转义防sql注入,然后链接数据库判断是否有该用户,判断返回的level,进行登录
看admin登录界面,有对level的判断,要同时满足登录和level等于1才能进入,没有问题
看修改用户信息的页面,此处只判断了用户是否处于登录的界面,但是并没有判断用户的level是否等于1,造成垂直越权的漏洞。
同时我们还需要注意exit,如果对exit进行注释,即使有header的跳转但是程序并不会完结会继续执行
注意:此时我是未登录的状态,但是我依然会执行后面的if判断,此处需要注意,header只能跳转并不能结束代码执行。
sql注入
宽字节注入
先看一下escape函数,使用了mysqli_real_escape_string转义,转义规则如下
'
会被转义为\'
"
会被转义为\"
\
会被转义为\\
此处刚好可以使用gbk的编码方式绕过,主要的漏洞就是上图箭头,在转义后给客户端设置了gbk编码
其余的sql注入
剩下的都是直接拼接产生的漏洞,所使用的只是不同的闭合方式,此处就不在赘述
xxe漏洞
使用了simplexml_load_string函数,将 XML 字符串转换为 SimpleXMLElement 对象的函数。造成了外部xml的注入。可以使用libxml_disable_entity_loader(ture)禁止从外部加载xml实体
梳理php语言中 owasp top 10 安全漏洞常见的危险函数并记录函数的常见用法
命令执行危险函数
- system 执⾏命令并输出结果
- shell_exec
- passthru 和system一样
- exec 执⾏命令只可获取最后⼀⾏结果
- popen 执⾏命令并建⽴管道 返回⼀个指针 使⽤fread等函数操作指针进⾏读写
- proc_open 同 popen
- pcnti_exec 执⾏命令只返回是否发⽣错误
- mail linux底层的sendmail发送信息,通过 -X 指定log文件记录邮件流量,实际可以达到写文件的效果
例子
$to = 'Alice@example.com';
$subject = 'Hello Alice!';
$message=‘<?php phhpinfo(); ?>’;
$headers = "CC: somebodyelse@example.com";
$options = '-OQueueDirectory=/tmp -X/var/www/html/rce.php';
mail($to, $subject, $message, $headers, $options);
代码执行危险函数
- eval 将传⼊的参数内容作为PHP代码执⾏ eval 不是函数 是⼀种语法结构 不能当做函数动态调⽤
- assert 将传⼊的参数内容作为PHP代码执⾏ 版本在PHP7以下是函数PHP7及以上为语法结构
- preg_replace 当preg_replace使⽤/e修饰符且原字符串可控时时 有可能执⾏php代码
- call_user_func 把第⼀个参数作为回调函数调⽤需要两个参数都完全可控才可利⽤ 只能传⼊⼀个参数调⽤
- create_funtion 根据传递的参数创建匿名函 数,并为其返回唯⼀名称 利⽤需要第⼆个参数可控 且创建的函数被执⾏
- include 包含并运⾏指定⽂件 执⾏出错会抛出错误,但是会继续执行
- require 同include 执⾏出错会抛出警告
- include_once 同require 但会检查之前是否已经包含该⽂件 确保不重复包含
- require_once 同include 但会检查之前是否已经包含该⽂件 确保不重复包含
文件读取危险函数
- file_get_contents 读⼊⽂件返回字符串
- readfile 读取⼀个⽂件,并写⼊到输出缓冲
- fopen/fread/fgets/fgetss/fgetc/fgetcsv/fpassthru/fscanf 打开⽂件或者 URL读取⽂件流
- file 把整个⽂件读⼊⼀个数组中
- highlight_file 语法⾼亮⼀个⽂件
- parse_ini_file 读取并解析⼀个ini配置⽂件
- simplexml_load_file 读取⽂件作为XML⽂档解析
文件上传危险函数
- file_put_contents 将⼀个字符串写⼊⽂件
- move_uploaded_file 将上传的临时⽂件移动到新的位置
- rename 重命名⽂件/⽬录
- unlink 删除⽂件
- rmdir 删除⽬录
- extractTo 解压ZIP到⽬录
- simplexml_load_string 加载解析XML字符串 有可能存在XXE 漏洞
- simplexml_load_file 读取⽂件作为XML⽂档解析 有可能存在XXE 漏洞
- request()->file()->move()
- request()->file()->file() thinkphp文件