Upload
nobutada-matsubara
View
343
Download
7
Embed Size (px)
Citation preview
Ctfのための
python ruby入門ひげ
尊敬すべき元ネタ
「Ctfのためのpython入門」http://www.slideshare.net/shiracamus/ctfpython
勝手にパロディましたすいません
自己紹介
いろんなプログラミング言語
さわる人(Rubyとか)
最近Python
さわり始めた人
最近CTF始めた人
「Ctfのためのpython入門」
に出会う
Pythonで行けるなRubyでもいけるのでは?
調べたのでまとめます
CTFあるある
数値 文字
巨大整数演算
エンコード・デコード
ハッシュ関数
Rubyもできます!(pythonの方が楽な気がするけど)
Rubyを使うには
www.ruby-lang.org
から
ダウンロード
インストール
Rubyのバージョン
新しいのを使おう!(現在 2.2.2)
早速使ってみよう!
インタープリタの起動と終了
sh $ irb
irb> exit
sh $
sh $ ruby <filename>
Rubyスクリプトファイルを実行する方法
※ irb は Ruby で書かれているRubyインタープリタなんだ!
電卓として使う
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(排他的論理和)
電卓として使う
irb> 'A' * 16 + '¥x86¥x64¥xca¥xfe'
=> "AAAAAAAAAAAAAAAA¥¥x86¥¥x64¥¥xca¥¥xfe"
¥x64 は ASCIIコードで ‘ d ’ のはず
なぜ変換されないのか?(ちなみにPythonではされる)
電卓として使う
実は原因はシングルクォートにある
Rubyはシングル・ダブルクォートで動作が違う
•ダブルクォーテーション•バックスラッシュ記法が使える•式展開される
•シングルクォーテーション•バックスラッシュ記法が使えない•式展開されない
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 クラスの % 演算子
タプル 配列
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"
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 は入力した式の評価結果を返す
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メソッドはない
文字
irb> 'A'.ord
=> 65
irb> 65.chr
=> "A"
irb> 65.to_s(16)
=> "41"
irb> (0x41 + 1).chr
=> "B"
文字列/配列(リスト)
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 はめんどくさい
でも、重ねがけが楽
部分文字列
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番目から末尾まで
ただし、末尾を含む
コッチは含まない
文字列分割・連結
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"
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
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
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
文字列変換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"
これを使うとさっきの問題がとても簡単に解ける
ROT13
ROT13変換とは13文字分ずらすシーザー暗号
Ruby には ROT13 を行うメソッドはない
しかし、以下のようにすればよい
irb> text.tr(‘A-Ma-mN-Zn-z’, ‘N-Zn-zA-Ma-m’)
※ Ruby はオープンクラスなのでString クラスに rot13 メソッドを自分で加えてもよい
任意 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
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
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"]
uu
バイナリ・テキストデータ間のエンコード方式の一つ電子メールの添付データなどでよく使われた
begin <mode> <pathname>
#86)C
end
modeは3桁の数字
ココにエンコードされた文字列
実は空白が1つある
irb> ['abc'].pack('u')
=> "#86)C¥n"
irb> '#86)C¥n'.unpack('u')
=> ["abc"]
エンコードされた文字列だけ出力
入力もエンコードされた文字列だけ
CTF過去問
KSNCTF : Onion
EVm0wd2QyUXlVWGxWV0d4V1YwZDRWMVl3WkRSV01WbDNXa1JTV0ZKdGVGWlZNakExVmpBeFYySkVU
bGhoTWsweFZtcEdZV015U2tWVQpiR2hvVFZWd1ZWWnRjRWRUTWxKSVZtdFdVZ3BpVlZwWVZtMTRj
MDB4V25GUmJVWlVUV3hLU1ZadGRHdFhRWEJwVW01Q1VGZFhNSGhpCk1WWlhWMjVHVW1KVldtRldh
a0Y0VGxaVmVXUkdaRmRWV0VKd1ZXcEtiMlJzV2tkWGJHUnJDazFXY0ZoV01qVlRZV3hLV0ZWdFJs
ZGgKYTFwTVZURmFZV1JIVWtkYVJscGhUVEJLZDFadGVHRmtNV1JYVjI1U1RsWkdTbkZEYXpGRlVX
cFNWMDFxVmxSWlYzaExWMFpXYzFacwpWbGNLVFRKb1RWWlVSbUZaVjFKSVZXdHNWV0pYYUZkV01G
:
:
Vm14d2FGbDZSbUZXVmtwMFpFWmthVkp1UWtwV2JYaGhZakpGZUZkcmFGWlhSM2hSVld0a05GSlda
SFVLWWpOa1VGVlkKUWtWWGJtOTNUMVZPYmxCVU1Fc0sK
解法
base64 + uuencode
http://ksnctf.sweetduet.info/problem/3
ハッシュ値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"
バイナリファイルの入出力
読み込みirb> binary =
File.binread('Reverseit').unpack(‘H*’)
書き込みirb> File.binwrite('aaa', binary.pack('H*'))
※ pack, unpack は 引数で ‘H*’を与えることで
バイナリデータと16進数での相互変換をしている
※ ほかにも File.open(filename, ‘rb’) とかもある
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
外部コマンドの実行
統一的で便利
require ‘open3’
out, err, status = Open3.capture3(‘ls -l’)
出力が戻り値で受け取れる
`ls -l`
戻り値は真偽値
system(‘ls -l‘)
いろいろ種類がある
Socket通信
require ‘socket’
solve = ‘hoge’
s = TCPSocket.open(‘123.45.67.89’, 1234)s.puts(hoge)s.close
HTTP通信
require ‘net/http’
http = Net::HTTP.new(‘www.yahoo.co.jp’)response = http.head(‘/’)p response
おしまい
ありがとうございました