Mon Dec 7 14:27:37 JST 2015

SECCON 2015 - Crypt 100 Unzip

既知平文攻撃 (Known-plaintext attack; KPA)

https://en.wikipedia.org/wiki/Known-plaintext_attack

これを使えるツールは pkcrack (他にある?)

設定

   echo '{SECRET FLAG 141306}' > flag
   wget -O backnumber09.txt http://2014.seccon.jp/mailmagazine/backnumber09.txt
   zip -e flag.zip flag backnumber09.txt
Enter password:
Verify password:
  adding: flag (stored 0%)
  adding: backnumber09.txt (deflated 60%)
   rm flag
   ls
backnumber09.txt  flag.zip

解読

   zip a.zip backnumber09.txt
   ls
a.zip  backnumber09.txt  flag.zip
   ~/Tools/pkcrack-1.2.2/src/pkcrack -C 100.zip -c backnumber09.txt -P a.zip -p backnumber09.txt -d b.zip
   unzip b.zip
Archive:  b.zip
extracting: flag
replace backnumber09.txt? [y]es, [n]o, [A]ll, [N]one, [r]ename: A
inflating: backnumber09.txt
   cat flag
{SECRET FLAG 141306}

SECCON 2015 - Web 100

URL http://entryform.pwn.seccon.jp/register.cgi だけが渡される. メールと名前だけの入力欄があるフォーム. http://entryform.pwn.seccon.jp/ にアクセスすると、 /SECRETS register.cgi_bak の存在が確認できて、 特に register.cgi_bak では register.cgi のソースコードらしきものがテキストとして読める.

中を見ると Perl で、 大事そうなとこだけ引用すると、

