ニュース

普通にRedmineを使っているとUTF8の4Byte文字が入力できない事に気付く

kanata7年以上前に追加

「𩸽」「🍠」「🍣」とか、軒並み入力できない

正確には入力できるんだけど、保存後の表示とかがおかしくなった

原因は、Mariadb(MySQL)の設定文字コードが、「latin1」とかいうよく解らない文字コードになっているから

Mariadb(MySQL)にログインした後、以下のSQLを実行することで、現状の文字コードが確認できる

> show variables like 'char%';

よっしゃ、そしたらutf8にしたるわ。。。と思っても1つ落とし穴がある。

Mariadb(MySQL)には、 utf8 という設定値と utf8mb4 という設定値の両方があり、4Byte文字を格納するためには、 utf8mb4 に設定しなければならない。

対策は、現状のDB文字コード設定を変更して、かつ、現状使用しているテーブルの文字コードも変更するということをしないといけない。

詳細は、以下を参照。

ALMInium - MariaDB(MySQL)の文字コードをutf8mb4にする

以下を参照して実施しました。ありがとうございます大変助かりました。

Dig that groovy! - Redmine構築後のDBの文字コードをutf8mb4に変換して絵文字に対応する
http://zappy.hatenablog.jp/entry/2015/05/19/015044

参考:世界の特殊文字ウィキ - ユニコード6.0以降で使用できる絵文字(食編)

Redmineのwikiでもシェルスクリプトに色を着けたい

kanata7年以上前に追加

デフォルトでbashのシンタックスハイライトの機能が無かったので、色のない簡素な感じになっていた。
こんな感じ。

#!/bin/bash

DATA=`date`
echo "This is test. ${DATE}"

これを、以下のように色つけるための手順
素敵。

#!/bin/bash

DATA=`date`
echo "This is test. ${DATE}"

詳細

Redmine - BASH Syntax Highlighting(bashのシンタックスハイライトを追加)

第24回◯◯o◯裏番組シェル芸勉強会に参加させて頂きました!

kanata7年以上前に追加

第24回◯◯o◯裏番組シェル芸勉強会に参加させて頂きました。

シェルスクリプト大好きなんですが、今回は新しい知見が得られすぎて、目からうろこが滝のように落ちました。
問題解説は、本家のサイトが詳しいので、そちらにお任せするとして、ここは私なりの感想と解説(?)をしたいと思います。

【問題と解答】第24回◯◯o◯裏番組シェル芸勉強会

第6回もう初心者向けでないなんて言わないよ絶対午前のシェル勉強会/第24回◯◯o◯裏番組シェル芸勉強会

Q1

$ cat Q1
玉子 卵 玉子 玉子 玉子 玉子
玉子 玉子 卵 卵 卵 玉子
卵 玉子 卵 玉子 玉子 玉子
卵 玉子 卵 卵 卵 卵
玉子 卵 玉子

上のようなQ1ファイルについて、次のような出力を得てください。

玉子:5 卵:1 
玉子:3 卵:3 
玉子:4 卵:2 
玉子:1 卵:5 
玉子:2 卵:1 

解答&解説

現地では、時間切れ。解説を聞いてなるほど~。と思った。むしろawk芸。

$ cat Q1 | awk '{for(i=1;i<=NF;i++){a[$i]++};for(k in a){printf("%s:%d ",k,a[k]);a[k]=0}print ""}'

私なりに解説しますと、awkの所がこんな感じ。

{
  for(i=1;i<=NF;i++){
    a[$i]++                  # 連想配列を使って、玉子と卵をカウント
  };
  for(k in a){
    printf("%s:%d ",k,a[k]); # 1行分の玉子と卵を出力
    a[k]=0                   # 連想配列を初期化
  }
  print ""                   # 改行を出力
}

Q2

次のようなテキストについて、繰り返し出てきた文字の2つ目以降を省いて出力してください。例えばQ2のファイル

$ cat Q2
へのへのもへじ

の場合、「へのもじ」が正解の出力になります。

解答&解説

自分が作ったシェル芸と解答が同じだった

$ cat Q2 | grep -o . | awk '{if(!a[$1]){printf $1};a[$1]=1}END{print ""}'

横文字を縦にする技

$ echo abcdefg | grep -o .
a
b
c
d
e
f
g
$ echo abcdefg | fold -w 1  # これでもいいか
a
b
c
d
e
f
g
$ echo abcdefg | sed 's/./&\n/g' # まぁ、これでもいいか
a
b
c
d
e
f
g

awk部分の解説

{
  if(!a[$1]){ # 連想配列の要素が存在していなかったら
    printf $1 # 文字を表示する
  };
  a[$1]=1     # 連想配列を存在させる
}
END{
  print ""    # 最後の最後に改行する
}

Q3

$ cat Q3
金 日成
キム ワイプ
金 正日
キム タオル
金 正男

というデータを、

%%
キム タオル
キム ワイプ
%%
金 正男
金 正日
金 日成
%%

というように第一フィールドをキーにして%%でレコードを区切ってください。awkを使ってできた人は、awkを使わないでやってみてください。

解答&解説

$ sort Q3 | awk '{if($1!=a){print "%%";print;a=$1}else{print}}END{print "%%"}'

awk解説

{
  if($1!=a){    # 1個目の要素(キムか金)が、aじゃなかったら
    print "%%"; # %%を出力
    print;      # 1行出力 
    a=$1        # aに1個目の要素(キムか金)を代入
  }else{
    print       # 1行出力
  }
}
END{
  print "%%"    # 最後の%%を出力
}

なるほどね~

Q4

Q4.xlsxのA1のセルには数字が書いてあります。その数字を出力してください。A4には文字列が書いてあるので余裕がある人はそれも特定してみましょう。

解答&解説

拡張子xlsxのファイルは実はzipという事を知っていれば、なんとかなる問題

A1のセル

初めて使ったけど、zipgrepというコマンドを使った。上田先生の解答はunzip -p を使っていました。

$ zipgrep . Q4.xlsx |grep A1
caution: filename not matched:  [Content_Types].xml
xl/worksheets/sheet1.xml:<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac"><dimension ref="A1:B4"/><sheetViews><sheetView tabSelected="1" workbookViewId="0"><selection activeCell="A5" sqref="A5"/></sheetView></sheetViews><sheetFormatPr baseColWidth="12" defaultRowHeight="18" x14ac:dyDescent="0"/><cols><col min="1" max="1" width="15.83203125" bestFit="1" customWidth="1"/><col min="2" max="2" width="14.33203125" bestFit="1" customWidth="1"/></cols><sheetData><row r="1" spans="1:2"><c r="A1"><v>114514</v></c><c r="B1" t="s"><v>0</v></c></row><row r="2" spans="1:2"><c r="A2" t="s"><v>1</v></c><c r="B2" t="s"><v>3</v></c></row><row r="3" spans="1:2"><c r="A3" t="s"><v>2</v></c><c r="B3" t="s"><v>4</v></c></row><row r="4" spans="1:2"><c r="A4" t="s"><v>6</v></c><c r="B4" t="s"><v>5</v></c></row></sheetData><phoneticPr fontId="1"/><pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3"/><extLst><ext uri="{64002731-A6B0-56B0-2670-7721B7C09600}" xmlns:mx="http://schemas.microsoft.com/office/mac/excel/2008/main"><mx:PLV Mode="0" OnePage="0" WScale="0"/></ext></extLst></worksheet>

