查看原文
其他

SQL注入详解|OWASP Top 10安全风险实践(二)

王爱华 新钛云服 2022-05-30

本文为一些列连载文章之一,不定期更新,计划目录如下:


OWASP介绍

SQL注入

命令注入

XML外部实体注入

XPATH注入

反射式、DOM及存储XSS

失效的身份认证和会话管理

不安全的直接对象引用

安全配置错误

敏感信息泄露

功能级访问控制缺失

跨站请求伪造

服务端请求伪造

文件上传漏洞

未验证的重定向和转发

不安全的反序列化

使用含有已知漏洞的组件


一、     注入


注入攻击漏洞,例如SQL,OS 以及 LDAP注入。这些攻击发生在当不可信的数据作为命令或 者查询语句的一部分,被发送给解释器的时候。攻击者发送的恶意数据可以欺骗解释器,以执行计划外的命令或者在未被恰当授权时访问数据。


  1. SQL注入


  • 漏洞利用演示

           

               

  • 漏洞危害说明

SQL注入攻击成功后,可导致用户数据库中存储的机密数据被窃取,更改,删除,或者上传木马文件,甚至执行系统命令以进一步获取服务器权限等。

 

  • 漏洞代码分析

   

处理用户登录的后台代码主要如下:(左右滑动查看代码)

   

