Do you know this common Go vulnerability?

LiveOverflow · Beginner ·🔐 Cybersecurity ·1y ago

Key Takeaways

The video discusses a common Go vulnerability, specifically an arbitrary file read vulnerability and a race condition, in the context of a CTF challenge. It explores the use of the G Json library, Docker containers, and Unix domain sockets in Go web development.

Full Transcript

in my job I'm doing security audits usually for web applications and sadly oftentimes I don't get the source code and need to test the web application blindly as a blackbox but you can still get a lot of hints from the backend implementation for example through error messages stack traces unique HTP headers or simply how the API endpoints behave and feel like for example when you have a go back end but you don't know that and it's using the popular G Json library then the incoming Json request can have an equ sign at the end this Library will happily parse it while the built in Json Library would throw an error sometimes I test for things like this in order to figure out if maybe the back end is using go this kind of knowledge I think is very helpful because every programming language and every framework has its own typical issues and pitfalls so when you know the backend you can optimize your testing you can look specifically for issues in that direction that is common in that world and of course this applies even more once you get access to the source code and you have full white box test and you can see the whole logic and you see exactly the libraries and Frameworks being used and at this point it's very very helpful when you can obviously read that code and you are aware of typical pitfalls and programmer mistakes to look out for so let's talk about such a pitfall in go code that I was not aware of this video is sponsored by hex.io our online training platform but more on that later let's get back to the video at the 38 C3 hxp so that's a CTF team primarily from the Technical University of Munich they organized the Congress CTF and our team Alice didn't really play but some of us joined forces with flux fingers to help them and one of the challenge that I looked at a little bit was the challenge fuch sorry I had to use AI to pronounce that for me this was a go web challenge and according to Jet GPT this roughly translates to key value store and that is exactly what it was so let's get a quick overview of the challenge and see what it is about in this challenge we get access to the source code and when you unpack the files you can find the following there are two go files KV and front end and Docker files so that you can quickly run it locally in the docker file we can also see that the flag.txt is copied into /home CF so our goal will be to leak the content of the flag from here the docker file also has a lot of weird additional code which you might think could have something to do with the challenge but somebody from flux fingers told me that this is likely just code to harden the challenge container clean it up a bit at the end you can then see that it executes the front end binary which was compiled up here so the front end is our entry point with the docker composed file we can also easily run this code with Docker locally the challenge is running now on local port 8080 and when we then open this page in the browser we can see the message we booted a fresh web scale key value store just for you if we look into the front and go code we can see the message here so this is handling an incoming HTTP request and this message only appears if we have no cookie with a valid session set if we have a session then the request is actually passed into this HTTP proxy Handler so something else is then actually handling the request if we look around a bit more we can also see that the front end executes the KV binary and then it creates this HTTP proxy with a Unix domain socket called KV socket and if we look now into the KV program we can see that it listens on this KV socket and it also declares two HTP Handler functions set and get so it looks like HTTP requests incoming into the front end get forwarded here via a Unix domain socket to the KV process we can also see that if we try that out in the browser if we have a session we can call set with the name for example test and a value a short one will fail with a 502 that's because of a bug in the code but a long value will work and now that we have set this value we can now get the value with a call to /g get surprice we can set and get values it's a key value store now this feels weird right why use this front- end code that executes another go binary and then using Unix sockets to forward incoming requests to the backend KV process if you know how typical web applications are set up this is very odd and uncommon and suspicious and this could have two reasons maybe it's necessary for the CTF challenge in order to do user separation or this is part of the vulnerability maybe there's an issue with the exic or an issue with the Unix socket if we look closer at the code if we don't have a session we can see that the session ID for the cookie is returned by new KV and in new KV the KV binary is executed and a proxy is set up with a unique Unix domain socket connection file so this means for each new session the front end creates a new backend process and given then the session ID in the cookie it can get the correct proxy back end and Route the HTTP requests to the correct KV process by going through the Unix domain socket file okay this makes it a lot more likely that it's just a setup to do user or team separation for the CTF but you can never be sure and it really confused me a lot to the point where I was not focusing on the right path and I missed it completely because eventually somebody from Flex fingers noticed something very obvious VI there is an arbitrary file read you provide the name or the key that you want to read it's passed to OS open it opens that file and then it reads that content and returns it and if we try that that's how it works we can read Etc pass WD so can we now just read the flag.txt file unfortunately that does not work there's this check path function and it checks that the file path does not contain a DOT and does not contain the string flag so flag.txt fails both checks of course there were ideas if we can somehow get a siming to the flag or we could use the set function because obviously there's an arbitrary file right as well the name and value is just used to write file and very suspicious that threw us for a loop was these permissions 777 the file gets execution permissions so could we write a binary or script or overwrite something and then abuse the EXC from the front end or something else to get rce but none of those ideas really led to anything until someone had a somewhat obvious idea the proc file system it contains information about every running process including the file descriptors opened by other processes and those are Sim links to the actual files so what if another process has the flag opened then we could bypass the check paath function there won't be a DOT and no flag string in the file name but there doesn't seem to be other processes that open the file right right nothing in this code reads and opens the flag file unless other teams solve the challenge because if another team somehow opens and reads the flag with their process we can get the flag through the file the crypto Sim link to the flag.txt file this is of course not the intended solution this was clear to us as well and flex fingers even asked the organizers if it's okay to do that because it could go against the rule of not attacking the infrastructure but they said it's fine so we did that here's the code for it it also uses one more trick to optimize this you need to know the process IDs of other processes and you could of course guess them but you need to be fast when a new process is started otherwise it might quit again and the file descript is gone but you can use another useful proc file for that and that is located in proc sis kernel namespace last process ID this file gives you the last allocated process ID inside your name space and so you can use this with the arbitrary file Le to check if a new process got started and if yes you can then use that process ID to leak the file descriptors and maybe that one opened the flag so the script was running and now we just had to wait but it didn't take too long and we got the flag and most likely it was not even another team solving it because in fancy modern CTF setups you often have health checks for the CTF F challenge Services often times they are running the solution script against it this way that you can always confirm that the challenge is still working as intended so probably their flag Checker solved the challenge to confirm it's working and we leaked the flag from that but what was the intended way that's actually the whole point of this video right um in the end only a team solved it even though the challenge difficulty was estimated by the organizers to be easy well after the CTF I was very curious and waited in the Discord server for the CTF for the intenna solution and it turns out the vulnerability was right here do you see it obviously I didn't see it either it has to do with the differences of colon equal and equal colon equal means declaration and assignment of a value while equal is just an assignment and this is important go has built in concurrency features that makes go pretty unique and Powerful concurrency is everywhere and go and so you need to be careful with threat safe code and variables let's have a closer look at this code of course these HTTP request handlers can run concurrently multiple requests in parallel can be handled here so they can be multiple requests with get or set calls in parallel now look here do you see how this error variable is only assigned and not declared the return of check path is only a assigned to the error variable it doesn't create a new error variable but where is the error variable then coming from where is it declared vs code actually knows this if you rightclick the arror variable find all references then it will highlight all the uses of this variable and it shows all the outer ones so here the variable is declared and everywhere here it's just used the other variables that are declared and assigned are not highlighted they are a different variable you can also see that when you debug the go code we can set a breakpoint here and then investigate the variables dynamically first we see here the aror variable but let's single step forward until the next one this one is declared and now we can see that there are two error variables one without parentheses and one with if we look into the source code of the go debugger interface in vs code you can annotate shadowed variables in parentheses so this is a so-called shadowed variable variable shadowing occurs when a variable declared within a certain scope has the same name as a variable declared in an outer scope so if you debug the code you can also see that something funky is going on with the variables here and this is an issue remember this code can run in parallel so the error variable is accessed in parallel and if you look closely you can see that the check is done in two steps first the error variable is assigned and then it's checked so what if the check path is called with flag.txt it sets the error variable as expected but then in parallel another request sets the error back to nil then this check would pass allowing you to read flag.txt so that is what it was it's a go race condition and I agree with the organizers assessment that this is an easy challenge currency is fundamental to go if your experience with writing or reading go you probably should know this but I didn't and I'm very bad and inexperienced with go but thanks to the CTF challenge I now am aware of this and from now on out when I read go code I will pay attention to the Declaration and assignments especially of error variables now here is the final exploit code it's super simple we first get a session ID to initialize our personal key value store and then we just Spam requests to get a file that passes the check path function and writes nil into the error variable while we also spam request to read the flag.txt file this will return an error but if right afterwards the error is then reset to nil it will leak the flag successfully now we can just run it and depending on the networking and various other factors eventually we will get the flag by the way this is also the answer to the question why this challenge has this unique and weird back and front end setup if all CTF teams would share the backend binary or backend process then everybody would accidentally rise condition each other by spawning a unique KV process for everybody based on the session ID the rise condition only happens within your unique session nobody influences each other if you want to learn more about hacking check out our online training platform hex free.io we are still in Early Access so there are still lots of content that we need to create but I am still very proud of what we created so far also Google sponsored our Android application security course they have hundreds of apps in their back Bounty program and they identified the lack of resources or good education as a major issue that's why they contacted us they hope that we can teach the next generation of Android application Buck Hunters so give these courses a try they were produced by St smash and me and we did a lot of additional research to create them this is not just knowledge that you can already find online we also cover several vulnerabilities that we have found ourselves in various applications and we created test applications where you can practice what you learned and hunt for Flags so come and check out our courses on hex.io [Music]

