Metasploit İçin Yardımcı Modül(Auxiliary) Geliştirme

Metasploit’in hali hazırda birçok istismarı veya çok çeşitli amaçlarla yazılmış bir çok modülü barındırmasının yanı sıra özel amaçlı modüllerin veya istismarların da hızlıca geliştirilmesine olanak tanıması günümüzde çoğu sızma test uzmanının veya istismar geliştiricisinin vazgeçilmez araçlarından biri olmasını sağlamıştır.


Bir iş için ayrı bir betik yazmak yerine bunu bir Metasploit modülü olarak yazmanın başlıca getirisi bu modülü Metasploit’in diğer modülleriyle etkileşim içinde kullanma imkanı elde etmemizdir.
Dokümanın amacı hedef sistemdeki saldırı engelleme sisteminin varlığını tespit edecek bir modül örneği üzerinden Metasploit için yardımcı modül yazımını anlatmaktır. Dokümanı rahatça takip edebilmek içinse Metasploit kullanımına hakim olmak ve giriş seviyesinde Ruby bilmek yeterli olacaktır.

Metasploit’in genel mimarisi Metasploit için mükemmel bir kaynak olan “Metasploit Unleashed” sayfasından alınan aşağıdaki resimde görülebilir.

Modül geliştirmek için her ne kadar genel yapıyı tanımamız gerekse de bizi esas ilgilendiren bölüm kütüphanelerdir. Metasploit’te üç temel kütüphane vardır MSF BASE, MSF CORE ve REX fakat modüllerde gerektiğinde diğer ruby kütüphaneleri de kullanılabilir. Bunlardan MSF BASE Metasploit yazılım çatısının ihtiyaç duyduğu en temel özellikleri barındırır. MSF CORE ise Metasploit’i Metasploit yapan programlama arayüzünü sağlar. REX de soketler, protokoller, kodlayıcılar gibi çok çeşitli işlerden sorumlu kütüphanedir.

Metasploit, modül geliştirmek isteyenler için farklı türde modüllerin taslaklarıyla beraber gelir. Bu taslaklara Metasploit ana dizini altındaki documentation/samples/modules/ dizininden ulaşabilirsiniz.

Bir modül taslağı seçip bunun üzerinden kendi modülümüzü yazmaya başlamadan önce modülün yapacağı işi ve kategorisini tanımlamamız gerekir. Örnek modül hedef sunucuya HTTP GET metodu ile saldırı engelleme sistemlerinin engellemek isteyeceği aşağıdaki dört farklı isteği gönderip isteğin engellenip engellenmemesini baz alarak bir tahmin yürütsün.
‘../../../etc/passwd’
‘etc/passwd’
‘../../../cmd.exe’
‘cmd.exe’

İstekleri gönderildiğinde geriye 404,301,400 gibi HTTP hata mesajları dönüyorsa muhtemelen arada saldırıyı engelleyen bir sistem yoktur (veya IPS kurallarında aktif değildir), eğer RST cevabı dönüyor ya da hiç cevap dönmüyorsa arada bir saldırı engelleme sistemi vardır diyebiliriz.

Zorunlu olmamakla birlikte Metasploitin özel modülleri için ~/.msf4/modules/ dizininin kullanımı tavsiye edilir. Örnek modülün adı ips_check olması ve auxiliary/scanner/misc kategorisine ait olması için msf4/documentation/samples/modules/auxiliary/sample.rb taslak dosyasını ~/.msf4/modules/auxiliary/scanner/misc/ips_check.rb şeklinde kopyalayıp modülü kodlama kısmına geçebiliriz.

Yardımcı modül olayı basitleştirmek adına üç bölümde incelenebilir. İlk bölümde

require ‘msf/core’

class Metasploit4 < Msf::Auxiliary
    include Msf::Exploit::Remote::HttpClient

İlk satırda MSF CORE kütüphanesinin kullanılacağı belirtilip daha sonra sınıfın(Metasploit’te her modül bir Ruby sınıfıdır.) hangi sınıftan türeyeceği gösterilmiştir. Üçüncü satırda da HTTP isteklerinde kullanılacak metodları içeren mixin belirtilmiştir.

İkinci bölümde sınıfın yapıcı metodu incelenebilir. Bu metod modülle ilgili genel bilgilerin belirlendiği, ayarların varsayılan değerlerinin atandığı veya yeni ayarların eklendiği bölümdür.

def initialize
        super(
            ‘Name’        => ‘IPS Check’,
            ‘Version’     => ‘$Revision: 1 $’,
            ‘Description’    => ‘IPS check by sending malicious GET requests’,
            ‘Author’      => ‘Onur Alanbel <onur.alanbel@bga.com.tr>’,
            ‘License’     => MSF_LICENSE,
        )
        register_options(
            [
                Opt::RPORT(80)
            ], self.class
        )
    end

