Proxy Checker & Proxy Destekli Dork Scanner #DevSecOps

Bunjo

Ar-Ge Ekibi Asistanı
14 Ara 2020
1,620
1,956
Expert (J)Ruby Developing

oqk18ir.png


p0qbke2.png


Merhabalar ben AR-GE Ekibi'nden Bunjo, bu konuda proxy destekli gelişmiş bir dork scannerin nasıl kodlanacağını anlatacağım.

Bildiğiniz üzere bizim forumumuz da dahil internette birçok dork tarayıcı projesi/programı var. Bu dork tarayıcların neredeyse hepsi sayfa atlama, proxy desteği veya çıkan robot doğrulamaları analiz ve bypass etme gibi özellikleri içinde barındırmıyor. Bu yazıda elimden geldiğince programı ve genel mantığı detaylı şekilde açıklamaya çalışacağım. Açıklamaları önceden kod okuyabilme becerisine sahip olan kişiler anlayacaktır. Faydası olması dileğiyle keyifli okumalar...



Dork Scanner (Tarayıcı) Nasıl Çalışır?

Ofansif taraflı çalışmalar yapıyorsanız Google'da veya başka bir arama motorunda dork aradığınz mutlaka olmuştur. Aslında dork scanner olarak adlandırdığımız yazılımlar da tamamen bundan ibaret. El ile dork aramanın hem yorucu hem de uzun sürmesi nedenleriyle bu yazılımlara ihtiyaç duyulmuştur. Google üzerinden örnek vereyim, Google'da arama yapmak için kullanacağınız forum "f" harfiyle adlandırılmıştır. İçerisinde bulunan arama yapılacak içerik "textarea" tagları içinde "q" saklanır. Bunları otomatize gerçekleştiren bir script yazalım

Kütüphane:

Bash:
gem install mechanize

Kod:

Ruby:
require 'mechanize'

# Kullanım için Mechanize nesnesi oluştur
agent = Mechanize.new

# Arama yapılacak veri
query = 'inurl: product.php?id= site: .uk'

# Google ana sayfasına git (GET isteği at)
page = agent.get('https://www.google.com')

search_form = page.form_with(name: 'f')
search_form.field_with(name: 'q').value = query
search_results_page = agent.submit(search_form)

# url getir
search_results_page.css('a').each do |a|
  href = a['href']

  if href && href.start_with?("/url?q=")
    url = href.split('&').first.gsub('/url?q=', '')
    puts URI.decode_www_form_component(url)
  end
end

Bu Kodda öncelikle "f" isminde olan form bulunur daha sonra bu formda "q" ismi tanımlanmış olan alan örnek bir dork ile doldurulur. (field) Son olarak form bu şekilde gönderilir ve dönüt incelenir.

Gelen dönütte "a" etiketi ile kullanılan veri bulunur ve içerisinden "href" yani yönlendirme yapılacak olan alan alınır.

Bu alım işlemi sonucunda bir dönütün gelip gelmediği ve gelen bu dönütün "/url?q=" ile başlayıp başlamadığı kontrol edilir.

Eğer başlıyorsa bu veri "&" işaretinin bulunduğu yerden ikiyi bölünüp ilk kısım alınır.

"gsub" metotu ile "/url?q=" kısmı boş string (metin) verisi ile değiştirilir en sona temiz URL verisi kalmış olur.

Örnek:

Kod:
/url?q=https://www.huey.co.uk/shop/cart.php%3Faction%3Dadd%26id%3D65&sa=U&ved=2ahUKEwj05--ss96GAxXuwzgGHe4cCfIQFnoECAcQAg&usg=AOvVaw1RR_OXa1wJ_earOHRc_uGO

https://www.huey.co.uk/shop/cart.php%3Faction%3Dadd%26id%3D65

https://www.huey.co.uk/shop/cart.php?action=add&id=65

Aşamalar şekildeki gibi devam eder.

Bir ayrı senaryoda forum doldurma işlemine girilmeden direkt URL kısmına q parametresine veri yazılır.



p0qbke2.png


Proxy Destekli Dork Tarayıcı

Github: Bağlantı adresi için tıklayınız.

Ruby:
require 'net/http'
require 'thread'
require 'nokogiri'
require 'optparse'
require 'uri'

Gerekli Kütüphaneler ve Sınıflar

Programın çalışması için gerekli kütüphaneler ve açıklamaları. Kütüphaneleri indirmeniz gerektiğinde "gem install kutuphane_adi" komutunu kullanabilirsiniz.

require 'net/http'
  • HTTP isteklerini gerçekleştirmek için kullanılır.
require 'thread'
  • İş parçacıkları (threads) oluşturmak için kullanılır.
require 'nokogiri'
  • HTML ve XML verilerini işlemek (parse etmek) için kullanılır.
require 'optparse'
  • Komut satırı argümanlarını işlemek için kullanılır.
require 'uri'
  • URI (Uniform Resource Identifier) işlemek için kullanılır.
Ruby:
class DorkDevSecOps
  def initialize
    @params = {
      proxy_list: nil,
      dork_list: nil,
      output: 'output.txt',
      timeout: 3,

      proxy_data: Hash.new,
      dork_data: Array.new,
      threads: Array.new
    }
  end

DorkDevSecOps Sınıfı

Bu sınıf, programın ana işlevselliğini sağlar.

initialize Metodu

  • @params adında bir hash oluşturur. Bu hash, proxy ve dork listeleri, çıktı dosyası, zaman aşımı süresi gibi parametreleri tutar.

Ruby:
def http_requester(dorks = "", proxies = "")
    @params[:dork_data].each do |dork_query|
      success = false
      @params[:proxy_data].each do |proxy_ip, proxy_port|
        break if success

        begin
          uri = URI.parse("https://google.com/?q=#{URI.encode_www_form_component(dork_query)}")

          proxy = Net::HTTP.Proxy(proxy_ip, proxy_port).new(uri.host, uri.port)
          proxy.use_ssl = false

          proxy.open_timeout = @params[:timeout]
          proxy.read_timeout = @params[:timeout]

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

          response = proxy.request(request)

          if response
            if captcha_check(response.body)
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> Captcha Bulundu".red)
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> #{response.code} - #{dork_query}".red)
            elsif (200 <= response.code.to_i && response.code.to_i < 300)
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> #{response.code} - #{dork_query}".green)
              check_and_save(response.body)
              success = true
              break
            else
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> #{response.code} - #{dork_query}".red)
            end
          end
        rescue Exception => error
          STDERR.puts("Hata: #{proxy_ip}:#{proxy_port} #{error}".red)
        rescue Net::OpenTimeout, Net::ReadTimeout
          STDERR.puts("Zaman Aşımı: #{proxy_ip}:#{proxy_port}".red)
        end
      end
    end
  end

http_requester Metodu

  • dorks ve proxies adında iki parametre alır. Ancak bu parametreler kullanılmaz.
  • Dorkları ve proxy'leri kullanarak Google'da arama yapar. Her dork sorgusu için proxy listesi üzerinde döngü yapar ve başarılı bir yanıt alana kadar devam eder.
  • Alınan yanıt başarısız olduğu zaman listede diğer sırada bulunan proxy adresini kullanmaya başlar.
  • İstekler sırasında oluşabilecek hataları ve zaman aşımı durumlarını yakalar ve hata mesajlarını yazdırır.
  • Yanıtın captcha içerip içermediğini kontrol eder ve sonuçları ekrana yazdırır.

Ruby:
def check_and_save(output)
    doc = Nokogiri::HTML(output)

      File.open(@params[:output], "a") do |fileman|
        doc.css('a').each do |a|
          href = a['href']

          if href && href.start_with?('/url?q=')
            decoded_url = href.split('&').first.gsub('/url?q=', '')
            url = URI.decode_www_form_component(decoded_url)
            fileman.puts(url)
          end
        end
      end
  end

check_and_save Metodu

Yazının ilk başında bahsettiğim kısmı programımın bu yerine kullandım.
  • Google arama sonuçlarını işler ve output.txt dosyasına sonuçları kaydeder.
  • HTML içindeki bağlantıları bulur ve /url?q= ile başlayan bağlantıları çözümler.

Ruby:
def print_help
    help_text = <<-'HELP_TEXT'
Parametreler:
  -p, --proxy-list PROXY_LIST: Proxy listesi tanımlamak için kullanılır.
  -d, --dork-list DORK_LIST: Dork listesi tanımlamak için kullanılır.
  -t, --timeout TIMEOUT: İsteklere zaman aşımı vermek için kullanılır.

  HELP_TEXT

    STDOUT.puts(help_text.blue)
  end

Programın kullanımı hakkında yardım metnini ekrana yazdırır.

Ruby:
def option_parser
    begin
      OptionParser.new do |opts|
        opts.on("-p", "--proxy-list PROXY_LIST", String, "Proxy listesi tanımlamak için kullanılır.") do |proxy_list|
          if File.exist?(proxy_list)
            @params[:proxy_list] = proxy_list
          else
            STDERR.puts("Hata: Belirtilen proxy listesi #{proxy_list} bulunamadı!".red)
            exit(1)
          end
        end

        opts.on("-c", "--cores", "İşlem parçacıklarını tanımlamak için kullanılır.") do |cores|
          @params[:cores] = cores
        end

        opts.on("-d", "--dork-list DORK_LIST", String, "Dork listesi tanımlamak için kullanılır.") do |dork_list|
          if File.exist?(dork_list)
            @params[:dork_list] = dork_list
          else
            STDERR.puts("Hata: Belirtilen dork listesi #{dork_list} bulunamadı!".red)
            exit(1)
          end
        end

        opts.on("-a", "--add", String, "Dorkların sonuna metin eklemesi yapmak için kullanılır.") do |add_to_dork|
          @params[:add_to_dork] = add_to_dork
        end

        opts.on("-h", "--help", "Yardım menüsünü ekrana yazdırır.") do
          print_help
          exit(0)
        end
      end.parse!
    rescue Exception => error
      STDERR.puts("Hata: #{error.class}:#{error.message}".red)
      exit!
    end
  end

option_parser Metodu

  • Komut satırı argümanlarını işler ve @params hash'ini günceller.
  • Proxy ve dork listelerinin var olup olmadığını kontrol eder. Hata durumunda programdan çıkar.
  • zaman aşımı süresi için veri alımı yaapr.
Ruby:
def proxy_loader
    proxy_data_lines = File.readlines(@params[:proxy_list]).uniq

    proxy_data_lines.each do |line|
      begin
        proxy_ip, proxy_port = line.split(":")
        @params[:proxy_data][proxy_ip.strip] = proxy_port.to_i if proxy_ip and proxy_port
      rescue Exception => error
        STDERR.puts("Hata: #{error.class}:#{error.message}".red)
        next
      end
    end
  end

  def dork_loader
    dork_data_lines = File.readlines(@params[:dork_list]).uniq

    dork_data_lines.each do |dork|
      @params[:dork_data].append(dork)
    end
  end

proxy_loader Metodu

  • Proxy listesini dosyadan okur ve @params[: proxy_data] hash'ine ekler.

dork_loader Metodu

  • Dork listesini dosyadan okur ve @params[:dork_data] array'ine ekler.

Ruby:
def display_params
    params_text = <<-"PARAMS"
Atanmış Parametreler:
  Dork Listesi: #{@params[:dork_list]}
  Proxy Listesi: #{@params[:proxy_list]}
    PARAMS

    puts params_text.blue
  end

display_params Metodu

  • Ayarlanmış parametreleri ekrana yazdırır.
Ruby:
def main
    begin
      option_parser

      if @params[:dork_list].nil? || @params[:proxy_list].nil?
        print_help
        exit!
      end

      proxy_loader
      dork_loader
      display_params

      http_requester
    rescue Interrupt

    end
  end
end

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

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

  def yellow
    "\e[33m#{self}\e[0m"
  end

  def blue
    "\e[34m#{self}\e[0m"
  end

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

dorkscan = DorkDevSecOps.new
dorkscan.main

main Metodu

  • Programın ana akışını yönetir.
  • Komut satırı argümanlarını işler, proxy ve dork listelerini yükler ve HTTP isteklerini başlatır.

String Sınıfı Üzerinde Değişiklikler

  • String sınıfına red, green, yellow, blue, ve magenta metodları eklenmiştir. Bu metodlar, metinleri renkli olarak konsola yazdırmak için kullanılır.

Programın Çalıştırılması

  • DorkDevSecOps sınıfından bir nesne oluşturulur ve main metodu çağrılır.

p0qbke2.png


Örnek Proxy Listesi

Kod:
70.166.167.38:57728
223.135.156.183:8080
186.215.87.194:30024
104.165.127.155:3128
18.133.16.21:1080
107.179.51.165:5808
38.242.240.167:49923
103.129.3.246:83
222.88.167.22:9002
103.247.23.69:8080
67.43.228.254:7169
59.11.82.216:3128
170.245.132.15:999
202.91.41.17:8888
200.108.190.38:999
103.109.212.85:1080
50.217.226.42:80
72.10.160.174:21013
211.128.96.206:80
45.4.144.232:4153
47.251.43.115:33333
158.177.111.149:3128
45.159.150.23:3128
190.140.31.195:9900
104.165.169.125:3128
104.233.13.226:6221
162.223.94.164:80
77.233.5.68:55443
190.94.213.8:999
189.250.135.40:80
102.209.18.26:8080
43.129.249.83:8888
192.241.243.131:9150
104.239.78.74:6019
103.127.63.57:5678
103.237.78.102:4996
213.136.84.202:16046
91.221.177.40:80
193.106.109.195:80
45.181.122.201:999
185.105.90.88:4444
183.88.223.211:8080
50.223.239.183:80
104.165.127.186:3128
185.161.186.83:54321
154.0.154.230:8080
23.228.83.39:5735
36.64.27.123:5678
50.168.72.117:80
72.10.160.90:9361
216.173.120.127:6419
188.125.167.67:8080
161.123.101.58:6684
195.138.90.226:3128
5.180.19.163:1080
223.207.102.16:4000
164.92.86.113:62027
176.192.65.34:5020
20.44.190.150:3129
49.13.48.21:80
59.144.184.73:80
121.182.138.71:80
133.18.234.13:80
172.183.241.1:8080
192.111.137.35:4145
13.36.87.105:3128
43.134.32.184:3128
104.223.157.148:6387
72.10.160.91:21477
104.238.111.107:15073
50.168.72.122:80
13.56.192.187:3128
202.6.224.52:1080
20.206.106.192:8123
8.242.178.5:999
190.94.212.76:999
154.113.121.60:80
50.231.110.26:80
182.253.39.206:8080


