WordPress Shell Finder Kodlamak! (Asenkron Multi-Process)

Bunjo

Uzman üye
14 Ara 2020
1,592
1,889
I Won

oqk18ir.png


lbn20fm.png



pDHFoUY.png


Merhabalar ben saldırı timlerinden Bunjo, bu konuda Wordpress için bir shell finder kodlayacağız.

Bu program verilen URL listesinde kullanıcının girdiği dosyayı arar, kısacası sadece shell aramak için kullanmak yerine kendinize göre konfigüre edebilirsiniz.



Ruby:
require 'eventmachine'
require 'optparse'
require 'thread'
require 'net/http'

  • eventmachine: Asenkron ve olay odaklı programlama için bir kütüphanedir. Bu kod, EventMachine'i kullanarak asenkron işlemleri yönetmekte ve olay tabanlı bir modeli uygulamaktadır.
  • optparse: Komut satırı seçeneklerini işlemek için kullanılır. Bu kod, OptionParser sınıfını kullanarak komut satırı seçeneklerini analiz eder.
  • thread: Çoklu iş parçacığı (thread) desteği sağlayan bir kütüphanedir. Kod, aynı anda birden fazla görevi işleyebilmek için bu kütüphaneyi kullanmaktadır.
  • net/http: HTTP istekleri yapmak ve almak için kullanılan bir kütüphanedir. Bu kod, HTTP istekleri gönderip yanıtları işlemek amacıyla Net::HTTP sınıfını kullanmaktadır.

Ruby:
class SHELL_FINDER
  def initialize
    @headers = {
      'Connection' => 'keep-alive',
      'Cache-Control' => 'max-age=0',
      'Upgrade-Insecure-Requests' => '1',
      'User-Agent' => 'Mozlila/5.0 (Linux; Android 7.0; SM-G892A Bulid/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/60.0.3112.107 Moblie Safari/537.36',
      'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
      'Accept-Encoding' => 'gzip, deflate',
      'Accept-Language' => 'en-US,en;q=0.9,fr;q=0.8',
      'referer' => 'www.google.com'
    }

    @threads = []

    @params = {
      input_file: nil,
      output_file: 'output.txt'
    }
  end

Başlatıcı Metod (initialize): Sınıfın örneklerini başlatırken çağrılan bir metod.
  • @ headers değişkenine, HTTP isteklerinde kullanılacak bir dizi başlık (header) atanır. Bu başlıklar, bir web tarayıcısının normalde gönderdiği başlıklara benzer bilgiler içerir.
  • @threads değişkeni, çoklu iş parçacıklarını (threads) tutan bir dizi olarak başlatılır. Bu, belirli görevleri eşzamanlı olarak yürütmek için kullanılabilir.
  • @params değişkenine varsayılan parametre değerleri atanır. Bu parametreler, giriş dosyası (input_file) ve çıkış dosyası (output_file) için kullanılacaktır.
Ruby:
def parser_options
    begin
      OptionParser.new do |parser|
        parser.on("-i", "--input_file INPUT_FILE") do |input_file|
          if File.exist?(input_file)
            @params[:input_file] = input_file
          else
            STDERR.puts("Not Found: #{input_file}".red)
            exit(1)
          end
        end

        parser.on("-o", "--output_file OUTPUT_FILE") do |output_file|
          @params[:output_file] = output_file
        end
      end.parse!
    rescue Exception => err_parser
      STDERR.puts("Error: #{err_parser}")
    end
  end

OptionParser Kullanımı:

OptionParser.new ile yeni bir OptionParser nesnesi oluşturulur.

parser.on ile belirli komut satırı seçenekleri tanımlanır. -i veya --input_file seçeneği,
giriş dosyasının adını belirlemek için kullanılır. -o veya --output_file seçeneği, çıkış dosyasının adını belirlemek için kullanılır.


Seçenekleri İşleme ve Parametre Ayarlama:

OptionParser bloğu içinde, parse! metodu kullanılarak komut satırı seçenekleri işlenir.

-i veya --input_file seçeneği ile belirlenen giriş dosyası parametresi kontrol edilir. Eğer dosya mevcut ise, @params[:input_file] değeri ayarlanır. Dosya bulunamazsa, bir hata mesajı yazdırılır ve program hata durumunda sonlandırılır.

-o veya --output_file seçeneği ile belirlenen çıkış dosyası parametresi @params[: output_file] değerine atanır.


Hata Kontrolü:

begin ve rescue blokları kullanılarak hata kontrolü sağlanır. Eğer bir hata oluşursa, Exception sınıfından türetilen err_parser değişkeni ile hatanın ayrıntıları alınır.

Hata durumunda STDERR.puts ile hata mesajı yazdırılır.



Ruby:
def parse_lines(lines)
    lines.each do |line|
      shell_finder(line.strip)
    end
  end
  • lines.each do |line|: Giriş olarak alınan lines dizisinin her elemanı üzerinde bir döngü başlatılır.
  • line.strip: Her satırın başındaki ve sonundaki boşlukları temizler.
  • shell_finder(line.strip): Temizlenmiş satır, shell_finder metoduna gönderilir. Bu metodun işlevi, belirli bir URL'yi işlemek ve dosya kontrolü yapmaktır.

Ruby:
def main
    begin
      unless @params[:input_file].nil?
        lines = File.readlines(@params[:input_file])

        lines.each_slice(10) do |line_group|
          @threads << Thread.new{parse_lines(line_group)}
        end

        @threads.each(&:join)

        puts("Exploit Completed".magenta)
        EM.stop
      else
        puts("Please set a URL file.")
        EM.stop
      end
    rescue StandardError
      return
    end
  end

Hata Yakalama (begin ve rescue):
  • begin ve rescue blokları ile metodun içindeki işlemlerin hata durumlarını ele alır.
  • Herhangi bir standart hata (StandardError) oluştuğunda, metodun işlemesini durdurur.
Giriş Dosyasının Varlığını Kontrol Etme:
  • unless @params[:input_file].nil?: Eğer giriş dosyası belirlenmişse (nil değilse), işlemlere devam eder. Aksi takdirde,
  • "Please set a URL file." şeklinde bir mesaj yazdırır ve EventMachine'i durdurur.
Dosyadan Satırları Okuma ve İşleme:
  • lines = File.readlines(@params[:input_file]): Giriş dosyasındaki tüm satırları okur ve lines değişkenine atar.
  • lines.each_slice(10) do |line_group|: Satırları 10'arlı gruplara böler ve her bir grup için ayrı bir iş parçacığı oluşturur.
  • @threads << Thread.new{parse_lines(line_group)}: Her bir grup için bir iş parçacığı oluşturur ve bu iş parçacığını @threads dizisine ekler.
  • Her bir iş parçacığı, parse_lines metodunu çağırarak belirli bir grup satırı işler.
İş Parçacıklarının Tamamlanmasını Bekleme:
  • @threads.each(&:join): Oluşturulan tüm iş parçacıklarının tamamlanmasını bekler. Bu, işlemlerin eşzamanlı olarak çalışmasını sağlar.
Sonuçları Bildirme ve EventMachine'i Durdurma:
  • puts("Exploit Completed".magenta): İşlem tamamlandığında bir mesajı renkli olarak konsola yazdırır.
  • EM.stop: EventMachine'i durdurur. Bu, asenkron işlemlerin ve event döngüsünün sonlandırılmasını sağlar.

    Hata Durumunda:
  • rescue StandardError: Eğer herhangi bir standart hata oluşursa, bu hatayı ele alır ve metodun işlemesini sonlandırır.
  • Bu, beklenmeyen bir hata durumunda programın tamamen kapanmasını engelleyebilir.
