chenhongl

导航

 

#知识点:
1.JavaWeb常见安全及代码逻辑
通过URL信息来对应源码文件。没有代码的情况下很难渗透。
2.目录遍历&身份验证&逻辑&JWT
3.访问控制&安全组件&越权&三方组件

 

1、JavaWeb-WebGoat8靶场搭建使用

  • 下载地址:https://github.com/WebGoat/WebGoat/releases,下载webgoat-server-8.2.2.jar

  • 压缩到jar包里面。
  • 如何启动:安装jdk,运行 java -jar webgoat-server-8.1.0.jar --server.port=9002
  • 访问127.0.0.1:9002/WebGoat/login,注册账号登录就可以了。

   WebGoat8.1版本,需求是JDK15
   WebGoat8.2版本,需求是JDK17

2、安全问题-目录遍历

【例1】:WebGoat8 - A1- 路径遍历 - 第2关:上传文件时的路径遍历,将文件上传到正常位置之外的位置
实际上传的目录地址:

目标地址:(实际上传地址的前2级目录)

 

关键代码:

publicAttackResultuploadFileHandler(@RequestParam("uploadedFile")MultipartFilefile,@RequestParam(value="fullName",required=false)StringfullName){
returnsuper.execute(file,fullName);
}

抓包地址:http://127.0.0.1:9002/WebGoat/start.mvc#lesson/AuthBypass.lesson/1

上传图片:

 

 查看代码:

 接收两个参数uploadFile赋值给file,fullName赋值给fullName

 

修改数据包中的“fullName”的值,文件的上传路径也会跟着变化

 

修改上传数据包为上上一级目录,结尾是test:成功通关

 

【例2】:A1- 第3关

../被过滤

关键代码:../被替换为空

 

 

由于replace只会过滤一次,把fullname修改为:

成功过关。

解决问题:如果当前目录(比如image文件夹)只能上传图片,该文件夹被设置为不能执行可执行文件,所以尝试将执行脚本上传至别的目录(一般上传图片的文件夹会限制不能执行脚本文件,但是根目录不会做限制)

 

3、安全问题 - 身份认证

【例】:A2-Authentication Bypasses-第2关:绕过身份验证 -绕过安全问题重置密码

代码:

 

键名---键值,从多个问题中随机选出2个问题来验证:问题和答案相对应

  问题s0:你的名字?---刘迪

  问题s1:你的出生地?---湖北

  给服务器发送数据  s0=xiaodi&s1=湖北 则验证通过

绕过逻辑:

  固定接收数据(安全的验证):只接收数据库存在的键名s0、s1,不接收不存在的键名

  不固定的接收数据(不安全的验证):键名和键值都接收,数据库存在s0和s1的键名,数据库不存在s3和s4(即s3=null,s4=null),攻击者通过s3=null&s4=null发送数据,因为s3 s4本来就为空,相当于NULL,那么就能进行绕过。

安全验证:

固定的接收数据:如果服务器只接收固定键名,s0和s1,再判断s0和s1的值,就没法绕过

 

4、安全问题 - JWT Token

使用JSON Web令牌(JWT)进行身份验证(java和python运用较多)

传统token方式和jwt在认证方面有什么差异?

传统token方式:

  用户登录成功后,服务端生成一个随机token给用户,并且在服务端(数据库或缓存)中保存一份token,以后用户再来访问时需携带token,服务端接收到token之后,去数据库或缓存中进行校验token的是否超时、是否合法。

jwt方式:

  用户登录成功后,服务端通过jwt生成一个随机token给用户(服务端无需保留token),以后用户再来访问时需携带token,服务端接收到token之后,通过jwt对token进行校验是否超时、是否合法。

 

JWT 令牌由三个部分组成,分别是 标头(Header)、有效载荷(Payload)、签名(Signature),并且由 "." 分割.

类似于 xxxx.yyyy.zzzzz ,也就是 Header.Payload.Signature

如:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

jwt解密平台:https://jwt.io/

