Wednesday, November 8, 2017, 22:48 - OS, OS / Linux
Posted by ELIN
xinetdやincrondでスペースを含む引数を指定すると意図したように動かない
スペースに限らずワンライナを仕込んだり、パイプで繋いだり、リダイレクトでゲロしたり、複数のコマンドを実行させたいときには、まず意図した挙動にならないだろう
一方でcrondはこれを回避して動いてくる

例えば以下のようなperlのワンライナをxinetdで設定する
server = /usr/bin/perl
server_args = -lnpe '...' >/var/log/hoge.log

コード部は省略するが、これの意図するところはログを吐き出したいのだ

ところがこれは往々にしてperlのsyntax errorで止まる

原因はlinuxを使っている人なら簡単に予想できるが、要するにcrondはシェルの上で走らせている(/etc/crontabのSHELLで指定しているのを知っているだろう)のでパイプやリダイレクトを使えるというわけ

ところがxinetdやincrondは何も考えずスペースで区切って渡してしまう

以下のような小文字へコンバートしてエコーするだけのサービスを考える
server = /usr/bin/perl
server_args = -lnpe '$_ = lc($_)'

これはうまく動かない
何も考えず、perlでいうところの"split(/ /,...)"で分解して渡してしまうので、perlのバイナリに渡される引数は...
$ARGV[0] # -lnpe
$ARGV[1] # '$_
$ARGV[2] # =
$ARGV[3] # lc($_)'

こんなんなってしまう、こんな区切り方じゃ動かせる感じがしない

これと同様の悩みは調べればすぐに見付かって、解決方法も至極簡単に書いてある
.shファイルを書いて(例題の場合はそのまま.plに起こせば良いね)そいつをxinetdやincrondから呼び出せばいい

しかしながらたった1行のコマンドやリダイレクトのためだけにファイルに起こすのはちょっと馬鹿馬鹿しい気もするのだ

linuxはwindowsのようなカスみたいなシェルじゃないのでもっと頭のいい(ひねくれた)方法があるだろうと考えた結果、こちら
server = /bin/sh
server_args = -c $* - eval perl -MPOSIX=strftime -lnpe 's/\r//;$.==1&&print$ENV{REMOTE_HOST}." - - [".strftime("%d/%b/%Y:%T %z",gmtime($^T))."] \"$_\"";!length()&&print&&exit;s/^/\t/' >>/var/log/honeypot.log && echo HTTP/1.0 200 OK;echo

パイプやリダイレクトの動作から/bin/shの実行は必須として、evalに被せることで後ろの文字列を実行させる
1行のhttp honeypotの完成だ、めでたしめでたし
1 comment ( 430 views )

| 1 | 2 | 3 | 4 | Next> Last>>