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関連のイベントがあれば参加しようと思います.

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

Python3メモ - matplotlibでグラフ描画

matplotlibとは

 Matplotlibは、プログラミング言語Pythonおよびその科学計算用ライブラリNumPyのためのグラフ描画ライブラリである。オブジェクト指向APIを提供しており、様々な種類のグラフを描画する能力を持つ。

https://ja.wikipedia.org/wiki/Matplotlib より引用

モジュールのインポート

Anaconda経由でpythonをインストールした場合は以下の通りでインポートできる

from matplotlib import pyplot as plt # 長いのでエイリアス設定

折れ線グラフをプロット(二次関数)

def draw_graph(x,y):
  plt.plot(x,y) # plot関数でプロット
  plt.xlabel("x") # x軸ラベルの設定
  plt.ylabel("y") # y軸ラベルの設定
  plt.title("f(x) = x^2") # タイトルの設定
  plt.axis(ymin=-1000, ymax= 12500, xmin=-150, xmax=150) # x,yの範囲を設定
  plt.show()

 

x = [i for i in range(-100, 101)]
y = list()
for xi in x:
  y.append(xi ** 2)
draw_graph(x,y)

f:id:Szarny:20170715234730p:plain

折れ線グラフをプロット(複数のグラフと凡例の表示)

def draw_graph(x,y1,y2,y3):
  plt.plot(x,y1,x,y2,x,y3,marker="o") # 複数のグラフのプロットとマーカーの設定("o"は黒丸)
  plt.xlabel("date(2017/7/xx)")
  plt.ylabel("maximum temperature")
  plt.title("Weather Forecast")
  plt.axis(ymin=15, ymax=40)
  plt.legend(["Hokkaido","Tohoku","Tokyo"]) # 凡例の設定(リスト形式)
  plt.grid() # グリッド線の表示
  plt.show() 

 

x = [i for i in range(15, 24)]
hok = [33,28,27,24,27,29,30,28,28]
toh = [31,30,33,30,30,31,32,32,31]
tok = [34,34,36,33,32,33,33,34,32]

draw_graph(x,hok,toh,tok)

f:id:Szarny:20170715235246p:plain

 散布図をプロット

import random
x = list()
y = list()
for i in range(100):
  x.append(random.random())
  y.append(random.random())

plt.scatter(x,y)
plt.show()

f:id:Szarny:20170716001830p:plain

 棒グラフ

def bar_chart(data, label):
  N = len(data)
  plt.barh(range(N), data) # 棒グラフの描画
  plt.yticks(range(N), label) # y軸のラベルを設定
  plt.xlabel("Person(100 million)")
  plt.ylabel("Country")
  plt.title("Population")
  plt.show()

data = [13.49, 3.10, 1.26, 0.82]
label = ["China", "America", "Japan", "Deutsch"]
bar_chart(data, label) 

f:id:Szarny:20170716002733p:plain

 ヒストグラムの描画

x = list()
for i in range(1000):
  x.append(random.gauss(0, 10)) # random.gauss(mean, S.D.)
plt.hist(x, bins=100) # ヒストグラムの生成
plt.show() 

f:id:Szarny:20170716003355p:plain

 

Python3メモ - BeautifulSoup4のあれこれ

BeautifulSoupとは

Beautiful Soup is a Python library for pulling data out of HTML and XML files. It works with your favorite parser to provide idiomatic ways of navigating, searching, and modifying the parse tree. It commonly saves programmers hours or days of work.

Beautiful Soup Documentation — Beautiful Soup 4.4.0 documentation より引用

 

 BeautifulSoupのインストールとインポート

pip3 install beautifulsoup4

from bs4 install BeautifulSoup

BeautifulSoupに用いるParserのインストー

pip3 install html.parser

pip3 install lxml

 

BeautifulSoupの簡単な例(アンカータグの抽出)

>>> from bs4 import BeautifulSoup as BS
>>> import requests
>>> page = requests.get("https://www.crummy.com/software/BeautifulSoup/bs4/doc")
>>> soup = BS(page.text, "lxml")

>>> soup.a 
<a accesskey="I" href="genindex.html" title="General Index">index</a>

