# 1. BANDIT OVER THE WIRE:
## Level 0
Em đăng nhập theo hướng dẫn cho sẵn.(em sử dụng Putty)
::: info
### Lý thuyết
SSH là viết tắt của Secure Shell, đây là một giao thức mạng được thiết kế để thiết lập kết nối an toàn giữa máy tính và máy chủ bằng mật khẩu hoặc các xác thực (key authentication)
### Ứng dụng
SSH được ứng dụng
- Bảo vệ dữ liệu truyền tải khỏi các truy cập trái phép và tấn công mạng.
- Quản lý máy tính từ xa bất kỳ đâu, bất kỳ lúc nào (bao gồm cài đặt, cấu hình, và giám sát.)
:::


## Level 0 → Level 1
Em sử dụng```ls [options] [file|dir] (dùng để liệt kê các tập tin và thư mục trong một thư mục cụ thể)``` để xem danh sách file có sẵn, và vì có mỗi file readme, nên em sử dụng ``` cat [options] file (Dùng để xử lý tệp tin )``` để lấy mật khẩu theo yêu cầu và ta ra được mật khẩu.

Mật khẩu : NH2SXQwcBdpmTEzi3bvBHMM9H66vVXjL
## Level 1 → level 2
Ở level này, em sử dụng ls và nhận thấy file được đặt tên theo ký tự đặt biệt, trong các trường hợp này, em tìm hiểu được hai cách để mở các file như vậy và ta có được mật khẩu.

