From 3347221669035b9267e588a212908b9eda1c509e Mon Sep 17 00:00:00 2001 From: "Taisen.fr (Dev)" Date: Thu, 26 Dec 2024 10:15:42 +0100 Subject: [PATCH] Init --- .config/dotnet-tools.json | 12 + .gitattributes | 2 + .github/FUNDING.yml | 13 + .github/workflows/docker.yml | 32 ++ .github/workflows/dotnet.yml | 26 ++ .gitignore | 403 +++++++++++++++++++ Controller/Controller.cs | 222 +++++++++++ Dockerfile | 22 ++ Identity/VLAIdentity.cs | 136 +++++++ LICENSE | 674 ++++++++++++++++++++++++++++++++ LogoVLA.png | Bin 0 -> 96063 bytes MidlWare/MidlWare.cs | 79 ++++ Model/Model.cs | 234 +++++++++++ Program.cs | 109 ++++++ Properties/launchSettings.json | 37 ++ README.md | 167 ++++++++ SECURITY.md | 12 + TestCpu/TestCpu.cs | 43 ++ VLAusecase.drawio | 193 +++++++++ VulnerableWebApplication.csproj | 28 ++ VulnerableWebApplication.sln | 25 ++ appsettings.Development.json | 9 + appsettings.json | 13 + english | 2 + francais | 2 + 25 files changed, 2495 insertions(+) create mode 100644 .config/dotnet-tools.json create mode 100644 .gitattributes create mode 100644 .github/FUNDING.yml create mode 100644 .github/workflows/docker.yml create mode 100644 .github/workflows/dotnet.yml create mode 100644 .gitignore create mode 100644 Controller/Controller.cs create mode 100644 Dockerfile create mode 100644 Identity/VLAIdentity.cs create mode 100644 LICENSE create mode 100644 LogoVLA.png create mode 100644 MidlWare/MidlWare.cs create mode 100644 Model/Model.cs create mode 100644 Program.cs create mode 100644 Properties/launchSettings.json create mode 100644 README.md create mode 100644 SECURITY.md create mode 100644 TestCpu/TestCpu.cs create mode 100644 VLAusecase.drawio create mode 100644 VulnerableWebApplication.csproj create mode 100644 VulnerableWebApplication.sln create mode 100644 appsettings.Development.json create mode 100644 appsettings.json create mode 100644 english create mode 100644 francais diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json new file mode 100644 index 0000000..fccc806 --- /dev/null +++ b/.config/dotnet-tools.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "dotnet-ef": { + "version": "7.0.0", + "commands": [ + "dotnet-ef" + ] + } + } +} \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..146d19b --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,13 @@ +# These are supported funding model platforms + +github: Aif4thah +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] \ No newline at end of file diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..c9de497 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,32 @@ +name: Docker + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build Docker image + run: docker build -t vulnerablelightapp . + + - name: Run Docker container + run: docker run -d -p 3000:3000 vulnerablelightapp + + - name: Wait for the container to be ready + run: sleep 30 + + - name: Test the application + run: curl -k https://127.0.0.1:3000 diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml new file mode 100644 index 0000000..7fed306 --- /dev/null +++ b/.github/workflows/dotnet.yml @@ -0,0 +1,26 @@ +# This workflow will build a .NET project +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net + +name: .NET + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build: + + runs-on: windows-latest + + steps: + - uses: actions/checkout@v4 + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.0.x + - name: Restore dependencies + run: dotnet restore + - name: Build + run: dotnet build --no-restore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b6e61b3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,403 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.tlog +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio 6 auto-generated project file (contains which files were open etc.) +*.vbp + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) +*.dsw +*.dsp + +# Visual Studio 6 technical files +*.ncb +*.aps + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# Visual Studio History (VSHistory) files +.vshistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +# VS Code files for those working on multiple tools +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp + +# JetBrains Rider +*.sln.iml + +# Tests files +Logs.html +pocXSS.svg +NewEmployees.txt diff --git a/Controller/Controller.cs b/Controller/Controller.cs new file mode 100644 index 0000000..9487d08 --- /dev/null +++ b/Controller/Controller.cs @@ -0,0 +1,222 @@ +using System.Data; +using System.Text; +using System.Xml; +using Newtonsoft.Json; +using Microsoft.IdentityModel.Tokens; +using System.Net.Http.Headers; +using System.Diagnostics; +using System.Text.RegularExpressions; +using Microsoft.CodeAnalysis.CSharp.Scripting; +using System.Xml.Linq; +using System.Xml.Xsl; +using System.Runtime.InteropServices; +using System.Web; +using VulnerableWebApplication.VLAModel; + + +namespace VulnerableWebApplication.VLAController +{ + public class VLAController + { + private static string LogFile; + + public static void SetLogFile(string logFile) + { + LogFile = logFile; + } + + public static object VulnerableHelloWorld(string FileName = "english") + { + /* + Retourne le contenu du fichier correspondant à la langue choisie par l'utilisateur + */ + if (FileName.IsNullOrEmpty()) FileName = "francais"; + while (FileName.Contains("../") || FileName.Contains("..\\")) FileName = FileName.Replace("../", "").Replace("..\\", ""); + + return Results.Ok(File.ReadAllText(FileName)); + } + + public static object VulnerableDeserialize(string Json) + { + /* + Deserialise les données JSON passées en paramètre. + On enregistre les objets "employé" valides dans un fichier en lecture seule + */ + string NewId = "-1"; + string HaveToBeEmpty = string.Empty; + string ROFile = "NewEmployees.txt"; + + if (!File.Exists(ROFile)) File.Create(ROFile).Dispose(); + File.SetAttributes(ROFile, FileAttributes.ReadOnly); + + JsonConvert.DeserializeObject(Json, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }); + Employee NewEmployee = JsonConvert.DeserializeObject(Json); + + if (NewEmployee != null && !NewEmployee.Address.IsNullOrEmpty() && !NewEmployee.Id.IsNullOrEmpty()) + { + HaveToBeEmpty = VulnerableBuffer(NewEmployee.Address); + if (HaveToBeEmpty.IsNullOrEmpty()) + { + NewId = VulnerableCodeExecution(NewEmployee.Id); + File.SetAttributes(ROFile, FileAttributes.Normal); + using (StreamWriter sw = new StreamWriter(ROFile, true)) sw.Write(JsonConvert.SerializeObject(NewEmployee, Newtonsoft.Json.Formatting.Indented)); + File.SetAttributes(ROFile, FileAttributes.ReadOnly); + } + } + + return Results.Ok(Newtonsoft.Json.JsonConvert.SerializeObject(new List { File.GetAttributes(ROFile).ToString(), NewId, HaveToBeEmpty.IsNullOrEmpty() })); + } + + public static string VulnerableXmlParser(string Xml) + { + /* + Parse les contrats au format XML passées en paramètre et retourne son contenu + */ + try + { + var Xsl = XDocument.Parse(Xml); + var MyXslTrans = new XslCompiledTransform(enableDebug: true); + var Settings = new XsltSettings(); + MyXslTrans.Load(Xsl.CreateReader(), Settings, null); + var DocReader = XDocument.Parse("").CreateReader(); + + var Sb = new StringBuilder(); + var DocWriter = XmlWriter.Create(Sb, new XmlWriterSettings() { ConformanceLevel = ConformanceLevel.Fragment }); + MyXslTrans.Transform(DocReader, DocWriter); + + return Sb.ToString(); + } + catch (Exception ex) + { + XmlReaderSettings ReaderSettings = new XmlReaderSettings(); + ReaderSettings.DtdProcessing = DtdProcessing.Parse; + ReaderSettings.XmlResolver = new XmlUrlResolver(); + ReaderSettings.MaxCharactersFromEntities = 6000; + + using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(Xml))) + { + XmlReader Reader = XmlReader.Create(stream, ReaderSettings); + var XmlDocument = new XmlDocument(); + XmlDocument.XmlResolver = new XmlUrlResolver(); + XmlDocument.Load(Reader); + + return XmlDocument.InnerText; + } + } + } + + public static void VulnerableLogs(string Str, string LogFile) + { + /* + Enregistre la chaine de caractères passée en paramètre dans le fichier de journalisation + */ + if (Str.Contains("script", StringComparison.OrdinalIgnoreCase)) Str = HttpUtility.HtmlEncode(Str); + if (!File.Exists(LogFile)) File.WriteAllText(LogFile, Data.GetLogPage()); + string Page = File.ReadAllText(LogFile).Replace("", $"

