Brute Force(暴力)
low
虽然题目叫暴力破解,但是这里还可以用sql注入。
sql注入
我们用万能密码admin‘ or 1=1#尝试,发现并不能登录成功,而使用admin‘ and 1=1#却可以登录成功。查看源码发现if( $result && mysqli_num_rows( $result ) == 1 ) {
返回的结果只能是一条而使用or返回的是所有结果,一开始我还不懂为什么,查询资料才发现我对sql的查询逻辑有误解。
sql有这样的特性逐行扫描:数据库会检查每一行是否满足 WHERE
条件,无论是否已找到有效数据。OR 1=1
会导致所有行满足条件,因此全部返回。也就是说是根据结果是否符合or中的两个条件再返回而不是先检查or的条件再执行查询。
暴力破解
关于bp中intruder四种爆破模式的区别可参考Burp Suite中intruder爆破模块四种模式的区别_bp两个payload-CSDN博客
使用可参照【实验报告】使用Burp Suite爆破网站登录账号,密码 - 知乎
成功。
medium
查看源码我们发现这关除了给user和password加上了过滤还在输入错误时sleep2秒以降低爆破的速度。
同样用bp爆破,只不过时间会慢一点。
high
1 | checkToken( $_REQUEST[ 'user_token'], $_SESSION[ 'session_token'], 'index.php'); |
查看源码发现这关加了个token的验证。
我们来看一下token的原理和作用机制。
什么是Token?
当用户登录成功,服务器会生成一个唯一的token,这个token通常会包含以下信息:
- 用户标识(例如用户ID)
- token生成的时间戳
- token的有效期
- 加密签名(用于验证token的完整性和真实性)
服务器将生成的token发送给客户端,客户端保存token并在每次发送请求时携带这个token与服务器那储存的token进行验证,退出时token消失。这里的token在每次请求还会刷新。
首先添加payload
payload1(密码)使用字典,payload2(token)类型使用递归提取,在设置里提取响应包的内容
这里选择我们刚刚提取的token并且首次请求的token是我们刚刚再次发送请求包中的token不是我们抓包时的token。成功爆破接下来就是等待。

