Showing posts with label CTF challenge. Show all posts
Showing posts with label CTF challenge. Show all posts

Monday, November 19, 2018

Square CTF - Dot-n-Dash

This was a fun little programming challenge from the recent Square CTF.

We are given an html file and an encoded 'instructions.txt' file, which is a cipher of sorts containing nothing but dots and dashes.

Loading the html file shows that there is JavaScript running that can encode and decode text. Unfortunately, the developers never finished the decode function off, so it is up to us to find a way to decode the message.



Looking at the source code, we can get a better understanding of what is going on, and also strip away functions and play with the app to get a clearer picture.


function encode() {
  var t = input.value;
  if (/^[-.]+$/.test(t)) {
    alert("Your text is already e'coded!");
  } else {
    input.value = _encode(t);
  }
  return false;
}

function decode() {
  var t = input.value;
  if (/^[-.]*$/.test(t)) {
    input.value = _decode(t);
  } else {
    alert("Your text is not e'coded!");
  }
  return false;
}

function _encode(input) {
  var a=[];
  for (var i=0; i < input.length; i++) {
    var t = input.charCodeAt(i);
    for (var j=0; j<8 if="" j="" t="">> j) & 1) {
        a.push(1 + j + (input.length - 1 - i) * 8);
      }
    }
  }

  var b = [];
  while (a.length) {
    var t = (Math.random() * a.length)|0;
    b.push(a[t]);
    a = a.slice(0, t).concat(a.slice(t+1));
  }

  var r = '';
  while (b.length) {
    var t = b.pop();
    r = r + "-".repeat(t) + ".";
  }
  return r;
}

// Everything below this line was lost due to cosmis radiation. The engineer who knows
// where the backups are stored already left.
function _decode(input) {
  return "";
}


Trying to encode "a":


Trying to encode "aa":




Essentially what this code is doing is taking the input given, converting all characters in the string to a decimal value, and then determining which bits are active and creates an array based on the bit numbers that are a 1. The next part randomizes all of the numbers in the array, and then each number is represented by dashes equal to how large it is. Each number is delimited by dots.

Now that we have this information, we can create a Python script to convert the encoded instructions.txt into an array.


stri = open("instructions.txt","r").read()
stri_list = stri.split('.')
a = []
for i in stri_list[:-1]:
    #print len(i)
    a.append(len(i))
print a




While the encoder tries to make it tricky by randomizing all the numbers, the idea is that this is a very long binary string, and each "1" is being represented by a number in a total of 1296 bits, so we can sort the numbers easily.



Now it is just a matter of adding to our script to create a binary string with these numbers as the "1" and the other numbers as "0", and then convert that binary string to ASCII text.


import binascii

stri = open("instructions.txt","r").read()
stri_list = stri.split('.')
a = []
for i in stri_list[:-1]:
    #print len(i)
    a.append(len(i))

print "Encoded array: "
print sorted(a, key=int)
print "\n"

allbits = []
for bits in range(1,1297):
    allbits.append(bits)

modbits = []
for i in allbits:
    if i in a and i in allbits:
        i=1
        modbits.append(i)
    else:
        i=0
        modbits.append(i)

binstring = ''.join(str(e) for e in modbits)

flag = int(binstring[::-1],2)
print binascii.unhexlify('%x' % flag)

Running the script and we get the flag!




























Sunday, February 25, 2018

TAMUCTF: Bandaid

We are given a broken binary that claims it needs some fixin'!

We can go about this two ways: Patch the assembly so it executes as it should OR we can just force it to execute properly in GDB by setting the EIP to the function it is supposed to execute. I went with the latter method.



Setting the EIP to the address for _Z2f2v, we continue the program and it spits out a ton of stuff.
The top portion is definitely some sort of encryption, and the two big chunks below it are a ton of base64. Wonder that that could be...


Ah--neat! So we get a private and public RSA key, which means the private key should be able to decrypt the message at the top.


Modifying an existing RSA decryption python script, we can easily decrypt our message and get our flag!



TAMUCTF: Pwn 1 & 2

Pwn1:

Disassembling the binary we are given, we can see there is a print_flag function that is preceded by a cmp instruction.


We can perform a buffer overflow to manually enter the hex word "0xf007ba11" so that the comparison statement evaluates properly and the print_flag function is executed.

Looking at the assembly we can determine that our padding for our exploit will be 23 bytes long + 4 more bytes with our hex word. Remember though--this needs to be put in little endian, so we end up with the following payload:



Testing this out in GDB we see that it works perfectly, and we are able to fulfill the check.



Now we can take our payload and send it to the server running the binary.


And we get the flag!


