2024年网络安全最全网络安全必学的SQL注入_sql 注入(3),2024年最新面试字节跳动被问网络安全屏幕适配方案

给大家的福利

零基础入门

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

同时每个成长路线对应的板块都有配套的视频提供:

在这里插入图片描述

因篇幅有限,仅展示部分资料

网络安全面试题

绿盟护网行动

还有大家最喜欢的黑客技术

网络安全源码合集+工具包

所有资料共282G,朋友们如果有需要全套《网络安全入门+黑客进阶学习资源包》,可以扫描下方二维码领取(如遇扫码问题,可以在评论区留言领取哦)~

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

Select * from name where id in (#{id})
复制代码

但由于这样写程序会报错,研发人员将SQL查询语句修改如下:

Select * from name where id in (${id})
复制代码

修改SQL语句之后,程序停止报错,但是却引入了SQL语句拼接的问题,如果没有对用户输入的内容做过滤,势必会产生SQL注入漏洞。

3)order by之后(重点和区分点)

当根据姓名、id序号等信息用户进行排序的时候,如果考虑安全编码规范问题,其对应的SQL语句如下:

Select * from user where name = 'qihoo' order by #{id} desc
复制代码

但由于发布时间id不是用户输入的参数,无法使用预编译。研发人员将SQL查询语句修改如下:

Select * from user where name = 'qihoo' order by ${id} desc
复制代码

修改之后,程序未通过预编译,但是产生了SQL语句拼接问题,极有可能引发SQL注入漏洞。

1.5 .实战案例-OFCMS SQL注入漏洞分析

本文中使用ofcms进行SQL注入漏洞讲解,此CMS算是对新手学习代码审计比较友好的CMS。

上述为安装成功页面,如何安装CMS本章不在赘述。

后台页面:http://localhost:8080/ofcms-admin/admin/index.html

image.png

漏洞点:

ofcms-admin/src/main/java/com/ofsoft/cms/admin/controller/system/SystemGeneratrController.java

create方法

| 

/**

* 创建表

*/

public void create() {

try {

String sql = getPara("sql");

Db.update(sql);

rendSuccessJson();

} catch (Exception e) {

e.printStackTrace();

rendFailedJson(ErrorCode.get("9999"), e.getMessage());

}

}
复制代码

上述代码中使用getpara获取sql的参数值,并update,跟进一下getpara和update方法。

跳转至 jfinal-3.2.jar/com/jfinal/core/controller.class

public String getPara(String name) {

return this.request.getParameter(name);

}
复制代码

上述代码无特殊用意,就是获取参数值,继续跟进 Db.update 方法。

跳转至 jfinal-3.2.jar/com/jfinal/plugin/activerecord/Db.class

public static int update(String sql) {

return MAIN.update(sql);

}
复制代码

发现调用 MAIN.update , 继续跟进。

跳转至 jfinal-3.2.jar/com/jfinal/plugin/activerecord/DbPro.class

public int update(String sql) {

return this.update(sql, DbKit.NULL_PARA_ARRAY);

}
复制代码

继续跟进到最后,发现华点。

public int update(String sql, Object... paras) {

Connection conn = null;

int var4;

try {

conn = this.config.getConnection();//连接

var4 = this.update(this.config, conn, sql, paras);//调用update更新

} catch (Exception var8) {

throw new ActiveRecordException(var8);

} finally {

this.config.close(conn);

}

return var4;

}
复制代码

重点:Object…

Object是所有类的基类,而 Object… 是不确定方法参数情况下的一种多态表现形式(可以传递多个参数)。

再继续跟进 update ,同文件代码

int update(Config config, Connection conn, String sql, Object... paras) throws SQLException {

PreparedStatement pst = conn.prepareStatement(sql);

config.dialect.fillStatement(pst, paras);

int result = pst.executeUpdate();

DbKit.close(pst);

return result;

}
复制代码

上述代码执行SQL语句,并返回结果。

至此,整个功能流程结束,在我们跟进的过程中,代码中无任何过滤语句,获取参数值,调用update方法更新,更新成功后返回结果。

漏洞验证

image.png

漏洞点打上断点,网页中输入poc进行验证

update of_cms_topic set topic_url=updatexml(1,concat(0x7e,(user())),0) where topic_id = 1
复制代码

image.png image.png image.png image.png

根据如上截图可看出我们传入的SQL语句是被完整的接收,并未做任何过滤直接带入数据库执行,所以此处直接写入漏洞代码爆出当前数据库账户为 root。

上述为sqlmap工具跑出来的注入点。

1.6 漏洞修复方法

添加全局过滤器,过滤特殊字符

image.png

SQLFilter.java中: image.png

PreparedStatement 参数化

如果使用参数化查询,则在SQL语句中使用占位符表示需在运行时确定的参数值。参数化查询使得SQL查询的语义逻辑被预先定义,而实际的查询参数值则等到程序运行时再确定。参数化查询使得数据库能够区分SQL语句中语义逻辑和数据参数,以确保用户输入无法改变预期的SQL查询语义逻辑。

在Java中,可以使用java.sql.PreparedStatement来对数据库发起参数化查询。在这个正确示例中,如果一个攻击者将itemName输入为name’ OR ‘a’ = ‘a,这个参数化查询将免受攻击,而是会查找一个itemName匹配name’ OR ‘a’ = 'a这个字符串的条目。

PreparedStatement stmt = null

ResultSet rs = null

try