if($q->param("mail") ne '' && $q->param("name") ne '') {
  open(SH, "|/usr/sbin/sendmail -bm '".$q->param("mail")."'");
  print SH "From: keigo.yamazaki\@seccon.jp\nTo: ".$q->param("mail")."\nSubject: from SECCON Entry Form\n\nWe received your entry.\n";
  close(SH);

Perl 知らないけどたぶん、 "/usr/sbin/sendmail -bm '".$q->param("mail")."'" という文字列を bash に投げるのだと思われる. というわけで、mail に ' ; echo Hi ; ' みたいな文字列を渡すことで OSコマンドインジェクションができる.

あと、

  open(LOG, ">>log"); ### <-- FLAG HERE ###
  flock(LOG, 2);

とあるので、作業ディレクトリ直下の log というファイルを覗いてみれば良いらしい.

肝心の sendmail が正しく動いてなかったり、 ファイルを新しく作ることが許可されてなかったりするので、 直接ファイルの中身を我々に見る手立てが無い. というわけでブラインドする.

tailed さんが自動化スクリプトを書いてくれたのでそれを使った. 賢いことに、 n文字目が何であるか? の命題 (真なら即座に結果が返って来て、さもなくば sleep 10 する) と、その逆の命題を同時に投げ、 先に返って来た命題が正しいと判定することでさっさとできる.

base64 に変換してからその判定に掛けるように変更して、ls の結果がわかるようになる

chars.each {|c|
  check("test $(ls -a . | base64 -w0 | cut -b #{i}) = #{c}")
}

で、 SECRETS/backdoor123.php なるファイルの存在を確認した. ブラウザでこれにアクセスして、エスパーして cat ../log したらできた (直接さっきのスクリプトで cat してもよかったのでは).

Mon Dec 7 17:28:23 JST 2015

テキスト分類 - 4chan 板当て

gist

https://gist.github.com/cympfh/d0e98d5d9006b03c0873

やったこと

使う板は /a/, /b/, /c/, /g/ (/a/nime, random, /c/ute, Technology) の4つ. /a/ と /c/ とは似てるのでこれが難しそう. /b/, /g/ の区別は簡単そう.

各板から10個、トップのスレッドを拾ってくる. ただし一番初めはようこそ的なスレッドなのでそれは除外. 拾ってくるスクリプトは以下ように. webスクレイピング部分はせっかくRubyで書いてるけどbashワンライナーしてる.

事前処理として、HTML実態参照をアンエスケープ (CGI.unescapeHTML) してるのと、>>[レス番号] みたいなのだけ削ってる. URLも削りたかったけど、http をみんな書いてないので、諦めた. スラッシュやドットをいくつか以上含んである程度の長さを持つトークン? とかすれば良さ気だけど.

#!/usr/bin/ruby
# filter.rb

# channel
c = ARGV[0]
exit 0 if not c

# thread catalog
data = `curl -s http://boards.4chan.org/#{c}/catalog | sed 's/^.*var catalog = //g' | sed 's/var style_group =.*$//g' | sed 's/; *$//g'`

# collection of thread info
threads = []

require 'json'
JSON.load(data)['threads'].each { |id, obj|
  sem_url = obj['semantic_url']
  threads << [c, id, sem_url]
}

# num of thread for use
M=10

require 'cgi'
for i in 1 .. M
  c, id, sem_url = threads[i]
  url = "http://boards.4chan.org/#{c}/thread/#{id}/#{sem_url}"
  text = `curl -s #{url} | grep -Po '<blockquote .*?<\/blockquote>' | sed 's/<[^>]*>//g' | sed 's/&gt;&gt;[0-9]*//g'`
  text = CGI.unescapeHTML text

  f = open("threads/#{c}.#{sem_url}", "w", 0666)
  text.split("\n").each { |line|
    f.puts line if line != ''
  }
  f.close
end
   mkdir threads
   ruby filter.rb a
   ruby filter.rb b
   ruby filter.rb c
   ruby filter.rb g
   ls threads

a.can-anyone-refute-this-argument
a.dont-forget-youre-always-super-special
a.holy-shit-what-a-slut
a.it-had-to-be-asked-the-question-of-the-year
a.love-live
a.one-piece-is-the-most-overrated-piece-of-fiction
a.owarimonogatari
a.ss-secret-santa
a.the-next-episode-of-opm-will-be-one-of-the-best
a.tokyo-ghoulre
b.ask-whatever-you-faggots-want-to-know
b.bro-whats-the-best-porn-search-engine
b.dubs-decides-what-i-say-next
b.hey-b-i-need-your-advice-im-a-hs-senior-18-yo
b.hey-b-i-suspect-that-my-shitskin-neighbor-is
b.hey-guys-im-a-new-pc-gamer-and-i-currently-have
b.how-does-b-like-my-gf
b.making-this-thread-in-case-the-other-one-404
b.no-porn-webm-lets-get-that-going
b.trips-names-the-ak
c.elizabeth-bathory-thread
c.holo-thread
c.if-i-may-request-a-thread-for-our-brave-prince
c.illyasviel-von-einzbern
c.kurumi-tokisaki
c.nakano-azusa-thread-11
c.noumi-kudryavka
c.tamamo-thread-pt-2
c.tohsaka-rin
c.tsf-thread
g.always-time-for-love
g.dpt-daily-programming-thread
g.javascript-project-accepting-any-nonmalicious
g.mdt-question-how-do-i-make-this-shit-autologon-to
g.phase-4-has-arrived-sunday-comes-to-a-close-those
g.roots-edition
g.seamonkey-waterfox-or-pale-moon
g.software-that-g-recommends-but-is-actually
g.whats-the-earliest-age-youd-give-a-smartphone-to
g.why-shouldnt-i-start-learning-swift-and-using-it

こんな感じ. 適当に、各板10スレッドの内7を訓練に持ってきて残りをテストにしよう.

   mkdir train
   mkdir test
   \ls -1 a.* | head -7 | sed 's/.*/mv & train/g' | sh
   \ls -1 b.* | head -7 | sed 's/.*/mv & train/g' | sh
   \ls -1 c.* | head -7 | sed 's/.*/mv & train/g' | sh
   \ls -1 g.* | head -7 | sed 's/.*/mv & train/g' | sh
   mv a.* b.* c.* g.* test

tf-idf

https://github.com/cympfh/nlptk を使う

cat a.* > all
echo --- >> all
cat b.* >> all
echo --- >> all
cat c.* >> all
echo --- >> all
cat g.* >> all

   ~/Tools/nlptk/tfidf/tfidf.exe -N 30 all
0.00284506 Luffy
0.00236193 Piece
0.00198617 Gaen
0.00171777 characters
0.00142253 One
0.00134201 Oda
0.00131448 she
0.00128833 vs
0.00128833 Araragi
0.00118097 Doffy
0.00107361 power
0.00107361 arc
0.000912566 Saitama
0.000912566 Kanbaru
0.000751525 punches
0.000751525 Tatsumaki
0.000751525 Law
0.000751525 Fubuki
0.000751525 Doflamingo
0.000712939 than
0.000697844 spoiler
0.000697844 shonen
0.000697844 series
0.000697844 opinions
0.000697844 arguing
0.000697844 Luffy's
0.000644164 plot
0.000644164 ideological
0.000644164 boring
0.000644164 Ougi
---
0.00299236 roll
0.00265988 Roll
0.00216115 980
0.00199491 cpu
0.00199491 970
0.00132994 upgrade
0.00132994 nudes
0.00132994 grades
0.00132994 dubs
0.00132994 colleges
0.00132994 /b/
0.0011637 amd
0.0011637 Quality:
0.0011637 GPA
0.000997454 nigger
0.000997454 mobo
0.000997454 max
0.000997454 im
0.000997454 community
0.000997454 WINRAR
0.000997454 GTX
0.000997454 $350
0.000965955 fuck
0.000831211 settings
0.000831211 i5
0.000831211 gpa
0.000831211 experience
0.000831211 card
0.000831211 Rolling
0.000831211 Hey
---
0.00328117 finished
0.00218745 folder
0.00218745 art
0.00164059 reading
0.00164059 kurumi
0.00164059 cute!
0.00164059 OST
0.00164059 Kurumi
0.00164059 Illya
0.00164059 Bump
0.00164059 Azunyan
0.00136715 manga
0.00109372 visual
0.00109372 too,
0.00109372 tease,
0.00109372 senjou
0.00109372 reality
0.00109372 punpun
0.00109372 pun
0.00109372 onee-san
0.00109372 koe
0.00109372 jsut
0.00109372 finish
0.00109372 doki
0.00109372 dedicated
0.00109372 cuddle
0.00109372 bend
0.00109372 adorable
0.00109372 Yet
0.00109372 Umineko
---
0.00806341 0
0.00367447 index
0.00326619 trackers
0.00244964 tracker
0.00224551 values
0.00224551 row
0.00183723 pixel
0.00183723 invite
0.0016331 PTP
0.00142896 private
0.00142896 pixels
0.00142896 latest
0.00142896 color
0.00122482 lines
0.00122482 const
0.00122482 channel
0.00122482 AB
0.00102068 wtf
0.00102068 utorrent
0.00102068 rows
0.00102068 pizza
0.00102068 colors
0.00102068 R
0.00102068 BTN
0.00102068 AHD
0.000918616 y
0.000889607 use
0.000816548 value
0.000816548 then?
0.000816548 tested

順に、/a/ /b/ /c/ /g/ の特徴的な (tf-idf 的な意味で) トップ30の語を列挙したが、、、 分かるような分からないような感じだ.

1-5gram で取ってみたほうが人間に取ってわかりよい:

   ~/Tools/nlptk/ngram/ngram.exe -n 1,2,3,4,5 --tfidf --limit 5.0 all

https://gist.github.com/cympfh/d0e98d5d9006b03c0873#file-4chan-ngram

comma とか引用の > が正しくトークナイズされてないので整形する. ルールベースで簡単にトークナイズして品詞タグ付けしてくれる npm/pos を使う. 書いたスクリプトは以下:

#!/usr/bin/env coffee
# pos.coffee

pos = require 'pos'
words = new pos.Lexer().lex(line)
tagger = new pos.Tagger()

fs = require 'fs'
text = fs.readFileSync(process.argv[2], 'utf-8').trim()
lines = text.split '\n'

for line in lines
  tagged = tagger.tag words
  console.log tagged.map(([w, p]) -> "#{w}_#{p}").join ' '

これを使って

   ls
pos.coffee  test  train
   \ls -1 train/* | sed 's/.*/coffee pos.coffee & > &.pos/g' | sh
   \ls -1 test/* | sed 's/.*/coffee pos.coffee & > &.pos/g' | sh

   head train/c.nakano-azusa-thread-11.pos
Azunyan_NN Thread_VB :_: Do_VBP it_PRP for_IN Her_PRP$ Edition>Previous_NNS thread_NN :_: >Previouser_NN threads_NNS :_: http_NN :_: /_NN /_NN pastebin_NN ._. com_NN /_NN CEmjik_NN 3_CD T>Useful_NN links_NNS :_: http_NN :_: /_NN /_NN pastebin_NN ._. com_NN /_NN 7_CD v_NN 605_CD WML_NN
Posting_VBG even_RB more_JJR birthday_NN art_NN that_IN was_VBD uploaded_VBN late_JJ on_IN Pixiv_NN
what_WP what_WP look_VB at_IN all_DT the_DT azunyan_NN merch_NN dedicated_VBN to_TO her_PRP$ 11_CD /_NN 11_CD birthday_NN !_! http_NN :_: /_NN /_NN www_NN ._. animenewsnetwork_NN ._. com_NN /_NN interest_NN /_NN 2015_CD -_: 11_CD -_: 11_CD /_NN pocky-day-shares-celebration-with-k-on-azu-nyan-idol-reina-tanaka_NN /_NN .95254_CD
I_NN really_RB really_RB really_RB want_VBP that_IN wallscroll_NN ._.
Full_JJ version_NN of_IN the_DT OP_NNP image_NN by_IN the_DT way_NN :_: https_NNS :_: /_NN /_NN jii_NN ._. moe_NN /_NN VJyi_NN 7_CD XJQl_NN ._. png_NN
Many_JJ thanks_NNS !_!
>tfw_NN no_DT Azunyan_NN maido_NN
Yet_RB more_JJR birthday_NN art_NN
Updated_VBN folder_NN of_IN 2015_CD birthday_NN art_NN :_: https_NNS :_: /_NN /_NN mega_JJ ._. nz_NN /_NN #_# F_NN !_! f_NN 9_CD IXwT_NN 4_CD L_NNP !_! t_NN 48_CD Ijs-_NN 8_CD mp_NN 99_CD paCLgSMYPQ_NN
>two_NN adorable_JJ nekos_NNS

こんな感じ. 引用符である > が相変わらずだ.

   cat a.*.pos > all
   echo --- >> all
   cat b.*.pos >> all
   echo --- >> all
   cat c.*.pos >> all
   echo --- >> all
   cat g.*.pos >> all
   ~/Tools/nlptk/ngram/ngram.exe -n 1,2,3,4,5 --tfidf --limit 5.0 all

https://gist.github.com/cympfh/d0e98d5d9006b03c0873#file-4chan-rev2-ngram

--limit 5.0 はわざと数を制限するためにつけたけど素性として使う場合は、 単にこれでソートして大きいのから使えばいいだけ.

   ~/Tools/nlptk/ngram/ngram.exe -n 1,2,3,4,5 --tfidf --limit 0.0 all | grep -v '^---$' | sort -gr -k2,2 > ngrams
   head ngrams
1 101.199 Luffy_NN
1 66.5421 Piece_NN
1 65.1558 Gaen_NN
1 65.1558 characters_NNS
2 58.2244 One_NN Piece_NN
1 49.9066 Araragi_NN
1 45.7477 Doffy_NN
1 42.9751 Saitama_NNP
1 42.9751 Oda_NN
1 42.9751 arc_NN
   tail ngrams
1 0 :_:
1 0 ;_;
1 0 ,_,
1 0 ,_,
1 0 ,_,
1 0 ,_,
1 0 -_:
1 0 -_:
1 0 -_:
1 0 -_:

Piece って何かと思ったらワンピースのことか.

クラス付き正則パターン

https://github.com/cympfh/alice を使う

   cat a.*.pos > all.a
   cat b.*.pos > all.b
   cat c.*.pos > all.c
   cat g.*.pos > all.g
   ~/Tools/nlptk/ngram/ngram.exe -n 1,2,3,4,5 --tfidf --limit 5.0 all > out
   54:23 ~/test/4chan/threads/train
   cat << EOM > split.awk
BEGIN {
  a[0]="a"
  a[1]="b"
  a[2]="c"
  a[3]="g"
  i=0
}
{
  if ($0 == "---") i++;
  else print $0 >> "ngram." a[i]
}
EOM
   awk -f split.awk out
   cat ngram.a | grep -v '__BOS__' | grep -v '__EOS__' | sort -gr -k 2,2 | head -n 100  | sed 's/^[^ ]* [^ ]* //g'  | sed 's/.*/<> & <>\n& <>/g' | sed 's/_/\//g' > seed.a

/c/ のためのパターンをテキスト all.c とシード ngrcm.c を用いて作る.

   head all.c
I_NN feel_VB like_IN crap_NN ._. How_WRB about_IN a_DT thread_NN of_IN my_PRP$ waifu_NN ?_.
>dat_NN cute_JJ nose_NN
I_NN wish_VBP I_NN had_VBD more_JJR to_TO post_NN but_CC my_PRP$ good_JJ folder_NN is_VBZ in_IN an_DT HDD_NN and_CC I_NN '_" m_NN on_IN my_PRP$ crappy_NN phone_NN ._.
>that_NN feel_VB your_PRP$ phone_NN dies_VBZ from_IN posting_VBG waifuJust_NN can_MD '_" t_NN handle_VB her_PRP$ perfectness_NN I_NN guess_VBP ._.
Well_UH this_DT is_VBZ it_PRP from_IN me_PRP for_IN now_RB ._. Thanks_NNS for_IN the_DT contributions_NNS anon_NN ._.
She_PRP looks_VBZ like_IN Yui_NN from_IN Angel_NNP Beats_VBZ ._. I_NN approve_VB ._.
The_DT "_" Blood_NNP Countess_NN "_" who_WP was_VBD charged_VBN with_IN murdering_VBG 80_CD young_JJ girls_NNS and_CC bathing_VBG in_IN their_PRP$ blood_NN ?_. And_CC also_RB had_VBD a_DT quest_NN in_IN Diablo_NN 2_CD ?_. Do_VBP you_PRP know_VB what_WP you_PRP '_" ve_NN gotten_VBN yourself_PRP into_IN ,_, OP_NNP ?_.
LIZ_NN THREAD_NN
Bathory_NN the_DT pioneering_VBG black_JJ metal_JJ band_NN ?_.
Yes_UH I_NN love_NN her_PRP$ ._. Can_MD '_" t_NN be_VB helped_VBD she_PRP chose_VBD my_PRP$ shitty_NN self_NN ,_, but_CC I_NN '_" m_NN loving_JJ it_PRP ._. Koi_NN no_DT beato_NN !_! Dragon_NNP sukeiru~_NN

   head seed.a
<> Luffy/NN <>
Luffy/NN <>
<> Piece/NN <>
Piece/NN <>
<> Gaen/NN <>
Gaen/NN <>
<> characters/NNS <>
characters/NNS <>
<> One/NN Piece/NN <>
One/NN Piece/NN <>
   for c in a b c g; do ~/study/alice/alice --book-only --frequency -P 30 -B 10 -S seed.$c all.$c > out.$c; done
   scan from text:all.a ... finished.
   time=1118
   scan from text:all.b ... finished.
   time=555
   scan from text:all.c ... finished.
   time=226
   scan from text:all.g ... finished.
   time=382

-B (book size) を小さくすると得られるパターンが具体的になることが期待できるけど、 分類の素性に使うには適度に一般化されたパターンであるべきなので、ある程度大きくないといけない.

  1. patterns for /a/
  2. patterns for /b/
  3. patterns for /c/
  4. patterns for /g/

期待することとして、 シードなしのパターンはただの構文を捉え (What I do ... ? だとか I want to VB だとか)、 シードで内容語 (content words) を用意することで、それに構文を当てはめる.

TODO

ここまでは素性を作るまでで、 ここから何かしらの学習器に食わせるフォーマットに直してっていう作業があるんだけど、 飽きたので(疲れたので).