Tüm Kaynak Kodu:

Ruby:
require 'net/http'
require 'thread'
require 'nokogiri'
require 'optparse'
require 'uri'

# Not:
# Program şuan için sadece "HTTP" türünde Proxy desteklemektedir.
# Proxy listesi IP:PORT şeklinde olmalıdır.

class DorkDevSecOps
  def initialize
    @params = {
      proxy_list: nil,
      dork_list: nil,
      output: 'output.txt',
      timeout: 3,

      proxy_data: Hash.new,
      dork_data: Array.new,
      threads: Array.new
    }
  end

  def http_requester(dorks = "", proxies = "")
    @params[:dork_data].each do |dork_query|
      success = false
      @params[:proxy_data].each do |proxy_ip, proxy_port|
        break if success

        begin
          uri = URI.parse("https://google.com/?q=#{URI.encode_www_form_component(dork_query)}")

          proxy = Net::HTTP.Proxy(proxy_ip, proxy_port).new(uri.host, uri.port)
          proxy.use_ssl = false

          proxy.open_timeout = @params[:timeout]
          proxy.read_timeout = @params[:timeout]

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

          response = proxy.request(request)

          if response
            if captcha_check(response.body)
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> Captcha Bulundu".red)
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> #{response.code} - #{dork_query}".red)
            elsif (200 <= response.code.to_i && response.code.to_i < 300)
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> #{response.code} - #{dork_query}".green)
              check_and_save(response.body)
              success = true
              break
            else
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> #{response.code} - #{dork_query}".red)
            end
          end
        rescue Exception => error
          STDERR.puts("Hata: #{proxy_ip}:#{proxy_port} #{error}".red)
        rescue Net::OpenTimeout, Net::ReadTimeout
          STDERR.puts("Zaman Aşımı: #{proxy_ip}:#{proxy_port}".red)
        end
      end
    end
  end

  def check_and_save(output)
    doc = Nokogiri::HTML(output)

      File.open(@params[:output], "a") do |fileman|
        doc.css('a').each do |a|
          href = a['href']

          if href && href.start_with?('/url?q=')
            decoded_url = href.split('&').first.gsub('/url?q=', '')
            url = URI.decode_www_form_component(decoded_url)
            fileman.puts(url)
          end
        end
      end
  end

  def captcha_check(body)
    return body.include?("recaptcha")
  end

  def print_help
    help_text = <<-'HELP_TEXT'
Parametreler:
  -p, --proxy-list PROXY_LIST: Proxy listesi tanımlamak için kullanılır.
  -d, --dork-list DORK_LIST: Dork listesi tanımlamak için kullanılır.
  -t, --timeout TIMEOUT: İsteklere zaman aşımı vermek için kullanılır.

  HELP_TEXT

    STDOUT.puts(help_text.blue)
  end

  def option_parser
    begin
      OptionParser.new do |opts|
        opts.on("-p", "--proxy-list PROXY_LIST", String, "Proxy listesi tanımlamak için kullanılır.") do |proxy_list|
          if File.exist?(proxy_list)
            @params[:proxy_list] = proxy_list
          else
            STDERR.puts("Hata: Belirtilen proxy listesi #{proxy_list} bulunamadı!".red)
            exit(1)
          end
        end

        opts.on("-c", "--cores", "İşlem parçacıklarını tanımlamak için kullanılır.") do |cores|
          @params[:cores] = cores
        end

        opts.on("-d", "--dork-list DORK_LIST", String, "Dork listesi tanımlamak için kullanılır.") do |dork_list|
          if File.exist?(dork_list)
            @params[:dork_list] = dork_list
          else
            STDERR.puts("Hata: Belirtilen dork listesi #{dork_list} bulunamadı!".red)
            exit(1)
          end
        end

        opts.on("-a", "--add", String, "Dorkların sonuna metin eklemesi yapmak için kullanılır.") do |add_to_dork|
          @params[:add_to_dork] = add_to_dork
        end

        opts.on("-h", "--help", "Yardım menüsünü ekrana yazdırır.") do
          print_help
          exit(0)
        end
      end.parse!
    rescue Exception => error
      STDERR.puts("Hata: #{error.class}:#{error.message}".red)
      exit!
    end
  end

  def proxy_loader
    proxy_data_lines = File.readlines(@params[:proxy_list]).uniq

    proxy_data_lines.each do |line|
      begin
        proxy_ip, proxy_port = line.split(":")
        @params[:proxy_data][proxy_ip.strip] = proxy_port.to_i if proxy_ip and proxy_port
      rescue Exception => error
        STDERR.puts("Hata: #{error.class}:#{error.message}".red)
        next
      end
    end
  end

  def dork_loader
    dork_data_lines = File.readlines(@params[:dork_list]).uniq

    dork_data_lines.each do |dork|
      @params[:dork_data].append(dork)
    end
  end

  def display_params
    params_text = <<-"PARAMS"
Atanmış Parametreler:
  Dork Listesi: #{@params[:dork_list]}
  Proxy Listesi: #{@params[:proxy_list]}
    PARAMS

    puts params_text.blue
  end

  def main
    begin
      option_parser

      if @params[:dork_list].nil? || @params[:proxy_list].nil?
        print_help
        exit!
      end

      proxy_loader
      dork_loader
      display_params

      http_requester
    rescue Interrupt

    end
  end
end

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

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

  def yellow
    "\e[33m#{self}\e[0m"
  end

  def blue
    "\e[34m#{self}\e[0m"
  end

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

dorkscan = DorkDevSecOps.new
dorkscan.main


p0qbke2.png


Program Hakkında

Bu program daha geliştirilme aşamasındadır. Bu yüzden gözünün üstünde kaşı var diye yapılan eleştiriler dışındaki her eleştiri büyük önem taşır.

Program hakkında olan görüşlerinizi, önerilerinizi ve eleştirilerinizi bekliyorum.

Yazılıma Eklenecek Desteklerden Bazıları:

- Sayfa atlama desteği (en fazla 10-15 sayfa olacak şekilde)
- Daha sıkı robot doğrulama algılama
- Paralel programlamayla çoklu thread desteği
- HTTPS proxy desteği

Google otomatize yazılımlardan yüksek seviyede korunma yöntemleri almış durumdadır. İnternette public olarak bulduğunuz proxy verilerinin çok büyük bir kısmı Google tarafından algılanır. Program çalışıp istek sonucu 200 kodu dönse bile, "dork" arama sonucunuza ait bir sonuç bulunamadı şeklinde dönütler alırsınız bu dönütlerin program ile hiçbir alakası olmamakla beraber sadece kullandığınız proxy verisine bağlıdır.

Kütüphane Kurulumları:

Bash:
gem install nokogiri

p0qbke2.png


Programın Kullanımı

Bash:
ruby program.rb -p proxy_dosyasi.txt -d dork_dosyasi.txt

95vcp8y.jpg


Gelen çıktının bir kısmı:

b1nvshl.png

pDHFoUY.png


Yukarıda bahsettiğim projede kullanabileceğiniz bir proxy checker yazılımı.

Github: GitHub - bayruby/HTTP-Proxy-Checker


pDHFoUY.png


Kaynak Kodu ve Açıklaması

Kütüphane aktarımları:

Ruby:
require 'net/http'
require 'optparse'
require 'uri'
  • net/http: HTTP istekleri göndermek için kullanılır.
  • optparse: Komut satırı argümanlarını işlemek için kullanılır.
  • uri: URL'leri ayrıştırmak ve işlemek için kullanılır.
Program sınıfının oluşturulması ve değişkenlerin tanımlanması

Ruby:
class Proxy_Auto
  def initialize
    @proxy_data = Hash.new
    @threads = Array.new
    @url_file = nil
    @proxy_file = nil
    @url = 'http://example.com'
    @output = 'proxy_success.txt'
  end
  • @proxy_data: Proxy verilerini saklamak için kullanılan bir hash (yani sözlük gibi düşünün).
  • @threads: Thread'leri saklamak için kullanılan bir dizi (liste).
  • @url: HTTP isteği gönderilecek varsayılan URL.
  • @output: Başarılı proxy bağlantılarının kaydedileceği dosya.
Terminalden veri aktarımı yapılması için parser fonksiyonu

Ruby:
def optparser
    OptionParser.new do |parser|
      parser.on("-p", "--proxy-list PROXY_LIST") { |proxy_file| @proxy_file = proxy_file }
    end.parse!
  end

Kullanıcının vereceği proxy dosyasını için veri girdisi parametresi ("-p")

HTTP isteklerinin yapılması için kullanılacak olan fonksiyon

Ruby:
  def http_proxy(url, proxy_addr, proxy_port)
    begin
      uri = URI.parse(url)

      proxy_http = Net::HTTP.Proxy(proxy_addr, proxy_port).new(uri.host, uri.port)
      proxy_http.use_ssl = (uri.scheme == 'https')

      proxy_http.open_timeout = 3
      proxy_http.read_timeout = 3

      request = Net::HTTP::Get.new(url)
      response = proxy_http.request(request)

      puts("URL: #{url}\nResponse Code: #{response.code}\nProxy IP: #{proxy_addr}\nProxy Port: #{proxy_port}".green)
      puts("-" * 30)

      File.open(@output, 'a+') { |file| file.puts("#{proxy_addr}:#{proxy_port}") }
    rescue Exception
      puts("#{proxy_addr}:#{proxy_port} --> Error".red)
      return
    end
  end

Bu fonksiyon, bir HTTP GET isteği gönderir:
  • uri değişkeni ile URL ayrıştırılır (parse edilir).
  • Proxy ayarları ile bir HTTP istemcisi (clienti) oluşturulur.
  • İstek zaman aşımı süreleri ve ssl kullanımı ayarlanır.
  • İstek gönderilir ve yanıt alınır.
  • Yanıt başarıyla alındığında, bu bilgi ekrana yazdırılır ve başarılı proxy bilgileri bir dosyaya kaydedilir.
  • Hata durumunda, hata mesajı ekrana yazdırılır.

Ruby:
def proxy_processer(proxy_addr, proxy_port)
    @threads << Thread.new { http_proxy(@url, proxy_addr, proxy_port) }
end

Proxy listesini teker teker okuyarak IP adresi, port numarası ayırma ve değişkene atama işleminin yapılacağı fonksiyon

Ruby:
def read_proxies
    proxies = File.readlines(@proxy_file)

    proxies.each do |proxy|
      proxy_ip, proxy_port = proxy.split(':')
      @proxy_data[proxy_ip.strip] = proxy_port.to_i
    end
  end

Eş zamanlı çalışma yapılacağı bu fonksiyon tanımlanır.

Fonksiyon kendisine gelen bölünmüş halde olan proxy listesini teker teker işleyerek HTTP isteğinin yapılacağı fonksiyonu çalıştıran yeni bir işlem parçacığı (thread) oluşturur.

Fonksiyonları başlatacak olan ana metot


Ruby:
  def main
    optparser
    read_proxies

    @proxy_data.each do |proxy_addr, proxy_port|
      proxy_processer(proxy_addr, proxy_port)
    end

    @threads.each(&:join)
  end
end

Programın çalışması için daha önceden tanımlanan gerekli fonksiyonları başlatır.

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

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

  def yellow
    "\e[33m#{self}\e[0m"
  end

  def blue
    "\e[34m#{self}\e[0m"
  end

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

auto_proxy = Proxy_Auto.new
auto_proxy.main

Çıktı renklendirmesi ve sınıf çağrımı

Tüm Kod:

Ruby:
require 'net/http'
require 'optparse'
require 'uri'

class Proxy_Auto
  def initialize
    @proxy_data = Hash.new
    @threads = Array.new
    @url_file = nil
    @proxy_file = nil
    @url = 'http://example.com'
    @output = 'proxy_success.txt'
  end

  def optparser
    OptionParser.new do |parser|
      parser.on("-p", "--proxy-list PROXY_LIST") { |proxy_file| @proxy_file = proxy_file }
    end.parse!
  end

  def http_proxy(url, proxy_addr, proxy_port)
    begin
      uri = URI.parse(url)

      proxy_http = Net::HTTP.Proxy(proxy_addr, proxy_port).new(uri.host, uri.port)
      proxy_http.use_ssl = (uri.scheme == 'https')

      proxy_http.open_timeout = 3
      proxy_http.read_timeout = 3

      request = Net::HTTP::Get.new(url)
      response = proxy_http.request(request)

      puts("URL: #{url}\nResponse Code: #{response.code}\nProxy IP: #{proxy_addr}\nProxy Port: #{proxy_port}".green)
      puts("-" * 30)

      File.open(@output, 'a+') { |file| file.puts("#{proxy_addr}:#{proxy_port}") }
    rescue Exception
      puts("#{proxy_addr}:#{proxy_port} --> Error".red)
      return
    end
  end

  def proxy_processer(proxy_addr, proxy_port)
    @threads << Thread.new { http_proxy(@url, proxy_addr, proxy_port) }
  end

  def read_proxies
    proxies = File.readlines(@proxy_file)

    proxies.each do |proxy|
      proxy_ip, proxy_port = proxy.split(':')
      @proxy_data[proxy_ip.strip] = proxy_port.to_i
    end
  end

  def main
    optparser
    read_proxies

    @proxy_data.each do |proxy_addr, proxy_port|
      proxy_processer(proxy_addr, proxy_port)
    end

    @threads.each(&:join)
  end
end

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

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

  def yellow
    "\e[33m#{self}\e[0m"
  end

  def blue
    "\e[34m#{self}\e[0m"
  end

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

auto_proxy = Proxy_Auto.new
auto_proxy.main

pDHFoUY.png


Programın Kullanımı

Bash:
ruby program_ismi.rb -p proxy_dosyasi.txt

j3iu0c9.gif



pDHFoUY.png


Programı geliştirme sürecinde bana yardımcı olan @ExeOweR, @Hea7, @teux ve @Suppressor hocalarıma teşekkür ediyorum.

Okuyan herkese teşekkürler, kendinize göre editleyip kullanabilirsiniz.


 

CH

Uzman üye
28 Ocak 2019
1,966
907
Siber
Ar-Ge Ekibini yürekten ve can-ı gönülden tebrik ederim başarılarımız daim olsun DevSecOps hayırlı olsun 👋🏻🇹🇷
 

Znéa

Administrator
19 Tem 2011
4,393
116
Bongomya
Projeyi yaparken kısım kısım takılmana rağmen güzelce aştın yapım aşamasının bir kısmında izleyebilme fırsatım oldu. Güzel ve üzerine uğraşılmış bir proje eline sağlık.
 