Original Description

When auditing code it's crucial to know about common issues. In this video we explore a Go issue that I was not aware of. Learn hacking on https://www.hextree.io/ (ad) 38c3 CTF - Fajny Jagazyn Wartości Kluczy: https://2024.ctf.link/internal/challenge/fb03748d-7e94-4ca2-8998-a5e0ffcbd761/ Unintended solution: https://msanft.foo/blog/hxp-38c3-web-fajny-jagazyn/ Challenge author writeup: https://hxp.io/blog/114/hxp-38C3-CTF-Fajny-Jagazyn-Wartoci-Kluczy/ VSCode Go debugger client code: https://github.com/golang/vscode-go/blob/39786ea90f18ab98f75d091b9a04367d1b1df82c/extension/src/debugAdapter/goDebug.ts#L1557 00:00 - Intro 00:20 - Go gjson vs json behavior 01:33 - Overview CTF challenge "Fajny Jagazyn Wartości Kluczy" 04:33 - Weird server setup? 05:55 - Arbitrary file read 07:00 - /proc filesystem trick 08:01 - Unintended solution 09:14 - What was the intended solution? 12:58 - Exploiting Go race condition 13:58 - Outro =[ ❤️ Support ]= → My courses: https://www.hextree.io/ → My font: https://shop.liveoverflow.com/ → per Video: https://www.patreon.com/join/liveoverflow → per Month: https://www.youtube.com/channel/UClcE-kVhqyiHCcjYwcpfj9w/join 2nd Channel: https://www.youtube.com/LiveUnderflow =[ 🐕 Social ]= → LinkedIn: https://www.linkedin.com/in/liveoverflow → X / Twitter: https://x.com/LiveOverflow/ → Instagram: https://instagram.com/LiveOverflow/ → Streaming: https://twitch.tv/LiveOverflow/ → TikTok: https://www.tiktok.com/@liveoverflow_ → Blog: https://liveoverflow.com/
Watch on YouTube ↗ (saves to browser)
Sign in to unlock AI tutor explanation · ⚡30

