---
# System prepended metadata

title: PicoCTF

---

Đang trong quá trình thu thập lại các writeup trước đó. 
Bên cạnh picoCTF, còn hoàn thành 1 số session của CryptoHack: [link](https://hackmd.io/LT-Q1JsiRR-mRdY-leR5Aw).


# Web
## Old Sessions
Proper session timeout controls are critical for securing user accounts. If a user logs in on a public or shared computer but doesn’t explicitly log out (instead simply closing the browser tab), and session expiration dates are misconfigured, the session may remain active indefinitely.
This then allows an attacker using the same browser later to access the user’s account without needing credentials, exploiting the fact that sessions never expire and remain authenticated.
Your friend tells you to check out a new social media platform he built a few years ago. Although its still under development, he said the site is almost complete. He also mentioned that he hates constantly logging into sites, and so has made his page that 'once you login, you never have to log-out again'!
Browse here, and find the flag!

![image](https://hackmd.io/_uploads/BJKe84t2bx.png)

Để có session thì đầu tiên ta phải đăng ký tài khoản đã. 
Sau khi đăng nhập sẽ có các comments như sau:

![image](https://hackmd.io/_uploads/BJKHU4Yh-g.png)

ta thử thêm `/sessions` vào cuối đường dẫn

![Screenshot 2026-04-12 221313](https://hackmd.io/_uploads/HJs-vEYn-l.png)

session thứ 2 chính là session của phiên hiện tại, vì vậy ta thay mã session đầu tiên vào và sẽ ra flag.

![Screenshot 2026-04-12 221437](https://hackmd.io/_uploads/HyzzDVY3-l.png)

`picoCTF{s3t_s3ss10n_3xp1rat10n5_2766ccb8}`

## No FA
Seems like some data has been leaked! Can you get the flag?
You can get started here to find the flag!
The application code can be found here.
The leaked data can be found here.
hint 1:What happens when there's no salt? 
hint 2: rockyou rockyou rockyou 
hint 3: What makes 2FA safe?

![image](https://hackmd.io/_uploads/rJxxy19n-e.png)

Ta đã lấy được thông tin tài khoản mật khẩu từ data bị leak, có 1 tài khoản duy nhất có twoFA, đó sẽ là tài khoản mà ta cần đăng nhập để lấy flag.
Nhưng mật khẩu đã bị mã hóa sha256, hint là dùng rockyou.txt chứng tỏ mật khẩu đơn giản, nên ta sẽ thử xem sao

![image](https://hackmd.io/_uploads/BkYY1J9nWe.png)

Khi đăng nhập sẽ cần mã otp

![image](https://hackmd.io/_uploads/rkVPzJc3be.png)



1. Phân tích cơ chế 2FA

Dựa vào source code:

```python
otp = str(random.randint(1000, 9999))
session['otp_secret'] = otp
session['otp_timestamp'] = time.time()
```

Ta thấy:

* OTP là số ngẫu nhiên 4 chữ số
* OTP có hiệu lực trong 120 giây:

```python
(time.time() - timestamp) < 120
```

* OTP được lưu trong `session`


2. Vấn đề bảo mật

Flask mặc định sử dụng **client-side session** (lưu trong cookie của người dùng).

```pthon
app = Flask(__name__)
app.secret_key = os.getenv('SECRET_KEY')
```

Điều này có nghĩa là:

* Dữ liệu `session` (bao gồm `otp_secret`) được lưu trong cookie
* Cookie chỉ được **ký (sign)** bằng `SECRET_KEY`, không được mã hóa hoàn toàn
* Nếu có `SECRET_KEY`, ta có thể decode nội dung session


3. Khai thác

Do OTP được lưu trong session (cookie phía client), ta có thể:

1. Đăng nhập bằng tài khoản có 2FA
2. Lấy cookie `session` từ trình duyệt
3. Decode cookie để lấy giá trị `otp_secret`
4. Sử dụng OTP này để vượt qua bước xác thực 2FA

Bây giở ta lên mạng kiếm tool Flask session decoder là done.

![image](https://hackmd.io/_uploads/Skf0f1chWg.png)

![image](https://hackmd.io/_uploads/SykG7k52bl.png)

Bingo `picoCTF{n0_r4t3_n0_4uth_d4a8be75}`

## Crack the Gate 1

We’re in the middle of an investigation. One of our persons of interest, ctf player, is believed to be hiding sensitive data inside a restricted web portal. We’ve uncovered the email address he uses to log in: ctf-player@picoctf.org. Unfortunately, we don’t know the password, and the usual guessing techniques haven’t worked. But something feels off... it’s almost like the developer left a secret way in. Can you figure it out?

Hints
* Developers sometimes leave notes in the code; but not always in plain text.
* A common trick is to rotate each letter by 13 positions in the alphabet.

Theo như hint thì hãy đọc scr code sẽ thấy có gì đó không dễ đọc như plaintext. Sau đó sẽ dùng shift cipher 13 lần.

![image](https://hackmd.io/_uploads/rJQZEXykGe.png)

![image](https://hackmd.io/_uploads/ByCbNQkJGe.png)

Điều bây giờ cần làm là set Header name: X-Dev-Access Value: yes. Khi gửi request có header này thì có thể bypass auth/login.
![image](https://hackmd.io/_uploads/ByInNQJ1ze.png)

`picoCTF{brut4_f0rc4_125f752d}`

## SSTI1
I made a cool website where you can announce whatever you want! Try it out!

I heard templating is a cool and modular way to build web apps! Check out my website here!

Hints
* Server Side Template Injection

Cách thức hoạt động cơ bản của ngôn ngữ template bao gồm back-end rendering và front-end rendering:

* Render trên back-end bao gồm việc dịch các ngôn ngữ template theo một tiêu chuẩn và chuyển chúng thành HTML, JavaScript hoặc CSS, từ đó trả về cho phía front-end.
* Sau đó, quá trình front-end rendering tiếp nhận, thực thi và gửi toàn bộ mã nguồn trên đến client, cho phép client tạo ra giao diện người dùng.

Server-side template injection (SSTI) là dạng lỗ hổng cho phép kẻ tấn công inject các payload (tạo bởi chính ngôn ngữ template đó) vào các template, và chúng được thực thi tại phía server. Trong đa số trường hợp xảy ra lỗ hổng SSTI đều mang lại các hậu quả to lớn cho server, bởi các payload SSTI được thực thi trực tiếp tại server và thường dẫn tới tấn công thực thi mã nguồn tùy ý từ xa (RCE - Remote Code Execution).

![image](https://hackmd.io/_uploads/BJpqFI1JGg.png)

Lets try.
`{{request.application.__globals__.__builtins__.__import__('os').popen('id').read()}}`
![image](https://hackmd.io/_uploads/Hyk6KLJJGl.png)

Ta sẽ thử đổi `id` sang `ls` để list danh sách file.

![image](https://hackmd.io/_uploads/rJZHcIJkMg.png)

Để có thể đọc được file flag thì dùng `cat`.

![image](https://hackmd.io/_uploads/B1gt9UJyGx.png)

`picoCTF{s4rv3r_s1d3_t3mp14t3_1nj3ct10n5_4r3_c001_dcdca99a}`

## head-dump
Welcome to the challenge! In this challenge, you will explore a web application and find an endpoint that exposes a file containing a hidden flag.

The application is a simple blog website where you can read articles about various topics, including an article about API Documentation. Your goal is to explore the application and find the endpoint that generates files holding the server’s memory, where a secret flag is hidden.

The website is running picoCTF News.


Hints
* Explore backend development with us
* The head was dumped.

Dựa vào Hint cũng như chỉ có mỗi `API Documents` là có thể nhấn vào xem được - chính xác với hint 1 để xem backend có nhứng API nào.

![image](https://hackmd.io/_uploads/BJi52Iykze.png)

![image](https://hackmd.io/_uploads/SkWs2IJkGe.png)

Dựa vào hint thứ 2 thì ta sẽ đổi url `http://verbal-sleep.picoctf.net:57357/api-docs/` thành `http://verbal-sleep.picoctf.net:57357/heapdump` - snapshot toàn bộ vùng nhớ heap tại một thời điểm.

![image](https://hackmd.io/_uploads/rJkrp8JJGl.png)

## Local Authority
Can you get the flag?
Hints
* How is the password checked on this website?

Ta thử Ctrl U xem có hint hay có gì đáng chú ý không.
```html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="style.css">
    <title>Secure Customer Portal</title>
  </head>
  <body>

    <h1>Secure Customer Portal</h1>
    
   <p>Only letters and numbers allowed for username and password.</p>
    
    <form role="form" action="login.php" method="post">
      <input type="text" name="username" placeholder="Username" required 
       autofocus></br>
      <input type="password" name="password" placeholder="Password" required>
      <button type="submit" name="login">Login</button>
    </form>
  </body>
</html>
```
Có vẻ để check điều kiện đăng nhập sẽ thông qua file login.php. Ta sẽ sửa url để đọc thử nếu có thể.
![image](https://hackmd.io/_uploads/HJLX1Pk1Gx.png)

Ta Ctrl U thì đọc được logic login.
```html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="style.css">
    <title>Login Page</title>
  </head>
  <body>
    <script src="secure.js"></script>
    
    <p id='msg'></p>
    
    <form hidden action="admin.php" method="post" id="hiddenAdminForm">
      <input type="text" name="hash" required id="adminFormHash">
    </form>
    
    <script type="text/javascript">
      function filter(string) {
        filterPassed = true;
        for (let i =0; i < string.length; i++){
          cc = string.charCodeAt(i);
          
          if ( (cc >= 48 && cc <= 57) ||
               (cc >= 65 && cc <= 90) ||
               (cc >= 97 && cc <= 122) )
          {
            filterPassed = true;     
          }
          else
          {
            return false;
          }
        }
        
        return true;
      }
    
      window.username = "";
      window.password = "";
      
      usernameFilterPassed = filter(window.username);
      passwordFilterPassed = filter(window.password);
      
      if ( usernameFilterPassed && passwordFilterPassed ) {
      
        loggedIn = checkPassword(window.username, window.password);
        
        if(loggedIn)
        {
          document.getElementById('msg').innerHTML = "Log In Successful";
          document.getElementById('adminFormHash').value = "2196812e91c29df34f5e217cfd639881";
          document.getElementById('hiddenAdminForm').submit();
        }
        else
        {
          document.getElementById('msg').innerHTML = "Log In Failed";
        }
      }
      else {
        document.getElementById('msg').innerHTML = "Illegal character in username or password."
      }
    </script>
    
  </body>
</html>

```
Ta thấy có file `secure.js` nên mở thử:
```javascript
function checkPassword(username, password)
{
  if( username === 'admin' && password === 'strongPassword098765' )
  {
    return true;
  }
  else
  {
    return false;
  }
}
```
Đăng nhập và bùm có flag.
`picoCTF{j5_15_7r4n5p4r3n7_05df90c8}`

## WebDecode
**Description**
Do you know how to use the web inspector?
Additional details will be available after launching your challenge instance.
Đây là bài mở màn, vào web sẽ như sau:
![image](https://hackmd.io/_uploads/ryy0UNonbe.png)
Ta kiểm tra từng tab, sang tab ABOUT thì hiện ra hint. Ta dùng f12 và trỏ vào chữ thì thấy form text ở base64.

![image](https://hackmd.io/_uploads/Byadd4snZx.png)

Ta decode được flag.

![image](https://hackmd.io/_uploads/rJqT_Nj3Wx.png)

`picoCTF{web_succ3ssfully_d3c0ded_df0da727}`

## Unminify
**Description**
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!
Browse here, and find the flag!

Do có hint nên đoán flag sẽ ở cuối code của web, ta ctr + U rồi kiếm flag theo format "picoCTF".

![image](https://hackmd.io/_uploads/BJ2z5No2Wg.png)

`picoCTF{pr3tty_c0d3_d9c45a0b}`

## Bookmarklet
**Description**
Why search for the flag when I can make a bookmarklet to print it for me?
Browse here, and find the flag!

![image](https://hackmd.io/_uploads/Sy9_c4jnZe.png)

Ta thấy đọna javascript, hãy chạy thửu xem sao?

![image](https://hackmd.io/_uploads/Hk0j94ihbl.png)

`picoCTF{p@g3_turn3r_e8b2d43b}`

## logon
**Description**
The factory is hiding things from all of its users.
Can you login as Joe and find what they've been looking at? http://fickle-tempest.picoctf.net:60220

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

Mình vào trang login và thử nhập đại:

- Username: bất kỳ
- Password: bất kỳ

Kết quả: vẫn login được

Thử với `Joe` thì lại **không login được**.

=> Có vẻ hệ thống:
- Không check password cho user thường
- Nhưng lại có logic riêng chặn Joe

![image](https://hackmd.io/_uploads/BkYpTVj3-l.png)

Đúng là như vậy, mục tiêu khi đã đăng nhập được là làm thế nào để có thể đổi từ cookie của người thường sang cookie của Joe. 

Vì:

* Không login được Joe
* Nhưng cookie lại quyết định quyền

=> Thử sửa cookie xem server có kiểm tra không

Thật lạ là ở trong cookie có `admin: Flase`. ta đổi thử sang `True` và bùm có flag.

![image](https://hackmd.io/_uploads/Hy_NCEihbx.png)

`picoCTF{th3_c0nsp1r4cy_l1v3s_4d184b0d}`



## IntroToBurp
Try here to find the flag

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.

Như hint thì ta sẽ sử dụng burpsuite để xem và sửa request.
![image](https://hackmd.io/_uploads/r1HzIwgJMx.png)

Trong quá trình đăng ký tài khoản, thì có 1 chỗ cần phải bypass đó là khi check 2FA code. 
![image](https://hackmd.io/_uploads/BJEdUDgJzl.png)

Cách đơn giản nhất là thử không forward 2FA code, vì như vậy sẽ không có giá trị để so sánh nữa. Ta sẽ xóa thử xem sao.

`picoCTF{#OTP_ByPyss_SuCC3$S_b3fa4f1a}`

## Inspect HTML
Can you get the flag?

Go to this website and see what you can discover.

Hints
What is the web inspector in web browsers?

Theo hint thì bài này Ctrl U xem có gì đặc biệt, thật bất ngờ có luôn flag, bài này có vẻ như là bước đệm cho bài nào đó khó hơn.
![image](https://hackmd.io/_uploads/ryO8edekGg.png)

`picoCTF{1n5p3t0r_0f_h7ml_8113f7e2}`

## Includes

Can you get the flag?

![image](https://hackmd.io/_uploads/Hkl8jg21Gg.png)

Khi ta nhấn "Say Hello" thì hiện ra 1 alert là "This code is in a separate file!" nên đoán flag đã bị phân mảnh ở nhiều file. Vì vậy ta Ctrl U để xem trang này cấu thành bởi file gì.

![image](https://hackmd.io/_uploads/ryjVjenJMg.png)

Gồm 2 file là `style.css` và `script.js` ta mở từng file thì có 2 mảnh flag, vậy là ta gộp lại thôi.

![image](https://hackmd.io/_uploads/SJddogn1Mg.png)

![image](https://hackmd.io/_uploads/rylFilh1fl.png)

`picoCTF{1nclu51v17y_1of2_f7w_2of2_b8f4b022}`

## Cookies

Who doesn't love cookies? Try to figure out the best one.

![image](https://hackmd.io/_uploads/Hk9Q6x2Jze.png)
Khi mới vào chỗ nhập có placeholder là "snickerdoodle" nên ta thửu search luôn thì có vẻ đang đi đúng đường.
![image](https://hackmd.io/_uploads/Skv8agnkGe.png)
Bài này tên là cookies nên ta sẽ thử mở ra xem có gì đặc biệt.
![image](https://hackmd.io/_uploads/BJDdplhJfe.png)
Value = 0 thay vì bằng -1 nếu ta search bằng key khác. Ta thử thay đổi giá trị thì chữ xuất hiện cũng khác.
![image](https://hackmd.io/_uploads/r1viaghyze.png)
Ta thử đến 18 thì ra flag.
![image](https://hackmd.io/_uploads/rJh3Tx3JMe.png)
Ý nghĩa bài này là cookie sẽ lưu thông tin ở trình duyệt của người dùng nên ta có đủ mọi quyền hạn để có thể chỉnh sửa. Vì vậy để bảo mật 1 số cookie sẽ phải được lưu và so sánh với server.
`picoCTF{3v3ry1_l0v3s_c00k135_a4dadb49}`

# Forensics
## Binary Digits
Description
This file doesn't look like much... just a bunch of 1s and 0s. But maybe it's not just random noise. Can you recover anything meaningful from this?
Download the file here.

Đây là file `.bin` nên chỉ cần cho vào cyberchef rồi được đề xuất là From Bin Render Image

![image](https://hackmd.io/_uploads/BkRJBJ92-x.png)

Bingo `picoCTF{h1dd3n_1n_th3_b1n4ry_8d00e35f}`



