*白百合めも*

セキュリティ中心に毎日の勉強の記録を書くよ*

Python3で通信まわりプログラミング❤️

こんにちは〜* 白百合です!🌺
今日は、土曜日に遊んでいたPython3で通信まわりのコードとかを書いていこうと思います(^v^)❤️

Kali linuxにて

$ wing-personal6.0

でWing IDEを起動して、Pythonのコードを書いていくよ♪

Webサイトからテキストを取得する

gettext_fromurl.py

from urllib.request import urlopen

with open("watch_beginner.txt" , "a" , encoding="UTF-8") as file:
    
    with urlopen("http://whitelily6u6.hateblo.jp/") as response:
        
        for line in response:
            line = line.decode("UTF-8")  #バイナリデータをテキストに変換するよ
            
            if "超初心者" in line:  
                file.write(line)
            if "<title>" in line:
                title = line.replace("<title>","").replace("</title>","")
            
print("I got texts from" + title)

(ファイル名やばくない?って思いましたよね...わかってます...命名センスが絶望的にないんです...)

このコードは何をしているかと言うと、
この白百合のブログ内のhtmlを1行1行見ていって、
"超初心者"と書かれた行だけを取得してwatch_beginner.txtというファイルに書き込んでいってます(誰得w)
書き込みが終わったら、I got texts from *白百合めも*(ブログのタイトルを抽出)と表示させてます♪


実行結果↓
f:id:white-lily6u6:20171001212008p:plain
はい!ちゃんと書き込まれてますね!(なんか恥ずかしい...笑)


気になるところだけ見ていきますね*^v^*

1)

from urllib.request import urlopen

urllib.requestモジュールの、urlopenという関数を使いますよーと言ってます🌼
インターネット上のリソースを取得するときは、このモジュールを使います💖

2)

with open("watch_beginner.txt" , "a" , encoding="UTF-8") as file:

with-asによって、何も書かなくてもopenしたものをcloseしてくれます!
以下のコードと同じことだよ♪

try:
    file =  open("watch_beginner.txt" , "a" , encoding="UTF-8")
finally:
    file.close()

1行で書けた方が楽だよね🍫
(with-asの中にさらにwith-as書いちゃったんだけどこれ書き方大丈夫?ちゃんとスマート?Python書いたことない超初心者だからわからないぞ)

また、2番目の引数のaっていうのは、追記で書いていきますよ〜ってこと!
今回は1行1行見ていくのでaにしました〜
普通に上書きしていくときは、wを指定するよ!


TCPクライアント&サーバーでやりとり


お次はsocketというモジュールでTCP通信を行ってみました❤️
クライアント側で0〜2の数字を入れると、脆弱性の名前が返ってくるという謎プログラムですw
サーバー側はtcpserver.py,クライアント側はtcpclient.pyに処理を書きました🌹

流れとしては、
①サーバー側がクライアント側を待ち受ける(listen)
②クライアント側が接続を試みたら(connect)、サーバー側は接続を受け付ける(accept)
③<<コネクション確立>>
④サーバー側からクライアント側に「脆弱性について知りたかったら0〜2の数字を打ってね⭐️」という意の文字列を送信し、表示
⑤クライアント側で0〜2の数字を入力し、サーバー側に送る
⑥サーバー側で「○○が脆弱性の名前を知りたがってるわ」の意の文字列を表示し、その数字に応じて脆弱性の名前をクライアント側に送信
⑦クライアント側で脆弱性の名前を表示
この、⑤〜⑦を"q"と入力するまで続けるって感じです💐

実際書いたコードは以下です↓

tcpserver.py

import socket

HOST = socket.gethostname()
PORT = 9999

serversocket= socket.socket(socket.AF_INET , socket.SOCK_STREAM)
serversocket.bind((HOST,PORT))
serversocket.listen(1)
clientsocket,addr = serversocket.accept()
print("Connected!")
welcommsg = "Type number 0-2 if you want to know about vulnerability."
clientsocket.send(welcommsg.encode("UTF-8"))

while True:
    data = clientsocket.recv(1024).decode("UTF-8")
    
    if data in ["0","1","2"] :
        print(str(addr) + " wants to know the name of vulnerability " + data)
    
    if data == "0":
        msg = "Heartbleed"
    elif data == "1":
        msg = "POODLE"
    elif data == "2":
        msg = "GHOST"
    elif data == "q":
        break
    else:
        msg = "Type number 0-2"
        
    clientsocket.send(msg.encode("UTF-8"))
    
clientsocket.close()


tcpclient.py

import socket

HOST = socket.gethostname()
PORT = 9999

s= socket.socket(socket.AF_INET , socket.SOCK_STREAM)
s.connect((HOST , PORT))
print("Connected!")

while True:
    data = s.recv(1024)
    print(data.decode("UTF-8"))
    data = input('>>> ')
    s.send(data.encode("UTF-8"))
    if data == "q" :
        break
s.close()



実行するとこうなるよ↓
サーバー側
f:id:white-lily6u6:20171002221758p:plain
クライアント側
f:id:white-lily6u6:20171002222008p:plain
はい、可愛い名前がいっぱい返ってきましたね^v^*

では、覚えておきたい部分を見ていこうと思いますーっ
サーバー側の方見てみようかな。
1)

serversocket= socket.socket(socket.AF_INET , socket.SOCK_STREAM)

ここで接続を定義してます🍰
socketモジュールのsocket関数を使っているんだけど、
第1引数がアドレスファミリで、今回はIPv4で通信するのでAF_INETを指定しました🌹
第2引数はソケットの型で、今回はTCPなのでSOCK_STREAMです♪
UDPとかだと、SOCK_DGRAMを指定するよっ

2)

serversocket.bind((HOST,PORT))
serversocket.listen(1)

bind関数によって、HOST:socket.gethostname()PORT:9999をソケットにセットします!
socket.gethostname()の中身は、172.0.0.1127.0.0.1、ローカルホストになってます♪
あとは、listen(1)でクライアントからの接続要求を1つ待っています🍡🍵

3)

clientsocket,addr = serversocket.accept()

ここで、クライアントからの接続を受け付けました❤️
accept()の戻り値は、ソケットと接続先アドレスなので、それぞれ変数に格納しました*


これでコネクションの確立ができたから、
あとは好きにsendとかrecvでデータの送受信して、最後にcloseして終わりだよ♪


参考サイトさま

18.1. socket — 低水準ネットワークインターフェース — Python 3.6.1 ドキュメント

Pythonでネットワークプログラミング(1) - 理想のユーザ・インターフェイスを求めて


ここまで読んでいただいてありがとうございましたー!
もー本当にね、未熟者ですので、ここ違くない?とかあったら教えてくださいね。
ちょっと本読みたい欲が出てきたので、
明日から「今日はこの本読みました!終わり!」って内容になるかもしれないですw
このブログは人に見せる用というよりは自分で見返してこんなことやったなーって振り返る用なので 気楽に書いていこうと思います🍫