From 231bccf7475358f0761413486fa19a2b7b61f167 Mon Sep 17 00:00:00 2001 From: Aristos Miliaressis Date: Sat, 2 Dec 2023 11:55:26 +0200 Subject: [PATCH] vhost_scan - work in progress --- src/core/pwnctl.app/Scope/Entities/ScopeDefinition.cs | 2 +- src/core/pwnctl.domain/Entities/HttpEndpoint.cs | 3 +++ src/core/pwnctl.domain/Entities/HttpParameter.cs | 2 +- src/core/pwnctl.exec/scripts/webcrawl.sh | 2 +- .../pwnctl.infra/Persistence/seed/post-web-recon.yaml | 8 ++++++++ src/core/pwnctl.infra/Persistence/seed/web-recon.td.yml | 5 ----- 6 files changed, 14 insertions(+), 8 deletions(-) create mode 100644 src/core/pwnctl.infra/Persistence/seed/post-web-recon.yaml diff --git a/src/core/pwnctl.app/Scope/Entities/ScopeDefinition.cs b/src/core/pwnctl.app/Scope/Entities/ScopeDefinition.cs index eec7d1d2..9eebc971 100644 --- a/src/core/pwnctl.app/Scope/Entities/ScopeDefinition.cs +++ b/src/core/pwnctl.app/Scope/Entities/ScopeDefinition.cs @@ -65,7 +65,7 @@ private bool UrlMatchingChecks(Asset? asset) { return asset switch { - HttpEndpoint ep => new Regex(Pattern).Matches(ep.Url).Count > 0, + HttpEndpoint ep => new Regex(Pattern).Matches(ep.ToString()).Count > 0, HttpParameter param => Matches(param.Endpoint), _ => false }; diff --git a/src/core/pwnctl.domain/Entities/HttpEndpoint.cs b/src/core/pwnctl.domain/Entities/HttpEndpoint.cs index 974fd528..b7cad327 100644 --- a/src/core/pwnctl.domain/Entities/HttpEndpoint.cs +++ b/src/core/pwnctl.domain/Entities/HttpEndpoint.cs @@ -4,6 +4,7 @@ using pwnctl.kernel.BaseClasses; using pwnctl.domain.BaseClasses; using pwnctl.domain.Enums; +using System.Text.RegularExpressions; public sealed class HttpEndpoint : Asset { @@ -15,6 +16,8 @@ public sealed class HttpEndpoint : Asset public Guid? ParentEndpointId { get; private init; } public HttpEndpoint? ParentEndpoint { get; private set; } public List HttpParameters { get; private set; } + + public bool IsIpBased => new Regex(@"^https?://[\d]{1,3}(\.[\d]{1,3}){3}").Match(Url).Success; public string Scheme { get; init; } public string Path { get; init; } diff --git a/src/core/pwnctl.domain/Entities/HttpParameter.cs b/src/core/pwnctl.domain/Entities/HttpParameter.cs index 007ca406..a55092d5 100644 --- a/src/core/pwnctl.domain/Entities/HttpParameter.cs +++ b/src/core/pwnctl.domain/Entities/HttpParameter.cs @@ -24,7 +24,7 @@ public HttpParameter() {} public HttpParameter(HttpEndpoint endpoint, string name, ParamType type, string? value) { Endpoint = endpoint; - Url = endpoint.Url; + Url = endpoint.ToString(); Name = name; Type = type; Value = value; diff --git a/src/core/pwnctl.exec/scripts/webcrawl.sh b/src/core/pwnctl.exec/scripts/webcrawl.sh index 7ccf1cdc..2535876c 100755 --- a/src/core/pwnctl.exec/scripts/webcrawl.sh +++ b/src/core/pwnctl.exec/scripts/webcrawl.sh @@ -13,7 +13,7 @@ timeout -v -k 30s 150m katana --silent --no-sandbox -hl -d 10 -silent -nc -or -o cat $katana_tmp | jq -r .request.endpoint | sort -u 2>/dev/null cat $katana_tmp \ - | jq -c 'select( .response.forms != null ) | .response.forms[] as $form | select( $form.parameters != null) | $form.parameters[] | { asset:($form.action+"?"+.), tags:{form:true,enctype:$form.enctype,method:$form.method} }' \ + | jq -c 'select( .response.forms != null ) | .response.forms[] as $form | select( $form.parameters != null) | $form.parameters[] | { asset:($form.action+"?"+.), tags:{form:"true",enctype:$form.enctype|tostring,method:$form.method} }' \ | jq -c 'if .tags.method != "GET" then .tags.Type="Body" else . end' 2>/dev/null >> $temp cat $temp | grep "form\":true" | while read url; do param=$(echo $url | jq -r .asset | cut -d '?' -f2); tags=$(echo $url | jq -c .tags); echo $url | jq -r .asset | sed 's/%/\\\\x/g' | xargs -I {} printf "{}\n" | unfurl format "{\"asset\":\"%s://%a%p?$param\",\"tags\":$tags}"; done | sort -u 2>/dev/null diff --git a/src/core/pwnctl.infra/Persistence/seed/post-web-recon.yaml b/src/core/pwnctl.infra/Persistence/seed/post-web-recon.yaml new file mode 100644 index 00000000..c5bcc3e2 --- /dev/null +++ b/src/core/pwnctl.infra/Persistence/seed/post-web-recon.yaml @@ -0,0 +1,8 @@ +Profile: "post_web_recon" + +TaskDefinitions: + - Name: vhost_scan + Subject: HttpEndpoint + Filter: HttpEndpoint.Path == "/" && HttpEndpoint.IsIpBased + CommandTemplate: vhost-scan.sh {{Url}} + StdinQuery: SELECT "TextNotation" FROM "asset_records" WHERE "InScope" = true AND "DomainNameId" != null \ No newline at end of file diff --git a/src/core/pwnctl.infra/Persistence/seed/web-recon.td.yml b/src/core/pwnctl.infra/Persistence/seed/web-recon.td.yml index 5aa3561c..e0d77845 100644 --- a/src/core/pwnctl.infra/Persistence/seed/web-recon.td.yml +++ b/src/core/pwnctl.infra/Persistence/seed/web-recon.td.yml @@ -153,8 +153,3 @@ TaskDefinitions: CommandTemplate: mdwfuzzer.sh {{Url}} Filter: HttpEndpoint.Path=="/" Subject: HttpEndpoint - - - Name: vhost_scan - CommandTemplate: vhost-scan.sh {{Url}} - Subject: HttpEndpoint - Filter: false && HttpEndpoint.Path=="/"