HTTPヘッダインジェクションをLinux(AWS)で試してみる。

#http インストール
yum -y install httpd

#perl-CGI インストール
yum -y install perl-CGI

#httpd.confの以下を変更
cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.org
ls -la /etc/httpd/conf/httpd.conf*

# vi /etc/httpd/conf/httpd.conf
# 以下を修正
#   Options Indexes FollowSymLinks
#  ==>  
#   #Options Indexes FollowSymLinks
#   Options Indexes ExecCGI FollowSymLinks
#
#   #AddHandler cgi-script .cgi
#  ==>  
#   #AddHandler cgi-script .cgi
#   AddHandler cgi-script .cgi

#流し込む場合
sed -i 's/Options Indexes FollowSymLinks/Options Indexes ExecCGI FollowSymLinks/' /etc/httpd/conf/httpd.conf
sed -i '/#AddHandler cgi-script .cgi/ s/#//' /etc/httpd/conf/httpd.conf

#Apache 起動関連
systemctl start httpd
systemctl enable httpd

cd /var/www/html/

#index.cgiを作成
cat <<'EOF' > index.cgi  #EOFを'でクォートしないと、$が変数として展開されてしまう。
#!/bin/perl
use CGI;
use CGI::Cookie;

my $cgi = new CGI;
my $url =$cgi->param('url');

if ($ENV{'QUERY_STRING'} ne '') {
  if ($url ne '') {
    print "Location: $url\n\n";
  }
  print $cgi->header;
}
else{

print $cgi->header;

my %cookies = fetch CGI::Cookie;
if (exists $cookies{'SID'}) {
    $value = $cookies{'SID'}->value;
    if ($value eq 12345){
        print "success";
    }
}else{
    print "hello";
}
}
EOF

#index.cgiに実行権限を付与
chmod +x index.cgi

■ではやってみる
①ページを表示する
http://203.0.113.25/index.cgi
→helloと表示される

②urlの引数を入れて、リダイレクトさせる。
ソースプログラムを見るとわかるが、URLに記載されたurlのパラメータ(値)を「Location: $url\n\n";」というHTTPレスポンスヘッダに入れているので、?url=で記載したURLにページが遷移する
http://203.0.113.25/index.cgi?url=https://www.yahoo.co.jp/

③CookieにSIDをセットする。
HTTPレスポンスヘッダでは、「Location: $url\n\n";」になっていて、以下のように%0D%0Aで改行コードを入れると、HTTPレスポンスヘッダに「Set-Cookie:SID=12345」が入れられる。なので、(セッションを受け取っているだけだとダメで、次にアクセスしたときにCGIスクリプトが反応するので、もしかするともう一度アクセスする必要があるだろうが、)CGIプログラムでSIDを見てsuccessと表示することができる。
http://203.0.113.25/index.cgi?url=http://203.0.113.25/index.cgi%0D%0ASet-Cookie:SID=12345

④HTTPヘッダをみてみよう。GoogleChromの場合、F12で開発者ツール、「Network」タブで、もう一度ページをリロードし、そのページをみるとHeaderが見える。
たとえば、ソースプログラムで以下のようにHTTPヘッダに文字を足してみて、HTTPヘッダをみてみると、わかりやすだろう。「Hello___」の文字が付与されているはずである。
else{
print "Hello___";
print $cgi->header