Ruby:
 def shell_finder(url)
    begin
      target_url = URI.parse(url)
      target_url.path = "/bunjo.php"

      http = Net::HTTP.new(target_url.host, target_url.port)
      http.use_ssl = (target_url.scheme = "https")

      http.open_timeout = 5
      http.read_timeout = 10

      request = Net::HTTP::Post.new(target_url)

      response = http.request(request)

      if request
        if response.body.include?('bunjo')
          puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Successfully".green)

          File.open(@params[:output_file], "a+") do |file|
            file.puts(target_url)
          end
          return
        else
          puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
          return
        end
      else
        puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
      end
    rescue Net::ReadTimeout
      puts("#{target_url.scheme}://#{target_url.host}#{target_url.path}? --> Not Vuln".red)
    rescue Net::OpenTimeout
      puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
      return
    rescue StandardError
      puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
      return
    end
  end
end

URL'nin Parçalanması ve Hedef URL'nin Oluşturulması:

target_url = URI.parse(url): Verilen URL'yi ayrıştırır ve target_url değişkenine atar.
target_url.path = "/bunjo.php": Hedef URL'nin yolu "/bunjo.php" olarak ayarlanır. Bu, yapılacak isteğin hedefini belirler.

HTTP İsteğinin Hazırlanması ve Gönderilmesi:

http = Net::HTTP.new(target_url.host, target_url.port): Yeni bir Net::HTTP nesnesi oluşturulur ve hedef URL'nin host ve port bilgileri ile yapılandırılır.

http.use_ssl = (target_url.scheme = "https"): Eğer URL "https" şemasi kullanıyorsa, use_ssl özelliği true olarak ayarlanır.

http.open_timeout ve http.read_timeout ile bağlantı ve okuma zaman aşım süreleri ayarlanır.

request = Net::HTTP::post.new(target_url): HTTP POSTisteği oluşturulur.

HTTP İsteğinin Gönderilmesi ve Yanıtın İncelenmesi:

response = http.request(request): Hazırlanan POST isteği gönderilir ve yanıt response değişkenine atanır.

Yanıtın İncelenmesi ve Sonuçların Raporlanması:

if request: İstek başarılı bir şekilde gönderildiyse:

if response.body.include?('bunjo'): Yanıtın gövdesinde 'bunjo' dizesi varsa:

Başarı mesajı ve hedef URL, yeşil renkte konsola yazdırılır.

File.open(@params[: output_file], "a+") do |file|: Çıkış dosyasını açar ve hedef URL'yi dosyaya ekler.

return: Metodu burada sonlandırır.

else: 'bunjo' dizesi yanıtın gövdesinde yoksa:

Başarısız mesaj ve hedef URL, kırmızı renkte konsola yazdırılır.

return: Metodu burada sonlandırır.

else: İstek gönderilemediyse:

Başarısız mesaj ve hedef URL, kırmızı renkte konsola yazdırılır.

Hata Kontrolü ve Raporlama: rescue blokları ile çeşitli hata durumları ele alınır:

Net::ReadTimeout: Okuma zaman aşımı durumunda, hedef URL ve "Not Vuln" mesajı kırmızı renkte konsola yazdırılır.

Net::OpenTimeout: Bağlantı zaman aşımı durumunda, hedef URL ve "Not Vuln" mesajı kırmızı renkte konsola yazdırılır.

StandardError: Diğer standart hata durumlarında, hedef URL ve "Not Vuln" mesajı kırmızı renkte konsola yazdırılır.

Ruby:
class String
  def red
    "\e[31m#{self}\e[0m"
  end

  def green
    "\e[32m#{self}\e[0m"
  end

  def magenta
    "\e[35m#{self}\e[0m"
  end
end

EM.run do
  finder = SHELL_FINDER.new
 finder.parser_options
 finder.main
end

String Sınıfı Uzantısı:

Bu bölümde, String sınıfına ait üç özel renklendirme metodu tanımlanmıştır:

red: Kırmızı renkte metni döndürür.

green: Yeşil renkte metni döndürür.

magenta: Magenta (bordo) renkte metni döndürür.

Bu metodlar, renkli metin oluşturmak için kullanıldı.

EventMachine (EM.run do Bloğu):

EM.run do: EventMachine event döngüsünü başlatmak için kullanılan bir bloktur.

finder = SHELL_FINDER.new: SHELL_FINDER sınıfından bir örnek (finder) oluşturulur.

finder.parser_options: Örnek üzerindeki parser_options metodunu çağırarak komut satırı seçeneklerini işler.


finder.main: Örnek üzerindeki main metodunu çağırarak ana işlemi başlatır.

Tüm Kod:

Ruby:
require 'eventmachine'
require 'optparse'
require 'thread'
require 'net/http'

class SHELL_FINDER
  def initialize
    @headers = {
      'Connection' => 'keep-alive',
      'Cache-Control' => 'max-age=0',
      'Upgrade-Insecure-Requests' => '1',
      'User-Agent' => 'Mozlila/5.0 (Linux; Android 7.0; SM-G892A Bulid/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/60.0.3112.107 Moblie Safari/537.36',
      'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
      'Accept-Encoding' => 'gzip, deflate',
      'Accept-Language' => 'en-US,en;q=0.9,fr;q=0.8',
      'referer' => 'www.google.com'
    }

    @threads = []

    @params = {
      input_file: nil,
      output_file: 'output.txt'
    }
  end

  def parser_options
    begin
      OptionParser.new do |parser|
        parser.on("-i", "--input_file INPUT_FILE") do |input_file|
          if File.exist?(input_file)
            @params[:input_file] = input_file
          else
            STDERR.puts("Not Found: #{input_file}".red)
            exit(1)
          end
        end

        parser.on("-o", "--output_file OUTPUT_FILE") do |output_file|
          @params[:output_file] = output_file
        end
      end.parse!
    rescue Exception => err_parser
      STDERR.puts("Error: #{err_parser}")
    end
  end

  def parse_lines(lines)
    lines.each do |line|
      shell_finder(line.strip)
    end
  end

  def main
    begin
      unless @params[:input_file].nil?
        lines = File.readlines(@params[:input_file])

        lines.each_slice(10) do |line_group|
          @threads << Thread.new{parse_lines(line_group)}
        end

        @threads.each(&:join)

        puts("Exploit Completed".magenta)
        EM.stop
      else
        puts("Please set a URL file.")
        EM.stop
      end
    rescue StandardError
      return
    end
  end

  def shell_finder(url)
    begin
      target_url = URI.parse(url)
      target_url.path = "/bunjo.php"

      http = Net::HTTP.new(target_url.host, target_url.port)
      http.use_ssl = (target_url.scheme = "https")

      http.open_timeout = 5
      http.read_timeout = 10

      request = Net::HTTP::Post.new(target_url)

      response = http.request(request)

      if request
        if response.body.include?('bunjo')
          puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Successfully".green)

          File.open(@params[:output_file], "a+") do |file|
            file.puts(target_url)
          end
          return
        else
          puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
          return
        end
      else
        puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
      end
    rescue Net::ReadTimeout
      puts("#{target_url.scheme}://#{target_url.host}#{target_url.path}? --> Not Vuln".red)
    rescue Net::OpenTimeout
      puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
      return
    rescue StandardError
      puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
      return
    end
  end
end

class String
  def red
    "\e[31m#{self}\e[0m"
  end

  def green
    "\e[32m#{self}\e[0m"
  end

  def magenta
    "\e[35m#{self}\e[0m"
  end
end

EM.run do
  finder = SHELL_FINDER.new
  finder.parser_options
  finder.main
end

bunjo.php shellini ve bunjo anahtar kelimesini ben kendim koydum.

Sizin shellinizin adı x.php ise değiştirebilirsiniz ve sadece sizin shellinizde geçen bir kelimeyi de anahtar kelime olarak kullanabilirsiniz.

Konfigürasyon ve Kullanım:

/bunjo.php'yi /wp-includes olarak, bunjo anahtar kelimesini de .php olarak değiştiriyorum.

ssumq7u.png


/wp-includes içerisinde ".php" metnini içeren siteler geldi. Ben bu örnekte her çoğu sitede geçebilecek bir uzantı kullandım.

Kendinize göre ayarlayabilirsiniz.

İyi forumlar.

Github.


 
Moderatör tarafında düzenlendi:

LordSUCCESS

Uzman üye
17 Eyl 2023
1,349
624
Eline sağlık, Bir süre sonra bundan python'ada yapmayı düşünüyorum, Mantığ nedir?
 

