47
Ctfのための python ruby入門 ひげ

Ruby4Ctf

Embed Size (px)

Citation preview

Page 1: Ruby4Ctf

Ctfのための

python ruby入門ひげ

Page 2: Ruby4Ctf

尊敬すべき元ネタ

「Ctfのためのpython入門」http://www.slideshare.net/shiracamus/ctfpython

Page 3: Ruby4Ctf

勝手にパロディましたすいません

Page 4: Ruby4Ctf

自己紹介

Page 5: Ruby4Ctf

いろんなプログラミング言語

さわる人(Rubyとか)

Page 6: Ruby4Ctf

最近Python

さわり始めた人

Page 7: Ruby4Ctf

最近CTF始めた人

Page 8: Ruby4Ctf

「Ctfのためのpython入門」

に出会う

Page 9: Ruby4Ctf

Pythonで行けるなRubyでもいけるのでは?

Page 10: Ruby4Ctf

調べたのでまとめます

Page 11: Ruby4Ctf

CTFあるある

Page 12: Ruby4Ctf

数値 文字

巨大整数演算

エンコード・デコード

ハッシュ関数

Page 13: Ruby4Ctf

Rubyもできます!(pythonの方が楽な気がするけど)

Page 14: Ruby4Ctf

Rubyを使うには

Page 15: Ruby4Ctf

www.ruby-lang.org

から

ダウンロード

インストール

Page 16: Ruby4Ctf

Rubyのバージョン

Page 17: Ruby4Ctf

新しいのを使おう!(現在 2.2.2)

Page 18: Ruby4Ctf

早速使ってみよう!

Page 19: Ruby4Ctf

インタープリタの起動と終了

sh $ irb

irb> exit

sh $

sh $ ruby <filename>

Rubyスクリプトファイルを実行する方法

※ irb は Ruby で書かれているRubyインタープリタなんだ!

Page 20: Ruby4Ctf

電卓として使う

irb> 1 + 2 * 3 - 10 / 3

=> 4

irb> 1 << 16

=> 65536

irb> 5 ** 1024

=> 556268464626...12890625

irb> 0xca ^ 0xfe

=> 52

irb> 'A' * 16 + '¥x86¥x64¥xca¥xfe'

=> "AAAAAAAAAAAAAAAA¥¥x86¥¥x64¥¥xca¥¥xfe"

四則演算

ビットシフト

べき乗

(Bignum : 長整数)

XOR(排他的論理和)

Page 21: Ruby4Ctf

電卓として使う

irb> 'A' * 16 + '¥x86¥x64¥xca¥xfe'

=> "AAAAAAAAAAAAAAAA¥¥x86¥¥x64¥¥xca¥¥xfe"

¥x64 は ASCIIコードで ‘ d ’ のはず

なぜ変換されないのか?(ちなみにPythonではされる)

Page 22: Ruby4Ctf

電卓として使う

実は原因はシングルクォートにある

Rubyはシングル・ダブルクォートで動作が違う

•ダブルクォーテーション•バックスラッシュ記法が使える•式展開される

•シングルクォーテーション•バックスラッシュ記法が使えない•式展開されない

Page 23: Ruby4Ctf

10進数

irb> 123

=> 123

irb> 123.to_s

=> "123"

irb> '123'.to_i

=> 123

irb> ‘%d’ % 123

=> “123”

irb> '%8d, %08d' % [123, 123]

=> " 123, 00000123"

String クラスの % 演算子

タプル 配列

Page 24: Ruby4Ctf

16進数

irb> 123.to_s(16)

=> "7b"

irb> 0x7b

=> 123

irb> '7b'.to_i(16)

=> 123

irb> '0x7b'.hex

=> 123

irb> '%-8x, %08x' % [123, 123]

=> "7b , 0000007b"

Page 25: Ruby4Ctf

8進数

irb> 123.to_s(8)

=> "173"

irb> '173'.to_i(8)

=> 123

irb> '0173'.oct

=> 123

irb> puts "%o¥n%06o" % [123, 123]

173

000173

=> nil irb は入力した式の評価結果を返す

Page 26: Ruby4Ctf

2進数

irb> 123.to_s(2)

=> "1111011"

irb> '1111011'.to_i(2)

=> 123

irb> '0b1111011'.to_i(2)

=> 123

irb> sprintf('%b', 123)

=> "1111011"

irb> sprintf('%016b', 123)

=> "0000000001111011"

binメソッドはない

Page 27: Ruby4Ctf

文字

irb> 'A'.ord

=> 65

irb> 65.chr

=> "A"

irb> 65.to_s(16)

=> "41"

