主にプログラミングに関して。Python, .NET Framework(C#), JavaScript, その他いくらか。
記事にあるサンプルやコードは要検証。使用に際しては責任を負いかねます

スポンサーサイト

                
tags:
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

DockerでSQLインジェクションを試せるイメージを用意する

                
 今となってはいろいろ対策の手が打たれているが、それでも知識もなくWebアプリを作るとうっかりできてしまうことがあるSQLインジェクション。どんな立場からどんな攻撃ができうるかを示すために、脆弱性を持ったWebアプリを作ってみようと考えた。
 それを使って脆弱性をつついてもらうデモにしたい。つついてもらったらデータベースに変更が入る。そうしたら別の人に試してもらうにはリセットが必要となる。もろもろの環境リセットが簡単にできるとデモとして最高。そういうわけでDockerイメージとして脆弱性を持ったWebアプリをすぐ実行できるものを用意する。


 Webアプリ部分はどんなものにするか。とりあえずすごく簡単なものにしておく。アクセスしてきたクライアントにフォームを返す。フォームに名前を入力してPostする。フォームに入力された名前がデータベースにあれば、実行されたクエリ文とその名前が表示される。入力された名前がデータベースになければエラー文が表示される。以上のものをPythonで書いた。
1601241839287.jpg
1601241839493.jpg
1601241840245.jpg
 「John」とポストするだけなら問題ない。「John"; SELECT * FROM employees;DROP TABLE employees;"」などとポストされるとJohnの登録されていたテーブルが落ち、以降はJohnと入力してもデータベースにそもそもテーブルがないためエラーとなる。


Dockerfileは以下。
FROM ubuntu

RUN apt-get update && apt-get -y install nginx && \
apt-get install -y supervisor && \
apt-get install -y python3-pip && \
pip3 install gunicorn && \
pip3 install tornado

RUN apt-get install -y mysql-server

RUN echo "daemon off;" >> /etc/nginx/nginx.conf
RUN rm /etc/nginx/sites-enabled/default
ADD hello.conf /etc/nginx/conf.d/
RUN /etc/init.d/nginx reload

ADD * /usr/
WORKDIR /usr/
RUN dpkg -i mysql-connector-python-py3_2.1.3-1ubuntu14.04_all.deb
RUN /etc/init.d/mysql start && \
mysql < init.sql

EXPOSE 80
CMD /usr/bin/supervisord -c supervisord.conf

 Python製Webアプリ、MySQL、NginXはsupervisordでコントロールにした。PythonのMySQLConnectorはpipインストール設定が手間だったのでdebパッケージを落としてきてdpkgコマンドインストールにした。

 その他ファイルの設定はGithubにて公開中。
https://github.com/hMatoba/SQLInjection-DockerSample

 上記のDockerfileがあるディレクトリでビルドを実行する。
> docker build -t matoba/sql_injection ./
 
 ついでにどこからでもダウンロードできるようにプッシュしておく。
> docker push matoba/sql_injection

 イメージをダウンロードし、そこからコンテナを立ち上げて試してみる。
> docker pull matoba/sql_injection
> docker run -d -p 80:80 --name sql_inj matoba/sql_injection
1601241927297.jpg


 動いているので問題なし。あとはデータベースを含めたWebアプリ部分をもうちょっとまともにする。今のままでも試すことはできるが、かなり最低限に絞っているので試した人のインパクトは小さいだろう。
 Dockerのおかげで、いつでも使い捨てができる手軽なSQLインジェクションの脆弱性を持ったWebアプリデモが簡単に用意できるようになった。
 
スポンサーサイト

AppVeyorを使ってWindowsでPythonプロジェクトのCI

                
tags: python CI
 GithubでCIといったらTravisCIと連携がポピュラーだと思う。TravisCIで環境として用意されてるのはUbuntuとOSX。
 WindowsでもPythonが使えることが近年はプッシュされている。VisualStudioではPython導入のツールが用意され、Django、Flaskなど有名フレームワークでWebアプリを作るテンプレートがある。それを作ったらAzureでホスティングとか。
 そういうわけでPythonを書いたらUbuntuやOSXだけでなく、WindowsのCI環境も欲しいよねというときにAppVeyor

 下の画像はデフォルト状態でlsコマンドでC:/直下のディレクトリを表示したものである。今回使うPythonはもちろん、RubyやGoも用意されているし、データベースとしてMongoDBも入っている。Windowsだからといって決してMS製品のみへ特化しているわけではなさそう。
1510061945253.jpg


 Github連携はどう使えばいいかというとTravisCIと同様である。GithubアカウントとのOAuth接続を許可し、マイページの自分のリポジトリ一覧から連携したいものをオンにする。あとはプロジェクトのルートにappveyor.ymlを置いてコミット、それをGithubサーバーへ送れば自動でappveyor.ymlの内容に沿ってビルドが始まる。

 GithubリポジトリからPythonで最小限のことをやっていそうなappveyor.ymlを探した。
https://github.com/jkbrzt/httpie/blob/master/appveyor.yml
 参考になるものを得て書いた自分のPythonプロジェクト用のappveyor.ymlが下記である。テスト用にPythonライブラリであるpillowが必要なプロジェクトになっている。
init:
- ECHO %PYTHON%
environment:
matrix:
- PYTHON: C:/Python27-x64
- PYTHON: C:/Python34-x64
- PYTHON: C:/Python33-x64

install:
- ECHO "Filesystem root:"
- ps: "ls \"C:/\""

- ECHO "Installed SDKs:"
- ps: "ls \"C:/Program Files/Microsoft SDKs/Windows\""

- ps: (new-object net.webclient).DownloadFile('https://raw.github.com/pypa/pip/master/contrib/get-pip.py', 'C:/get-pip.py')
- "%PYTHON%/python.exe C:/get-pip.py"
- "%PYTHON%/Scripts/pip.exe install pillow==2.9.0"

test_script:
- '%PYTHON%\python.exe setup.py test'


 まずinitで初期化設定を行っている。といっても特にやることはなくて、テストするPythonのバージョンの表示を行っている。これは次に行うenvironmentの次に書けば良かったかも。
 initの下にあるenvironmentではビルドテストを行う環境を指定している。Pythonの複数のバージョンで使えるものを書いたので、複数のPython環境を指定している。ビルドテストはそれぞれのPython環境で行われることになる。
 installでは文字通り必要なもののインストールを行っている。今回必要なのは実は下から三行のみである。そこでpipをインストール、さらにそれを使ってpillowをインストールしている。
 test_scriptではテストコマンドを書いている。

 テストが通るとバーが緑色になる。
1510062016444.jpg

 Github連携でおなじみのバッジもある。デフォルトではTravisCIと似たようなバッジが得られるが、それと差別化してshields.ioを通して下記のようなバッジに変換しているケースが多かった。
1510062017480.jpg
https://img.shields.io/appveyor/ci/[your AppVeyor ID]/[repositry name].svg?label=windows%20build

Docker: Docker + supervisor + NginX

                
tags: Docker python
 前回はDocker + NginxでPythonのWebアプリを走らせた。
http://elicon.blog57.fc2.com/blog-entry-460.html
 前回作ったものはコンテナを走らせてからNginXを追加コマンドで走らせていた。どうせならコンテナを走らせればNginxとPythonスクリプトが起動して、Webアプリとしても動作してくれるとありがたかったのだが、NginXが基本的にデーモンプロセスで実行なことなどでそうなっていた。今回はそれをsupervisorを使って解消し、コンテナを走らせれば追加コマンドなしでWebアプリとして動作するようにコンテナを作る。

 前回からWebアプリのPythonスクリプトhello.pyと、NginXの設定ファイルhello.confをそのまま持ってくる。あとsupervisor設定ファイルsupervisord.confを用意する。
 
 Dockerfileとsupervisor.confは以下。
FROM ubuntu

RUN apt-get update && apt-get -y install nginx && \
apt-get install -y supervisor && \
apt-get install -y python3-pip && \
pip3 install gunicorn && \
pip3 install tornado

RUN echo "daemon off;" >> /etc/nginx/nginx.conf
RUN rm /etc/nginx/sites-enabled/default
ADD hello.conf /etc/nginx/conf.d/
RUN /etc/init.d/nginx reload

ADD . /usr/
WORKDIR /usr/

EXPOSE 80
CMD /usr/bin/supervisord -c supervisord.conf


[supervisord]
nodaemon = true

[program:nginx]
command = nginx

[program:hello_app]
command = gunicorn hello:wsgi_app


 上記のファイルを用意した状態で下記二行を実行すればsupervisorによってNginXとPythonWebアプリの両方が起動している。http://192.168.59.103/へアクセス。
docker build -t b3_tmp ./
docker run -d -p 80:80 --name b3 b3_tmp

1507290936497.jpg

Dockerを使ってLinuxサーバにのっけるWebアプリをWindowsで開発する

                
tags: python Docker
 MSのIDEであるVisualStudioではPythonやNode.js開発を可能にするツール類もリリースされており、VisualStudioをコーディングに使うことを考える。VisualStudioでコーディングをしてそのWebアプリを仮想マシンのLinuxで走らせてデバッグを行いたい。それがそれほどの手間にならずに行えたらコーディングにVisualStudioを使うのを一つの選択肢に入れようかという気になってくる。そこでDockerを使う。ASP.NETもLinux対応が始まっている。ASP.NETといえば開発はVisualStudioを使うのが標準だろうから、Linuxサーバで動かすASP.NETアプリをWindows上のVisualStudioで開発という話はやっぱり出てくるだろう。
 Linuxサーバで動かすWebアプリをWindows上で書いてしまう。こんなことをする一定の価値はあるはず。

 Windows上で書いたWebアプリをコンテナとして用意したLinuxサーバで簡単にデバッグできるかやってみる。DockerでWebアプリを動かすというのは前にもやっているが、イマイチ手順が整理できてなかったので改めて。

 まずはWebアプリの用意から。簡単なサンプルをPythonで用意。"/"にアクセスすると"Hello."を返すだけのもので、Gunicorn + nginxで動かす。これhello.pyとしてプロジェクトのディレクトリ内に配置。
import os

import tornado.web
import tornado.wsgi


class HelloHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello.")


settings = {
"static_path": os.path.join(os.path.dirname(__file__), "static"),
}

application = tornado.web.Application([
("/", HelloHandler),
], **settings)

wsgi_app = tornado.wsgi.WSGIAdapter(application)

あとnginx設定ファイルとしてhello.confというファイルも作って同様に配置しておく。
server {
listen 80 default;
server_name example.org;
access_log /var/log/nginx/example.log;

location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}


 適当過ぎるWebアプリが用意できたので、WindowsにBoot2Dockerを入れてコマンドラインを立ち上げる。ここからはDockerの操作。
 Dockerを使うにあたってイメージとコンテナという二つの概念がある。イメージがクラスでコンテナがインスタンスと考えられるかもしれない。OSイメージからコンテナをつくる、実際に環境として動くのが作られたコンテナの方。
 Boot2Dockerで立ち上げたコマンドラインにDockerコマンドを入れていく。

docker pull ubuntu:latest
ubuntuイメージを用意。今回はサーバとしてubuntuを使うことにしておく。

docker run -it --name [new container name] ubuntu bash
ubuntuイメージを利用してコンテナを作成、同時に作成したコンテナでbashをとりあえず実行。

(作成したコンテナ内)
apt-get update;apt-get install -y nginx;rm /etc/nginx/sites-enabled/default;apt-get install -y python3-pip;pip3 install gunicorn;pip3 install tornado;
Webアプリサーバにするのに必要なソフトやライブラリをコンテナ内で用意。

ctrl + dでコンテナから抜ける

docker commit [container name] [new image name]
前までで使いまわしたい構成がコンテナとして用意できた。さらにその前でイメージからコンテナを作成したことからわかるように、コンテナのままでは同じ構成、状態を使いまわせず、コンテナを一旦イメージとしてコミットしておく必要がある。コミットが終了したらそのコンテナは用済み。

cd /c/Users/john/hello
hello.pyを保存してあるディレクトリへ移動(WindowsのパスをUNIX風に書き換えるc:\→/c/)。そこにコンテナ内で実行したいコマンドを列記したDockerfileを用意しておく。コマンドとしてはWebアプリを立ち上げるもの。Dockerfileの中身はあとに載せておく。

******
docker build -t [new image name] ./
Dockerfileをもとに新しいイメージをビルド。ここでWindowsで作っておいたプロジェクトのファイルをもろもろ、さっき必要なソフトをインストールしたコンテナから作成したイメージ内にコピーしたりソフトの設定したり。

docker run -d -p 80:80 --name [container name] [image name]
イメージからコンテナを用意して走らせる。

docker exec [container name] nginx
nginxをコンテナ内で走らせる。

Windowsのブラウザでhttp://192.168.59.103へアクセス。"Hello."が返ってくることを確認する。
15070302291312.jpg


******

Webアプリの立ち上げを含めたコンテナの用意ができているので、これを手軽に反復できるようにする。******~******内で使用しているdockerコマンドをshファイルにまとめる。ここではhello.shという名前にしておく。コンテナは作成時に指定の名前のものがすでに存在する場合は作成が実行されない。それを回避するためにすでに存在するコンテナを削除するためのコマンドも追加しておく。
cd /c/Users/foo/py_web
docker stop [container name]
docker rm [container name]
docker build -t [new image name] ./
docker run -d -p 80:80 --name [new container name] [image name]
docker exec b2 nginx


 hello.pyをちょっと書き換えてみる。返す文字列を"Hello."から"Hello, again."へ。

 Webアプリの書き換えを行ったので"sh hello.sh"を実行してLinuxサーバを再度立ち上げなおし、ブラウザでまたhttp://192.168.59.103へアクセスして返ってくる文字列をチェックする。おおよそ10秒ほどでコンテナが立ち上がり、アドレスへのアクセスが可能になった。
1507030230089.jpg


 このhello.shをDocker上で実行、終了後のお掃除をするためのコマンドを書いたバッチファイルを用意するのもいいかもしれない。
@echo off
boot2docker ssh sh [project directory]/hello.sh
echo Server is running. http://192.168.59.103/
echo Press any key to stop server.
pause > NUL
echo Removing container...
boot2docker ssh docker stop [container name]
boot2docker ssh docker rm [container name]
pause


 Dockerを使うことでWindowsから手軽にLinuxサーバのWebアプリを立ち上げることができた。今回の使い方においてはGUIありの仮想マシーンを使うよりだいぶテンポよくWindows上でLinuxサーバのWebアプリを立ち上げられそうであり、デバッグに使えそうである。


今回のDockerfileの中身
******
FROM [image name]

ADD . /usr/
WORKDIR /usr/
EXPOSE 80
RUN cp hello.conf /etc/nginx/conf.d/
RUN /etc/init.d/nginx reload
CMD gunicorn hello:wsgi_app
******
ADDは指定ファイルを指定ディレクトリへコピー
WORKDIRはワーキングディレクトリの指定(cdコマンドでは行わない)
EXPOSEで待ち受けポートの指定
あとはコマンド実行である

.NET Framework: スクショデスクトップアプリ

                
”たとえばこのUIをWindowsで実装しようとすると、千行近いコードをCか何かで書かなければならず”
http://qiita.com/uiureo/items/0353e37bcffe94731c6b
 一部で話題になっているQiitaの記事。Node.jsだったかそのフォークのio.jsかで透明なウィンドウを使ったUIのクロスプラットフォームのデスクトップアプリを作れるという話。で、その本文にある上記の文がツッコミを受けている。

 ぼくもWindows上でのみの動作だがスクショを撮るためのデスクトップアプリを作ったことがある。
15052401.jpg
 アプリケーションを起動すると黒い半透明ウィンドウが出てきて、このウィンドウをドラッグしてスクショを撮りたいところの真上にもっていってShotボタンを押せばいいようになっている。ウィンドウ右下のサム要素でサイズが変えられるようになっている。

 件の記事でやっていることと比較するとデスクトップアプリに半透明ウィンドウを使っているあたり似ていると思う。そんなデスクトップアプリは”Cか何か”ではなく、Web系でもよく使われているPython(厳密には.NET Frameworkで走るIronPython)で書き、タイマーや取得画像のサイズ調整などの機能まで含めて100行程度、UI部分はXMLベースのXAMLで160ほどだった。C#で書いてもUI部分に変更はないし、コード部分で変数に宣言を加え、ブロックにブラケットを適用していくぐらいだろう。

 クロスプラットフォームではないという問題は、実行を.NETからMonoにゆだねて、UI部分をWPFからGTK#にすればクリアできるだろう。GTKで透過ウィンドウを使ってデスクトップに適当な形の要素を表示というのはやったことがある。
http://elicon.blog57.fc2.com/blog-entry-45.html
http://elicon.blog57.fc2.com/blog-entry-20.html
 要は最初からWPFではなくGTK#で書いておけば、VisualStudioでビルドした.exeだろうとLinuxやMacにそのまま持ち込んで実行できるということだ。これがあまり流行ってるように見えないのは、そっち方面でそういう需要が少なくて、一つのOSでしっかり動けばそれで十分なことが多いんだろう。

 VisualStudioでPythonやJavaScript開発をするツールがリリースされている。Web系の発展のスピードが目覚ましいかもしれないが、MSやその周辺ではそれをうまくそれを取り込もうとしている様子が見られる。その上でPCアプリ開発者というのは規模や実績、安定性に合わせて言語を選んでいるのではと思う。
プロフィール

h

Author:h

最新記事
リンク
作ったものなど
月別アーカイブ
カテゴリ
タグリスト

検索フォーム
Amazon
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。