生成规则如下:

  • 第一段HEADER部分,固定包含算法和token类型,对此json进行base64url加密,这就是token的第一段。
    {
       "alg""HS256",
       "typ""JWT"
     }
  • 第二段PAYLOAD部分,包含一些数据,对此json进行base64url加密,这就是token的第二段。
    {
        "sub""1234567890",
        "name""John Doe",
        "iat": 1516239022
         ...
    }
  • 第三段SIGNATURE部分,把前两段的base密文通过.拼接起来,然后对其进行HS256加密,再然后对hs256密文进行base64url加密,最终得到token的第三段。
  base64url(
    HMACSHA256(
      base64UrlEncode(header) + "." + base64UrlEncode(payload),
      your-256-bit-secret (秘钥加盐)
    )
  )

最后将三段字符串通过 .拼接起来就生成了jwt的token。

注意:base64url加密是先做base64加密,然后再将 - 替代 + 及 _ 替代 / 。

 

【例】:A2-JWT tokens - 第五关:尝试更改令牌,登录管理员用户

① 切换账号为“Tom”(普通用户),抓包发现:Cookie为三段式的,说明是jwt生成的token格式

解密后:Tom非admin用户

 

JWT的攻击方式:

  1.空加密算法(很少见)

  2.爆破

  3.KID

参考,JWT原理及常见攻击方式:https://www.cnblogs.com/vege/p/14468030.html

1.空加密算法:
因为生成字JWT符串:算法模式+秘钥(缺一不可)

空加密算法的设计初衷是用于调试的,但是如果某天开发人员脑阔瓦特了,在生产环境中开启了空加密算法,缺少签名算法,jwt保证信息不被篡改的功能就失效了。

空加密算法,可以在header中指定alg为None,把签名设置为空(即不添加signature字段),这需要服务器(后端代码)支持不要秘钥签名(空模式加密,即加密方式为None的时候,就不需要签名(密钥))

比如:

找到相对应的代码段发现可以空加密然后用python脚本去写空加密jwt

# -*- coding:utf-8 -*-

import jwt
import base64


def b64urlencode(data):
    return base64.b64encode(data).replace(b'+', b'-').replace(b'/', b'_').replace(b'=', b'')

print(b64urlencode(b'{"alg":"none"}')+b'.'+b64urlencode(b'{"iat":1573470025,"admin":"true","user":"Tom"}')+b'.')

eyJhbGciOiJub25lIn0.eyJpYXQiOjE1NzM0NzAwMjUsImFkbWluIjoidHJ1ZSIsInVzZXIiOiJUb20ifQ.

//(header+'.'+payload,去掉了'.'+signature字段),没有签名(密钥),就只有2段了,没有第3段

 

看代码是否支持空模式加密:

 


2.密钥爆破:

http://127.0.0.1:9091/WebGoat/start.mvc#lesson/JWT.lesson/7

【例】:A2-第8关,通过原JWT拿到密钥,修改用户名为webgoat,生成新的JWT

通过字典爆破,拿到签名,修改用户名为WebGoat,生成新的jwt

从代码中找到密钥:

爆破相关工具:c-jwt-cracker、python脚本

 

3. 修改KID参数

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

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

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

(1)任意文件读取

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

{
    "alg" "HS256",
    "typ" "jwt",
    "kid" "/etc/passwd"
}

(2)SQL注入

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

{
    "alg" "HS256",
    "typ" "jwt",
    "kid" "key11111111' || union select 'secretkey' -- "
}

(3)命令注入

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

"/path/to/key_file|whoami"

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

 

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

【例】:A9-第12关-Vulnerable Components

 

 

① 查看代码,发现引用了xstream组件:

 

百度查找相关漏洞:xstream 1.4.5 CVE-2013-7285

找到这个漏洞的介绍:https://x-stream.github.io/CVE-2013-7285.html     影响版本:XStream <= 1.4.6

找漏洞利用的POC

 

② 发现log4j组件

 

6、访问控制

- 隐藏属性:前端页面选择性的展示某些信息(隐藏某些重要的信息)

- 水平越权:同一级别用户权限的查看

 

【例】:A5-第2关登录后、第3关查看个人信息

①隐藏属性

查看源码:

 

 

②水平越权

比如,只要修改“userId”的值,就可以查看其他用户的个人信息。

 

posted on 2024-01-23 15:07  chenhongl  阅读(282)  评论(0)    收藏  举报