Bunjo

Ar-Ge Ekibi Asistanı
14 Ara 2020
1,620
1,956
Expert (J)Ruby Developing
Eline sağlık, Şemistan ve ben seni tebrik ediyoruz.
Ar-Ge Ekibini yürekten ve can-ı gönülden tebrik ederim başarılarımız daim olsun DevSecOps hayırlı olsun 👋🏻🇹🇷
Eline sağlık kardeşim, proje gelişime açıktır fikirleri Bunjo mutlaka önemser (y)
Eline sağlık kardeşim :)

//Konu Sabit
Projeyi yaparken kısım kısım takılmana rağmen güzelce aştın yapım aşamasının bir kısmında izleyebilme fırsatım oldu. Güzel ve üzerine uğraşılmış bir proje eline sağlık.
Şemistan başta olmak üzere güzel mesajlarınız için hepinize çok teşekkür ederim.
 

LydexCoding

Moderasyon Ekibi Çaylak
24 May 2024
388
125
:)

oqk18ir.png


p0qbke2.png


Merhabalar ben AR-GE Ekibi'nden Bunjo, bu konuda proxy destekli gelişmiş bir dork scannerin nasıl kodlanacağını anlatacağım.

Bildiğiniz üzere bizim forumumuz da dahil internette birçok dork tarayıcı projesi/programı var. Bu dork tarayıcların neredeyse hepsi sayfa atlama, proxy desteği veya çıkan robot doğrulamaları analiz ve bypass etme gibi özellikleri içinde barındırmıyor. Bu yazıda elimden geldiğince programı ve genel mantığı detaylı şekilde açıklamaya çalışacağım. Açıklamaları önceden kod okuyabilme becerisine sahip olan kişiler anlayacaktır. Faydası olması dileğiyle keyifli okumalar...



Dork Scanner (Tarayıcı) Nasıl Çalışır?

Ofansif taraflı çalışmalar yapıyorsanız Google'da veya başka bir arama motorunda dork aradığınz mutlaka olmuştur. Aslında dork scanner olarak adlandırdığımız yazılımlar da tamamen bundan ibaret. El ile dork aramanın hem yorucu hem de uzun sürmesi nedenleriyle bu yazılımlara ihtiyaç duyulmuştur. Google üzerinden örnek vereyim, Google'da arama yapmak için kullanacağınız forum "f" harfiyle adlandırılmıştır. İçerisinde bulunan arama yapılacak içerik "textarea" tagları içinde "q" saklanır. Bunları otomatize gerçekleştiren bir script yazalım

Kütüphane:

Bash:
gem install mechanize

Kod:

Ruby:
require 'mechanize'

# Kullanım için Mechanize nesnesi oluştur
agent = Mechanize.new

# Arama yapılacak veri
query = 'inurl: product.php?id= site: .uk'

# Google ana sayfasına git (GET isteği at)
page = agent.get('https://www.google.com')

search_form = page.form_with(name: 'f')
search_form.field_with(name: 'q').value = query
search_results_page = agent.submit(search_form)

# url getir
search_results_page.css('a').each do |a|
  href = a['href']

  if href && href.start_with?("/url?q=")
    url = href.split('&').first.gsub('/url?q=', '')
    puts URI.decode_www_form_component(url)
  end
end

Bu Kodda öncelikle "f" isminde olan form bulunur daha sonra bu formda "q" ismi tanımlanmış olan alan örnek bir dork ile doldurulur. (field) Son olarak form bu şekilde gönderilir ve dönüt incelenir.

Gelen dönütte "a" etiketi ile kullanılan veri bulunur ve içerisinden "href" yani yönlendirme yapılacak olan alan alınır.

Bu alım işlemi sonucunda bir dönütün gelip gelmediği ve gelen bu dönütün "/url?q=" ile başlayıp başlamadığı kontrol edilir.

Eğer başlıyorsa bu veri "&" işaretinin bulunduğu yerden ikiyi bölünüp ilk kısım alınır.

"gsub" metotu ile "/url?q=" kısmı boş string (metin) verisi ile değiştirilir en sona temiz URL verisi kalmış olur.

Örnek:

Kod:
/url?q=https://www.huey.co.uk/shop/cart.php%3Faction%3Dadd%26id%3D65&sa=U&ved=2ahUKEwj05--ss96GAxXuwzgGHe4cCfIQFnoECAcQAg&usg=AOvVaw1RR_OXa1wJ_earOHRc_uGO

https://www.huey.co.uk/shop/cart.php%3Faction%3Dadd%26id%3D65

https://www.huey.co.uk/shop/cart.php?action=add&id=65

Aşamalar şekildeki gibi devam eder.

Bir ayrı senaryoda forum doldurma işlemine girilmeden direkt URL kısmına q parametresine veri yazılır.



p0qbke2.png


Proxy Destekli Dork Tarayıcı

Github: Bağlantı adresi için tıklayınız.

Ruby:
require 'net/http'
require 'thread'
require 'nokogiri'
require 'optparse'
require 'uri'

Gerekli Kütüphaneler ve Sınıflar

Programın çalışması için gerekli kütüphaneler ve açıklamaları. Kütüphaneleri indirmeniz gerektiğinde "gem install kutuphane_adi" komutunu kullanabilirsiniz.

require 'net/http'
  • HTTP isteklerini gerçekleştirmek için kullanılır.
require 'thread'
  • İş parçacıkları (threads) oluşturmak için kullanılır.
require 'nokogiri'
  • HTML ve XML verilerini işlemek (parse etmek) için kullanılır.
require 'optparse'
  • Komut satırı argümanlarını işlemek için kullanılır.
require 'uri'
  • URI (Uniform Resource Identifier) işlemek için kullanılır.
Ruby:
class DorkDevSecOps
  def initialize
    @params = {
      proxy_list: nil,
      dork_list: nil,
      output: 'output.txt',
      timeout: 3,

      proxy_data: Hash.new,
      dork_data: Array.new,
      threads: Array.new
    }
  end

DorkDevSecOps Sınıfı

Bu sınıf, programın ana işlevselliğini sağlar.

initialize Metodu

  • @params adında bir hash oluşturur. Bu hash, proxy ve dork listeleri, çıktı dosyası, zaman aşımı süresi gibi parametreleri tutar.

Ruby:
def http_requester(dorks = "", proxies = "")
    @params[:dork_data].each do |dork_query|
      success = false
      @params[:proxy_data].each do |proxy_ip, proxy_port|
        break if success

        begin
          uri = URI.parse("https://google.com/?q=#{URI.encode_www_form_component(dork_query)}")

          proxy = Net::HTTP.Proxy(proxy_ip, proxy_port).new(uri.host, uri.port)
          proxy.use_ssl = false

          proxy.open_timeout = @params[:timeout]
          proxy.read_timeout = @params[:timeout]

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

          response = proxy.request(request)

          if response
            if captcha_check(response.body)
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> Captcha Bulundu".red)
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> #{response.code} - #{dork_query}".red)
            elsif (200 <= response.code.to_i && response.code.to_i < 300)
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> #{response.code} - #{dork_query}".green)
              check_and_save(response.body)
              success = true
              break
            else
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> #{response.code} - #{dork_query}".red)
            end
          end
        rescue Exception => error
          STDERR.puts("Hata: #{proxy_ip}:#{proxy_port} #{error}".red)
        rescue Net::OpenTimeout, Net::ReadTimeout
          STDERR.puts("Zaman Aşımı: #{proxy_ip}:#{proxy_port}".red)
        end
      end
    end
  end

http_requester Metodu

  • dorks ve proxies adında iki parametre alır. Ancak bu parametreler kullanılmaz.
  • Dorkları ve proxy'leri kullanarak Google'da arama yapar. Her dork sorgusu için proxy listesi üzerinde döngü yapar ve başarılı bir yanıt alana kadar devam eder.
  • Alınan yanıt başarısız olduğu zaman listede diğer sırada bulunan proxy adresini kullanmaya başlar.
  • İstekler sırasında oluşabilecek hataları ve zaman aşımı durumlarını yakalar ve hata mesajlarını yazdırır.
  • Yanıtın captcha içerip içermediğini kontrol eder ve sonuçları ekrana yazdırır.

Ruby:
def check_and_save(output)
    doc = Nokogiri::HTML(output)

      File.open(@params[:output], "a") do |fileman|
        doc.css('a').each do |a|
          href = a['href']

          if href && href.start_with?('/url?q=')
            decoded_url = href.split('&').first.gsub('/url?q=', '')
            url = URI.decode_www_form_component(decoded_url)
            fileman.puts(url)
          end
        end
      end
  end

check_and_save Metodu

Yazının ilk başında bahsettiğim kısmı programımın bu yerine kullandım.
  • Google arama sonuçlarını işler ve output.txt dosyasına sonuçları kaydeder.
  • HTML içindeki bağlantıları bulur ve /url?q= ile başlayan bağlantıları çözümler.

Ruby:
def print_help
    help_text = <<-'HELP_TEXT'
Parametreler:
  -p, --proxy-list PROXY_LIST: Proxy listesi tanımlamak için kullanılır.
  -d, --dork-list DORK_LIST: Dork listesi tanımlamak için kullanılır.
  -t, --timeout TIMEOUT: İsteklere zaman aşımı vermek için kullanılır.

  HELP_TEXT

    STDOUT.puts(help_text.blue)
  end

Programın kullanımı hakkında yardım metnini ekrana yazdırır.

Ruby:
def option_parser
    begin
      OptionParser.new do |opts|
        opts.on("-p", "--proxy-list PROXY_LIST", String, "Proxy listesi tanımlamak için kullanılır.") do |proxy_list|
          if File.exist?(proxy_list)
            @params[:proxy_list] = proxy_list
          else
            STDERR.puts("Hata: Belirtilen proxy listesi #{proxy_list} bulunamadı!".red)
            exit(1)
          end
        end

        opts.on("-c", "--cores", "İşlem parçacıklarını tanımlamak için kullanılır.") do |cores|
          @params[:cores] = cores
        end

        opts.on("-d", "--dork-list DORK_LIST", String, "Dork listesi tanımlamak için kullanılır.") do |dork_list|
          if File.exist?(dork_list)
            @params[:dork_list] = dork_list
          else
            STDERR.puts("Hata: Belirtilen dork listesi #{dork_list} bulunamadı!".red)
            exit(1)
          end
        end

        opts.on("-a", "--add", String, "Dorkların sonuna metin eklemesi yapmak için kullanılır.") do |add_to_dork|
          @params[:add_to_dork] = add_to_dork
        end

        opts.on("-h", "--help", "Yardım menüsünü ekrana yazdırır.") do
          print_help
          exit(0)
        end
      end.parse!
    rescue Exception => error
      STDERR.puts("Hata: #{error.class}:#{error.message}".red)
      exit!
    end
  end

option_parser Metodu

  • Komut satırı argümanlarını işler ve @params hash'ini günceller.
  • Proxy ve dork listelerinin var olup olmadığını kontrol eder. Hata durumunda programdan çıkar.
  • zaman aşımı süresi için veri alımı yaapr.
Ruby:
def proxy_loader
    proxy_data_lines = File.readlines(@params[:proxy_list]).uniq

    proxy_data_lines.each do |line|
      begin
        proxy_ip, proxy_port = line.split(":")
        @params[:proxy_data][proxy_ip.strip] = proxy_port.to_i if proxy_ip and proxy_port
      rescue Exception => error
        STDERR.puts("Hata: #{error.class}:#{error.message}".red)
        next
      end
    end
  end

  def dork_loader
    dork_data_lines = File.readlines(@params[:dork_list]).uniq

    dork_data_lines.each do |dork|
      @params[:dork_data].append(dork)
    end
  end

proxy_loader Metodu

  • Proxy listesini dosyadan okur ve @params[: proxy_data] hash'ine ekler.

dork_loader Metodu

  • Dork listesini dosyadan okur ve @params[:dork_data] array'ine ekler.

Ruby:
def display_params
    params_text = <<-"PARAMS"
Atanmış Parametreler:
  Dork Listesi: #{@params[:dork_list]}
  Proxy Listesi: #{@params[:proxy_list]}
    PARAMS

    puts params_text.blue
  end

display_params Metodu

  • Ayarlanmış parametreleri ekrana yazdırır.
Ruby:
def main
    begin
      option_parser

      if @params[:dork_list].nil? || @params[:proxy_list].nil?
        print_help
        exit!
      end

      proxy_loader
      dork_loader
      display_params

      http_requester
    rescue Interrupt

    end
  end
end

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

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

  def yellow
    "\e[33m#{self}\e[0m"
  end

  def blue
    "\e[34m#{self}\e[0m"
  end

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

dorkscan = DorkDevSecOps.new
dorkscan.main

main Metodu

  • Programın ana akışını yönetir.
  • Komut satırı argümanlarını işler, proxy ve dork listelerini yükler ve HTTP isteklerini başlatır.

String Sınıfı Üzerinde Değişiklikler

  • String sınıfına red, green, yellow, blue, ve magenta metodları eklenmiştir. Bu metodlar, metinleri renkli olarak konsola yazdırmak için kullanılır.

Programın Çalıştırılması

  • DorkDevSecOps sınıfından bir nesne oluşturulur ve main metodu çağrılır.

p0qbke2.png


Örnek Proxy Listesi

Kod:
70.166.167.38:57728
223.135.156.183:8080
186.215.87.194:30024
104.165.127.155:3128
18.133.16.21:1080
107.179.51.165:5808
38.242.240.167:49923
103.129.3.246:83
222.88.167.22:9002
103.247.23.69:8080
67.43.228.254:7169
59.11.82.216:3128
170.245.132.15:999
202.91.41.17:8888
200.108.190.38:999
103.109.212.85:1080
50.217.226.42:80
72.10.160.174:21013
211.128.96.206:80
45.4.144.232:4153
47.251.43.115:33333
158.177.111.149:3128
45.159.150.23:3128
190.140.31.195:9900
104.165.169.125:3128
104.233.13.226:6221
162.223.94.164:80
77.233.5.68:55443
190.94.213.8:999
189.250.135.40:80
102.209.18.26:8080
43.129.249.83:8888
192.241.243.131:9150
104.239.78.74:6019
103.127.63.57:5678
103.237.78.102:4996
213.136.84.202:16046
91.221.177.40:80
193.106.109.195:80
45.181.122.201:999
185.105.90.88:4444
183.88.223.211:8080
50.223.239.183:80
104.165.127.186:3128
185.161.186.83:54321
154.0.154.230:8080
23.228.83.39:5735
36.64.27.123:5678
50.168.72.117:80
72.10.160.90:9361
216.173.120.127:6419
188.125.167.67:8080
161.123.101.58:6684
195.138.90.226:3128
5.180.19.163:1080
223.207.102.16:4000
164.92.86.113:62027
176.192.65.34:5020
20.44.190.150:3129
49.13.48.21:80
59.144.184.73:80
121.182.138.71:80
133.18.234.13:80
172.183.241.1:8080
192.111.137.35:4145
13.36.87.105:3128
43.134.32.184:3128
104.223.157.148:6387
72.10.160.91:21477
104.238.111.107:15073
50.168.72.122:80
13.56.192.187:3128
202.6.224.52:1080
20.206.106.192:8123
8.242.178.5:999
190.94.212.76:999
154.113.121.60:80
50.231.110.26:80
182.253.39.206:8080