:::warning
* Trong đó, khi ta dùng``` cat > - ``` shell sẽ mở tệp và kết nối nội dung của nó với **stdin (đầu vào tiêu chuẩn/standard input)** *"stdin" Input sử dụng để nhận dữ liệu từ bên ngoài. Thường là dữ liệu được nhập từ bàn phím* của lệnh ``` cat ```
* ``` cat ./-``` sẽ mở file ngay tại thư mục thực thi câu lệnh. Ở đây ta không dùng ``` cat - ``` vì ``` - ``` sẽ được hiểu là thực thi ```[Option]```
:::
Mật khẩu : rRGizSaX8Mk1RTb1CNQoXTcYZWU6lgzi
## Level 2 → Level 3
Trong Level lần này, ta thấy mật khẩu lưu trong file có tên chứa dấu cách, vì vậy em bỏ file trong dấu ngoặc kép rồi đọc mật khẩu chứa trong file bằng cat.!(Trước đó em có tìm hiểu cách sử dụng dấu gạch chéo để đọc file có chứa dấu cách, cú pháp là ta dùng dấu ```\``` không phải dấu ``` /```)


Mật khẩu: aBZ0W5EmUfAf7kHTQeOwd8bauFJ2lAiG
## Level 3 → Level 4
Dựa vào đề bài, em dùng ls -a để xem toàn bộ file+folder đang có hiện tại, dùng ```cd inhere``` để vào trong directory. Sau đó ta dùng cat để đọc mật khẩu 
Mật khẩu : 2EW7BBsr6aMMoJ2HjW067dm8EgX26xNe
## Level 4 → Level 5
Ở level này, em dùng ```ls``` để xem bên trong có gì, sau đó em dùng ```cd (dùng để thay đổi đường dẫn thư mục làm việc hiện tại )``` để vào "inhere", nhận thấy bên trong có 9 thư mục khác nhau. Yêu cầu đề bài là thư mục mà chứa mật khẩu là thư mục human-readable, tức là ta có thể đọc được,nhưng mở từng file lên đọc rất lâu nên nên em đến gợi ý thứ hai là , tức là trong 9 file sẽ có 1 file khác với 8 file còn lại, nên em dùng ``` file ./* (dùng để xác định loại tệp của một tệp tin)``` để tìm kiểu file của 9 file là gì và tìm thấy file cần tìm.

Mật khẩu : lrIWWI6bB37kxfiCQZqUdOIYfr6eEeqR
## Level 5 → Level 6
Ở level này, sau khi vào inhere, theo yêu cầu ta sẽ tìm file có cả 3 yếu tố theo đề, ta thường dùng lệnh ```find [path] [options] [expression] (dùng để tìm kiếm các tệp tin và thư mục dựa trên một hoặc nhiều đặc điểm nhất định)``` tuy nhiên trong đề nó có phần human-readable, cái mà em chỉ biết khi đọc từng file, nên em sẽ tìm các file có ```1033 byte``` trước để dễ loại trừ *(1 phần em cũng chưa biết tìm file "not executable")* Và vì chỉ có 1 file thỏa mãn 1 trong 3 điều kiện trên nên chắc chắn file này là file ta cần tìm

Vậy, pass là : P4L4vucdmLnm8I7Vl7jG1ApGSfjYKqJU
## Level 6 → Level 7:
Ở level này em sử dụng lệnh find để tìm theo yêu cầu và ta có một list các địa chỉ thư mục nhưng đa phần đều bị từ chối truy cập

trừ /var/lib/dpkg/info/bandit7.password. Dựa vào đây ta sử dụng cat và có được pass

:::info
Em thấy ở lần này ta phải dùng ```\``` trước ```-type f``` vì ở nó sẽ tìm ở thư mục hiện tại => không có bất kì file nào thỏa yêu cầu, nên dùng ```find``` sẽ không ra kết quả, còn dùng ```\``` thì ```find``` sẽ tìm toàn bộ hệ thống tệp tin.
:::
pass : z7WtoNQU2XfjmMtWA8u5rN4vzqu4v99S
## Level 7 → Level 8
Ở level này thì file cần tìm có ngay ban đầu, và theo đề bài mật khẩu cạnh chữ ```millionth``` nên em sử dụng ```grep [options] pattern [files] (được sử dụng để tìm kiếm các dòng văn bản trong tệp tin)``` để tìm trong data.txt và ta có mật khẩu:

Pass : TESKZC0XvTetK0S9xNwm25STk5iWrBvP
## Level 8 → Level 9
Theo gợi ý thì mật khẩu tiếp theo là dòng chỉ xuất hiện 1 lần. Em tìm hiểu và biết được ta có thể dùng lệnh ```uniq [OPTIONS] [INPUT_FILE [OUTPUT_FILE]] (dùng để loại bỏ các dòng trùng lặp từ đầu )``` Nhưng kết quả hiện ra là một list các chuỗi *(giải thích ở đoạn này là dựa vào gợi ý em suy ra sẽ có nhiều dòng trùng và vì lệnh thực thi là sẽ lấy duy nhất dòng riêng biệt, tức là có sẽ nhiều dòng trùng khác nhau bên trong).*

Nên cách này không hiệu quả, nên em dùng ```sort (sắp xếp các dòng trong một tệp tin theo thứ tự tăng dần hoặc giảm dần.)``` để sắp xếp lại thì chắc chắn sẽ tìm ra dòng mật khẩu không có trùng lặp :

pass : EN632PlfYiZbn3PhVK3XOGSlNInNE00t
## Level 9 → Level 10
Ở level này, khi mở tệp thì file có nhiều kí tự đặt biệt không thể đọc. Em sử dụng lệnh ```strings [options] <filename> (sử dụng để trích xuất các chuỗi văn bản từ tệp tin nhị phân)``` để mở, đồng thời tìm các dòng chứa dấu ```=``` và ta tìm ra được mật khẩu như sau :

Vậy pass là : G7w8LIi6J3kTb8A7j9LgrywtEUlyyp6s
## Level 10 → Level 11
Ở level này, dựa vào gợi ý, ta cần mã hóa trong tệp data.txt bằng lệnh ```base64 -d (giải mã chuỗi Base64 thành dữ liệu nhị phân)``` để decode :

Và ta có mật khẩu là :6zPeziLdR2RKNdNYFNb6nVCKzphlXHBM
## Level 11 → Level 12
Ở đây khi ta mở file lên thì thấy hiện một dãy các ký tự theo mật mã ROT13, vì vậy em lên mạng và có chuyển đổi trên web:


:::info
Về sau em tìm hiểu lại và có cách để decode tại chỗ bằng lệnh
```tr 'A-Za-z' 'N-ZA-Mn-za-m'``` .Cụ thể hơn, ```tr [options] set1 set2``` dùng để thay thế các ký tự theo trình tự *(theo trình tự tiến tới, như từ a-z, không có ngược lại)* ở ```set1``` trong```[Options]```theo các ký tự theo trình tự ở ```set2```.
:::

Vậy pass là : JVNBBFSmZwKKOP0XbFXOoW8chDz5yVRv
## Level 12 → Level 13
Ở bài này, trước hết dựa vào gợi ý em sẽ tạo một thư mục mới dưới ```/tmp``` bằng ```mkdir [options] dir_name (dùng để tạo mới một hoặc nhiều thư mục mới )```
Sau đó em copy file ```data.txt``` vào đường dẫn em vừa tạo để được quyền tác động lên nó bằng lệnh ```cp source_file destination ()```

Khi đọc file ```data.txt``` thì đây là một file hexdump (là dạng xem thập lục phân văn bản của dữ liệu), không thể đọc nên em sẽ đưa nó về một ngôn ngữ dễ đọc hơn là hệ nhị phân bằng lệnh(theo lý thuyết) ```xxd -r[evert] [options] [infile [outfile]] (được sử dụng để chuyển đổi tệp nhị phân thành mã hex và ngược lại)```, lưu dưới dạng [gzip compressed data](https://linuxize.com/post/gzip-command-in-linux/#:~:text=Gzip%20is%20one%20of%20the,it%20to%20the%20client%20browser.) và ta sẽ đổi tên ```mv [OPTIONS] SOURCE DESTINATION``` nó có đuôi ```.gz``` để giải nén file bằng lệnh ```gzip [OPTION]... [FILE]...```

Check file mới được giải nén và ta nhận ra file đó đang định dạng là [bzip2](https://docs.fileformat.com/vi/compression/bz2/), nên ta tiếp tục đưa nó có tên chứa đuôi ```.bz2``` để giải nén bằng lệnh ```bzip2 [OPTIONS] filenames ...``` và ta lại ra một file ```gzip```, thực hiện lại bước trên và ta được một file đuôi mới là [```POSIX tar archive (GNU)```](https://www.hostinger.vn/huong-dan/tar-command)

lúc này em sẽ giải nén file mới tương tự như các bước trên bằng lệnh ```tar [options] [archive-file] [file or directory]```, ta được ```data5.bin``` cũng là một ```.tar``` file nên em giải nén tiếp, kết quả là ta được file ```data6.bin``` định dạng ```bzip2```.

Lặp lại cho đến khi ta file đích không còn định dạng là file nén, và ta có được mật khẩu

::: info
ở đây, các file đuôi .bz2, .gz, .tar là các file nén
:::
Pass :wbWdlBxEir4CaE8LaPhauuOo6pwRmrDw
## Level 13 → Level 14
Ở level, dựa vào yêu cầu đề em rút ra rằng lần này ta cần [private SSH key](https://nhanhoa.com/tin-tuc/ssh-key-la-gi.html) để đăng nhập vào bandit14,
Em mở thử và nhận thấy có sẵn ```private SSH key```, nên em sử dụng ```ssh [options] [user@]hostname [command] (Dùng để hiết lập kết nối với các máy chủ từ xa)``` để đăng nhập :

Sau đó t chọn Yes để đăng nhập và thành công vào level 14. Sau đó ta mở xem mật khẩu theo gợi ý từ đề bài.!


pass: fGrHPx402xGC7U7rXKDaxiWFTOiF0ENq
## Level 14 → Level 15
Bài này em sử dụng lệnh netcat để đưa password theo yêu cầu ```nc [<options>] <host> <port>` ( được sử dụng để thiết lập các kết nối mạng và thực hiện các hoạt động mạng) ```

::: info
### Tìm hiểu ngoài lề
* **Netcat** : kết nối mạng thông qua giao thức TCP hoặc UDP,là một công cụ linh hoạt, có khả năng mở các kết nối TCP, gửi các gói UDP, nghe trên các cổng TCP và UDP tùy ý, v.v.
* **[TCP](https://bizflycloud.vn/tin-tuc/tcp-la-gi-20181022170658844.htm)** : (Transmission Control Protocol) là một giao thức truyền tải có kết nối, đảm bảo việc truyền tải dữ liệu một cách đáng tin cậy giữa các thiết bị trong mạng.
* **[UDP](https://blog.vinahost.vn/giao-thuc-udp-la-gi/)** : (User Datagram Protocol) là một giao thức truyền tải không có kết nối, không đảm bảo việc truyền tải dữ liệu một cách đáng tin cậy như TCP.
:::
PAss: jN2kgmIXJ6fShzhT2avhotn4Zcka6tnt
## Level 15 → Level 16
Ơ level này, em nhận thấy có gợi ý sử dụng SSL encryption *((mã hóa SSL) là phần của SSL giao thức, đề cập đến việc sử dụng các thuật toán mã hóa để bảo vệ dữ liệu truyền qua kết nối SSL.)*. Ở bài này em tìm em sử dụng lệnh ```ncat (giống nc nhưng có nhiều tính năng hơn) [options] [hostname] [port]``` để thực hiện yêu cầu.

:::info
*ncat có thể sử dụng OpenSSL hoặc một thư viện mã hóa khác để cung cấp tính năng SSL/TLS. Điều này giúp cho ncat có khả năng kết nối với các máy chủ yêu cầu kết nối bảo mật thông qua SSL/TLS mà không cần sử dụng các công cụ hay thư viện bổ sung.*
:::
pass : JQttfApK4SeyHwDlI9SXGR50qclOAil1
## Level 16 → Level 17
Ở level này, trước tiên ta cần tìm cổng có khả năng "listen" *(đang ở trạng thái sẵn sàng chấp nhận các kết nối đến từ các máy khác trên mạng mà gửi dữ liệu đến cổng đó)* bằng ```nmap [Scan Type(s)] [Options] {target specification} (dùng để khám phá và kiểm tra các máy tính và thiết bị mạng trong một mạng) ```

Dựa theo đề bài thì ta có thể suy ra ngay cổng cần tìm đó là 1 tronh 2 cổng 31790 và 31518. Sau đó em gửi và nhận về mật khẩu cho level sau :

Kết quả nhận về là một private RSA key,, em sử dụng ```nano [options] filename``` để lưu nó thành một file riêng, lưu trong ```/tmp```. Em dùng ```chmod [options] mode file (dùng để thay đổi quyền truy cập của tệp và thư mục)``` để cung cấp quyền đọc file. Sau đó dùng nó như một SSH key để đăng nhập vào bandit 17 và lấy pass từ đó.


pass: VwOSWtCA7lRKkTfbr2IDh6awj9RNZM5e
:::info
Từ đây ta nhận thấy file chứa mật khẩu đều nằm trong đường dẫn thư mục là ```/etc/bandit_pass```, nhưng muốn mở thì cần phải có quyền truy cập.
:::
## Level 17 → Level 18
Ở level này dựa vào hướng dẫn ,dùng lệnh``` diff [options] file1 file2```, em sẽ tìm ra được phần khác nhau giữa 2 file, và em sẽ lấy phần ở password new. Mật khẩu đăng nhập tiếp theo là:

pass : hga5tuuCLF6fFzUpnagiMN8ssu9LFrdg
Tuy nhiên khi sử dụng mật khẩu này để đăng nhập thì sẽ tự động thoát ra ngoài, nên em sẽ thử kết nối bằng trong terminal ubuntu
## Level 18 → Level 19
Dựa vào đề ta được biết file ```.bashrc``` bị sửa nên khi ta không thể vào được. Ở level, em dựa vào gợi ý sử dụng ```ssh``` nên em tìm xem có này ta sẽ mở kết nối vào bên trong lệnh ssh mà không cần đăng nhập. Em kiếm được một <option> là ```ssh -t``` cho phép em thực hiện lệnh từ xa mà không cần đăng nhập trực tiếp.

Pass : awhqfNnAbc1naukrpqDYcF95h7HoMTrC
<option>
## Level 19 → Level 20
Ở bài này sau khi em mở ra file bên trong phát hiện thấy có một tên bị bôi đỏ

em thử dùng ```cat``` và ```cd``` để xem đây là loại file gì kết quả không có gì ngoài một số ký tự lạ. sau khi tìm hiểu thì đây là ```quyền setuid```, *(tức là người thực thi là người sở hữu thay vì người sử dụng lệnh)*, vì vậy để chạy được thì ta sử dụng ```./``` để nó tự chạy dưới quyền hạn của chính nó - chủ sở hữu. Và theo đề thì file chứa mật khẩu nằm ở trong ```/etc/bandit_pass```

pass: "VxCazJaVykI6W36BkBU0mJTCM8rR95XT"
## Level 20 → Level 21
Dựa vào đề bài thì file ```setuid``` lần này sẽ kết nối 1 cổng cụ thể nào đó, đọc dòng văn bản, so sánh với mật khẩu level trước. Nếu đúng thì sẽ đưa cho ta mật khẩu ở level tiếp theo.
Em thử chạy file ```suconnect``` và nhận được dòng sau : 
Vậy cách để kết nối ```suconnect``` với một cổng bất kì đã có, giờ em cần tạo cổng *(vì không có gợi ý về một cổng cụ thể)*, và gửi mật khẩu qua bên cổng đó trước khi kết nối.

:::warning
Cần đặt ```&``` để lệnh chạy nền, tức là không cần đợi lệnh hoàn thành, ta vẫn thực hiện lệnh khác được. Vì cổng mà ta ngẫu nhiên tạo ra có nhiều thiết lập chưa được cài đặt, dẫn đến thời gian phản hồi lâu hơn.
:::
Pass: NvEJF7oVjkddltPSrdKEFOllh9V1IBcq
## Level 21 → Level 22
Ở level này, dựa vào gợi ý, em vào theo địa chỉ đường dẫn

Em thấy có một tệp đọc liên quan đến level tiếp theo nên em mở ra.

Có một đường dẫn đến một tệp nên em tiếp tục mở và thấy một file đọc mới, tiếp tục đọc và ta có được mật khẩu


:::info
### Tìm hiểu thêm
[Crontab](https://viblo.asia/p/tim-hieu-crontab-tren-linux-WApGx3DbM06y) (CRON TABLE) là một tiện ích cho phép thực hiện các tác vụ một cách tự động theo định kỳ, ở chế độ nền của hệ thống. Crontab là một file chứa đựng bảng biểu (schedule) của các entries được chạy.
:::
pass: WdDozAdTM2z9DiFEQ2mGlwngMfj4EZff
## Level 22 → Level 23
Như ở level trên, sau khi đọc file ```cronjob_bandit23.sh``` thì nó hiện ra như sau :

Trong đó ta để ý ở ```mytarget = $(echo I am user $myname | md5sum | cut -d ' ' -f 1) ```, Lệnh bên trong sẽ tạo một mã hash MD5 từ chuỗi sau *(chuỗi dữ liệu đầu vào và chuyển đổi nó thành một giá trị hash có độ dài cố định)* ```echo```, nên em thử chạy câu lệnh bên trong ngoặc được một chuỗi ký tự giống địa chỉ ở câu trước. Em thử đọc nhưng không có kết quả gì, tiếp tục đổi từ ```myname``` thành ```bandit23``` vì đây là tên user tiếp theo, mở thử file và ra được mật khẩu
.
:::success
lệnh gán ```variable_name=value```, ta dùng ```""``` để gán info/biến và ```$()``` để gán output của lệnh,
```whoami``` sẽ cho ta biết user hiện tại.
:::
PAss: QYw0Y2aiA672PsMmh9puTQuhoz8SyR2G
## Level 23 → Level 24
Tiếp tục vào như hai level trên, khi em mở được ```cronjob_bandit24``` thì bên trong nó cho ta một scrip.
Đây là gợi ý để lấy pass tiếp theo.
Ở đây đoạn scrip sẽ tự động chạy rồi xóa toàn bộ scripts trong ``/var/spool/$myname/foo`` *(nếu không phải do user hiện tại tạo)*, trong thời gian 60s

Em thử vào nhưng kết quả không có gì, em thử bằng user bandit24 và ta vào được nhưng bị từ chối quyền sử dụng lệnh, vậy lần này em cần phải tạo file shell-scrpit để nó chạy và lưu trong file khác mà ta có quyền.
Trước tiên em sẽ tạo một thư mục cho phép em tự do truy cập là `/tmp/sh`
Sử dụng `vim [filename]` để viết scrpit ```shell_script.sh``` tự động tạo truyền nội dung password có sẵn trong ```/etc/bandit_pass/bandit24``` vào file trống ``matkhau24`` bằng lệnh ``touch *(hữu ích để tạo tệp trống và cập nhật dấu thời gian của các tệp hiện)* ``

Sau đó ta cấp quyền thực thi file để nó được đọc bởi bandit24, rồi đưa file vào thư mục ``/var/spool/bandit 24/foo`` để file .sh được thực thi và ta có mật khẩu cho level tiếp theo.

Pass : VAfGXJ1PBSsPSnvsjI8p759leLZ9GGar
## Level 24 → Level 25
Dựa vào gợi ý thì muốn đăng nhập vào level tiếp theo thì ta phải gửi pass level trước và một mã PIN 4 chữ số, vậy mục tiêu là tìm ra số có 4 chữ số thỏa yêu cầu:

không có gợi ý nào hơn nên ta phải thử toàn bộ 4 chữ số, từ `0000 tới 9999`, bằng lệnh ```for [variable] in [list]
do
[commands]
done```
và kiểm tra bằng cách gửi nó chung với mật khẩu, từ đó ta có cú pháp :

Vì nó không chạy được toàn bộ nên em chia thành từ x000 tới x999 để chạy và ta được pass:

pass: p7TaowMYrmu23Ol8hiZh9UvD0O9hpx8d
## Level 25 → Level 26
Ở level này thì ta thử sử dụng kết nối bằng SSH key, nhưng điều này không thể, vì ta sẽ bị đóng kết nối khi vừa vào,

Ở đây ta dựa vào gợi ý là bandit26 không sài /bin/bash, vậy nên ta thử tìm xem bandit26 sẽ sử dụng cái nào bằng cách xem file `/ect/passwd *(file cấu hình chứa thông tin chi tiết về người dùng)*`

Vậy bandit26 đang dùng riêng đuôi thư mục là ```/usr/bin/showtext```, khác với các tư mục trên chỉ có ```/bin/bash```, nên ta mở thử bên trong có gì,

Tìm hiểu thì ta biết được rằng
:::info
* ```more [-options] [-num] [+/pattern] [+linenum] [file_name] ``` sẽ xuất toàn bộ text lên màn hình,
* ~/filename : Lệnh được truy cập vào thư mục hiện tại.
* exit 0 : sẽ tự động out khi lệnh chạy thành công
:::
Từ đó ta suy ra ta cần chặn file ```text.txt ``` xuất hoàn toàn lên màn hình, tức là thu nhỏ cửa số lại khi chạy lệnh để nó chỉ xuất 1 phần, không đóng kết nối ngay lập tức. Sau đó em tìm cách để vào được bên trong, tức là đăng nhập vào bandit26. Hiện tại ta đang vào là một file text, vì vậy ta có thể lợi dụng vim để sửa. Sau đó ta dụng lệnh :```set shell=``` để thay đổi giá trị shell thành ```/bin/bash``` và ```:shell``` để khởi động shell đó từ trong vim ra ngoài, và ta thành công đăng nhập vào user bandit26

và vào đường dẫn thư mục chứa mật khẩu level này

Pass : c7GvcKlw9mC7aUQaPx7nwFstuAIBw1o1
## Level 26 → Level 27
Ở level này ta lại có thêm một file SUID, mở ra xem thì có thêm hai file ta đọc được bằng cat.



Khi mở suid thì bên trong có cấu trúc thư mục giống như các user khác ngay khi ta vừa đăng nhập vào. THêm 1 phần trong file `bandit27.do` 
ám chỉ ta chạy lệnh ở thư mục kia tương tự như user, nên ta sẽ mở thư mục chứa pass để coi thử và ta có được password:
Pass : YnQpBuifNMas1hcUFk70ZmqkhUU2EuaS

## Level 27 → Level 28
Dựa vào gợi ý thì em tìm thử lệnh clone khi dùng git là gì
:::info
### Sơ lược về Git
Là một hệ thống quản lý phiên bản (Version Control System - VCS). Git được sử dụng để quản lý các phiên bản của mã nguồn.
:::

Sau đó em dùng lệnh để chạy thử xem nó làm gì, thì em thấy nó đang cố tạo cái gì đó, nhưng bị từ chối ở thư mục hiện tại, nên em sẽ vào thư mục được có quyền tự do tạo: 
Nó đang kết nối với cổng 22, mà đề yêu cầu là 2220, nên ta sẽ gắn cổng vào, và ta tạo thành công, mở ra xem và đó là 1 tệp, tiếp tục mở tệp đó và ta có được mật khẩu tiếp theo:

Pass: AVanL161y9rsbcJIsFHuw35rjaOM19nR
## Level 28 → Level 29
Đề này giống đề trước nên em thực hiện các bước tương tự, và bên trong có một file `README.md`, kiểm tra file là text nên mở ra đọc và ta thấy mật khẩu file bị thay bằng chữ x.

Gợi ý chỉ bảo sử dụng `git` nên em tìm hiểu thêm. Sử dụng `git log` để xem hiển thị lịch sử thay đổi, thêm `-p` để xem cụ thể trong từng commit, và ta ra được mật khẩu.

pass : tQKvmcwNYcFS6vmPHIUSI3ShmsrQZK8S
## Level 29 → Level 30
Tiếp tục vào đọc thư mục `README.md`, lần này password không tìm thấy.

Vì bài này có vẻ cùng tên file với bài trước nên chắc chắn mật khẩu cũng sẽ được lưu đâu đó trong quá trình sửa đổi.🫤
Tìm trong lịch sử sửa đổi cũng không có, nên em bắt đầu tìm kiếm và biết được trong lịch sử thay đổi có một thuật ngữ là `branch` *(là một con trỏ linh hoạt trỏ đến một điểm trong lịch sử thay đổi của mã nguồn)*, nên em sẽ thử vào.Phát hiện ra 4 cái tên, nên em dùng `checkout` chạy chuyển đổi cách nhánh, nhánh nào chứa dữ liệu cũ, thò ta có hai nhánh `dev` và `sploits-dev`. 🤯
Khi ta chạy branch `dev` thì nó xuất hiện một thư mục mới, vào và thực thi file bên trong, lúc này `README.md` được khôi phục về lúc còn mật khẩu.Tương tự ở cách trên nhưng nếu ta áp dụng cho `sploits-dev` thì `README.md` quay về lại ban đầu:

Pass: xbhV3HpNGlTIdnjUrdAlPzc2L6y9EOnS
## Level 30 → Level 31
Tiếp tục vào đọc thư mục `README.md`, lần này không có password. Mở log -p lên thì không có sự sửa đổi nào nên branch cũng sẽ không tồn tại. Kiểm tra Git có được đánh dấu không bằng `tag`, ta thấy có một tag, đọc tag bằng `show`, ta có được mật khẩu.

Pass : OoffzGDlzhAlerFJ2cAiz1D41JW1Mhmt
## Level 31 → Level 32
Sau khi mở thành công, đề lần này là đưa một file đến một kho lưu trữ từ xa.

Trước hết em tạo file theo yêu cầu. Sau đó ta cần đảm bảo file không bị đưa vào `gitignore`,và tạo commit để được phép`push` . Sau đó ta bắt đầu thực hiện yêu cầu, và ta có được mật khẩu

Pass : rmCBvG56y58BXzv98yZGdO7ATVL5dW8y
## Level 32 → Level 33
Khi đăng nhập thành công, ta được giới thiệu đây là `UPPERCASE SHELL` là shell chạy lệnh được hiển thị in hoa. Các lệnh đều không chạy được. Chạy`$0` *( một biến đặc biệt chứa tên của chương trình hoặc script mà ta đang thực thi từ dòng lệnh để tự chạy script)* và đã thành công.
odHo63fHiFqcWWJG9rLiLDtPm45KzUKy
## Level 33 → Level 34
"At this moment, level 34 does not exist yet."

:::info
# CLEAR
:::
# 2.LABS: PicoCTF:
## 1.GET aHEAD
Đề

Dựa vào gợi ý đầu thì em không có thông tin cần thiết để giải bài, gợi ý thứ hai cho bảo ta xem phần responses sau khi điều chỉnh lại phần request. Nên em sẽ đổi phương thức(methods) của request. Trong tên tiêu đề chữ a viết thường lại, điều đó cho ta thấy thêm một gợi ý nữa, đó là methods ta cần thay thế là "GET" thành "HEAD"
( Sử dụng lệnh ```curl [option] <url>``` để gửi request. MẶc định khi sài với mỗi lệnh ```curl``` dùng methods `GET`.=> kết quả đưa ra là đoạn code giống với ban đầu.=> web dùng methods `GET` )
Bằng cách thay `--head` vào thì web được thực thi bằng method `HEAD`, và cho ra flag:

```typescript=
$ curl --head http://mercury.picoctf.net:28916/
HTTP/1.1 200 OK
flag: picoCTF{r3j3ct_th3_du4l1ty_70bc61c4}
Content-type: text/html; charset=UTF-8
```
Trong Python, để đổi request method thì cần phải có thư viện `requests`, sau đó bắt đầu khởi động lệnh
```typescript=
import requests //nhập thư viện
url = 'http://mercury.picoctf.net:28916/'
response = requests.head(url) //Lưu thông tin phản hồi từ sau khi request dùng methods là head
print(response.status_code) // in ra HTTP STATUS CODE, có thể có lỗi hoặc không khi thực hiện truyền đi
print(response.headers) //in ra responds sau khi truyền đi thành công.
```

#### FLAG : picoCTF{r3j3ct_th3_du4l1ty_70bc61c4}
## 2.Cookies

Ở phần này khi mở trang web lên thì bên trong ô điền có sẵn một từ, nhập vào và ta được chuyển hướng đến `/check`,

Thử các từ khóa khác về tên các loại "cookies" thì đều bị từ chối, từ đó ta suy ra có một cookies lưu thông tin đăng nhập đang được lưu trữ, Em mở thử vào trong `burp` xem trang web, nhận thấy bên trong có một cookies có key name là `0.`

Thử thay đổi giá trị name của cookie cần tìm bằng một khác để tìm hiểu cookie ta đang tìm có "name=" là số hay text.

Vậy ta cần chạy thử các số từ 1 trở đi để xem cookies nào chứa flag ta cần tìm.
Em thử chạy ở các giả lập online nhưng không chạy được ở lần thứ 5 nên em sẽ lưu nó ở 1 file riêng trên máy tính.
File có tên là ```new.py```
```typescript=
import requests
url = "http://mercury.picoctf.net:64944/check"
for i in range(1, 21): // tạo vòng lặp, cho giá trị i chạy.
//ta chạy headers của request, xem responds mà ta nhận về có chứa Flag mà ta cần tìm hay không
headers = {
"Host": "mercury.picoctf.net:64944",
"Cache-Control": "max-age=0",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.6367.118 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"Referer": "http://mercury.picoctf.net:64944/",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "en-US,en;q=0.9",
"Cookie": f"name={i}",
"Connection": "close"
}
response = requests.get(url, headers=headers)
if "pico" in response.text: // Để tìm kiếm gọn hơn thì kiểm tra xem chữ "pico" có được chứa trong phản hồi không, vì các flag đề có từ khóa pico để ta phân biệt
print(f"cookie cần tìm có giá trị là: {i}:")//tham số mà cookies đó chữa flag
print(response.text)
```

#### Flag: picoCTF{3v3ry1_l0v3s_c00k135_cc9110ba}
# 3.Root Me
## HTTP - IP restriction bypass challenge

Dựa vào để thì ta biết muốn lấy được flag thì phải đăng nhập vào website bằng cách sử dụng địa chỉ IP cá nhân/IP nội bộ thay vì dùng IP hiện tại (bypass IP) bypass ở đây là ta tạo một IP nằm trong danh sách truy cập của HTTP.

Có một ressource liên dãy số địa chỉ IP cá nhân, nên ta sẽ dùng nó.

```da.py```
```typescript=
import requests
url = "http://challenge01.root-me.org/web-serveur/ch68/"
headers = {"X-Forwarded-For": "172.16.0.0"}
r = requests.get(url, headers=headers)
print(r.text)
```
Lệnh ```"X-Forwarded-For"``` ban đầu được sử dụng để xác định IP gốc của client kết nối với máy chủ thông qua proxy HTTP. Vì vậy để ta sẽ đặt mặt định IP của chúng ta thành ```172.16.0.0```*(nằm trong IP nội bộ)* , như vậy request sẽ được gửi đi với IP mặt định như trên. Lúc này ta đã đăng nhập thành công vào bên trong và nhận được flag:

#### Flag: Ip_$po0Fing
## HTTP - POST challenge
Khi em mở web thì yêu cầu là ta phải tạo ra 1 số lớn hơn số mà web cho. Bấm thử thì em thấy nút cho ra là một số ngẫu nhiên bé hơn. Vậy mục đích ở đây là ta sẽ thay đổi số tạo ra không mang giá trị ngẫu nhiên nữa.

Cho vào ```burp suit``` thì ta có một dòng trong request hiện số ngẫu nhiên, lúc này ta chỉ cần đổi số thành số lớn hơn số ban đầu, ta đã có flag cần tìm.

Hoặc dựa vào đó ta biết vị trí giá trị ta cần thay đổi, ta chỉ cần gán giá trị đó bằng giá trị khác lớn hơn yêu cầu đề bài. Ở đây phần tạo số được hiển thị sử dụng methods là ```post```
```ssss.py```
```typescript=
import requests
url = "http://challenge01.root-me.org/web-serveur/ch56/"
data = {"score": "100000000", "generate": "Give a try!"} //phần thông tin thêm vào để gửi đi cùng.
r = requests.post(url, data=data)
print(r.text)
```
ở đây không dùng headers như mọi lần vì vị trí ta cần sửa nằm `trong body request`, nên ta dùng `data`.

#### FLAG: H7tp_h4s_N0_s3Cr37S_F0r_y0U
## HTTP - Headers challenge
Đề bài ở đây là ta phải có kiếm quyền đăng nhập vào web. Đưa lênh ```burp suit``` và chạy thử, ta được một đoạn code như sau

Để ý thấy trong đoạn code response trên có 'Header-RootMe-Admin' đang có giá trị là ``none``, ta sẽ đổi nó thành giá trị mang ý nghĩa ngược lại để đăng nhập
`ADMin.py`
```python=
import requests
url = "http://challenge01.root-me.org/web-serveur/ch5/"
headers = {"Header-RootMe-Admin": "yes"}
r = requests.get(url, headers=headers)
print(r.text)
```
Trong bài lần này ta có thể thấy headers cho phép chúng ta

#### FLAG: HeadersMayBeUseful
## HTTP - User-agent challenge
:::info
### User-agent,
chuỗi này chứa thông tin về trình duyệt và hệ điều hành đang được sử dụng.
:::
Khi mở thử trang web thì ta không vào được vì sai user-agent, nó không phải là admin của browser. Vậy nên nhiệm vụ của ta là thay cái giá trị của User-Agent hiện tại thành admin dựa theo gợi ý.

`user.py`
```python=
import requests
url = "http://challenge01.root-me.org/web-serveur/ch2/p"
headers = {"User-Agent": "admin"}
r = requests.get(url, headers=headers)
print(r.text)
```

#### Flag: rr$Li9%L34qd1AAe27