Playlist

Uploads from LiveOverflow · LiveOverflow · 0 of 60

← Previous Next →
1 LiveOverflow - Trailer
LiveOverflow - Trailer
LiveOverflow
2 Introduction to Linux - Installation and the Terminal - bin 0x01
Introduction to Linux - Installation and the Terminal - bin 0x01
LiveOverflow
3 Writing a simple Program in C
Writing a simple Program in C
LiveOverflow
4 Writing a simple Program in Python - bin 0x03
Writing a simple Program in Python - bin 0x03
LiveOverflow
5 Live Hacking - Twitch Recording overthewire.org - Vortex 0x01-0x03 (3h)
Live Hacking - Twitch Recording overthewire.org - Vortex 0x01-0x03 (3h)
LiveOverflow
6 Reversing and Cracking first simple Program - bin 0x05
Reversing and Cracking first simple Program - bin 0x05
LiveOverflow
7 Abusing the exception handler to leak flag - 32C3CTF readme (pwnable 200)
Abusing the exception handler to leak flag - 32C3CTF readme (pwnable 200)
LiveOverflow
8 ROP with a very small stack - 32C3CTF teufel (pwnable 200)
ROP with a very small stack - 32C3CTF teufel (pwnable 200)
LiveOverflow
9 Uncrackable Programs? Key validation with Algorithm and creating a Keygen - Part 1/2 - bin 0x07
Uncrackable Programs? Key validation with Algorithm and creating a Keygen - Part 1/2 - bin 0x07
LiveOverflow
10 Uncrackable Program? Finding a Parser Differential in loading ELF - Part 2/2 - bin 0x08
Uncrackable Program? Finding a Parser Differential in loading ELF - Part 2/2 - bin 0x08
LiveOverflow
11 Syscalls, Kernel vs. User Mode and Linux Kernel Source Code - bin 0x09
Syscalls, Kernel vs. User Mode and Linux Kernel Source Code - bin 0x09
LiveOverflow
12 Smashing the Stack for Fun and Profit - setuid, ssh and exploit.education - bin 0x0B
Smashing the Stack for Fun and Profit - setuid, ssh and exploit.education - bin 0x0B
LiveOverflow
13 Live Hacking - EFF-CTF 2016 - Level 0-4 (Enigma Conference)
Live Hacking - EFF-CTF 2016 - Level 0-4 (Enigma Conference)
LiveOverflow
14 First Stack Buffer Overflow to modify Variable - bin 0x0C
First Stack Buffer Overflow to modify Variable - bin 0x0C
LiveOverflow
15 First Exploit! Buffer Overflow with Shellcode - bin 0x0E
First Exploit! Buffer Overflow with Shellcode - bin 0x0E
LiveOverflow
16 Buffer Overflows can Redirect Program Execution - bin 0x0D
Buffer Overflows can Redirect Program Execution - bin 0x0D
LiveOverflow
17 Doing ret2libc with a Buffer Overflow because of restricted return pointer - bin 0x0F
Doing ret2libc with a Buffer Overflow because of restricted return pointer - bin 0x0F
LiveOverflow
18 Reverse engineering C programs (64bit vs 32bit) - bin 0x10
Reverse engineering C programs (64bit vs 32bit) - bin 0x10
LiveOverflow
19 pwnable.kr - Levels: fd, collision, bof, flag
pwnable.kr - Levels: fd, collision, bof, flag
LiveOverflow
20 Reverse Engineering and identifying Bugs - BKPCTF cookbook (pwn 6) part 1
Reverse Engineering and identifying Bugs - BKPCTF cookbook (pwn 6) part 1
LiveOverflow
21 Leaking Heap and Libc address - BKPCTF cookbook (pwn 6) part 2
Leaking Heap and Libc address - BKPCTF cookbook (pwn 6) part 2
LiveOverflow
22 Arbitrary write with House of Force (heap exploit) - BKPCTF cookbook (pwn 6) part 3
Arbitrary write with House of Force (heap exploit) - BKPCTF cookbook (pwn 6) part 3
LiveOverflow
23 Live Hacking - Internetwache CTF 2016 - web50, web60, web80
Live Hacking - Internetwache CTF 2016 - web50, web60, web80
LiveOverflow
24 Live Hacking - Internetwache CTF 2016 - crypto60, crypto70, crypto90
Live Hacking - Internetwache CTF 2016 - crypto60, crypto70, crypto90
LiveOverflow
25 A simple Format String exploit example - bin 0x11
A simple Format String exploit example - bin 0x11
LiveOverflow
26 NEW VIDEOS ARE COMING - loopback 0x00
NEW VIDEOS ARE COMING - loopback 0x00
LiveOverflow
27 HTML + CSS + JavaScript introduction - web 0x00
HTML + CSS + JavaScript introduction - web 0x00
LiveOverflow
28 The HTTP Protocol: GET /test.html - web 0x01
The HTTP Protocol: GET /test.html - web 0x01
LiveOverflow
29 Building Poor Man's Logic Analyzer with an Arduino - Reverse Engineering A/C Remote part 1
Building Poor Man's Logic Analyzer with an Arduino - Reverse Engineering A/C Remote part 1
LiveOverflow
30 What is PHP and why is XSS so common there? - web 0x02
What is PHP and why is XSS so common there? - web 0x02
LiveOverflow
31 Introducing the AngularJS Javascript Framework - XSS with AngularJS 0x00
Introducing the AngularJS Javascript Framework - XSS with AngularJS 0x00
LiveOverflow
32 Sandbox Bypass in Version 1.0.8 - XSS with AngularJS 0x1
Sandbox Bypass in Version 1.0.8 - XSS with AngularJS 0x1
LiveOverflow
33 Capturing & Analyzing Packets with Saleae Logic Pro 8 - Reverse Engineering A/C Remote part 2
Capturing & Analyzing Packets with Saleae Logic Pro 8 - Reverse Engineering A/C Remote part 2
LiveOverflow
34 XSS Contexts and some Chrome XSS Auditor tricks - web 0x03
XSS Contexts and some Chrome XSS Auditor tricks - web 0x03
LiveOverflow
35 Previous Bypass is now fixed in version 1.4.7 - XSS with AngularJS 0x2
Previous Bypass is now fixed in version 1.4.7 - XSS with AngularJS 0x2
LiveOverflow
36 New Sandbox Bypass in 1.4.7 - XSS with AngularJS 0x3
New Sandbox Bypass in 1.4.7 - XSS with AngularJS 0x3
LiveOverflow
37 The Heap: what does malloc() do? - bin 0x14
The Heap: what does malloc() do? - bin 0x14
LiveOverflow
38 The Heap: How to exploit a Heap Overflow - bin 0x15
The Heap: How to exploit a Heap Overflow - bin 0x15
LiveOverflow
39 Reverse Engineering with Binary Ninja and gdb a key checking algorithm - TUMCTF 2016 Zwiebel part 1
Reverse Engineering with Binary Ninja and gdb a key checking algorithm - TUMCTF 2016 Zwiebel part 1
LiveOverflow
40 Scripting radare2 with python for dynamic analysis - TUMCTF 2016 Zwiebel part 2
Scripting radare2 with python for dynamic analysis - TUMCTF 2016 Zwiebel part 2
LiveOverflow
41 Live Hacking - Internetwache CTF 2016 - exp50, exp70, exp80
Live Hacking - Internetwache CTF 2016 - exp50, exp70, exp80
LiveOverflow
42 Sandbox bypass for the latest AngularJS version 1.5.8 - XSS with AngularJS 0x4
Sandbox bypass for the latest AngularJS version 1.5.8 - XSS with AngularJS 0x4
LiveOverflow
43 Channel is growing and Riscure hardware CTF starting soon - loopback 0x01
Channel is growing and Riscure hardware CTF starting soon - loopback 0x01
LiveOverflow
44 Explaining Dirty COW local root exploit - CVE-2016-5195
Explaining Dirty COW local root exploit - CVE-2016-5195
LiveOverflow
45 What is CTF? An introduction to security Capture The Flag competitions
What is CTF? An introduction to security Capture The Flag competitions
LiveOverflow
46 The Heap: How do use-after-free exploits work? - bin 0x16
The Heap: How do use-after-free exploits work? - bin 0x16
LiveOverflow
47 The Browser is a very Confused Deputy - web 0x05
The Browser is a very Confused Deputy - web 0x05
LiveOverflow
48 The Heap: Once upon a free() - bin 0x17
The Heap: Once upon a free() - bin 0x17
LiveOverflow
49 Simple reversing challenge and gaming the system - BruCON CTF part 1
Simple reversing challenge and gaming the system - BruCON CTF part 1
LiveOverflow
50 int0x80 from DualCore lent me his lockpicking set and I'm a horse - BruCON CTF part 2
int0x80 from DualCore lent me his lockpicking set and I'm a horse - BruCON CTF part 2
LiveOverflow
51 The Heap: dlmalloc unlink() exploit - bin 0x18
The Heap: dlmalloc unlink() exploit - bin 0x18
LiveOverflow
52 MD5 Length Extension and Blind SQL Injection - BruCON CTF part 3
MD5 Length Extension and Blind SQL Injection - BruCON CTF part 3
LiveOverflow
53 TCP Protocol introduction - bin 0x1A
TCP Protocol introduction - bin 0x1A
LiveOverflow
54 Socket programming in python and Integer Overflow - bin 0x1B
Socket programming in python and Integer Overflow - bin 0x1B
LiveOverflow
55 Linux signals and core dumps - bin 0x1C
Linux signals and core dumps - bin 0x1C
LiveOverflow
56 [Live] Remote oldschool dlmalloc Heap exploit - bin 0x1F
[Live] Remote oldschool dlmalloc Heap exploit - bin 0x1F
LiveOverflow
57 Riscure Embedded Hardware CTF setup and introduction - rhme2 Soldering
Riscure Embedded Hardware CTF setup and introduction - rhme2 Soldering
LiveOverflow
58 Rooting a CTF server to get all the flags with Dirty COW - CVE-2016-5195
Rooting a CTF server to get all the flags with Dirty COW - CVE-2016-5195
LiveOverflow
59 How to learn hacking? ft. Rubber Ducky
How to learn hacking? ft. Rubber Ducky
LiveOverflow
60 Format String to dump binary and gain RCE - 33c3ctf ESPR (pwn 150)
Format String to dump binary and gain RCE - 33c3ctf ESPR (pwn 150)
LiveOverflow

This video teaches viewers about common Go vulnerabilities, including arbitrary file read and race conditions, and how to identify and exploit them in a CTF challenge. It provides a comprehensive overview of the vulnerability and its implications for cybersecurity.

Key Takeaways
  1. Get a session ID to initialize personal key value store
  2. Spawn requests to get a file that passes check path function and writes nil into error variable
  3. Read flag.txt file while error variable is reset to nil
  4. Use the G Json library to parse JSON requests with an equals sign at the end
  5. Use Docker containers to harden the challenge container
  6. Use Unix domain sockets to forward incoming requests to a backend KV process
💡 The video highlights the importance of understanding common vulnerabilities in Go code and how to identify and exploit them, particularly in the context of CTF challenges.

Related Reads

Chapters (10)

Intro
0:20 Go gjson vs json behavior
1:33 Overview CTF challenge "Fajny Jagazyn Wartości Kluczy"
4:33 Weird server setup?
5:55 Arbitrary file read
7:00 /proc filesystem trick
8:01 Unintended solution
9:14 What was the intended solution?
12:58 Exploiting Go race condition
13:58 Outro
Up next
Best VPN For China 2026 — Which One Actually Works?
Tutorial Stack
Watch →