2013年7月29日月曜日

MySQL Proxyで認証をフックしようと悪戦苦闘(ユーザー名だけ書き換えはOK)

前回 の続き。
要件はこんな感じ。

  • ユーザー名に"+"が含まれていた場合、"+"とそれ以降の文字列を握りつぶす。
    • mysql -uroot+yoku0825 -p だったら、rootに変換してやる。
  • パスワードやその他のオプションは入力されたものを素通し。
  • クライアントはmysqlコマンドラインクライアントとは限らない。

取り敢えず判ったところまででは、
  • MySQL Proxy 0.8.3以降はto_response_packetにserver_capabilitiesの指定が必須になったっぽい。
  • server_capabilitiesに使える値の一覧はinclude/mysql_com.hに書いてある。
  • 取り敢えず ここ を参考にCLIENT_PROTOCOL_41(=512)とCLIENT_SECURE_CONNECTION(=32768)を設定したら、ユーザー名の握りつぶしは成功した。
$ cat ./proxy.lua
local password= assert(require("mysql.password"))
local proto= assert(require("mysql.proto"))

function read_auth()
  local c = proxy.connection.client
  local s = proxy.connection.server

  local proxy_user= c.username
  local mysql_user= string.match(c.username, "^(%w+)+")
  if not mysql_user then mysql_user= proxy_user end

  proxy.queries:append(1, proto.to_response_packet(
  {
    server_capabilities= 33280,
    username= mysql_user,
    response= c.scrambled_password
  }))

  return proxy.PROXY_SEND_QUERY
end

$ /usr/mysql/proxy/bin/mysql-proxy --proxy-address=127.0.0.55:3306 --proxy-backend-addresses=127.0.0.1:64055 --proxy-lua-script=/usr/mysql/proxy/proxy.lua --log-level=debug

$ mysql -h 127.0.0.55 -P 3306 -u root+yoku0825 -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 15
Server version: 5.5.32-log Source distribution

Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> status
--------------
mysql  Ver 14.14 Distrib 5.6.12, for Linux (x86_64) using  EditLine wrapper

Connection id:          15
Current database:
Current user:           root@localhost
SSL:                    Not in use
Current pager:          stdout
Using outfile:          ''
Using delimiter:        ;
Server version:         5.5.32-log Source distribution
Protocol version:       10
Connection:             127.0.0.55 via TCP/IP
Server characterset:    utf8
Db     characterset:    utf8
Client characterset:    utf8
Conn.  characterset:    utf8
TCP port:               3306
Uptime:                 2 days 19 hours 27 min 2 sec

Threads: 3  Questions: 77  Slow queries: 2  Opens: 36  Flush tables: 1  Open tables: 29  Queries per second avg: 0.000
--------------

mysql> SELECT current_user();
+----------------+
| current_user() |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)

よしよしよしよし。
しかしまあ、相変わらずパスワードとかいじろうとすると(to_response_packetでresponseを書き換えると)assertion `20 == challenge_len' failedになっちゃうんだよなぁ。。
そこはまた追って調べるとして、取り敢えずこれで他に情報をログする部分を書きましょうそうしましょう。

0 件のコメント :

コメントを投稿