{

String userName = ctx.getAuthenticatedUserName(); //this is a constant

String itemName = request.getParameter("itemName");

// ...Ensure that the length of userName and itemName is legitimate

// ...

String sqlString = "SELECT * FROM t_item WHERE owner=? AND itemName=?";

stmt = connection.prepareStatement(sqlString);

stmt.setString(1, userName);

stmt.setString(2, itemName);

rs = stmt.executeQuery();

// ... result set handling

}

catch (SQLException se)

{

// ... logging and error handling

}
复制代码

存储过程参数化

这个存储过程使用参数化查询,而未包含不安全的动态SQL构建。数据库编译此存储过程时,会生成一个SELECT查询的执行计划,只允许原始的SQL语义被执行。任何参数值,即使是被注入的SQL语句也不会被执行,因为它们不是执行计划的一部分。

CallableStatement = null

ResultSet results = null;

try

{

String userName = ctx.getAuthenticatedUserName(); //this is a constant

String itemName = request.getParameter("itemName");

// ... Ensure that the length of userName and itemName is legitimate

// ...

cs = connection.prepareCall("{call sp_queryItem(?,?)}");

cs.setString(1, userName);

cs.setString(2, itemName);

results = cs.executeQuery();

// ... result set handling

}

catch (SQLException se)

{

// ... logging and error handling

}
复制代码

Hibernate 参数化查询

Hibernate支持SQL/HQL参数化查询。为了防止SQL注入以及改善性能,以上这些示例使用了参数化绑定 的方式来设置查询参数。

String userName = ctx.getAuthenticatedUserName(); //this is a constant

String itemName = request.getParameter("itemName");

Query hqlQuery = session.createQuery("from Item as item where item.owner = ? and item.itemName = ?");

hqlQuery.setString(1, userName);

hqlQuery.setString(2, itemName);

List<Item> rs = (List<Item>) hqlQuery.list();
复制代码

HQL基于名称的参数化查询

String userName = ctx.getAuthenticatedUserName(); //this is a constant

String itemName = request.getParameter("itemName");

Query hqlQuery = session.createQuery("from Item as item where item.owner = :owner and item.itemName = :itemName");

hqlQuery.setString("owner", userName);

hqlQuery.setString("itemName", itemName);

List<Item> rs = (List<Item>) hqlQuery.list();
复制代码

原生参数化查询

String userName = ctx.getAuthenticatedUserName(); //this is a constant

String itemName = request.getParameter("itemName");

Query sqlQuery = session.createSQLQuery("select * from t_item where owner = ? and itemName = ?");

sqlQuery.setString(0, owner);

sqlQuery.setString(1, itemName);

List<Item> rs = (List<Item>) sqlQuery.list();
复制代码

MyBatis框架的修复方案

尽量使用#描述参数,如果一定要使用$,则需要自己过滤用户输入

模糊查询like SQL注入修复建议

按照新闻标题对新闻进行模糊查询,可将SQL查询语句设计如下:

select * from news where name like concat(‘%’,#{name }, ‘%’)
复制代码

采用预编译机制,避免了SQL语句拼接的问题,从根源上防止了SQL注入漏洞的产生。

in之后的参数SQL注入修复建议

在对新闻进行同条件多值查询的时候,可使用Mybatis自带循环指令解决SQL语句动态拼接的问题:

select * from news where id in<foreach collection="ids" item="item" open="("separator="," close=")">#{item} </foreach>
复制代码

order by SQL注入修复建议

在Java层面做映射预编译机制只能处理查询参数,其他地方还需要研发人员根据具体情况来解决。如前面提到的排序情景:

Select * from news where title =‘淘宝’ order by #{time} asc,
复制代码

这里time不是查询参数,无法使用预编译机制,只能这样拼接:

Select * from news where title =‘淘宝’ order by ${time} asc
复制代码

针对这种情况研发人员可以在java层面做映射来进行解决。如当存在发布时间time和点击量click两种排序选择时,我们可以限制用户只能输入1和2。

当用户输入1时,我们在代码层面将其映射为time,当用户输入2时,将其映射为click。而当用户输入1和2之外的其他内容时,我们可以将其转换为默认排序选择time(或者click)。

​最后

为了帮助大家更好的学习网络安全,小编给大家准备了一份网络安全入门/进阶学习资料,里面的内容都是适合零基础小白的笔记和资料,不懂编程也能听懂、看懂,所有资料共282G,朋友们如果有需要全套网络安全入门+进阶学习资源包,可以点击免费领取(如遇扫码问题,可以在评论区留言领取哦)~

😝有需要的小伙伴,可以点击下方链接免费领取或者V扫描下方二维码免费领取🆓

👉CSDN大礼包🎁:全网最全《网络安全入门&进阶学习资源包》免费分享**(安全链接,放心点击)**👈

1️⃣零基础入门

① 学习路线

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

② 路线对应学习视频

同时每个成长路线对应的板块都有配套的视频提供:

因篇幅有限,仅展示部分资料

2️⃣视频配套资料&国内外网安书籍、文档

① 文档和书籍资料

② 黑客技术

因篇幅有限,仅展示部分资料

👉CSDN大礼包🎁:全网最全《网络安全入门&进阶学习资源包》免费分享**(安全链接,放心点击)**👈

3️⃣网络安全源码合集+工具包

一、网安学习成长路线图

网安所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
在这里插入图片描述

二、网安视频合集

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
在这里插入图片描述

三、精品网安学习书籍

当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。
在这里插入图片描述

四、网络安全源码合集+工具包

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
在这里插入图片描述

五、网络安全面试题

最后就是大家最关心的网络安全面试题板块
在这里插入图片描述在这里插入图片描述

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 20
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值