LordSUCCESS

Uzman üye
17 Eyl 2023
1,349
624
Düşünebilirsin. Yazılan konulara, konuları okumadan "eline sağlık" gibi mesajlar yazarsan da yüzlerce satır boyunca anlatılmış bir kodun veya bir programın mantığını anlamazsın.
Hocam anladımda, yani o anlamda demedim mesele siteye wp-content diye istekte bulunuyoruz bize fobiden hatası veriyor biz bunu yaparsak istek 200 yanıtını alır ondan dedim
 

drjacob

Uzman üye
21 Ocak 2012
1,791
416
localhost

oqk18ir.png


lbn20fm.png



pDHFoUY.png


Merhabalar ben saldırı timlerinden Bunjo, bu konuda Wordpress için bir shell finder kodlayacağız.

Bu program verilen URL listesinde kullanıcının girdiği dosyayı arar, kısacası sadece shell aramak için kullanmak yerine kendinize göre konfigüre edebilirsiniz.



Ruby:
require 'eventmachine'
require 'optparse'
require 'thread'
require 'net/http'

  • eventmachine: Asenkron ve olay odaklı programlama için bir kütüphanedir. Bu kod, EventMachine'i kullanarak asenkron işlemleri yönetmekte ve olay tabanlı bir modeli uygulamaktadır.
  • optparse: Komut satırı seçeneklerini işlemek için kullanılır. Bu kod, OptionParser sınıfını kullanarak komut satırı seçeneklerini analiz eder.
  • thread: Çoklu iş parçacığı (thread) desteği sağlayan bir kütüphanedir. Kod, aynı anda birden fazla görevi işleyebilmek için bu kütüphaneyi kullanmaktadır.
  • net/http: HTTP istekleri yapmak ve almak için kullanılan bir kütüphanedir. Bu kod, HTTP istekleri gönderip yanıtları işlemek amacıyla Net::HTTP sınıfını kullanmaktadır.

Ruby:
class SHELL_FINDER
  def initialize
    @headers = {
      'Connection' => 'keep-alive',
      'Cache-Control' => 'max-age=0',
      'Upgrade-Insecure-Requests' => '1',
      'User-Agent' => 'Mozlila/5.0 (Linux; Android 7.0; SM-G892A Bulid/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/60.0.3112.107 Moblie Safari/537.36',
      'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
      'Accept-Encoding' => 'gzip, deflate',
      'Accept-Language' => 'en-US,en;q=0.9,fr;q=0.8',
      'referer' => 'www.google.com'
    }

    @threads = []

    @params = {
      input_file: nil,
      output_file: 'output.txt'
    }
  end

Başlatıcı Metod (initialize): Sınıfın örneklerini başlatırken çağrılan bir metod.
  • @ headers değişkenine, HTTP isteklerinde kullanılacak bir dizi başlık (header) atanır. Bu başlıklar, bir web tarayıcısının normalde gönderdiği başlıklara benzer bilgiler içerir.
  • @threads değişkeni, çoklu iş parçacıklarını (threads) tutan bir dizi olarak başlatılır. Bu, belirli görevleri eşzamanlı olarak yürütmek için kullanılabilir.
  • @params değişkenine varsayılan parametre değerleri atanır. Bu parametreler, giriş dosyası (input_file) ve çıkış dosyası (output_file) için kullanılacaktır.
Ruby:
def parser_options
    begin
      OptionParser.new do |parser|
        parser.on("-i", "--input_file INPUT_FILE") do |input_file|
          if File.exist?(input_file)
            @params[:input_file] = input_file
          else
            STDERR.puts("Not Found: #{input_file}".red)
            exit(1)
          end
        end

        parser.on("-o", "--output_file OUTPUT_FILE") do |output_file|
          @params[:output_file] = output_file
        end
      end.parse!
    rescue Exception => err_parser
      STDERR.puts("Error: #{err_parser}")
    end
  end

OptionParser Kullanımı:

OptionParser.new ile yeni bir OptionParser nesnesi oluşturulur.

parser.on ile belirli komut satırı seçenekleri tanımlanır. -i veya --input_file seçeneği,
giriş dosyasının adını belirlemek için kullanılır. -o veya --output_file seçeneği, çıkış dosyasının adını belirlemek için kullanılır.


Seçenekleri İşleme ve Parametre Ayarlama:

OptionParser bloğu içinde, parse! metodu kullanılarak komut satırı seçenekleri işlenir.

-i veya --input_file seçeneği ile belirlenen giriş dosyası parametresi kontrol edilir. Eğer dosya mevcut ise, @params[:input_file] değeri ayarlanır. Dosya bulunamazsa, bir hata mesajı yazdırılır ve program hata durumunda sonlandırılır.

-o veya --output_file seçeneği ile belirlenen çıkış dosyası parametresi @params[: output_file] değerine atanır.


Hata Kontrolü:

begin ve rescue blokları kullanılarak hata kontrolü sağlanır. Eğer bir hata oluşursa, Exception sınıfından türetilen err_parser değişkeni ile hatanın ayrıntıları alınır.

Hata durumunda STDERR.puts ile hata mesajı yazdırılır.



Ruby:
def parse_lines(lines)
    lines.each do |line|
      shell_finder(line.strip)
    end
  end
  • lines.each do |line|: Giriş olarak alınan lines dizisinin her elemanı üzerinde bir döngü başlatılır.
  • line.strip: Her satırın başındaki ve sonundaki boşlukları temizler.
  • shell_finder(line.strip): Temizlenmiş satır, shell_finder metoduna gönderilir. Bu metodun işlevi, belirli bir URL'yi işlemek ve dosya kontrolü yapmaktır.

Ruby:
def main
    begin
      unless @params[:input_file].nil?
        lines = File.readlines(@params[:input_file])

        lines.each_slice(10) do |line_group|
          @threads << Thread.new{parse_lines(line_group)}
        end

        @threads.each(&:join)

        puts("Exploit Completed".magenta)
        EM.stop
      else
        puts("Please set a URL file.")
        EM.stop
      end
    rescue StandardError
      return
    end
  end

Hata Yakalama (begin ve rescue):
  • begin ve rescue blokları ile metodun içindeki işlemlerin hata durumlarını ele alır.
  • Herhangi bir standart hata (StandardError) oluştuğunda, metodun işlemesini durdurur.
Giriş Dosyasının Varlığını Kontrol Etme:
  • unless @params[:input_file].nil?: Eğer giriş dosyası belirlenmişse (nil değilse), işlemlere devam eder. Aksi takdirde,
  • "Please set a URL file." şeklinde bir mesaj yazdırır ve EventMachine'i durdurur.
Dosyadan Satırları Okuma ve İşleme:
  • lines = File.readlines(@params[:input_file]): Giriş dosyasındaki tüm satırları okur ve lines değişkenine atar.
  • lines.each_slice(10) do |line_group|: Satırları 10'arlı gruplara böler ve her bir grup için ayrı bir iş parçacığı oluşturur.
  • @threads << Thread.new{parse_lines(line_group)}: Her bir grup için bir iş parçacığı oluşturur ve bu iş parçacığını @threads dizisine ekler.
  • Her bir iş parçacığı, parse_lines metodunu çağırarak belirli bir grup satırı işler.
İş Parçacıklarının Tamamlanmasını Bekleme:
  • @threads.each(&:join): Oluşturulan tüm iş parçacıklarının tamamlanmasını bekler. Bu, işlemlerin eşzamanlı olarak çalışmasını sağlar.
Sonuçları Bildirme ve EventMachine'i Durdurma:
  • puts("Exploit Completed".magenta): İşlem tamamlandığında bir mesajı renkli olarak konsola yazdırır.
  • EM.stop: EventMachine'i durdurur. Bu, asenkron işlemlerin ve event döngüsünün sonlandırılmasını sağlar.

    Hata Durumunda:
  • rescue StandardError: Eğer herhangi bir standart hata oluşursa, bu hatayı ele alır ve metodun işlemesini sonlandırır.
  • Bu, beklenmeyen bir hata durumunda programın tamamen kapanmasını engelleyebilir.