>>> for anchor in soup.find_all("a"):
...     print("{}({})".format(anchor.string, anchor.get("href")))
...
index(genindex.html)
Beautiful Soup 4.4.0 documentation(#)
¶(#beautiful-soup-documentation)
Beautiful Soup(http://www.crummy.com/software/BeautifulSoup/)
Beautiful Soup 3(http://www.crummy.com/software/BeautifulSoup/bs3/documentation.html)
...

各種の要素の取得・操作等

子要素・親要素・兄弟要素 関連

soup.body.name # bodyのタグ名を返却

 

soup.body.contents #  bodyの子要素をリスト形式で返却

soup.body.children # bodyの子要素をジェネレータ形式で返却

 

soup.body.descendants # bodyの子要素をジェネレータ形式で再帰的に返却

soup.body.strings # bodyの子要素に含まれる文字列全てをジェネレータ形式で返却

 

soup.title.parent # titleの親要素全体を取得

soup.title.parents # titleの親要素を再帰的に取得(BeautifulSoupオブジェクトに行きつくと終了)

 

soup.p.next_sibling # 最初のp要素の次の兄弟要素を取得

soup.p.previous_sibling # 最初のp要素の前の兄弟要素を取得

 

soup.p.next_element # 最初のp要素の次の兄弟要素を取得(要素内も順次取得)

soup.p.previous_sibling最初のp要素の前の兄弟要素を取得(要素内も順次取得)

 検索(find, find_all, select)

soup.find("a") # 最初のa要素を検索

soup.find_all("a") # a要素をリスト形式ですべて取得
# soup("a") ... find_allは省略可能

soup.find_all("a",limit=5) # a要素をリスト形式で5個まで取得

soup.find_all(["a","p"]) # p要素とa要素をリスト形式ですべて取得

soup.find_all(text="piyo") # 要素内に指定文字列を持つ要素を取得

 

def my_filter(t):
    return t.has_attr("id")

soup.find_all(my_filter) # 自作フィルターの利用

 

soup.find_all(id="hoge") # キーワード引数を用いた検索

soup.find_all(attrs={"id":"hoge", "class":"huga"}) # 辞書を用いた複数条件の検索

soup.p.find_all_next() # 最初のp要素以降の要素をすべて取得(再帰的)

soup.p.find_all_previous() # 最初のp要素以前の要素をすべて取得(再帰的)

 

soup.select("#hoge") # idにhogeを持つ要素をCSSセレクタ記法で取得

soup.select(".huga") # classにhugaを持つ要素をCSSセレクタ記法で取得

要素の変更・追加

soup.p.name = "h1" # 最初のp要素をh1要素に変更

soup.p.string = "piyo" # 最初のp要素内をpiyoに変更

soup.p.append("huga") # 最初のp要素内にhugaを追加

soup.p["id"] = "hoge" # 最初のp要素のidをhogeに変更

del soup.p["class"] # 最初のp要素のclass属性を削除

 

soup.body.append(soup.new_tag("p")) # body要素の最後尾にp要素を追加

soup.p.insert_after(soup.new_string("hoge")) # 最初のp要素の直後にhoge文字列を追加

 

soup.p.clear() # 最初のp要素内のコンテンツを削除

soup.p.extract() # 最初のp要素を抽出し返却(抽出されたp要素は削除される)

soup.body.decompose() # body内の要素を全削除

 

soup.p.wrap(soup.new_tag("div")) # 最初のp要素をdiv要素で包む

soup.p.unwrap() # 最初のp要素のタグを外す(返却値はタグ)

 

Python3メモ - Web関連

requestsモジュールを用いたWebコンテンツへのアクセス

>>> import requests

>>> req = requests.open("https://www.google.com")

>>> for k,v in req.headers.items():

...        print("[{}]{}".format(k,v))

[Date]Mon, 10 Jul 2017 04:10:28 GMT

[Expires]-1

[Cache-Control]private, max-age=0

...

>>> print(req.text)
b'<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="ja"><head><meta content="\x90\xa2\x8aE...

 

Web Server

PythonのWebフレームワークを用いることで,リクエストとレスポンスといった基本的な処理から,URLルーティング・動的ページ生成・セッション管理といった複雑な処理まで行うことができる.

Bottle

from bottle import run, route, static_file

 

@route("/")
def root():
return static_file("index.html", root=".")

 

@route("/<yourname>")
def yourname(yourname):
return "Hello! {}".format(yourname)

 

run(host="localhost", port=9999)

 Flask

from flask import Flask, render_template, request

app = Flask(__name__)

 

@app.route("/")
def main():
    return app.send_static_file("index.html")

 

@app.route("/echo/<arg1>/<arg2>")
def echo(arg1, arg2):
    k = {}
    k["path1"] = arg1
    k["path2"] = arg2
    k["get1"] = request.args.get("get1")
    k["get2"] = request.args.get("get2")
    return render_template("template.html", **k)

app.run(port=9999, debug=True)

template/template.html

<html>
<head><title>Flask</title></head>
<body>
<p>path1: {{path1}}</p>
<p>path2: {{path2}}</p>
<br>
<p>GET1: {{get1}}</p>
<p>GET2: {{get2}}</p>
</body>
</html>

 

Webスクレイピング

BeautifulSoup

def get_links(url):
    import requests
    from bs4 import BeautifulSoup as soup

    html = soup(requests.get(url).text)
    links = [element.get("href") for element in html.find_all("a")]
    return links


url = input("URL : ")
for i, link in enumerate(get_links(url), start=1):
    print(i,link)

 

参考文献 : 入門Python3 O'REILLY

Python3メモ - 文字列関連

 Python3の忘れそうな文字列関連のメソッド等々についてのメモ

  • string.find(word)
    string内において,最初にwordが出現する位置を返す
    >>> alphabet = "abcdefghijklmnopqrstuvwxyz"
    >>> alphabet.find("k")
    10

  • string.replace(str1, str2, time)
    string内のstr1をstr2へ最大time回置換する
    >>> greeting = "Good Morning, Good Evening, Good Night"
    >>> greeting.replace("Good", "Bad", 2)
    'Bad Morning, Bad Evening, Good Night'


  • string内の一部を変更する
    stringはimmutableなオブジェクトなので,直接変更はできない

    >>> text = "Hello morld"
    >>> text[6] = "w"
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    TypeError: 'str' object does not support item assignment

  • 解決法1 : listに一旦変換して変更する
    >>> text = "Hello morld"
    >>> text_list = list(text)
    >>> text_list[6] = "w"
    >>> text = "".join(text_list)
    >>> text
    'Hello world'
  • 解決法2 : スライスを用いる

    >>> text = "Hello morld"
    >>> text = text[:6] + "w" + text[7:]
    >>> text
    'Hello world'