Skip to content

Instantly share code, notes, and snippets.

@glabra
Last active August 29, 2015 14:04
Show Gist options
  • Save glabra/e71e1feab0000a914f22 to your computer and use it in GitHub Desktop.
Save glabra/e71e1feab0000a914f22 to your computer and use it in GitHub Desktop.
Twitter.CTFのお供にでもどうぞ
=begin
/*****
decrypt.rb
*****/
Synopsis:
難読化されたツイートをデコードするプラグインです。
Avaliable formats:
Base64, gzip, rot13, rot47
既知の不具合:
デコード結果がnilだった場合、[ERROR] stack level too deep が発生する。
解凍結果が非常に膨大になった場合、rubyごと落ちる。
Usage:
⚡ :decrypt [FORMAT] $xx
$xxをFORMATの順に従ってdecryptする。制御文字は~に置換される。
FORMATの指定方法:
","区切りで指定、左から順に解読される。
なお、指定するフォーマット名は下記の通りである。
auto(base64, gzip): auto
base64: b64
gzip: gz
rot13: r13
rot47(rot13の変種): r47
上記以外のフォーマット名は無視される。
Options:
Earthquake.config[:decrypt] = {
:auto => Boolean # trueで自動デコードを有効にします。
:auto_format => Boolean # 自動デコード時に使用するフォーマット
を指定します。
:auto_paranoia => Boolean # 自動デコード結果に制御文字が含まれ
ていた場合もデコードします
:strip_text => int # デコード結果が指定数字以上のツイートを指定メッセージに置き換えます。
無効にするには0以下の数値を入力してください。
:strip_text_message => String # strip_textにおける指定メッセー
ジを指定します。
:format_default => String # FORMATのデフォルト値を指定します。
}
=end
# lzmaサポートは、ライブラリが不安定すぎるので消しました
require 'base64'
require 'zlib'
require 'stringio'
#require 'lzma'
Earthquake.init do
# 初期化
config[:decrypt] ||= {}
config[:decrypt][:auto] ||= true
config[:decrypt][:auto_format] ||= ["auto"]
config[:decrypt][:auto_paranoia] ||= false
config[:decrypt][:strip_text] ||= 1024
config[:decrypt][:strip_text_message] ||= "[decrypt.rb] It's Too Long."
config[:decrypt][:format_default] ||= ["auto"]
# 本体
if config[:decrypt][:auto]
output_filter do |item|
next unless item["text"]
# 数字4桁だけのツイートが何故かデコードされるので一応の対策として
next if item["text"].match(/^[0-9]+$/)
if decrypted_text = decrypter(config[:decrypt][:auto_format], item["text"])
if config[:decrypt][:auto_paranoia]
item["text"] = decrypted_text.gsub(/[[:cntrl:]]/, "~") + " [d]".c(:notice)
elsif !decrypted_text.match(/[[:cntrl:]]/)
item["text"] = decrypted_text + " [d]".c(:notice)
end
end
end
end
command :decrypt do |m|
data = m[1].split(" ")
tweet = twitter.status(data.shift)
if data[0].match(/^(\$[a-z]{2}|[0-9]+)$/)
format = config[:decrypt][:format_default]
else
format = data.shift.split(",")
end
if decrypted_text = decrypter(format, tweet["text"])
decrypted_text = "'#{tweet["user"]["screen_name"]}: #{decrypted_text.gsub(/[[:cntrl:]]/, "~")}'"
else
decrypted_text = "'#{tweet["user"]["screen_name"]}: #{tweet["text"]}'"
end
puts(decrypted_text.c(:info))
end
help :decrypt, "Decode obfuscationized tweet.", <<-HELP
⚡ :decrypt [FORMAT] $xx
If FORMAT is not provided, assume FORMAT as #{config[:decrypt][:format_default]}.
FORMAT:
auto(base64, gzip): auto
Base64: b64
gzip: gz
rot13: r13
rot47: r47
HELP
# TODO: 何故か”デコード”後のものが降ってくる
# command :undecrypt do |m|
# tweet = twitter.status(m[1].split(" ").shift)
# puts("'#{tweet["user"]["screen_name"]}: #{tweet["text"]}'".c(:info))
# end
#
# help :undecrypt, "unDecode auto decrypted tweet.", <<-HELP
#⚡ :undecrypt $xx
#
#Undecrypt auto decrypted tweet.
#HELP
end
# local 関数群
# XXX: defの順番によって動かなくなったり動かなくなったりします。多分。あと汚くなってきた。
def decrypter(format, data_raw)
if data_raw.match(/^(@([A-Za-z0-9]|_)+\s+)+/)
reply_target = $&
text_raw = $'
processing = $'
else
reply_target = ""
text_raw = data_raw
processing = data_raw
end
for fmt in format
case fmt
when "auto"
processing = decrypter_auto(processing)
when "b64"
processing = decrypter_decode_base64(processing)
when "gz"
processing = decrypter_inflate_gzip(processing)
# when "lz"
# processing = decrypter_inflate_lzma(processing)
when "rot13"
processing = decrypter_decode_rot13(processing)
when "rot47"
processing = decrypter_decode_rot47(processing)
end
end
if config[:decrypt][:strip_text] > 0 && processing.length >= config[:decrypt][:strip_text]
retval = config[:decrypt][:strip_text_message]
elsif text_raw.gsub("\n", "") != processing
retval = reply_target + processing
else
retval = nil
end
return retval
end
def decrypter_decode_base64(data_raw)
data_raw.gsub!(/(\r\n|\r|\n)/, "")
begin
data_decrypted = Base64.strict_decode64(data_raw)
rescue
data_decrypted = nil
end
return data_decrypted
end
def decrypter_inflate_gzip(data_raw)
begin
Zlib::GzipReader.wrap(StringIO.open(data_raw)) do |c_zlib|
return c_zlib.read
end
rescue
return nil
end
end
#def decrypter_inflate_lzma(data_raw)
# begin
# data_decrypted = LZMA.decompress(data_raw)
# rescue
# data_decrypted = nil
# end
# return data_decrypted
#end
def decrypter_decode_rot13(data_raw)
return data_raw.tr("A-Za-z", "N-ZA-Mn-za-m")
end
def decrypter_decode_rot47(data_raw)
return data_raw.tr("!-~", "P-~!-O")
end
def decrypter_auto(data_raw)
retval = nil
retval ||= decrypter_inflate_gzip(data_raw)
# retval ||= decrypter_inflate_lzma(data_raw)
retval ||= decrypter_decode_base64(data_raw)
if retval
retval = decrypter_auto(retval)
else
retval = data_raw
end
return retval
end
@glabra
Copy link
Author

glabra commented Jul 22, 2014

制御文字は~に置換され、てなかったので修正

@glabra
Copy link
Author

glabra commented Jul 23, 2014

大改造劇的ビフォーアフター

@glabra
Copy link
Author

glabra commented Jul 23, 2014

動くようになりました

@glabra
Copy link
Author

glabra commented Jul 24, 2014

Base64.strict_decode64 は改行を許さなかったので改行を殺したという気持ち

@glabra
Copy link
Author

glabra commented Aug 2, 2014

Replyの自動デコードに対応した

@glabra
Copy link
Author

glabra commented Aug 2, 2014

あのさぁ…@がついてるからってさぁ…

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment