Wednesday, December 01, 2010
Redmineに関する雑多メモ
Monday, August 16, 2010
textsize, sp and dp
Tuesday, March 02, 2010
自分の無能さを晒す 2 Google Dev Fest 2010 の Quiz パッチワーク版
まずは,6時間かかったバージョン。
#!/opt/local/bin/ruby
# read file and create array.
$basearea = []
$hascheckedarea = []
$max_x_size = 0
$max_y_size = 0
open(ARGV[0]) do |file|
while l = file.gets
$max_y_size += 1
l.chomp!
add_array = []
add_check_array = []
for i in 0 .. l.size - 1
add_array += [l[i].chr]
add_check_array += [false]
end
$basearea << add_array
if ($max_x_size < add_array.size)
$max_x_size = add_array.size
end
$hascheckedarea << add_check_array
end
end
# main routine
def clear_has_checked_array
for x in 0 .. ($hascheckedarea.size - 1)
for y in 0 .. $hascheckedarea[x].size - 1
$hascheckedarea[x][y] = false
end
end
end
def is_equal_char_forpoint(compare_char, point_x, point_y)
# debug_str = "checking (x, y) = (" + point_x.to_s + ", " + point_y.to_s + ")"
if point_x < 0 || point_y < 0 || point_x >= $max_x_size || point_y >= $max_y_size
return false
end
# p debug_str
retvalue = false
if $basearea[point_x][point_y]
if $hascheckedarea[point_x][point_y] == true
# debug_str += (" has been checked ")
else
$hascheckedarea[point_x][point_y] = true
# debug_str += (" is " + $basearea[point_x][point_y])
if compare_char == $basearea[point_x][point_y]
retvalue = true
else
retvalue = false
end
# debug_str += (retvalue == true) ? "result is true" : "result is false"
end
end
# debug_str += " for ( " + point_x.to_s + ", " + point_y.to_s + ")"
# p debug_str
retvalue
end
def measure_continuous_area(base_char, start_point_x, start_point_y)
# debug_str = "searching (" + (start_point_x).to_s + ", " + (start_point_y).to_s + ")"
# p debug_str
retvalue = 1
$hascheckedarea[start_point_x][start_point_y] = true
if is_equal_char_forpoint(base_char, start_point_x - 1, start_point_y)
retvalue += measure_continuous_area(base_char,
start_point_x - 1, start_point_y)
end
if is_equal_char_forpoint(base_char, start_point_x, start_point_y - 1)
retvalue += measure_continuous_area(base_char,
start_point_x, start_point_y -1)
end
if is_equal_char_forpoint(base_char, start_point_x + 1, start_point_y)
retvalue += measure_continuous_area(base_char,
start_point_x + 1, start_point_y)
end
if is_equal_char_forpoint(base_char, start_point_x, start_point_y + 1)
retvalue += measure_continuous_area(base_char,
start_point_x, start_point_y + 1)
end
retvalue
end
x_axis = 0
y_axis = 0
conarea_size =[]
for x_axis in 0 .. $basearea.size - 1
line_size = []
for y_axis in 0 .. $basearea[x_axis].size - 1
#p $basearea[x_axis][y_axis]
clear_has_checked_array()
line_size += [measure_continuous_area($basearea[x_axis][y_axis], x_axis, y_axis)]
end
conarea_size << line_size;
end
$basearea.each do |array|
p array
end
#conarea_size.each do |array|
# p array
#end
max_area_size = 0
conarea_size.each do |x_array|
p x_array
x_array.each do |value|
if max_area_size < value
max_area_size = value
end
end
end
#debug_str = "max area size " + max_area_size.to_s
#p debug_str
conarea_size.each do |x_array|
count = 0
x_array.each do |value|
if max_area_size == value
count += 1
end
end
p count
end
何がまずいか。
- 各点ごとに最大連結エリアサイズを求めようとしている。
- エリアサイズを求める際に,境界を記録しておく配列 $hascheckedarea (サイズ 600×600)を用意していたが,各点のエリア計算時にクリアしている。
AAB BAA BBAを例にしたとき,A全ての点でおいて最大連結エリアサイズを求めている。この場合,点(0,0)のAの最大連結エリアサイズが判れば,他の点で計算する必要はない。しかも,$hascheckedarea を各点の計算毎にクリアしているので,とんでもない無駄な計算をしてしまった。
回答終了後,DevFest Quizパッチワーク問題の回答 CommonJS編 (電脳戦士ハラキリ -SE道とは死ぬ事と見つけたり)を見て,最大連結エリアを構成する部分集合のうちの1点だけを記録して,最後に答となる点から連結するエリアを塗りつぶせばいいということと(リンク先の配列 maxScoreCells[]と関数 fill()に注目),チェックした領域を1点ごとにクリアしてはいけない ($hascheckedareaを利用しない。そのかわり,$scoreMapで記録する。このscoreMapは全ての点において正しい最大連結エリアの値を保存しているとは限らない) ということを理解して,改訂しました。
#!/opt/local/bin/ruby
# read file and create array.
$basearea = []
$scoreMap = []
$max_x_size = 0
$max_y_size = 0
# 問題ファイルを読みこみ,元となる配列 $basearea を作成
open(ARGV[0]) do |file|
while l = file.gets
$max_y_size += 1
l.chomp!
add_array = []
add_check_array = []
for i in 0 .. l.size - 1
add_array += [l[i].chr]
add_check_array += [-1]
end
$basearea << add_array
if ($max_x_size < add_array.size)
$max_x_size = add_array.size
end
$scoreMap << add_check_array
end
end
def is_equal_char_forpoint(compare_char, point_x, point_y)
# debug_str = "checking (x, y) = (" + point_x.to_s + ", " + point_y.to_s + ")"
if point_x < 0 || point_y < 0 || point_x >= $max_x_size || point_y >= $max_y_size
return false
end
if $scoreMap[point_x][point_y] != -1
return false # this point has been already checked
end
# p debug_str
retvalue = false
if $basearea[point_x][point_y]
if compare_char == $basearea[point_x][point_y]
retvalue = true
else
retvalue = false
end
end
# debug_str += " for ( " + point_x.to_s + ", " + point_y.to_s + ")"
# p debug_str
retvalue
end
def measure_continuous_area(base_char, start_point_x, start_point_y)
# debug_str = "searching (" + (start_point_x).to_s + ", " + (start_point_y).to_s + ")"
# p debug_str
if $scoreMap[start_point_x][start_point_y] != -1
retvalue = 0 # チェック済みなので計算させない
end
$scoreMap[start_point_x][start_point_y] = 0 # この作業で点 (start_point_x, start_point_y) はチェック済みであることを表す。
if (base_char == $basearea[start_point_x][start_point_y])
retvalue = 1
end
if is_equal_char_forpoint(base_char, start_point_x - 1, start_point_y)
retvalue += measure_continuous_area(base_char,
start_point_x - 1, start_point_y)
end
if is_equal_char_forpoint(base_char, start_point_x, start_point_y - 1)
retvalue += measure_continuous_area(base_char,
start_point_x, start_point_y -1)
end
if is_equal_char_forpoint(base_char, start_point_x + 1, start_point_y)
retvalue += measure_continuous_area(base_char,
start_point_x + 1, start_point_y)
end
if is_equal_char_forpoint(base_char, start_point_x, start_point_y + 1)
retvalue += measure_continuous_area(base_char,
start_point_x, start_point_y + 1)
end
retvalue
end
x_axis = 0
y_axis = 0
maxScore = 0
maxScorePoint = []
for x in 0 .. $basearea.size - 1
for y in 0 .. $basearea[x_axis].size - 1
#p $basearea[x_axis][y_axis]
# clear_has_checked_array()
score = measure_continuous_area($basearea[x][y], x, y)
if (maxScore < score)
maxScore = score
maxScorePoint = [[x, y]]
elsif (maxScore == score)
maxScorePoint += [[x, y]]
end
end
end
$basearea.each do |array|
p array
end
def fill(x, y, chr)
if ($basearea[x][y] != chr)
return
end
$basearea[x][y] = '_'
fill(x+1, y, chr)
fill(x, y+1, chr)
fill(x-1, y, chr)
fill(x, y-1, chr)
end
maxScorePoint.each do |point|
x = point[0]
y = point[1]
fill(x, y, $basearea[x][y])
end
$basearea.each do |array|
p array
end
$basearea.each do |array|
cnt = 0
array.each do |chr|
if chr == '_'
cnt += 1
end
end
p cnt
end
結果,10秒程度で実行完了。自分の無能さを実感した日でした。
自分の無能さを晒す 1 Google Dev Fest 2010 の Quiz 漢字変換サーバ版
あー,自分でWebサーバ持っていないし,GAEにアプリ登録したこともないから,この問題にはチャレンジできないなと思っていましたが,回答締切6時間前に,別に自分で簡易ウェブサーバ立ちあげればいいんじゃないと思い,急遽やってみました。
幸いなことに,EmacsをChrome上で利用するためにWEBrickを利用したHTTPサーバのスクリプトを読んだこと(ChromeとEmacsを愛するもの達へ 【編集あり】)を思いだしたのが幸いでした。
方針は,
- 特殊ケース 0 の場合は 零(H) を返す
- 兆の位の4桁,億の位の4桁,万の位の4桁,一の位?の4桁を抽出して,漢数字に変換する。0や1千の扱い時に注意する。
def trans_4digit_kansuzi(num)
digit_1st_array = ['', 'G', 'B', 'S', 'A', 'Q', 'Z', 'P', 'C', 'Y'] # 零 一 二 三 四 五 六 七 八 九
digit_other_array = ['', '', 'B', 'S', 'A', 'Q', 'Z', 'P', 'C', 'Y'] # 零 一 二 三 四 五 六 七 八 九
unit_array = ['N', 'M', 'J', ''] # 千 百 十 零
is_top_digit_zero = true
ret_str = ""
for i in 0 .. unit_array.size - 1
tmp_num = (num % (10 ** (unit_array.size - i))) / (10 ** (unit_array.size - 1 -i))
if tmp_num > 0 || is_top_digit_zero == false
is_top_digit_zero = false
if tmp_num != 0
if i == (unit_array.size - 1)
ret_str += (digit_1st_array[tmp_num] + unit_array[i])
else
ret_str += (digit_other_array[tmp_num] + unit_array[i])
end
end
end
end
return ret_str
end
def trans_kansuzi(num)
if num == 0
return 'H' # 零
end
unit_array = ['T', 'D', 'K', ''] # 兆 億 万 零
ret_str = ""
is_top_digit_zero = true
for i in 0 .. unit_array.size - 1
tmp_num = (num % (10000 ** (unit_array.size - i))) / (10000 ** (unit_array.size - 1 - i))
debug_str = i.to_s + " " + tmp_num.to_s
p debug_str
if tmp_num > 0 || is_top_digit_zero == false
is_top_digit_zero = false
if tmp_num != 0
ret_str += (trans_4digit_kansuzi(tmp_num) + unit_array[i])
end
end
end
return ret_str
end
p trans_kansuzi(ARGV[0].to_i)
本当は
tmp_num = (num % (10000 ** (unit_array.size - i))) / (10000 ** (unit_array.size - 1 - i))のように上位桁から検証してしまったが,
tmp_num = num % 10000 # 下4桁の値を得る # tmp_num 文字列生成処理 num = num / (10000 ** i) # 右4桁移動する。のように,下位桁から検証した方が綺麗。(テストはしていない)
Google Dev Fest 2010 Japan の Quiz 暗号通信版
パッチワークの問題の解き方があまりにも恥しかったので,自分への懲戒のため自分の回答を晒します。(Google Dev Fest 2010 の Quiz) まずは,暗号通信から。 楽に,手を抜くために慣れたRubyで実装しました。
シーザー暗号なんだなと思ったけど,tr コマンドの使い方を理解していなかったことが発覚。なので,地味に書きました。手を抜くために,gemのJSONライブラリ,JSON implementation for Rubyを利用しました。
#!/opt/local/bin/ruby
require "json"
require "net/http"
target_host = "devquiz.appspot.com"
target_file = "/personalpost"
key = "(snip)"
plain_text="my email address"
pass_text=""
for i in 0 .. plain_text.size - 1
ch = plain_text[i]
if (ch >= 'a'[0] && ch <= 'z'[0] ) # 小文字の変換
tmp = (ch - 'a'[0] + 4) % 26
pass_text += ('a'[0] + tmp).chr
elsif (ch >= 'A'[0] && ch <= 'Z'[0] ) # 大文字の変換
tmp = (ch - 'A'[0] + 4) % 26
pass_text += ('A'[0] + tmp).chr
else # その他の文字はそのまま通過
pass_text += plain_text[i].chr
end
end
json = {"key" => key, "pass" => pass_text}.to_json
#p json
Net::HTTP.start(target_host, 80 ) do |http|
# response = http.get('/')
response = http.post( target_file, json )
p response
end
tr を用いた別解
DevFestクイズ答案: 暗号通信
Sunday, February 21, 2010
第3回東北情報セキュリティ勉強会に行ってきました。
2010年2月20日に開催された,第3回東北情報セキュリティ勉強会に行ってきました。主催なさった方,講師の方々,会場を手配くださった岩手県立大学の高田先生,ならびに学生様ありがとうございました。
参加したのはセキュリティトラック系。noteから更に抜粋に加え,自分のと思ったこと書きなぐってみます。
「近年のモバイル端末に関するセキュリティ」
- 日本の携帯は初めっから安全に振られている。しかし,新しい機能を入れたら,それは大丈夫だろうか。
- 携帯のブラウザにはCookieの概念がない。個体識別番号 (携帯 UID) + src IP アドレスfilterでセキュリティを確保。更にUAを加えて,携帯電話とPCとの判別をしている。 (自分 個体識別番号が盗まれたとき,engress filterをかましていないISPからUAを偽造してアクセスされたらどうなるのだろうか。まだengress filterをかましていないISPはあるだろう?)
- (自分 高木浩光@自宅の日記 - 日本のインターネットが終了する日をもう一回理解する必要がある)
- USER_AGENT変更ツール FireMobileSimulator (Firefox add-on)
- 携帯JavaScriptとXSSの組み合わせによる「かんたんログイン」なりすましの可能性
XSSの脆弱性を利用して,攻撃用JavaScriptを読みこませる。XMLHttpRequest.setRequestHeader を用いて他人のUIM,iモードIDを産めこむ。 対策 docomo の proxy server 側 で setRequestHeader を無効にした。 - 新しい機能を実行したら,パソコン関係ではスルーしてしまう問題は,日本の携帯キャリア・ベンダーは対応が早い。
- iモード専用サイトのhtmlソースの閲覧方法 DNS rebindingを用い,JavaScriptのクロスドメイン制限を回避。(自分 というか,webサイトでソース見られたらまずい実装するのはどうなのか?。DNSの運用の問題?DNSSECは?)
- Exploiting Smartphone系,iPhone (携帯電話と違い,比較的自由な開発環境)。開発も環境もオープンなため,様々なリサーチが行われている。
- ARMのexploit codeのdemo (Thumb命令とARM命令を両立させて 0x00を消去する)。OSでも対策はある。W^X 。書き込み(W)と実行(X)を天分にする仕様
- 書き込みできるメモリ空間は実行できず,実行できるメモリ空間は書き込みできない
- OpenBSDが採用,mprotect で切り替え可
- Application側でport listenして,そのlistenしている applicationにvulnerability があれば,攻撃の対象になる。
- JailBreak,マジコン,PSPのCF。ハードウェアをハックされてしまうとどうしようもない。ハックされないようなハードウェアの設計?OSの設計?
- 携帯電話はWeb系のセキュリティが主流
- 携帯ブラウザのAjax, JavaScript関連
- martphoneは比較的OSやハードウェアに近い部分のセキュリティがメイン
- iPhoneのjailbreakなど
SmartphoneにターゲットしたJavaScriptコードはどうなるのか?現状,webkitを使用しているので,様問題があるのならば,pcアプリにも同様の問題があるということ。なので対応は早いのではないのか?
Gumblar.x を除いてみた。 メモのみ
Googleで検索する。
対策はひっかかるが。
- Web誘導感染型 (1段階置いて, phising?Web誘導)
- FTPアカウントの搾取
- Webサイトの改竄 ? (盗んだFTPパスワードを取得して,改竄する)
- SQL injection で改竄されても Gumblar?
- Phishing なのに Gumblar?
Gumblarを分類する
- Gumblar.x
- *.ru:8080 (GNU GPL)
Gumblar.x
GENOウィルス = Gumblar 2009年春ごろ
Gumblar 亜種 (Gumblar.x) 2009年10月中旬ごろ-
GENOウィルスの絵 (sourceが難読化されている)
-> document.write("<script src=attacker's siteURL></script>");
Gumblar.X
</head>
<script src="http://***.php">></script> (飛び先も正規サイト)
<body>
見に行っただけで感染
Pegel.*
*.ru:8080 - 2009年12月頃
難読化されたコード
Gumblar-x Pegel との比較
利用される脆弱性 Adobe Reader,Flash MSOfficeWeb, IE Gumblar-x
Adobe Reader, MDAC, SnapShotViewer, JRE Pegel
QuickTimer を使うのもある
感染後の動作 FTPアカウントの摂取,rootkit
自分自身のupdate Gumblar-x
Downloader(他のマルウェアを落とす), 偽アンチウィルス,SpamBot Pegel
国内感染情報 3000以上 (Gumblar-x) 350以上 (Pegel) (クローラーで見ているので,数値にはあまり意味がないのかもしれない。)
Pegelは12月終わりごろから出現
今日の話は Gumblar-x の話
Attack Flow
Redirect <script src="*php"%gt; %gt;- これが正規のホストであるので,この段階での検出はNGの可能性が高い。
Browser Check (UAを確認,未対応は404を返す初めのころはOpera,Firefox等ははじいていた)
wgetやweb emulatrion
難読化されたJavaScriptをdownload
アクセスしてきたPCの環境をチェックして,該当するexploitをdownloadする。(Active-Xなど)
downloaderが落としてきたペイロードを脆弱性があるapplicationが実行して,
更に次の攻撃先にアクセスする。
最後に,exeが落ちてきて,実行する。
PDFのフライトレコード (PDFの暗号化,zlibで暗号化)
CWS Exploit (FWSをzlibで暗号化したやつ)
いずれにせよ,コアな部分は http://attackerhost.com/gumblar.php? <- このURLにアクセスさせる。
EXE <- Kates (Danol) と呼ばれている
-> DLL を作成
-> Processにインジェクション
-> 再起動後,真っ暗な画面になる。
DEMO
レジストリの隠蔽
感染ファイルの保護
ツールの妨害
- regmon.exe
- filemon.exe
- gmer.exe (rootkit killer)
- avz.exe (rootkit killer)
Hidden Packet
C&C との通信
Xost: www.google.co.jp (グーグル searchを実行した時に大量に振ってくるパケットに偽造して IPSにひっかからないようにしている)
UPDATE
(自己消滅するものも?)
FTP情報の窃盗 (Header S0:S1 に FTPのaccountをのせている)
Anti Anti-Virus for
IET / HTTP/1.1 ? なんで IET (オンラインスキャンも,trial version もdownloadできなくする)
CLEANING DEMO
Gumblar対策
感染予防
OS/Software Update
Anti Virus softわれの導入
ScriptやActive XのOff
- Adobe製品,Webブラウザ
パスワードの管理を徹底する?
- 保存しない
- 平文で送らない
- 定期的に更新する
仮想化を使う
- VMware
- サンドボックス
あとは運を天に任せる
感染してしまったら
- 感染PCの処理
+ ウィルスの駆除
+ OSのリカバリ
- Webページの修正
- パスワードの変更
- Backdoorの削除
- 謝罪文ページの作成
自分のnote難読化されたJavaScript (そもそも何でそんなことが置きているのか)
unescape, escape コードを動的に生成する。
自分はunix系サーバーなので,Gumblarなんて関係ないよと思ってはいけない。
侵入されたら,<script src="*php"> >-ー これが正規のホスト が埋めこまれるので,感染の土台となる。 passwordの管理。application作者は,生でpasswordを保存してはいけない。セキュアなpasswordの扱い方を。(core-dumpされても大丈夫なように)。IPAのセキュア・プログラミング講座の附則の事態対策など読んでおくべき。
大変だ…。
Friday, February 12, 2010
ChromeとEmacsを愛するもの達へ 【編集あり】
Chromeもいいけど,TextareaはEmacsで編集したいのでFirefox + Dafizilla ViewSourceWith から抜けだせないあなたへ。
- Google Chrome のテキストエリアを外部エディタで編集する Edit with Emacs (酒日記 はてな支店)
- Google Chromeのtextareaを外部エディタで編集する (Ruby版) (monoの開発ブログ)
自分はやっぱりemacsclientを使いたいのと,Ruby on Railsの環境を構築済みなので,monoさんのWEBrickを用いたWebサーバー版のを使わせていただきました。
しかし,
temp << req.bodyではutf-8を上手くあつかえていないので( << が駄目だと思う ),自分のところでは,
temp.puts req.body.toutf8に手直しして使っています。
自分のところのruby-server.rbはこんな感じです。どうもありがとうございました。
#!/usr/bin/ruby -Ku
require 'webrick'
require 'tempfile'
require 'kconv'
$EDITOR = '/Applications/Emacs.app/Contents/MacOS/bin/emacsclient'
$PORT = 9292
server = WEBrick::HTTPServer.new(:Port => $PORT)
trap('INT') { server.shutdown }
server.mount_proc('/status') do |req, res|
res.status = 200
end
server.mount_proc('/edit') do |req, res|
temp = Tempfile.new('editwith_')
if req.body
temp.puts req.body.toutf8
end
temp.close false
system $EDITOR, temp.path
temp.open
res.body = temp.read.toutf8
temp.close
res.status = 200
res['Content-Type'] = 'text/plain'
res['Content-Length'] = res.body.size
end
server.start
追記 req.body の nil チェック忘れてました。
if req.body
temp.puts req.body.toutf8
end
Sunday, January 24, 2010
Dashboard用のWidget開発してみました
前回のPAkita.mの終わりごろに,何かWidgetを作成してみると宣言したので,試しにDashboard用のWidget,アナログ時計を作成してみました。
開発中の画面はこんな感じです。
公開は,背景画の使用許可を(書面で!)得なければならないので後ほど。
基本となるHTMLやJavaScriptの動作確認はChronium上で,Dashboard用Widgetを作成する際のデザインや約束事はDashcodeで作成いたしました。この内容を適当に数枚(3,4枚?)ぐらいのスライドにまとめて,紹介できればいいかなと考えています。
次回のAkita.mの出席できるかどうか未定ですが…(すいません。いつも。)