=============

Pwn 2:


Using objectdump first, we are able to see that this is a hidden print_flag function that we can call after initiating a buffer overflow.



This time our buffer is a bit larger than last time, and our padding will be 243 bytes followed by our 4 byte address for print_flag.


Sending this to the server, we are able to get the flag!



TAMUCTF: Enum

This was by far my favorite challenge of the CTF since it resembled a mini boot-to-root challenge (minus actually getting root part...), which focused a lot (surprise, surprise) on enumeration.



When we initially SSH in, we are dropped into a restricted shell, so first things first to make it easier on ourselves, call /bin/bash with echo 'os.system("/bin/bash")' .

It took quite a lot of prodding around to find anything interesting, but I eventually discovered the following:



Alright, so we know they are running a pyserver of some sort. Time to find out what's going on.



Cool, it is running as root over port 9000. Now it's just a matter of finding a way to interact with it. We can do this by port forwarding to our local host with the following command:


Now that it is set, all we need to do is pull up our browser and navigate to our local host and the 8080 port we indicated.




Doing so, we get the flag!

Friday, December 29, 2017

34C3 Junior CTF

CTF: 34C3 Junior CTF 2017

Challenge:
SPI

Category:
Misc



We are given a sound file to listen to, which is a recording of various values.
Writing them all down gives us the following:

76 83 48 116 76 105 52 103
76 83 48 116 76 83 52 103
76 105 48 117 76 83 65 116
76 83 48 116 76 105 65 116
76 105 48 117 76 83 52 103
76 83 48 116 76 83 48 103
76 83 52 117 76 83 65 117
76 83 52 117 73 67 48 117
76 83 52 116 76 105 65 116
76 83 48 117 73 67 48 116
76 83 48 116 73 67 48 117
76 83 52 116 76 105 65 116
76 83 48 116 76 83 65 116
76 105 52 116 73 67 52 116
76 105 52 78 67 103 61 61

These are decimal values, so converting to ascii we are given a base64 encoding:

LS0tLi4gLS0tLS4gLi0uLSAtLS0tLiAtLi0uLS4gLS0tLS0gLS4uLSAuLS4uIC0uLS4tLiAtLS0uIC0tLS0tIC0uLS4tLiAtLS0tLSAtLi4tIC4tLi4NCg==

Converting the base64 back to ascii gives us some morse code:

---.. ----. .-.- ----. -.-.-. ----- -..- .-.. -.-.-. ---. ----- -.-.-. ----- -..- .-..

I spent a bit trying to decipher this because it is not just a simple case of decoding it as is. I even reversed the whole code, but that didn't work either, but then I decided to swap all the dashes for dots and all the dots for dashes and got the flag!

...-- ....- -.-. ....- .-.-.- ..... .--. -.-- .-.-.- ...- ..... .-.-.- ..... .--. -.--
                                         

Flag:

34C4.5PY.V5.5PY


===================================

Challenge:
Digital Billboard

Category:
PWN



This program allows us to set text displayed on a billboard, but when exploring the menu options there is a devmode that is locked to the regular user.



Exploring the source code that they give us, this devmode allows us to execute the priviledged function "shell" which gives us access to /bin/bash--so this is our goal here.



Luckily there is an easy way to enable devmode. The set_text function is using the strcpy function, which we can exploit.
The struct for billboard has an array for text with a buffer of 256 bytes, which is immediately followed by the flag for devmode. We can overflow this buffer to change the subsequent value and enable devmode.

Inputting our string we are able to access devmode and use the shell command which gives us an interactive bash shell.
Checking the files in the directory, we find the flag!




===================================

Challenge:
Babybash

Category:
Misc



For this challenge we are dropped into a restricted bash shell, but we need to execute the "get_flag" program.



Luckily we are able to use capital letters and creativity to bypass this.

They throw a bit of a twist into the mix when executing the program for the first time, and it requires an additional argument,so we modify our command a bit and get the flag upon properly execution.



===================================

Challenge:
ARM1

Category:
Rev



Simply running strings on the ARM binary will reveal the flag (the other ARM-related challenges were not this simple...)



===================================

Challenge:
ARM2

Category:
Rev



Upgrading the difficulty from the prior ARM challenge, it seems like the flag is encrypted in some way judging by the characters that follow the "The flag is:" string.



I used a couple of programs to analyze. I used IDA to grab all the hex values for the encrypted string.



And since I couldn't get a good output of the pseudocode for whatever reason, I used Hopper, which gave me the hint that these values were being xor'ed with 0x55.

Using a script that I wrote to automate the decryption of these types of challenges (seems like there are often similar ones in CTFs all the time), we are able to get our flag!