{Str}


{Environment.NewLine}"); + File.WriteAllText(LogFile, Page); + } + + public static async Task VulnerableWebRequest(string Uri = "https://localhost:3000/") + { + /* + Effectue une requête web sur la boucle locale + */ + if (Uri.IsNullOrEmpty()) Uri = "https://localhost:3000/"; + if (Regex.IsMatch(Uri, @"^https://localhost")) + { + using HttpClient Client = new(); + Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/html")); + + var Resp = await exec(Client, Uri); + static async Task exec(HttpClient client, string uri) + { + var Result = client.GetAsync(uri); + Result.Result.EnsureSuccessStatusCode(); + return Result.Result.StatusCode.ToString(); + } + return Results.Ok(Resp); + } + else return Results.Unauthorized(); + } + + public static object VulnerableObjectReference(string Id) + { + /* + Retourne les informations liées à l'ID de l'utilisateur + Permets aux employés de consulter leurs données personnelles + */ + var Employee = Data.GetEmployees()?.Where(x => Id == x.Id)?.FirstOrDefault(); + + return Results.Ok(Newtonsoft.Json.JsonConvert.SerializeObject(Employee)); + } + + public static object VulnerableCmd(string UserStr) + { + /* + Effectue une requête DNS pour le FQDN passé en paramètre + */ + if (Regex.Match(UserStr, @"^(?:[a-zA-Z0-9_\-]+\.)+[a-zA-Z]{2,}(?:.{0,100})$").Success) + { + Process Cmd = new Process(); + Cmd.StartInfo.FileName = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "powershell" : "/bin/sh"; + Cmd.StartInfo.RedirectStandardInput = true; + Cmd.StartInfo.RedirectStandardOutput = true; + Cmd.StartInfo.CreateNoWindow = true; + Cmd.StartInfo.UseShellExecute = false; + Cmd.Start(); + Cmd.WaitForExit(200); + Cmd.StandardInput.WriteLine("nslookup " + UserStr); + Cmd.StandardInput.Flush(); + Cmd.StandardInput.Close(); + + return Results.Ok(Cmd.StandardOutput.ReadToEnd()); + } + else return Results.Unauthorized(); + } + + public static unsafe string VulnerableBuffer(string UserStr) + { + /* + Limite les chaines à 50 caractères + */ + int BuffSize = 50; + char* Ptr = stackalloc char[BuffSize], Str = Ptr + BuffSize; + foreach (var c in UserStr) *Ptr++ = c; + + return new string(Str); + } + + public static string VulnerableCodeExecution(string UserStr) + { + /* + Retourne un nouvel Id + */ + string Result = string.Empty; + if (UserStr.Length < 40 && !UserStr.Contains("class") && !UserStr.Contains("using")) + { + Result = CSharpScript.EvaluateAsync($"System.Math.Pow(2, {UserStr})")?.Result?.ToString(); + } + + return Result; + } + + public static async Task VulnerableHandleFileUpload(IFormFile UserFile, string Header) + { + /* + Permets l'upload de fichier de type SVG + */ + if (!Header.Contains("10.10.10.256")) return Results.Unauthorized(); + + if (UserFile.FileName.EndsWith(".svg")) + { + using var Stream = File.OpenWrite(UserFile.FileName); + await UserFile.CopyToAsync(Stream); + + return Results.Ok(UserFile.FileName); + } + else return Results.Unauthorized(); + } + + + } +} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..578b047 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,22 @@ +FROM debian:latest + +USER root + +RUN apt update && \ + apt upgrade -y && \ + apt install -y wget git + +RUN wget https://packages.microsoft.com/config/debian/12/packages-microsoft-prod.deb -O packages-microsoft-prod.deb && \ + dpkg -i packages-microsoft-prod.deb && \ + rm packages-microsoft-prod.deb + +RUN apt update && \ + apt install -y dotnet-sdk-8.0 dotnet-runtime-8.0 + +EXPOSE 3000 + +WORKDIR /app +RUN git clone https://github.com/Aif4thah/VulnerableLightApp.git +WORKDIR /app/VulnerableLightApp + +CMD ["dotnet", "run", "--url=https://0.0.0.0:3000"] \ No newline at end of file diff --git a/Identity/VLAIdentity.cs b/Identity/VLAIdentity.cs new file mode 100644 index 0000000..82fca78 --- /dev/null +++ b/Identity/VLAIdentity.cs @@ -0,0 +1,136 @@ +using System.Data; +using System.Security.Claims; +using System.Text; +using System.IdentityModel.Tokens.Jwt; +using Microsoft.IdentityModel.Tokens; +using System.Security.Cryptography; +using Newtonsoft.Json.Linq; + + +namespace VulnerableWebApplication.VLAIdentity +{ + public class VLAIdentity + { + private static string Secret; + + public static void SetSecret(string secret) + { + Secret = secret; + } + + private static string LogFile; + + public static void SetLogFile(string logFile) + { + LogFile = logFile; + } + + + public static async Task VulnerableQuery(string User, string Passwd) + { + /* + Authentifie les utilisateurs par login et mot de passe, et renvoie un token JWT si l'authentification a réussi + */ + SHA256 Sha256Hash = SHA256.Create(); + byte[] Bytes = Sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(Passwd)); + StringBuilder stringbuilder = new StringBuilder(); + for (int i = 0; i < Bytes.Length; i++) stringbuilder.Append(Bytes[i].ToString("x2")); + string Hash = stringbuilder.ToString(); + + VLAController.VLAController.VulnerableLogs("login attempt for:\n" + User + "\n" + Passwd + "\n", LogFile); + var DataSet = VLAModel.Data.GetDataSet(); + var Result = DataSet.Tables[0].Select("Passwd = '" + Hash + "' and User = '" + User + "'"); + var userRow = DataSet.Tables[0].AsEnumerable().FirstOrDefault(row => row.Field("User") == User && row.Field("IsAdmin") == 1); + + return Result.Length > 0 ? Results.Ok(VulnerableGenerateToken(User, userRow != null)) : Results.Unauthorized(); + } + + public static string VulnerableGenerateToken(string User, bool IsAdmin) + { + /* + Retourne un token JWT signé pour l'utilisateur passé en paramètre + */ + var TokenHandler = new JwtSecurityTokenHandler(); + var Key = Encoding.ASCII.GetBytes(Secret); + var TokenDescriptor = new SecurityTokenDescriptor + { + Subject = new ClaimsIdentity(new[] { new Claim("Id", User), new Claim("IsAdmin", IsAdmin.ToString()) }), + Expires = DateTime.UtcNow.AddDays(365), + SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(Key), SecurityAlgorithms.HmacSha256Signature) + }; + var Token = TokenHandler.CreateToken(TokenDescriptor); + + return TokenHandler.WriteToken(Token); + } + + public static bool VulnerableValidateToken(string Token, string Secret) + { + /* + Vérifie la validité du token JWT passé en paramètre + */ + var TokenHandler = new JwtSecurityTokenHandler(); + var Key = Encoding.ASCII.GetBytes(Secret); + bool Result = true; + Token = Token.Substring("Bearer ".Length); + + try + { + var JwtSecurityToken = TokenHandler.ReadJwtToken(Token); + if (JwtSecurityToken.Header.Alg == "HS256" && JwtSecurityToken.Header.Typ == "JWT") + { + TokenHandler.ValidateToken(Token, new TokenValidationParameters + { + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(Key), + ValidateIssuer = false, + ValidateAudience = false, + ValidateLifetime = true, + }, out SecurityToken validatedToken); + + var JwtToken = (JwtSecurityToken)validatedToken; + } + } + catch(Exception e) { Result = false; } + + return Result; + } + + public static bool VulnerableAdminValidateToken(string Token, string Secret) + { + /* + Vérifie la validité du token ADMIN passé en paramètre + */ + var TokenHandler = new JwtSecurityTokenHandler(); + var Key = Encoding.ASCII.GetBytes(Secret); + bool Result = false; + Token = Token.Substring("Bearer ".Length); + + try + { + var JwtSecurityToken = TokenHandler.ReadJwtToken(Token); + if (JwtSecurityToken.Header.Alg == "HS256" || JwtSecurityToken.Header.Typ == "JWT") + { + TokenHandler.ValidateToken(Token, new TokenValidationParameters + { + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(Key), + ValidateIssuer = false, + ValidateAudience = false, + ValidateLifetime = true, + }, out SecurityToken validatedToken); + + var JwtToken = (JwtSecurityToken)validatedToken; + var claims = JwtToken.Claims; + + var isAdminClaim = claims.FirstOrDefault(c => c.Type == "IsAdmin"); + if (isAdminClaim.Value.Contains("True")) Result = true; + } + } + catch (Exception e) { Result = false; } + + return Result; + } + + + } +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e62ec04 --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ +GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/LogoVLA.png b/LogoVLA.png new file mode 100644 index 0000000000000000000000000000000000000000..4e040ad443d44259f646d6ac53ee9bc59bf42e1d GIT binary patch literal 96063 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�Tcb=CKbeX?@c~E7wz^Qj&q? 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%0Ajw(Zr~d-7s&0OLK>dN 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 Yj!Ca$sfLpL`1W2jFx4+S@9^Y*0BJlJYXATM literal 0 HcmV?d00001 diff --git a/MidlWare/MidlWare.cs b/MidlWare/MidlWare.cs new file mode 100644 index 0000000..e0aad8a --- /dev/null +++ b/MidlWare/MidlWare.cs @@ -0,0 +1,79 @@ +using Microsoft.Extensions.Options; +using VulnerableWebApplication.VLAIdentity; +using VulnerableWebApplication; +using Microsoft.IdentityModel.Tokens; +using Microsoft.AspNetCore.Http; +using System.Text; + +namespace VulnerableWebApplication.MidlWare +{ + public class XRealIPMiddleware + { + /* + Ajoute le Header "X-Real-IP:" pour les logs de l'application + */ + private readonly RequestDelegate _next; + + public XRealIPMiddleware(RequestDelegate next) + { + _next = next; + } + + public async Task Invoke(HttpContext context) + { + context.Request.Headers["X-Real-IP"] = context.Connection.RemoteIpAddress.ToString(); + await _next(context); + } + + } + + + public class ValidateJwtMiddleware + { + private readonly RequestDelegate _next; + + public ValidateJwtMiddleware(RequestDelegate next) + { + _next = next; + } + + public async Task InvokeAsync(HttpContext context, IConfiguration configuration) + { + /* + Authentifie les utilisateurs + */ + + string authHeader = context.Request.Headers["Authorization"]; + string UnauthMsg = "Welcome to vulnerableLightApp. You are not authenticated. Source code is available at https://github.com/Aif4thah/VulnerableLightApp"; + + // URL Without Authentication + var path = context.Request.Path.Value; + if (path.Equals("/login", StringComparison.OrdinalIgnoreCase) || path.StartsWith("/swagger", StringComparison.OrdinalIgnoreCase)) + { + await _next(context); + return; + } + + // User Authentication + if (authHeader.IsNullOrEmpty() || !VLAIdentity.VLAIdentity.VulnerableValidateToken(authHeader, configuration["Secret"])) + { + context.Response.StatusCode = StatusCodes.Status401Unauthorized; + var bytes = Encoding.UTF8.GetBytes(UnauthMsg); + context.Response.Body.WriteAsync(bytes, 0, bytes.Length); + return; + } + + // Admin Authentication + if (path.StartsWith("/Patch", StringComparison.OrdinalIgnoreCase) && (authHeader.IsNullOrEmpty() || !VLAIdentity.VLAIdentity.VulnerableAdminValidateToken(authHeader, configuration["Secret"])) ) + { + context.Response.StatusCode = StatusCodes.Status401Unauthorized; + var bytes = Encoding.UTF8.GetBytes(UnauthMsg); + context.Response.Body.WriteAsync(bytes, 0, bytes.Length); + return; + } + + await _next(context); + } + } + +} diff --git a/Model/Model.cs b/Model/Model.cs new file mode 100644 index 0000000..3098253 --- /dev/null +++ b/Model/Model.cs @@ -0,0 +1,234 @@ +using GraphQL.Types; +using System.Data; +using GraphQL; + +namespace VulnerableWebApplication.VLAModel +{ + public class Employee + { + /* + Données des employés de l'entreprise + */ + public string Id { get; set; } + public string Name { get; set; } + public int Age { get; set; } + public string Address { get; set; } + } + + public class Creds + { + /* + Login et mots de passe des employés de l'entreprise + */ + public string User { get; set; } + public string Passwd { get; set; } + } + + public class Data + { + public static string GetLogPage() + { + /* + Structure des journaux d'événements + */ + return @"Application Logs

