ほぼPython

Not技術ブログBut勉強ブログ 内容には誤りがあることが多いです

PythonのGUI自動化で自作Webサイトにハッキングを試みた

今日、図書館で退屈なことはPythonにやらせようを読んでいたらGUIオートメーションについての記載がありました。

 

GUIオートメーションとは、キーボードやマウスをプログラムで操作してフォームの入力など退屈な作業を自動化するといった話のようです。

 

当然の発想ですが、GUIオートメーションによって、セキュリティが(ものすごく)低いサイトに対してなら簡単にハッキング出来ます。

 

ということで、さっそくやってみました。

 

今回用意したデモサイトは

フォームに4桁のパスワード(数字)を入力し、パスワードが一致すると他のサイト(僕が前に作ったデモサイト)に飛ぶという仕様になっています。

さらに、何度入力を間違えてもロックがかからないというセキュリティがひどいものになっています。(そもそもパスワードの認証部分はJSで書いていて、まったくパスワードになっていませんが、見かけ上パスワードということで。)

 

pyautoguiというすごく便利なモジュールを使って

 

・マウスの制御によりフォームのクリック

・キーボードの制御によるパスワードの入力

 

を行います。そして、別ページに飛べるまでループを続けるという処理により、ハッキングしています。

 

退屈な動画ですが、ハッキング動画はこちらです。

 

 

 

 

 

くどいようですが、マウスクリックや入力はすべてプログラムが制御しています。

ただ、動画を見ていただけるとわかると思いますが、思っていた以上に動きが遅いです。

そうは言っても4桁ですべて数字・何回ミスしてもロックされないというゆるゆるセキュリティのサイトがもしあれば、こういうプログラムを起動して放置しておけば、侵入できてしまうので、危ないですね。(まぁ、そんなサイトはないと思いますが・・・)

 

ハッキングなんかせずとも、GUI自動化をすれば繰り返しのフォーム入力の自動化など面白いことがいろいろできます。皆さんもぜひ試してみてはいかがでしょうか。

 

コードはすごく簡単なので、今回は公開はしないでおきます。

ほとんどpyautogui.clickとpyautogui.typewriteだけしか使ってないです。

 

 

 

PythonとMySQLを接続しようと思ったら遠回りしてしまい苦労した話

Pythonでデータベースを使う必要が出てきました。

 

そこで、とりあえず、MySQLとつなげてみようと思い、MySQLのインストールから始めました。最終的にはPythonからデータベースをいじることに成功しましたが、結構遠回りしたので、せっかくなのでまとめておきます。

 

合計所要時間は100分です。遠回りにかかった時間は60分です。

きっと遠回りしなければ、1時間もかかりません・・・。

 

MySQLのダウンロード・インストール

MySQLのダウンロードおよびインストール、その後のPATH通しなどは以下のサイトを参考に、ハマることなく、終えました。

このサイト、信じられないほどわかりやすかったです。

 

 

MySQLのインストールとPATH通しが終わったら、さっそくデータベースを作ってみました。

 

データベースを作成

まず、コマンドプロンプトからmysqlに接続します。

mysql -u root -p

 

データベースを作成します。今回、名前はsampleとしました。

create database sample;

 

データベースにテーブルを作成します。今回はpersonというテーブルを1つだけ作成しました。ちなみに、「id」のデータ型はint型、「name」データ型はvarchar(20)型を指定しています。

create table sample.person(id int, name varchar(20));

 

テーブルが作成できているか確認します。テーブルを表示します。

show tables from sample;

 

作成したテーブルにデータを挿入します。

insert into person(id,name) values(1453 ,'Yanagi');

 

テーブルのデータを表示します。無事、データが入っています。

select *from sample.person;

 

僕は、これで満足したのですが、ユーザーというのも作成する必要があるようです。 

 

ユーザーの作成

create user hoge@localhost IDENTIFIED BY 'password';

 

ユーザーの権限の設定

grant all on sample.* TO hoge@localhost;

 

これで、MySQLの方は終わりました。たぶんここまで30分くらいでした。

 

Pythonとの接続(失敗した手順)

さて、MySQLはいい感じだったので、Pythonから操作するというメインの部分にとりかかりました。

 

まず、ググったら mysqlclient というモジュールが良いと出てきました。そのため、このモジュールのインストールを以下のように試みました。

pip install mysqlclient

しかし、エラーが出ました。

 

エラーメッセージ:

error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": url

 

 そこで、【python】ライブラリインストール時に「error: Microsoft Visual C++ 14.0 is required.」エラーが発生を参考にエラーの対処に取り掛かりました。

 