Tüm Kaynak Kodu:

Ruby:
require 'net/http'
require 'thread'
require 'nokogiri'
require 'optparse'
require 'uri'

# Not:
# Program şuan için sadece "HTTP" türünde Proxy desteklemektedir.
# Proxy listesi IP:PORT şeklinde olmalıdır.

class DorkDevSecOps
  def initialize
    @params = {
      proxy_list: nil,
      dork_list: nil,
      output: 'output.txt',
      timeout: 3,

      proxy_data: Hash.new,
      dork_data: Array.new,
      threads: Array.new
    }
  end

  def http_requester(dorks = "", proxies = "")
    @params[:dork_data].each do |dork_query|
      success = false
      @params[:proxy_data].each do |proxy_ip, proxy_port|
        break if success

        begin
          uri = URI.parse("https://google.com/?q=#{URI.encode_www_form_component(dork_query)}")

          proxy = Net::HTTP.Proxy(proxy_ip, proxy_port).new(uri.host, uri.port)
          proxy.use_ssl = false

          proxy.open_timeout = @params[:timeout]
          proxy.read_timeout = @params[:timeout]

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

          response = proxy.request(request)

          if response
            if captcha_check(response.body)
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> Captcha Bulundu".red)
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> #{response.code} - #{dork_query}".red)
            elsif (200 <= response.code.to_i && response.code.to_i < 300)
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> #{response.code} - #{dork_query}".green)
              check_and_save(response.body)
              success = true
              break
            else
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> #{response.code} - #{dork_query}".red)
            end
          end
        rescue Exception => error
          STDERR.puts("Hata: #{proxy_ip}:#{proxy_port} #{error}".red)
        rescue Net::OpenTimeout, Net::ReadTimeout
          STDERR.puts("Zaman Aşımı: #{proxy_ip}:#{proxy_port}".red)
        end
      end
    end
  end

  def check_and_save(output)
    doc = Nokogiri::HTML(output)

      File.open(@params[:output], "a") do |fileman|
        doc.css('a').each do |a|
          href = a['href']

          if href && href.start_with?('/url?q=')
            decoded_url = href.split('&').first.gsub('/url?q=', '')
            url = URI.decode_www_form_component(decoded_url)
            fileman.puts(url)
          end
        end
      end
  end

  def captcha_check(body)
    return body.include?("recaptcha")
  end

  def print_help
    help_text = <<-'HELP_TEXT'
Parametreler:
  -p, --proxy-list PROXY_LIST: Proxy listesi tanımlamak için kullanılır.
  -d, --dork-list DORK_LIST: Dork listesi tanımlamak için kullanılır.
  -t, --timeout TIMEOUT: İsteklere zaman aşımı vermek için kullanılır.

  HELP_TEXT

    STDOUT.puts(help_text.blue)
  end

  def option_parser
    begin
      OptionParser.new do |opts|
        opts.on("-p", "--proxy-list PROXY_LIST", String, "Proxy listesi tanımlamak için kullanılır.") do |proxy_list|
          if File.exist?(proxy_list)
            @params[:proxy_list] = proxy_list
          else
            STDERR.puts("Hata: Belirtilen proxy listesi #{proxy_list} bulunamadı!".red)
            exit(1)
          end
        end

        opts.on("-c", "--cores", "İşlem parçacıklarını tanımlamak için kullanılır.") do |cores|
          @params[:cores] = cores
        end

        opts.on("-d", "--dork-list DORK_LIST", String, "Dork listesi tanımlamak için kullanılır.") do |dork_list|
          if File.exist?(dork_list)
            @params[:dork_list] = dork_list
          else
            STDERR.puts("Hata: Belirtilen dork listesi #{dork_list} bulunamadı!".red)
            exit(1)
          end
        end

        opts.on("-a", "--add", String, "Dorkların sonuna metin eklemesi yapmak için kullanılır.") do |add_to_dork|
          @params[:add_to_dork] = add_to_dork
        end

        opts.on("-h", "--help", "Yardım menüsünü ekrana yazdırır.") do
          print_help
          exit(0)
        end
      end.parse!
    rescue Exception => error
      STDERR.puts("Hata: #{error.class}:#{error.message}".red)
      exit!
    end
  end

  def proxy_loader
    proxy_data_lines = File.readlines(@params[:proxy_list]).uniq

    proxy_data_lines.each do |line|
      begin
        proxy_ip, proxy_port = line.split(":")
        @params[:proxy_data][proxy_ip.strip] = proxy_port.to_i if proxy_ip and proxy_port
      rescue Exception => error
        STDERR.puts("Hata: #{error.class}:#{error.message}".red)
        next
      end
    end
  end

  def dork_loader
    dork_data_lines = File.readlines(@params[:dork_list]).uniq

    dork_data_lines.each do |dork|
      @params[:dork_data].append(dork)
    end
  end

  def display_params
    params_text = <<-"PARAMS"
Atanmış Parametreler:
  Dork Listesi: #{@params[:dork_list]}
  Proxy Listesi: #{@params[:proxy_list]}
    PARAMS

    puts params_text.blue
  end

  def main
    begin
      option_parser

      if @params[:dork_list].nil? || @params[:proxy_list].nil?
        print_help
        exit!
      end

      proxy_loader
      dork_loader
      display_params

      http_requester
    rescue Interrupt

    end
  end
end

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

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

  def yellow
    "\e[33m#{self}\e[0m"
  end

  def blue
    "\e[34m#{self}\e[0m"
  end

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

dorkscan = DorkDevSecOps.new
dorkscan.main


p0qbke2.png


Program Hakkında

Bu program daha geliştirilme aşamasındadır. Bu yüzden gözünün üstünde kaşı var diye yapılan eleştiriler dışındaki her eleştiri büyük önem taşır.

Program hakkında olan görüşlerinizi, önerilerinizi ve eleştirilerinizi bekliyorum.

Yazılıma Eklenecek Desteklerden Bazıları:

- Sayfa atlama desteği (en fazla 10-15 sayfa olacak şekilde)
- Daha sıkı robot doğrulama algılama
- Paralel programlamayla çoklu thread desteği
- HTTPS proxy desteği

Google otomatize yazılımlardan yüksek seviyede korunma yöntemleri almış durumdadır. İnternette public olarak bulduğunuz proxy verilerinin çok büyük bir kısmı Google tarafından algılanır. Program çalışıp istek sonucu 200 kodu dönse bile, "dork" arama sonucunuza ait bir sonuç bulunamadı şeklinde dönütler alırsınız bu dönütlerin program ile hiçbir alakası olmamakla beraber sadece kullandığınız proxy verisine bağlıdır.

Kütüphane Kurulumları:

Bash:
gem install nokogiri

p0qbke2.png


Programın Kullanımı

Bash:
ruby program.rb -p proxy_dosyasi.txt -d dork_dosyasi.txt

95vcp8y.jpg


Gelen çıktının bir kısmı:

b1nvshl.png

pDHFoUY.png


Yukarıda bahsettiğim projede kullanabileceğiniz bir proxy checker yazılımı.

Github: GitHub - bayruby/HTTP-Proxy-Checker


pDHFoUY.png


Kaynak Kodu ve Açıklaması

Kütüphane aktarımları:

Ruby:
require 'net/http'
require 'optparse'
require 'uri'
  • net/http: HTTP istekleri göndermek için kullanılır.
  • optparse: Komut satırı argümanlarını işlemek için kullanılır.
  • uri: URL'leri ayrıştırmak ve işlemek için kullanılır.
Program sınıfının oluşturulması ve değişkenlerin tanımlanması

Ruby:
class Proxy_Auto
  def initialize
    @proxy_data = Hash.new
    @threads = Array.new
    @url_file = nil
    @proxy_file = nil
    @url = 'http://example.com'
    @output = 'proxy_success.txt'
  end
  • @proxy_data: Proxy verilerini saklamak için kullanılan bir hash (yani sözlük gibi düşünün).
  • @threads: Thread'leri saklamak için kullanılan bir dizi (liste).
  • @url: HTTP isteği gönderilecek varsayılan URL.
  • @output: Başarılı proxy bağlantılarının kaydedileceği dosya.
Terminalden veri aktarımı yapılması için parser fonksiyonu

Ruby:
def optparser
    OptionParser.new do |parser|
      parser.on("-p", "--proxy-list PROXY_LIST") { |proxy_file| @proxy_file = proxy_file }
    end.parse!
  end

Kullanıcının vereceği proxy dosyasını için veri girdisi parametresi ("-p")

HTTP isteklerinin yapılması için kullanılacak olan fonksiyon

Ruby:
  def http_proxy(url, proxy_addr, proxy_port)
    begin
      uri = URI.parse(url)

      proxy_http = Net::HTTP.Proxy(proxy_addr, proxy_port).new(uri.host, uri.port)
      proxy_http.use_ssl = (uri.scheme == 'https')

      proxy_http.open_timeout = 3
      proxy_http.read_timeout = 3

      request = Net::HTTP::Get.new(url)
      response = proxy_http.request(request)

      puts("URL: #{url}\nResponse Code: #{response.code}\nProxy IP: #{proxy_addr}\nProxy Port: #{proxy_port}".green)
      puts("-" * 30)

      File.open(@output, 'a+') { |file| file.puts("#{proxy_addr}:#{proxy_port}") }
    rescue Exception
      puts("#{proxy_addr}:#{proxy_port} --> Error".red)
      return
    end
  end

Bu fonksiyon, bir HTTP GET isteği gönderir:
  • uri değişkeni ile URL ayrıştırılır (parse edilir).
  • Proxy ayarları ile bir HTTP istemcisi (clienti) oluşturulur.
  • İstek zaman aşımı süreleri ve ssl kullanımı ayarlanır.
  • İstek gönderilir ve yanıt alınır.
  • Yanıt başarıyla alındığında, bu bilgi ekrana yazdırılır ve başarılı proxy bilgileri bir dosyaya kaydedilir.
  • Hata durumunda, hata mesajı ekrana yazdırılır.

Ruby:
def proxy_processer(proxy_addr, proxy_port)
    @threads << Thread.new { http_proxy(@url, proxy_addr, proxy_port) }
end

Proxy listesini teker teker okuyarak IP adresi, port numarası ayırma ve değişkene atama işleminin yapılacağı fonksiyon

Ruby:
def read_proxies
    proxies = File.readlines(@proxy_file)

    proxies.each do |proxy|
      proxy_ip, proxy_port = proxy.split(':')
      @proxy_data[proxy_ip.strip] = proxy_port.to_i
    end
  end

Eş zamanlı çalışma yapılacağı bu fonksiyon tanımlanır.

Fonksiyon kendisine gelen bölünmüş halde olan proxy listesini teker teker işleyerek HTTP isteğinin yapılacağı fonksiyonu çalıştıran yeni bir işlem parçacığı (thread) oluşturur.

Fonksiyonları başlatacak olan ana metot


Ruby:
  def main
    optparser
    read_proxies

    @proxy_data.each do |proxy_addr, proxy_port|
      proxy_processer(proxy_addr, proxy_port)
    end

    @threads.each(&:join)
  end
end

Programın çalışması için daha önceden tanımlanan gerekli fonksiyonları başlatır.

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

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

  def yellow
    "\e[33m#{self}\e[0m"
  end

  def blue
    "\e[34m#{self}\e[0m"
  end

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

auto_proxy = Proxy_Auto.new
auto_proxy.main

Çıktı renklendirmesi ve sınıf çağrımı

Tüm Kod:

Ruby:
require 'net/http'
require 'optparse'
require 'uri'

class Proxy_Auto
  def initialize
    @proxy_data = Hash.new
    @threads = Array.new
    @url_file = nil
    @proxy_file = nil
    @url = 'http://example.com'
    @output = 'proxy_success.txt'
  end

  def optparser
    OptionParser.new do |parser|
      parser.on("-p", "--proxy-list PROXY_LIST") { |proxy_file| @proxy_file = proxy_file }
    end.parse!
  end

  def http_proxy(url, proxy_addr, proxy_port)
    begin
      uri = URI.parse(url)

      proxy_http = Net::HTTP.Proxy(proxy_addr, proxy_port).new(uri.host, uri.port)
      proxy_http.use_ssl = (uri.scheme == 'https')

      proxy_http.open_timeout = 3
      proxy_http.read_timeout = 3

      request = Net::HTTP::Get.new(url)
      response = proxy_http.request(request)

      puts("URL: #{url}\nResponse Code: #{response.code}\nProxy IP: #{proxy_addr}\nProxy Port: #{proxy_port}".green)
      puts("-" * 30)

      File.open(@output, 'a+') { |file| file.puts("#{proxy_addr}:#{proxy_port}") }
    rescue Exception
      puts("#{proxy_addr}:#{proxy_port} --> Error".red)
      return
    end
  end

  def proxy_processer(proxy_addr, proxy_port)
    @threads << Thread.new { http_proxy(@url, proxy_addr, proxy_port) }
  end

  def read_proxies
    proxies = File.readlines(@proxy_file)

    proxies.each do |proxy|
      proxy_ip, proxy_port = proxy.split(':')
      @proxy_data[proxy_ip.strip] = proxy_port.to_i
    end
  end

  def main
    optparser
    read_proxies

    @proxy_data.each do |proxy_addr, proxy_port|
      proxy_processer(proxy_addr, proxy_port)
    end

    @threads.each(&:join)
  end
end

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

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

  def yellow
    "\e[33m#{self}\e[0m"
  end

  def blue
    "\e[34m#{self}\e[0m"
  end

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

auto_proxy = Proxy_Auto.new
auto_proxy.main

pDHFoUY.png


Programın Kullanımı