Ruby:
 def shell_finder(url)
    begin
      target_url = URI.parse(url)
      target_url.path = "/bunjo.php"

      http = Net::HTTP.new(target_url.host, target_url.port)
      http.use_ssl = (target_url.scheme = "https")

      http.open_timeout = 5
      http.read_timeout = 10

      request = Net::HTTP::Get.new(target_url)

      response = http.request(request)

      if request
        if response.body.include?('bunjo')
          puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Successfully".green)

          File.open(@params[:output_file], "a+") do |file|
            file.puts(target_url)
          end
          return
        else
          puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
          return
        end
      else
        puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
      end
    rescue Net::ReadTimeout
      puts("#{target_url.scheme}://#{target_url.host}#{target_url.path}? --> Not Vuln".red)
    rescue Net::OpenTimeout
      puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
      return
    rescue StandardError
      puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
      return
    end
  end
end

URL'nin Parçalanması ve Hedef URL'nin Oluşturulması:

target_url = URI.parse(url): Verilen URL'yi ayrıştırır ve target_url değişkenine atar.
target_url.path = "/bunjo.php": Hedef URL'nin yolu "/bunjo.php" olarak ayarlanır. Bu, yapılacak isteğin hedefini belirler.

HTTP İsteğinin Hazırlanması ve Gönderilmesi:

http = Net::HTTP.new(target_url.host, target_url.port): Yeni bir Net::HTTP nesnesi oluşturulur ve hedef URL'nin host ve port bilgileri ile yapılandırılır.

http.use_ssl = (target_url.scheme = "https"): Eğer URL "https" şemasi kullanıyorsa, use_ssl özelliği true olarak ayarlanır.

http.open_timeout ve http.read_timeout ile bağlantı ve okuma zaman aşım süreleri ayarlanır.

request = Net::HTTP::Get.new(target_url): HTTP GET isteği oluşturulur.

HTTP İsteğinin Gönderilmesi ve Yanıtın İncelenmesi:

response = http.request(request): Hazırlanan GET isteği gönderilir ve yanıt response değişkenine atanır.

Yanıtın İncelenmesi ve Sonuçların Raporlanması:

if request: İstek başarılı bir şekilde gönderildiyse:

if response.body.include?('bunjo'): Yanıtın gövdesinde 'bunjo' dizesi varsa:

Başarı mesajı ve hedef URL, yeşil renkte konsola yazdırılır.

File.open(@params[: output_file], "a+") do |file|: Çıkış dosyasını açar ve hedef URL'yi dosyaya ekler.

return: Metodu burada sonlandırır.

else: 'bunjo' dizesi yanıtın gövdesinde yoksa:

Başarısız mesaj ve hedef URL, kırmızı renkte konsola yazdırılır.

return: Metodu burada sonlandırır.

else: İstek gönderilemediyse:

Başarısız mesaj ve hedef URL, kırmızı renkte konsola yazdırılır.

Hata Kontrolü ve Raporlama: rescue blokları ile çeşitli hata durumları ele alınır:

Net::ReadTimeout: Okuma zaman aşımı durumunda, hedef URL ve "Not Vuln" mesajı kırmızı renkte konsola yazdırılır.

Net::OpenTimeout: Bağlantı zaman aşımı durumunda, hedef URL ve "Not Vuln" mesajı kırmızı renkte konsola yazdırılır.

StandardError: Diğer standart hata durumlarında, hedef URL ve "Not Vuln" mesajı kırmızı renkte konsola yazdırılır.

Ruby:
class String
  def red
    "\e[31m#{self}\e[0m"
  end

  def green
    "\e[32m#{self}\e[0m"
  end

  def magenta
    "\e[35m#{self}\e[0m"
  end
end

EM.run do
  finder = SHELL_FINDER.new
 finder.parser_options
 finder.main
end

String Sınıfı Uzantısı:

Bu bölümde, String sınıfına ait üç özel renklendirme metodu tanımlanmıştır:

red: Kırmızı renkte metni döndürür.

green: Yeşil renkte metni döndürür.

magenta: Magenta (bordo) renkte metni döndürür.

Bu metodlar, renkli metin oluşturmak için kullanıldı.

EventMachine (EM.run do Bloğu):

EM.run do: EventMachine event döngüsünü başlatmak için kullanılan bir bloktur.

finder = SHELL_FINDER.new: SHELL_FINDER sınıfından bir örnek (finder) oluşturulur.

finder.parser_options: Örnek üzerindeki parser_options metodunu çağırarak komut satırı seçeneklerini işler.


finder.main: Örnek üzerindeki main metodunu çağırarak ana işlemi başlatır.

Tüm Kod:

Ruby:
require 'eventmachine'
require 'optparse'
require 'thread'
require 'net/http'

class SHELL_FINDER
  def initialize
    @headers = {
      'Connection' => 'keep-alive',
      'Cache-Control' => 'max-age=0',
      'Upgrade-Insecure-Requests' => '1',
      'User-Agent' => 'Mozlila/5.0 (Linux; Android 7.0; SM-G892A Bulid/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/60.0.3112.107 Moblie Safari/537.36',
      'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
      'Accept-Encoding' => 'gzip, deflate',
      'Accept-Language' => 'en-US,en;q=0.9,fr;q=0.8',
      'referer' => 'www.google.com'
    }

    @threads = []

    @params = {
      input_file: nil,
      output_file: 'output.txt'
    }
  end

  def parser_options
    begin
      OptionParser.new do |parser|
        parser.on("-i", "--input_file INPUT_FILE") do |input_file|
          if File.exist?(input_file)
            @params[:input_file] = input_file
          else
            STDERR.puts("Not Found: #{input_file}".red)
            exit(1)
          end
        end

        parser.on("-o", "--output_file OUTPUT_FILE") do |output_file|
          @params[:output_file] = output_file
        end
      end.parse!
    rescue Exception => err_parser
      STDERR.puts("Error: #{err_parser}")
    end
  end

  def parse_lines(lines)
    lines.each do |line|
      shell_finder(line.strip)
    end
  end

  def main
    begin
      unless @params[:input_file].nil?
        lines = File.readlines(@params[:input_file])

        lines.each_slice(10) do |line_group|
          @threads << Thread.new{parse_lines(line_group)}
        end

        @threads.each(&:join)

        puts("Exploit Completed".magenta)
        EM.stop
      else
        puts("Please set a URL file.")
        EM.stop
      end
    rescue StandardError
      return
    end
  end

  def shell_finder(url)
    begin
      target_url = URI.parse(url)
      target_url.path = "/bunjo.php"

      http = Net::HTTP.new(target_url.host, target_url.port)
      http.use_ssl = (target_url.scheme = "https")

      http.open_timeout = 5
      http.read_timeout = 10

      request = Net::HTTP::Get.new(target_url)

      response = http.request(request)

      if request
        if response.body.include?('bunjo')
          puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Successfully".green)

          File.open(@params[:output_file], "a+") do |file|
            file.puts(target_url)
          end
          return
        else
          puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
          return
        end
      else
        puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
      end
    rescue Net::ReadTimeout
      puts("#{target_url.scheme}://#{target_url.host}#{target_url.path}? --> Not Vuln".red)
    rescue Net::OpenTimeout
      puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
      return
    rescue StandardError
      puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
      return
    end
  end
end

class String
  def red
    "\e[31m#{self}\e[0m"
  end

  def green
    "\e[32m#{self}\e[0m"
  end

  def magenta
    "\e[35m#{self}\e[0m"
  end
end

EM.run do
  finder = SHELL_FINDER.new
  finder.parser_options
  finder.main
end

bunjo.php shellini ve bunjo anahtar kelimesini ben kendim koydum.

Sizin shellinizin adı x.php ise değiştirebilirsiniz ve sadece sizin shellinizde geçen bir kelimeyi de anahtar kelime olarak kullanabilirsiniz.

Konfigürasyon ve Kullanım:

/bunjo.php'yi /wp-includes olarak, bunjo anahtar kelimesini de .php olarak değiştiriyorum.

