---
# System prepended metadata

title: ASCIS 2023 Warmup Writeup

---

# "ASCIS 2023 Warmup" Writeup
Author: JakeClark
Date: Sat, Oct 7th 2023
Site: warmup.ascis.vn
## Web Application

### Hide and Seek! (current: 300 -> 100 points/83 solves)
Description:
```
Let Find me!
http://access.sectigo.one:18000 
```

Đây là 1 thử thách khá khó vì chúng ta chả thể làm gì được nếu chỉ dựa vào front-end (vì front-end chả có gì đặc biệt để khai thác):
``` htmlmixed
<!DOCTYPE html>
<html>
<body style="background-color:black;" >
<style type="text/css">
    img {
      width: 800px;
      height: auto;
      align-items: center;
    }

    .center {
      display: block;
      margin-left: auto;
      margin-right: auto;
      width: 50%;
    }
</style>
    <header>
        <title>
            Hide And Seek!
        </title>
    </header>
    <body>
        <img src="https://www.jeumobi.com/wp-content/uploads/2021/01/hide-and-seek-among-us.jpg" class="center">
        <br>
        <img src="https://www.buzzsight.co/Uploads/imgQ//20230104/04edb70c3bec440d83a63d5b85c4c636.jpg" class="center">
    </body>
</html>
```
Vậy làm sao để khai thác được nó? Thực ra bài này tui không giải được, nhưng sau khi hết giờ làm bài thì 1 người nào đó (cứ tưởng tượng là ông Bụt đi) đã nghe thấy tui *khóc* và ông Bụt đã cho gợi ý như sau: "Con đã biết IP của trang web này rồi đúng không, vậy con hãy thay đổi số đầu thành 127 đi, rồi con sẽ thấy bất ngờ..." (yên tâm, tui bịa đấy)
Vậy là tui đã mang request này vào Burp Suite Repeater, chỉnh chỗ `access.sectigo.one` thành `127.90.227.28` (IPv4 ban đầu của nó là `103.90.227.28`)
**request:**
```
GET / HTTP/1.1
Host: 127.90.227.28:18000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/118.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1

```
**response:**
```
HTTP/1.1 200 OK
Server: nginx
Date: Sat, 07 Oct 2023 07:02:07 GMT
Content-Type: text/html
Content-Length: 16
Connection: close
Last-Modified: Sat, 07 Oct 2023 02:41:22 GMT
ETag: "6520c552-10"
X-Server-BE: Server-1
X-NginX-Http-Proxy-Host: 127.0.0.1:18000
Accept-Ranges: bytes
X-NginX-Http-Host: 127.90.227.28:18000
X-NginX-Proxy: true

ASCIS{0ppp!_Y0u
```
Sau đó ta liên tục thử đổi port tăng dần lên 1, ta nhận được lần lượt những response sau:
```
Host: 127.90.227.28:18001

-Rand0mly-

Host: 127.90.227.28:18002

F0und_M3

Host: 127.90.227.28:18007

_Gre@t!}
```
Ghép chúng lại, ta sẽ có flag là: `ASCIS{REDACTED}` 
<details>
  <summary>REDACTED?</summary>
    Tới đây thì coi như là 1 bài tập nhỏ ha, ghép các mảnh flag trên rồi thay thế vào <code>ASCIS{REDACTED}</code> là xong mà...
</details>


---

