Closed8

Python

おしぼりおしぼり
  • strip()は何も指定していないと空白文字を削除する
  • fはフォーマット文字列でbはバイト文字列
    • 通信プログラムを書く時によくbが出てくる
    • hoge = b'huga'hoge = 'huga' + hoge.encode()が等価
    • hoge = 'huga'hoge = b'huga' + hoge.decode()が等価
    • エンコードやデコードはutf-8がデフォルト
  • argparserが便利(Qiitaの記事, 公式
    • 必須引数はargXXで指定
    • オプション引数は--<option-name>で指定.短縮形も指定可能.
    • parser.args.<option-name>で参照できる
    • デフォルト値,型指定,フラグなどもできる
  • sys.stdin.read()で複数行の入力を受け付けることが可能

TCPクライアントの実装

  1. socketオブジェクトを作成
  2. connect((ip, port))でコネクションを確立
  3. send(bytes)でデータを送信
  4. recv(bytes)で受信

TCPサーバーの実装

  1. socketオブジェクトを作成
  2. bind((ip, port))で受け付けIPとポートを指定
  3. listen(最大接続数)で最大接続数を指定
  4. accept()で接続を受け付ける
  5. threading.Thead(target, argc)で接続ごとに別スレッドを作成
  6. start()でスレッドの実行開始
  7. recv(bytes)で受信
おしぼりおしぼり
  • subprocessでPythonコードからシェルを実行できる(参考
    • 同期処理のrunと非同期処理のPopenがある
    • run(..., check=True, stdout=PIPE).stdoutcheck_outputが等価
    • これを使って接続先のサーバーでコマンドを実行できる
  • shlexで簡単にシェル関連の字句解析ができる
    • 例えばsubprocess.run(shlex.split(コマンド文字列), ...)でコマンドを実行可能
  • inputで入力を受け取る(scanfみたいなもの)
  • with文はスコープを限定してオブジェクトを保持したいときに使う
    • 具体的にはファイルなどの使い終わったら解放が必要なものを扱うときに使う
    • with open(filepath) as f:という書き方をする
  • textwrapで表示用のテキストを良い感じに加工できる
  • for x, y in zip(seq1, seq2) で2つのシーケンスオブジェクトを同時にループできる
おしぼりおしぼり
  • chrordでASCII↔文字列の変換ができる
  • joinでiteratableなオブジェクトの文字列要素を結合できる
    • 例えば文字列の配列とか文字列のタプルなど
  • リスト内包表記が便利
  • reprはオブジェクトのデバッグとかに使える
おしぼりおしぼり
  • SSHしたいときparamikoを使って簡単にSSHプログラムを書ける
  • paramikoを使ったSSHクライアントのテストはローカルのsshサービスへ行う
    • username=vagrant, password=vagrant, ip=0.0.0.0, port=22 でいけた
    • sudo systemctl status ssh すればどこでリッスンしているか分かる
    • paramiko.TransportはSSH通信の設定などを行い,実際のやり取りはparamiko.Channelで行うっぽい?
  • SSHリバーストンネリング
    • 仮想マシンでSSHサーバー(192.168.56.101:2222)を立ち上げておいて,ホストでSSHクライアント(192.168.56.1:2222)と転送先サーバー(0.0.0.0:9998)を立ち上げておく(SSHクライアント側にリバーストンネリング機能が必要で,paramikoのrforward.pyを使った).この状態で仮想マシンのブラウザからローカルの2222ポートに接続すると,SSHクライアントを中継して接続がホストの転送先さーばーに転送される.
    • プロミスキャスモードでは同じネットワーク宛のパケットを全て受信する.ここを読む限り,盗聴ホストなどがこのモードで動いていることがある.
    • connect()したときにConnection Refused Exceptionが発生するとき,内部では相手サーバーまたは中継サーバーからICMP port not reachableを受信している.一番多い原因はポート番号が間違っていることで,次に多いのがファイアウォールで拒否されていること.
  • IPレベルで疎通確認するときはpingでOK. ポート指定で疎通確認するならtelnetやnetcatを使う.netcatだと nc -vz <ip> <port> で疎通確認できる.
  • netcatでできることがいくつか書かれているリンク
  • TCPの3ウェイハンドシェイクとPythonでの実装の対応
    1. connect()
    2. accept()
    3. send()
おしぼりおしぼり
  • pingをしてもsnifferのプログラムが動かなかった原因→送信元IPが指定したものになってなかった.pingのデフォルトの送信元IPはどうなるのか調べる.
  • socket.SOCK_RAW でrawソケットを開く.rawソケットではデータリンク層まで含むためEthernetヘッダなどが見れるようになる.
  • プロミスキャスモードでパケットを盗聴しつつ,サブネット内のすべての(存在するか不明な)ホストに適当にUDPパケットを送信して, ICMP code == 3 and ICMP type == 3 なパケットが返ってくれば,そのホストは存在すると分かる.
  • sshするとき,ユーザーはログインするサーバーに事前に公開鍵を登録しておく.サーバー側はログイン要求があったときに,登録されている公開鍵を使ってユーザーを認証する.
  • ホスト鍵は クライアントがサーバーを識別するために使う もの (参考)
  • known_hostsに置かれているのはホスト鍵
  • paramiko.set_missing_host_key_policy ではホストキーが存在しないサーバーに接続するときのポリシーを設定する.AutoAddPolicty()では初回通信時にホスト鍵を受けとってそれをローカルに保存する.
  • paramiko.connectでは認証を行っているが,まだセッションが確立されたわけではない.connectした後にchannelを確立する必要がある.channelの種類はsession, forwarded-tcpip, direct-tcpip, x11 などがある.
おしぼりおしぼり
  • scapyでsniffするときにifaceを指定しないときにどこのifaceが選ばれるのかわからない
  • conf.ifaceを指定しておけばそのifaceが指定される
  • しなかったらどこが指定されているのかはよく分からん
  • EtherARPクラスの補完をvscodeで効かせるにはfrom scapy.layers.l2 import (Ether, ARP) する
おしぼりおしぼり
  • VagrantではデフォルトでNATが有効になる.NATはIPアドレスを変換するので,当然ホストとVMは異なるネットワークに属している.そのため,ホストからブロードキャストでフレームを送信してもVMには届かないし,その逆も同じ.
  • ARPパケットをホストからVMに送信したい場合はブリッジアダプターを使う.
  • VMのeth0(10.0.2.15)をpdstに設定してARPリクエストを送信するとeth1(10.27.68.205)に届く.VMのeth1(10.27.68.205)をpdstに設定してARPリクエストを送信するとeth1(10.27.68.205)に届く.
  • つまり,VMの2つのインターフェース(eth0eth1)宛にARPリクエストを送信すると,どちらもeth1に届く.
おしぼりおしぼり
  • os.listdirはディレクトリ配下のファイルとディレクトリをリスト形式で出力
  • 文字列はlowerupperで大文字や小文字に変換できる.
  • os.joinでパスを結合
  • 値の入っていない変数はNoneで初期化
このスクラップは2023/11/18にクローズされました