baby toctou -- Race Condition

URL: http://webhacking.kr:10019arrow-up-right

WebShell [Version 1.0.00000.001]  
  
WebShell:/ $ help  
only "ls", "cat api.php", "cat index.php" allowed  
WebShell:/ $ ls  
api.php  
flag.php  
index.php  
user  
  
WebShell:/ $ cat api.php  
<?php  
	// system($_GET['q']);
	if (!preg_match('/^[a-f0-9]+$/', $_COOKIE["baby_toctou"])) {
	    $newCookie = uniqid() . rand(1, 999999999);
	    setcookie("baby_toctou", $newCookie);
	    $_COOKIE["baby_toctou"] = $newCookie;
	}
	$cmd = $_GET["q"];
	($myfile = fopen("user/{$_COOKIE["baby_toctou"]}.sh", "w")) or die("Unable to open file!");
	fwrite($myfile, $cmd);
	fclose($myfile);
	if ($cmd === "ls" || $cmd === "cat api.php" || $cmd === "cat index.php") {
	    // valid check
	    sleep(1); // my server is small and weak
	    system("sh ./user/{$_COOKIE["baby_toctou"]}.sh");
	} else {
	echo <<<HELP  
only "ls", "cat api.php", "cat index.php" allowed  
HELP;  
	}
?>  
WebShell:/ $

Looks like we have Race Condition, because of sleep before system. First we make good request, followed by bad request. Good request will go into valid check and sleep for 1 second, bad request within this timeframe will write malicious payload into the script file and good request will execute whatever bad has written.

We can easily achieve this using asyncio requests using Python:

Change tasks in code to

And get the flag:


toctue turns out means Time-of-check to time-of-use

https://omni.wikiwand.com/en/articles/Time-of-check_to_time-of-usearrow-up-right

Last updated