rev,pwnに使うツール(弊研究室の某課題について考える3日目)

はじめに

この記事は弊研究室の某課題について考えるの3日目の記事です。

有名所が多いので詳しい使い方等は他の方の記事を見てください。この記事ではツールの存在を知ってもらうことを重要視します。

基本的にこの一連の記事ではobjdumpとgdb-pedaで進みます。

ツール紹介

使えるツール群の紹介

  • ltrace,strace
  • objdump
  • gdb,gdb-peda
  • radare2
  • IDA
  • ollydbg
  • pwntools
  • checksec
  • rp++

ltrace, strace

ltraceはライブラリ関数の動きを追跡するコマンド、straceはシステムコールの動きを追跡するコマンドです。

objdump

objdumpはオブジェクトファイルの情報を表示するコマンドです。

Man page of objdump

よく使うのは

$ objdump -d -M intel ./program

これでIntel記法のアセンブラを読むことができます。またret2pltの攻撃方法で必要となるpltも調べられます。その時は

$ objdump -d -M inlte -j .plt ./program

objdumpの結果からgrepしてる人もいますが、こっちのほうがスマート

gdb, gdb-peda

gdbとはelfバイナリの解析に使うソフトウェアです。実際にプログラムを動かしながら確認のできる動的デバッガツールとして優秀です。

gdb-pedaはgdbpythonで拡張したものとなります。

pedaはこちら

github.com

pedaを利用することによってブレークポイントにたどり着いたときにレジスタやスタックの表示等が行われるのですごく見やすくなります。EIPを奪えているのかも一目瞭然!!

使い方はここにあります。peda$ help allで全てのコマンドが見れます。

radare2

radare2はバイナリ解析ツールです。gdbと違い対応しているアーキテクチャが多いです。gdbで解析できないバイナリもradare2ではアセンブラが見えたりといったこともあります。

github.com

IDA

超有名な逆アセンブラ&逆コンパイラ

幅広いアーキテクチャに対応しており、関数の流れを図で見ることができます。

機能は制限されますが無償版も存在しており、無償版でも有用に使えます。いつかは私も買いたい

ollydbg

こっちはWindowsのexeファイルを解析するときに使うツール

ブレークポイント決めて動的にいろいろ試すこともできる、レジスタの中身とかも表示されてるので直感的に扱いやすい

Pwntools

これは実際にexploitコードを送り込むときに役立つツール。

いろいろと用意されているのでとっても便利。

checksec

バイナリを攻撃から防御する機構であるNXやRELRO,PIE, canaryといったものが有効であるか等を調べるシェルスクリプト

余談だがgdb-peadでもchecksecは用意されている

rp++

rp++はROPガジェットを見つけるツール

ropするときに使います。PE/Elfでも使えるという特徴がある

おしまい

とりあえずこんなところか、最初にも書いたけどこの一連の記事ではobjdumpとgdb-pedaが使えればだいたいなんとかなるはず。

XSS(弊研究室の某課題について考える17日目)

はじめに

この記事は弊研究室の某課題について考えるの17日目の記事です。

いよいよWeb編です

XSS

XSS(Corss Site Scripting)とは任意のJavaScriptを実行できる脆弱性です。Cross Site ScriptingなのにXSSなのはCascading Style Sheet(CSS)と紛らわしいためです。基本的にはXSSです。

サンプル

今回ですがdockerでサンプルを用意しました。

サンプルはこちら

$ docker-compose up -dしてlocalhost:3333/index.phpにアクセスしてください。

サンプルですが入力した文字をpostで受け取り、それを表示するといったものとなります。

ソースコード

index.php

<html>
<meta charset="utf-8">
<title>XSS sample</title>
<body>
<form method="POST" action="post.php">
<input type="text" name="data">
<input type="submit" value="Submit">
</form>
</body>
</html>

post.php

<html>
<meta charset="utf-8">
<title>XSS Sample</title>
<body>
Your input : <?php echo $_POST["data"];?><br>
<a href="./index.php">back</a>
</body>
</html>

脆弱性

post.phpのほうに脆弱性が存在します。<?php echo $_POST["data"];?>です。index.phpのほうで<script>alert('1');</script>と実行すると下のようになります

f:id:kataware8136:20171224154740p:plain

XSSの危険性

XSS脆弱性があると、どういった攻撃をされるかといったことが以下になります(Wikipediaより)

  • 標的サイトの変数値やcookieなどからの情報漏洩
  • セッションハイジャック
  • 機能の不正実行
  • ウェブサイトの改竄(ただし攻撃者が準備したURLからアクセスした場合のみ)
  • 悪意のあるスクリプトによりWebページを改ざんする事でパスワードやクレジットカード番号を入力するフォームをWebページに追加し、ユーザからこれらの情報を盗む(フィッシング 詐欺)
  • 悪意のあるスクリプトを使ってブラウザの脆弱性を突き、ユーザ端末を乗っ取る
  • ワームの実行

ということで対策が必要です。

XSSの対策

さてXSSの対策ですが以下のようなものがあります

  • エスケープ
  • CSP
  • IDSで監視する

