CTF-Writeups

Writeups for the past CTF challenges

View on GitHub

Hey guys back with another set of few writeups.

CRYPTO

Discrete Superlog-:

description:

You’ve heard of discrete log…now get ready for the discrete superlog.

Server 1: nc crypto.2020.chall.actf.co 20603

Server 2: nc 3.234.224.95 20603

Server 3: nc 3.228.7.55 20603

Author: lamchcl

Solution:

When we connect to the server,we were greeted with this

image

So from the description we know we need to do something with discrete log . But then analyzing this opertor ^^ , we found that this is something we known as Tetration. So in Discrete log , for a function (a^x)=b mod p we need to find x by using baby-step giant-step method. But here the things are different and as they Discrete superlog.

So let’s brute the value of x , in simple words we check for each value of x. Having Fermat’s Little Theorem in mind, I know pow(a,x,p)=pow(a,x mod(phi(p)),p ) where phi() is euler totient function.

So whenever the power raised is getting bigger we will make it smaller by taking modulo over phi(p).Using simple recursion will help it.

Termination:

The program will terminate when finally the power raised is getting modulo 1 or we would say phi(phi(phi….(p)….))=1. After then the answer will be same for every x.

def tet(a,x,p):
    if p==1 or x==0:
        return 1 
    phi=totient(p)
    return pow(a,tet(a,x-1,phi),p)

After testing over some values:

>>> tet(5,1,37)
5
>>> tet(5,2,37)
17
>>> tet(5,3,37)
35
>>> tet(5,4,37)
35
>>> tet(5,5,37)
35

Here is our final script:

from pwn import *
from sympy.ntheory import totient

def tet(a,x,p):
    if p==1 or x==0:
        return 1 
    phi=totient(p)
    return pow(a,tet(a,x-1,phi),p)

r=remote("crypto.2020.chall.actf.co",20603)
level=1

while 1:
    if level>10:
        print(r.recv())
        exit()
    print(r.recvuntil("...\n"))
    details=r.recv()
    values=details.split("\n")[:-1]
    print(values)
    p=int(values[0].split()[-1])
    a=int(values[1].split()[-1])
    b=int(values[2].split()[-1])
    x=0
    while 1:
        c=tet(a,x,p)
        if c == b:
            break
        x+=1
    print("x value : "  + str( x ) )
    r.sendline(str(x))
    level+=1

r.close()

We got this response for the above script:

image

Here is our flag:actf{lets_stick_to_discrete_log_for_now...}

Wacko Images-:

description:

How to make hiding stuff a e s t h e t i c? And can you make it normal again? enc.png image-encryption.py

Author: floorthfloor

Solution:

So we are given a script which just encrypt the value of [r,g,b] values of each pixel in the image. And makes the image completely gibberish from outside.

image

The given script:

from numpy import *
from PIL import Image

flag = Image.open(r"flag.png")
img = array(flag)

key = [41, 37, 23]

a, b, c = img.shape

for x in range (0, a):
    for y in range (0, b):
        pixel = img[x, y]
        for i in range(0,3):
            pixel[i] = pixel[i] * key[i] % 251
        img[x][y] = pixel

enc = Image.fromarray(img)
enc.save('enc.png')

So if we see the script we found that values are multiplied by key array. So we need to just divide it (modular division) :smiley: .

Here is our script:

from numpy import *
from PIL import Image
from gmpy2 import *

flag = Image.open(r"enc.png")
img = array(flag)

key = [41, 37, 23]
invkey=[invert(k,251) for k in key]

a, b, c = img.shape

for x in range (0, a):
    for y in range (0, b):
        pixel = img[x, y]
        for i in range(0,3):
            pixel[i] = pixel[i] * invkey[i] % 251
        img[x][y] = pixel

dec = Image.fromarray(img)
dec.save('flag.png')

Voila! we got the flag: image

There is our flag : actf{m0dd1ng_sk1llz}