ssumq7u.png


/wp-includes içerisinde ".php" metnini içeren siteler geldi. Ben bu örnekte her çoğu sitede geçebilecek bir uzantı kullandım.

Kendinize göre ayarlayabilirsiniz.

İyi forumlar.

Github.


eline sağlık.
 

Gazeteci Şerif

Katılımcı Üye
9 Eyl 2023
309
569
Trablusgarp Cephesi

oqk18ir.png


lbn20fm.png



pDHFoUY.png


Merhabalar ben saldırı timlerinden Bunjo, bu konuda Wordpress için bir shell finder kodlayacağız.

Bu program verilen URL listesinde kullanıcının girdiği dosyayı arar, kısacası sadece shell aramak için kullanmak yerine kendinize göre konfigüre edebilirsiniz.



Ruby:
require 'eventmachine'
require 'optparse'
require 'thread'
require 'net/http'

  • eventmachine: Asenkron ve olay odaklı programlama için bir kütüphanedir. Bu kod, EventMachine'i kullanarak asenkron işlemleri yönetmekte ve olay tabanlı bir modeli uygulamaktadır.
  • optparse: Komut satırı seçeneklerini işlemek için kullanılır. Bu kod, OptionParser sınıfını kullanarak komut satırı seçeneklerini analiz eder.
  • thread: Çoklu iş parçacığı (thread) desteği sağlayan bir kütüphanedir. Kod, aynı anda birden fazla görevi işleyebilmek için bu kütüphaneyi kullanmaktadır.
  • net/http: HTTP istekleri yapmak ve almak için kullanılan bir kütüphanedir. Bu kod, HTTP istekleri gönderip yanıtları işlemek amacıyla Net::HTTP sınıfını kullanmaktadır.

Ruby:
class SHELL_FINDER
  def initialize
    @headers = {
      'Connection' => 'keep-alive',
      'Cache-Control' => 'max-age=0',
      'Upgrade-Insecure-Requests' => '1',
      'User-Agent' => 'Mozlila/5.0 (Linux; Android 7.0; SM-G892A Bulid/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/60.0.3112.107 Moblie Safari/537.36',
      'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
      'Accept-Encoding' => 'gzip, deflate',
      'Accept-Language' => 'en-US,en;q=0.9,fr;q=0.8',
      'referer' => 'www.google.com'
    }

    @threads = []

    @params = {
      input_file: nil,
      output_file: 'output.txt'
    }
  end

Başlatıcı Metod (initialize): Sınıfın örneklerini başlatırken çağrılan bir metod.
  • @ headers değişkenine, HTTP isteklerinde kullanılacak bir dizi başlık (header) atanır. Bu başlıklar, bir web tarayıcısının normalde gönderdiği başlıklara benzer bilgiler içerir.
  • @threads değişkeni, çoklu iş parçacıklarını (threads) tutan bir dizi olarak başlatılır. Bu, belirli görevleri eşzamanlı olarak yürütmek için kullanılabilir.
  • @params değişkenine varsayılan parametre değerleri atanır. Bu parametreler, giriş dosyası (input_file) ve çıkış dosyası (output_file) için kullanılacaktır.
Ruby:
def parser_options
    begin
      OptionParser.new do |parser|
        parser.on("-i", "--input_file INPUT_FILE") do |input_file|
          if File.exist?(input_file)
            @params[:input_file] = input_file
          else
            STDERR.puts("Not Found: #{input_file}".red)
            exit(1)
          end
        end

        parser.on("-o", "--output_file OUTPUT_FILE") do |output_file|
          @params[:output_file] = output_file
        end
      end.parse!
    rescue Exception => err_parser
      STDERR.puts("Error: #{err_parser}")
    end
  end

OptionParser Kullanımı:

OptionParser.new ile yeni bir OptionParser nesnesi oluşturulur.

parser.on ile belirli komut satırı seçenekleri tanımlanır. -i veya --input_file seçeneği,
giriş dosyasının adını belirlemek için kullanılır. -o veya --output_file seçeneği, çıkış dosyasının adını belirlemek için kullanılır.


Seçenekleri İşleme ve Parametre Ayarlama:

OptionParser bloğu içinde, parse! metodu kullanılarak komut satırı seçenekleri işlenir.

-i veya --input_file seçeneği ile belirlenen giriş dosyası parametresi kontrol edilir. Eğer dosya mevcut ise, @params[:input_file] değeri ayarlanır. Dosya bulunamazsa, bir hata mesajı yazdırılır ve program hata durumunda sonlandırılır.

-o veya --output_file seçeneği ile belirlenen çıkış dosyası parametresi @params[: output_file] değerine atanır.


Hata Kontrolü:

begin ve rescue blokları kullanılarak hata kontrolü sağlanır. Eğer bir hata oluşursa, Exception sınıfından türetilen err_parser değişkeni ile hatanın ayrıntıları alınır.

Hata durumunda STDERR.puts ile hata mesajı yazdırılır.



Ruby:
def parse_lines(lines)
    lines.each do |line|
      shell_finder(line.strip)
    end
  end
  • lines.each do |line|: Giriş olarak alınan lines dizisinin her elemanı üzerinde bir döngü başlatılır.
  • line.strip: Her satırın başındaki ve sonundaki boşlukları temizler.
  • shell_finder(line.strip): Temizlenmiş satır, shell_finder metoduna gönderilir. Bu metodun işlevi, belirli bir URL'yi işlemek ve dosya kontrolü yapmaktır.

Ruby:
def main
    begin
      unless @params[:input_file].nil?
        lines = File.readlines(@params[:input_file])

        lines.each_slice(10) do |line_group|
          @threads << Thread.new{parse_lines(line_group)}
        end

        @threads.each(&:join)

        puts("Exploit Completed".magenta)
        EM.stop
      else
        puts("Please set a URL file.")
        EM.stop
      end
    rescue StandardError
      return
    end
  end

Hata Yakalama (begin ve rescue):
  • begin ve rescue blokları ile metodun içindeki işlemlerin hata durumlarını ele alır.
  • Herhangi bir standart hata (StandardError) oluştuğunda, metodun işlemesini durdurur.
Giriş Dosyasının Varlığını Kontrol Etme:
  • unless @params[:input_file].nil?: Eğer giriş dosyası belirlenmişse (nil değilse), işlemlere devam eder. Aksi takdirde,
  • "Please set a URL file." şeklinde bir mesaj yazdırır ve EventMachine'i durdurur.
Dosyadan Satırları Okuma ve İşleme:
  • lines = File.readlines(@params[:input_file]): Giriş dosyasındaki tüm satırları okur ve lines değişkenine atar.
  • lines.each_slice(10) do |line_group|: Satırları 10'arlı gruplara böler ve her bir grup için ayrı bir iş parçacığı oluşturur.
  • @threads << Thread.new{parse_lines(line_group)}: Her bir grup için bir iş parçacığı oluşturur ve bu iş parçacığını @threads dizisine ekler.
  • Her bir iş parçacığı, parse_lines metodunu çağırarak belirli bir grup satırı işler.
İş Parçacıklarının Tamamlanmasını Bekleme:
  • @threads.each(&:join): Oluşturulan tüm iş parçacıklarının tamamlanmasını bekler. Bu, işlemlerin eşzamanlı olarak çalışmasını sağlar.
Sonuçları Bildirme ve EventMachine'i Durdurma:
  • puts("Exploit Completed".magenta): İşlem tamamlandığında bir mesajı renkli olarak konsola yazdırır.
  • EM.stop: EventMachine'i durdurur. Bu, asenkron işlemlerin ve event döngüsünün sonlandırılmasını sağlar.

    Hata Durumunda:
  • rescue StandardError: Eğer herhangi bir standart hata oluşursa, bu hatayı ele alır ve metodun işlemesini sonlandırır.
  • Bu, beklenmeyen bir hata durumunda programın tamamen kapanmasını engelleyebilir.
