PwnCollege - RE - Input Restrictions

Input Restrictions (Python)

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
def main():
if len(sys.argv) >= 2:
path = sys.argv[1]
assert path.endswith(".cimg"), "ERROR: file has incorrect extension"
file = open(path, "rb")
else:
file = sys.stdin.buffer

header = file.read1(9)
assert len(header) == 9, "ERROR: Failed to read header!"

assert header[:4] == b"cIMG", "ERROR: Invalid magic number!"

assert int.from_bytes(header[4:5], "little") == 1, "ERROR: Invalid version!"

width = int.from_bytes(header[5:7], "little")
assert width == 71, "ERROR: Incorrect width!"

height = int.from_bytes(header[7:9], "little")
assert height == 21, "ERROR: Incorrect height!"

data = file.read1(width * height)
assert len(data) == width * height, "ERROR: Failed to read data!"

pixels = [Pixel(character) for character in data]

invalid_character = next((pixel.ascii for pixel in pixels if not (0x20 <= pixel.ascii <= 0x7E)), None)
assert invalid_character is None, f"ERROR: Invalid character {invalid_character:#04x} in data!"

with open("/flag", "r") as f:
flag = f.read()
print(flag)


if __name__ == "__main__":
try:
main()
except AssertionError as e:
print(e, file=sys.stderr)
sys.exit(-1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from pwn import *
from pwn import process

header = b"cIMG"
version = 1
width = 71
height = 21
data_length = width * height

# I -> 4 bytes
# B -> 1 byte
# H -> 2 bytes
file_header = struct.pack("<4sBHH", header,version, width, height)

pixel_data = b"A" * data_length

payload = file_header + pixel_data

file = open("payload.cimg", "wb")
file.write(payload)
file.close()

p = process(["/challenge/cimg", "payload.cimg"], stdin=process.PTY, stdout=process.PTY)
print(p.recvall())

b’pwn.college{**********************************************}’

Input Restrictions (C)

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
// ...
#define CIMG_NUM_PIXELS(cimg) ((cimg)->header.width * (cimg)->header.height)
#define CIMG_DATA_SIZE(cimg) (CIMG_NUM_PIXELS(cimg) * sizeof(pixel_t))
// ...
int main(int argc, char **argv, char **envp)
{

struct cimg cimg = { 0 };
int won = 1;

if (argc > 1)
{
if (strcmp(argv[1]+strlen(argv[1])-5, ".cimg"))
{
printf("ERROR: Invalid file extension!");
exit(-1);
}
dup2(open(argv[1], O_RDONLY), 0);
}

read_exact(0, &cimg.header, sizeof(cimg.header), "ERROR: Failed to read header!", -1);

if (cimg.header.magic_number[0] != 'c' || cimg.header.magic_number[1] != 'I' || cimg.header.magic_number[2] != 'M' || cimg.header.magic_number[3] != 'G')
{
puts("ERROR: Invalid magic number!");
exit(-1);
}

if (cimg.header.version != 1)
{
puts("ERROR: Unsupported version!");
exit(-1);
}

if (cimg.header.width != 71)
{
puts("ERROR: Incorrect width!");
exit(-1);
}

if (cimg.header.height != 21)
{
puts("ERROR: Incorrect height!");
exit(-1);
}

unsigned long data_size = cimg.header.width * cimg.header.height * sizeof(pixel_t);
pixel_t *data = malloc(data_size);
if (data == NULL)
{
puts("ERROR: Failed to allocate memory for the image data!");
exit(-1);
}
read_exact(0, data, data_size, "ERROR: Failed to read data!", -1);

for (int i = 0; i < cimg.header.width * cimg.header.height; i++)
{
if (data[i].ascii < 0x20 || data[i].ascii > 0x7e)
{
fprintf(stderr, "ERROR: Invalid character 0x%x in the image data!\n", data[i].ascii);
exit(-1);
}
}

if (won) win();
}
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
from pwn import *
from pwn import process

header = b"cIMG"
version = 1
width = 71
height = 21
data_length = width * height

# I -> 4 bytes
# B -> 1 byte
# H -> 2 bytes
# Q -> 8 bytes
file_header = struct.pack("<4sHBQ", header,version, width, height)

pixel_data = b"A" * data_length

payload = file_header + pixel_data

file = open("payload.cimg", "wb")
file.write(payload)
file.close()

p = process(["/challenge/cimg", "payload.cimg"], stdin=process.PTY, stdout=process.PTY)
print(p.recvall())

b’pwn.college{**********************************************}’

Input Restrictions (x86)

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
# ...
│ 0x004012fd 807c240663 cmp byte [rsp + 6], 0x63 ; 'c'
│┌─< 0x00401302 7515 jne 0x401319
││ 0x00401304 807c240749 cmp byte [rsp + 7], 0x49 ; 'I'
┌───< 0x00401309 750e jne 0x401319
│││ 0x0040130b 807c24084d cmp byte [rsp + 8], 0x4d ; 'M'
┌────< 0x00401310 7507 jne 0x401319
││││ 0x00401312 807c240947 cmp byte [rsp + 9], 0x47 ; 'G'
┌─────< 0x00401317 7414 je 0x40132d
│└└─└─> 0x00401319 488d3df60d.. lea rdi, str.ERROR:_Invalid_magic_number_ ; 0x402116 ; "ERROR: Invalid magic number!"
┌─┌┌─┌─> 0x00401320 e81bfeffff call sym.imp.puts ;[6]
┌────└──> 0x00401325 83cfff or edi, 0xffffffff ; -1
╎╎│╎╎ ╎ 0x00401328 e8d3feffff call sym.imp.exit ;[7]
╎╎└─────> 0x0040132d 48837c240a01 cmp qword [rsp + 0xa], 1
╎╎ ╎╎ ╎ 0x00401333 488d3df90d.. lea rdi, str.ERROR:_Unsupported_version_ ; 0x402133 ; "ERROR: Unsupported version!"
╎└──────< 0x0040133a 75e4 jne 0x401320
╎ ╎╎ ╎ 0x0040133c 66837c24122e cmp word [rsp + 0x12], 0x2e ; '.'
╎ ╎╎ ╎ 0x00401342 488d3d060e.. lea rdi, str.ERROR:_Incorrect_width_ ; 0x40214f ; "ERROR: Incorrect width!"
╎ └────< 0x00401349 75d5 jne 0x401320
╎ ╎ ╎ 0x0040134b 837c241414 cmp dword [rsp + 0x14], 0x14
╎ ╎ ╎ 0x00401350 488d3d100e.. lea rdi, str.ERROR:_Incorrect_height_ ; 0x402167 ; "ERROR: Incorrect height!"
╎ └───< 0x00401357 75c7 jne 0x401320
╎ ╎ 0x00401359 bf98030000 mov edi, 0x398 ; 920
╎ ╎ 0x0040135e e85dfeffff call sym.imp.malloc ;[8]
╎ ╎ 0x00401363 488d3d160e.. lea rdi, str.ERROR:_Failed_to_allocate_memory_for_the_image_data_ ; 0x402180 ; "ERROR: Failed to all
╎ ╎ 0x0040136a 4889c3 mov rbx, rax
╎ ╎ 0x0040136d 4885c0 test rax, rax
╎ └─< 0x00401370 74ae je 0x401320
╎ 0x00401372 ba98030000 mov edx, 0x398 ; 920
╎ 0x00401377 4889c6 mov rsi, rax
╎ 0x0040137a 4183c8ff or r8d, 0xffffffff ; -1
╎ 0x0040137e 31ff xor edi, edi
╎ 0x00401380 488d0d2e0e.. lea rcx, str.ERROR:_Failed_to_read_data_ ; 0x4021b5 ; "ERROR: Failed to read data!"
╎ 0x00401387 e83f020000 call sym.read_exact ;[5]
╎ 0x0040138c 0fb7542412 movzx edx, word [rsp + 0x12]
╎ 0x00401391 0faf542414 imul edx, dword [rsp + 0x14]
╎ 0x00401396 31c0 xor eax, eax
╎ ┌─> 0x00401398 39c2 cmp edx, eax
╎ ┌──< 0x0040139a 762f jbe 0x4013cb
╎ │╎ 0x0040139c 0fb60c03 movzx ecx, byte [rbx + rax]
╎ │╎ 0x004013a0 48ffc0 inc rax
╎ │╎ 0x004013a3 8d71e0 lea esi, [rcx - 0x20]
╎ │╎ 0x004013a6 4080fe5e cmp sil, 0x5e ; '^' ; 94
╎ │└─< 0x004013aa 76ec jbe 0x401398
╎ │ 0x004013ac 488b3d8d2c.. mov rdi, qword [obj.stderr] ; obj.stderr__GLIBC_2.2.5
╎ │ ; [0x404040:8]=0
╎ │ 0x004013b3 488d15170e.. lea rdx, str.ERROR:_Invalid_character_0x_x_in_the_image_data__n ; str.ERROR:_Invalid_character_0x_x_
╎ │ ; 0x4021d1 ; "ERROR: Invalid character 0x%x in the image data!\n"
╎ │ 0x004013ba be01000000 mov esi, 1
╎ │ 0x004013bf 31c0 xor eax, eax
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from pwn import *
from pwn import process

header = b"cIMG"
version = 1
width = 0x2e
height = 0x14
data_length = width * height

file_header = struct.pack("<4sQHI", header,version, width, height)

pixel_data = b"A" * data_length

payload = file_header + pixel_data

file = open("payload.cimg", "wb")
file.write(payload)
file.close()

p = process(["/challenge/cimg", "payload.cimg"], stdin=process.PTY, stdout=process.PTY)
print(p.recvall())

b’pwn.college{**********************************************}’