しかし、その後もcl.exeが無い?と言ったようなエラーが出ました。(エラーメッセージは消してしまいました・・・)

 

ここまで来て、このまま突き進むのは良くないと感じ、別の方法を調べました。

 

すると、mysqlclientがWindowsでインストールできない | coffee break designs.というページに行き付きました。

このページを参考にwhlファイルを直接ダウンロードし、それを利用してインストールしようと試みました。

 

しかし、ここでもまたエラーが。

 

エラーメッセージ:

●● is not a supported wheel on this platform.

 

どうやら、whlファイルにはいくつか種類?があり、対応しているものを選ばないといけなかったようです。

 

qiita.com

 

ここに載っている方法で対応しているタイプを調べました。

 

これでwhlファイルがあるフォルダに移動し

pip install ファイル名.whl

 

 とすることで、無事、mysqlclientのインストールに成功しました。

 

ここに至るまでに60分・・・

しかし・・・!!

 

実際にPythonからこのモジュールを使おうとするとエラーが発生しました・・・。

 

エラーメッセージ:

_mysql_exceptions.OperationalError: (2059, <NULL>)

 

調べてみると、こんな回答が。

stackoverflow.com

僕の場合にも当てはまるかわかりませんが、この回答者はMySQLをダウングレードしたら使えるようになったそうです。MySQLのダウングレードはまたいろいろとハマりそうだと思い、ここにきて別のモジュールを使おう・・・と思いました。

 

Pythonとの接続(成功した手順)

このページを参考に進めたら、どこにもハマることなく10分でPythonからMySQLを操作することに成功しました・・・。

www.sejuku.net

 

まとめ

結果的には、間違った方向へ進んでしまいかなりの時間を無駄にしてしまいました。

 

しかし、whlファイルを使ったインストールなど、新しい方法を知ることもできて勉強になりました。

 

そしてバズワードと侍エンジニア塾ブログは非常にわかりやすかったです。

 

今後、データベースを使ったものを作っていきたいと思います。

 

ここまで読んでいただきありがとうございました。

任意のTwitterユーザーの画像・動画・GIF動画を保存するプログラムをまた、少し改良。

前に作ったものですが、さらに改良して、画像・動画・GIF動画が添付された際のツイートとその日時をエクセルファイル(.xlsx)に保存するようにしました。

 

コマンドプロンプトから実行し、DocumentにユーザーIDごとにフォルダが作られます。このフォルダをそのままにしておけば、再度起動した際、(見かけ上)更新分のみDLします。

 

まぁ、同じような機能をもつもっと優れたアプリは山ほどあります。完全に自己満ですね・・・。(自分のはコマンドプロンプトから起動する感じだし)

 

改良版ソースはこんな感じです。

Pythonでババ抜きシミュレーターを作った

こんにちは。

どうやら、今日でちょうど、このブログを開設して半年だそうです。このブログの開設と同時にPythonを始めたので、Pythonを勉強し始めてからちょうど半年が経ったということになりますね。

 

さて、来る8月某日に大学院入試(化学系)を迎える私ですが、諸事情により(?)全く入試の勉強をする気は起きず、勉強は放置しておき、ババ抜きシミュレーターを作ってみました。(友人に触発された)

 

簡単にできると思って作り始めたのですが、かなり苦労しました。

これまでは、「モジュールの使い方がわからない」とか「APIの仕様がわからない」というわからないがほとんどでしたが、今回のプログラムについては「処理の流れをどうすればいいかわからない」という、調べてもそう簡単に解決する問題ではない悩みでした。(競プロにおける、この問題わからない、に近い)

 

Twitterでそんなことを呟いていたら、「やることを箇条書きにしてみるといい」というアドバイスをいただいたので、箇条書きにしてみました。これにより、一気に作業が進み、たぶん完成しました。

 

実際に、プログラムを実行する。

今回は、プレイヤーの人数は10人にしました。

まず、各プレイヤーにカードが分配され、かぶっているカードは捨てられます。

 

f:id:short_4010:20180727175152p:plain

 

次に、それぞれのプレイヤーが次のプレイヤーからカードを引きます。手札にカードのかぶりがあったらカードを捨てて、手札が0枚になったら上がります。

 

f:id:short_4010:20180727175524p:plain

 

途中も、同じようにひたすら進んでいきます。最後のターンを載せておきます。

 

f:id:short_4010:20180727175825p:plain

 