### A big Blue Whale (current: 500 -> 100 points/75 solves)
#### Description:
```
tags: web system linux misc 
A big blue whale allows our development teams to move fast, deploy software efficiently, and operate at an unprecedented scale.
https://bluewhale.sectigo.one 
```
index.html:
```htmlmixed
<html>
    <header>
        <title>It works on my machine!!</title>
    </header>
    <body>
        <img src="https://sectigo.one/whale.gif">
        <pre>
            A big blue whale enables you to build, ship and run your application anywhere!
        </pre>
<!-- 
  _____
 < boo >
  -----
     \
      \
       \
                     ##        .
               ## ## ##       ==
            ## ## ## ##      ===
        /""""""""""""""""___/ ===
   ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ /  ===- ~~~
        \______ o          __/
         \    \        __/
           \____\______/
-->
    </body>
</html>

```
Một lần nữa, ta lại gặp 1 bài không có gì để khai thác ở front-end cả. Tuy nhiên, nếu ta tinh ý, nhìn thấy con cá heo này ta sẽ nhớ đến gì? Chính xác, Docker! Mà trong Docker, file gì dùng để xây dựng (build) Docker? Chính xác, Dockerfile! Còn nếu bạn lười, dùng dirsearch cũng được :) . Cú pháp tui dùng ở đây là:
``` bash
dirsearch -u https://bluewhale.sectigo.one/
```
Sau khi quét xong thì ta thấy dòng 200 ở `/Dockerfile`, và đây là source của nó:
```dockerfile
FROM sectigo1/webbase:latest
LABEL MAINTAINER Sectigo <system@sectigo.one>
USER root
RUN mkdir -p /etc/nginx/ssl
COPY ssl/server* /etc/nginx/ssl/
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY ./index.html ./Dockerfile /usr/share/nginx/html
EXPOSE 80 443
HEALTHCHECK CMD curl --fail -k https://localhost:443 || exit 1
CMD ["nginx", "-g", "daemon off;"]
USER nginx
```
Nhìn vào đây, ta biết là: server dùng backend là NginX, bảo mật bằng OpenSSL, có sẵn cả filesystem và HĐH gói gọn trong sectigo1/webbase. Nhiệm vụ của Dockerfile này là:

1. Mang sectigo1/webbase về Docker
2. Đặt label, chuyển user thành root, để làm những việc cao cả nhất
3. Tạo 1 thư mục /etc/nginx/ssl nếu chưa tồn tại trong filesystem, thư mục này chứa chứng chỉ và khóa cho SSL
4. Copy toàn bộ những file trong thư mục ssl có tên bắt đầu bằng `server` (thư mục này ở trong local và cùng cấp với Dockerfile) vào thư mục đã tạo
5. Copy file config của NignX vào /etc/nginx/conf.d/default.conf
6. Copy 2 file, index.html và Dockerfile vào /usr/share/nginx/html
7. Đổi port 80 thành 443
8. Kiểm tra docker có kết nối với local port 443 tốt chưa bằng lệnh curl, sau đó tự thoát với mã 1, tức là có lỗi
9. Chạy lệnh `nginx -g daemon off`, tức là chạy server NginX trên foreground
10. Chuyển user về lại cho nginx

<details>
  <summary>Đó là cách hiểu của tui, còn nếu còn nghi ngờ gì thì để ChatGPT trả lời giùm</summary>
  <ol>
      <li><code>FROM sectigo1/webbase:latest</code>: This line specifies the base image for this Docker image. It starts with the "sectigo1/webbase" image, which serves as the foundation for the custom web server image. ":latest" indicates that it's using the latest version of the "sectigo1/webbase" image.</li>
      <li><code>LABEL MAINTAINER Sectigo &ltsystem@sectigo.one&gt</code>: This line sets a label in the image metadata, indicating the image's maintainer or creator. In this case, it's labeled as maintained by Sectigo with an email address.</li>
      <li><code>USER root</code>: This command switches the user to the "root" user within the Docker container. This is done to perform administrative tasks that require superuser privileges during the image build process.</li>
      <li><code>RUN mkdir -p /etc/nginx/ssl</code>: This command creates a directory "/etc/nginx/ssl" inside the container where SSL certificate files may be stored.</li>
      <li><code>COPY ssl/server* /etc/nginx/ssl/</code>: This line copies files matching the pattern "server*" from the host machine's "ssl" directory to the container's "/etc/nginx/ssl/" directory. These are likely SSL certificate and key files used for HTTPS configurations.</li>
      <li><code>COPY nginx.conf /etc/nginx/conf.d/default.conf</code>: This command copies the "nginx.conf" file from the host machine to the container's "/etc/nginx/conf.d/default.conf" directory. This likely contains the Nginx server configuration.</li>
      <li><code>COPY ./index.html ./Dockerfile /usr/share/nginx/html</code>: This line copies the "index.html" file and the "Dockerfile" itself from the host machine to the container's "/usr/share/nginx/html" directory. This is where the web content (HTML files) for the Nginx server will be served from.</li>
      <li><code>EXPOSE 80 443</code>: This command specifies that the Docker container will listen on ports 80 and 443. Port 80 is typically used for HTTP, while port 443 is used for HTTPS.</li>
      <li><code>HEALTHCHECK CMD curl --fail -k https://localhost:443 || exit 1</code>: This sets up a health check for the container. It uses the "curl" command to check if the HTTPS service is accessible at "https://localhost:443". If the check fails, it will exit with a status code of 1, indicating a failure.</li>
      <li><code>CMD ["nginx", "-g", "daemon off;"]</code>: This is the command that will be executed when the container is started. It runs Nginx with the specified arguments, which include "daemon off;" to keep Nginx running in the foreground.</li>
      <li><code>USER nginx</code>: Finally, this command switches the user to "nginx" within the container. This is typically done for security reasons, as it's best practice to run services with the least necessary privileges.</li>
    </ol>