Application Logs

"; + } + + public static DataSet GetDataSet() + { + /* + Contenu de la BDD relationnelle (Utilisateurs) + */ + DataTable table = new DataTable(); + table.Columns.Add("User", typeof(string)); + table.Columns.Add("Passwd", typeof(string)); + table.Columns.Add("IsAdmin", typeof(int)); + table.Rows.Add("user", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 0); + table.Rows.Add("root", "ce5ca673d13b36118d54a7cf13aeb0ca012383bf771e713421b4d1fd841f539a", 1); + table.Rows.Add("admin", "8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a444", 1); + table.Rows.Add("Alice", "9b510b4af0d9b121f68d5a3400975047cbf38f963963b4c7510842d9d6310e7f", 0); + table.Rows.Add("Bob", "aed8f2deab14c36eeaa6d9c5c07ac6b586a74c18015dff9ac1cd0fc320f107b2", 0); + table.Rows.Add("Charlie", "99cdaf24cef97271760d72f0552ff18bb0c53e47d272cc1b3aa2c8b4e7d71b22", 0); + table.Rows.Add("Diana", "c27ab3e46131d5e15819aa5c919dca2c7d449a13a1293c9963e1a9d6181b51ac", 0); + table.Rows.Add("Edward", "3b179a52471e65a043a6c2b2dc1cb703165e2f94a8d4d3818b35eb278f730111",0); + table.Rows.Add("Fiona", "31b6273952ff5ef238f5ef544a212eb434813782a279de537bf8c02ccc07fa08", 0); + table.Rows.Add("George", "27730420c3b86d8eb76e568be4e9279f69d5b00d625c2f0742d260ed9cc2ec26", 0); + table.Rows.Add("Hannah", "dc8fd3ef67d7031e81a8e2d088aceb430972e4ad03bfccafd063b5729ca0a139", 0); + table.Rows.Add("Ian", "0964e66cc96ed16adb6364caf1d0c80f80b91c9bf49aed3ffc0e51bca4dc0567", 0); + table.Rows.Add("Julia", "69ccc763a7a99e5ef616c760e8dcc90a96491cfd15ec84d61fbbf222474a9b3d", 0); + var DataSet = new DataSet(); + DataSet.Tables.Add(table); + return DataSet; + } + + + public static List GetEmployees() + { + /* + Contenu de la BDD non relationnelle (Employés) + */ + List Employees = new List() { + new Employee() { Id = "1", Name = "John", Age = 16, Address = "4 rue jean moulin"}, + new Employee() { Id = "42", Name = "Steve", Age = 21, Address = "3 rue Victor Hugo" }, + new Employee() { Id = "1000", Name = "Bill", Age = 18, Address = "4 place du 18 juin" }, + new Employee() { Id = "1001", Name = "Alice", Age = 25, Address = "123 rue de la Paix" }, + new Employee() { Id = "1002", Name = "Bob", Age = 30, Address = "456 avenue des Champs-Élysées" }, + new Employee() { Id = "1003", Name = "Charlie", Age = 28, Address = "789 boulevard Saint-Germain" }, + new Employee() { Id = "1004", Name = "Diana", Age = 32, Address = "1010 rue du Faubourg Saint-Honoré" }, + new Employee() { Id = "1005", Name = "Edward", Age = 45, Address = "2020 avenue de la République" }, + new Employee() { Id = "1006", Name = "Fiona", Age = 29, Address = "3030 place de la Concorde" }, + new Employee() { Id = "1007", Name = "George", Age = 35, Address = "4040 rue de Rivoli" }, + new Employee() { Id = "1008", Name = "Hannah", Age = 27, Address = "5050 avenue Montaigne" }, + new Employee() { Id = "1009", Name = "Ian", Age = 40, Address = "6060 rue de la Boétie" }, + new Employee() { Id = "1010", Name = "Julia", Age = 22, Address = "7070 rue de Vaugirard" } + }; + return Employees; + } + } + + + /* + Classes et Query GraphQL (clients) + */ + public record Client(int Id, string Name, int Country, int Bank); + public record Country(int Id, string Name); + + public record Bank(int id, string RIB, string Name); + + public class ClientDetails + { + public int Id { get; set; } + public string Name { get; set; } + public string Country { get; set; } + public string Bank { get; set; } + + + } + + public class ClientDetailsType : ObjectGraphType + { + public ClientDetailsType() + { + Field(x => x.Id); + Field(x => x.Name); + Field(x => x.Country); + Field(x => x.Bank); + } + } + + public interface IClientService + { + public List GetClients(); + public List GetClient(int empId); + public List GetClientsByCountry(int Country); + public List GetClientsByBank(int BankId); + } + + public class ClientService : IClientService + { + public ClientService(){} + + private List Clients = new List + { + new Client(1, "NovaSynergy Solutions", 1,1), + new Client(2, "EcoVerde Innovations", 1,1), + new Client(3, "AstraTech Dynamics", 2,1), + new Client(4, "Luminara Creation", 2,1), + new Client(5, "ZenithWave Enterprises", 3,1), + }; + + private List Countrys = new List + { + new Country(1, "France"), + new Country(2, "Taïwan"), + new Country(3, "China"), + }; + + private List Banks = new List + { + new Bank(1, "FR1610096000703816856838K74" ,"BdF"), + + }; + + public List GetClients() + { + return Clients.Select(emp => new ClientDetails + { + Id = emp.Id, + Name = emp.Name, + Country = Countrys.First(d => d.Id == emp.Country).Name, + }).ToList(); + } + + public List GetClient(int empId) + { + return Clients.Where(emp => emp.Id == empId).Select(emp => new ClientDetails + { + Id = emp.Id, + Name = emp.Name, + Country = Countrys.First(d => d.Id == emp.Country).Name, + }).ToList(); + } + + + public List GetClientsByCountry(int CountryId) + { + return Clients.Where(emp => emp.Country == CountryId).Select(emp => new ClientDetails + { + Id = emp.Id, + Name = emp.Name, + Country = Countrys.First(d => d.Id == CountryId).Name, + }).ToList(); + } + + + public List GetClientsByBank(int BankId) + { + return Clients.Where(emp => emp.Bank == BankId).Select(emp => new ClientDetails + { + Id = emp.Id, + Name = emp.Name, + Bank = Banks.First(b => b.id == BankId).RIB, + }).ToList(); + } + } + + public class ClientQuery : ObjectGraphType + { + public ClientQuery(IClientService ClientService) + { + + Field>( + "Clients", + resolve: context => ClientService.GetClients() + ); + + Field>( + "Client", + arguments: new QueryArguments(new QueryArgument { Name = "Id" }), + resolve: context => ClientService.GetClient(context.GetArgument("Id")) + ); + + Field>( + "ClientsByCountry", + arguments: new QueryArguments(new QueryArgument { Name = "CountryId" }), + resolve: context => ClientService.GetClientsByCountry(context.GetArgument("CountryId")) + ); + + Field>( + "ClientsByBank", + arguments: new QueryArguments(new QueryArgument { Name = "Bank" }), + resolve: context => ClientService.GetClientsByBank(context.GetArgument("Bank")) + ); + } + } + + public class ClientDetailsSchema : Schema + { + public ClientDetailsSchema(IServiceProvider serviceProvider) : base(serviceProvider) + { + Query = serviceProvider.GetRequiredService(); + } + } +} + diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..b76d283 --- /dev/null +++ b/Program.cs @@ -0,0 +1,109 @@ +using System.Web; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Builder; +using VulnerableWebApplication.VLAController; +using Microsoft.AspNetCore.DataProtection; +using Microsoft.AspNetCore.HttpLogging; +using Microsoft.AspNetCore.HttpOverrides; +using VulnerableWebApplication.VLAModel; +using VulnerableWebApplication.VLAIdentity; +using VulnerableWebApplication.MidlWare; +using VulnerableWebApplication.TestCpu; +using Microsoft.AspNetCore.OpenApi; +using GraphQL.Types; +using GraphQL; +using System.Net.Sockets; + + +// Configuration du service + +var builder = WebApplication.CreateBuilder(args); + +builder.Configuration + .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) + .AddJsonFile($"appsettings{builder.Environment.EnvironmentName}.json", optional: true, reloadOnChange: true) + .AddEnvironmentVariables(); + +// Swagger +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); +builder.Services.AddAntiforgery(); + +// GraphQL + +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +builder.Services.AddGraphQL(b => b.AddAutoSchema().AddSystemTextJson()); + +builder.Services.AddHttpLogging(logging => +{ + logging.LoggingFields = HttpLoggingFields.All; + logging.RequestHeaders.Add("X-Real-IP"); + logging.RequestBodyLogLimit = 4096; + logging.ResponseBodyLogLimit = 4096; + logging.CombineLogs = true; +}); + +// Configuration de l'application : +var app = builder.Build(); +app.UseAntiforgery(); +app.UseMiddleware(); +app.UseMiddleware(); +app.UseHttpLogging(); +app.UseSwagger(); +app.UseSwaggerUI(); + + +// Variables : +VLAIdentity.SetSecret(app.Configuration["Secret"]); +VLAIdentity.SetLogFile(app.Configuration["LogFile"]); +VLAController.SetLogFile(app.Configuration["LogFile"]); + + +// Endpoints : + +app.MapGet("/", async (string? lang) => await Task.FromResult(VLAController.VulnerableHelloWorld(HttpUtility.UrlDecode(lang)))); + +app.MapPost("/Login", [ProducesResponseType(StatusCodes.Status200OK)] async (HttpRequest request, [FromBody] VulnerableWebApplication.VLAModel.Creds login) => await Task.FromResult(VLAIdentity.VulnerableQuery(login.User, login.Passwd)).Result).WithOpenApi(); + +app.MapGet("/Contract", async (string i) => await Task.FromResult(VLAController.VulnerableXmlParser(HttpUtility.UrlDecode(i)))).WithOpenApi(); + +app.MapGet("/LocalWebQuery", async (string? i) => await VLAController.VulnerableWebRequest(i)).WithOpenApi(); + +app.MapGet("/Employee", async (string i) => await Task.FromResult(VLAController.VulnerableObjectReference(i))).WithOpenApi(); + +app.MapGet("/NewEmployee", async (string i) => await Task.FromResult(VLAController.VulnerableDeserialize(HttpUtility.UrlDecode(i)))).WithOpenApi(); + +app.MapGet("/LocalDNSResolver", async (string i) => await Task.FromResult(VLAController.VulnerableCmd(HttpUtility.UrlDecode(i)))).WithOpenApi(); + +app.MapPatch("/Patch", async ([FromHeader(Name="X-Forwarded-For")] string h, [FromForm] IFormFile file) => await VLAController.VulnerableHandleFileUpload(file, h)).DisableAntiforgery().WithOpenApi(); + +app.UseGraphQL("/Client"); + +app.UseGraphQLPlayground("/GraphQLUI", new GraphQL.Server.Ui.Playground.PlaygroundOptions{GraphQLEndPoint="/Client",SubscriptionsEndPoint="/Client"}); + + +// Arguments : + +string url = args.FirstOrDefault(arg => arg.StartsWith("--url=")); +string test = args.FirstOrDefault(arg => arg.StartsWith("--test")); + +if(!string.IsNullOrEmpty(test)) +{ + Console.WriteLine("Start CPU Testing"); + TestCpu.TestAffinity(); +} + +if (string.IsNullOrEmpty(url)) +{ + app.Urls.Add("http://localhost:4000"); + app.Urls.Add("https://localhost:3000"); +} +else app.Urls.Add(url.Substring("--url=".Length)); + +// Lancement : + +app.Run(); diff --git a/Properties/launchSettings.json b/Properties/launchSettings.json new file mode 100644 index 0000000..02bb7fe --- /dev/null +++ b/Properties/launchSettings.json @@ -0,0 +1,37 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:28467", + "sslPort": 44318 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:5200", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:7175;http://localhost:5200", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..5f07666 --- /dev/null +++ b/README.md @@ -0,0 +1,167 @@ +

+ Dojo-101 +

+ +[![License: GNU GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) +![GitHub last commit](https://img.shields.io/github/last-commit/Aif4thah/VulnerableLightApp) +[![.NET](https://github.com/Aif4thah/VulnerableLightApp/actions/workflows/dotnet.yml/badge.svg)](https://github.com/Aif4thah/VulnerableLightApp/actions/workflows/dotnet.yml) +[![Docker](https://github.com/Aif4thah/VulnerableLightApp/actions/workflows/docker.yml/badge.svg)](https://github.com/Aif4thah/VulnerableLightApp/actions/workflows/docker.yml) + + + +> ⚠️ **Disclaimer** : This repository, together with its tools, is provided by Taisen-Solutions on an "as is" basis. Be aware that this application is highly vulnerable, including remote command and code execution. Use it at your own risk. Taisen-Solutions makes no representations or warranties of any kind, express or implied, as to the operation of the information, content, materials, tools, services and/or products included on the repository. Taisen-Solution disclaims, to the full extent permissible by applicable law, all warranties, express or implied, including but not limited to, implied warranties of merchantability and fitness for a particular purpose. + + +## 🎱 Components + +```mermaid +flowchart TD + A{**.NET REST API**} + A --> B[SQL DB] + A --> C[File System] + A --> D[Host services] + A --> F[GraphQL] + A --> G[App Services] + + B --> I(*Identities*) + C --> J(*Logs*) + C --> K(*Secrets*) + D --> L(*DNS*) + F --> M(*Sensitive Data*) + G --> O(*Serialized Data*) +``` + +## 🐞 Vulnerabilities + +| MITRE Reference | Description | Difficulty | +|----|---|----| +| CWE-22 | Path Traversal | Medium | +| CWE-78 | OS Command Injection | Easy | +| CWE-79 | Cross-site Scripting | Easy | +| CWE-89 | SQL Injection | Easy | +| CWE-94 | Code Injection| Hard | +| CWE-91 | XML Injection | Hard | +| CWE-98 | Remote File Inclusion | Hard | +| CWE-184 | Incomplete List of Disallowed Inputs | Medium | +| CWE-200 | Exposure of Sensitive Information to an Unauthorized Actor | Medium | +| CWE-213 | Exposure of Sensitive Information Due to Incompatible Policies | Easy | +| CWE-284 | Improper Access Control | Medium | +| CWE-287 | Improper Authentication | Medium | +| CWE-319 | Cleartext Transmission of Sensitive Information | Easy | +| CWE-326 | Inadequate Encryption Strength | Easy | +| CWE-434 | Unrestricted Upload of File with Dangerous Type | Hard | +| CWE-502 | Deserialization of Untrusted Data | Hard | +| CWE-521 | Weak Password Requirements | Easy | +| CWE-532 | Insertion of Sensitive Information into Log File | Easy | +| CWE 639 | Insecure Direct Object Reference | Medium | +| CWE-611 | XML External Entity Reference | Hard | +| CWE-787 | Out-of-bounds Write | Easy | +| CWE-798 | Use of Hard-coded Credentials | Easy | +| CWE-829 | Local File Inclusion | Easy | +| CWE-912 | Backdoor | Hard | +| CWE-918 | Server-Side Request Forgery | Medium | +| CWE-1270 | Generation of Incorrect Security Tokens | Medium | + + + +## 🔑 Hint & Write Up + +* Try reading [Dojo-101](https://github.com/Aif4thah/Dojo-101), this project contains all you need to hack this app. +* [Become a sponsor](https://github.com/sponsors/Aif4thah?frequency=recurring&sponsor=Aif4thah) and get access to the **full methodology** and **complete write-up**. + + +## ⬇️ Download + +```PowerShell +git clone https://github.com/Aif4thah/VulnerableLightApp.git +cd .\VulnerableLightApp\ +``` + + +## 🔧🔥 Build and Run + +You can use **Dotnet** or **Docker** + +### Dotnet + +Check `.csproj` file to get the current dotnet version and install [.NET SDK](https://dotnet.microsoft.com/en-us/download) + +```PowerShell +dotnet run [--url=] +``` + +Alternatively, you can use bin files : + +```PowerShell +dotnet build +.\bin\Debug\net8.0\VulnerableWebApplication.exe [--url=] +``` + +### Docker + +```bash +docker build -t vulnerablelightapp . +docker run -p 3000:3000 vulnerablelightapp +``` + +### first request + +Default : `127.0.0.1:3000` + +```sh +curl -k https://127.0.0.1:3000 +``` + + +## 🛠️ Debug + +### 401 Unauthorized + +Your first request may return a 401 code due to unsuccessful authentication. It's ok, Start Hacking ! + +### Dotnet Framework + +Verify you use the intended .NET Framework + +```cmd +where dotnet +dotnet --version +dotnet --list-sdks +``` + +### Dotnet on Linux + +Ubuntu / Debian exemple + +```bash +wget https://packages.microsoft.com/config/debian/12/packages-microsoft-prod.deb -O packages-microsoft-prod.deb +dpkg -i packages-microsoft-prod.deb +apt update && apt install -y dotnet-sdk-8.0 dotnet-runtime-8.0 +``` + + +### Certificates + +To trust the certificate + +```PowerShell +dotnet dev-certs https --trust +``` + + +### Dependancies + +dependancies have to be dowloaded from [standard sources](https://go.microsoft.com/fwlink/?linkid=848054) + +```sh +dotnet nuget add source "https://api.nuget.org/v3/index.json" --name "Microsoft" +``` + +### Misc + +* Be aware that VLA runs Linux and MacOS, but is only tested and supported on Windows. + +## 💜 Crédits + +* **Special thanks to all the hackers and students who pushed me to improve this work** +* Project maintened by [Michael Vacarella](https://github.com/Aif4thah) diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..f6ac199 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,12 @@ +# Security Policy + +Despite my efforts to add some mitigations, VLA is designed to contain critical vulnerabilities. +Run it at your own risk. + +## Tracability + +A simple way to keep some logs is to redirect console output into a file : + +```powershell +.\VulnerableWebApplication.exe >> C:\Users\\log.txt +``` \ No newline at end of file diff --git a/TestCpu/TestCpu.cs b/TestCpu/TestCpu.cs new file mode 100644 index 0000000..bb45959 --- /dev/null +++ b/TestCpu/TestCpu.cs @@ -0,0 +1,43 @@ +using GraphQL; +using System; +using System.Diagnostics; +using System.Linq; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics.Arm; +using System.Security.Cryptography; +using System.Text; +using System.Threading; + + +namespace VulnerableWebApplication.TestCpu +{ + /* + Test de perfs sur un seul proc (compatible Windows et Linux uniquement) + */ + public class TestCpu + { + public static void TestAffinity() + { + byte[] bytes = File.ReadAllBytes("appsettings.json"); + StringBuilder binary = new StringBuilder(); + var sha256 = SHA256.Create(); + foreach (byte b in bytes) binary.Append(Convert.ToString(b, 2).PadLeft(8, '0')); + string BinStr = binary.ToString(); + foreach (char bit in BinStr) + { + Thread.Sleep(1000); + if (bit == '0') Thread.Sleep(4000); + else + { + Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(bit - '0' + 1); + var stopWatch = new Stopwatch(); + stopWatch.Start(); + while (stopWatch.Elapsed.TotalSeconds < 4) sha256.ComputeHash(bytes); + stopWatch.Stop(); + } + } + Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)5; + } + + } +} diff --git a/VLAusecase.drawio b/VLAusecase.drawio new file mode 100644 index 0000000..d75f431 --- /dev/null +++ b/VLAusecase.drawio @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/VulnerableWebApplication.csproj b/VulnerableWebApplication.csproj new file mode 100644 index 0000000..d4f06d1 --- /dev/null +++ b/VulnerableWebApplication.csproj @@ -0,0 +1,28 @@ + + + + net8.0 + enable + enable + true + + + + + + + + + + + + + + Always + + + Always + + + + diff --git a/VulnerableWebApplication.sln b/VulnerableWebApplication.sln new file mode 100644 index 0000000..4460def --- /dev/null +++ b/VulnerableWebApplication.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.4.33110.190 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VulnerableWebApplication", "VulnerableWebApplication.csproj", "{B5FA6BE4-39EE-4DE3-BDF0-A09B1D23C8A6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B5FA6BE4-39EE-4DE3-BDF0-A09B1D23C8A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B5FA6BE4-39EE-4DE3-BDF0-A09B1D23C8A6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B5FA6BE4-39EE-4DE3-BDF0-A09B1D23C8A6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B5FA6BE4-39EE-4DE3-BDF0-A09B1D23C8A6}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {9D0B560F-67C2-4809-BB6D-CC25C4AA2CE8} + EndGlobalSection +EndGlobal diff --git a/appsettings.Development.json b/appsettings.Development.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/appsettings.json b/appsettings.json new file mode 100644 index 0000000..457f8fb --- /dev/null +++ b/appsettings.json @@ -0,0 +1,13 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Information", + "Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware": "Information" + } + }, + "AllowedHosts": "*", + "Secret": "7E91A318E0BCA7601717E409E86342D8AA7B54AE1BE4033577921B2B1D09F57B", + "LogFile": "Logs.html" + +} diff --git a/english b/english new file mode 100644 index 0000000..e4d7a6a --- /dev/null +++ b/english @@ -0,0 +1,2 @@ +Hi, Welcome on "Vulnerable-Light-Apps". +Reminder: Performing hack attempts without permission is illegal. \ No newline at end of file diff --git a/francais b/francais new file mode 100644 index 0000000..43aa179 --- /dev/null +++ b/francais @@ -0,0 +1,2 @@ +Bonjour, bienvenu sur "Vulnerable-Light-Apps". +Pour rappel, attaquer une cible sans autorisation, meme vulnérable, est illégal et peut entrainer des poursuite. \ No newline at end of file