ちなみに、「ターン」については、あるプレイヤーが1回カードを引いたら「1ターン」にしています。そのため、##118ターン目 と書いてありますが、実際に、ゲームが終了したのは、119ターン目になります。(ちょっと書き方が微妙だなと思ったが、これが一番きれいに書けたので妥協しました)

 

最後に、結果が表示されます。

 

f:id:short_4010:20180727180459p:plain

 

苦労した点について

特に苦労したのは、手札が0枚になったら上がるという処理です。

 

当然ですが、カードを引いたプレイヤーだけではなく、カードを引かれたプレイヤーも手札が0枚になる可能性があります。このあたりの場合分けをできるだけキレイに書きたいと思い、もがいていました。しかし、プレイヤー自体を配列として持っているので、上がるプレイヤーの配列上の位置によって処理を変える必要があるなど、どうしても読みにくいコードになってしまいました。

 

さらに、プレイヤーが上がったときに、上がった後のプレイヤーからゲームを再開するにはどうすればいいかという点も苦労しました。これについては、プレイヤーの配列を並び替えてループし直すという処理により解決したはずです。

 

醤油も載せておくので、ぜひコピーしてシミュレートしてみてください!(あと、もし、間違っているところに気づいたらご指摘お願いします!!)

ソース

 

 

 

PythonのTinyDBを使ってキャッシュっぽい機能をつくる。

PythonのモジュールにTinyDBというものがあります。

これは、指定したデータをjsonファイルで保存してくれて、簡単なデータベースとして使えます。

 

さて、ぷちばず検索でTwitterAPIを使ってツイートを検索する際に、すぐにAPI制限に引っかかってしまうため、誰かがアクセスしたら、その時に取得したツイートリストをデータベースに保存して、15分間はそのデータベースから読みこむという処理をしています。15分経つと、またAPIを使ってツイッターにアクセスします。(ちなみに、HEROKUはアクセスが無いと30分でデータベースは消えてしまいますが、今回はずっと保持していたいデータなわけではないので問題ない)

 

こんな感じの機能をキャッシュというっぽい(要出展)ので単体で、この機能だけのコードを書いてみました。

 

今回は、コードが実行されるとi=0からi=100000000まで計算されるという重い処理をしています。しかし、30秒以内にもう一度コードが実行された場合、データベースから読み込むので計算せずに済み、処理が早くなります。

 

初回実行時

f:id:short_4010:20180704224004j:plain

 

これを見ると、実行に15秒くらいかかっていることがわかります。

 

 

30秒以内にもう一度実行した場合

f:id:short_4010:20180704224013j:plain

 

これを見ると、0.4秒で実行が完了していることがわかります。

 

キャッシュを使えば、処理の時間を短縮出来たり、APIの使用回数を減らせたり、いいことがたくさんですね。

 

ソースも載せておきます。

 

バズりそうなツイートを検索するWebアプリを作った

今日は時間があったので、ちょっとバズってる、あと少しで一気にバズりそうなツイートを検索するWebアプリを作りました。

作ったサイト:ぷちばず検索

 

 動機:

・バズりそうなツイートを見つけて早いうちにパクツイしたい

ツイッターで高度な検索すればこういうことはできないことはないがめんどくさい。

特徴:

・画像やURLが含まれるツイートは除外。(画像付きにすると企業などのツイートが多く含まれてしまったため)

・最大50件表示する。

残念な点:

・検索に時間がかかる。(最大20秒くらい)

・すぐAPI制限にひっかかる。(15分以内に合計12回検索されたら15分止まる)

→この点は改良済み キャッシュを使いAPI制限は回避(追記)

・UI, UXについては全く工夫してない。

 

↑を文章で書くと・・・

 

ツイッターでも高度な検索を使えば、いろいろと検索できますが、高度な検索は入力文字数が多く、面倒だし、英語のスペル忘れるし(?)、なかなか活用できていないので、pythonでやろうと思い、作りました。

 

バズりそうなツイートを検索したい」と思ったのが事のはじまりで、最新ツイートのうち、RTが50くらいあれば、バズりそうだなぁという考えのもとコードを書きました。

 

スマホから見れないと意味がないのでFlaskとHerokuも使って(一応)Webアプリ(と呼べるのか?)にしました。

 

APIの仕様を詳しく調べてないので詳しくはわからないですが、検索ワードが無いと検索できないっぽかったので、いくつかの助詞を検索ワードにしました。バズるようなツイートは、ある程度長めの文章が多く、ほとんどの場合助詞が含まれているだろうと思ったからです。

 

ただ、実際に検索してみると企業のツイートや芸能人のツイートなど、あまりおもしろくないツイートが多く引っかかってしまったので、画像とURLが含まれているツイートは除くようにしました。

 