</details>

#### Idea:
Như vậy tui đã đặt ra 1 nghi ngờ, nếu chúng ta không còn tìm kiếm thêm được file nào nữa thì vấn đề là ở webbase: `sectigo1/webbase`, liệu nó có chứa tài liệu mật (flag) hay không? Để trả lời được điều đó thì ta sẽ tự build 1 Docker với Dockerfile có sẵn, file index.html cũng có sẵn, nhưng chỉ có 2 thứ không có sẵn: file nginx.conf và nội dung trong thư mục ssl. Vậy nên ta sẽ tự tạo những thứ này.
Với sự trợ giúp của AI nổi tiếng đã đề cập tên ở phía trên, đây là file nginx.conf:
``` nginx
server {
    listen 80;
    listen 443 ssl;
    server_name localhost;

    ssl_certificate /etc/nginx/ssl/server.crt;
    ssl_certificate_key /etc/nginx/ssl/server.key;

    location / {
        root /usr/share/nginx/html;
        index index.html;
    }
}
```
Thực hiện liên tục các lệnh bash sau để tạo khóa và chứng chỉ của SSL:
``` bash
mkdir ssl
cd ssl/
openssl genpkey -algorithm RSA -out server.key
openssl req -new -key server.key -x509 -days 365 -out server.crt
```
Thư mục để chuẩn bị build Docker trông như sau:
```
/path/to/your/dockerfile/directory/
├── Dockerfile
├── ssl/
│   ├── server.crt
│   └── server.key
└── nginx.conf
└── index.html
```
Sau đó ta bắt đầu chạy các lệnh sau để build:
``` bash
sudo docker build -t bluewhale .
sudo docker run -d -p 8080:80 --name mynginxcontainer bluewhale
sudo docker exec -it --user=root mynginxcontainer /bin/sh
```
Và chào mừng các bạn đã đến với shell của chính Docker bạn vừa tạo! Hãy sử dụng các lệnh như ls, cd, cat để tham quan shell này và tìm flag nha...
Flag: `ASCIS{REDACTED}`
<details>
  <summary>REDACTED?</summary>
    <pre><code>/ # ls
bin                   etc                   mnt                   run                   tmp
dev                   home                  opt                   sbin                  usr
docker-entrypoint.d   lib                   proc                  srv                   var
docker-entrypoint.sh  media                 root                  sys
/ # cd root
~ # ls
flag.txt
~ # cat flag.txt 
ASCIS{1t_R3a114_30rks_0n_m4_m@chin3}</code></pre>
    Thấy chưa, cái này là do bạn không chịu đọc kỹ tag đề bài rồi...
</details>