פיתחתי רכיב ואני מעוניין לוודא שבזמן ריצה לא השחילו לי איזה סוסון טרויני. אשפרי?
אני גם רוצה לוודא שמי שמרים את הרכיב שלי גם הוא מישהו שאני בוטח בו. אפשרי?
אפשרי בערבון מוגבל. למה בערבון מוגבל? כי באבטחת מידע אין הבטחה מוחלטת – זה עניין של להעלות את הרף עוד ועוד.
תסריט מס’ 1 – הפעלת רכיב בצורה של Early Binding
כדי שרכיבים יזהו אחד את השני Net Fx כולל המצאה שנקראית Code Access Security או בקיצור CAS. מדובר על ניהול ואכיפת הרשאות שלא מבוססות משתמש [ל-CAS לא אכפת מי המשתמש] אלא ניהול הרשאות על בסיס זהות של רכיב. ישנם הרבי מאפייני זהות של רכיב והכי חזק ביניהם הוא Strong Name. אז כדאי מאוד לחתום את הרכיבים ע”י SNK.
כמבון שיש את העניין של ניהול 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.
בזמני הפנוי אני מפתח את עצמי בתחומים רבים אחרים.