Sunday, December 17, 2017

InCTF | Web Challenge: Liar

Challenge:
Liar

Category
Web



When the site loads, there is nothing on the page except for a message that nothing is on their website--but we know, as the title of the challenge states, this is a big, fat lie.



The hint tells us that the site is using some form of VCS, and after some testing, I discovered the site was using Mercurial. Based on this knowledge, I used wget to download the ".hg/dirstate" file, which is a binary file that is an information directory about the repository.

Running strings on the file, the following was output:



Nice, so now we have a directory to look at, and it seems like there is also a vulnerable PHP to work with as well. The index.html has a form to "find your friends" and this is what is running the PHP.



Inspecting the source code, we get a bit of a hint:



So, I fired up Sqlmap to do the heavy lifting based on the data that was being passed, including name and the captcha:

sqlmap -u "http://liar.inctf.in/1ts_h4rd_t0_gu3ss/vulnerable.php" --data="name=ron&g-recaptcha-response=03AO6mBfw5nAnH7od5LVOqf7H-Yib-8E52lULt4-Zxt9dVb_j3NV6lLCf0BEAK5i3BnYLgoAradJJYGXSCPAe3OhOFJndC4eiJ2ndshWtp74YgsDO-qcfM2Iy4yvDuuCO4N_oIsZ-QtL9uqgqJseKy0ncgRT91QOL7QnKYun60O_2pSwJUN7tgXpxQjqaCzM-V064cRpAHePHKX8nUaAxvRanHQTfINRMFI9MSu1wlJnLO4GS-GD9reD2lZDqIRXJ8bGBRVBDmhtYJ2KUxPVYTMlKnS9BnrsT_eMvMIcef0ULl3-Zc4_qO81sCw0iEEEdjkNbL0PaQ72uUr8TZMH8MQR-xQ3xlNVs_VwZOGu79WeVEMtwLqfVFCONbaOJfpupzHEL17KMCemKxn3gLrNqhAe-7muUxB3EZ7iSQVQa16moJkxPOm8Hf7982" --dump-all --threads=10 --random-agent --dbms=mysql --level=5 --risk=3

The result:





Now when we go to dump all the databases, we get trolled. The CTF database had some leet speak in it that appeared to be the flag, but it was not. Since this is time-based, it will take a while to dump everything in information_schema (there are 61 tables), so I turned to check the mysql database first instead. Guessing a bit here, I first got the "innodb_table_stats" table and then decided to guess that a "phone" column existed in there since the hint in the source code mentioned our answer is in the phone column.

Luckily I was correct!

sqlmap -u "http://liar.inctf.in/1ts_h4rd_t0_gu3ss/vulnerable.php" --data="name=ron&g-recaptcha-response=03AO6mBfw5nAnH7od5LVOqf7H-Yib-8E52lULt4-Zxt9dVb_j3NV6lLCf0BEAK5i3BnYLgoAradJJYGXSCPAe3OhOFJndC4eiJ2ndshWtp74YgsDO-qcfM2Iy4yvDuuCO4N_oIsZ-QtL9uqgqJseKy0ncgRT91QOL7QnKYun60O_2pSwJUN7tgXpxQjqaCzM-V064cRpAHePHKX8nUaAxvRanHQTfINRMFI9MSu1wlJnLO4GS-GD9reD2lZDqIRXJ8bGBRVBDmhtYJ2KUxPVYTMlKnS9BnrsT_eMvMIcef0ULl3-Zc4_qO81sCw0iEEEdjkNbL0PaQ72uUr8TZMH8MQR-xQ3xlNVs_VwZOGu79WeVEMtwLqfVFCONbaOJfpupzHEL17KMCemKxn3gLrNqhAe-7muUxB3EZ7iSQVQa16moJkxPOm8Hf7982" --threads=10 --random-agent --dbms=mysql --level=5 --risk=3 -D mysql -T innodb_table_stats -C phone --dump

Though the above took quite a bit to finish, it eventually dumps out our flag:

inctf{H0w_@b0Ut_@n_r3@L_1nJ3c}


InCTF | Rev Challenge: Time

Challenge:
Time

Category
Rev



Since this was an ARM file I couldn't find a way to run it on my machine, so I stuck to disassembling the binary file with Binary Ninja.

Looking at what was going on, I found a big segment of data that definitely looked like it could be important.



Working backwards from here, it became clear that the function that spits out the flag, uses this data, and looking at the disassembly, you can see that the program is taking each one of these hex values and XORing it with 0x7.



I created a Python script to do just that:



Running it we get the flag:



Powered by Blogger.