DCSIMG
עמוד הבית| חבילות השירות שלנו| חומר חופשי| צור קשר
ארכוויז מס’ 6 – איך למנוע סוסים טרויניים ברכיבי .Net שלי? - בלוג היועצים של מיקרוסופט ישראל

בלוג היועצים של מיקרוסופט ישראל

ארכוויז מס’ 6 – איך למנוע סוסים טרויניים ברכיבי .Net שלי?

Alik Levin     פיתחתי רכיב ואני מעוניין לוודא שבזמן ריצה לא השחילו לי איזה סוסון טרויני. אשפרי?

אני גם רוצה לוודא שמי שמרים את הרכיב שלי גם הוא מישהו שאני בוטח בו. אפשרי?

אפשרי בערבון מוגבל. למה בערבון מוגבל? כי באבטחת מידע אין הבטחה מוחלטת – זה עניין של להעלות את הרף עוד ועוד.

תסריט מס’ 1 – הפעלת רכיב בצורה של Early Binding

כדי שרכיבים יזהו אחד את השני Net Fx כולל המצאה שנקראית Code Access Security או בקיצור CAS. מדובר על ניהול ואכיפת הרשאות שלא מבוססות משתמש [ל-CAS לא אכפת מי המשתמש]  אלא ניהול הרשאות על בסיס זהות של רכיב. ישנם הרבי מאפייני זהות של רכיב והכי חזק ביניהם הוא Strong Name. אז כדאי מאוד לחתום את הרכיבים ע”י SNK.

image

כמבון שיש את העניין של ניהול SNK בצורה מאובטחת – זה מכוסה ע”י Delayed Signing.

לא עניין גדול – חתמתי על הרכיב שלי ע”י SNK והוספתי Reference אליו מרכיב אחר ובנייתי את האפליקציה. תהליך הבנייה כלל גם הצמדה של מאפיני SNK בין הרכיבים. בזמן ריצה ה-CLR מזהה את הצימוד הזה ומוודא שהקשר לא נשבראיך אפשר לשבור אותו?למשל, ע”י כך שהרכיב שלי הוחלף ע”י רכיב אחר אך דומה וללא SNK שלי. במקרה של החלפה ה-CLR יעיף את הרכיב הזדוני ויחד איתו את האפליקציה שלי כולל רישום ל-Event Log.

אחלה! נראה פשוט – חותמים עם SNK והכול סבבה במקרה של Early Binding. מה קורה אם אני מרים את הרכיב ב-Reflection? הרי ישנם הרבה מקרים בהם ישנו שימוש מאוד מורחב ב-Reflection כמו במקרה של Provider Design Patterns או בשם אחר Abstract Factory Design Pattern.

תסריט מס’ 2– הפעלת רכיב ע”י Reflection ללא בדיקת חתימה

הקוד הבסיסי להרמת הרכיב בעזרת Reflection הוא דומה לזה:

Assembly asm = Assembly.LoadFrom("TrustedComponent.dll");
Type myType = asm.GetType("TrustedComponent.MyBusinessComponent");
IBusinessComponent myComponent = 
              (IBusinessComponent)Activator.CreateInstance(myType);
Console.WriteLine(myComponent.PerformBusinessAction(Guid.NewGuid().ToString()));
Console.ReadLine();

הקוד הזה יצליח בכל מקרה – עם SNK וללא SNK.  וזה מכיוון שהרכיב מורם בצורת Late Binding. לרכיב המרים אין שום ידע מוקדם לגבי הרכיב המורם.

מסקנה – מי שעובד עם Reflection להרמת רכיבים בצורת Late Binding חסוף לתקיפות של סוסים טרויניים. עם או בלי SNK.

ראה הוזהרת!

תסריט מס’ 3– הפעלת רכיב ע”י Reflection עם בדיקת חתימה

אם אכפת לך מסוסים טרויניים ואתה עובד עם Reflection אז הקטע הבא הוא בשבילך.

אתה צריך לבדוק בתוך הקוד ולהשוות SNKים של שני הרכיבים. ההשוואה הכי בסיסית היא לוודא שהSNKים זהים – הרי את הרכיבים שלך היית חותם עם אותו ה-SNK, נכון? אם ה-SNK לא זהים אז נתקלת במקרה של השחלה של סוס טרויני בקוד שלך. הקוד שבודק ומשווה את ה-SNK נראה פחות או יותר כך:

//GET STRONG NAME FOR THE LOADED ASSEMBLY
StrongName sn = GetStrongName(assembly);

StrongName myStrongName = null;

//GET CURRENT APPDOMAIN STRONG NAME
IEnumerator enumerator = (IEnumerator)AppDomain.CurrentDomain.Evidence.GetEnumerator();
enumerator.Reset();
while (enumerator.MoveNext())
{
    if (enumerator.Current.GetType().Equals(typeof(StrongName)))
        myStrongName = (StrongName)enumerator.Current;
}


if (!sn.PublicKey.Equals(myStrongName.PublicKey))
{
    throw new ApplicationException("SPOOFED!!");
}
static StrongName GetStrongName(Assembly assembly)
{
    if (assembly == null)
        throw new ArgumentNullException("assembly");

    AssemblyName assemblyName = assembly.GetName();
    // get the public key blob
    byte[] publicKey = assemblyName.GetPublicKey();
    if (publicKey == null || publicKey.Length == 0)
        throw new InvalidOperationException(String.Format("{0} is not strongly named", assembly));
    StrongNamePublicKeyBlob keyBlob = new StrongNamePublicKeyBlob(publicKey);

    // create the StrongName
    return new StrongName(keyBlob, assemblyName.Name, assemblyName.Version);
}

אחלה! עכשיו אפשר לנשום לרווחה, לא? :)

תסריט מס’ 4 – Link Demands

אני, הרכיב התמים, לא רוצה שיפעילו אותי כל מי שבא לו אז אני אסמן את עצמי עם SNIP – קיצור של StrongNameIdentityPermission. וואו, כתבתי את זה! שימוש ביכולת הזו מעלה רף הגנה מפני הפעלה לא מורשית של רכיבים שלי [התסריט ההפוך מאלה שדיברתי עליהם קודם]. הנה לך הסבר מצוין איך להשתמש בזה -

Using the StrongNameIdentityPermissionAttribute

חשוב לציין ש-SNIP הוא לא תרופה אולטימטיבית מפני תקיפה של סוסים. במיוחד בסביבה שהיא Full Trust – ה-SNIP לא מזיז ל-CLR במקרה הזה בכלל. Full Trust Means Full Trust

חשבת פעם להגדיר Custom Trust Level? זה יכול לעזור לך עם SNIP.  דרך נוספת לכתוב קוד דומה לזה בתואר בתסריט 3.

 

איך אתה היית מונע תקיפה של סוסים טרויניים על הקוד .Net?

שירותי MCS שאני מדלוור

חומר רלוונטי

 

שמי אליק לוין ואני מתרכז ב- Architecture, Security, and Performance באפליקציות Net.

בזמני הפנוי אני מפתח את עצמי בתחומים רבים אחרים.

This template is made with PracticeThis.com plugin for Windows Live Writer

שלח תגובה

(שדה חובה)  

(שדה חובה)  

(אופציונלי)

(שדה חובה) 

Please add 7 and 6 and type the answer here:


Enter the numbers above: