├── Demo.gif ├── Subdominator.Tests ├── GlobalUsings.cs ├── ThreadValidationTests.cs ├── Subdominator.Tests.csproj ├── ValidatorTests.cs ├── FingerprintTests.cs └── CoverageTests.cs ├── Subdominator ├── Models │ ├── MatchedRecord.cs │ ├── MatchedLocation.cs │ ├── CnameResolutionResult.cs │ ├── Options.cs │ ├── TakeoverResult.cs │ └── Fingerprint.cs ├── Validators │ ├── IValidator.cs │ ├── AWSElasticBeanstalkValidator.cs │ └── MicrosoftAzureValidator.cs ├── Properties │ └── launchSettings.json ├── JsonSerializerContext.cs ├── Utils │ └── ValidatorUtils.cs ├── SingleOrArrayConverter.cs ├── OptionsBinder.cs ├── Subdominator.csproj ├── Scanner.cs ├── Program.cs ├── custom_fingerprints.json └── SubdomainHijack.cs ├── .github └── workflows │ ├── dotnet-core.yml │ └── release.yml ├── LICENSE.md ├── Subdominator.sln ├── .gitattributes ├── .gitignore └── ReadMe.md /Demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stratus-Security/Subdominator/HEAD/Demo.gif -------------------------------------------------------------------------------- /Subdominator.Tests/GlobalUsings.cs: -------------------------------------------------------------------------------- 1 | global using Microsoft.VisualStudio.TestTools.UnitTesting; -------------------------------------------------------------------------------- /Subdominator/Models/MatchedRecord.cs: -------------------------------------------------------------------------------- 1 | namespace Subdominator.Models; 2 | 3 | public enum MatchedRecord 4 | { 5 | None, 6 | CNAME, 7 | A, 8 | AAAA 9 | } -------------------------------------------------------------------------------- /Subdominator/Validators/IValidator.cs: -------------------------------------------------------------------------------- 1 | namespace Subdominator.Validators; 2 | 3 | public interface IValidator 4 | { 5 | Task Execute(IEnumerable cnames); 6 | } 7 | -------------------------------------------------------------------------------- /Subdominator/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Subdominator": { 4 | "commandName": "Project", 5 | "commandLineArgs": "-l subs.txt" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /Subdominator/Models/MatchedLocation.cs: -------------------------------------------------------------------------------- 1 | namespace Subdominator.Models; 2 | 3 | public enum MatchedLocation 4 | { 5 | None, 6 | HttpStatus, 7 | HttpBody, 8 | NXDomain, 9 | DomainAvailable 10 | } 11 | -------------------------------------------------------------------------------- /Subdominator/JsonSerializerContext.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace Subdominator; 4 | 5 | [JsonSerializable(typeof(List))] 6 | public partial class JsonContext : JsonSerializerContext 7 | { 8 | } -------------------------------------------------------------------------------- /Subdominator.Tests/ThreadValidationTests.cs: -------------------------------------------------------------------------------- 1 | using Subdominator; 2 | 3 | namespace Subdominator.Tests; 4 | 5 | [TestClass] 6 | public class ThreadValidationTests 7 | { 8 | [TestMethod] 9 | public void InvalidThreadValuesDefaultTo50() 10 | { 11 | Assert.AreEqual(50, Program.ValidateThreadCount(0)); 12 | Assert.AreEqual(50, Program.ValidateThreadCount(-5)); 13 | Assert.AreEqual(10, Program.ValidateThreadCount(10)); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Subdominator/Models/CnameResolutionResult.cs: -------------------------------------------------------------------------------- 1 | namespace Subdominator.Models; 2 | 3 | public class CnameResolutionResult 4 | { 5 | public List Cnames { get; set; } = new List(); 6 | public List A { get; set; } = new List(); 7 | public List AAAA { get; set; } = new List(); 8 | public bool IsNxdomain { get; set; } = false; 9 | public bool? IsDomainRegistered { get; set; } = null; // null indicates not checked 10 | } -------------------------------------------------------------------------------- /Subdominator/Models/Options.cs: -------------------------------------------------------------------------------- 1 | namespace Subdominator.Models; 2 | 3 | public class Options 4 | { 5 | public string Domain { get; set; } 6 | public string DomainsFile { get; set; } 7 | public string OutputFile { get; set; } 8 | public string CsvHeading { get; set; } 9 | public int Threads { get; set; } = 50; 10 | public bool Verbose { get; set; } 11 | public bool ExcludeUnlikely { get; set; } 12 | public bool Validate { get; set; } 13 | public bool Quiet { get; set; } 14 | } 15 | -------------------------------------------------------------------------------- /Subdominator/Models/TakeoverResult.cs: -------------------------------------------------------------------------------- 1 | namespace Subdominator.Models; 2 | 3 | public class TakeoverResult 4 | { 5 | public bool IsVulnerable { get; set; } 6 | public bool IsVerified { get; set; } 7 | public Fingerprint? Fingerprint { get; set; } 8 | public List? CNAMES { get; set; } 9 | public List? A { get; set; } 10 | public List? AAAA { get; set; } 11 | public MatchedRecord MatchedRecord { get; set; } 12 | public MatchedLocation MatchedLocation { get; set; } 13 | } 14 | -------------------------------------------------------------------------------- /.github/workflows/dotnet-core.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v2 15 | - name: Setup .NET 16 | uses: actions/setup-dotnet@v1 17 | with: 18 | dotnet-version: 8.0.x 19 | - name: Install dependencies 20 | run: dotnet restore Subdominator.sln 21 | - name: Build 22 | run: dotnet build --configuration Release --no-restore Subdominator.sln -------------------------------------------------------------------------------- /Subdominator/Utils/ValidatorUtils.cs: -------------------------------------------------------------------------------- 1 | using Subdominator.Validators; 2 | 3 | namespace Subdominator.Utils; 4 | 5 | public static class ValidatorUtils 6 | { 7 | private static IValidator _azureValidator = new MicrosoftAzureValidator(); 8 | 9 | // This could use reflection but it will break AoT compilation. 10 | // Instead, it needs to have any new validators manually added. 11 | // The validator key is same as the fingerprint name/service, minus any '/' or ' ' chars 12 | public static IValidator? GetValidatorInstance(string key) 13 | { 14 | return key switch 15 | { 16 | "MicrosoftAzure" => _azureValidator, // Use a global instance so it only asks for creds once 17 | "AWSElasticBeanstalk" => new AWSElasticBeanstalkValidator(), 18 | _ => null, 19 | }; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Subdominator.Tests/Subdominator.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | false 9 | true 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | all 18 | runtime; build; native; contentfiles; analyzers; buildtransitive 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Subdominator/Models/Fingerprint.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace Subdominator; 4 | 5 | public class Fingerprint 6 | { 7 | [JsonPropertyName("cname")] 8 | public List Cnames { get; set; } = new(); 9 | 10 | [JsonPropertyName("a")] 11 | public List ARecords { get; set; } = new(); 12 | 13 | [JsonPropertyName("aaaa")] 14 | public List AAAARecords { get; set; } = new(); 15 | 16 | [JsonPropertyName("fingerprint")] 17 | [JsonConverter(typeof(SingleOrArrayConverter))] 18 | public List FingerprintTexts { get; set; } 19 | 20 | [JsonPropertyName("http_status")] 21 | public int? HttpStatus { get; set; } 22 | 23 | [JsonPropertyName("nxdomain")] 24 | public bool Nxdomain { get; set; } 25 | 26 | [JsonPropertyName("service")] 27 | public string Service { get; set; } 28 | 29 | [JsonPropertyName("status")] 30 | public string Status { get; set; } 31 | 32 | [JsonPropertyName("vulnerable")] 33 | public bool Vulnerable { get; set; } 34 | } 35 | -------------------------------------------------------------------------------- /Subdominator/SingleOrArrayConverter.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | using System.Text.Json; 3 | 4 | namespace Subdominator; 5 | 6 | public class SingleOrArrayConverter : JsonConverter> 7 | { 8 | public override List Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) 9 | { 10 | List list = new List(); 11 | if (reader.TokenType == JsonTokenType.StartArray) 12 | { 13 | while (reader.Read()) 14 | { 15 | if (reader.TokenType == JsonTokenType.EndArray) return list; 16 | list.Add(JsonSerializer.Deserialize(ref reader, options)); 17 | } 18 | } 19 | else 20 | { 21 | var value = JsonSerializer.Deserialize(ref reader, options); 22 | list.Add(value); 23 | } 24 | return list; 25 | } 26 | 27 | public override void Write(Utf8JsonWriter writer, List value, JsonSerializerOptions options) 28 | { 29 | JsonSerializer.Serialize(writer, value, options); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Stratus Security 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: "Create Releases" 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | release: 9 | name: Release 10 | strategy: 11 | matrix: 12 | kind: ['linux', 'windows'] 13 | include: 14 | - kind: linux 15 | os: ubuntu-20.04 16 | target: linux-x64 17 | ext: '' 18 | - kind: windows 19 | os: windows-latest 20 | target: win-x64 21 | ext: '.exe' 22 | runs-on: ${{ matrix.os }} 23 | steps: 24 | - name: Checkout 25 | uses: actions/checkout@v4 26 | 27 | - name: Setup dotnet 28 | uses: actions/setup-dotnet@v4 29 | with: 30 | dotnet-version: 8.0.x 31 | 32 | - name: Build 33 | shell: bash 34 | run: | 35 | release_name="Subdominator-${{ matrix.target }}" 36 | # Build everything 37 | dotnet publish Subdominator/Subdominator.csproj -r "${{ matrix.target }}" -c Release -o "Release-${{ matrix.target }}" -p:UseNativeAot=true 38 | - name: Publish 39 | uses: softprops/action-gh-release@v0.1.5 40 | with: 41 | files: "Release-${{ matrix.target }}/*${{ matrix.ext }}" 42 | env: 43 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /Subdominator/OptionsBinder.cs: -------------------------------------------------------------------------------- 1 | using System.CommandLine.Binding; 2 | using System.CommandLine; 3 | using Subdominator.Models; 4 | using System.Reflection; 5 | 6 | namespace Subdominator 7 | { 8 | public class OptionsBinder : BinderBase 9 | { 10 | private readonly List