irb> (0x41 + 1).chr

=> "B"

Page 28: Ruby4Ctf

文字列/配列(リスト)

irb> 'abc'.split('')

=> ["a", "b", "c"]

irb> 'abc'.split('').map{|c| c.ord}

=> [97, 98, 99]

irb> [97, 98, 99].map{|x| x.chr}

=> ["a", "b", "c"]

irb> 'abc'.split('').map{|c| c.ord.to_s(16)}

=> ["61", "62", "63"]

irb> ['a', 'b', 'c'].join

=> "abc"

Ruby の String は chr の配列ではない

Ruby の map はめんどくさい

でも、重ねがけが楽

Page 29: Ruby4Ctf

部分文字列

irb> 'abcdefg'[0]

=> "a"

irb> 'abcdefg'[-1]

=> "g"

irb> 'abcdefg'[1, 3]

=> "bcd"

irb> 'abcdefg'[3..-1]

=> "defg"

irb> 'abcdefg'[3...-1]

=> "def"

先頭

末尾

1番目から3文字分

3番目から末尾まで

ただし、末尾を含む

コッチは含まない

Page 30: Ruby4Ctf

文字列分割・連結

irb> '83 69 67 67 79 78'.split()

=> ["83", "69", "67", "67", "79", "78"]

irb> '53:45:43:43:4f:4e'.split(':')

=> ["53", "45", "43", "43", "4f", "4e"]

irb> [83, 69, 67, 67, 79, 78].join(' ')

=> "83 69 67 67 79 78"

irb> ['53','45','43','43','4f','4e'].join(':')

=> "53:45:43:43:4f:4e"

Page 31: Ruby4Ctf

CTF過去問

CSAW CTF 2011 Crypto1

87 101 108 99 111 109 101 32 116 111 32 116 104 101 32 50

48 49 49 32 78 89 85 32 80 111 108 121 32 67 83 65 87 32 67

84 70 32 101 118 101 110 116 46 32 87 101 32 104 97 118

101 32 112 108 97 110 110 101 100 32 109 97 110 121 32 99

104 97 108 108 101 110 103 101 115 32 102 111 114 32 121

111 117 32 97 110 100 32 119 101 32 104 111 112 101 32 121

111 117 32 104 97 118 101 32 102 117 110 32 115 111 108

118 105 110 103 32 116 104 101 109 32 97 108 108 46 32 84

104 101 32 107 101 121 32 102 111 114 32 116 104 105 115

32 99 104 97 108 108 101 110 103 101 32 105 115 32 99 114

121 112 116 111 103 114 97 112 104 121 46

解法

10進数のASCIIコードなので数字から文字に変換

Hint: map method

https://ctf.isis.poly.edu/static/archives/2011/challenges.php.html

Page 32: Ruby4Ctf

CTF過去問

CSAW CTF 2011 Crypto2

54:68:69:73:20:69:73:20:74:68:65:20:66:69:72:73:74:20:6d:65:73:73:6

1:67:65:20:62:65:69:6e:67:20:73:65:6e:74:20:74:6f:20:79:6f:75:20:62:7

9:20:74:68:65:20:6c:65:61:64:65:72:73:68:69:70:20:6f:66:20:74:68:65:

20:55:6e:64:65:72:67:72:6f:75:6e:64:20:55:70:72:69:73:69:6e:67:2e:20

:49:66:20:79:6f:75:20:68:61:76:65:20:64:65:63:6f:64:65:64:20:74:68:69

:73:20:6d:65:73:73:61:67:65:20:63:6f:72:72:65:63:74:6c:79:20:79:6f:75

:20:77:69:6c:6c:20:6e:6f:77:20:6b:6e:6f:77:20:6f:75:72:20:6e:65:78:74:

20:6d:65:65:74:69:6e:67:20:77:69:6c:6c:20:62:65:20:68:65:6c:64:20:6f

:6e:20:57:65:64:6e:65:73:64:61:79:20:40:20:37:70:6d:2e:20:57:65:20:7

7:69:6c:6c:20:61:6c:73:6f:20:72:65:71:75:69:72:65:20:61:20:6b:65:79:

20:74:6f:20:62:65:20:6c:65:74:20:69:6e:74:6f:20:74:68:65:20:6d:65:65:

74:69:6e:67:73:3b:20:74:68:69:73:20:77:65:65:6b:1f:73:20:6b:65:79:20

:77:69:6c:6c:20:62:65:20:6f:76:65:72:74:68:72:6f:77:2e

解法

16進数のASCIIコードなので16進数から10進数に直して文字に変換

https://ctf.isis.poly.edu/static/archives/2011/challenges.php.html