Bash:
ruby program_ismi.rb -p proxy_dosyasi.txt

j3iu0c9.gif



pDHFoUY.png


Programı geliştirme sürecinde bana yardımcı olan @ExeOweR, @Hea7, @teux ve @Suppressor hocalarıma teşekkür ediyorum.

Okuyan herkese teşekkürler, kendinize göre editleyip kullanabilirsiniz.


Ellerinize sağlık hocam çok güzel olmuş :)
 

oqk18ir.png


p0qbke2.png


Merhabalar ben AR-GE Ekibi'nden Bunjo, bu konuda proxy destekli gelişmiş bir dork scannerin nasıl kodlanacağını anlatacağım.

Bildiğiniz üzere bizim forumumuz da dahil internette birçok dork tarayıcı projesi/programı var. Bu dork tarayıcların neredeyse hepsi sayfa atlama, proxy desteği veya çıkan robot doğrulamaları analiz ve bypass etme gibi özellikleri içinde barındırmıyor. Bu yazıda elimden geldiğince programı ve genel mantığı detaylı şekilde açıklamaya çalışacağım. Açıklamaları önceden kod okuyabilme becerisine sahip olan kişiler anlayacaktır. Faydası olması dileğiyle keyifli okumalar...



Dork Scanner (Tarayıcı) Nasıl Çalışır?

Ofansif taraflı çalışmalar yapıyorsanız Google'da veya başka bir arama motorunda dork aradığınz mutlaka olmuştur. Aslında dork scanner olarak adlandırdığımız yazılımlar da tamamen bundan ibaret. El ile dork aramanın hem yorucu hem de uzun sürmesi nedenleriyle bu yazılımlara ihtiyaç duyulmuştur. Google üzerinden örnek vereyim, Google'da arama yapmak için kullanacağınız forum "f" harfiyle adlandırılmıştır. İçerisinde bulunan arama yapılacak içerik "textarea" tagları içinde "q" saklanır. Bunları otomatize gerçekleştiren bir script yazalım

Kütüphane:

Bash:
gem install mechanize

Kod:

Ruby:
require 'mechanize'

# Kullanım için Mechanize nesnesi oluştur
agent = Mechanize.new

# Arama yapılacak veri
query = 'inurl: product.php?id= site: .uk'

# Google ana sayfasına git (GET isteği at)
page = agent.get('https://www.google.com')

search_form = page.form_with(name: 'f')
search_form.field_with(name: 'q').value = query
search_results_page = agent.submit(search_form)

# url getir
search_results_page.css('a').each do |a|
  href = a['href']

  if href && href.start_with?("/url?q=")
    url = href.split('&').first.gsub('/url?q=', '')
    puts URI.decode_www_form_component(url)
  end
end

Bu Kodda öncelikle "f" isminde olan form bulunur daha sonra bu formda "q" ismi tanımlanmış olan alan örnek bir dork ile doldurulur. (field) Son olarak form bu şekilde gönderilir ve dönüt incelenir.

Gelen dönütte "a" etiketi ile kullanılan veri bulunur ve içerisinden "href" yani yönlendirme yapılacak olan alan alınır.

Bu alım işlemi sonucunda bir dönütün gelip gelmediği ve gelen bu dönütün "/url?q=" ile başlayıp başlamadığı kontrol edilir.

Eğer başlıyorsa bu veri "&" işaretinin bulunduğu yerden ikiyi bölünüp ilk kısım alınır.

"gsub" metotu ile "/url?q=" kısmı boş string (metin) verisi ile değiştirilir en sona temiz URL verisi kalmış olur.

Örnek:

Kod:
/url?q=https://www.huey.co.uk/shop/cart.php%3Faction%3Dadd%26id%3D65&sa=U&ved=2ahUKEwj05--ss96GAxXuwzgGHe4cCfIQFnoECAcQAg&usg=AOvVaw1RR_OXa1wJ_earOHRc_uGO

https://www.huey.co.uk/shop/cart.php%3Faction%3Dadd%26id%3D65

https://www.huey.co.uk/shop/cart.php?action=add&id=65

Aşamalar şekildeki gibi devam eder.

Bir ayrı senaryoda forum doldurma işlemine girilmeden direkt URL kısmına q parametresine veri yazılır.



p0qbke2.png


Proxy Destekli Dork Tarayıcı

Github: Bağlantı adresi için tıklayınız.

Ruby:
require 'net/http'
require 'thread'
require 'nokogiri'
require 'optparse'
require 'uri'

Gerekli Kütüphaneler ve Sınıflar

Programın çalışması için gerekli kütüphaneler ve açıklamaları. Kütüphaneleri indirmeniz gerektiğinde "gem install kutuphane_adi" komutunu kullanabilirsiniz.

require 'net/http'
  • HTTP isteklerini gerçekleştirmek için kullanılır.
require 'thread'
  • İş parçacıkları (threads) oluşturmak için kullanılır.
require 'nokogiri'
  • HTML ve XML verilerini işlemek (parse etmek) için kullanılır.
require 'optparse'
  • Komut satırı argümanlarını işlemek için kullanılır.
require 'uri'
  • URI (Uniform Resource Identifier) işlemek için kullanılır.
Ruby:
class DorkDevSecOps
  def initialize
    @params = {
      proxy_list: nil,
      dork_list: nil,
      output: 'output.txt',
      timeout: 3,

      proxy_data: Hash.new,
      dork_data: Array.new,
      threads: Array.new
    }
  end

DorkDevSecOps Sınıfı

Bu sınıf, programın ana işlevselliğini sağlar.

initialize Metodu

  • @params adında bir hash oluşturur. Bu hash, proxy ve dork listeleri, çıktı dosyası, zaman aşımı süresi gibi parametreleri tutar.

Ruby:
def http_requester(dorks = "", proxies = "")
    @params[:dork_data].each do |dork_query|
      success = false
      @params[:proxy_data].each do |proxy_ip, proxy_port|
        break if success

        begin
          uri = URI.parse("https://google.com/?q=#{URI.encode_www_form_component(dork_query)}")

          proxy = Net::HTTP.Proxy(proxy_ip, proxy_port).new(uri.host, uri.port)
          proxy.use_ssl = false

          proxy.open_timeout = @params[:timeout]
          proxy.read_timeout = @params[:timeout]

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

          response = proxy.request(request)

          if response
            if captcha_check(response.body)
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> Captcha Bulundu".red)
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> #{response.code} - #{dork_query}".red)
            elsif (200 <= response.code.to_i && response.code.to_i < 300)
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> #{response.code} - #{dork_query}".green)
              check_and_save(response.body)
              success = true
              break
            else
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> #{response.code} - #{dork_query}".red)
            end
          end
        rescue Exception => error
          STDERR.puts("Hata: #{proxy_ip}:#{proxy_port} #{error}".red)
        rescue Net::OpenTimeout, Net::ReadTimeout
          STDERR.puts("Zaman Aşımı: #{proxy_ip}:#{proxy_port}".red)
        end
      end
    end
  end

http_requester Metodu

  • dorks ve proxies adında iki parametre alır. Ancak bu parametreler kullanılmaz.
  • Dorkları ve proxy'leri kullanarak Google'da arama yapar. Her dork sorgusu için proxy listesi üzerinde döngü yapar ve başarılı bir yanıt alana kadar devam eder.
  • Alınan yanıt başarısız olduğu zaman listede diğer sırada bulunan proxy adresini kullanmaya başlar.
  • İstekler sırasında oluşabilecek hataları ve zaman aşımı durumlarını yakalar ve hata mesajlarını yazdırır.
  • Yanıtın captcha içerip içermediğini kontrol eder ve sonuçları ekrana yazdırır.

Ruby:
def check_and_save(output)
    doc = Nokogiri::HTML(output)

      File.open(@params[:output], "a") do |fileman|
        doc.css('a').each do |a|
          href = a['href']

          if href && href.start_with?('/url?q=')
            decoded_url = href.split('&').first.gsub('/url?q=', '')
            url = URI.decode_www_form_component(decoded_url)
            fileman.puts(url)
          end
        end
      end
  end

check_and_save Metodu

Yazının ilk başında bahsettiğim kısmı programımın bu yerine kullandım.
  • Google arama sonuçlarını işler ve output.txt dosyasına sonuçları kaydeder.
  • HTML içindeki bağlantıları bulur ve /url?q= ile başlayan bağlantıları çözümler.

Ruby:
def print_help
    help_text = <<-'HELP_TEXT'
Parametreler:
  -p, --proxy-list PROXY_LIST: Proxy listesi tanımlamak için kullanılır.
  -d, --dork-list DORK_LIST: Dork listesi tanımlamak için kullanılır.
  -t, --timeout TIMEOUT: İsteklere zaman aşımı vermek için kullanılır.

  HELP_TEXT

    STDOUT.puts(help_text.blue)
  end

Programın kullanımı hakkında yardım metnini ekrana yazdırır.

Ruby:
def option_parser
    begin
      OptionParser.new do |opts|
        opts.on("-p", "--proxy-list PROXY_LIST", String, "Proxy listesi tanımlamak için kullanılır.") do |proxy_list|
          if File.exist?(proxy_list)
            @params[:proxy_list] = proxy_list
          else
            STDERR.puts("Hata: Belirtilen proxy listesi #{proxy_list} bulunamadı!".red)
            exit(1)
          end
        end

        opts.on("-c", "--cores", "İşlem parçacıklarını tanımlamak için kullanılır.") do |cores|
          @params[:cores] = cores
        end

        opts.on("-d", "--dork-list DORK_LIST", String, "Dork listesi tanımlamak için kullanılır.") do |dork_list|
          if File.exist?(dork_list)
            @params[:dork_list] = dork_list
          else
            STDERR.puts("Hata: Belirtilen dork listesi #{dork_list} bulunamadı!".red)
            exit(1)
          end
        end

        opts.on("-a", "--add", String, "Dorkların sonuna metin eklemesi yapmak için kullanılır.") do |add_to_dork|
          @params[:add_to_dork] = add_to_dork
        end

        opts.on("-h", "--help", "Yardım menüsünü ekrana yazdırır.") do
          print_help
          exit(0)
        end
      end.parse!
    rescue Exception => error
      STDERR.puts("Hata: #{error.class}:#{error.message}".red)
      exit!
    end
  end

option_parser Metodu

  • Komut satırı argümanlarını işler ve @params hash'ini günceller.
  • Proxy ve dork listelerinin var olup olmadığını kontrol eder. Hata durumunda programdan çıkar.
  • zaman aşımı süresi için veri alımı yaapr.
Ruby:
def proxy_loader
    proxy_data_lines = File.readlines(@params[:proxy_list]).uniq

    proxy_data_lines.each do |line|
      begin
        proxy_ip, proxy_port = line.split(":")
        @params[:proxy_data][proxy_ip.strip] = proxy_port.to_i if proxy_ip and proxy_port
      rescue Exception => error
        STDERR.puts("Hata: #{error.class}:#{error.message}".red)
        next
      end
    end
  end

  def dork_loader
    dork_data_lines = File.readlines(@params[:dork_list]).uniq

    dork_data_lines.each do |dork|
      @params[:dork_data].append(dork)
    end
  end

proxy_loader Metodu

  • Proxy listesini dosyadan okur ve @params[: proxy_data] hash'ine ekler.

dork_loader Metodu

  • Dork listesini dosyadan okur ve @params[:dork_data] array'ine ekler.

Ruby:
def display_params
    params_text = <<-"PARAMS"
Atanmış Parametreler:
  Dork Listesi: #{@params[:dork_list]}
  Proxy Listesi: #{@params[:proxy_list]}
    PARAMS

    puts params_text.blue
  end

display_params Metodu

  • Ayarlanmış parametreleri ekrana yazdırır.
Ruby:
def main
    begin
      option_parser

      if @params[:dork_list].nil? || @params[:proxy_list].nil?
        print_help
        exit!
      end

      proxy_loader
      dork_loader
      display_params

      http_requester
    rescue Interrupt

    end
  end
end

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

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

  def yellow
    "\e[33m#{self}\e[0m"
  end

  def blue
    "\e[34m#{self}\e[0m"
  end

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

dorkscan = DorkDevSecOps.new
dorkscan.main

main Metodu

  • Programın ana akışını yönetir.
  • Komut satırı argümanlarını işler, proxy ve dork listelerini yükler ve HTTP isteklerini başlatır.

String Sınıfı Üzerinde Değişiklikler

  • String sınıfına red, green, yellow, blue, ve magenta metodları eklenmiştir. Bu metodlar, metinleri renkli olarak konsola yazdırmak için kullanılır.

Programın Çalıştırılması

  • DorkDevSecOps sınıfından bir nesne oluşturulur ve main metodu çağrılır.

p0qbke2.png


Örnek Proxy Listesi

Kod:
70.166.167.38:57728
223.135.156.183:8080
186.215.87.194:30024
104.165.127.155:3128
18.133.16.21:1080
107.179.51.165:5808
38.242.240.167:49923
103.129.3.246:83
222.88.167.22:9002
103.247.23.69:8080
67.43.228.254:7169
59.11.82.216:3128
170.245.132.15:999
202.91.41.17:8888
200.108.190.38:999
103.109.212.85:1080
50.217.226.42:80
72.10.160.174:21013
211.128.96.206:80
45.4.144.232:4153
47.251.43.115:33333
158.177.111.149:3128
45.159.150.23:3128
190.140.31.195:9900
104.165.169.125:3128
104.233.13.226:6221
162.223.94.164:80
77.233.5.68:55443
190.94.213.8:999
189.250.135.40:80
102.209.18.26:8080
43.129.249.83:8888
192.241.243.131:9150
104.239.78.74:6019
103.127.63.57:5678
103.237.78.102:4996
213.136.84.202:16046
91.221.177.40:80
193.106.109.195:80
45.181.122.201:999
185.105.90.88:4444
183.88.223.211:8080
50.223.239.183:80
104.165.127.186:3128
185.161.186.83:54321
154.0.154.230:8080
23.228.83.39:5735
36.64.27.123:5678
50.168.72.117:80
72.10.160.90:9361
216.173.120.127:6419
188.125.167.67:8080
161.123.101.58:6684
195.138.90.226:3128
5.180.19.163:1080
223.207.102.16:4000
164.92.86.113:62027
176.192.65.34:5020
20.44.190.150:3129
49.13.48.21:80
59.144.184.73:80
121.182.138.71:80
133.18.234.13:80
172.183.241.1:8080
192.111.137.35:4145
13.36.87.105:3128
43.134.32.184:3128
104.223.157.148:6387
72.10.160.91:21477
104.238.111.107:15073
50.168.72.122:80
13.56.192.187:3128
202.6.224.52:1080
20.206.106.192:8123
8.242.178.5:999
190.94.212.76:999
154.113.121.60:80
50.231.110.26:80
182.253.39.206:8080


