Bir Saldırının Anatomisi ve Application Domain Sınıfı-3

Bir Saldırının Anatomisi ve Application Domain Sınıfı-3   Bir önceki yazıdan devam edelim ve en son yaptığımız gibi, kendi oluşturduğumuz ozelAlan domainimize  MarshalByRefObjects classından türettiğimiz expTestAssebmly.dll ‘limizi ekleyerek tekrar listeyi alalım.

    class Program    {        static void Main(string[] args)        {            AppDomainSetup domainBilgi = new AppDomainSetup();            domainBilgi.ApplicationBase = "D:\Alt_Domain";            AppDomain ozelAlan = AppDomain.CreateDomain("domain#1", null, domainBilgi);            Console.Write("Default Domain Adı : {0} " +                          "Uygulama Dizini    : {1} " +                          "------------------------ " +                          "Alt Domain Adı     : {2} " +                          "Uygulama Dizini    : {3} ",                          AppDomain.CurrentDomain.FriendlyName,                          AppDomain.CurrentDomain.SetupInformation.ApplicationBase,                          ozelAlan.FriendlyName,                          ozelAlan.SetupInformation.ApplicationBase                          );

 

            Assembly asm = Assembly.LoadFile(ozelAlan.SetupInformation.ApplicationBase + "\expTestAssembly.dll");

            object obj;

            obj = ozelAlan.CreateInstanceAndUnwrap(asm.GetName().Name, "expTestAssembly.Test");

 

            //Assebmly listeleri alınıyor

            Console.Write(" Default Domain Assemblies ------------------------ ");            foreach (Assembly assm in AppDomain.CurrentDomain.GetAssemblies())            {                Console.WriteLine(" " + assm.GetName().Name);            }            Console.Write(" Child Domain Assemblies ------------------------ ");            foreach (Assembly assm in ozelAlan.GetAssemblies())            {                Console.WriteLine(" " + assm.GetName().Name);            }            Console.ReadKey();

    }

}

Burada farkettiğinzi gibi doğrudan ozelAlan.Load() metodunu kullanmadım. Çünkü bir domaine referans yaklaşımıyla nesne ekleyemiyoruz, bunun yerine ozelAlan domaini üzerinden yeni bir instance oluşturuyoruz ve bu yeni nesne doğrudan domain üzerinde yer alıyor. Sadece Assembly’i belirtip ilk ihtiyaç duyduğumuz anda instance’sını oluşturmak yerine herşeyden önce bir instance oluşturmak gerekiyor

Bu işlem için kullanılabilecek dört farklı metod mevcuttur bunlar

ozelAlan.CreateInstance(...) Belirtilen assebmly üzerinden istenilen type için bir instance oluşturur ve bu yeni nesneyi döner

ozelAlan.CreateInstanceAndUnwrap(...)Belirtilen assebmly üzerinden istenilen type için bir instance oluşturur ve bu yeni nesnenin ObjectHandle bilgisini döner

ozelAlan.CreateInstanceFrom(...)Belirtilen assebmly üzerinden istenilen type için bir instance oluşturur ve bu yeni nesneyi döner

ozelAlan.CreateInstanceFromAndUnwrap(...)Belirtilen assebmly üzerinden istenilen type için bir instance oluşturur ve bu yeni nesnenin ObjectHandle bilgisini döner

 

                Buraya kadar yazdıklarımızı kontrol edecek olursak; classımız tamam dll çıktısı Alt_Domain kısmında sorun yok, assemblyi doğrudan bulunduğu yerden instance’layarak ozelAlan Domainine yükledik , yani her şey süper hadi bi kodu çalıştıralım artık.

 

Kodu derledikten sonra muhtemel karşılasacağımız hata: File Not Found

 

Herşeyi eksiksiz yaptığımız ve sorunsuz gözüken kodumuz yukarıdaki gibi bir hata oluşturdu. Bunu sebebi hiç endişelenmeyin siz değilsiniz, çünkü son dongüyü açıklama satırı haline getirip kodu tekrar çalıştırdığınızda aslında expTestAssebmly.dll dosyasını Default Domaine başarlı bir şekilde yüklendiğiniz göreceksiniz. Şimdi Child Domainde kendi Assmebly’imi görmek için yapmam gereken projenin referanslarına expTestAssembly.dll’ini eklemek;

 

expTestAssembly.dll ‘in refransımıza eklenmiş hali

 

Aynı kodu tekrar derleyelim ve ekran çıktısında iki domaindede dll’in bulunduğunu göreceksiniz

 

Kodumuzun son çıktısı

 