publicbooleancheck_Sql_Login(String ipaddr) throws Exception { getConnection(); String name = loginuser.getName(); String passwd_page = loginuser.getPassword(); boolean flag = false; // 默认返回值是false Md5Util md5 = new Md5Util(); String passwd =md5.getMD5(passwd_page.getBytes()); // 拼凑的SQL语句,存在注入风险 String sql = "selectname from user where name=" + "'" + name + "'" + " andpassword=" + "'" + passwd + "'"; System.out.println("登录页面,拼凑SQL语句: " + sql); try { java.sql.Statement st = conn.createStatement(); rs =st.executeQuery(sql); if (rs.next()) { flag = true; } else { flag = false; } st.close(); System.out.println("登录页面查询结果" + "db.java.check_Sql_Login():" + flag); } catch (Exceptione) { e.printStackTrace(); } finally { out.close(); conn.close(); } return flag; }


如果用户名tmp已经存在,输入tmp‘#即可。

如果用户名不存在,继续构建条件为true的语句,如xxx’ or 1=1or ‘1’=’1。

调试输出分别如下:


登录页面,拼凑SQL语句1: select name from user where name='tmp'#' andpassword='d41d8cd98f00b204e9800998ecf8427e'

登录页面查询结果db.java.check_Sql_Login(): true

 

登录页面,拼凑SQL语句1: select name from user where name='xxxxx' or1=1 or '1'='1' and password='d41d8cd98f00b204e9800998ecf8427e'

登录页面查询结果db.java.check_Sql_Login(): true

 

  • 漏洞代码修复


防止SQL注入可使用:(左右滑动查看代码)


     a.推荐使用预编译语句,通过prepared Statements类的set方法对参数进行检测;  

publicbooleancheck_Presql_Login() throws Exception { getConnection(); String name = loginuser.getName(); String passwd = loginuser.getPassword(); boolean flag = false; //定义执行的SQL代码 //区分data和code String sql = "select* from user where name=" + "?" + " andpassword=" + "?"; pst = conn.prepareStatement(sql); pst.setString(1,name); Md5Util md5 = new Md5Util(); passwd = md5.getMD5(passwd.getBytes()); pst.setString(2,passwd); System.out.println("登录页面,预编译SQL语句: " + sql); rs = pst.executeQuery(); if (rs.next()) { flag = true; } else { flag = false; }rs.close();System.out.println("登录页面查询结果" + "db.java.check_Presql_Login():" + flag);return flag;}


     b.使用ESAPI提供的方法;(左右滑动查看代码)

publicbooleancheck_EsapiSql_Login() throws Exception { getConnection(); String name = loginuser.getName(); String passwd = loginuser.getPassword(); boolean flag = false; // 默认返回值是false Md5Util md5 = new Md5Util(); passwd = md5.getMD5(passwd.getBytes()); Codec mysqlCodec = newMySQLCodec(MySQLCodec.MYSQL_MODE); String esapi_name = ESAPI.encoder().encodeForSQL(mysqlCodec,name); String esapi_passwd = ESAPI.encoder().encodeForSQL(mysqlCodec,passwd); // 拼凑的SQL语句,存在注入风险 String sql = "selectname from user where name=" + "'" +esapi_name + "'" + " andpassword=" + "'" + esapi_passwd+ "'"; try { java.sql.Statement st = conn.createStatement(); rs =st.executeQuery(sql); if (rs.next()) { flag = true; } else { flag = false; } st.close(); System.out.println("登录页面查询结果" + "db.java.check_Sql_Login():" + flag); } catch (Exceptione) { e.printStackTrace(); } finally { out.close(); conn.close(); } return flag;    }


c.自定义过滤方法;  


1) 自定义过滤方法(左右滑动查看代码)

protectedstaticboolean sqlValidate(String str) { str = str.toLowerCase();//统一转为小写 String badStr = "'|and|exec|execute|insert|select|delete|update|count|drop|*|%|chr|mid|master|truncate|" + "char|declare|sitename|netuser|xp_cmdshell|;|or|-|+|,|like'|and|exec|execute|insert|create|drop|" + "table|from|grant|use|group_concat|column_name|" + "information_schema.columns|table_schema|union|where|select|delete|update|order|by|count|*|" + "chr|mid|master|truncate|char|declare|or|;|-|--|+|,|like|//|/|%|#";//过滤掉的sql关键字,可以手动添加 String[] badStrs = badStr_miss.split("\\|"); for (int i = 0; i< badStrs.length; i++) { if(str.indexOf(badStrs[i]) >= 0) { System.out.println("发现非法字符:"+badStrs[i]); returntrue; } } returnfalse;}

 

2)对用户输入进行过滤  (左右滑动查看代码)

publicboolean check_ValidSql_Login() throws Exception { getConnection(); String name = loginuser.getName(); String passwd = loginuser.getPassword(); boolean flag = false; // 默认返回值是false Md5Util md5 = new Md5Util(); passwd = md5.getMD5(passwd.getBytes()); // 拼凑的SQL语句,存在注入风险 String sql = "selectname from user where name=" + "'" + name + "'" + " andpassword=" + "'" + passwd + "'"; if (sqlValidate(name)){ System.out.println("登录页面,拼凑SQL语句: " + sql); } else { try { java.sql.Statement st = conn.createStatement(); rs = st.executeQuery(sql); if (rs.next()) { flag = true; } else { flag = false; } st.close(); System.out.println("登录页面查询结果" + "db.java.check_Sql_Login():" + flag); } catch (Exceptione) { e.printStackTrace(); } finally { out.close(); conn.close(); } } return flag;}

 

作者:王爱华 新钛云服安全架构师

二十年IT行业安全咨询、安全技术和安全管理经验,拥有安全行业CISSP、CISA认证,曾任浦东中软、络安、盛大网络、平安付、沪江网等公司安全咨询顾问、安全经理、高级安全研究员、安全架构师职位。处理过互联网公司各类安全问题,包括信息基础架构安全,应用架构和代码安全,应用运维安全,数据安全和灾难恢复等。
熟悉ISO17799、等级保护、PCI-DSS、SOX等信息安全标准规范,具有支付牌照、等级保护、PCI认证的申请、实施和年审经验。熟悉Shell、Python、Java等语言,曾负责搭建metron开源大数据平台,单独开发OWASP TOP 10安全演示平台和企业信息安全管理平台等。


了解新钛云服

新钛云服正式获批工信部ISP/IDC(含互联网资源协作)牌照

深耕专业,矗立鳌头,新钛云服获千万Pre-A轮融资

原电讯盈科中国区副总裁加入新钛云服「附专访」

新钛云服,打造最专业的Cloud MSP+,做企业业务和云之间的桥梁

新钛云服一周年,完成两轮融资,服务五十多家客户

上海某仓储物流电子商务公司混合云解决方案


新钛云服出品的部分精品技术干货

OWASP Top 10安全风险实践(一)

七个用于Docker和Kubernetes防护的安全工具

运维人的终身成长,从清单管理开始|万字长文!

99%运维不知道,系统文件md5变了,竟然是因为......

OpenStack与ZStack深度对比:架构、部署、计算存储与网络、运维监控等

什么是云原生?

IT混合云战略:是什么、为什么,如何构建?

 

 


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存