問題のファイルはこちら
#!/usr/bin/ruby
#
# CTF勉強会で出題されたforensic300を解くプログラム
# 2008/12/6
#
# RMagickはgemsとかでいれてください
#
# $ sudo gem install rmagick
#
# 参考:
# RMagick 1.15.0 User's Guide and Reference
# http://www.simplesystems.org/RMagick/doc/
#
require 'rubygems'
require 'rmagick'
def usage
STDERR.puts "usage : #{__FILE__} image_file"
exit 0
end
usage if ARGV.size == 0
img = Magick::ImageList.new(ARGV[0])
pixels = img.get_pixels(0, 0, 6, 1)
pixels.each {|p|
#RMagickでは0〜65535で表現されるみたいなので
#0〜255の間に変換している
r = p.red >> 8
g = p.green >> 8
b = p.blue >> 8
a = p.opacity >> 8
# for test...
#puts "ARGB: #{a} #{r} #{g} #{b}"
#puts " : #{[255-a,r,g,b].pack("C*")}"
print [255-a,r,g,b].pack("C*")
}
puts
CTF勉強会の時にちょっとだけ作ってみたプログラムです。
//
// gcc -I/usr/local/include/opencv -L/usr/local/lib -lhighgui -lcv -lcxcore -o f400 f400.c
//
#include <stdio.h>
#include <cv.h>
#include <highgui.h>
#if _WIN32
#pragma comment(lib, "cv.lib")
#pragma comment(lib, "cxcore.lib")
#pragma comment(lib, "highgui.lib")
#endif
int
main (int argc, char **argv)
{
CvCapture *cap;
IplImage *img;
// 動画ファイルをオープン
cap = cvCaptureFromFile("f400.mpg");
// 1フレームをキャプチャ
img = cvQueryFrame (cap);
// キャプチャしたイメージを保存
cvSaveImage ("f400.png", img);
cvReleaseImage (&img);
return 0;
}
Mac OS Xで動作確認していますが、たぶんVisualC++でも使えると思います(未確認)
OpenCVの動画ファイルの取り扱いはDirectShowとかQuickTimeのコーデックが使われるはずです。 詳しくはhighguiの中身を見てくださいw
Pythonの練習とCTF勉強会のforensic510を考えるために作ったプログラムです。 作りかけ途中なのですが、とりあえずここにメモ。
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# CTF勉強会で出題されたforensic510を回答するプログラム(書きかけ途中)
#
# 実行前にあらかじめPILをインストールしておいてください。
#
# Python Imaging Library (PIL)
# http://www.pythonware.com/products/pil/
#
import sys, os
import PIL.Image
import PIL.ImageDraw
if len(sys.argv) == 1:
print "usage: " + __file__ + " image_file\n"
sys.exit()
# 画像のロード
img = PIL.Image.open(sys.argv[1])
d = PIL.ImageDraw.Draw(img)
w = img.size[0]
h = img.size[1]
# RGBAのAのあるところは削除
for y in range(0, h):
for x in range(0, w):
c = img.getpixel((x,y))
if c[3] == 0:
c = (c[0], c[1], c[2], 255)
else:
c = (0, 0, 0, 0)
d.point((x,y), c)
img.save("process1.png")
# 頻度解析
# key:色,value:カウント
hist = {}
for y in range(0, h):
for x in range(0, w):
color = img.getpixel((x,y))
hist[color] = (hist[color] + 1) if hist.has_key(color) else 1
# (0,0,0,0)の色は抜いておく
del hist[(0,0,0,0)]
# key:カウント,value:色の配列
r_hist = {}
for color, count in hist.iteritems():
if r_hist.has_key(count):
r_hist[count].append(color)
else:
r_hist[count] = [color]
#count_keys = r_hist.keys()
#count_keys.sort()
#for count in count_keys:
# print count, r_hist[count]
max_count = max(r_hist.keys())
max_color = r_hist[max_count][0]
print "一番多い色: 数:%d, 色:%s" % (max_count, r_hist[max_count])
# 一番多い色の点のx,y座標を取得
pos = []
for y in range(0, h):
for x in range(0, w):
color = img.getpixel((x,y))
if color == max_color:
pos.append((x,y))
print pos
for p in pos:
x = p[0]
y = p[1]
print "(x,y) = (%03d, %03d) x+y=%d x-y=%d y-x=%d " % (x, y, x+y, x-y, y-x)
# 一番多い色の点を強調して表示する
for y in range(0, h):
for x in range(0, w):
c = img.getpixel((x,y))
if c == max_color:
c = (255, 0, 0, 255)
else:
# 該当しないところは少し明るさをおさえて表示
c = (c[0]/10, c[1]/10, c[2]/10, 255)
d.point((x,y), c)
img.save("process2.png")
PILはなかなかいい感じに使えるライブラリだけど、 個人的にPythonに慣れてないので、関数とかクラスの 使い方を調べている時間の方が長かったり(汗
Pythonを書くのに参考にしたサイトはこのあたりです。
それnkfでできるよ。ということでメモ。
エンコード $ echo -n "hello world" | nkf -MB aGVsbG8gd29ybGQ= デコード $ echo -n aGVsbG8gd29ybGQ= | nkf -mB hello world
Base64についての詳細についてはWikipediaあたりを参照。
元データのサイズがちょうど3の倍数のときは文字列の終端に=がつかないのですが、 予選問題のときは分かりやすく==がついていることを期待しておきますw
◆ xcorp [/usr/bin/base64 ってのがあるよね]
◆ yoggy [おお、それは知らんかった(;´Д`)]
◆ TIP [JS使ってatob()でやってます。]