どうも、だーやまんです。
当ブログでは、だーやまんの戯言や、プログラミングの話、あとDiscord Bot「喋太郎」の案内なんかもやってます。 どうぞ、ごゆるりとお過ごしください。
nonbiriyanonikki.hatenablog.com
Twitter: @gamerkohei
どうも、だーやまんです。
当ブログでは、だーやまんの戯言や、プログラミングの話、あとDiscord Bot「喋太郎」の案内なんかもやってます。 どうぞ、ごゆるりとお過ごしください。
nonbiriyanonikki.hatenablog.com
Twitter: @gamerkohei
カニ食べたい。どうも、だーやまんです。
これは、SLP KBIT Advent Calendar 2019 - Adventarの15日目の記事です。
Text To Speech APIを利用する際、API側で読み仮名が正しく認識されないことがある。造語などに関しては、いうまでもなく。そのような時、どのようにして送信した文字列を思い通りに読んでもらうか、という処理をPythonで行った場合を紹介する。
以下の通りに読んで欲しい文字列があるとする。ここでは、鉤括弧や句読点等は読み飛ばされるものとする。
文字列: 僕の禁断の過負荷 『却本作り』!! 読み: ぼくのはじまりのまいなす、ぶっくめーかー
( めだかボックス第11巻 p25 )
この場合、正しくない読み仮名と造語が入り混じった文になっている。まずはこれらの辞書を作成する
u_dict = { '禁断':'はじまり', '過負荷':'まいなす', '却本作り':'ブックメーカー' }
あとは、元の文字列に対して、辞書の登録数だけ一致する部分を変換するだけである。辞書に対して、 items()
を使うことでキーと値のペアのタプルのリストを取得できる。あとは置換してやるだけである。
read_text = ' 僕の禁断の過負荷 『却本作り』!!' for word, read in u_dict.items(): read_text = read_text.replace(word, read) print(read_text)
結果
僕のはじまりのまいなす 『ぶっくめーかー』!!
これで思い通りに変換ができた。これがとりあえずの実装になる。
以上の実装で、以下のような辞書と文字列の時、どうなるだろうか。
u_dict = {'蜂':'びー', 'びー':'ハエ'} read_text = 'ぶんぶんぶん、蜂がとぶ。びーは蠅である。'
for文の1巡目で文中の「蜂」が「びー」に変換され、2巡目で「びー」が「ハエ」に変換される。その結果、
ぶんぶんぶん、ハエがとぶ。ハエは蠅である。
になる。
変換された読み仮名がさらに変換されるのは問題である。自分の思わぬ文字列に変換される恐れがあるし、文字列爆発による攻撃も可能になる。
文字列爆発の例
u_dict = { 'a':'bbb', 'b':'ccc'} read_text = 'aaa'
変換結果
ccccccccccccccccccccccccccc
悪意のある文字列を登録された場合、文字列は指数関数的に伸ばすことが可能になるので、メモリへの攻撃が可能になる。
str型の組み込み関数、 format()
を用いる。一度、文字列の変換該当部分を{}と変換先の文字列の引数番号にする。そうすることで二重の変換を防ぐことができる。コードを見てみよう。
u_dict = {'蜂':'びー', 'びー':'ハエ'} read_text = 'ぶんぶんぶん、蜂がとぶ。びーは蠅である。' print(read_text) read_list = [] # あとでまとめて変換するときの読み仮名リスト for i, one_dic in enumerate(u_dict.items()): # one_dicは単語と読みのタプル。添字はそれぞれ0と1。 read_text = read_text.replace(one_dic[0], '{'+str(i)+'}') read_list.append(one_dic[1]) # 変換が発生した順に読みがなリストに追加 print(read_text) read_text = read_text.format(*read_list) #読み仮名リストを引数にとる print(read_text)
実行結果
ぶんぶんぶん、蜂がとぶ。びーは蠅である。 ぶんぶんぶん、{0}がとぶ。{1}は蠅である。 ぶんぶんぶん、びーがとぶ。ハエは蠅である。
いい感じに変換されました。
辞書の登録順に変換されてしまうので、優先度等の重みつけはできていない。辞書型を使うのではなく、新しくクラスを定義することで可能になるかな〜。私が運用している喋太郎でも、今回紹介した方法を用いている。誰かの参考になれば幸い。
さっぶ。どうも、だーやまんです。
この記事は、本番環境でやらかしちゃった人 Advent Calendar 2019 - Qiitaの11日目の記事です。
これは、中途半端な知識でサービスを運用していた結果、タイトル通りの大失敗をしてしまったお話です。個人開発での出来事なので、業務で起きたことかと胃薬を握られていた方はご安心ください。
語るのもすごい恥ずかしいレベルですが、戒めのために晒しておきます。
Hello. You may be surprised to see this message, but it was your bad security practices that allowed us to steal your database. If you want to restore your data, and continue using it, send 0.075000 Bitcoin to [おそらくBitCoinのウォレットアドレス] and go to the page using tor browser [謎のURL]. In return, you will get the copy we have of your database. You can download the tor browser on the official website https://www.torproject.org/download/ | [おそらくBitCoinのウォレットアドレス] | [謎のURL]
(意訳)(悪意マシマシ)
「おっすwwwww驚いた?wwwwガバガバセキュリティのおかげでwwwwデータ盗めたわwwww返して欲しかったらwwwウェwwwここにビットコインwwww振り込みよろwwwww」
やられた
とりあえず現在進行形で踏み台にされている可能性があるので、必要と思われるログや設定ファイルをまとめてメインPCに保存(それも安全なのかっていう)。その後、DBサーバをシャットダウン。 自分だけではログの読み方もいまいちわからなかったため、詳しい友人や、先輩に調査のお願いをした。
まず、postgresの設定をどのようになっていたのか
今思うと素敵な設定してますね。玄関の鍵を閉めないタイプか?
それでは、設定ファイル(pg_hba.conf)の接続可能ホストを確認してみよう。(IPアドレスは架空のもの)
# TYPE DATABASE USER ADDRESS METHOD [省略] host all all 184.14.25.76/0 md5 host all all 184.14.133.122/0 md5
サブネットマスクが0になってるね。これはIPアドレスの仕組みをよく理解しておらず、なんとなくググってこのような設定を見つけたので真似した結果。(「IPアドレス 一つ 指定」みたいな検索をした気がする)
追記
サブネットマスクが0であることの何がまずいか。
IPアドレスをどのような値にしたところで、 0.0.0.0
、つまりな任意のIPアドレスという意味になる。上記の設定の場合、接続ホストを制限するどころか、あらゆるホストの接続を許可したことになる。自宅が公共施設になってしまった。
この話がよくわからないという人は、サービスの公開をする前にネットワークを勉強しような。だーやまんの二の舞になるぞ。
ガバガバのガバ。ログとかめっちゃ攻撃された足跡あった。
どうもこの隙を突いて、任意のコマンドを実行、悪意のあるスクリプトをダウンロード・実行させられたらしい。ログファイルにダウンロードの痕跡と、見覚えのないファイルが/var/lib/pgsql/11/data/
以下に存在していた。
mackerelから不自然なアラートが起きたときにもすぐに対応せずに放置したのもBadポイント。
そもそも上記の事項は大学の講義で履修した内容であるので、いかに適当に単位をとってきたかが伺える結果。そら留年するわ。
さくらのVPSは無料でローカルネットワークを組めると知らなかったので、サーバ同士の通信がグローバルIPアドレスを用いて行われていた。
メールアドレスなど、直接的に個人と結びつくような情報は保存していない(できない)ため、流出しなかった。ユーザネームやユーザ辞書に個人情報が書かれていた場合はどうしようもない...。
さもなくば、信用を失う上に友人から一生煽られることになります。
サブネットマスクを間違えただけなのに・・・
— ヒデホヒ (@eakonnsamui) 2019年11月12日
主演:だーやまん 来年春 公開
だーやまん/0はなぁ
— ヒデホヒ (@eakonnsamui) 2019年11月14日
早速、いくつか反応をいただけたので補足いたします。
そうですね。postgresユーザがデフォルトパスワードのままmd5になってました。書くの忘れてました...(今は変更してます)
使ってますよ〜。被害にあった時はssh用のポート(こっちは変更していた)と、5432ポートをインターネットに向けて開いてました。
記事中に追記しました。
あれ〜、じゃあ自分で「postgres」にしたのかしら。DBのownerは複雑なやつにしてたから割とまじで大馬鹿案件...?
ほんまです。就職してからじゃあ洒落にならないことになってました。
*1:Discordでは1つのコミュニティをサーバと表記するが、混乱を防ぐためにここではギルドと表記
9月に入りましたがひたすら暑くて溶けてます。どうも、だーやまんです。
ドメインを取得して、当ブログのURLが変わったのでお知らせします。
になりました。旧URLからでもリダイレクトされるのでブクマの再登録は大丈夫だとは思いますが、気になる方は再登録をお願いします〜。
それと、過去記事を大幅に消しちゃいました。お気に入りの記事があったら、ごめんなさいね〜。
でわでわ、今後とも当ブログをよろしくお願いいたします。