エスケープとCSPについて解説します。

エスケープ

エスケープとは攻撃者が送り込むコードを実行されないような形に変化させることです。たとえば<&lt;に変えるとかですね。

こういった関数は言語によっては用意されていることがあり、例えばPHPではhtmlspecialchars($str)関数を利用することでエスケープできます。

基本的に文字列の出力時にエスケープ処理を欠かさないようにしておく意識を持ったほうがいいと個人的には思います。

エスケープのサンプル

今回あげたサンプルにはエスケープの効果を実感してもらうためのページも用意してあります。

localhost:3333/escape/index.phpにアクセスしてscriptを埋め込んでみてください。下のようになるはずです。

f:id:kataware8136:20171224154854p:plain

CSP

Content Security PolicyもXSSを防ぐ機構です。これは結構強力で正しく設定すればXSSを防げます。

設定方法はHTTPレスポンスヘッダかにContent-Security-Policyを設定し、コンテンツとしてCSPの設定内容を書きます。

CSPですが開発者が許可しないJavaScript全てを実行しないといったことができます。

CSPのサンプル

<?php

header("Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self';");

?>

<html>
<meta charset="utf-8">
<title>XSS Sample</title>
<body>
Your input : <?php echo $_POST["data"];?><br>
<a href="./index.php">back</a>
</body>
</html>

このscript-srcがJavaScriptの制御を行います。selfというのは自ホストからのJSの読み込みを許可すると言う意味です(localhostにあるJavaScriptファイルは読み込める)。それ以外に何も書いてないので他のJSファイルは動作しません。

物は試し、localhost:3333/csp/index.phpにアクセスしてスクリプトを入れてみてください。

f:id:kataware8136:20171224154804p:plain

おわりに

とまぁこんな感じです。Web開発するなら気をつけなければ行けない攻撃でした。Web開発しない人でも覚えておきましょう。

Androidアプリ動的解析ツールFridaを使う

Harekaze Advent Calender21日目の記事です

adventar.org

前日はbanbanさんでした。Harekazeらしいいい記事です!!

banban.hateblo.jp

それで私が話すのは最近見つけたCTFに使えるツールの使い方です。

Frida

FridaとはAndroidアプリへの動的解析ツールでありアプリの解析やセキュリティに関する調査も行えるツールだそうです。

つい最近知ったのですが今回はそれを使うところまで行こうかなと思います

ちなみにこの記事ではAndroid Emulatorなどは使える前提で進めます。具体的に言うとadb devicesコマンドを打ったときにデバイスが認識されている状況にしてください。

私の試した環境はこんな感じ

$ uname -a
Linux durian 3.13.0-121-generic #170-Ubuntu SMP Wed Jun 14 09:04:33 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 14.04.5 LTS
Release:    14.04
Codename:   trusty
$ adb --version
Android Debug Bridge version 1.0.39
Version 27.0.0-4455170
Installed as ~/android/android-sdk-linux/platform-tools/adb

Android Emulatorの環境

環境
OS Android7.0.0
CPU ARM(armeabi-v7a)

Fridaのインストール

基本的にはFridaのページに書いてあるとおりにやれば問題ないです。

Linux側での準備

$ sudo pip install frida

Android側の準備

まずここからfrida-serverをダウンロード展開します。

$ adb root # might be required
$ adb push frida-server /data/local/tmp/ 
$ adb shell "chmod 755 /data/local/tmp/frida-server"
$ adb shell "/data/local/tmp/frida-server &"

という感じでfrida-serverを実行しておけば準備完了です。

Fridaを使う

サンプルコードを用いて解説していきます。このサンプルコードですがSECCON2015 reverse-engineering-android-apk-1の問題です。

import frida, sys

def on_message(message, data):
    if message['type'] == 'send':
        print("[*] {0}".format(message['payload']))
    else:
        print(message)

jscode = """
Java.perform(function () {
    // Function to hook is defined here
    var MainActivity = Java.use('com.example.seccon2015.rock_paper_scissors.MainActivity');

    // Whenever button is clicked
    MainActivity.onClick.implementation = function (v) {
        // Show a message to know that the function got called
        send('onClick');

        // Call the original onClick handler
        this.onClick(v);

        // Set our values after running the original onClick handler
        this.m.value = 0;
        this.n.value = 1;
        this.cnt.value = 999;

        // Log to the console that it's done, and we should have the flag!
        console.log('Done:' + JSON.stringify(this.cnt));
    };
});
"""

process = frida.get_usb_device().attach('com.example.seccon2015.rock_paper_scissors')
script = process.create_script(jscode)
script.on('message', on_message)
print('[*] Running CTF')
script.load()
sys.stdin.read()

基本的な使い方ですが

process = frida.get_usb_device().attach(packagename)のpackageに解析するapkのパッケージを入力することで動的解析ができる環境になり

process.create_script(jscode)で実行させるJavaScriptを読み込みscript.load()でスクリプト実行させます。Fridaで使えるJavaScriptのメソッドはここを参照してください。

このapkのMainActivityですが下のようになっています。

public class MainActivity extends Activity
    implements android.view.View.OnClickListener
{

    public MainActivity()
    {
        cnt = 0;
    }

    public native int calc();

    public void onClick(View view)
    {
        if(flag == 1)
            return;
        flag = 1;
        ((TextView)findViewById(0x7f0c0052)).setText("");
        TextView textview = (TextView)findViewById(0x7f0c0050);
        TextView textview1 = (TextView)findViewById(0x7f0c0051);
        m = 0;
        n = (new Random()).nextInt(3);
        int i = n;
        textview1.setText((new String[] {
            "CPU: Paper", "CPU: Rock", "CPU: Scissors"
        })[i]);
        if(view == P)
        {
            textview.setText("YOU: Paper");
            m = 0;
        }
        if(view == r)
        {
            textview.setText("YOU: Rock");
            m = 1;
        }
        if(view == S)
        {
            textview.setText("YOU: Scissors");
            m = 2;
        }
        handler.postDelayed(showMessageTask, 1000L);
    }

    protected void onCreate(Bundle bundle)
    {
        super.onCreate(bundle);
        setContentView(0x7f040018);
        P = (Button)findViewById(0x7f0c004d);
        S = (Button)findViewById(0x7f0c004f);
        r = (Button)findViewById(0x7f0c004e);
        P.setOnClickListener(this);
        r.setOnClickListener(this);
        S.setOnClickListener(this);
        flag = 0;
    }

    Button P;
    Button S;
    int cnt;
    int flag;
    private final Handler handler = new Handler();
    int m;
    int n;
    Button r;
    private final Runnable showMessageTask = new Runnable() {

        public void run()
        {
            TextView textview = (TextView)findViewById(0x7f0c0052);
            if(n - m == 1)
            {
                MainActivity mainactivity = MainActivity.this;
                mainactivity.cnt = mainactivity.cnt + 1;
                textview.setText((new StringBuilder()).append("WIN! +").append(String.valueOf(cnt)).toString());
            } else
            if(m - n == 1)
            {
                cnt = 0;
                textview.setText("LOSE +0");
            } else
            if(m == n)
                textview.setText((new StringBuilder()).append("DRAW +").append(String.valueOf(cnt)).toString());
            else
            if(m < n)
            {
                cnt = 0;
                textview.setText("LOSE +0");
            } else
            {
                MainActivity mainactivity1 = MainActivity.this;
                mainactivity1.cnt = mainactivity1.cnt + 1;
                textview.setText((new StringBuilder()).append("WIN! +").append(String.valueOf(cnt)).toString());
            }
            if(1000 == cnt)
                textview.setText((new StringBuilder()).append("SECCON{").append(String.valueOf((cnt + calc()) * 107)).append("}").toString());
            flag = 0;
        }

        final MainActivity this$0;

            
            {
                this$0 = MainActivity.this;
                super();
            }
    };

    static 
    {
        System.loadLibrary("calc");
    }
}

onClickでじゃんけんが開始されてmとnとcntの値次第でflagが出力されるようです。 m=1,n=0,cnt=999をセットしてrun関数が実行できればcalcのディスアセンブルをしなくても答えが出そうです

Fridaですが既存のJavaメソッドに拡張を施すことができます。下のは公式で載せられているサンプルです。

Java.perform(function () {
    var Activity = Java.use("android.app.Activity");
    Activity.onResume.implementation = function () {
        send("onResume() got called! Let's call the original implementation");
        this.onResume();
    };
});

Java.performJavaを使うことを宣言し、Java.useで拡張したいJavaのクラスを設定、Activity.---.implementationでそのクラスの中の関数に拡張を施します。

エクスプロイトコードはcom.example.seccon2015.rock_paper_scissors.MainActivitymncntを変更したいので下のようになります

Java.perform(function () {
    // Function to hook is defined here
    var MainActivity = Java.use('com.example.seccon2015.rock_paper_scissors.MainActivity');

    // Whenever button is clicked
    MainActivity.onClick.implementation = function (v) {
        // Show a message to know that the function got called
        send('onClick');

        // Call the original onClick handler
        this.onClick(v);

        // Set our values after running the original onClick handler
        this.m.value = 0;
        this.n.value = 1;
        this.cnt.value = 999;

        // Log to the console that it's done, and we should have the flag!
        console.log('Done:' + JSON.stringify(this.cnt));
    };

これで実行すると次の画面になります(スクショが死んでたのでsurfaceカメラですいません)

f:id:kataware8136:20171221134925j:plain

Fridaでできること

現状自分も調べてる真っ最中なのでまだまだできることはあると思いますがCTFですぐ使えそうなのが

  • Javaメソッドを拡張する
  • 実行中のメモリの中身を見る

あたりかなと....

終わり

ちなみにAndroid Hacking Event 2017 AES-Decrypt Writeup - ごちうさ民の覚え書きもFridaを使っています。個人的には苦渋を飲んでいるHelloDalvikもFridaでいけないかなと考えています。がんばります

明日はうさぎさんです!CBCTFの暗号問の解説ってすごい..

素晴らしい人の前日が自分ですいません.....よいCTFライフを送ってください!!