Tüm Kaynak Kodu:

Ruby:
require 'net/http'
require 'thread'
require 'nokogiri'
require 'optparse'
require 'uri'

# Not:
# Program şuan için sadece "HTTP" türünde Proxy desteklemektedir.
# Proxy listesi IP:PORT şeklinde olmalıdır.

class DorkDevSecOps
  def initialize
    @params = {
      proxy_list: nil,
      dork_list: nil,
      output: 'output.txt',
      timeout: 3,

      proxy_data: Hash.new,
      dork_data: Array.new,
      threads: Array.new
    }
  end

  def http_requester(dorks = "", proxies = "")
    @params[:dork_data].each do |dork_query|
      success = false
      @params[:proxy_data].each do |proxy_ip, proxy_port|
        break if success

        begin
          uri = URI.parse("https://google.com/?q=#{URI.encode_www_form_component(dork_query)}")

          proxy = Net::HTTP.Proxy(proxy_ip, proxy_port).new(uri.host, uri.port)
          proxy.use_ssl = false

          proxy.open_timeout = @params[:timeout]
          proxy.read_timeout = @params[:timeout]

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

          response = proxy.request(request)

          if response
            if captcha_check(response.body)
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> Captcha Bulundu".red)
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> #{response.code} - #{dork_query}".red)
            elsif (200 <= response.code.to_i && response.code.to_i < 300)
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> #{response.code} - #{dork_query}".green)
              check_and_save(response.body)
              success = true
              break
            else
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> #{response.code} - #{dork_query}".red)
            end
          end
        rescue Exception => error
          STDERR.puts("Hata: #{proxy_ip}:#{proxy_port} #{error}".red)
        rescue Net::OpenTimeout, Net::ReadTimeout
          STDERR.puts("Zaman Aşımı: #{proxy_ip}:#{proxy_port}".red)
        end
      end
    end
  end

  def check_and_save(output)
    doc = Nokogiri::HTML(output)

      File.open(@params[:output], "a") do |fileman|
        doc.css('a').each do |a|
          href = a['href']

          if href && href.start_with?('/url?q=')
            decoded_url = href.split('&').first.gsub('/url?q=', '')
            url = URI.decode_www_form_component(decoded_url)
            fileman.puts(url)
          end
        end
      end
  end

  def captcha_check(body)
    return body.include?("recaptcha")
  end

  def print_help
    help_text = <<-'HELP_TEXT'
Parametreler:
  -p, --proxy-list PROXY_LIST: Proxy listesi tanımlamak için kullanılır.
  -d, --dork-list DORK_LIST: Dork listesi tanımlamak için kullanılır.
  -t, --timeout TIMEOUT: İsteklere zaman aşımı vermek için kullanılır.

  HELP_TEXT

    STDOUT.puts(help_text.blue)
  end

  def option_parser
    begin
      OptionParser.new do |opts|
        opts.on("-p", "--proxy-list PROXY_LIST", String, "Proxy listesi tanımlamak için kullanılır.") do |proxy_list|
          if File.exist?(proxy_list)
            @params[:proxy_list] = proxy_list
          else
            STDERR.puts("Hata: Belirtilen proxy listesi #{proxy_list} bulunamadı!".red)
            exit(1)
          end
        end

        opts.on("-c", "--cores", "İşlem parçacıklarını tanımlamak için kullanılır.") do |cores|
          @params[:cores] = cores
        end

        opts.on("-d", "--dork-list DORK_LIST", String, "Dork listesi tanımlamak için kullanılır.") do |dork_list|
          if File.exist?(dork_list)
            @params[:dork_list] = dork_list
          else
            STDERR.puts("Hata: Belirtilen dork listesi #{dork_list} bulunamadı!".red)
            exit(1)
          end
        end

        opts.on("-a", "--add", String, "Dorkların sonuna metin eklemesi yapmak için kullanılır.") do |add_to_dork|
          @params[:add_to_dork] = add_to_dork
        end

        opts.on("-h", "--help", "Yardım menüsünü ekrana yazdırır.") do
          print_help
          exit(0)
        end
      end.parse!
    rescue Exception => error
      STDERR.puts("Hata: #{error.class}:#{error.message}".red)
      exit!
    end
  end

  def proxy_loader
    proxy_data_lines = File.readlines(@params[:proxy_list]).uniq

    proxy_data_lines.each do |line|
      begin
        proxy_ip, proxy_port = line.split(":")
        @params[:proxy_data][proxy_ip.strip] = proxy_port.to_i if proxy_ip and proxy_port
      rescue Exception => error
        STDERR.puts("Hata: #{error.class}:#{error.message}".red)
        next
      end
    end
  end

  def dork_loader
    dork_data_lines = File.readlines(@params[:dork_list]).uniq

    dork_data_lines.each do |dork|
      @params[:dork_data].append(dork)
    end
  end

  def display_params
    params_text = <<-"PARAMS"
Atanmış Parametreler:
  Dork Listesi: #{@params[:dork_list]}
  Proxy Listesi: #{@params[:proxy_list]}
    PARAMS

    puts params_text.blue
  end

  def main
    begin
      option_parser

      if @params[:dork_list].nil? || @params[:proxy_list].nil?
        print_help
        exit!
      end

      proxy_loader
      dork_loader
      display_params

      http_requester
    rescue Interrupt

    end
  end
end

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

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

  def yellow
    "\e[33m#{self}\e[0m"
  end

  def blue
    "\e[34m#{self}\e[0m"
  end

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

dorkscan = DorkDevSecOps.new
dorkscan.main


p0qbke2.png


Program Hakkında

Bu program daha geliştirilme aşamasındadır. Bu yüzden gözünün üstünde kaşı var diye yapılan eleştiriler dışındaki her eleştiri büyük önem taşır.

Program hakkında olan görüşlerinizi, önerilerinizi ve eleştirilerinizi bekliyorum.

Yazılıma Eklenecek Desteklerden Bazıları:

- Sayfa atlama desteği (en fazla 10-15 sayfa olacak şekilde)
- Daha sıkı robot doğrulama algılama
- Paralel programlamayla çoklu thread desteği
- HTTPS proxy desteği

Google otomatize yazılımlardan yüksek seviyede korunma yöntemleri almış durumdadır. İnternette public olarak bulduğunuz proxy verilerinin çok büyük bir kısmı Google tarafından algılanır. Program çalışıp istek sonucu 200 kodu dönse bile, "dork" arama sonucunuza ait bir sonuç bulunamadı şeklinde dönütler alırsınız bu dönütlerin program ile hiçbir alakası olmamakla beraber sadece kullandığınız proxy verisine bağlıdır.

Kütüphane Kurulumları:

Bash:
gem install nokogiri

p0qbke2.png


Programın Kullanımı

Bash:
ruby program.rb -p proxy_dosyasi.txt -d dork_dosyasi.txt

95vcp8y.jpg


Gelen çıktının bir kısmı:

b1nvshl.png

pDHFoUY.png


Yukarıda bahsettiğim projede kullanabileceğiniz bir proxy checker yazılımı.

Github: GitHub - bayruby/HTTP-Proxy-Checker


pDHFoUY.png


Kaynak Kodu ve Açıklaması

Kütüphane aktarımları:

Ruby:
require 'net/http'
require 'optparse'
require 'uri'
  • net/http: HTTP istekleri göndermek için kullanılır.
  • optparse: Komut satırı argümanlarını işlemek için kullanılır.
  • uri: URL'leri ayrıştırmak ve işlemek için kullanılır.
Program sınıfının oluşturulması ve değişkenlerin tanımlanması

Ruby:
class Proxy_Auto
  def initialize
    @proxy_data = Hash.new
    @threads = Array.new
    @url_file = nil
    @proxy_file = nil
    @url = 'http://example.com'
    @output = 'proxy_success.txt'
  end
  • @proxy_data: Proxy verilerini saklamak için kullanılan bir hash (yani sözlük gibi düşünün).
  • @threads: Thread'leri saklamak için kullanılan bir dizi (liste).
  • @url: HTTP isteği gönderilecek varsayılan URL.
  • @output: Başarılı proxy bağlantılarının kaydedileceği dosya.
Terminalden veri aktarımı yapılması için parser fonksiyonu

Ruby:
def optparser
    OptionParser.new do |parser|
      parser.on("-p", "--proxy-list PROXY_LIST") { |proxy_file| @proxy_file = proxy_file }
    end.parse!
  end

Kullanıcının vereceği proxy dosyasını için veri girdisi parametresi ("-p")

HTTP isteklerinin yapılması için kullanılacak olan fonksiyon

Ruby:
  def http_proxy(url, proxy_addr, proxy_port)
    begin
      uri = URI.parse(url)

      proxy_http = Net::HTTP.Proxy(proxy_addr, proxy_port).new(uri.host, uri.port)
      proxy_http.use_ssl = (uri.scheme == 'https')

      proxy_http.open_timeout = 3
      proxy_http.read_timeout = 3

      request = Net::HTTP::Get.new(url)
      response = proxy_http.request(request)

      puts("URL: #{url}\nResponse Code: #{response.code}\nProxy IP: #{proxy_addr}\nProxy Port: #{proxy_port}".green)
      puts("-" * 30)

      File.open(@output, 'a+') { |file| file.puts("#{proxy_addr}:#{proxy_port}") }
    rescue Exception
      puts("#{proxy_addr}:#{proxy_port} --> Error".red)
      return
    end
  end

Bu fonksiyon, bir HTTP GET isteği gönderir:
  • uri değişkeni ile URL ayrıştırılır (parse edilir).
  • Proxy ayarları ile bir HTTP istemcisi (clienti) oluşturulur.
  • İstek zaman aşımı süreleri ve ssl kullanımı ayarlanır.
  • İstek gönderilir ve yanıt alınır.
  • Yanıt başarıyla alındığında, bu bilgi ekrana yazdırılır ve başarılı proxy bilgileri bir dosyaya kaydedilir.
  • Hata durumunda, hata mesajı ekrana yazdırılır.

Ruby:
def proxy_processer(proxy_addr, proxy_port)
    @threads << Thread.new { http_proxy(@url, proxy_addr, proxy_port) }
end

Proxy listesini teker teker okuyarak IP adresi, port numarası ayırma ve değişkene atama işleminin yapılacağı fonksiyon

Ruby:
def read_proxies
    proxies = File.readlines(@proxy_file)

    proxies.each do |proxy|
      proxy_ip, proxy_port = proxy.split(':')
      @proxy_data[proxy_ip.strip] = proxy_port.to_i
    end
  end

Eş zamanlı çalışma yapılacağı bu fonksiyon tanımlanır.

Fonksiyon kendisine gelen bölünmüş halde olan proxy listesini teker teker işleyerek HTTP isteğinin yapılacağı fonksiyonu çalıştıran yeni bir işlem parçacığı (thread) oluşturur.

Fonksiyonları başlatacak olan ana metot


Ruby:
  def main
    optparser
    read_proxies

    @proxy_data.each do |proxy_addr, proxy_port|
      proxy_processer(proxy_addr, proxy_port)
    end

    @threads.each(&:join)
  end
end

Programın çalışması için daha önceden tanımlanan gerekli fonksiyonları başlatır.

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

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

  def yellow
    "\e[33m#{self}\e[0m"
  end

  def blue
    "\e[34m#{self}\e[0m"
  end

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

auto_proxy = Proxy_Auto.new
auto_proxy.main

Çıktı renklendirmesi ve sınıf çağrımı

Tüm Kod:

Ruby:
require 'net/http'
require 'optparse'
require 'uri'

class Proxy_Auto
  def initialize
    @proxy_data = Hash.new
    @threads = Array.new
    @url_file = nil
    @proxy_file = nil
    @url = 'http://example.com'
    @output = 'proxy_success.txt'
  end

  def optparser
    OptionParser.new do |parser|
      parser.on("-p", "--proxy-list PROXY_LIST") { |proxy_file| @proxy_file = proxy_file }
    end.parse!
  end

  def http_proxy(url, proxy_addr, proxy_port)
    begin
      uri = URI.parse(url)

      proxy_http = Net::HTTP.Proxy(proxy_addr, proxy_port).new(uri.host, uri.port)
      proxy_http.use_ssl = (uri.scheme == 'https')

      proxy_http.open_timeout = 3
      proxy_http.read_timeout = 3

      request = Net::HTTP::Get.new(url)
      response = proxy_http.request(request)

      puts("URL: #{url}\nResponse Code: #{response.code}\nProxy IP: #{proxy_addr}\nProxy Port: #{proxy_port}".green)
      puts("-" * 30)

      File.open(@output, 'a+') { |file| file.puts("#{proxy_addr}:#{proxy_port}") }
    rescue Exception
      puts("#{proxy_addr}:#{proxy_port} --> Error".red)
      return
    end
  end

  def proxy_processer(proxy_addr, proxy_port)
    @threads << Thread.new { http_proxy(@url, proxy_addr, proxy_port) }
  end

  def read_proxies
    proxies = File.readlines(@proxy_file)

    proxies.each do |proxy|
      proxy_ip, proxy_port = proxy.split(':')
      @proxy_data[proxy_ip.strip] = proxy_port.to_i
    end
  end

  def main
    optparser
    read_proxies

    @proxy_data.each do |proxy_addr, proxy_port|
      proxy_processer(proxy_addr, proxy_port)
    end

    @threads.each(&:join)
  end
end

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

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

  def yellow
    "\e[33m#{self}\e[0m"
  end

  def blue
    "\e[34m#{self}\e[0m"
  end

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

auto_proxy = Proxy_Auto.new
auto_proxy.main

pDHFoUY.png


Programın Kullanımı

Bash:
ruby program_ismi.rb -p proxy_dosyasi.txt

j3iu0c9.gif



pDHFoUY.png


Programı geliştirme sürecinde bana yardımcı olan @ExeOweR, @Hea7, @teux ve @Suppressor hocalarıma teşekkür ediyorum.

Okuyan herkese teşekkürler, kendinize göre editleyip kullanabilirsiniz.


Eline sağlık çok detaylı olmuş
 

SiberAslan

Üye
24 May 2024
170
86
Ötüken.

oqk18ir.png


p0qbke2.png


Merhabalar ben AR-GE Ekibi'nden Bunjo, bu konuda proxy destekli gelişmiş bir dork scannerin nasıl kodlanacağını anlatacağım.