Ruby:
 def shell_finder(url)
    begin
      target_url = URI.parse(url)
      target_url.path = "/bunjo.php"

      http = Net::HTTP.new(target_url.host, target_url.port)
      http.use_ssl = (target_url.scheme = "https")

      http.open_timeout = 5
      http.read_timeout = 10

      request = Net::HTTP::Get.new(target_url)

      response = http.request(request)

      if request
        if response.body.include?('bunjo')
          puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Successfully".green)

          File.open(@params[:output_file], "a+") do |file|
            file.puts(target_url)
          end
          return
        else
          puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
          return
        end
      else
        puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
      end
    rescue Net::ReadTimeout
      puts("#{target_url.scheme}://#{target_url.host}#{target_url.path}? --> Not Vuln".red)
    rescue Net::OpenTimeout
      puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
      return
    rescue StandardError
      puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
      return
    end
  end
end

URL'nin Parçalanması ve Hedef URL'nin Oluşturulması:

target_url = URI.parse(url): Verilen URL'yi ayrıştırır ve target_url değişkenine atar.
target_url.path = "/bunjo.php": Hedef URL'nin yolu "/bunjo.php" olarak ayarlanır. Bu, yapılacak isteğin hedefini belirler.

HTTP İsteğinin Hazırlanması ve Gönderilmesi:

http = Net::HTTP.new(target_url.host, target_url.port): Yeni bir Net::HTTP nesnesi oluşturulur ve hedef URL'nin host ve port bilgileri ile yapılandırılır.

http.use_ssl = (target_url.scheme = "https"): Eğer URL "https" şemasi kullanıyorsa, use_ssl özelliği true olarak ayarlanır.

http.open_timeout ve http.read_timeout ile bağlantı ve okuma zaman aşım süreleri ayarlanır.

request = Net::HTTP::Get.new(target_url): HTTP GET isteği oluşturulur.

HTTP İsteğinin Gönderilmesi ve Yanıtın İncelenmesi:

response = http.request(request): Hazırlanan GET isteği gönderilir ve yanıt response değişkenine atanır.

Yanıtın İncelenmesi ve Sonuçların Raporlanması:

if request: İstek başarılı bir şekilde gönderildiyse:

if response.body.include?('bunjo'): Yanıtın gövdesinde 'bunjo' dizesi varsa:

Başarı mesajı ve hedef URL, yeşil renkte konsola yazdırılır.

File.open(@params[: output_file], "a+") do |file|: Çıkış dosyasını açar ve hedef URL'yi dosyaya ekler.

return: Metodu burada sonlandırır.

else: 'bunjo' dizesi yanıtın gövdesinde yoksa:

Başarısız mesaj ve hedef URL, kırmızı renkte konsola yazdırılır.

return: Metodu burada sonlandırır.

else: İstek gönderilemediyse:

Başarısız mesaj ve hedef URL, kırmızı renkte konsola yazdırılır.

Hata Kontrolü ve Raporlama: rescue blokları ile çeşitli hata durumları ele alınır:

Net::ReadTimeout: Okuma zaman aşımı durumunda, hedef URL ve "Not Vuln" mesajı kırmızı renkte konsola yazdırılır.

Net::OpenTimeout: Bağlantı zaman aşımı durumunda, hedef URL ve "Not Vuln" mesajı kırmızı renkte konsola yazdırılır.

StandardError: Diğer standart hata durumlarında, hedef URL ve "Not Vuln" mesajı kırmızı renkte konsola yazdırılır.

Ruby:
class String
  def red
    "\e[31m#{self}\e[0m"
  end

  def green
    "\e[32m#{self}\e[0m"
  end

  def magenta
    "\e[35m#{self}\e[0m"
  end
end

EM.run do
  finder = SHELL_FINDER.new
 finder.parser_options
 finder.main
end

String Sınıfı Uzantısı:

Bu bölümde, String sınıfına ait üç özel renklendirme metodu tanımlanmıştır:

red: Kırmızı renkte metni döndürür.

green: Yeşil renkte metni döndürür.

magenta: Magenta (bordo) renkte metni döndürür.

Bu metodlar, renkli metin oluşturmak için kullanıldı.

EventMachine (EM.run do Bloğu):

EM.run do: EventMachine event döngüsünü başlatmak için kullanılan bir bloktur.

finder = SHELL_FINDER.new: SHELL_FINDER sınıfından bir örnek (finder) oluşturulur.

finder.parser_options: Örnek üzerindeki parser_options metodunu çağırarak komut satırı seçeneklerini işler.


finder.main: Örnek üzerindeki main metodunu çağırarak ana işlemi başlatır.

Tüm Kod:

Ruby:
require 'eventmachine'
require 'optparse'
require 'thread'
require 'net/http'

class SHELL_FINDER
  def initialize
    @headers = {
      'Connection' => 'keep-alive',
      'Cache-Control' => 'max-age=0',
      'Upgrade-Insecure-Requests' => '1',
      'User-Agent' => 'Mozlila/5.0 (Linux; Android 7.0; SM-G892A Bulid/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/60.0.3112.107 Moblie Safari/537.36',
      'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
      'Accept-Encoding' => 'gzip, deflate',
      'Accept-Language' => 'en-US,en;q=0.9,fr;q=0.8',
      'referer' => 'www.google.com'
    }

    @threads = []

    @params = {
      input_file: nil,
      output_file: 'output.txt'
    }
  end

  def parser_options
    begin
      OptionParser.new do |parser|
        parser.on("-i", "--input_file INPUT_FILE") do |input_file|
          if File.exist?(input_file)
            @params[:input_file] = input_file
          else
            STDERR.puts("Not Found: #{input_file}".red)
            exit(1)
          end
        end

        parser.on("-o", "--output_file OUTPUT_FILE") do |output_file|
          @params[:output_file] = output_file
        end
      end.parse!
    rescue Exception => err_parser
      STDERR.puts("Error: #{err_parser}")
    end
  end

  def parse_lines(lines)
    lines.each do |line|
      shell_finder(line.strip)
    end
  end

  def main
    begin
      unless @params[:input_file].nil?
        lines = File.readlines(@params[:input_file])

        lines.each_slice(10) do |line_group|
          @threads << Thread.new{parse_lines(line_group)}
        end

        @threads.each(&:join)

        puts("Exploit Completed".magenta)
        EM.stop
      else
        puts("Please set a URL file.")
        EM.stop
      end
    rescue StandardError
      return
    end
  end

  def shell_finder(url)
    begin
      target_url = URI.parse(url)
      target_url.path = "/bunjo.php"

      http = Net::HTTP.new(target_url.host, target_url.port)
      http.use_ssl = (target_url.scheme = "https")

      http.open_timeout = 5
      http.read_timeout = 10

      request = Net::HTTP::Get.new(target_url)

      response = http.request(request)

      if request
        if response.body.include?('bunjo')
          puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Successfully".green)

          File.open(@params[:output_file], "a+") do |file|
            file.puts(target_url)
          end
          return
        else
          puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
          return
        end
      else
        puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
      end
    rescue Net::ReadTimeout
      puts("#{target_url.scheme}://#{target_url.host}#{target_url.path}? --> Not Vuln".red)
    rescue Net::OpenTimeout
      puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
      return
    rescue StandardError
      puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
      return
    end
  end
end

class String
  def red
    "\e[31m#{self}\e[0m"
  end

  def green
    "\e[32m#{self}\e[0m"
  end

  def magenta
    "\e[35m#{self}\e[0m"
  end
end

EM.run do
  finder = SHELL_FINDER.new
  finder.parser_options
  finder.main
end

bunjo.php shellini ve bunjo anahtar kelimesini ben kendim koydum.

Sizin shellinizin adı x.php ise değiştirebilirsiniz ve sadece sizin shellinizde geçen bir kelimeyi de anahtar kelime olarak kullanabilirsiniz.

Konfigürasyon ve Kullanım:

/bunjo.php'yi /wp-includes olarak, bunjo anahtar kelimesini de .php olarak değiştiriyorum.

ssumq7u.png


/wp-includes içerisinde ".php" metnini içeren siteler geldi. Ben bu örnekte her çoğu sitede geçebilecek bir uzantı kullandım.

Kendinize göre ayarlayabilirsiniz.

