寻找可以控制写入的内容点
fwrite()
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) 把 ptr 所指向的数组中的数据写入到给定流 stream 中。
如果成功,该函数返回一个 size_t 对象,表示元素的总数,该对象是一个整型数据类型。如果该数字与 nmemb 参数不同,则会显示一个错误。
file_put_contents()
把一个字符串写入文件中
file_put_contents(file,data,mode,context)
file 必需。规定要写入数据的文件。如果文件不存在,则创建一个新文件。
data 可选。规定要写入文件的数据。可以是字符串、数组或数据流。
mode 可选。规定如何打开/写入文件。可能的值:
FILE_USE_INCLUDE_PATH
FILE_APPEND
LOCK_EX
context 可选。规定文件句柄的环境。
工具:
代码审计工具
74ms
漏洞点
admin/admin_templates.php
的113到未行
elseif ($act == 'do_edit')
{
check_permissions($_SESSION['admin_purview'],"tpl_edit");
$tpl_name = !empty($_POST['tpl_name']) ? trim($_POST['tpl_name']) : '';
$tpl_content = !empty($_POST['tpl_content']) ? deep_stripslashes($_POST['tpl_content']) : '';
if(empty($tpl_name)){
adminmsg('����ģ���ļ�����', 0);
}
$file_dir='../templates/'.$_POST['tpl_dir'].'/'.$tpl_name;
if(!$handle = @fopen($file_dir, 'wb')){
adminmsg("��Ŀ��ģ���ļ� $tpl_name ʧ�ܣ�����ģ��Ŀ¼��Ȩ��",0);
}
if(fwrite($handle, $tpl_content) === false){
adminmsg('д��Ŀ�� $tpl_name ʧ��,�����дȨ��',0);
}
fclose($handle);
$link[0]['text'] = "�����༭���ļ�";
$link[0]['href'] =$_SERVER['HTTP_REFERER'];
$link[1]['text'] = "����ģ���ļ��б�";
$link[1]['href'] ="?act=edit&tpl_dir=".$_POST['tpl_dir'];
adminmsg('�༭ģ��ɹ�',2,$link);
}
漏洞利用点
: $file_dir='../templates/'.$_POST['tpl_dir'].'/'.$tpl_name;
fopen()打开一个文件或url
fopen($file_dir, ‘wb’))以wb权限打开
“r” (只读方式打开,将文件指针指向文件头)
“r+” (读写方式打开,将文件指针指向文件头)
“w” (写入方式打开,清除文件内容,如果文件不存在则尝试创建之)
“w+” (读写方式打开,清除文件内容,如果文件不存在则尝试创建之)
“a” (写入方式打开,将文件指针指向文件末尾进行写入,如果文件不存在则尝试创建之)
“a+” (读写方式打开,通过将文件指针指向文件末尾进行写入来保存文件内容)
“x” (创建一个新的文件并以写入方式打开,如果文件已存在则返回 FALSE 和一个错误)
“x+” (创建一个新的文件并以读写方式打开,如果文件已存在则返回 FALSE 和一个错误)
include_path 可选。如果您还想在 include_path(在 php.ini 中)中搜索文件的话,请设置该参数为 ‘1’。
context 可选。规定文件句柄的环境。context 是一套可以修改流的行为的选项。
您还可以使用 “b” 来强制使用二进制模式,这样就不会转换数据。为了使用这些标记,请使用 “b” 或者 “t” 来作为 mode 参数的最后一个字符。
tpl_dir 以requrst方式写入
payload