Bildiğiniz üzere bizim forumumuz da dahil internette birçok dork tarayıcı projesi/programı var. Bu dork tarayıcların neredeyse hepsi sayfa atlama, proxy desteği veya çıkan robot doğrulamaları analiz ve bypass etme gibi özellikleri içinde barındırmıyor. Bu yazıda elimden geldiğince programı ve genel mantığı detaylı şekilde açıklamaya çalışacağım. Açıklamaları önceden kod okuyabilme becerisine sahip olan kişiler anlayacaktır. Faydası olması dileğiyle keyifli okumalar...



Dork Scanner (Tarayıcı) Nasıl Çalışır?

Ofansif taraflı çalışmalar yapıyorsanız Google'da veya başka bir arama motorunda dork aradığınz mutlaka olmuştur. Aslında dork scanner olarak adlandırdığımız yazılımlar da tamamen bundan ibaret. El ile dork aramanın hem yorucu hem de uzun sürmesi nedenleriyle bu yazılımlara ihtiyaç duyulmuştur. Google üzerinden örnek vereyim, Google'da arama yapmak için kullanacağınız forum "f" harfiyle adlandırılmıştır. İçerisinde bulunan arama yapılacak içerik "textarea" tagları içinde "q" saklanır. Bunları otomatize gerçekleştiren bir script yazalım

Kütüphane:

Bash:
gem install mechanize

Kod:

Ruby:
require 'mechanize'

# Kullanım için Mechanize nesnesi oluştur
agent = Mechanize.new

# Arama yapılacak veri
query = 'inurl: product.php?id= site: .uk'

# Google ana sayfasına git (GET isteği at)
page = agent.get('https://www.google.com')

search_form = page.form_with(name: 'f')
search_form.field_with(name: 'q').value = query
search_results_page = agent.submit(search_form)

# url getir
search_results_page.css('a').each do |a|
  href = a['href']

  if href && href.start_with?("/url?q=")
    url = href.split('&').first.gsub('/url?q=', '')
    puts URI.decode_www_form_component(url)
  end
end

Bu Kodda öncelikle "f" isminde olan form bulunur daha sonra bu formda "q" ismi tanımlanmış olan alan örnek bir dork ile doldurulur. (field) Son olarak form bu şekilde gönderilir ve dönüt incelenir.

Gelen dönütte "a" etiketi ile kullanılan veri bulunur ve içerisinden "href" yani yönlendirme yapılacak olan alan alınır.

Bu alım işlemi sonucunda bir dönütün gelip gelmediği ve gelen bu dönütün "/url?q=" ile başlayıp başlamadığı kontrol edilir.

Eğer başlıyorsa bu veri "&" işaretinin bulunduğu yerden ikiyi bölünüp ilk kısım alınır.

"gsub" metotu ile "/url?q=" kısmı boş string (metin) verisi ile değiştirilir en sona temiz URL verisi kalmış olur.

Örnek:

Kod:
/url?q=https://www.huey.co.uk/shop/cart.php%3Faction%3Dadd%26id%3D65&sa=U&ved=2ahUKEwj05--ss96GAxXuwzgGHe4cCfIQFnoECAcQAg&usg=AOvVaw1RR_OXa1wJ_earOHRc_uGO

https://www.huey.co.uk/shop/cart.php%3Faction%3Dadd%26id%3D65

https://www.huey.co.uk/shop/cart.php?action=add&id=65

Aşamalar şekildeki gibi devam eder.

Bir ayrı senaryoda forum doldurma işlemine girilmeden direkt URL kısmına q parametresine veri yazılır.



p0qbke2.png


Proxy Destekli Dork Tarayıcı

Github: Bağlantı adresi için tıklayınız.

Ruby:
require 'net/http'
require 'thread'
require 'nokogiri'
require 'optparse'
require 'uri'

Gerekli Kütüphaneler ve Sınıflar

Programın çalışması için gerekli kütüphaneler ve açıklamaları. Kütüphaneleri indirmeniz gerektiğinde "gem install kutuphane_adi" komutunu kullanabilirsiniz.

require 'net/http'
  • HTTP isteklerini gerçekleştirmek için kullanılır.
require 'thread'
  • İş parçacıkları (threads) oluşturmak için kullanılır.
require 'nokogiri'
  • HTML ve XML verilerini işlemek (parse etmek) için kullanılır.
require 'optparse'
  • Komut satırı argümanlarını işlemek için kullanılır.
require 'uri'
  • URI (Uniform Resource Identifier) işlemek için kullanılır.
Ruby:
class DorkDevSecOps
  def initialize
    @params = {
      proxy_list: nil,
      dork_list: nil,
      output: 'output.txt',
      timeout: 3,

      proxy_data: Hash.new,
      dork_data: Array.new,
      threads: Array.new
    }
  end

DorkDevSecOps Sınıfı

Bu sınıf, programın ana işlevselliğini sağlar.

initialize Metodu

  • @params adında bir hash oluşturur. Bu hash, proxy ve dork listeleri, çıktı dosyası, zaman aşımı süresi gibi parametreleri tutar.

Ruby:
def http_requester(dorks = "", proxies = "")
    @params[:dork_data].each do |dork_query|
      success = false
      @params[:proxy_data].each do |proxy_ip, proxy_port|
        break if success

        begin
          uri = URI.parse("https://google.com/?q=#{URI.encode_www_form_component(dork_query)}")

          proxy = Net::HTTP.Proxy(proxy_ip, proxy_port).new(uri.host, uri.port)
          proxy.use_ssl = false

          proxy.open_timeout = @params[:timeout]
          proxy.read_timeout = @params[:timeout]

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

          response = proxy.request(request)

          if response
            if captcha_check(response.body)
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> Captcha Bulundu".red)
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> #{response.code} - #{dork_query}".red)
            elsif (200 <= response.code.to_i && response.code.to_i < 300)
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> #{response.code} - #{dork_query}".green)
              check_and_save(response.body)
              success = true
              break
            else
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> #{response.code} - #{dork_query}".red)
            end
          end
        rescue Exception => error
          STDERR.puts("Hata: #{proxy_ip}:#{proxy_port} #{error}".red)
        rescue Net::OpenTimeout, Net::ReadTimeout
          STDERR.puts("Zaman Aşımı: #{proxy_ip}:#{proxy_port}".red)
        end
      end
    end
  end

http_requester Metodu

  • dorks ve proxies adında iki parametre alır. Ancak bu parametreler kullanılmaz.
  • Dorkları ve proxy'leri kullanarak Google'da arama yapar. Her dork sorgusu için proxy listesi üzerinde döngü yapar ve başarılı bir yanıt alana kadar devam eder.
  • Alınan yanıt başarısız olduğu zaman listede diğer sırada bulunan proxy adresini kullanmaya başlar.
  • İstekler sırasında oluşabilecek hataları ve zaman aşımı durumlarını yakalar ve hata mesajlarını yazdırır.
  • Yanıtın captcha içerip içermediğini kontrol eder ve sonuçları ekrana yazdırır.

Ruby:
def check_and_save(output)
    doc = Nokogiri::HTML(output)

      File.open(@params[:output], "a") do |fileman|
        doc.css('a').each do |a|
          href = a['href']

          if href && href.start_with?('/url?q=')
            decoded_url = href.split('&').first.gsub('/url?q=', '')
            url = URI.decode_www_form_component(decoded_url)
            fileman.puts(url)
          end
        end
      end
  end

check_and_save Metodu

Yazının ilk başında bahsettiğim kısmı programımın bu yerine kullandım.
  • Google arama sonuçlarını işler ve output.txt dosyasına sonuçları kaydeder.
  • HTML içindeki bağlantıları bulur ve /url?q= ile başlayan bağlantıları çözümler.

Ruby:
def print_help
    help_text = <<-'HELP_TEXT'
Parametreler:
  -p, --proxy-list PROXY_LIST: Proxy listesi tanımlamak için kullanılır.
  -d, --dork-list DORK_LIST: Dork listesi tanımlamak için kullanılır.
  -t, --timeout TIMEOUT: İsteklere zaman aşımı vermek için kullanılır.

  HELP_TEXT

    STDOUT.puts(help_text.blue)
  end

Programın kullanımı hakkında yardım metnini ekrana yazdırır.

Ruby:
def option_parser
    begin
      OptionParser.new do |opts|
        opts.on("-p", "--proxy-list PROXY_LIST", String, "Proxy listesi tanımlamak için kullanılır.") do |proxy_list|
          if File.exist?(proxy_list)
            @params[:proxy_list] = proxy_list
          else
            STDERR.puts("Hata: Belirtilen proxy listesi #{proxy_list} bulunamadı!".red)
            exit(1)
          end
        end

        opts.on("-c", "--cores", "İşlem parçacıklarını tanımlamak için kullanılır.") do |cores|
          @params[:cores] = cores
        end

        opts.on("-d", "--dork-list DORK_LIST", String, "Dork listesi tanımlamak için kullanılır.") do |dork_list|
          if File.exist?(dork_list)
            @params[:dork_list] = dork_list
          else
            STDERR.puts("Hata: Belirtilen dork listesi #{dork_list} bulunamadı!".red)
            exit(1)
          end
        end

        opts.on("-a", "--add", String, "Dorkların sonuna metin eklemesi yapmak için kullanılır.") do |add_to_dork|
          @params[:add_to_dork] = add_to_dork
        end

        opts.on("-h", "--help", "Yardım menüsünü ekrana yazdırır.") do
          print_help
          exit(0)
        end
      end.parse!
    rescue Exception => error
      STDERR.puts("Hata: #{error.class}:#{error.message}".red)
      exit!
    end
  end

option_parser Metodu

  • Komut satırı argümanlarını işler ve @params hash'ini günceller.
  • Proxy ve dork listelerinin var olup olmadığını kontrol eder. Hata durumunda programdan çıkar.
  • zaman aşımı süresi için veri alımı yaapr.
Ruby:
def proxy_loader
    proxy_data_lines = File.readlines(@params[:proxy_list]).uniq

    proxy_data_lines.each do |line|
      begin
        proxy_ip, proxy_port = line.split(":")
        @params[:proxy_data][proxy_ip.strip] = proxy_port.to_i if proxy_ip and proxy_port
      rescue Exception => error
        STDERR.puts("Hata: #{error.class}:#{error.message}".red)
        next
      end
    end
  end

  def dork_loader
    dork_data_lines = File.readlines(@params[:dork_list]).uniq

    dork_data_lines.each do |dork|
      @params[:dork_data].append(dork)
    end
  end

proxy_loader Metodu

  • Proxy listesini dosyadan okur ve @params[: proxy_data] hash'ine ekler.

dork_loader Metodu

  • Dork listesini dosyadan okur ve @params[:dork_data] array'ine ekler.

Ruby:
def display_params
    params_text = <<-"PARAMS"
Atanmış Parametreler:
  Dork Listesi: #{@params[:dork_list]}
  Proxy Listesi: #{@params[:proxy_list]}
    PARAMS

    puts params_text.blue
  end

display_params Metodu

  • Ayarlanmış parametreleri ekrana yazdırır.
Ruby:
def main
    begin
      option_parser

      if @params[:dork_list].nil? || @params[:proxy_list].nil?
        print_help
        exit!
      end

      proxy_loader
      dork_loader
      display_params

      http_requester
    rescue Interrupt

    end
  end
end

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

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

  def yellow
    "\e[33m#{self}\e[0m"
  end

  def blue
    "\e[34m#{self}\e[0m"
  end

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

dorkscan = DorkDevSecOps.new
dorkscan.main

main Metodu

  • Programın ana akışını yönetir.
  • Komut satırı argümanlarını işler, proxy ve dork listelerini yükler ve HTTP isteklerini başlatır.

String Sınıfı Üzerinde Değişiklikler

  • String sınıfına red, green, yellow, blue, ve magenta metodları eklenmiştir. Bu metodlar, metinleri renkli olarak konsola yazdırmak için kullanılır.

Programın Çalıştırılması

  • DorkDevSecOps sınıfından bir nesne oluşturulur ve main metodu çağrılır.

p0qbke2.png


Örnek Proxy Listesi

Kod:
70.166.167.38:57728
223.135.156.183:8080
186.215.87.194:30024
104.165.127.155:3128
18.133.16.21:1080
107.179.51.165:5808
38.242.240.167:49923
103.129.3.246:83
222.88.167.22:9002
103.247.23.69:8080
67.43.228.254:7169
59.11.82.216:3128
170.245.132.15:999
202.91.41.17:8888
200.108.190.38:999
103.109.212.85:1080
50.217.226.42:80
72.10.160.174:21013
211.128.96.206:80
45.4.144.232:4153
47.251.43.115:33333
158.177.111.149:3128
45.159.150.23:3128
190.140.31.195:9900
104.165.169.125:3128
104.233.13.226:6221
162.223.94.164:80
77.233.5.68:55443
190.94.213.8:999
189.250.135.40:80
102.209.18.26:8080
43.129.249.83:8888
192.241.243.131:9150
104.239.78.74:6019
103.127.63.57:5678
103.237.78.102:4996
213.136.84.202:16046
91.221.177.40:80
193.106.109.195:80
45.181.122.201:999
185.105.90.88:4444
183.88.223.211:8080
50.223.239.183:80
104.165.127.186:3128
185.161.186.83:54321
154.0.154.230:8080
23.228.83.39:5735
36.64.27.123:5678
50.168.72.117:80
72.10.160.90:9361
216.173.120.127:6419
188.125.167.67:8080
161.123.101.58:6684
195.138.90.226:3128
5.180.19.163:1080
223.207.102.16:4000
164.92.86.113:62027
176.192.65.34:5020
20.44.190.150:3129
49.13.48.21:80
59.144.184.73:80
121.182.138.71:80
133.18.234.13:80
172.183.241.1:8080
192.111.137.35:4145
13.36.87.105:3128
43.134.32.184:3128
104.223.157.148:6387
72.10.160.91:21477
104.238.111.107:15073
50.168.72.122:80
13.56.192.187:3128
202.6.224.52:1080
20.206.106.192:8123
8.242.178.5:999
190.94.212.76:999
154.113.121.60:80
50.231.110.26:80
182.253.39.206:8080


Tüm Kaynak Kodu:

Ruby:
require 'net/http'
require 'thread'
require 'nokogiri'
require 'optparse'
require 'uri'

# Not:
# Program şuan için sadece "HTTP" türünde Proxy desteklemektedir.
# Proxy listesi IP:PORT şeklinde olmalıdır.