Page 33: Ruby4Ctf

CTF過去問

CSAW CTF 2011 Crypto3

01001100011000010111001101110100001000000111011101100101011001010110101101110011001000000110110101100

10101100101011101000110100101101110011001110010000001110111011000010111001100100000011000010010000001

10011101110010011001010110000101110100001000000111001101110101011000110110001101100101011100110111001

10010111000100000010101110110010100100000011100110110010101100101011011010010000001110100011011110010

00000110001001100101001000000110011101100101011011100110010101110010011000010111010001101001011011100

11001110010000001100001001000000110110001101111011101000010000001101111011001100010000001100010011101

01011110100111101000100000011000010110001001101111011101010111010000100000011101000110100001100101001

00000011011010110111101110110011001010110110101100101011011100111010000101110001000000101010001101000

01100101001000000110101101100101011110010010000001100110011011110111001000100000011011100110010101111

00001110100001000000111011101100101011001010110101101110011001000000110110101100101011001010111010001

10100101101110011001110010000001101001011100110010000001110010011001010111001101101001011100110111010

00110000101101110011000110110010100101110001000000100100101100110001000000111010001101000011001010111

00100110010100100000011010010111001100100000011000010110111001111001011011110110111001100101001000000

11001010110110001110011011001010010000001111001011011110111010100100000011010110110111001101111011101

11001000000110111101100110001000000111010001101000011000010111010000100000011011010110000101111001001

00000011000100110010100100000011010010110111001110100011001010111001001100101011100110111010001100101

01100100001000000110100101101110001000000110101001101111011010010110111001101001011011100110011100100

00001100010011100100110100101101110011001110010000001110100011010000110010101101101001000000111010001

10111100100000011101000110100001100101001000000110110101100101011001010111010001101001011011100110011

10010000001110100011010000110100101110011001000000111011101100101011001010110101100101110001000000100

10010111010000100000011101110110100101101100011011000010000001100010011001010010000001101000011001010

11011000110010000100000011100110110000101101101011001010010000001110100011010010110110101100101001011

00001000000111001101100001011011010110010100100000011100000110110001100001011000110110010100101110

解法

2進数のASCIIコードなので8桁ずつ分割して前と同じ