Burada çok iyi düşünülmüş bir güvenlik mekanızması var.  Her hangi biri sizin uygulamanız üzerinden başka bir dll çalıştırmak isterse bu dll’öncelikle Proje referanslarında yer almalıdır. Güzel, güvenli olmaya güvenlide yazılmamış bir dll projeme nasıl dahil edilecek peki ??, işte burada Interface ve OOP devreye giriyor. Biz kurallarımızı belirleyen bir Interface yazıyoruz ve sonrasında bu interface’in implement edildiği dll’ler sadece projemize eklenebiliyor. Konuyu dağıtmamak için buna fazla değinmiyorum, Interface Programing ile iligili detaylı bilgiyi sonraki makallerimde bulabileceksiniz. Şimdi bu şekilde Child Domaine dll’ide ekledikten sonra sıra geldi bu domain üzerinde nesneler oluşturmaya ve bunları kullanmaya.

    class Program    {        static void Main(string[] args)        {            AppDomainSetup domainBilgi = new AppDomainSetup();            domainBilgi.ApplicationBase = "D:\Alt_Domain";            AppDomain ozelAlan = AppDomain.CreateDomain("domain#1", null, domainBilgi);            Console.Write("Default Domain Adı : {0} " +                          "Uygulama Dizini    : {1} " +                          "------------------------ " +                          "Alt Domain Adı     : {2} " +                          "Uygulama Dizini    : {3} ",                          AppDomain.CurrentDomain.FriendlyName,                          AppDomain.CurrentDomain.SetupInformation.ApplicationBase,                          ozelAlan.FriendlyName,                          ozelAlan.SetupInformation.ApplicationBase                          );

            //ApplicationBase"de yer alan assembly"i domaine yükleniyor            Assembly asm = Assembly.LoadFile(ozelAlan.SetupInformation.ApplicationBase + \expTestAssembly.dll);

            /* test classının bir instance oluştmak ve kullanmak */            object obj;            obj = ozelAlan.CreateInstanceAndUnwrap(asm.GetName().Name, "expTestAssembly.Test");                        expTestAssembly.Test test = (expTestAssembly.Test)obj;

            test.Navigate(http://suattuncer.blogcu.com);            test.SaveFile("d:\DomainTest.txt", "buda bir test file denemesidir");           

            /*--------------------------------------------------*/            //Assebmly listeleri alınıyor

            Console.Write(" Default Domain Assemblies ------------------------ ");            foreach (Assembly assm in AppDomain.CurrentDomain.GetAssemblies())            {                Console.WriteLine(" " + assm.GetName().Name);            }            Console.Write(" Child Domain Assemblies ------------------------ ");            foreach (Assembly assm in ozelAlan.GetAssemblies())            {                Console.WriteLine(" " + assm.GetName().Name);            } 

            Console.ReadKey();

        }

    }

Kodumuzun son haliyle çalıştırdığımıza , yazdığımız fonksiyonların sorunsuz çalıştığını göreceksiniz.  Kodlarda eklediğim satırlara bakıcak olursanız bildiğiniz sıradan bir cast işlemi gibi görünüyor

            object obj;

            obj = ozelAlan.CreateInstanceAndUnwrap(asm.GetName().Name, "expTestAssembly.Test");

                        expTestAssembly.Test test = (expTestAssembly.Test)obj;

            test.Navigate("http://suattuncer.blogcu.com");

            test.SaveFile("d:\DomainTest.txt", "buda bir test file denemesidir");

 

Bir instance oluştur obj nesnesine ata sonrada bunu test classına cast et , öylemi ? Bakın şimdi Watch ekranında obj nesnesinin değerini bi görelim.

 

Instance’ın AppDomain’den Remoting ile çağrılışının resmi

Umarım yukarıdaki resim biraz daha hayal gücünüzü zorlamayı başarmıştır, şimdi Remoting’deki kuralları bi düşünün ve bunu kendi uygulamalarınızda güvenlik için nasıl implement edeceğinizi düşünün :-). Şimdi size bunları anlatırken programı bir süreliğine BreakPoint’de beklettim daha sonra geri dönüp çalıştırmak istedim ve sonuç !

 

Server bulunamadı veya bağlantı koptu hatası !

Aslında bir çok defa “Remoting çok kullanışsız, bak şu kadar kullanıcı erişince patlıyor” gibi sözlere en güzel cevap bu olsa gerek. .Net Framework için Remoting sadece portlar arası haberleşme değildir.  Bu remote kavramın tam anlamıyla yeniden şekillendirilmesidir. Tekrar AppDomainler üzerinden kod çalıştırmaya dönelim ve şimdide reflection kullanarak method’lara erişelim.

 

test.Navigate("http://suattuncer.blogcu.com");

satırı yerine , aşşağıdaki kodları yazalım

            MethodInfo met;

            met = test.GetType().GetMethod("Navigate");

            object[] param ={ "http://suattuncer.blogcu.com" };

            met.Invoke(test, param);

 

 

Buda yine domain üzerindeki bir metoda erişmek için kullanılan bir yöntemdir fakat kodlama zamanında pek kullanışlı değildir, sadece özel durumlarda, runtime compile uygulamalarında kullanılabilir yine yukarıda bahsettiğim tüm kurallar buradada geçirlidir. Runtime Compiling hakıkında detaylı bilgiyi Runtime Compiling Uygulamasi isimli makalemde bulabilirsiniz.

 

                Bu makalede AppDomain üzerinde nesnelerimize iki farklı yöntemle erişmeyi gördük, aslında en önemlisi AppDomain’ler arasında remotingin nasıl bir görev üstlendiğini ve nasıl çalıştığını inceledik, bir sonraki makalede, güvenlik kuralları belirleyerek kodlarımız çalıştırmaya bakacağız.

Döküman Arama

Başlık :

Kapat