java-SQL注入(java sec code)

admin 2024年2月15日23:27:58评论9 views字数 3439阅读11分27秒阅读模式

sql注入

在常见的网络应用漏洞中,SQL注入漏洞较为常见,危害大。攻击者一旦利用系统中存在的SQL注入漏洞来发起攻击,在条件允许的情况下,不仅可以获取整站数据,还可通过进一步的渗透 来获取服务器权限,从而进入内网,大家也许都听过某某学长通过攻击学校数据库修改自己成绩的事情,这些学长们一般用的就是SQL注入方法。注入攻击的本质,是把用户输入的数据当做代码执行。

SQL注入条件

1、是用户能够控制输入

2、是原本程序 要执行的代码,拼接了用户输入的数据

案例一

当用户发送GET请求:http://www.xxx.com/news.jsp?id=1

这是一个新闻详情页面,会显示出新闻的title和content,程序内部 会接收这个id参数传递给SQL语句,SQL如下:

SELECT title,content FROM news WHERE id = 1

这是SQL的原义,也是程序员想要得到的结果,但是如果用户改变了id 的内容,修改成如下:

http://www.jd.com/news.jsp?id=1 and 1=2 UNION SELECTuserna-me, password FROM admin

此时内部程序执行的SQL语句为:

SELECT title,content FROM news WHERE id = 1 and 1=2UNION SELECT username, password FROM admin

这条SQL的原义就会被改变,导致将管理员数据表中的用户名显示 在页面title位置,密码显示在页面content位置,攻击成功。

java-JDBC

以前程序员往往这么从数据库获取数据。

// 程序宇数据库的连接方式:先连接、构造sql语句、执行public User getUserById(String id) throws  //String字符串类型或者 idSQLException {    Connection connection =JDBCTOOLS.getConnection(); String sql = "select id,username from user where id=" + id; //直接拼接sql语句 Statement statement =connection.createStatement();    ResultSet resultSet =statement.executeQuery(sql);    resultSet.next();    int userId = resultSet.getInt(1);    String username = resultSet.getString(2);    User user = new User(userId, username);    return user;}

通过拼接字符串来构建sql语句,其中又有用户可控的部分,很容易 出现问题

直接拼接实例代码http://localhost:8080/sqli/jdbc/vul?username=joychou
java-SQL注入(java sec code)

源码分析

 @GetMapping("/jdbc/vuln")  // 访问了 /jdbc/vuln  就执行以下方法    //public String jdbc_sqli_vul(@RequestParam("username") String username) {        public String jdbc_sqli_vul( String username) {        StringBuilder result = new StringBuilder();        try {            Class.forName(driver);            Connection con = DriverManager.getConnection(url, user, password);            if (!con.isClosed())                System.out.println("Connect to database successfully.");            // sqli vuln code            Statement statement = con.createStatement();            String sql = "select * from users where username = '" + username + "'";            logger.info(sql);            ResultSet rs = statement.executeQuery(sql);

预编译处理后的代码(修复后代码)

http://localhost:8080/sqli/jdbc/sec?username=joychou

后来,出现了预编译机制,但是预编译只能处理查询参数,很多场 景下仅仅使用预编译是不够的。

// fix code            String sql = "select * from users where username = ?"; // 这里使用了? 用来做预处理编译// sql: "select *from users where userbane=?"            PreparedStatement st = con.prepareStatement(sql); //con.prepareStatement java 预编译代码函数// st "com.mysql.cj.jdbc.clientPerparedStatement: select *from users where username= 'joychou ' or '1'='1'" com:ConnectionImapl@8805 sql: "select *from users where username =?"            st.setString(1, username);  // 预编译完成后占位上输入占位符           //  username: "joychou ' or '1'='1"            logger.info(st.toString());  // sql after prepare statement            ResultSet rs = st.executeQuery();        // st "com.mysql.cj.jdbc.clientPerparedStatement: select *from users where username= 'joychou ' or '1'='1'"//从以上代码可以看出 con.prepareStatement  是做了预编译 预处理,相当于出现单引号就加/ 这样 攻击者输入的语句就无法//被当初sql语句执行了

like

like拼接实现代码:

http://localhost:8080/sqli/jdbc/like?username=joy

在使用模糊查询的场景中

String sql = "select * from user where usernamelike '%?%'";

这种写法是无法进行预编译的,程序会报错

java-SQL注入(java sec code)

like预处理报错

http://localhost:8080/sqli/jdbc/likesec?username=joy
java-SQL注入(java sec code)

这里报错的原因是 jbc 预处理方法是针对于前面大众形式的,防止注入:字符串,数字型等 := ..但是对于 like 搜索的 有 等号= ?号的  是不太适用

like预处理

http://localhost:8080/sqli/jdbc/likesec?username=joy
java-SQL注入(java sec code)

order by

需要按照时间、id等信息进行排序的时候,也是无法使用预编译 的。sort=123

String sort = req.getParameter("sort");String sql = "select * from user order by ?";PreparedStatement preparedStatement =connection.prepareStatement(sql); //预编译preparedStatement.setString(1, sort); //绑定参数ResultSet resultSet =preparedStatement.executeQuery();

如果像上面这样强行使用预编译,数据库会将字段名解析为字符 串,即实际执行的sql为

select * from user order by 'sort';

总结

jdbc方式进行拼接的,可以直接使用预处理来规避sql注入, 但是如果有like、order by 进行参数拼接不能直接使用预处理来解 决,必须在set处把%拼接上。

原文始发于微信公众号(漏洞404):java-SQL注入(java sec code)

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年2月15日23:27:58
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   java-SQL注入(java sec code)http://cn-sec.com/archives/2185760.html

发表评论

匿名网友 填写信息