> For the complete documentation index, see [llms.txt](https://tazarkour.gitbook.io/blog/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://tazarkour.gitbook.io/blog/writeups/ctfzone-quals-2024-or-youtube-unlock-and-youtube-unlock-revenge-ggc-exploit.md).

# CTFZONE Quals 2024 | Youtube Unlock & Youtube Unlock Revenge (GGC Exploit)

Difficulty : Easy to Medium

I solved these two tasks but I don't understand them very much, sorry if there are any inconsistencies.&#x20;

### Youtube Unlock :&#x20;

<figure><img src="https://2030182716-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHaXlWvvSeitk8U02TmA9%2Fuploads%2Fh9Wdac7AzjSCFxhflTqg%2Fimage.png?alt=media&amp;token=d5643a95-f98d-4e11-a945-316b50463cc3" alt=""><figcaption></figcaption></figure>

Let's start by reading the code to understand the task.

&#x20;/app/nginx/nginx.conf :&#x20;

```nginx
worker_processes  1;

events {
    worker_connections  1024;
}


http {
    include       mime.types;

    default_type  application/octet-stream;

    sendfile        on;
    
    keepalive_timeout  65;
    
    server {
        listen       80;

        location / {
            return 301 https://$host$request_uri;
        }
    }

    server {
        listen       4431 ssl;
        ssl_certificate /cert.pem;
        ssl_certificate_key /cert.key;

        location / {
            return 301 https://blocked.org.uk:443;
        }
    }

    server {
        listen       4432 ssl;
        ssl_certificate /cert.pem;
        ssl_certificate_key /cert.key;

        location / {
            return 301 https://www.youtube.com/watch?v=WIRK_pGdIdA;
        }
    }
}

stream {
    map $ssl_preread_server_name $proxy {
        youtube.com              backend;
        www.youtube.com          backend;
        default                  backend_default;
    }

    upstream backend_default {
        server 127.0.0.1:4431;
    }

    upstream backend {
        server 127.0.0.1:4432;
    }

    server {
        listen 4430;
        ssl_preread on;
        proxy_pass  $proxy;
    }
}
```

&#x20;/app/dpi/dpi.py :&#x20;

```python
import socket
import select
import os 

def server_connection(dst_ip, dst_port):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((dst_ip, dst_port))
    return sock

BUFFER_SIZE = 140

dst_ip = 'nginx'
dst_port = 4430
srv_port = 443
sockets = []

srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

srv.bind(("0.0.0.0", srv_port))
srv.listen(3)

print(f'listening connection on port {srv_port}')

sockets.append(srv)

while True:
    socks,_,_=select.select(sockets,[],[])
    
    for sock in socks:
        
        try:
            
            if sock==srv:
                print ("sock : " +str(sock))
                print ("srv : " + str(srv))
                buf ="empty"
                client,_=srv.accept()
                print(f"new connection")
                sockets.append(client)
                server=server_connection(dst_ip, dst_port)
                sockets.append(server)
                buff=sock.recv(BUFFER_SIZE)
                print("buffer : "+str(buff))
            else:
                buf=sock.recv(BUFFER_SIZE)
                if b'youtube' in buf:
                    print('BAN!!!')
                    os.system("echo BAN > ban.txt;")
                    continue
                id=sockets.index(sock)
                if id%2==1: 
                    if len(buf) == 0:
                        sockets[id].close()
                        sockets[id+1].close()
                        del sockets[id]
                        del sockets[id]
                    else:
                        sockets[id+1].sendall(buf)
                else: 
                    if len(buf) == 0:
                        sockets[id-1].close()
                        sockets[id].close()
                        del sockets[id-1]
                        del sockets[id-1]
                    else:
                        sockets[id-1].sendall(buf)
                        print("success")
        except Exception as e:
            print(e)
```

The nginx server hosts 2 servers each one under a service name, accessing the server normally will result to a redirect blocked.org.uk, what is needed is to use the Service name youtube.com to access the youtube video that will probably contain the flag.

So now checking the python code, we see that it acts as a proxy to our nginx server, it will block every request containing the string "youtube", but since it's case sensitive we can just bypass it by using "Youtube.com" instad of "youtube.com".

So now how do we do this ?

First we intercepted a request to the server and put in repeater.

<figure><img src="https://2030182716-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHaXlWvvSeitk8U02TmA9%2Fuploads%2FfTrWjJ5x2LsQcgeRu4wR%2Fimage.png?alt=media&amp;token=fb51667e-593e-4329-b4ca-1a381c7133e3" alt=""><figcaption></figcaption></figure>

Then you got edit target and change the check override SNI and enter Youtube.com

<figure><img src="https://2030182716-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHaXlWvvSeitk8U02TmA9%2Fuploads%2FlVuDnHYtRIqLXvwdfhcJ%2F2.PNG?alt=media&amp;token=19600e31-84b9-4ce0-9cbf-c81ff678c50d" alt=""><figcaption></figcaption></figure>

After it we follow the redirection and get to a youtube video

<figure><img src="https://2030182716-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHaXlWvvSeitk8U02TmA9%2Fuploads%2FzJunMWdZWaWMJhp6vhkQ%2Fimage.png?alt=media&amp;token=683eb32f-f827-49f1-bc59-250f1a490c4f" alt=""><figcaption></figcaption></figure>

This video will contain the flag.

<figure><img src="https://2030182716-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHaXlWvvSeitk8U02TmA9%2Fuploads%2FDDUQPr7M0nofzTw617CW%2F4.PNG?alt=media&amp;token=2600018a-8a98-4632-a7b3-0d95b9fdce6e" alt=""><figcaption></figcaption></figure>

Pretty easy stuff

## Youtube unlock | Revenge :&#x20;

<figure><img src="https://2030182716-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHaXlWvvSeitk8U02TmA9%2Fuploads%2F1y9pnfyiLQG448MUT8kr%2Fimage.png?alt=media&amp;token=7d72d324-33e9-482c-8175-e2aae1c653b6" alt=""><figcaption></figcaption></figure>

The second challenge is almost the same thing but with a little change to the files.

&#x20;/app/nginx/nginx.conf :&#x20;

```nginx
worker_processes  1;

events {
    worker_connections  1024;
}


http {
    include       mime.types;

    default_type  application/octet-stream;

    sendfile        on;
    
    keepalive_timeout  65;
    
    server {
        listen       80;

        location / {
            return 301 https://$host$request_uri;
        }
    }

    server {
        listen       4431 ssl;
        ssl_certificate /cert.pem;
        ssl_certificate_key /cert.key;

        location / {
            return 301 https://blocked.org.uk:443;
        }
    }

    server {
        listen       4432 ssl;
        ssl_certificate /cert.pem;
        ssl_certificate_key /cert.key;

        location / {
            return 301 https://www.youtube.com/watch?v=WIRK_pGdIdA;
        }
    }
}

stream {
    map $ssl_preread_server_name $proxy {
        youtube.com              backend;
        www.youtube.com          backend;
        default                  backend_default;
    }

    upstream backend_default {
        server 127.0.0.1:4431;
    }

    upstream backend {
        server 127.0.0.1:4432;
    }

    server {
        listen 4430;
        ssl_preread on;
        proxy_pass  $proxy;
    }
}
```

&#x20;/app/dpi/dpi.py :&#x20;

```python
import socket
import select

def server_connection(dst_ip, dst_port):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((dst_ip, dst_port))
    return sock

BUFFER_SIZE = 140

dst_ip = 'nginx'
dst_port = 4430
srv_port = 443
sockets = []

srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

srv.bind(("0.0.0.0", srv_port))
srv.listen(3)

print(f'listening connection on port {srv_port}')

sockets.append(srv)

while True:
    socks,_,_=select.select(sockets,[],[])

    for sock in socks:
        try:
            if sock==srv:
                client,_=srv.accept()
                print(f"new connection")
                sockets.append(client)
                server=server_connection(dst_ip, dst_port)
                sockets.append(server)
            else:
                buf=sock.recv(BUFFER_SIZE)
                if b'youtube' in buf.lower():
                    print('BAN!!!')
                    continue
                id=sockets.index(sock)
                if id%2==1: 
                    if len(buf) == 0:
                        sockets[id].close()
                        sockets[id+1].close()
                        del sockets[id]
                        del sockets[id]
                    else:
                        sockets[id+1].sendall(buf)
                else: 
                    if len(buf) == 0:
                        sockets[id-1].close()
                        sockets[id].close()
                        del sockets[id-1]
                        del sockets[id-1]
                    else:
                        sockets[id-1].sendall(buf)
        except Exception as e:
            print(e)
```

The key difference is now file upload is allowed on the server and secondly the server will require a pair socket id. To ensure we get two sockets in our request, we can upload a blank file so it would queue the file transfer in the socket queue.

so again with the same.

<figure><img src="https://2030182716-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHaXlWvvSeitk8U02TmA9%2Fuploads%2FEZOvxJGJRu7ttYb9AW1s%2F6.PNG?alt=media&amp;token=0f72e75e-fc82-4265-b520-8e2ab702e910" alt=""><figcaption></figcaption></figure>

and for our request.

<figure><img src="https://2030182716-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHaXlWvvSeitk8U02TmA9%2Fuploads%2F2A9craQbF44LZdHWsZzL%2F5.PNG?alt=media&amp;token=376a3f66-9c87-4e9a-84c8-5963e8004c49" alt=""><figcaption></figcaption></figure>

we get the flag appended to the youtube link.

I didn't understand this challenge very well, it tried this and worked, what I wrote here is me trying to understand why it works, so sorry if I'm wrong in some points.&#x20;