İlk kısımda super metodu ile üst sınıfa modülle ilgili genel bilgiler bildiriliyor, ikinci kısımda ise RPORT seçeneğine varsayılan değer olarak 80 atanıyor. Buradaki register_options a gönderilen listeye
OptString.new(‘SeçenekAdı’’, [ true,  “Seçenek Tanımı”, ‘Varsayılan değeri’’]) satırı eklenerek string tipinde yeni bir seçenek oluşturmak mümkün. Aynı şekilde tamsayı tipinde bir parametre için OptInt.new veya mantıksal bir parametre için OptBool.new kullanılabilir.
Üçüncü bölüm ise run komutu çalıştırıldığında esas işi yapacak kısımdır.

def run
        urllist=[
            ‘../../../etc/passwd’,
            ‘etc/passwd’,
            ‘../../../cmd.exe’,
            ‘cmd.exe’]

        urllist.each do |url|
            begin              
                res = send_request_raw(
                {
                        ‘method’=> ‘GET’,
                        ‘uri’=> url
                })

                if res
                    print_good(“No IPS! for #{url}”)
                else
                    print_status(“IPS(no response) detected for #{url}”)
                end
            rescue Errno::ECONNRESET
                print_status(“IPS(rst) detected for #{url}”)
            rescue Exception
                print_error(“Connection failed.”)
         end
        end
    end

Bu bölümde önce gönderilecek isteklerin listesi oluşturuluyor. (Bu isteklerin seçeneklerden alınacak bir dosyadan okunması daha kullanışlı olur ancak konudan sapmamak adına bu şekilde bırakılmıştır.) Daha sonra bu listedeki her bir eleman için send_raw_request metodu ile http isteği gönderilip eğer bir http cevabı dönerse (if res kısmında ) o istek için engelleme olmadığını ekrana iyi haber olarak yazılıyor. Eğer hiçbir cevap dönmezse (else kısmında) bilgi olarak bir engelleme olduğu bildiriliyor.

Eğer bağlantı sırasında beklenmeyen bir RST gelirse o da istisna olarak yakalanıp (rescue Errno::ECONNRESET kısmında) ekrana yazılıyor. Eğer bilinmeyen(ya da ilgili olmayan) bir şekilde bağlantı koparsa da (rescue Exception kısmında) bağlantı hatası olarak ekrana yazılıyor.

Modülleri Metasploit’e yüklemek için eğer konsol daha önce açıldıysa load veya loadpath komutları ya da açılışta yüklemek için msfconsole komutu -m parametresiyle (msfconsole -m ~/.msf4/modules) kullanılabilir. Daha önceden yüklenmiş bir modül üzerinde yapılan değişikliğin geçerli olması için reload komutu ile tekrar yüklenebilir. Modül yazarken reload ve run komutlarının birleşimi olan rerun komutu da kestirme olması açısından kullanılabilir. Modülün üç örnek durum için çıktısı şu şekildedir.

Modül yazmaya başlamadan önce diğer modül yazarlarının sık yaptığı hataları görmek adına https://github.com/rapid7/metasploit-framework/wiki/Common-Metasploit-Module-Bad-Coding-Practice adresine göz atılmasında fayda var.

ips_check.rb

##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
#   http://metasploit.com/
##

require ‘msf/core’

class Metasploit4 < Msf::Auxiliary
    include Msf::Exploit::Remote::HttpClient

    def initialize
        super(
            ‘Name’        => ‘IPS Check’,
            ‘Version’     => ‘$Revision: 1 $’,
            ‘Description’ => ‘IPS check by malicious GET requests’,
            ‘Author’      => ‘Onur Alanbel <onur.alanbel@bga.com.tr>’,
            ‘License’     => MSF_LICENSE,
        )
        register_options(
            [
                Opt::RPORT(80)
            ], self.class
        )
    end

    def run
        urllist=[
            ‘../../../etc/passwd’,
            ‘etc/passwd’,
            ‘../../../cmd.exe’,
            ‘cmd.exe’]

        urllist.each do |url|
            begin               
                res = send_request_raw(
                {
                        ‘method’=> ‘GET’,
                        ‘uri’=> url
                })

                if res
                    print_good(“No IPS! for #{url}”)
                else
                    print_status(“IPS(no response) detected for #{url}”)
                end
            rescue Errno::ECONNRESET
                print_status(“IPS(rst) detected for #{url}”)
            rescue Exception
                print_error(“Connection failed.”)
            end
        end
    end
end


Onur ALANBEL (onur.alanbel@bga.com.tr)