n文字で分割する: ‘ irb> text.scan(/.{1,#{n}}/) ’https://ctf.isis.poly.edu/static/archives/2011/challenges.php.html

Page 34: Ruby4Ctf

文字列変換irb> "abc".unpack('H*')

=> ["616263"]

irb> ["616263"].pack('H*')

=> "abc"

irb> "abc".unpack('B*')

=> ["011000010110001001100011"]

irb> ["011000010110001001100011"].pack('B*')

=> "abc"

irb> "abc".unpack('C*')

=> [97, 98, 99]

irb> [97, 98, 99].pack('C*')

=> "abc"

これを使うとさっきの問題がとても簡単に解ける

Page 35: Ruby4Ctf

ROT13

ROT13変換とは13文字分ずらすシーザー暗号

Ruby には ROT13 を行うメソッドはない

しかし、以下のようにすればよい

irb> text.tr(‘A-Ma-mN-Zn-z’, ‘N-Zn-zA-Ma-m’)

※ Ruby はオープンクラスなのでString クラスに rot13 メソッドを自分で加えてもよい

Page 36: Ruby4Ctf

任意 ROT 関数

こんな感じ

class Stringdef rot(n)

return self.split('').map{|c| /[A-Z]/ =~ c ?

('A'.ord + (c.ord - 'A'.ord + n) % 26).chr : c}.map{|c| /[a-z]/ =~ c ?

('a'.ord + (c.ord - 'a'.ord + n) % 26).chr : c}.join

endend

Page 37: Ruby4Ctf

CTF過去問

KSNCTF : Easy Cipher

EBG KVVV vf n fvzcyr yrggre fhofgvghgvba pvcure

gung ercynprf n yrggre jvgu gur yrggre KVVV yrggref

nsgre vg va gur nycunorg. EBG KVVV vf na rknzcyr bs

gur Pnrfne pvcure, qrirybcrq va napvrag Ebzr. Synt vf

SYNTFjmtkOWFNZdjkkNH. Vafreg na haqrefpber

vzzrqvngryl nsgre SYNT.

解法

ROT13を行う!

※ 英文中に1文字が現れるのは‘a’か‘I’パッと見で大文字小文字は保持されているのでn からROT13ではないのかとあたりをつける

http://ksnctf.sweetduet.info/problem/2

Page 38: Ruby4Ctf

base64

印字可能な64文字( A-z, 0-9, +, / )へのエンコード方式(上記の記号に加えてパディングとして = も使われる)

irb> ['abc'].pack('m')

=> "YWJj¥n"

irb> "YWJj¥n".unpack('m')

=> ["abc"]

irb> puts ['abc'].pack('m')

YWJj

=> nil

irb> "YWJj".unpack('m')

=> ["abc"]

Page 39: Ruby4Ctf

uu

バイナリ・テキストデータ間のエンコード方式の一つ電子メールの添付データなどでよく使われた

begin <mode> <pathname>

#86)C

end

modeは3桁の数字

ココにエンコードされた文字列

実は空白が1つある

irb> ['abc'].pack('u')

=> "#86)C¥n"

irb> '#86)C¥n'.unpack('u')

=> ["abc"]

エンコードされた文字列だけ出力

入力もエンコードされた文字列だけ

Page 40: Ruby4Ctf

CTF過去問

KSNCTF : Onion

EVm0wd2QyUXlVWGxWV0d4V1YwZDRWMVl3WkRSV01WbDNXa1JTV0ZKdGVGWlZNakExVmpBeFYySkVU

bGhoTWsweFZtcEdZV015U2tWVQpiR2hvVFZWd1ZWWnRjRWRUTWxKSVZtdFdVZ3BpVlZwWVZtMTRj

MDB4V25GUmJVWlVUV3hLU1ZadGRHdFhRWEJwVW01Q1VGZFhNSGhpCk1WWlhWMjVHVW1KVldtRldh

a0Y0VGxaVmVXUkdaRmRWV0VKd1ZXcEtiMlJzV2tkWGJHUnJDazFXY0ZoV01qVlRZV3hLV0ZWdFJs

ZGgKYTFwTVZURmFZV1JIVWtkYVJscGhUVEJLZDFadGVHRmtNV1JYVjI1U1RsWkdTbkZEYXpGRlVX

cFNWMDFxVmxSWlYzaExWMFpXYzFacwpWbGNLVFRKb1RWWlVSbUZaVjFKSVZXdHNWV0pYYUZkV01G

:

:

Vm14d2FGbDZSbUZXVmtwMFpFWmthVkp1UWtwV2JYaGhZakpGZUZkcmFGWlhSM2hSVld0a05GSlda

SFVLWWpOa1VGVlkKUWtWWGJtOTNUMVZPYmxCVU1Fc0sK

解法

base64 + uuencode

http://ksnctf.sweetduet.info/problem/3

Page 41: Ruby4Ctf

ハッシュ値irb> require 'digest'

=> true

irb> Digest::MD5.hexdigest('abc')

=> "900150983cd24fb0d6963f7d28e17f72"

irb> Digest::SHA1.hexdigest('abc')

=> "a9993e364706816aba3e25717850c26c9cd0d89d"

irb> Digest::SHA256.hexdigest('abc')

=> "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"

irb> Digest::SHA512.hexdigest('abc')

=> "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"

Page 42: Ruby4Ctf

バイナリファイルの入出力

読み込みirb> binary =

File.binread('Reverseit').unpack(‘H*’)

書き込みirb> File.binwrite('aaa', binary.pack('H*'))

※ pack, unpack は 引数で ‘H*’を与えることで

バイナリデータと16進数での相互変換をしている

※ ほかにも File.open(filename, ‘rb’) とかもある

Page 43: Ruby4Ctf

CTF過去問

SECCON 2014 : Reverse it

Reverseit という謎のファイルが配られる

解法

バイナリデータを読み出す

16進数の1文字ずつ反転

バイナリデータを書き込む

JPEGファイルになりFLAGが書いてある

(画像も反転してるのでImageMagick等で反転する)

※ 反転するという発想は問題名やバイナリのヘッダから推測

https://github.com/ctfs/write-ups-2014/tree/master/seccon-ctf-2014/reverse-it

Page 44: Ruby4Ctf

外部コマンドの実行

統一的で便利

require ‘open3’

out, err, status = Open3.capture3(‘ls -l’)

出力が戻り値で受け取れる

`ls -l`

戻り値は真偽値

system(‘ls -l‘)

いろいろ種類がある

Page 45: Ruby4Ctf

Socket通信

require ‘socket’

solve = ‘hoge’

s = TCPSocket.open(‘123.45.67.89’, 1234)s.puts(hoge)s.close

Page 46: Ruby4Ctf

HTTP通信

require ‘net/http’

http = Net::HTTP.new(‘www.yahoo.co.jp’)response = http.head(‘/’)p response

Page 47: Ruby4Ctf

おしまい

ありがとうございました