La mia risposta ha avuto più tempo del previsto, quindi per darti la risposta: <body onpageshow="alert(1)">
probabilmente funziona, e in caso contrario, <body onpaonpageonpagonpageonpageshowshoweshowshowgeshow="alert(1)">
lo farà.
Come provare a ignorare un filtro personalizzato
Dici di provare a imparare come fare tu stesso, quindi ecco alcuni dei primi passi che prendo:
- check case: non tutti i filtri sono case sensitive.
I
è anche sostituito o solo i
?
- controlla le codifiche alternative:
:
non è consentito, ma :
potrebbe essere (e funziona allo stesso modo in molti contesti).
- controlla cosa sta effettivamente facendo il filtro. Le sostituzioni vengono sempre eseguite o solo in determinati contesti (ad es.
i
sempre filtrata o solo in script
o solo circondata da caratteri o ...)? I filtri vengono applicati una sola volta (ad esempio <scri<script>pt>
diventa <script>
)?
L'ultimo punto è il più complesso. Ad esempio, tu dici che i
è sempre sostituito da .
. Ma poi nei commenti, dici che <scri<script>pt>
diventa <scri<scr.pt>pt>
. Quindi forse i
è solo sostituito in script
?
Hai anche detto che on
è filtrata. Sei sicuro? Oppure vengono filtrati solo alcuni degli specifici attributi degli eventi? Hai provato onFooBar
? Se viene filtrato, verranno filtrati tutti gli attributi di on
. Ma se no, alcuni potrebbero bypassare il filtro. Se è così, dovresti provare soprattutto i nuovi HTM5, alcuni dei quali sono spesso dimenticati. Ecco un elenco degli attributi degli eventi da controllare.
Che cosa potrebbe funzionare nel tuo caso
Non eri abbastanza specifico con le tue regole [*] per dare una risposta definitiva, ma ecco alcune idee:
-
<meta http-equIv="refresh" content="0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==">
funzionerà se il filtro i
non è sensibile al maiuscolo / minuscolo (meno probabile), o se si applica solo a script
(che sembra essere il caso nel tuo esempio). Tieni presente che :
funzionerà al posto di :
.
- se il filtro
i
non è sensibile al maiuscolo / minuscolo, potrebbero esserci molti carichi utili: <scrIpt src=http://localhost/s.js></scrIpt>
(non contiene <script>
), <a href="javascrIpt:alert(1)">click</a>
, ecc.
[*] E ti contraddicono anche un po '; se <script>
diventa uno spazio vuoto e i
diventa .
, allora perché <scri<script>pt>
porta a <scri<scr.pt>pt>
, invece di <scr. pt>
, che corrisponderebbe alle tue regole?
Qual è il filtro effettivo nel tuo caso
I filtri XSS possono essere visualizzati qui .
Dalla descrizione del filtro, sei al livello due (o forse al terzo livello). Il filtro è:
-
script
diventa sc.pt
-
onclick
diventa o.ick
-
onmouseover
diventa o.ver
-
onload
diventa o.oad
-
onerror
diventa o.err
-
ondblclick
diventa o.dbl
-
&
diventa !
-
:
diventa !
O in alternativa per il livello tre, lo stesso, eccetto che i filtri on
sono un po 'meno cattivi.
Quali payload ignoreranno questi filtri
Ora che abbiamo una descrizione adeguata dei filtri, possiamo facilmente aggirarli.
Ma prima di tutto, i bypass che in realtà non funzioneranno:
-
<meta http-equiv="refresh" content="0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==">
: non funzionerà. i
non è in realtà sempre sostituito con .
(il che ha senso, in quanto tale filtro distruggerebbe tutti gli input effettivi), ma non possiamo usare &
, e quindi non possiamo usare un URL di dati.
-
<a href="javascript:alert(1)">click</a>
: problema con script
e anche &
.
Puoi vedere che il primo fallisce solo a causa di una regola che non hai menzionato: &
replace.
Ma ora per una soluzione che funziona. Per il livello due:
- qualsiasi attributo
on
che non sia onclick
, onmouseover
, onload
, onerror
o ondblclick
. Ce ne sono molte, ad esempio <body onpageshow="alert(1)">
.
Per il livello tre, il trucco è che ci sono molti più attributi di attributi on
(non ho controllato se è tutto), ma sono sostituiti da nulla (quattro volte). Ciò significa che se includi la parola chiave in sé cinque volte, ignori il filtro:
-
<body onpaonpageonpagonpageonpageshowshoweshowshowgeshow="alert(1)">
Conclusione
La descrizione del filtro è incoerente e incompleta, quindi non è possibile ottenere la risposta in base ad essa.
Durante il test di un filtro come questo, dovresti provare tutti i casi d'angolo attorno alle regole che hai definito possibili, in modo da ottenere una descrizione del filtro che sia il più vicino possibile alla realtà.
Quindi è solo questione di trovare il carico utile corretto per aggirare queste regole.