これで答えが見えるので、強引になんとかできる。

$ zipgrep . Q4.xlsx |sed 's/<c/\n<c/g'|grep r=\"A1|cut -d '>' -f 3 |cut -d '<' -f 1
114514

A4のセル

上田先生のエクシェル芸ツールを使ってズルしたw

$ exread-str Q4.xlsx 
0 シェル芸バイブ
1 危険シェル芸
2 キュアエンジニア
3 ドラゴン曲線
4 素数
5 変態シェル芸
6 エクシェル芸

A4のセルに入っている文字列が、6番めの"エクシェル芸"であるということは、以下でわかる

$  zipgrep . Q4.xlsx |sed 's/<c/\n<c/g'|grep A4
caution: filename not matched:  [Content_Types].xml
<c r="A4" t="s"><v>6</v></c>

Q5

ファイルQ5について、xに好きな数を代入して各行の式を計算してください。

$ cat Q5
x + x^2
x + 1/x
x*x*x

余裕のある人は、例えばxに2を代入したければ、

$ echo 2 | ...

というようにecho <代入したい数>から始めてワンライナーで解いてみてください。

解答&解説

解説を聞いて、はえ~ってなった。

$ echo -2 | xargs -I@ awk -v a=@ '{gsub(/x/,a,$0);print}' Q5 | bc -l

awkは、こんな感じ

# a変数には、-2が設定されているところからスタート
{
  gsub(/x/,a,$0); # xを-2で置換 $0は1行全体が置換対象という意味
  print           # 出力
}

Q6

「玉子」と「卵」の数を数えて、数が少ない方を数が大きい方で置換してください。

$ cat Q6 
卵卵玉子玉子玉子玉子玉子卵卵卵玉子玉子卵玉子玉子玉子玉子卵卵玉子卵玉子卵卵玉子卵玉子

解答&解説

力技でいかようにもできそうだけれど、エレガントな解法を考えるとキツイ
解答もやっぱり力技だったw

$ cat Q6 | grep -oE '(玉子|卵)' | sort | uniq -c | sort -n -k1,1n | awk '{print $2}' | xargs | awk '{print "s/"$1"/"$2"/g"}' | xargs -I@ sed @ Q6

grep -oE '(玉子|卵)' は、縦にする魔法。mecabを使うという方法もあったが、私の環境には入っていない。

$ cat Q6 | grep -oE '(玉子|卵)' 
卵
卵
玉子
玉子
玉子
玉子
玉子
卵
卵
卵
玉子
玉子
卵
玉子
玉子
玉子
玉子
卵
卵
玉子
卵
玉子
卵
卵
玉子
卵
玉子

カウントすると玉子の方が多いですね

$ cat Q6 | grep -oE '(玉子|卵)' | sort | uniq -c | sort -n -k1,1n 
     12 卵
     15 玉子

次が新しい知見で、awkでなんとsedのパラメタを作り出して流しこむという・・・!!

これが

$ cat Q6 | grep -oE '(玉子|卵)' | sort | uniq -c | sort -n -k1,1n | awk '{print $2}' | xargs | awk '{print "s/"$1"/"$2"/g"}' 
s/卵/玉子/g

こうなる・・・!

$ cat Q6 | grep -oE '(玉子|卵)' | sort | uniq -c | sort -n -k1,1n | awk '{print $2}' | xargs | awk '{print "s/"$1"/"$2"/g"}' | xargs -I@ sed @ Q6
玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子

Q7

次のseq(あるいはjot等)の出力から、各桁の数字の構成が同じもの(例: 11122と22111等)を重複とみなし、除去してください。

$ seq -w 00000 99999

解答&解説

考え方は合ってたんだけど、コードが書けなかった。
考え方としては、1行の各数字をソートして、uniqすればいい(上田先生の解答では、 sort -u を使っている)
awkのasort関数か~。そういうのがあるのか~。

$ seq -w 00000 99999 | sed 's/./& /g' | awk '{for(i=1;i<=NF;i++)a[i]=$i;asort(a);for(k in a){printf a[k]}print ""}' | sort -u

空白区切りでバラす技

$ echo abcdefg | sed 's/./& /g'
a b c d e f g 

awkは、こんな感じ

{
  for(i=1;i<=NF;i++)a[i]=$i; # 連想配列に数字を格納
  asort(a);                  # 連想配列aをソート
  for(k in a){               # 
    printf a[k]              # そして表示
  }
  print ""                   # 改行を出力
}

Q8

  1. まず、1〜7を全て含む7桁の整数を全て列挙して、tmpというファイルに出力してください。

  2. 次に、相異なる7以下の正の整数a,b,c,d,e,f,gを用いて、

abcd + efg

と表せる素数と、その時のa〜gの数字を全て求めましょう。tmpを用いて構いません。

