あいうえお

あいうえお

pythonとセキュリティ

どうも、糞記事量産予定の人です.
まず、K先輩枠を譲っていただきありがとうございます
私は一応セキュリティ科の人間でして、初回はセキュリティについて書こうかと。
色々な本やサイトを見て勉強したので、少しアウトプットしようかなと思います。
コードが行数を取るので、少し薄くなりそうです。

時間が無いので、できたら理論についてもう少し書くかも
あと、ウイルスに付いて等も加筆するかも。

SecにPythonを使うメリットは幾つかあります。

メリット

  • ネットワークモジュールが充実している。

  • 其の中でも、Scapy等の強力な物がある。

  • CythonでCの機能を呼び出せたりしちゃう

デメリットについては、正直良くわかりません。
ポインタなどを扱えない所などでしょうか?
一応ゴリ押せば、使えるらしいですが。
後、少々低速であったり、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通信なども簡単に行なえ、機能を組み合わせたら遠隔操作とかも多分簡単にできちゃいます。
ペネトレーションツールなどの作成にも使えそうなので、面白そうです。
以上で、終わります。