28.1大纲
Javaweb-SQL 注入攻击-预编译机制绕过
28.1.1预编译机制与case when
---防御 sql 注入:1.session2.参数绑定存储过程
#利用 session 防御
---session 内容正常情况下是用户无法修改的
---select * from users where user = "'" +session.getAttribute("UserID") + "'";(session在服务器内)
#参数绑定方式,利用了 sql 的预编译技术
---常用Statement、PreparedStatement 和 CallableStatement三种方式来执行查询语句,其中 Statement 用于通用查询, PreparedStatement 用于执行参数化查询,而 CallableStatement则是用于存储过程。
---Statement 该对象用于执行静态的 SQL 语句,并且返回执行结果。 此处的SQL语句必须是完整的,有明确的数据指示。查的是哪条记录?改的是哪条记录?都要指示清楚。
---PreparedStatement ,SQL 语句被预编译并存储在 PreparedStatement 对象中。然后可以使用此对象多次高效地执行该语句。(这里是PreparedStatement不允许一个占位符(?)有多个值,注入的语句也就不会被执行)
---在使用参数化查询的情况下,数据库系统不会将参数的内容视为SQL指令的一部分来处理
---而是在数据库完成SQL指令的编译后,才套用参数运行,因此就算参数中含有破坏性的指令,也不会被数据库所运行。
---String query = "SELECT * FROM users WHERE last_name = ?";// 不允许一个占位符(?)有多个值
---通过使用 case when 语句可以将 order by 后的 orderExpression 表达式中添加 select 语句。(原理类似堆叠注入,一条语句出现多条命令)
#进入靶场
#数据包分析(发送的请求指向的是源代码中的server)
#源代码分析
---发现SQL语句,并且语句后面有order by(传递column参数),寻找传参column的地方
---抓包工具修改
---修改ip为1
---报错的时候存在order by,因此可以用case when语句
---case when原理:普通的按某一个字段或者多个字段排序没办法满足我们的需求时,可以通过case when 来排序
如果是Java语句的SQL如果是预编译的的话,基本不能注入。除非存在order by,可以用order by case when 来构造查询语句(具体构造也不太会,突然感觉408和数据库的重要性),来进行数据库的查询。其实这个Python代码感觉挺有用的,但是代码看的似懂非懂)
28.2JWT
直接上靶场实例’
这数据的三个部分,前面的两个部分都是base64加密
28.2.1JWT身份验证 有点像身份令牌
打开靶场,首先点击用户tom抓取数据包,发现token中没有数据,之后再点删除(reset votes)之后进行抓包发现然后再访问jwt.io网站对该串数据进行解码
解密之后得到的数据,然后发现可以通过修改admin后面的值在修改自己的用户状态to true。第一个header其实就是指蓝色部分签名密匙的加密方式,里面的内容就是加密方式(通过第三个框框可以看见,只有输入密匙之后才可以查看签名的内容)所以可以修改加密方式为none。
修改这个数据包之后发送,发现回显结果已经发生改变,但还是无法直接完成目的
报出签名不对了,也就是蓝色代码的部分不对(没有密匙)
修改数据,注意在加密后的base64后面的等号需要删除,然后再将签名删除(没有密匙,保留点号)这个成功的条件是,对方不验证签名才可以的。
28.2.2JWT密匙爆破
原理:
首先这关是建立在没有令牌密匙的前提下的,也就是说仍然是后面留一个点的情况。
有关的小知识:可以看到iat,与一个exp,这个东西就是时间戳,iat就是这个令牌有效的开始时间,而exp 就是指这个令牌的失效时间。
这题的思路就是在获取到别人支付的令牌的代码 (通过日志文件等等)之后然后自己进行支付时将自己的身份换成别人的令牌后修改结束时间戳使得其令牌重新激活,让别人替你完成支付。
28.2.3jwt配合sql注入
就是通过代码的分析之后发现该代码执行过程中会涉及到查询kid的一个操作,由此而引发出的sql注入。
28.2.4一点小知识
authorization(授权),这个其实有那么一点会出现jwt的标识,但是并不绝对
28.2.5ctf靶场实例
首先先明确一个特性,jwt是身份铭牌,只有当这个用户存在的时候才会出现这么一个身份铭牌,所以打开靶场
发现这么一个界面之后随便输入一个账号密码后打开burp进行抓包发现数据包中的authorization为空之后,重新注册一个账号并进行抓包,发现出现了jwt令牌后送往网站进行查看,发现变量中有一个 secretied这个意思就是是否有密钥的意思,所以肯定改成空([]表示空),然后通过查看题目是Nodejs百度知道管理员是admin于是直接将username改成admin后将得到的jwt放入数据包中完成。(这里不知道为啥没有密码验证,猜测是题目本身就没有设置验证密码)