pythonとセキュリティ
どうも、糞記事量産予定の人です.
まず、K先輩枠を譲っていただきありがとうございます
私は一応セキュリティ科の人間でして、初回はセキュリティについて書こうかと。
色々な本やサイトを見て勉強したので、少しアウトプットしようかなと思います。
コードが行数を取るので、少し薄くなりそうです。
時間が無いので、できたら理論についてもう少し書くかも
あと、ウイルスに付いて等も加筆するかも。
SecにPythonを使うメリットは幾つかあります。
デメリットについては、正直良くわかりません。
ポインタなどを扱えない所などでしょうか?
一応ゴリ押せば、使えるらしいですが。
後、少々低速であったり、GUIが難しかったり。
概要
Pythonに於いてのセキュリティのお話。
ローカルハックから、グローバルハックを書いていきます。
この記事は一部Scapyを使用する事にします。
ちなみに、基本的にはPython2系を使用します。
Scapyって?
ざっくりいうと、セキュリティに纏わるPythonのモジュールです。
非常に強力で、様々なものに対応しています。
そして、ターミナルやCMDに「scapy」と打ち込むとインタプリタの様な物が出現。
そこで、Scapyを扱うことが出きます。
例えば、パケットを作る場合
Ether()/TCP()/IP()
因みに、Scapyのお勉強はこちらでどうぞ。
www.slideshare.net
Pythonでパケットを盗聴してみよう
パケットを盗聴するのは、別にPythonを使わないといけないわけではないのですが、
言語を使って柔軟に対応するという意味では必要かもしれません。
で、盗聴する場合に前提条件となるのが「プロミスキャスモード」というモードです。
これは、簡単に説明すると「汎ゆる宛先のパケットを受け取る」モードになります。
つまり、これによって本来自分宛てではないパケットを取得します。
コードを見てみましょう。
import socket import os host = "172.168.0.5" if os.name== "nt" : soc_protocol = socket.IPPROTO_IP else : soc_protocol = socket.IPPROTO_ICMP sniffer = socket.socket(socket.AF_INET,socket.SOCK_RAW,soc_protocol) sniffer.bind((host,0)) sniffer.setsockopt(socket.IPPROTO_IP,socket.IP_HDRINCL,1) #プロミスキャスモード有効 if os.name == "nt" : sniffer.ioctl(socket.SIO_RCVALL,socket.RCVALL_ON) print sniffer.recvfrom(65565) #無効 if os.name == "nt" : sniffer.ioctl(socket.SIO_RCVALL,socket.RCVALL_OFF)
取り敢えず、この様な感じで単一パケットを取得できます。
「if os.name == "nt"」の部分は、OSがWindowsであればという処理で、
Linuxとは違う動作をするようなのでこの様な記述をしています。
「sniffer.ioctl」辺りは、プロミスキャスモードのON,OFFをしています。
まあ、あとは見たまんまかな?
これで一応パケットの取得はできるんですが(筈)、なんせこれでは、
1つのパケットしか取得できません。
複数取得しようとすると、ちょっと面倒でコード量がすごいことになるので、
気が向けばGITHUBに上げておきます。
プロキシー使おうぜ
おそらく悪い事をしたいときや、安全にWEBを楽しみたい場合には
プロキシー等が使われると思います
例えば、匿名性がないと行えない操作がある場合や、セキュリティ面での場合。
Pythonでプロキシーを通して、かつリクエストを送信してみようと思います。
因みに、これは余分な部分を削いだ状態で、全体書くの大変だったんですよね。
from __future__ import with_statement import urllib2 #送信パラメーターをセット obj = {"actions" : "param"} #タイムアウト設定の時間 timeout = 0.5 with open('/proxy.txt') as ip_list: for ip in ip_list: proxy = {'http':'http://{0}'.format(ip)} proxy_handler = urllib2.ProxyHandler(proxy) opener = urllib2.build_opener(proxy_handler) urllib2.install_opener(opener) #Request作成 request = urllib2.urlopen(request,timeout=timeout) param = urllib.urlencode( obj ) request = urllib2.Request(url,param) #User-Agentを設定 request.add_header("User-agent", 'Mozilla/5.0') #refererを設定 request.add_header('Referer', 'http://hoge.com') #エンコード方法を設定 request.add_header('Content-Type', 'application/x-www-form-urlencoded') request.add_data(param) try : #URLを開く(送信) request = urllib2.urlopen(request,timeout=timeout) except : print("error")
objが送信するパラメーター部分の定義で、「opener = urllib2.build_opener(proxy_handler)」
この辺りで、プロキシーをぶっ刺しております。
このプログラムは、予めプロキシーをリスト化しておいて、読み込み、リクエストする方式になっています。
後は、URLを開いてパラメーターを送信して〜という単純な流れです。
色々なパスで総当りしようぜ
WEBサーバーのセキュリティで、ファイルなどのパスは非常に重要です。
予期せぬファイルに落とし穴(脆弱性)が潜んでいたり。
そこで、Pythonでパスを総当りして行く事にします。
import urllib2 import threading import Queue import urllib threads = 30 t_url = "http://hogehoge.com" word_dict = "./word.txt" resume = None user_agent = "Mozilla/5.0" #辞書ファイルから読み込む def send_word(word_dict) : with open(word_dict) f_raw_word : raw_words = f_raw_word.read() found_resume = False words = Queue.Queue() for word in raw_words : word = word.rstrip() if resume != None : if found_resume : words.put(word) else: if word == resume : found_resume = True print(word list from %s)%resume else: words.put(word) return words
単純なプログラムで、リストを呼び出してQueueにぶち込んで、総当りしていきます。
で、WEBサイトがダウンしたりした場合に備わっており、Resumeにパスが記憶されています。
因みに、ここでは紹介しきれませんがARPキャッシュポイゾニングや、
データの解析など様々なことができてしまいます。
TCP/IP通信なども簡単に行なえ、機能を組み合わせたら遠隔操作とかも多分簡単にできちゃいます。
ペネトレーションツールなどの作成にも使えそうなので、面白そうです。
以上で、終わります。