Command Injection(命令执行)
第一次见这种漏洞,先了解一下基本情况。
漏洞描述
命令执行漏洞是指服务器没有对执行的命令进行过滤,用户可以随意执行系统命令,命令执行漏洞属于高危漏洞之一
如PHP的命令执行漏洞主要是基于一些函数的参数过滤不足导致,可以执行命令的函数有system( )、exec( )、shell_exec( )、passthru( )、pcntl_execl( )、popen( )、proc_open( )等,当攻击者可以控制这些函数中的参数时,就可以将恶意的系统命令拼接到正常命令中,从而造成命令执行攻击
PHP执行命令是继承WebServer用户的权限,这个用户一般都有权限向Web目录写文件,可见该漏洞的危害性相当大。
命令执行与代码执行的区别
代码执行:执行效果完全依赖于语言本身
命令执行:执行效果不受语言本身、命令本身的限制
window常见的命令拼接符
|
直接执行后面的语句
||
如果前面命令是错的那么就执行后面的语句,否则只执行前面的语句
&
前面和后面命令都要执行,无论前面真假
&&
如果前面为假,后面的命令也不执行,如果前面为真则执行两条命令
Linux常见的命令拼接符
除了|、||、&、&&
还多了一个;
,作用和&
一样.
常见的命令执行函数:
1)system
该函数会把执行结果输出 并把输出结果的最后一行作为字符串返回 如果执行失败则返回false 这个也最为常用
(2)exec
不输出结果,返回执行结果的最后一行 可以使用output进行输出
(3)passthru
此函数只调用命令 并把运行结果原样地直接输出 没有返回值。
(4)shell_exec
不输出结果,返回执行结果 使用反引号(``)时调用的就是此函数
low
查看源码发现并没有任何过滤代码,我们直接用127.0.0.1&whoami
,whoami会显示当前用户的用户名和SID(Windows操作系统中用于唯一标识用户、组和计算机账户的一个唯一标识符)。
成功。
medium
查看源码
1 | $substitutions = array( '&&' => '', ';' => '', ); |
发现把&&
和;
过滤了,那么我们可以利用没有被过滤的命令拼接符,如127.0.0.1&whoami
.
high
查看源码
1 | $substitutions = array( '||' => '', '&' => '', ';' => '', '| ' => '', '-' => '', '$' => '', '(' => '', ')' => '', '`' => '', ); |
发现把能过滤的都过滤了,不过仔细看发现|
其实是|
,多了个括号,那么这个过滤是没用的。我们直接用127.0.0.1|whoami测试成功。
CSRF(跨站请求伪造)
第一次见,看原理:
简单的说,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己以前认证过的站点并运行一些操作(如发邮件,发消息,甚至财产操作(如转账和购买商品))。因为浏览器之前认证过,所以被访问的站点会觉得这是真正的用户操作而去运行。
从上图能够看出,要完毕一次CSRF攻击,受害者必须依次完毕两个步骤:
登录受信任站点A,并在本地生成Cookie。
在不登出A的情况下,访问危险站点B。
(要在同一个浏览器中进行)
攻击者只有预测出URL的所有参数与参数值,才能成功地构造一个伪造的请求;反之,攻击者将无法攻击成功。
low
我们修改密码后发现发送的是GET请求,URL如下:
http://dvwa:8898/vulnerabilities/csrf/?password_new=password&password_conf=password&Change=Change#
由此我们也可以伪造一个url
http://dvwa:8898/vulnerabilities/csrf/?password_new=123&password_conf=123&Change=Change#
这样在登录状态下用同一个浏览器打开便会修改密码。
但是这样的url太明显了,我们可以利用站长工具生成一个短域名,用这个短域名进入的也是同一个页面。
我们也可以在html中用支持src的标签将url隐藏起来。
medium
这关主要改变的代码是
1 | stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false |
代码检查了保留变量 HTTP_REFERER(http包头的Referer参数的值,表示来源地址)中是否包含SERVER_NAME(http包头的Host参数,及要访问的主机名)
这个检查的作用是验证用户是否是从同一个网站上的另一个页面跳转过来的,防止外部链接直接访问某些页面,增加网站安全性。
我们可以抓包修改请求头referer
我们也可以绕过
1 | 目录混淆法:将HTML页面放在127.0.0.1目录下,构建payload |
high
application/json
查看源码发现
1 | $data = json_decode(file_get_contents('php://input'), true); |
这是针对application/json类型的数据
数据格式:
- 数据以JSON(JavaScript Object Notation)格式表示。
- JSON格式可以表示更复杂的数据结构,如数组、对象、嵌套对象等。
- 字符串需要用双引号包裹。
示例:
{"name": "John Doe", "age": 30, "city": "New York"}
用途:
- 适用于现代Web应用程序,特别是那些使用Ajax技术进行数据交换的应用程序。
- 适合传输复杂或结构化数据。
虽然有这个解析代码但我们这的请求中不是这类数据。
源码中新增了 checkToken( $token, $_SESSION[ 'session_token' ], 'index.php' );
来检查token。
那么我们就需要获取用户的token。
方法一
由于现在的浏览器是不允许跨域请求,即攻击者的服务器192.168.67.140不能向被攻击的服务器192.168.67.143发送请求,除非是被攻击服务器主动发给攻击者服务器。那么我们只能将我们的攻击页面放在被攻击者的服务器引诱受害者访问,攻击页面代码如下。
1 | <script type="text/javascript"> |
- 在
<script>
标签中定义了一个JavaScript函数attack()
,该函数的作用是:- 从隐藏的
<iframe>
中获取名为user_token
的元素的值(这通常是用来防止CSRF攻击的一种令牌)。 - 将获取到的
user_token
值设置到当前页面表单中名为user_token
的隐藏输入字段。 - 提交表单
transfer
。
- 从隐藏的