環境構築
root@ubuntu:~# for i in {0..34}; do wget http://archive.apache.org/dist/httpd/httpd-2.2.${i}.tar.gz;tar xf httpd-2.2.${i}.tar.gz; pushd httpd-2.2.${i}; ./configure --prefix=/opt/httpd/2.2.${i};make;make install;sed -i "s/Listen 80/Listen $((2000+${i}))/" /opt/httpd/2.2.${i}/conf/httpd.conf; echo "TraceEnable Off" >> /opt/httpd/2.2.${i}/conf/httpd.conf; /opt/httpd/2.2.${i}/bin/apachectl start; popd; done
Apache2系の複数のバージョンをコマンドライン一撃で、ソースコンパイルし、複数のポートで起動する。
テストケース作成
root@ubuntu:~# cat << EOF > wiki-http-headers
wikipedia(英)のHTTPheader Listという項目から、HTTP Server Header 一覧を適当にテキストに保存し、貼り付ける
root@ubuntu:~# cat wiki-http-headers | cut -f3 | grep ":" | sed "s#Example....##g" | sort -u
解説の文章とかあるので、邪魔なものを取り除く
root@ubuntu:~/afl-2.52b/testcases/others/http# cat wiki-http-headers | cut -f3 | grep ":" | sed "s#Example....##g" | sort -u
Accept-Charset: utf-8
Accept-Datetime: Thu, 31 May 2007 20:35:00 GMT
Accept-Encoding: gzip, deflate
Accept-Language: en-US
Accept-Patch: text/example;charset=utf-8
Accept-Ranges: bytes
Accept: text/plain
Access-Control-Allow-Origin: *
Access-Control-Request-Method: GET
Age: 12
Allow: GET, HEAD
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Cache-Control: max-age=3600
Cache-Control: no-cache
Content-Disposition: attachment; filename="fname.ext"
Content-Encoding: gzip
Content-Language: da
Content-Length: 348
Content-Location: /index.htm
Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==
Content-Range: bytes 21010-47021/47022
Content-Type: application/x-www-form-urlencoded
Content-Type: text/html; charset=utf-8
Cookie: $Version=1; Skin=new;
Date: Tue, 15 Nov 1994 08:12:31 GMT
DNT: 0 (Do Not Track Disabled)
DNT: 1 (Do Not Track Enabled)
ETag: "737060cd8c284d8af7ad3082f209582d"
Expect: 100-continue
Expires: Thu, 01 Dec 1994 16:00:00 GMT
Forwarded: for=192.0.2.60;proto=http;by=203.0.113.43 Forwarded: for=192.0.2.43, for=198.51.100.17
From: user@example.com
Front-End-Https: on
If-Match: "737060cd8c284d8af7ad3082f209582d"
If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
If-None-Match: "737060cd8c284d8af7ad3082f209582d"
If-Range: "737060cd8c284d8af7ad3082f209582d"
If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT
Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT
Link: </feed>; rel="alternate"[43]
Location: http://www.w3.org/pub/WWW/People.html
Location: /pub/WWW/People.html
Max-Forwards: 10
Origin: http://www.example-social-network.com
P3P: CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info."
Pragma: no-cache
Proxy-Authenticate: Basic
Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Proxy-Connection: keep-alive
Public-Key-Pins: max-age=2592000; pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=";
Range: bytes=500-999
Referer: http://en.wikipedia.org/wiki/Main_Page
Refresh: 5; url=http://www.w3.org/pub/WWW/People.html
Retry-After: 120
Retry-After: Fri, 07 Nov 2014 23:59:59 GMT
Server: Apache/2.4.1 (Unix)
Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1
Status: 200 OK
Strict-Transport-Security: max-age=16070400; includeSubDomains
Timing-Allow-Origin: *
Timing-Allow-Origin: <origin>[, <origin>]*
Trailer: Max-Forwards
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20100101 Firefox/12.0
Vary: *
Vary: Accept-Language
Via: 1.0 fred, 1.1 example.com (Apache/1.1)
Warning: 199 Miscellaneous warning
WWW-Authenticate: Basic
X-Att-Deviceid: GT-P7320/P7320XXLPG
X-Content-Duration: 42.666
X-Content-Type-Options: nosniff[55]
X-Csrf-Token: i8XNjC4b8KVok4uw5RftR38Wgp2BFwql
X-Forwarded-For: 129.78.138.66, 129.78.64.103
X-Forwarded-For: client1, proxy1, proxy2
X-Forwarded-Host: en.wikipedia.org
X-Forwarded-Host: en.wikipedia.org:8080
X-Forwarded-Proto: https
X-Frame-Options: deny
X-HTTP-Method-Override: DELETE
X-Powered-By: PHP/5.4.0
X-Requested-With: XMLHttpRequest
X-Request-ID: f058ebd6-02f7-4d3f-942e-904344e8cde5
X-UA-Compatible: Chrome=1
X-UA-Compatible: IE=edge
X-UA-Compatible: IE=EmulateIE7
X-UIDH: ...
x-wap-profile: http://wap.samsungmobile.com/uaprof/SGH-I777.xml
X-WebKit-CSP: default-src 'self'
X-XSS-Protection: 1; mode=block
まだ汚いので
root@ubuntu:~# a=0 && IFS=$'\n' && for header in $(cat wiki-http-headers | cut -f3 | grep ":" | sort -u); do echo -e "GET / HTTP/1.0\r\n$header\r\n\r\n" > "testcase$a.req";a=$(($a+1)); done && unset IFS
これらのHTTPヘッダーを含む、HTTPリクエストを生成する。(この時点ではZzufに食わせる前の正常なリクエスト)
root@ubuntu:~# for i in {0..89}; do for f in testcase.*; do zzuf -r 0.01 -s $i < "$f" > "$i-$f"; done; done
^GET / HTTP/^Q.0
Accept-^Charset: utf-8
^GET / HTTP/^Q.0
Allow: ^GET, HEAD
^GET / HTTP/^Q.0
Authori:ation: Basic QWxhZGRpbjpvc<C7>V5IHNhk2FtZQ==
^GET / HTTP/^Q.0
Cache-C/ntrol: max-age=3600
^GET / HTTP/^Q.0
Cache-C/ntrol: no-cache
^GET / HTTP/^Q.0
ContentmDisposition: attachment; f<E9>l%nama5"fname.ext"
^GET / HTTP/^Q.0
ContentmEncoding: gzip
^GET / HTTP/^Q.0
ContentmLanguage: da
^GET / HTTP/^Q.0
ContentmLength: 348
Zzufを使い、先ほどのリクエストをランダムに変化させる。
表示すると以下のようにHTTPリクエストとしておかしいものが出現する。(ダムファジングなので、プロトコルとして、おかしいものも対象とする)
fuzzing 実施
root@ubuntu:~# for v in {0..89}; do for p in {2000,2002,2003,2004,2006,2008,2009,2010,2013,2020,2021,2022,2034};do nc -nv 192.168.204.80 ${p} < ${v}-testcase${v}.req; done; done > `date +%Y%m%d%H%M%S.log`
先ほど、生成したおかしなHTTPリクエストをnetcatがファイルから読み込み送信する。