(参考: 2011年日本数学オリンピック予選第3問から。一部改。http://www.imojp.org/challenge/old/jmo21yq.html)

解答&解説

まず、1〜7を全て含む7桁の整数を全て列挙して、tmpというファイルに出力してください。

ズルしたw
自作の重複順列作成ツールがあるので、それを使ってしまった。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# 重複順列求めるツール ver 0.1
# 2016.08.02 kanata

import sys
from itertools import permutations

if( (len(sys.argv)-1) != 2 or not sys.argv[1].isdigit() ):
  print 'Usage:'+sys.argv[0]+" [length] [element]"
  print '   ex:'+sys.argv[0]+" 3 abc123"
  sys.exit(1)

# permutations…重複順列
# combinations…組み合わせ
itr = permutations(sys.argv[2],int(sys.argv[1]))

for i in itr:
  print "".join(map(str,i))
sys.exit(0)
$ permutations.py 7 1234567
1234567
1234576
1234657
  .
  .
7654321

ただ、上田先生の解法が目から鱗で、1234567の全てを含む結果を出せばいいだけだった。

$ seq -w 0000000 9999999 | grep -v [089] | grep 1 | grep 2 | grep 3 | grep 4 | grep 5 | grep 6 | grep 7 > tmp

次に、相異なる7以下の正の整数a,b,c,d,e,f,gを用いて...

factorコマンドを使うというイメージはあったんだけど、そこで止まった。

$ cat tmp | sed 's/./& /g' | awk '{print $1$2$3$4$5$6$7,$1*$2*$3*$4+$5*$6*$7}' | while read a b ; do echo $b | factor | awk -v n=$a 'NF==2{gsub(/./,"& ",n);print n,$2}' ; done

まず、[元の数字列] [計算結果]というフォーマットを出力する

$ cat tmp | sed 's/./& /g' | awk '{print $1$2$3$4$5$6$7,$1*$2*$3*$4+$5*$6*$7}' 
1234567 234
1234576 234
1234657 234
     .
     .

これに対してwhile文を使う

while read a b
do
  echo $b | factor | awk -v n=$a 'NF==2{gsub(/./,"& ",n);print n,$2}'
done

$bが素数であるという事と、それを表示するという事を以下でやってる。

$ echo 179 | factor | awk -v n=$a 'NF==2{print $2}' # 素数じゃなかったら出力されない
179

いい感じで整形した結果

$ cat tmp | sed 's/./& /g' | awk '{print $1$2$3$4$5$6$7,$1*$2*$3*$4+$5*$6*$7}' | while read a b ; do echo $b | factor | awk -v n=$a 'NF==2{gsub(/./,"& ",n);print n,$2}' ; done
2 3 4 6 1 5 7  179
2 3 4 6 1 7 5  179
2 3 4 6 5 1 7  179
        .
        .
        .

勉強になりました~。

アクセスログから、Googleでどんな検索をして、このサイトに来たかを知る方法

kanata7年以上前に追加

やりたいこと

まず、こういうタイプのApacheのログがある。

999.999.999.999 - - [01/Jun/2016:00:00:00 +0900] "GET /projects/a-painter-and-a-black-cat/news HTTP/1.1" 200 54953 "https://www.google.co.jp/search?q=%E7%94%BB%E5%83%8F+%E3%83%87%E3%83%BC%E3%82%BF+%E9%9A%A0%E8%94%BD+ctf&btnG=%E6%A4%9C%E7%B4%A2&hl=ja" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0"

このログからは、googleで検索して、このページに来たことがわかる。Refererに記録されている。

ただ、マルチバイト文字は、すべからくURLエンコードされていて、そのままでは読めない。ログから、それを抽出して、デコードして表示してみましょう。

Google Analyticsを使えばいいという話もあるけれど、シェル芸の練習でやってみます。

ログの抽出

ここがシェルスクリプトの真骨頂である。1行でいける。

まず、該当のログを出力してみる。

# cat /var/log/httpd/access_log-???????? /var/log/httpd/access_log

全部のログが表示されちゃう。絞り込んでみよう。

  • "google"が含まれるログに絞り込む。
| grep google
  • そこから、"Googlebot"を含まないログに絞り込む。
|grep -v Googlebot
  • そこから、q=&"を含まないログに絞り込む。
|grep -v "q=&"
  • そこから、"q=cache"を含まないログに絞り込む。
|grep -v "q=cache"
  • そこから、"q="を含むログに絞り込む。
|grep q=

全部くっつけて、、、こうじゃ!

# cat /var/log/httpd/access_log-???????? /var/log/httpd/access_log |grep google|grep -v Googlebot|grep -v "q=&"|grep -v "q=cache"|grep q=

環境の違いで、微妙に上手くいかない人もいるかと思うが、適宜調整してください。

URLデコード

URLデコードは、実はワンライナーで実現できる。

perl -e '$ARGV[0]=~s/\+/ /g;$ARGV[0]=~s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg;print"$ARGV[0]\n"' "ここにURLエンコードデータ"

上の方に書いたログで試してみよう。

対象は、以下の部分である。

%E7%94%BB%E5%83%8F+%E3%83%87%E3%83%BC%E3%82%BF+%E9%9A%A0%E8%94%BD+ctf

ほい。

$ perl -e '$ARGV[0]=~s/\+/ /g;$ARGV[0]=~s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg;print"$ARGV[0]\n"' "%E7%94%BB%E5%83%8F+%E3%83%87%E3%83%BC%E3%82%BF+%E9%9A%A0%E8%94%BD+ctf"
画像 データ 隠蔽 ctf

さて、ログから該当部分を抽出するにはどうするか。

こうした。

  • "q="を区切り文字として、それ以降を出力
echo 'ログのデータ1行' | awk -F'q=' '{print $2}'
  • "&"を区切り文字として、その手前を出力
|awk -F'&' '{print $1}'
  • "(ダブルコーテーション)を区切り文字として、その手前を出力
|awk -F'\"' '{print $1}'

全部くっつけて、、、こうじゃ!

echo 'ログのデータ1行' | awk -F'q=' '{print $2}'|awk -F'&' '{print $1}'|awk -F'\"' '{print $1}'

実際に試してみよう。

$ echo '999.999.999.999 - - [01/Jun/2016:00:00:00 +0900] "GET /projects/a-painter-and-a-black-cat/news HTTP/1.1" 200 54953 "https://www.google.co.jp/search?q=%E7%94%BB%E5%83%8F+%E3%83%87%E3%83%BC%E3%82%BF+%E9%9A%A0%E8%94%BD+ctf&btnG=%E6%A4%9C%E7%B4%A2&hl=ja" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0"' | awk -F'q=' '{print $2}'|awk -F'&' '{print $1}'|awk -F'\"' '{print $1}'
%E7%94%BB%E5%83%8F+%E3%83%87%E3%83%BC%E3%82%BF+%E9%9A%A0%E8%94%BD+ctf

ちゃんと抽出できてますね。

Googleでどんな検索をして、このサイトに来たかを知るツール(シェルスクリプト)

それで、こんなシェルスクリプトを作ってみた。
時系列でどんな検索ワードで飛んできたかわかる。

PrintGoogleSearchWords.sh

#!/bin/bash

IFS='
'

CONTENT=`cat /var/log/httpd/access_log-???????? /var/log/httpd/access_log |grep google|grep -v Googlebot|grep -v "q=&"|grep -v "q=cache"|grep q=`

for WORD in ${CONTENT}
do
  HOST_NAME=`echo ${WORD} | awk '{print $1}'`
  ACCESS_DATE=`echo ${WORD} | awk '{print $4}'|tr -d '['`
  URL_ENCODE_DATA=`echo ${WORD} | awk -F'q=' '{print $2}'|awk -F'&' '{print $1}'|awk -F'\"' '{print $1}'`
  URL_DECODE_DATA=`perl -e '$ARGV[0]=~s/\+/ /g;$ARGV[0]=~s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg;print"$ARGV[0]\n"' ${URL_ENCODE_DATA}`
  printf "%s %15s %s\n" ${ACCESS_DATE} ${HOST_NAME} ${URL_DECODE_DATA}
done

exit 0

ファイルに含まれるbase64部分を抽出・デコードしてファイルに保存するツール作りました

kanata7年以上前に追加

ファイルに含まれるbase64部分を抽出・デコードしてファイルに保存するツール

これでちょっとは楽になるんじゃないだろうか。

CTFって、Base64が頻出するわりには、手作業でデコードしてたので、嫌になって自動化した。
これでちょっとは楽になるかな?

$ base64_extraction.py test.txt 
checking...7190/42005   test_7191.png
checking...13406/42005  test_13407.png
checking...18594/42005  test_18595.png
checking...24697/42005  test_24698.png
checking...29677/42005  test_29678.png
checking...35553/42005  test_35554.png
checking...38782/42005  test_38783.png
checking...41550/42005  test_41551.stream

まぁ長いASCII文字列があるとBase64形式だと見誤ってデコードしちゃうんだけど、それはもぅ回避できない仕様。

詳細

CTF Crypto - ファイルに含まれるbase64部分を抽出・デコードしてファイルに保存するツール

江戸前セキュリティ勉強会(2016/08)に参加してきました

kanata7年以上前に追加

江戸前セキュリティ勉強会(2016/08)に参加してきました

江戸前セキュリティ勉強会(2016/08) - 江戸前セキュリティ勉強会

三村聡志さんの、流れるようなマクラからの入りは、もぅそれ落語家として食べていけるレベルでしたw

園田先生のSECCON GOも楽しかったです。CTFの裏側が見えて面白かったです。

NECTFの園田さんも、なんか、よくわかります。。企業内の苦労話。

Trendmicro CTFの岩田さん、先日は楽しませて行きました。
そう言えば、TMCTF2016のForensic 200の問題ファイルが3Gバイトだったけど、アレ何の問題(トラフィック的な)もなくダウンロードできたんですよね。やっぱりアレは、あのインフラのなせる技ですか。と、質問しようと思ってたのを後で思い出しました。残念。

CTF for GILRS!鈴木さん、裏方はとっても大変な部分もあると思いますが、応援しております!
AMATERAS零(アマテラス・ゼロ)カッコイイよね。

仕切ってくださった、まっちゃだいふくさんお疲れ様でした。ともて有意義でございました。

しかもお菓子が出るんです!!ごちそうさまです!美味でございました。(しかも2個食べました)

20160806_edomaesec.jpg

また参加したいと思いました!

Trend Micro CTF 2016 Writeup

kanata7年以上前に追加

CTF Writeup TMCTF2016

結果&感想

Trend Micro CTF 2016 に、某チームで参加しました。
結果は、去年より若干悪くなっている(と言っても、国内10位以内)んだけれど、予め申し上げておくと、今回、私は 得点できず でした。
いやぁ、難しかった。去年も難しかったけど、今年は輪をかけて難しかった。

そんな中でも、チームのc@tさんとリリりん♪さんは、やはりひと味違ってましたね。。

ままま、アシストできた問題と、良い所まで行った問題のwriteupというか、解った所までを書こうと思います。

20160730_tmctf_seika.jpg

Trend Micro CTF Asia Pacific & Japan 2016 オンライン予選 ランキングページ
https://ctf.trendmicro.co.jp/ranking.html

Analysis - defensive 100

Decode me!

で、こんなファイルが渡される。

decodeme_decodeme.php

<?php
$GLOBALS['key'] = "6c7f4d49729e58d7a458999b570e0151bc034ca7"; 
$func="cr"."eat"."e_fun"."cti"."on";$decodeme=$func('$x','ev'.'al'.'("?>".gz'.'in'.'fla'.'te(ba'.'se'.'64'.'_de'.'co'.'de($x)));');$decodeme("7f1n0+zMcSgIfh...base64っぽい文字列が続く...tP34vUP6/");?>

お、PHPやんけ!実行したろ。。と思って、実行するとhtmlが出力されるが、特にflagやヒント等は書かれていない。

    <html><head><meta http-equiv='Content-Type' content='text/html; charset=utf-8'><meta http-equiv='Content-Language' content='en-us'>                                                               
    <title>decodeme</title>                                       
    <style type='text/css'>                                       
    <!--                                                          
    body{ background-color:darkred; color:white; }                
    hr{ background-color:dimgray; color:dimgray; border:0 none; height: 2px; }                                                      
    -->                                                           
    </style>                                                      
    </head>                                                       
    <body>                                                        
    <br><br>                                                      
    <form method='post'>                                          
    <center>                                                      
    <input type='password' id='key' name='key'>                   
    <p>enter ****</p>                                             
    </center>                                                     
    </form>                                                       
    </body></html>                                               

デコード

その時「元のサイズが32kもあるんだから、そんな短いhtmlになるのはおかしい。eval直前の値を取り出したら良いのでは」

と c@tさんが教えてくれた

あぁ、そうか、なるほど。ちょっと解りにくくしてあるけど、コードを整理してみよう。

<?php
$GLOBALS['key'] = "6c7f4d49729e58d7a458999b570e0151bc034ca7"; 
$func="create_function";
$decodeme=$func('$x','eval("?>".gzinflate(base64_decode($x)));');
$decodeme("7f1n0+zMcSgIfh...base64っぽい文字列が続く...tP34vUP6/");?>

こうなってる。で、こんな感じに修正して、eval直前の値を取り出す。
evalの所をprintに修正する。

<?php
$GLOBALS['key'] = "6c7f4d49729e58d7a458999b570e0151bc034ca7"; 
$func="create_function";
$decodeme=$func('$x','print("?>".gzinflate(base64_decode($x)));');
$decodeme("7f1n0+zMcSgIfh...base64された文字列が続く...tP34vUP6/");?>

すると、でた。沢山でた。

?><?php
// reference: https://github.com/b374k/b374k/blob/master/LICENSE.md
function chk_password(){
    if(!isset($GLOBALS['key'])){ die(); }
    if(trim($GLOBALS['key'])==''){ die(); }
    $glob = $GLOBALS['key'];

    $post = '';
    $cook = '';
    if (isset($_POST['key'])) { $post = $_POST['key']; }
    if (isset($_COOKIE['key'])) { $cook = $_COOKIE['key']; }
    if ($cook==$glob) { return; }

    if($post != ''){
        $key = sha1(md5($post));
        if($key==$glob){
            setcookie("key", $key, time()+36000, "/");
            $qstr = (isset($_SERVER["QUERY_STRING"])&&(!empty($_SERVER["QUERY_STRING"])))?"?".$_SERVER["QUERY_STRING"]:"";
            header("Location: ".htmlspecialchars($_SERVER["REQUEST_URI"].$qstr, 2 | 1));
            $cook = $_COOKIE['key'];
        }
    }

    $output = "
    <html><head><meta http-equiv='Content-Type' content='text/html; charset=utf-8'><meta http-equiv='Content-Language' content='en-us'>
    <title>decodeme</title>
    <style type='text/css'>
    <!--
    body{ background-color:darkred; color:white; }
    hr{ background-color:dimgray; color:dimgray; border:0 none; height: 2px; }
    -->
    </style>
    </head>
    <body>
    <br><br>
    <form method='post'>
    <center>
    <input type='password' id='key' name='key'>
    <p>enter ****</p>
    </center>
    </form>
    </body></html>";

    echo $output;
    die();

}
chk_password();
?>

<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta http-equiv="Content-Language" content="en-us">
<title>decodeme</title>
<style type="text/css">
<!--
body{ background-color:darkred; color:white; }
hr{ background-color:dimgray; color:dimgray; border:0 none; height: 2px; }
-->
</style>
</head>

<?php
$GLOBALS['images']['version']= "iVBORw0KGgoAAAANSUhEUgAA...以下、省略

ざっと、全体を眺めてみると webshell を実現する何かみたい。
さてさて、怪しそうな所は・・・

デコードされたコードを読む・認証の仕組み

このデコードしたソースには、認証の方式がコーディングされている

ここ

    if($post != ''){
        $key = sha1(md5($post));
        if($key==$glob){

入力した値をMD5でハッシュ化して、さらにSHA1でハッシュ化したものと比べている。
比較している $globは・・・
これだろうな。

$GLOBALS['key'] = "6c7f4d49729e58d7a458999b570e0151bc034ca7"; 

あと、これもヒントだね。認証画面での入力は、4文字を期待しているっぽい。

    <form method='post'>
    <center>
    <input type='password' id='key' name='key'>
    <p>enter ****</p>
    </center>
    </form>

整理すると、こうだ。

  • flagは4文字
  • flagをmd5して、それを更にsha1すると 6c7f4d49729e58d7a458999b570e0151bc034ca7 になる

チームメンバがPNGファイルの中からExifを見つけてくれる

デコードしたソースは、このページでは省略しているけど、本当は、Base64でエンコードされた画像データが、いくつか埋まっていた。
ソース中に、こんなのがいくつかある。

$GLOBALS['images']['lock']= "iVBORw0KGgoAAAANSU...中略

    <img align="left" src="data:image/png;base64,<?php echo $GLOBALS['images']['lock']; ?>" alt="figure" />

その中の一つのpng画像に、Exifがあって、そこにBase64の文字列が入っていることをチームのメンバが発見してくれたのでした!

PNGはExif情報をサポートしてないから、無理やり入れたんだろうな。。

$ xxd image7.png |head
0000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452  .PNG........IHDR
0000010: 0000 0047 0000 0072 0803 0000 0141 de0c  ...G...r.....A..
0000020: a500 0000 a67a 5458 7452 6177 2070 726f  .....zTXtRaw pro
0000030: 6669 6c65 2074 7970 6520 6578 6966 0000  file type exif..
0000040: 78da 558e cb0d 4331 0804 efae 2225 9805  x.U...C1...."%..
0000050: 16bb 1cfb c596 d241 ca0f ef73 c94a 6860  .......A...s.Jh`
0000060: 0412 657d 3fbb bcce 8858 318f c64e d68c  ..e}?....X1..N..
0000070: 75eb 18d9 b47a 0759 bbca 457f 146f 4abd  u....z.Y..E..oJ.
0000080: bd3d ab05 47fd 0b36 1606 36f3 901e a4f0  .=..G..6..6.....
0000090: 4023 28a1 74a5 9a6f 1a9d ca8b 6880 0f8f  @#(.t..o....h...
$

デコードすると、以下のようになるとのこと。

echo 'flag is sha1(password)';

4文字のパスワードをsha1したのが答えですって事なんでしょう。

結果

それで、flagの4文字は、どうやって見つけるんだろう、総当りしかないのかしら?
と思っていろいろ調べてたんだけど、結局、c@tさんが一瞬で解いてくれました(総当りでw)

答え

h4ck

それを更にSHA1

TMCTF{e17e98788d6b4ac922b2df100ef9398ae0f229ad}

余談(ハッシュ値の総当り)

c@tさんに頂いたrubyスクリプトを参考に、総当りするPythonスクリプトとシェルスクリプトを書いてみた。

  • Python - 総当り
#!/usr/bin/env python

import sys
import hashlib
from itertools import permutations

answer = "6c7f4d49729e58d7a458999b570e0151bc034ca7"
itr = permutations("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",4)

for i in itr:
  password  = "".join(map(str,i))
  hash = hashlib.sha1(hashlib.md5(password).hexdigest()).hexdigest()
  if hash == answer:
    print password
    sys.exit(0)

print "Not found."
sys.exit(1)

実行結果

$ time python 20160802_TMCTF_defence100.py

h4ck

real    1m39.699s
user    0m38.926s
sys     0m0.106s
  • ShellScript - 総当り
#!/bin/bash

python permutations.py 4 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ > list.txt

MAX=`cat list.txt|wc -l`
I="0"

while read WORD
do
  HASH=`echo -n $WORD |md5sum |awk '{print $1}'|tr -d '\n'|sha1sum|awk '{print $1}'`
  if [ "$HASH" = "6c7f4d49729e58d7a458999b570e0151bc034ca7" ]
  then
    echo $WORD
    exit 0
  fi
  #I=$((I + 1))
  #printf "%d/%d\r" "$I" "$MAX"
done < list.txt

echo "Not found."
exit 1

順列の算出(総当りの元)は、やむを得ずPythonスクリプトを使った。
egzactが使えたかもしれない。

permutations.py

#!/usr/bin/env python

import sys
from itertools import permutations

itr = permutations(sys.argv[2],int(sys.argv[1]))

for i in itr:
  print "".join(map(str,i))

実行結果

$ time solv.sh
h4ck
6894.03user 13979.57system 26:07:07elapsed 22%CPU (0avgtext+0avgdata 1464maxresident)k
35744inputs+8outputs (78major+8601248019minor)pagefaults 0swaps

なんか26時間程かかっていた模様。実用に耐えないなw

余談(md5sum,sha1sumコマンドのハマり所)

普段何気なくシェル芸してハッシュ値を確認するんだけど、 ハッシュした値を更にハッシュする は、やった経験がなくて、微妙にハマった。

  • ハマった理由
■ダメな理由
$ echo -n h4ck |md5sum 
0ed5f1f056b1d96122afaae306d3dd65  -
                                ^^^
                                邪魔!

ゆえに、単純にパイプして出力すると期待したハッシュ値が得られない

■NG
$ echo -n h4ck |md5sum |sha1sum 
7265ca1966827b7cda1e61183cee77996aeca50d  -
■OK
$ echo -n h4ck |md5sum |awk '{print $1}'|tr -d '\n'|sha1sum 
6c7f4d49729e58d7a458999b570e0151bc034ca7  -

整理すると以下になる。ハッシュ値以外の余計なものを出力するやつは、途中にパイプを挟んでハイフンやら改行やらの削除が必要。

  • PHPの実行結果
$ cat md5.php 
<?php
$ans = md5($argv[1]);
echo $ans;
?>
$ php md5.php h4ck
0ed5f1f056b1d96122afaae306d3dd65
$ cat sha1.php 
<?php
$ans = sha1($argv[1]);
echo $ans;
?>
$ php sha1.php h4ck
e17e98788d6b4ac922b2df100ef9398ae0f229ad
$ cat md5_sha1.php 
<?php
$ans = sha1(md5($argv[1]));
echo $ans;
?>
$ php md5_sha1.php h4ck
6c7f4d49729e58d7a458999b570e0151bc034ca7
  • KaliLinuxでの実行結果

KaliLinuxには、md5deep,sha1deepというコマンドがあった。違いは知らん。ただ、語尾のハイフンが付いていない。

$ echo -n h4ck |md5sum
0ed5f1f056b1d96122afaae306d3dd65  -
$ echo -n h4ck |md5deep 
0ed5f1f056b1d96122afaae306d3dd65
$ echo -n h4ck |sha1deep 
e17e98788d6b4ac922b2df100ef9398ae0f229ad
$ echo -n h4ck |sha1sum 
e17e98788d6b4ac922b2df100ef9398ae0f229ad  -
$ echo -n h4ck |md5sum |awk '{print $1}'|tr -d '\n'|sha1sum 
6c7f4d49729e58d7a458999b570e0151bc034ca7  -
$ echo -n h4ck |md5deep |tr -d '\n'|sha1deep 
6c7f4d49729e58d7a458999b570e0151bc034ca7
  • CentOSでの実行結果

CentOSに md5deep,sha1deep というコマンドは無い。

$ echo -n h4ck |md5sum 
0ed5f1f056b1d96122afaae306d3dd65  -
$ echo -n h4ck |sha1sum 
e17e98788d6b4ac922b2df100ef9398ae0f229ad  -
$ echo -n h4ck |md5sum |awk '{print $1}'|tr -d '\n'|sha1sum 
6c7f4d49729e58d7a458999b570e0151bc034ca7  -

SCADA 100

Setup a free account on Shodan.io. 
Somewhere on the Class C network xxx.xxx.x.1-255 you will find a suspicious looking Gas Station.

Without directly interacting with the server (it will be offline during the qualifier),
but only using what Shodan has found for you - attempt to determine the flag

※ipアドレス xxx.xxx.x.1-255は、なんか迷惑がかかってもいけないので、伏せました。

Shodan先生を使った調査作業ですね。
こいつは結局最後まで解けなくて、そして、これに最も時間を費やしたw
解けそうで解けなかった。もどかしかった。。

問題の意図を確認

Setup a free account on Shodan.io.

Shodanのフリーアカウントを作りなさい

Somewhere on the Class C network xxx.xxx.x.1-255 you will find a suspicious looking Gas Station.

ガソリンスタンドのIPアドレスが xxx.xxx.x.1-255 にあるから、見つけなさい

Without directly interacting with the server (it will be offline during the qualifier),

発見したIPアドレスに接続は不要(どのみちオフラインだよ)

but only using what Shodan has found for you - attempt to determine the flag

Shodanだけ使ってflagを発見するのです!

なぜフリーアカウントを作るのか

フリーアカウントを作れという事は、アカウントがないと使えない機能があるということでしょう。

登録ページに Developer API が使えるっぽい事が書いてあるので、それを利用するんだなと予想しました。

ちなみに、①登録→②メールが来る→③メールにあるアドレスにアクセス→④ログインできるようになる。
んだけど、②のメールが迷惑メールフォルダに入ってて、気づかなくてハマった。

チームメンバが怪しいIPを発見してくれる

さっそく見つけてくれました。便宜上、ここでは xxx.xxx.x.189 としておきます。

得られた情報は、こんな感じ。

5900
tcp
http-simple
 RFB 003.007
authentication disabled

20160730_tmctf_scada100.jpg

10001
tcp
automated-tank-gauge
 I20100
07/20/2016 23:38

TMCTF FUEL STATION
Yubinbango151-0053
Mines Tower
Shinjuku

IN-TANK INVENTORY

TANK PRODUCT             VOLUME TC VOLUME   ULLAGE   HEIGHT    WATER     TEMP
  1  TMTANK1               3538      3647     7695    37.57     9.52    51.42
  2  TMTANK1               8902      9068     9781    73.94     9.17    59.27
  3  TMTANK3               8478      8614     3081    26.52     3.60    52.58
  4  TMTANK4               7552      7642     3081    55.77     6.51    50.54

スクリーンショットに怪しい値 "00 00 17 15 08 30 74 15 1e 12 0d 0f 0c 4e" が見えます。

ハマりポイント

さてさて、ログイン無しで得られる情報は、ここまでのようです。
さっそく Developer API を使ってみましょう。フリーアカウントを作ると、APIキーが発行されます。

ここでは便宜上 {SHODAN_API_KEY} と表現することにします。
Developer APIを使う時、APIキーが必要になります。

使える言語は、以下

SHODAN DEVELOPER Clients/ Libraries
https://developer.shodan.io/api/clients

RubyやPythonも使えますが、自分的には一番楽なRESTを使います。
RESTだったら、ブラウザか、curlコマンド一発で出ますし。おすし。

以下の使い方をみて、コーディング。
1行で書けるのは気持ちがいい。

SHODAN DEVELOPER REST API Documentation
https://developer.shodan.io/api

こんな感じ。jqを通しているのは、受信したJSONを整形したいので。

$ curl https://api.shodan.io/shodan/host/xxx.xxx.x.189?key={SHODAN_API_KEY}&history=true | jq .

これで、過去5回分ぐらいのスキャン結果が得られました!
これを舐めまわすように調べます。執拗に調べます。スクリーンショットにあった謎の数値も関係あるのでしょう。そこも意識して。

結果。

20160730_tmctf_seika.jpg

何の成果も得られませんでした。
キース隊長ばりにハゲるかと思った。

唐突に見つける別のIP

もぅ何も見つけられなくて、ぼんやりしながら、
そう言えば、このガソリンスタンドは TMCTF FUEL STATION って言うんだな、ふーん。

って、横になりながら
"TMCTF FUEL STATION" をShodanで検索してみると、別のIP(便宜上 yy.yyy.yyy.yy とします)が出た。

あれ・・・

Somewhere on the Class C network xxx.xxx.x.1-255 you will find a suspicious looking Gas Station.

ガソリンスタンドのIPアドレスが xxx.xxx.x.1-255 にあるから、見つけなさい

xxx.xxx.x.1-255の範囲じゃないのかww

こんな結果が出る!怪しい!怪しいぞ!

5353
udp
mdns
 \x00\x00\x84\x00\x00\x01\x00\x04\x00\x00\x00\x00\t_services\x07_dns-sd\x04_udp\x05local\x00\x00\x0c\x00\x01\xc0\x0c\x00\x0c\x00\x01\x00\x00\x00\n\x00\x13\x0b_udisks-ssh\x04_tcp\xc0#\xc0\x0c\x00\x0c\x00\x01\x00\x00\x00\n\x00\x08\x05_http\xc0F\xc0\x0c\x00\x0c\x00\x01\x00\x00\x00\n\x00\x07\x04_rfb\xc0F\xc0\x0c\x00\x0c\x00\x01\x00\x00\x00\n\x00\x0f\x0c_workstation\xc0F
10001
tcp
automated-tank-gauge
 I20100
07/11/2016 17:39

TMCTF FUEL STATION
Yubinbango151-0053
Mines Tower
Shinjuku



IN-TANK INVENTORY

TANK PRODUCT             VOLUME TC VOLUME   ULLAGE   HEIGHT    WATER     TEMP
  1  TMTANK1               9035      9136     6367    41.96     8.56    58.70
  2  TMTANK1               4312      4500     9107    62.78     4.42    59.44
  3  TMTANK3               7537      7689     3670    53.21     5.15    52.79
  4  TMTANK4               6454      6505     3670    28.29     9.14    54.19

なんだこのexploit的なコードが怪しい。

さぁもう一度 DEVELOPER API

DEVELOPER API を使って再度情報を取得

こんな感じ。さっきとやり方は同じ。

$ curl https://api.shodan.io/shodan/host/yy.yyy.yyy.yy?key={SHODAN_API_KEY}&history=true | jq .

すると。。
いっぱい情報ががが!

怪しいとろこを抜き出すと以下の通り

  "vulns": [
    "!CVE-2014-0160",
    "!CVE-2014-0160",
    "!CVE-2014-0160",

CVE-2014-0160は、懐かしのHeartbleedの脆弱性!

      "data": "220 flawless-server ESMTP Postfix (Ubuntu)\r\n250-flawless-server\r\n250-PIPELINING\r\n250-SIZE 10240000\r\n250-VRFY\r\n250-ETRN\r\n250-STARTTLS\r\n250-ENHANCEDSTATUSCODES\r\n250-8BITMIME\r\n250 DSN\r\n",

SIZE 10240000 …でかいサイズを要求し、Hearbleedの脆弱性を利用して鍵情報の流出を狙っているんじゃないだろうか。

      "data": "SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2\nKey type: ssh-rsa\nKey: AAAAB3NzaC1yc2EAAAADAQABAAABAQC4HCDyPMoybg5G+Tk7z84msC+BovKHFmdZduUXX+T1WwRw\nb51AWsXrbHnoCWvhWj1KJNkhzIQ4p1y3/TDpRCuCcUr+iMialVlJj8vkHMBCpbqnNe2NprMmvFdN\nL7PXtwfvCOIJKABalT/QgQ23RBsDlXomWP8ja+Bb5kRdJh18zRb5b3bZEyq52F5Uq//plH4Hx8Yd\n5WeuyxlsltO51ZhZBDunRRycYoV2exgpZX2o5oChPvEKwjwlwDV5VRN/JKl82Cdf23ekMDOrc7bN\nk9E8RycGAkDbIbHS/6mYxB62eRp+25g69IIIBnbRsaffl+UmzudvEVixzxLn+MNJ5hpJ\nFingerprint: ae:89:cd:05:90:4d:ec:56:9b:b9:f1:41:28:24:e3:77",
      "ssh": {
        "fingerprint": "ae:89:cd:05:90:4d:ec:56:9b:b9:f1:41:28:24:e3:77",
        "mac": "hmac-sha2-256",
        "cipher": "aes128-ctr",
        "key": "AAAAB3NzaC1yc2EAAAADAQABAAABAQC4HCDyPMoybg5G+Tk7z84msC+BovKHFmdZduUXX+T1WwRw\nb51AWsXrbHnoCWvhWj1KJNkhzIQ4p1y3/TDpRCuCcUr+iMialVlJj8vkHMBCpbqnNe2NprMmvFdN\nL7PXtwfvCOIJKABalT/QgQ23RBsDlXomWP8ja+Bb5kRdJh18zRb5b3bZEyq52F5Uq//plH4Hx8Yd\n5WeuyxlsltO51ZhZBDunRRycYoV2exgpZX2o5oChPvEKwjwlwDV5VRN/JKl82Cdf23ekMDOrc7bN\nk9E8RycGAkDbIbHS/6mYxB62eRp+25g69IIIBnbRsaffl+UmzudvEVixzxLn+MNJ5hpJ\n",
        "kex": {
          "languages": [
            ""
          ],
          "server_host_key_algorithms": [
            "ssh-rsa",
            "ssh-dss",
            "ecdsa-sha2-nistp256",
            "ssh-ed25519"
          ],
          "encryption_algorithms": [
            "aes128-ctr",
            "aes192-ctr",
            "aes256-ctr",
            "arcfour256",
            "arcfour128",
            "aes128-gcm@openssh.com",
            "aes256-gcm@openssh.com",
            "chacha20-poly1305@openssh.com",
            "aes128-cbc",
            "3des-cbc",
            "blowfish-cbc",
            "cast128-cbc",
            "aes192-cbc",
            "aes256-cbc",
            "arcfour",
            "rijndael-cbc@lysator.liu.se"
          ],
          "kex_follows": false,
          "unused": 0,
          "kex_algorithms": [
            "curve25519-sha256@libssh.org",
            "ecdh-sha2-nistp256",
            "ecdh-sha2-nistp384",
            "ecdh-sha2-nistp521",
            "diffie-hellman-group-exchange-sha256",
            "diffie-hellman-group-exchange-sha1",
            "diffie-hellman-group14-sha1",
            "diffie-hellman-group1-sha1"
          ],
          "compression_algorithms": [
            "none",
            "zlib@openssh.com"
          ],
          "mac_algorithms": [
            "hmac-md5-etm@openssh.com",
            "hmac-sha1-etm@openssh.com",
            "umac-64-etm@openssh.com",
            "umac-128-etm@openssh.com",
            "hmac-sha2-256-etm@openssh.com",
            "hmac-sha2-512-etm@openssh.com",
            "hmac-ripemd160-etm@openssh.com",
            "hmac-sha1-96-etm@openssh.com",
            "hmac-md5-96-etm@openssh.com",
            "hmac-md5",
            "hmac-sha1",
            "umac-64@openssh.com",
            "umac-128@openssh.com",
            "hmac-sha2-256",
            "hmac-sha2-512",
            "hmac-ripemd160",
            "hmac-ripemd160@openssh.com",
            "hmac-sha1-96",
            "hmac-md5-96"
          ]
        },
        "type": "ssh-rsa"
      }

鍵情報が出ちゃってるんじゃないだろうかw

あと、こういう怪しそうな情報が散見される。

      "data": "\\x00\\x00\\x84\\x00\\x00\\x01\\x00\\x02\\x00\\x00\\x00\\x00\\t_services\\x07_dns-sd\\x04_udp\\x05local\\x00\\x00\\x0c\\x00\\x01\\xc0\\x0c\\x00\\x0c\\x00\\x01\\x00\\x00\\x00\\n\\x00\\x14\\x0c_workstation\\x04_tcp\\xc0#\\xc0\\x0c\\x00\\x0c\\x00\\x01\\x00\\x00\\x00\\n\\x00\\x0e\\x0b_udisks-ssh\\xc0G",
      "data": "\\x03\\x00\\x00\\x0b\\x06\\xd0\\x00\\x00\\x00\\x00\\x00",
        "raw": "000084000001000200000000095f7365727669636573075f646e732d7364045f756470056c6f63616c00000c0001c00c000c00010000000a00140c5f776f726b73746174696f6e045f746370c023c00c000c00010000000a000e0b5f756469736b732d737368c047"

この鍵は・・・なんだ・・・?で、時間切れ

さて、この鍵、Base64形式だね。

間に \n が入っているので注意

AAAAB3NzaC1yc2EAAAADAQABAAABAQC4HCDyPMoybg5G+Tk7z84msC+BovKHFmdZduUXX+T1WwRw\nb51AWsXrbHnoCWvhWj1KJNkhzIQ4p1y3/TDpRCuCcUr+iMialVlJj8vkHMBCpbqnNe2NprMmvFdN\nL7PXtwfvCOIJKABalT/QgQ23RBsDlXomWP8ja+Bb5kRdJh18zRb5b3bZEyq52F5Uq//plH4Hx8Yd\n5WeuyxlsltO51ZhZBDunRRycYoV2exgpZX2o5oChPvEKwjwlwDV5VRN/JKl82Cdf23ekMDOrc7bN\nk9E8RycGAkDbIbHS/6mYxB62eRp+25g69IIIBnbRsaffl+UmzudvEVixzxLn+MNJ5hpJ\n

Base64形式だったので、デコードしてダンプみる。

$ xxd key.bin 
0000000: 0000 0007 7373 682d 7273 6100 0000 0301  ....ssh-rsa.....
0000010: 0001 0000 0101 00b8 1c20 f23c ca32 6e0e  ......... .<.2n.
0000020: 46f9 393b cfce 26b0 2f81 a2f2 8716 6759  F.9;..&./.....gY
0000030: 76e5 175f e4f5 5b04 706f 9d40 5ac5 eb6c  v.._..[.po.@Z..l
0000040: 79e8 096b e15a 3d4a 24d9 21cc 8438 a75c  y..k.Z=J$.!..8.\
0000050: b7fd 30e9 442b 8271 4afe 88c8 9a95 5949  ..0.D+.qJ.....YI
0000060: 8fcb e41c c042 a5ba a735 ed8d a6b3 26bc  .....B...5....&.
0000070: 574d 2fb3 d7b7 07ef 08e2 0928 005a 953f  WM/........(.Z.?
0000080: d081 0db7 441b 0395 7a26 58ff 236b e05b  ....D...z&X.#k.[
0000090: e644 5d26 1d7c cd16 f96f 76d9 132a b9d8  .D]&.|...ov..*..
00000a0: 5e54 abff e994 7e07 c7c6 1de5 67ae cb19  ^T....~.....g...
00000b0: 6c96 d3b9 d598 5904 3ba7 451c 9c62 8576  l.....Y.;.E..b.v
00000c0: 7b18 2965 7da8 e680 a13e f10a c23c 25c0  {.)e}....>...<%.
00000d0: 3579 5513 7f24 a97c d827 5fdb 77a4 3033  5yU..$.|.'_.w.03
00000e0: ab73 b6cd 93d1 3c47 2706 0240 db21 b1d2  .s....<G'..@.!..
00000f0: ffa9 98c4 1eb6 791a 7edb 983a f482 0806  ......y.~..:....
0000100: 76d1 b1a7 df97 e526 cee7 6f11 58b1 cf12  v......&..o.X...
0000110: e7f8 c349 e61a 49     

ん?んん・・・これpem形式じゃないし・・・なんの形式かしら?どうやって使うのかしら?
と、調べている間に時間切れ・・・

OpenSSH形式の鍵フォーマットなんじゃないかな。というあたりまでは解った。

どう使うかあたりは、もっと調査が必要だったと思われ。
以下が参考になるんじゃないかな(まだちゃんと見てないけど)。

Signing data with ssh-agent
http://blog.oddbit.com/2011/05/09/signing-data-with-ssh-agent/

Converting OpenSSH public keys
http://blog.oddbit.com/2011/05/08/converting-openssh-public-keys/

こうやって解くんじゃない?

実はこのスクリーンショットの怪しい数字

20160730_tmctf_scada100.jpg

00 00 17 15 08 30 74 15 1e 12 0d 0f 0c 4e

これを前述の鍵で複合すればflagなんでしょ!?

も、もぅ、知ってるんだからねっ(*/ω\*)

誰か続きを頼む

あともうちょっとだと思うんだけどな~

こ、これ本当に100点なのかw
こいつはアレだ。。競技時間は終わったけど、調査は続けられるハズ。
誰か解いて教えてくれ。。

答えがわかった

2016.8.6 追記

Trend Micro CTF 2016 Online Qualifier | #Scada | SCADA 100 Points
https://www.youtube.com/watch?v=YyHbJDmSQWc

なんとも言えないこの徒労感。このエスパー感がたまらない。

00 00 17 15 08 30 74 15 1e 12 0d 0f 0c 4e と TMTANK3TMTANK3 で xor

$ cat solv.sh 
#!/bin/bash

printf "%b" $(printf '%s%x' '\x' $((0x54 ^ 0x00)))
printf "%b" $(printf '%s%x' '\x' $((0x4d ^ 0x00)))
printf "%b" $(printf '%s%x' '\x' $((0x54 ^ 0x17)))
printf "%b" $(printf '%s%x' '\x' $((0x41 ^ 0x15)))
printf "%b" $(printf '%s%x' '\x' $((0x4e ^ 0x08)))
printf "%b" $(printf '%s%x' '\x' $((0x4b ^ 0x30)))
printf "%b" $(printf '%s%x' '\x' $((0x33 ^ 0x74)))
printf "%b" $(printf '%s%x' '\x' $((0x54 ^ 0x15)))
printf "%b" $(printf '%s%x' '\x' $((0x4d ^ 0x1e)))
printf "%b" $(printf '%s%x' '\x' $((0x54 ^ 0x12)))
printf "%b" $(printf '%s%x' '\x' $((0x41 ^ 0x0d)))
printf "%b" $(printf '%s%x' '\x' $((0x4e ^ 0x0f)))
printf "%b" $(printf '%s%x' '\x' $((0x4b ^ 0x0c)))
printf "%b" $(printf '%s%x' '\x' $((0x33 ^ 0x4e)))

$ ./solv.sh 
TMCTF{GASFLAG}

Open Source unConference 2016 Chiba を賑やかしに行きました

kanataほぼ8年前に追加

Open Source unConference 2016 Chiba を賑やかしに行きました!

Open Source unConference 2016 Chiba (2016/07/23 15:00〜)

飲食物が出ます!
ビールを飲みながらのLTは最高ですな~。

印象に残った面白そうな話

不正アクセスを検出して、iptablesにアクセス禁止を加えるというfail2banを参考に、に更にIPv6に対応したもの。イカス。

どんな話が繰り広げられているのか気になったw
車の話とか、女子トイレの話とか、あと、女子トイレの話とか

20160723_OSunC.jpg

katagaitai CTF勉強会#5 - 関東|med に参加してきました

kanataほぼ8年前に追加

5周年、おめでとうございます。今回も良い勉強会でございました。

katagaitai CTF勉強会 #5 - 関東|med : ATND

場所は安定の、人員の許容量が宇宙ヤバい秋葉原UDXで開催。広い。
途中、スピーカーへの音声インジェクション(混線とも言う)でpwnされるというハプニングがあって笑った。

trmrさんの部

スライド中でご紹介頂き、ありがとうございます~。

ハッシュ面白い~。
MD5をもう使うなって件は、単にハッシュ値が短くて、衝突しやすいから使うのやめようって話だと、ずっと思ってた。
実は総当りよりも遥かに少ない回数で衝突させることが出来るとは、ちょっと衝撃でした。
ツール(HashPump,FastColl,HashClash)も幾つか教えて頂いたので試してみようかと思っています。

暗号学の偉人伝は、実はかなり面白かった。
レトロハッカーズを思い出した。

bataさんの部

私が今一番知りたかったヒープの話があって、良かった。ありえん良さみが深かった。
たぶん、初めて参加した1年ぐらい前だと全然理解できなかったと思うんですが、今はお話が解るようになりました。
わ、私にも解かる、解かるぞ!(問題が解けるとは言っていない)

「全ての複雑なものは、単純なものの組み合わせで出来ている」

っていう私の好きな言葉があるんですが(誰が言ったか覚えていない)、今回まさにそれでした。ただ、、複雑過ぎて笑った。

個々の単純な部分まで分解して、説明して貰ったので、とても解りやすかったです。

発表したスライドは、後々slideshareで公開されるようなので、参加しなかった方も乞うご期待!!

ま、それが組み合わさって、解答に辿り着くまでの道筋は、なんというか、常軌を逸していたけれどw

ほんと、こんな問題よく作ったな。。。そしてよく解いたな。。。

ヒープについては、自分の勉強ノートに書けていないのですが、整理して書く良いきっかけになりました。

延長戦でのDWARFの話も大変興味深かったです。

20160716_katagaitaiCTF.jpg

頂きもの

ノートとペンを頂きました。ありがてぇ・・・ありがてぇ・・・

ノートはCamiApp対応で重宝しそう。
スマホで写してDropBoxへ転送。。捗る。

このペン実は、前回も前々回も頂いているんですが、隠れた高性能っぷりを発揮しておりまして、
普通の貰い物ボールペンは、途中でよくインク出なくなって終了したりするんですが、これはインク切れが無いんですよ!!
日々愛用させて頂いております。

20160716_katagaitaiCTF_NRIsecure.jpg

Trend Micro CTF 2016 (1コメント)

kanataほぼ8年前に追加

今年も
/attachments/download/106/20150715_aa.jpg

セキュリティ技術の競技大会「Trend Micro CTF 2016」を開催
~全世界の技術者が、IoTや制御システム関連のセキュリティ技術を競う~
http://www.trendmicro.co.jp/jp/about-us/press-releases/articles/20160701042341.html

Trend Micro CTF 2016
http://www.trendmicro.co.jp/jp/sp/ctf2016_jp/index.html

Trend Micro CTF 2016

しかしkatagaitai勉強会#6 - 関東|easyと被ってしまってるぅぅぅぅ。
うわぁああぁぁぁあああああああああああああああああ

katagaitai勉強会#6 - 関東|easy : ATND

1 ... 7 8 9 10 11 ... 16 (81-90/152)

他の形式にエクスポート: Atom

クリップボードから画像を追加 (サイズの上限: 100 MB)