【如需转载,请详细表明来源,请勿设置原创】
嗨,大家好,我是闪石星曜CyberSecurity创始人Power7089。
欢迎大家扫描下方二维码关注 “闪石星曜CyberSecurity” 公众号,这里专注分享渗透测试,Java代码审计,PHP代码审计等内容,都是非常干的干货哦。
今天为大家带来PHP代码审计基础系列文章第九篇之任意文件读取篇。
这是【炼石计划@PHP代码审计】知识星球第二阶段的原创基础系列文章,拿出部分课程分享给零基础的朋友学习。本系列原创基础文章涵盖了PHP代码审计中常见的十余种WEB漏洞,是匹夫老师精心的创作,欢迎关注我的公众号跟着一起学习。
【炼石计划@PHP代码审计】是一个系统化从入门到提升学习PHP代码审计的成长型知识星球。这里不仅注重夯实基础,更加专注实战进阶。强烈推荐加入我们,一起来实战提升PHP代码审计。
PHP代码审计之任意文件读取
1.任意文件读取原理
在一些文件下载以及浏览的功能点中存在一些文件读取的函数,且参数中的文件名或者路径可以由用于控制且关键字符未能进行有效的过滤就会造成任意文件读取。
2.任意文件读取危害
①如果读取路径没有限制则可读取系统下任意敏感文件,如数据库账号密码,后台账号密码等……
②通过任意文件读取将后端源码全部读取用来代码审计,找到更有价值的漏洞
③通过收集到的信息与其他漏洞打组合拳造成更大的危害
3.任意文件读取相关函数
readfile()
该函数特点是不需要使用echo
等输出函数进行输出
1 2 3 4 5 6 7 8 9 10 11
| 定义和用法: 该函数读取一个文件,并写入到输出缓冲。
语法: readfile(filename,include_path,context) filename 必需。规定要读取的文件。 include_path 可选。如果您还想在 include_path(在 php.ini 中)中搜索文件的话,请设置该参数为 '1'。 context 可选。规定文件句柄的环境。context 是一套可以修改流的行为的选项。
返回值: 如果成功,该函数返回从文件中读入的字节数。如果失败,该函数返回 FALSE 并附带错误信息。您可以通过在函数名前面添加一个 '@' 来隐藏错误输出。
|
代码示例:
1 2 3 4 5 6
| <?php highlight_file(__FILE__);
$filename = @$_REQUEST['filename']; readfile($filename); ?>
|
file_get_contents()
该函数需要echo等输出函数输出。
1 2 3 4 5 6 7 8 9 10 11 12 13
| 定义和用法: 该函数把整个文件读入一个字符串中。该函数是用于把文件的内容读入到一个字符串中的首选方法。
语法: file_get_contents(path,include_path,context,start,max_length) path 必需。规定要读取的文件。 include_path 可选。如果您还想在 include_path(在 php.ini 中)中搜索文件的话,请设置该参数为 '1'。 context 可选。规定文件句柄的环境。context 是一套可以修改流的行为的选项。若使用 NULL,则忽略。 start 可选。规定在文件中开始读取的位置。该参数是 PHP 5.1 中新增的。 max_length 可选。规定读取的字节数。该参数是 PHP 5.1 中新增的。
返回值: 如果读取文件存在则返回文件内容如果不存在则报出No such file or directory
|
代码示例:
1 2 3 4 5 6 7
| <?php highlight_file(__FILE__); header("Content-Type:text/html; charset=utf-8");
$filename = $_GET['filename']; echo file_get_contents($filename); ?>
|
如果在参数中没有进行严格的过滤,在Windows中我们可以使用../或者..\实现目录跳转。
fopen()
该函数需要首先打开文件配合fread()
函数通过文件字节大小进行文件读取,最后使用fclose()
关闭打开的文件,且函数也需要使用echo等输出函数进行输出。
1 2 3 4 5 6 7 8 9 10 11 12
| 定义和用法: 该函数用于打开文件或者 URL。
语法: fopen(filename,mode,include_path,context) filename 必需。规定要打开的文件或 URL。 mode 必需。规定要求到该文件/流的访问类型。如r、r+、w、w+等。 include_path 可选。如果也需要在 include_path 中检索文件的话,可以将该参数设为 1 或 TRUE。 context 可选。规定文件句柄的环境。Context 是可以修改流的行为的一套选项。
返回值: 如果打开失败,本函数返回 FALSE。
|
fread()
1 2 3 4 5 6 7 8 9 10 11 12
| 定义和用法: 该函数从文件指针stream读取最多length个字节。该函数在遇上以下几种情况时停止读取文件: 读取了 length 个字节 到达了文件末尾(EOF)
语法: fread(resource $stream, int $length) stream 文件系统指针,是典型地由 fopen() 创建的 resource(资源)。 length 最多读取 length 个字节。
返回值: 返回所读取的字符串, 或者在失败时返回 false。
|
代码示例:
1 2 3 4 5 6 7 8
| <?php highlight_file(__FILE__);
$filename = $_GET['filename']; $f = fopen($filename,'r'); echo fread($f,filesize($filename)); fclose($f); ?>
|
如果这里filename
打开的内容我们可以控制那么就可以通过../或者..\等方法来读取任意文件。
Windows、Linux常见敏感路径
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| Windows: C:\boot.ini //查看系统版本 C:\Windows\System32\inetsrv\MetaBase.xml //IIS配置文件 C:\Windows\repair\sam //存储系统初次安装的密码 C:\Program Files\mysql\my.ini //Mysql配置 C:\Program Files\mysql\data\mysql\user.MYD //Mysql root C:\Windows\php.ini //php配置信息 C:\Windows\my.ini //Mysql配置信息
Linux: /root/.ssh/authorized_keys /root/.ssh/id_rsa /root/.ssh/id_ras.keystore /root/.ssh/known_hosts /etc/passwd 查看用户文件文件 /etc/shadow 查看密码文件 /etc/my.cnf /etc/httpd/conf/httpd.conf 查看apache的配置文件 /root/.bash_history 查看历史命令 /root/.mysql_history /proc/self/fd/fd[0-9]*(文件标识符) /proc/mounts /porc/config.gz /root/.ssh/authorized_keys /root/.ssh/id_rsa /root/.ssh/id_ras.keystore /root/.ssh/known_hosts //记录每个访问计算机用户的公钥 /etc/passwd /etc/shadow /etc/my.cnf //mysql配置文件 /etc/httpd/conf/httpd.conf //apache配置文件 /root/.bash_history //用户历史命令记录文件 /root/.mysql_history //mysql历史命令记录文件 /proc/mounts //记录系统挂载设备 /porc/config.gz //内核配置文件 /var/lib/mlocate/mlocate.db //全文件路径 /porc/self/cmdline //当前进程的cmdline参数
|
4.任意文件读取代码审计总结
1
| 关于本节的PHP任意文件读取漏洞,在代码审计中我们只需要关注上面介绍到的三个PHP函数即可,了解他们的区别可以让大家在日后的代码审计中更快的定位漏洞点,而不用去纠结函数本身从而可以把精力放在如何绕过过滤或者通过任意文件读取来将该漏洞的危害最大化。
|