class DorkDevSecOps
  def initialize
    @params = {
      proxy_list: nil,
      dork_list: nil,
      output: 'output.txt',
      timeout: 3,

      proxy_data: Hash.new,
      dork_data: Array.new,
      threads: Array.new
    }
  end

  def http_requester(dorks = "", proxies = "")
    @params[:dork_data].each do |dork_query|
      success = false
      @params[:proxy_data].each do |proxy_ip, proxy_port|
        break if success

        begin
          uri = URI.parse("https://google.com/?q=#{URI.encode_www_form_component(dork_query)}")

          proxy = Net::HTTP.Proxy(proxy_ip, proxy_port).new(uri.host, uri.port)
          proxy.use_ssl = false

          proxy.open_timeout = @params[:timeout]
          proxy.read_timeout = @params[:timeout]

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

          response = proxy.request(request)

          if response
            if captcha_check(response.body)
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> Captcha Bulundu".red)
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> #{response.code} - #{dork_query}".red)
            elsif (200 <= response.code.to_i && response.code.to_i < 300)
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> #{response.code} - #{dork_query}".green)
              check_and_save(response.body)
              success = true
              break
            else
              STDOUT.puts("#{proxy_ip}:#{proxy_port} -> #{response.code} - #{dork_query}".red)
            end
          end
        rescue Exception => error
          STDERR.puts("Hata: #{proxy_ip}:#{proxy_port} #{error}".red)
        rescue Net::OpenTimeout, Net::ReadTimeout
          STDERR.puts("Zaman Aşımı: #{proxy_ip}:#{proxy_port}".red)
        end
      end
    end
  end

  def check_and_save(output)
    doc = Nokogiri::HTML(output)

      File.open(@params[:output], "a") do |fileman|
        doc.css('a').each do |a|
          href = a['href']

          if href && href.start_with?('/url?q=')
            decoded_url = href.split('&').first.gsub('/url?q=', '')
            url = URI.decode_www_form_component(decoded_url)
            fileman.puts(url)
          end
        end
      end
  end

  def captcha_check(body)
    return body.include?("recaptcha")
  end

  def print_help
    help_text = <<-'HELP_TEXT'
Parametreler:
  -p, --proxy-list PROXY_LIST: Proxy listesi tanımlamak için kullanılır.
  -d, --dork-list DORK_LIST: Dork listesi tanımlamak için kullanılır.
  -t, --timeout TIMEOUT: İsteklere zaman aşımı vermek için kullanılır.

  HELP_TEXT

    STDOUT.puts(help_text.blue)
  end

  def option_parser
    begin
      OptionParser.new do |opts|
        opts.on("-p", "--proxy-list PROXY_LIST", String, "Proxy listesi tanımlamak için kullanılır.") do |proxy_list|
          if File.exist?(proxy_list)
            @params[:proxy_list] = proxy_list
          else
            STDERR.puts("Hata: Belirtilen proxy listesi #{proxy_list} bulunamadı!".red)
            exit(1)
          end
        end

        opts.on("-c", "--cores", "İşlem parçacıklarını tanımlamak için kullanılır.") do |cores|
          @params[:cores] = cores
        end

        opts.on("-d", "--dork-list DORK_LIST", String, "Dork listesi tanımlamak için kullanılır.") do |dork_list|
          if File.exist?(dork_list)
            @params[:dork_list] = dork_list
          else
            STDERR.puts("Hata: Belirtilen dork listesi #{dork_list} bulunamadı!".red)
            exit(1)
          end
        end

        opts.on("-a", "--add", String, "Dorkların sonuna metin eklemesi yapmak için kullanılır.") do |add_to_dork|
          @params[:add_to_dork] = add_to_dork
        end

        opts.on("-h", "--help", "Yardım menüsünü ekrana yazdırır.") do
          print_help
          exit(0)
        end
      end.parse!
    rescue Exception => error
      STDERR.puts("Hata: #{error.class}:#{error.message}".red)
      exit!
    end
  end

  def proxy_loader
    proxy_data_lines = File.readlines(@params[:proxy_list]).uniq

    proxy_data_lines.each do |line|
      begin
        proxy_ip, proxy_port = line.split(":")
        @params[:proxy_data][proxy_ip.strip] = proxy_port.to_i if proxy_ip and proxy_port
      rescue Exception => error
        STDERR.puts("Hata: #{error.class}:#{error.message}".red)
        next
      end
    end
  end

  def dork_loader
    dork_data_lines = File.readlines(@params[:dork_list]).uniq

    dork_data_lines.each do |dork|
      @params[:dork_data].append(dork)
    end
  end

  def display_params
    params_text = <<-"PARAMS"
Atanmış Parametreler:
  Dork Listesi: #{@params[:dork_list]}
  Proxy Listesi: #{@params[:proxy_list]}
    PARAMS

    puts params_text.blue
  end

  def main
    begin
      option_parser

      if @params[:dork_list].nil? || @params[:proxy_list].nil?
        print_help
        exit!
      end

      proxy_loader
      dork_loader
      display_params

      http_requester
    rescue Interrupt

    end
  end
end

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

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

  def yellow
    "\e[33m#{self}\e[0m"
  end

  def blue
    "\e[34m#{self}\e[0m"
  end

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

dorkscan = DorkDevSecOps.new
dorkscan.main


p0qbke2.png


Program Hakkında

Bu program daha geliştirilme aşamasındadır. Bu yüzden gözünün üstünde kaşı var diye yapılan eleştiriler dışındaki her eleştiri büyük önem taşır.

Program hakkında olan görüşlerinizi, önerilerinizi ve eleştirilerinizi bekliyorum.

Yazılıma Eklenecek Desteklerden Bazıları:

- Sayfa atlama desteği (en fazla 10-15 sayfa olacak şekilde)
- Daha sıkı robot doğrulama algılama
- Paralel programlamayla çoklu thread desteği
- HTTPS proxy desteği

Google otomatize yazılımlardan yüksek seviyede korunma yöntemleri almış durumdadır. İnternette public olarak bulduğunuz proxy verilerinin çok büyük bir kısmı Google tarafından algılanır. Program çalışıp istek sonucu 200 kodu dönse bile, "dork" arama sonucunuza ait bir sonuç bulunamadı şeklinde dönütler alırsınız bu dönütlerin program ile hiçbir alakası olmamakla beraber sadece kullandığınız proxy verisine bağlıdır.

Kütüphane Kurulumları:

Bash:
gem install nokogiri

p0qbke2.png


Programın Kullanımı

Bash:
ruby program.rb -p proxy_dosyasi.txt -d dork_dosyasi.txt

95vcp8y.jpg


Gelen çıktının bir kısmı:

b1nvshl.png

pDHFoUY.png


Yukarıda bahsettiğim projede kullanabileceğiniz bir proxy checker yazılımı.

Github: GitHub - bayruby/HTTP-Proxy-Checker


pDHFoUY.png


Kaynak Kodu ve Açıklaması

Kütüphane aktarımları:

Ruby:
require 'net/http'
require 'optparse'
require 'uri'
  • net/http: HTTP istekleri göndermek için kullanılır.
  • optparse: Komut satırı argümanlarını işlemek için kullanılır.
  • uri: URL'leri ayrıştırmak ve işlemek için kullanılır.
Program sınıfının oluşturulması ve değişkenlerin tanımlanması

Ruby:
class Proxy_Auto
  def initialize
    @proxy_data = Hash.new
    @threads = Array.new
    @url_file = nil
    @proxy_file = nil
    @url = 'http://example.com'
    @output = 'proxy_success.txt'
  end
  • @proxy_data: Proxy verilerini saklamak için kullanılan bir hash (yani sözlük gibi düşünün).
  • @threads: Thread'leri saklamak için kullanılan bir dizi (liste).
  • @url: HTTP isteği gönderilecek varsayılan URL.
  • @output: Başarılı proxy bağlantılarının kaydedileceği dosya.
Terminalden veri aktarımı yapılması için parser fonksiyonu

Ruby:
def optparser
    OptionParser.new do |parser|
      parser.on("-p", "--proxy-list PROXY_LIST") { |proxy_file| @proxy_file = proxy_file }
    end.parse!
  end

Kullanıcının vereceği proxy dosyasını için veri girdisi parametresi ("-p")

HTTP isteklerinin yapılması için kullanılacak olan fonksiyon

Ruby:
  def http_proxy(url, proxy_addr, proxy_port)
    begin
      uri = URI.parse(url)

      proxy_http = Net::HTTP.Proxy(proxy_addr, proxy_port).new(uri.host, uri.port)
      proxy_http.use_ssl = (uri.scheme == 'https')

      proxy_http.open_timeout = 3
      proxy_http.read_timeout = 3

      request = Net::HTTP::Get.new(url)
      response = proxy_http.request(request)

      puts("URL: #{url}\nResponse Code: #{response.code}\nProxy IP: #{proxy_addr}\nProxy Port: #{proxy_port}".green)
      puts("-" * 30)

      File.open(@output, 'a+') { |file| file.puts("#{proxy_addr}:#{proxy_port}") }
    rescue Exception
      puts("#{proxy_addr}:#{proxy_port} --> Error".red)
      return
    end
  end

Bu fonksiyon, bir HTTP GET isteği gönderir:
  • uri değişkeni ile URL ayrıştırılır (parse edilir).
  • Proxy ayarları ile bir HTTP istemcisi (clienti) oluşturulur.
  • İstek zaman aşımı süreleri ve ssl kullanımı ayarlanır.
  • İstek gönderilir ve yanıt alınır.
  • Yanıt başarıyla alındığında, bu bilgi ekrana yazdırılır ve başarılı proxy bilgileri bir dosyaya kaydedilir.
  • Hata durumunda, hata mesajı ekrana yazdırılır.

Ruby:
def proxy_processer(proxy_addr, proxy_port)
    @threads << Thread.new { http_proxy(@url, proxy_addr, proxy_port) }
end

Proxy listesini teker teker okuyarak IP adresi, port numarası ayırma ve değişkene atama işleminin yapılacağı fonksiyon

Ruby:
def read_proxies
    proxies = File.readlines(@proxy_file)

    proxies.each do |proxy|
      proxy_ip, proxy_port = proxy.split(':')
      @proxy_data[proxy_ip.strip] = proxy_port.to_i
    end
  end

Eş zamanlı çalışma yapılacağı bu fonksiyon tanımlanır.

Fonksiyon kendisine gelen bölünmüş halde olan proxy listesini teker teker işleyerek HTTP isteğinin yapılacağı fonksiyonu çalıştıran yeni bir işlem parçacığı (thread) oluşturur.

Fonksiyonları başlatacak olan ana metot


Ruby:
  def main
    optparser
    read_proxies

    @proxy_data.each do |proxy_addr, proxy_port|
      proxy_processer(proxy_addr, proxy_port)
    end

    @threads.each(&:join)
  end
end

Programın çalışması için daha önceden tanımlanan gerekli fonksiyonları başlatır.

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

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

  def yellow
    "\e[33m#{self}\e[0m"
  end

  def blue
    "\e[34m#{self}\e[0m"
  end

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

auto_proxy = Proxy_Auto.new
auto_proxy.main

Çıktı renklendirmesi ve sınıf çağrımı

Tüm Kod:

Ruby:
require 'net/http'
require 'optparse'
require 'uri'

class Proxy_Auto
  def initialize
    @proxy_data = Hash.new
    @threads = Array.new
    @url_file = nil
    @proxy_file = nil
    @url = 'http://example.com'
    @output = 'proxy_success.txt'
  end

  def optparser
    OptionParser.new do |parser|
      parser.on("-p", "--proxy-list PROXY_LIST") { |proxy_file| @proxy_file = proxy_file }
    end.parse!
  end

  def http_proxy(url, proxy_addr, proxy_port)
    begin
      uri = URI.parse(url)

      proxy_http = Net::HTTP.Proxy(proxy_addr, proxy_port).new(uri.host, uri.port)
      proxy_http.use_ssl = (uri.scheme == 'https')

      proxy_http.open_timeout = 3
      proxy_http.read_timeout = 3

      request = Net::HTTP::Get.new(url)
      response = proxy_http.request(request)

      puts("URL: #{url}\nResponse Code: #{response.code}\nProxy IP: #{proxy_addr}\nProxy Port: #{proxy_port}".green)
      puts("-" * 30)

      File.open(@output, 'a+') { |file| file.puts("#{proxy_addr}:#{proxy_port}") }
    rescue Exception
      puts("#{proxy_addr}:#{proxy_port} --> Error".red)
      return
    end
  end

  def proxy_processer(proxy_addr, proxy_port)
    @threads << Thread.new { http_proxy(@url, proxy_addr, proxy_port) }
  end

  def read_proxies
    proxies = File.readlines(@proxy_file)

    proxies.each do |proxy|
      proxy_ip, proxy_port = proxy.split(':')
      @proxy_data[proxy_ip.strip] = proxy_port.to_i
    end
  end

  def main
    optparser
    read_proxies

    @proxy_data.each do |proxy_addr, proxy_port|
      proxy_processer(proxy_addr, proxy_port)
    end

    @threads.each(&:join)
  end
end

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

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

  def yellow
    "\e[33m#{self}\e[0m"
  end

  def blue
    "\e[34m#{self}\e[0m"
  end

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

auto_proxy = Proxy_Auto.new
auto_proxy.main

pDHFoUY.png


Programın Kullanımı

Bash:
ruby program_ismi.rb -p proxy_dosyasi.txt

j3iu0c9.gif



pDHFoUY.png


Programı geliştirme sürecinde bana yardımcı olan @ExeOweR, @Hea7, @teux ve @Suppressor hocalarıma teşekkür ediyorum.

Okuyan herkese teşekkürler, kendinize göre editleyip kullanabilirsiniz.


Python programlama dilini kullansanız daha anlaşılır olurdu hocam.. ruby ile bunu yapmakta çok zor olmali oyuzden bu dev konu için teşekkürler, emeğinize sağlık ❤️
 

Bunjo

Ar-Ge Ekibi Asistanı
14 Ara 2020
1,620
1,956
Expert (J)Ruby Developing
Teşekkürler
Eline emeğine sağlık Aslanım benim
Teşekkürler abim
Emeğine sağlık
Teşekkürler
Eline sağlık çok detaylı olmuş
Sağol
Python programlama dilini kullansanız daha anlaşılır olurdu hocam.. ruby ile bunu yapmakta çok zor olmali oyuzden bu dev konu için teşekkürler, emeğinize sağlık ❤️
Teşekkür ederim dostum
 
Ü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.