[OverTheWire] Natas – Level 22

http://natas22.natas.labs.overthewire.org/

only admins can reveal the password…

Nhấn View sourcecode:

Do không hiểu cơ chế của cái hàm header() nên mình rơi vào bế tắc, rất cảm ơn Nam Tóc Xù đã hint mình bài này sweet_kiss

Thực chất vấn đề redirect bằng header() như trên do phía trình duyệt xử lý, chứ không phải là server redirect trực tiếp. Hay nói cách khác, toàn bộ nội dung của file trước khi redirect vẫn được tải về chứ không hề bị ngắt sau khi gọi hàm header(). Ta có thể dễ dàng kiểm tra điều này bằng cách xem tab Network trong Web Developer Tools của trình duyệt.

Để nhận nội dung mà không redirect, ta có thể dùng curl ở chế độ mặc định:

You are an admin. The credentials for the next level are:<br><pre>Username: nata
s23
Password: D0vlad33nQF0Hz2EP255TP5wSW9ZsRSE

→ flag = D0vlad33nQF0Hz2EP255TP5wSW9ZsRSE.

[OverTheWire] Natas – Level 21

http://natas21.natas.labs.overthewire.org/

Note: this website is colocated with http://natas21-experimenter.natas.labs.overthewire.org

You are logged in as a regular user. Login as an admin to retrieve credentials for natas22.

Nhấn View sourcecode:

Thua, đố làm được emo_popo_beat_plaster

Chuyển qua trang kia và chú ý ở:

Xong, còn có thể mong chờ một bài dễ hơn được nữa ở level này không hả trời surrender

Rõ ràng ta có thể edit cái form submit để trang thứ 2 này lưu $_SESSION với các giá trị tùy ý, trong khi trang 1 lại dùng chung session với trang 2. Thế là emo_popo_look_down

  1. Submit trang 2 với một thuộc tính có name:value = admin:1
  2. Đổi biến PHPSESSID của trang 1 thành PHPSESSID của trang 2.
  3. Done.
You are an admin. The credentials for the next level are:

Username: natas22
Password: chG9fbe1Tq2eWVMgjYYD1MsfIvN461kJ

→ flag = chG9fbe1Tq2eWVMgjYYD1MsfIvN461kJ.

[OverTheWire] Natas – Level 20

http://natas20.natas.labs.overthewire.org/

You are logged in as a regular user. Login as an admin to retrieve credentials for natas21.

Nhấn View sourcecode:

Chúng ta sẽ đi lần lượt theo quy trình xử lý của bài này. Đầu tiên khi ta submit form login:

Quá trình set giá trị cho biến $_SESSION được thực hiện qua hàm mywrite(), đáng chú ý ở:

Tức là giá trị của biến $_SESSION sẽ được lưu vào file thành 1 dòng. Sau đó là quá trình đọc thông tin login của user:

Thao tác lấy giá trị được đảm nhiệm bởi hàm myread():

Có một điểm đặc biệt là, nếu xét đúng bản chất, biến $_SESSION chỉ có thể chứa một thuộc tính có tên là name, tuy nhiên ở hàm myread(), code vẫn đọc từng dòng từ file để gán giá trị, và nó dẫn đến một cánh cửa vô cùng sáng cho ta lao vào, đó là inject ký tự xuống dòng vào username để tạo ra một thuộc tính 2 trong 1 khi đưa vô file still_dreaming

Kết quả:

You are an admin. The credentials for the next level are:<br><pre>Username: nata
s21
Password: IFekPyrQXftziDEsUr3x21sYuahypdgJ

→ flag = IFekPyrQXftziDEsUr3x21sYuahypdgJ.

[OverTheWire] Natas – Level 19

http://natas19.natas.labs.overthewire.org/

This page uses mostly the same code as the previous level, but session IDs are no longer sequential…

Please login with your admin account to retrieve credentials for natas20.

Không có View sourcecode, tuy nhiên dựa vào lời tựa, ta có thể hiểu là nó cũng tương tự bài 18, chỉ khác là giá trị của PHPSESSID sẽ không còn đơn giản nữa.

Thử login với:

username:password = yeuchimse:123456

Kiểm tra cookie:

PHPSESSID=3334332d7965756368696d7365

Khá giống một xâu HEX, decode:

343-yeuchimse

Đơn giản đến không ngờ. Như vậy ta chỉ cần dò giống hệt bài trước, khác mỗi cái cơ chế encode của biến PHPSESSID:

Kết quả là ta tìm được admin tại id = 176

→ flag = eofm3Wsshxc5bwtVnEuGIlr7ivb9KABF.

[OverTheWire] Natas – Level 18

http://natas18.natas.labs.overthewire.org/

Please login with your admin account to retrieve credentials for natas19.

Nhấn View sourcecode:

Bài này sử dụng một custom-session-manager, với giá trị của PHPSESSID nằm ngẫu nhiên trong khoảng từ (1, 640). Tất nhiên admin cũng chỉ có thể nằm trong mớ giá trị đó thôi, và chúng ta sẽ thử dần dần từng giá trị cho đến khi thành công:

Kết quả là SESSID của admin = 84:

→ flag = 4IwIrekcuZlA9OsjOkoUtwU6lhokCPYs.

[OverTheWire] Natas – Level 17

http://natas17.natas.labs.overthewire.org/

Nhấn View sourcecode:

Tất cả các thông báo đều đã bị xoẹt xoẹt, làm sao đây emo_popo_cry

Dựa vào cái gì để phân biệt giữa True và False bây giờ emo_popo_pudency

……

………

……

emo_popo_haha

Hãy cùng để ý phần Time-based, vì nó chính là thứ chúng ta cần sweet_kiss

