文件上传(包含)漏洞
弱类型语言——PHP
PHP脚本以<?php开始,以? >结束
变量以$符号开始,后跟变量名,必须以字母或者下划线开始,并区分大小写
array用于创建数组,count()函数获取数组长度,foreach()关联数组的创建及遍历
局部作用域和全局作用域
global关键字用于函数内访问全局变量 static作用域:使某个局部变量在函数结束后不被删除
两种比较符号:
==弱等于:在比较前把两种字符串类型转成相同的在进行比较,即只比较值。
===强等于:先比较类型,不同直接返回不相等,既比较值也比较类型。
示例simple.php
**$a == 0
**:传递a=a
这里的 $a
是字符串 "a"
。在 PHP 中,弱类型比较时,非数字的字符串与数字进行比较时,字符串会被转换为数字。
字符串 "a"
会被 PHP 转换为 0
,因为 PHP 会尝试从字符串的开头提取数字,而 "a"
并没有任何可提取的数字部分,所以转换的结果是 0
。
因此,"a" == 0
为 真。
错误控制运算符@
当在某个表达式前加上 @
,如果该表达式出错,PHP 不会显示错误信息,而是返回 false
或 null
index.php
index.php是一个用PHP语言开发的网站的首页,index是普遍意义上的“首页”,也就是你输入一个域名后会打开一个页面,基本上就是index.xxxx(基本上首页都不会把index.xxxx显示在url里,但也不绝对)
index.php是一种常见的网页文件,它通常用于网站的首页或默认页面。在使用PHP编程语言的网站中,index.php文件是网站的入口点,它负责处理和呈现网页内容。
当访问一个使用PHP编写的网站时,服务器会首先查找并执行index.php文件。该文件可以包含PHP代码、HTML标记和其他相关内容,用于生成并呈现动态的网页内容。
PHP2(PHPS)
phps文件就是php的源代码文件,通常用于提供给用户直接通过Web浏览器查看php代码的内容。
因为用户无法直接通过Web浏览器“看到”php文件的内容,所以需要用phps文件代替。用户访问phps文件就能看到对应的php文件的源码。
PHP序列化和反序列化
序列化字符串的标准格式: O:<类名的长度>:"<类名>":<成员属性的个数>:{S:<成员属性名的长度>:"<成员属 性名>";......}
序列化serialize():是将变量或对象转换成字符串的过程( 序列化只作用于对象,不序列化方法),用于存储或传递 PHP 的值的过程中,同时不丢失其类型和结构。
反序列化unserialize():将字符串转换成变量或对象的过程,是一种将存储在字符串中的PHP对象转换为PHP变量的过程。这可以通过使用unserialize()函数来实现。
PHP魔术方法
__sleep()
serialize() 函数会检查类中是否存在一个魔术方法 __sleep()。如果存在,该方法会先被调用,然后才执行序列化操作。此功能可以用于清理对象,并返回一个包含对象中所有应被序列化的变量名称的数组。如果该方法未返回任何内容,则 NULL 被序列化,并产生一个 E_NOTICE 级别的错误。
对象被序列化之前触发,返回需要被序列化存储的成员属性,删除不必要的属性。
__wakeup()
unserialize() 会检查是否存在一个 __wakeup() 方法。如果存在,则会先调用 __wakeup 方法,预先准备对象需要的资源。
漏洞:当序列化字符串表示对象属性个数的数字值大于真实类中属性的个数时就会跳过__wakeup的执行。
预先准备对象资源,返回void,常用于反序列化操作中重新建立数据库连接或执行其他初始化操作。
用php脚本实现哈希值爆破
```
关于substr函数:substr(string $string, int $start, ?int $length = null): string
**$string
**:要操作的原始字符串,以上即为 MD5 哈希值字符串。 **$start
**:提取的起始位置。-6
表示从字符串的倒数第 6 个字符开始。 **$length
**:要提取的字符数,这里是 6
,表示提取 6 个字符。
文件上传漏洞
常见的形式(对应于upload-labs靶场):前端验证、文件类型验证、黑名单验证(.htaccess解析绕过、大小写绕过、空格绕过、
上传了一个可执行的文件到服务器并执行(某些网站中没有严格限制用户上传文件的后缀名及类型,导致可以上传任意PHP文件,并能够在远程服务器上执行任意PHP脚本)
基础知识:
Webshell
以php等网页文件形式存在的一种命令执行环境(网页后门),混在web目录下正常的网页文件,隐蔽性高,可以轻松穿越防火墙,且访问 WebShell 时不会留下系统日志
一句话木马:
利用文件上传漏洞,通过攻击者传递的命令获得服务器的控制权。
<?php @eval($_POST['attack']);?>
@表示后面即使执行错误也不报错;eval()函数表示括号内的语句字符串都当作代码执行。$_POST[‘attack’]表示从页面中获得attack这个参数值。
例:使用eval()函数执行PHP代码 <?php eval($_POST['cmd']); ?>
通过POST请求传递PHP代码,eval()
会将这些代码作为PHP代码执行。
图片木马
在路径下准备好一句话木马
.php
和一张图片.png
(或者.jpg
)输入系统指令:
copy 一张图片.png/b+一句话木马.php/a 生成图片名称.png
这样图片木马就合成好了
doc、pdf、excel文件头木马写入
准备word文档
.doc
+.exe
木马文件输入系统指令:
copy CSDN.doc/b + 1.exe/a phpinfo.doc
常见的绕过方式
伪造文件格式——绕过文件头验证
GIF89a伪造文件格式的实现:
(文件头标识符:文件类型在文件开头都有独特的二进制标识符,用来标识文件格式。如:GIF文件通常以 GIF89a
或 GIF87a
开头)
在恶意代码前插入伪造的文件头:为了使一个PHP脚本伪装成GIF文件,在PHP代码前加上 GIF89a
,即伪造一个GIF文件头。服务器很可能不会进一步检查文件内容,认为这是一个合法的图片,从而通过了上传验证。
利用科学计数法绕过长度限制
用1e9
的格式表示大数值,PHP自动识别为浮点数,假设限制5位数字,此时长度仅为3个字符,从而绕过长度限制
js前端校验绕过
删除js校验代码(f12调试器禁用js)、更改js校验中的白名单、先改文件后缀名通过校验后抓包更改后缀上传至服务器
分布式配置文件.htaccess
.htaccess文件解析漏洞可以利用其将我们所的文件都解析成php或者是特定的文件解析为php,与下面,user.ini大同小异
.user.ini绕过
关于.ini配置文件
.ini文件主要用于服务器端的PHP配置,定义PHP的设置参数,
.user.ini实际上就是一个可以由用户”自定义”的php.ini.
.user.ini为特定目录设置PHP配置,允许在不访问PHP主配置(php.ini
)的情况下,对特定目录的PHP行为进行局部配置,而且可以由用户在应用运行时动态配置(即auto_prepend_file
可由 .user.ini
文件动态设置且定期加载,允许攻击者不重启服务器即可立即执行恶意代码。)
PHP配置项的利用
auto_prepend_file
允许在执行某个 PHP 文件之前,自动加载并运行指定的文件。即指定的文件中的内容会首先执行,可以被用来控制 PHP 代码执行的顺序
通过上传 .user.ini
文件来设置 auto_prepend_file
,并将其指向一个伪装为图片的恶意文件。绕过文件类型检测,该文件伪装成图片文件,在文件头部添加 GIF89a
绕过方式:
首先上传包含上述内容的.user.ini内容文件(auto_prepend_file = “a.jpg),然后上传包含有一句话木马的a.jpg
过滤绕过(windows)
大小写转换、点(.)、空格、特殊字符::$DATA
点空格点(. .)绕过
原理:由源码可知,对文件名末尾的点,大小写转换,去除了::$DATA,首位去空了,但是这些操作只会执行一次,所以我们可以抓包,加上后缀. .
,这样程序在经过处理之后,我们的文件名就只剩一个.
,可以绕过黑名单检测,最后在服务器中自动去除.
,我们就可以正常访问shell.php了
双写绕过
双写绕过就是双写文件后缀名来进行绕过,如:test.php 双写后为 test.pphphp。
通常情况下双写绕过用于绕过源代码中的 str_ireplace()函数
原理:源代码中有黑名单和str_ireplace()函数的联合使用,将黑名单中的敏感后缀名全部都进行了删除。这就会使我们上传的 test.php 上传后变成 test. ,这就会使Apache无法解析,以至于不会执行文件中的php代码。 而str_ireplace() 函数的缺陷是只会进行一次删除操作,我们这时就可以使用双写进行绕过。test.pphphp 被删除一次php后依然还剩 test.php,这样就可以成功执行php代码。