すると、本来のツイッターらしい(?)文章だけでRTを稼ぐような面白いツイートをいくつか発掘することに成功しました。

 

しかし、検索にかかる時間がすごい遅いのと、結構すぐにAPI制限かかってしまうのが残念です。(一応API KEYを2つ回すように少し工夫はした)

 

また、herokuは30分(数字はうろ覚え)アクセスが無いと休眠状態に入ってしまうため、30分ぶりにアクセスしようとした人はトップページにすら重くて時間かかると思います。あと、本当はAjaxで検索待ちのときグルグルさせようと思ったのですが、まぁ(実質)自分用だしいいか、といった感じです。

 

バズりのタネのツイートはかなり価値あると思うので、ある程度理想のものが作れて満足です。今後も退屈なことはPythonにやらせようと思います(読んだことない)

 

ぷちばず検索

 

ちなみにソースはこちら

Pythonでスレーターの規則に従い、電子が感じる有効核電荷を計算する

今回は有効核電荷というものをPythonで計算するプログラムを書いてみました。

 

単純なモデルでは原子は以下の図のようにあらわされますね。

 

f:id:short_4010:20180530222026p:plain

 

この図の最外殻の電子は中心に存在する原子核の正電荷をどれくらい感じるのでしょうか。

 

ものすごくシンプルに考えてみましょう。中心の正電荷は +11 となっています。

よって最外殻の電子は +11 の正電荷感じていると考えることが出来ます。

 

しかし、実際には最外殻の電子は、その内側に存在する電子たちにより、正電荷の一部が遮られており、その差分の正電荷感じます。(遮へいされているという)

 

しかもそもそも原子はもっと複雑な形をしていて、注目した電子がどれくらいの正電荷感じているかはそう簡単には計算できません。

 

しかし、比較的当てはまりがよく、おおまかに、ある電子が感じる正電荷の強さを計算する方法としてスレーターの規則というものがあります。ちなみにある電子が感じる電荷のことを有効核電荷と言います。 

 

スレーターの規則は以下のようなルールのことをいいます。(Wikipediaより)

 

まず、電子を主量子数 n に従って昇順、 n が同じ場合は方位量子数  に従ってグループ化し、昇順に並べる(s電子とp電子だけはまとめる)。

[1s] [2s,2p] [3s,3p] [3d] [4s,4p] [4d] [4f] [5s, 5p] [5d] etc.

それぞれのグループについて、そのグループより前のグループに入っている電子の数と軌道の種類に依存した異なる遮蔽定数が与えられる。

それぞれのグループの遮蔽定数は次の三つの寄与の和からなる。

  1. 同じグループにある別の電子の数の 0.35 倍( [1s] グループだけは 0.30 倍)
  2. [s p] 型のグループの場合、そのグループよりも主量子数が1だけ小さいグループの電子数の 0.85倍、主量子数が2以上小さいグループの電子数の1.00倍
  3. [d] 及び [f] 型のグループの場合、そのグループよりも原子に「近い」電子の数の 1.00倍。つまり、 i) 主量子数 n が小さいグループと ii) 主量子数が同じでも方位量子数  が小さいグループの電子数である。表にまとめると、この法則は以下のように表わされる。

 

さて、これをPythonで書いてみました。ググったところ、スレーターの規則をPythonでやってみたという記事は全然出てこなかったので嬉しかったのですが、実際に書いてみると、とてもきれいなコードとは言えず、(というかひどいコード)、全くドヤれないのが残念です。

 

今回は、電子配置が簡単な原子番号1の水素から原子番号36のクリプトンまでを実装しました。一応、電子配置のところさえ書き換えれば、拡張できるように作ったつもりですが、途中からかなり場当たり的に書いていたので、なんかもうそのあたりは何とも言えません。

 

とりあえず、いくつかの入力例を載せてから最後にコードを載せたいと思います。

 

入力例1:

f:id:short_4010:20180530225645j:plain

これより、上の例で挙げたナトリウムの最外殻電子(3s軌道上の電子)が感じる有効核電荷は 2.2 だということがわかります。 +11 とは全然違いますね。

 

入力例2:

f:id:short_4010:20180530225123j:plain

これより、鉄の3d軌道の電子が感じる有効核電荷は 6.25 だとわかります。

 

いくつかの入力でチェックしたつもりですが、バグがあったら教えてくれると嬉しいです。

 

最後にコードです。汚いですが、一応載せておきます。

P.S なぜ「感じる」と表現するのかとても謎です。英語の直訳感がすごいですよね。