İyi forumlar.

Github.


Hocam eline emeğine sağlık 👏👏
 

Butcherb3y

Uzman üye
1 Eyl 2022
1,610
1,195
Anıtkabir

oqk18ir.png


lbn20fm.png



pDHFoUY.png


Merhabalar ben saldırı timlerinden Bunjo, bu konuda Wordpress için bir shell finder kodlayacağız.

Bu program verilen URL listesinde kullanıcının girdiği dosyayı arar, kısacası sadece shell aramak için kullanmak yerine kendinize göre konfigüre edebilirsiniz.



Ruby:
require 'eventmachine'
require 'optparse'
require 'thread'
require 'net/http'

  • eventmachine: Asenkron ve olay odaklı programlama için bir kütüphanedir. Bu kod, EventMachine'i kullanarak asenkron işlemleri yönetmekte ve olay tabanlı bir modeli uygulamaktadır.
  • optparse: Komut satırı seçeneklerini işlemek için kullanılır. Bu kod, OptionParser sınıfını kullanarak komut satırı seçeneklerini analiz eder.
  • thread: Çoklu iş parçacığı (thread) desteği sağlayan bir kütüphanedir. Kod, aynı anda birden fazla görevi işleyebilmek için bu kütüphaneyi kullanmaktadır.
  • net/http: HTTP istekleri yapmak ve almak için kullanılan bir kütüphanedir. Bu kod, HTTP istekleri gönderip yanıtları işlemek amacıyla Net::HTTP sınıfını kullanmaktadır.

Ruby:
class SHELL_FINDER
  def initialize
    @headers = {
      'Connection' => 'keep-alive',
      'Cache-Control' => 'max-age=0',
      'Upgrade-Insecure-Requests' => '1',
      'User-Agent' => 'Mozlila/5.0 (Linux; Android 7.0; SM-G892A Bulid/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/60.0.3112.107 Moblie Safari/537.36',
      'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
      'Accept-Encoding' => 'gzip, deflate',
      'Accept-Language' => 'en-US,en;q=0.9,fr;q=0.8',
      'referer' => 'www.google.com'
    }

    @threads = []

    @params = {
      input_file: nil,
      output_file: 'output.txt'
    }
  end

Başlatıcı Metod (initialize): Sınıfın örneklerini başlatırken çağrılan bir metod.
  • @ headers değişkenine, HTTP isteklerinde kullanılacak bir dizi başlık (header) atanır. Bu başlıklar, bir web tarayıcısının normalde gönderdiği başlıklara benzer bilgiler içerir.
  • @threads değişkeni, çoklu iş parçacıklarını (threads) tutan bir dizi olarak başlatılır. Bu, belirli görevleri eşzamanlı olarak yürütmek için kullanılabilir.
  • @params değişkenine varsayılan parametre değerleri atanır. Bu parametreler, giriş dosyası (input_file) ve çıkış dosyası (output_file) için kullanılacaktır.
Ruby:
def parser_options
    begin
      OptionParser.new do |parser|
        parser.on("-i", "--input_file INPUT_FILE") do |input_file|
          if File.exist?(input_file)
            @params[:input_file] = input_file
          else
            STDERR.puts("Not Found: #{input_file}".red)
            exit(1)
          end
        end

        parser.on("-o", "--output_file OUTPUT_FILE") do |output_file|
          @params[:output_file] = output_file
        end
      end.parse!
    rescue Exception => err_parser
      STDERR.puts("Error: #{err_parser}")
    end
  end

OptionParser Kullanımı:

OptionParser.new ile yeni bir OptionParser nesnesi oluşturulur.

parser.on ile belirli komut satırı seçenekleri tanımlanır. -i veya --input_file seçeneği,
giriş dosyasının adını belirlemek için kullanılır. -o veya --output_file seçeneği, çıkış dosyasının adını belirlemek için kullanılır.


Seçenekleri İşleme ve Parametre Ayarlama:

OptionParser bloğu içinde, parse! metodu kullanılarak komut satırı seçenekleri işlenir.

-i veya --input_file seçeneği ile belirlenen giriş dosyası parametresi kontrol edilir. Eğer dosya mevcut ise, @params[:input_file] değeri ayarlanır. Dosya bulunamazsa, bir hata mesajı yazdırılır ve program hata durumunda sonlandırılır.

-o veya --output_file seçeneği ile belirlenen çıkış dosyası parametresi @params[: output_file] değerine atanır.


Hata Kontrolü:

begin ve rescue blokları kullanılarak hata kontrolü sağlanır. Eğer bir hata oluşursa, Exception sınıfından türetilen err_parser değişkeni ile hatanın ayrıntıları alınır.

Hata durumunda STDERR.puts ile hata mesajı yazdırılır.



Ruby:
def parse_lines(lines)
    lines.each do |line|
      shell_finder(line.strip)
    end
  end
  • lines.each do |line|: Giriş olarak alınan lines dizisinin her elemanı üzerinde bir döngü başlatılır.
  • line.strip: Her satırın başındaki ve sonundaki boşlukları temizler.
  • shell_finder(line.strip): Temizlenmiş satır, shell_finder metoduna gönderilir. Bu metodun işlevi, belirli bir URL'yi işlemek ve dosya kontrolü yapmaktır.

Ruby:
def main
    begin
      unless @params[:input_file].nil?
        lines = File.readlines(@params[:input_file])

        lines.each_slice(10) do |line_group|
          @threads << Thread.new{parse_lines(line_group)}
        end

        @threads.each(&:join)

        puts("Exploit Completed".magenta)
        EM.stop
      else
        puts("Please set a URL file.")
        EM.stop
      end
    rescue StandardError
      return
    end
  end

Hata Yakalama (begin ve rescue):
  • begin ve rescue blokları ile metodun içindeki işlemlerin hata durumlarını ele alır.
  • Herhangi bir standart hata (StandardError) oluştuğunda, metodun işlemesini durdurur.
Giriş Dosyasının Varlığını Kontrol Etme:
  • unless @params[:input_file].nil?: Eğer giriş dosyası belirlenmişse (nil değilse), işlemlere devam eder. Aksi takdirde,
  • "Please set a URL file." şeklinde bir mesaj yazdırır ve EventMachine'i durdurur.
Dosyadan Satırları Okuma ve İşleme:
  • lines = File.readlines(@params[:input_file]): Giriş dosyasındaki tüm satırları okur ve lines değişkenine atar.
  • lines.each_slice(10) do |line_group|: Satırları 10'arlı gruplara böler ve her bir grup için ayrı bir iş parçacığı oluşturur.
  • @threads << Thread.new{parse_lines(line_group)}: Her bir grup için bir iş parçacığı oluşturur ve bu iş parçacığını @threads dizisine ekler.
  • Her bir iş parçacığı, parse_lines metodunu çağırarak belirli bir grup satırı işler.
İş Parçacıklarının Tamamlanmasını Bekleme:
  • @threads.each(&:join): Oluşturulan tüm iş parçacıklarının tamamlanmasını bekler. Bu, işlemlerin eşzamanlı olarak çalışmasını sağlar.
Sonuçları Bildirme ve EventMachine'i Durdurma:
  • puts("Exploit Completed".magenta): İşlem tamamlandığında bir mesajı renkli olarak konsola yazdırır.
  • EM.stop: EventMachine'i durdurur. Bu, asenkron işlemlerin ve event döngüsünün sonlandırılmasını sağlar.

    Hata Durumunda:
  • rescue StandardError: Eğer herhangi bir standart hata oluşursa, bu hatayı ele alır ve metodun işlemesini sonlandırır.
  • Bu, beklenmeyen bir hata durumunda programın tamamen kapanmasını engelleyebilir.
