我刚刚做了一个 CTF,你可以在其中查看源代码,我的做法比预期的要复杂一些。无论如何,只有这段代码我没有完全理解它的行为方式,因为我希望它创建的每个文件最终都会被删除。我使用了一点竞争条件来解决这个问题,基本上减慢了这段代码的执行速度,但是如果您通过将其扩展名更改为非阻塞文件来设法偷偷盗取一个 zip 文件,您就可以避免该文件被删除。 有人可以向我解释为什么会发生这种情况吗?这是代码:
function isitup($url){
$ch=curl_init();
curl_setopt($ch, CURLOPT_URL, trim($url));
curl_setopt($ch, CURLOPT_USERAGENT, "siteisup.htb beta");
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$f = curl_exec($ch);
$header = curl_getinfo($ch);
if($f AND $header['http_code'] == 200){
return array(true,$f);
}else{
return false;
}
curl_close($ch);
}
if($_POST['check']){
# File size must be less than 10kb.
if ($_FILES['file']['size'] > 10000) {
die("File too large!");
}
$file = $_FILES['file']['name'];
# Check if extension is allowed.
$ext = getExtension($file);
if(preg_match("/php|php[0-9]|html|py|pl|phtml|zip|rar|gz|gzip|tar/i",$ext)){
die("Extension not allowed!");
}
# Create directory to upload our file.
$dir = "uploads/".md5(time())."/";
if(!is_dir($dir)){
mkdir($dir, 0770, true);
}
# Upload the file.
$final_path = $dir.$file;
move_uploaded_file($_FILES['file']['tmp_name'], "{$final_path}");
# Read the uploaded file.
$websites = explode("\n",file_get_contents($final_path));
foreach($websites as $site){
$site=trim($site);
if(!preg_match("#file://#i",$site) && !preg_match("#data://#i",$site) && !preg_match("#ftp://#i",$site)){
$check=isitup($site);
if($check){
echo "<center>{$site}<br><font color='green'>is up ^_^</font></center>";
}else{
echo "<center>{$site}<br><font color='red'>seems to be down :(</font></center>";
}
}else{
echo "<center><font color='red'>Hacking attempt was detected !</font></center>";
}
}
# Delete the uploaded file.
@unlink($final_path);
}
我尝试查找取消链接函数的文档,并尝试在本地针对 zip 文件执行此函数,但这似乎不是问题。
我已经重新组织了一些事情,但还没有尝试运行它。我的主要技巧是将代码分成更小的功能块,每个功能块都更容易测试。另外,我仅在知道文件存在时才取消链接该文件,并且在取消链接之前删除了@,以暴露它返回的任何错误。希望这有帮助!
<?php
function postIsOk($field)
{
if (isset($_POST[$field]) && ($_POST[$field])) {
return true;
}
return false;
}
function isFileOk($file)
{
// File size must be less than 10kb.
if ($file['size'] > 10000) {
//log('File too large!');
return false;
}
$filename = $file['name'];
// Check if extension is allowed.
$ext = getExtension($filename);
if (preg_match('/php|php[0-9]|html|py|pl|phtml|zip|rar|gz|gzip|tar/i', $ext)) {
//log('Extension not allowed!');
return false;
}
// Create directory to upload our file.
$dir = 'uploads/'.md5(time()).'/';
if (! is_dir($dir)) {
mkdir($dir, 0770, true);
}
if (! is_dir($dir)) {
//log('Directory not created!');
return false;
}
// Upload the file.
$file_path = $dir.$filename;
move_uploaded_file($file['tmp_name'], "{$file_path}");
if (! file_exists($file_path)) {
//log('File not created');
return false;
}
return $file_path;
}
function isSiteUp($url)
{
$headers = get_headers(trim($url));
if (is_array($headers) && isset($headers['http_code']) && (int) $headers['http_code'] == 200) {
if (! preg_match('#file://#i', $url) && ! preg_match('#data://#i', $url) && ! preg_match('#ftp://#i', $url)) {
return "<center>{$url}<br><font color='green'>is up ^_^</font></center>";
} else {
return "<center>{$url}<br><font color='red'>seems to be down :(</font></center>";
}
}
return false;
}
function getUrlsFromFilePath($file_path)
{
// Read the uploaded file.
return explode("\n", file_get_contents($file_path));
}
if (postIsOk('check')) {
$file_path = isFileOk($_FILES['file']);
if ($file_path) {
$urls = getUrlsFromFilePath($file_path);
foreach ($urls as $url) {
$check = isSiteUp($url);
if ($check) {
echo $check;
}
}
// Delete the uploaded file.
unlink($file_path);
}
}