Ý tưởng là, ta sẽ viết một câu query với đặc tính sau:

  • Nếu phép kiểm tra là đúng, sleep 3 giây.
  • Nếu phép kiểm tra là sai, không làm gì cả.

Khi ấy, bằng việc so sánh khoảng thời gian thực hiện việc gửi và nhận request, ta có thể biết được phép thử mình gửi lên là đúng hay sai (tất nhiên không xét trường hợp tốc độ mạng quá chậm, dẫn đến không phân biệt nổi giữa sleep 3 giây và sleep 0 giây emo_popo_look_down)

Code minh họa như sau (sẵn kết hợp cả Binary Search thần thánh, nhưng mình không khuyến khích dùng vì… mình không thích cho dùng sexy_girl):

Kết quả:

xvKIqDjy4OPv7wCRgDlmj0pFsCsDjhdP

→ flag = xvKIqDjy4OPv7wCRgDlmj0pFsCsDjhdP.

[OverTheWire] Natas – Level 16

http://natas16.natas.labs.overthewire.org/

For security reasons, we now filter even more on certain characters
Find words containing…

Nhấn View sourcecode:

Thấy quen quen emo_popo_shame

Vì rằng input đã bị escape một số ký tự chủ chốt, ta buộc phải nghĩ cách khác. Cách hay nhất chính là dùng… Google emo_popo_haha

Có những thứ trong cuộc sống mà chúng ta buộc phải chấp nhận một điều, rằng chúng ta chưa có đủ kiến thức để có thể đạt được nó. Chưa đi học, chúng ta không thể hiểu làm sao để giải cái phương trình bậc 2, và thậm chí cũng không biết rằng nó được gọi là phương trình bậc 2, nên không thể tự tìm cách giải quyết. Các bạn hiểu mình đang nói gì không? emo_popo_angry

Sau khi Google, mình biết được một điều rằng ta có thể lồng các câu lệnh con vào làm tham số của một câu lệnh khác, bằng cách sử dụng $(). Ví dụ:

output:

:sure:

Trở lại chức năng tìm kiếm của task này, dễ thấy ta có thể inject các câu lệnh theo ý muốn và dựa vào kết quả trả về để xác định password cho task 17. Nó kiểu như:

  • Nếu ký tự đầu tiên của task17.pw là ‘a’: Tìm kiếm với keyword = ‘a’.
  • Ngược lại: Tìm kiếm với keyword ‘xxx’ (hoặc 1 từ bất kỳ không xuất hiện trong dictionary.txt).

Như thế, nếu có dữ liệu trả về, thì phép thử của chúng ta là đúng, còn ngược lại, phép thử là sai. Tương tự như vậy đối với các ký tự khác.

Tuy nhiên không hiểu sao mình chật vật mãi với đám ifthenfi mà vẫn không xong, nên mình đã Google tiếp và ra một câu lệnh khác, xì tin hơn nhiều:

Xét 2 câu lệnh sau và output của nó:

abcdef

(không trả về gì cả)

Tức là, nếu ta nhập input sau vào box search:

thì sẽ có 2 trường hợp xảy ra:

  1. Có dữ liệu liên quan đến từ Americanism trả về: Như vậy $(grep…) trả về <rỗng>, tức là phép thử của chúng ta (task17.pw bắt đầu bằng a) là sai.
  2. Không có dữ liệu trả về: Như vậy $(grep…) trả về khác <rỗng>, tức là phép thử của chúng ta là đúng, ta tìm được 1 ký tự của pw.

Lặp lại các phép thử như vậy, ta sẽ có đủ 32 ký tự cần tìm.

Code minh họa (không khuyến cáo dùng vì rất chậm):

Kết quả:

8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw

→ flag = 8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw.

[OverTheWire] Natas – Level 15

http://natas15.natas.labs.overthewire.org/

Nhấn View sourcecode:

Có một điều khác biệt so với task trước, đó là không hề có câu lệnh in ra password cho level tiếp theo. Vậy phải làm sao?

Có một ý tưởng (dự đoán), đó là liệu trong database có username và password cho level 16?

Thử nhập username = natas16:

This user exists.

Ok, vậy gần như chắc chắn password của user này sẽ là thứ ta cần tìm.

Có nhiều cách để dò pw, mà thường cách phổ thông nhất là so sánh từng ký tự của pw (MYSQL cung cấp cho ta hàm ascii()substring() để làm việc này) với các ký tự hợp lệ (trong trường hợp này là a..z, A..Z, 0..9), tức mất tối đa 26 + 26 + 10 = 62 lần thử để tìm ra một ký tự. Độ dài pw là 32, nên số phép thử là khá lớn.

Nếu đi theo tư tưởng của Binary Search, ta chỉ mất khoảng 7 (hay 8 gì đó =.=) lần thử cho 1 ký tự.

Code minh họa như sau (bạn có thể không cần hiểu, vì mình đọc lại cũng không hiểu lắm emo_popo_pudency, nhưng tư tưởng của Binary Search thì thống nhất trên Google rồi, ai cũng có thể tự cài đặt theo ý thích):

Kết quả:

WaIHEacj63wnNIBROHeqi3p9t0m5nhmh

→ flag = WaIHEacj63wnNIBROHeqi3p9t0m5nhmh.

[OverTheWire] Natas – Level 14

http://natas14.natas.labs.overthewire.org/

Nhấn View sourcecode:

Ta thấy ngay được là username và password đều không bị escape. Inject với câu lệnh được dạy trong sách giáo khoa:

username = " OR 1=1#
password = <gì cũng được>

Kết quả:

Successful login! The password for natas15 is AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J

→ flag = AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J.