Ruby:
 def shell_finder(url)
    begin
      target_url = URI.parse(url)
      target_url.path = "/bunjo.php"

      http = Net::HTTP.new(target_url.host, target_url.port)
      http.use_ssl = (target_url.scheme = "https")

      http.open_timeout = 5
      http.read_timeout = 10

      request = Net::HTTP::Get.new(target_url)

      response = http.request(request)

      if request
        if response.body.include?('bunjo')
          puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Successfully".green)

          File.open(@params[:output_file], "a+") do |file|
            file.puts(target_url)
          end
          return
        else
          puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
          return
        end
      else
        puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
      end
    rescue Net::ReadTimeout
      puts("#{target_url.scheme}://#{target_url.host}#{target_url.path}? --> Not Vuln".red)
    rescue Net::OpenTimeout
      puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
      return
    rescue StandardError
      puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
      return
    end
  end
end

URL'nin Parçalanması ve Hedef URL'nin Oluşturulması:

target_url = URI.parse(url): Verilen URL'yi ayrıştırır ve target_url değişkenine atar.
target_url.path = "/bunjo.php": Hedef URL'nin yolu "/bunjo.php" olarak ayarlanır. Bu, yapılacak isteğin hedefini belirler.

HTTP İsteğinin Hazırlanması ve Gönderilmesi:

http = Net::HTTP.new(target_url.host, target_url.port): Yeni bir Net::HTTP nesnesi oluşturulur ve hedef URL'nin host ve port bilgileri ile yapılandırılır.

http.use_ssl = (target_url.scheme = "https"): Eğer URL "https" şemasi kullanıyorsa, use_ssl özelliği true olarak ayarlanır.

http.open_timeout ve http.read_timeout ile bağlantı ve okuma zaman aşım süreleri ayarlanır.

request = Net::HTTP::Get.new(target_url): HTTP GET isteği oluşturulur.

HTTP İsteğinin Gönderilmesi ve Yanıtın İncelenmesi:

response = http.request(request): Hazırlanan GET isteği gönderilir ve yanıt response değişkenine atanır.

Yanıtın İncelenmesi ve Sonuçların Raporlanması:

if request: İstek başarılı bir şekilde gönderildiyse:

if response.body.include?('bunjo'): Yanıtın gövdesinde 'bunjo' dizesi varsa:

Başarı mesajı ve hedef URL, yeşil renkte konsola yazdırılır.

File.open(@params[: output_file], "a+") do |file|: Çıkış dosyasını açar ve hedef URL'yi dosyaya ekler.

return: Metodu burada sonlandırır.

else: 'bunjo' dizesi yanıtın gövdesinde yoksa:

Başarısız mesaj ve hedef URL, kırmızı renkte konsola yazdırılır.

return: Metodu burada sonlandırır.

else: İstek gönderilemediyse:

Başarısız mesaj ve hedef URL, kırmızı renkte konsola yazdırılır.

Hata Kontrolü ve Raporlama: rescue blokları ile çeşitli hata durumları ele alınır:

Net::ReadTimeout: Okuma zaman aşımı durumunda, hedef URL ve "Not Vuln" mesajı kırmızı renkte konsola yazdırılır.

Net::OpenTimeout: Bağlantı zaman aşımı durumunda, hedef URL ve "Not Vuln" mesajı kırmızı renkte konsola yazdırılır.

StandardError: Diğer standart hata durumlarında, hedef URL ve "Not Vuln" mesajı kırmızı renkte konsola yazdırılır.

Ruby:
class String
  def red
    "\e[31m#{self}\e[0m"
  end

  def green
    "\e[32m#{self}\e[0m"
  end

  def magenta
    "\e[35m#{self}\e[0m"
  end
end

EM.run do
  finder = SHELL_FINDER.new
 finder.parser_options
 finder.main
end

String Sınıfı Uzantısı:

Bu bölümde, String sınıfına ait üç özel renklendirme metodu tanımlanmıştır:

red: Kırmızı renkte metni döndürür.

green: Yeşil renkte metni döndürür.

magenta: Magenta (bordo) renkte metni döndürür.

Bu metodlar, renkli metin oluşturmak için kullanıldı.

EventMachine (EM.run do Bloğu):

EM.run do: EventMachine event döngüsünü başlatmak için kullanılan bir bloktur.

finder = SHELL_FINDER.new: SHELL_FINDER sınıfından bir örnek (finder) oluşturulur.

finder.parser_options: Örnek üzerindeki parser_options metodunu çağırarak komut satırı seçeneklerini işler.


finder.main: Örnek üzerindeki main metodunu çağırarak ana işlemi başlatır.

Tüm Kod:

Ruby:
require 'eventmachine'
require 'optparse'
require 'thread'
require 'net/http'

class SHELL_FINDER
  def initialize
    @headers = {
      'Connection' => 'keep-alive',
      'Cache-Control' => 'max-age=0',
      'Upgrade-Insecure-Requests' => '1',
      'User-Agent' => 'Mozlila/5.0 (Linux; Android 7.0; SM-G892A Bulid/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/60.0.3112.107 Moblie Safari/537.36',
      'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
      'Accept-Encoding' => 'gzip, deflate',
      'Accept-Language' => 'en-US,en;q=0.9,fr;q=0.8',
      'referer' => 'www.google.com'
    }

    @threads = []

    @params = {
      input_file: nil,
      output_file: 'output.txt'
    }
  end

  def parser_options
    begin
      OptionParser.new do |parser|
        parser.on("-i", "--input_file INPUT_FILE") do |input_file|
          if File.exist?(input_file)
            @params[:input_file] = input_file
          else
            STDERR.puts("Not Found: #{input_file}".red)
            exit(1)
          end
        end

        parser.on("-o", "--output_file OUTPUT_FILE") do |output_file|
          @params[:output_file] = output_file
        end
      end.parse!
    rescue Exception => err_parser
      STDERR.puts("Error: #{err_parser}")
    end
  end

  def parse_lines(lines)
    lines.each do |line|
      shell_finder(line.strip)
    end
  end

  def main
    begin
      unless @params[:input_file].nil?
        lines = File.readlines(@params[:input_file])

        lines.each_slice(10) do |line_group|
          @threads << Thread.new{parse_lines(line_group)}
        end

        @threads.each(&:join)

        puts("Exploit Completed".magenta)
        EM.stop
      else
        puts("Please set a URL file.")
        EM.stop
      end
    rescue StandardError
      return
    end
  end

  def shell_finder(url)
    begin
      target_url = URI.parse(url)
      target_url.path = "/bunjo.php"

      http = Net::HTTP.new(target_url.host, target_url.port)
      http.use_ssl = (target_url.scheme = "https")

      http.open_timeout = 5
      http.read_timeout = 10

      request = Net::HTTP::Get.new(target_url)

      response = http.request(request)

      if request
        if response.body.include?('bunjo')
          puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Successfully".green)

          File.open(@params[:output_file], "a+") do |file|
            file.puts(target_url)
          end
          return
        else
          puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
          return
        end
      else
        puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
      end
    rescue Net::ReadTimeout
      puts("#{target_url.scheme}://#{target_url.host}#{target_url.path}? --> Not Vuln".red)
    rescue Net::OpenTimeout
      puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
      return
    rescue StandardError
      puts("#{target_url.scheme}://#{target_url.host}#{target_url.path} --> Not Vuln".red)
      return
    end
  end
end

class String
  def red
    "\e[31m#{self}\e[0m"
  end

  def green
    "\e[32m#{self}\e[0m"
  end

  def magenta
    "\e[35m#{self}\e[0m"
  end
end

EM.run do
  finder = SHELL_FINDER.new
  finder.parser_options
  finder.main
end

bunjo.php shellini ve bunjo anahtar kelimesini ben kendim koydum.

Sizin shellinizin adı x.php ise değiştirebilirsiniz ve sadece sizin shellinizde geçen bir kelimeyi de anahtar kelime olarak kullanabilirsiniz.

Konfigürasyon ve Kullanım:

/bunjo.php'yi /wp-includes olarak, bunjo anahtar kelimesini de .php olarak değiştiriyorum.

ssumq7u.png


/wp-includes içerisinde ".php" metnini içeren siteler geldi. Ben bu örnekte her çoğu sitede geçebilecek bir uzantı kullandım.

Kendinize göre ayarlayabilirsiniz.

İyi forumlar.

Github.


Elinize sağlık hocam yine döktürmüşsunuz
 
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.