
Chương trình An ninh Cơ sở Hạ tầng Quan trọng (CISS) là một sự kiện hàng đầu thường niên và duy nhất trong lĩnh vực an ninh mạng, cung cấp một cuộc thi CTF (Capture The Flag) chuyên biệt về công nghệ vận hành (OT), được tổ chức tại Đại học Công nghệ và Thiết kế Singapore (SUTD) và được tổ chức bởi trung tâm nghiên cứu iTrust. CISS mang đến cơ hội tuyệt vời để các chuyên gia CTF toàn cầu cùng nhau giải quyết các thách thức an ninh mạng OT thực tế. Năm nay, CISS 2025 bao gồm hai giai đoạn:
-
Giai đoạn 1 – Vòng loại: một cuộc thi CTF trực tuyến kéo dài 48 giờ (đã kết thúc vào ngày 31 tháng 7).
-
Giai đoạn 2 – Chung kết: một buổi thực hành trực tiếp kéo dài 4 giờ trên các testbed thực tế tại SUTD-iTrust.
CISS-2025-Giai đoạn 1 đã kết thúc vào tháng trước với sự tham gia của 61 Đội Đỏ quốc tế và 10 đội hàng đầu sẽ tiến vào vòng chung kết. Để biết thêm chi tiết, vui lòng truy cập Trang web CISS 2025.
Trong bài viết này, tôi sẽ trình bày chi tiết một thử thách kết hợp CNTT-OT mà tôi đã gửi cho Giai đoạn 1 của CISS2025: “Vượt qua Cánh cửa của Durin”. Đây là thử thách đầu tiên của cuộc thi, được thiết kế như một điểm khởi đầu cho người tham gia. Nó có một trình mô phỏng Siemens S7-1200 PLC chạy một dịch vụ S7Comm—cho phép sửa đổi khối dữ liệu bộ nhớ bằng giao thức Siemens S7 OT—và một giao diện web trực quan hóa trạng thái bộ nhớ PLC đồng thời nhúng một số câu đố nhẹ tập trung vào CNTT.
# Author: Yuancheng Liu
# Created: 2025/06/28
# Version: v_0.3.1
# Copyright: Copyright (c) National Cybersecurity R&D Laboratory (NCL)
# License: MIT License
Giới thiệu Thử thách: Vượt qua Cánh cửa của Durin
Mỗi năm, CISS CTF đều có một cốt truyện sáng tạo để truyền cảm hứng cho việc thiết kế thử thách. Phiên bản năm 2025 áp dụng chủ đề “Sự trở lại của Kiểm soát”, lấy cảm hứng từ Chúa tể của những chiếc nhẫn: Sự trở lại của nhà vua (xem áp phích CISS2024 bên dưới).

Thử thách “Vượt qua Cánh cửa của Durin” đóng vai trò là cổng vào đầu tiên mà mọi Đội Đỏ nên vượt qua khi bắt đầu CTF. Lấy cảm hứng từ cuộc hành trình đầy hiểm nguy của Frodo và Sam đến Núi Doom để tiêu diệt chiếc nhẫn, thử thách này đặt ra một sân khấu để người tham gia bắt đầu cuộc tìm kiếm của riêng họ—mở khóa kiến thức ẩn giấu và bước vào thế giới của các câu đố an ninh mạng CNTT-OT.
Về cốt lõi, thử thách cung cấp một môi trường thực hành mô phỏng Siemens S7-1200 PLC cho mỗi đội đỏ. Người tham gia cần:
-
Khám phá IP và các cổng có thể truy cập của PLC.
-
Phân tích các khối dữ liệu bộ nhớ S7Comm và suy ra logic được thực thi bởi PLC.
-
Chèn đúng loại dữ liệu (int, bool, float) vào đúng địa chỉ khối bộ nhớ.
-
Điều khiển PLC để hoàn thành các nhiệm vụ được giao và khám phá các flag.
Thử thách được cấu trúc thành bốn nhiệm vụ chính, mỗi nhiệm vụ bao gồm một cặp câu hỏi tập trung vào CNTT và một câu hỏi tập trung vào OT—tổng cộng sáu câu đố kết hợp CNTT-OT. Thiết kế này đảm bảo người tham gia phải kết hợp các kỹ năng CTF cổ điển (khai thác web, quét, viết script) với các kỹ thuật cụ thể của OT (xử lý giao thức S7Comm, thao tác khối bộ nhớ).
Thiết kế môi trường tổng thể được minh họa bên dưới:

Để giải quyết thử thách, các Đội Đỏ cần SSH vào gateway và jumphost được chỉ định cho họ, sau đó truy cập Kali Linux Transaction VM chuyên dụng của họ (Máy tấn công). Từ đó, họ cần:
-
Xác định địa chỉ IP PLC và các dịch vụ khả dụng.
-
Chuyển tiếp giao diện web xác minh và nhiệm vụ thử thách đến máy cục bộ của họ.
-
Phát triển các script tấn công tùy chỉnh hoặc cài đặt các công cụ (với đầy đủ quyền
sudo) trên Kali VM. -
Giao tiếp với cả máy chủ xử lý dữ liệu S7Comm của PLC (Cổng 102) và máy chủ web dựa trên Flask (Cổng 5001) để thao tác bộ nhớ PLC và xác thực kết quả.
Mô phỏng PLC cơ bản dựa trên một phần của dự án mã nguồn mở của tôi Py_PLC_Honey_Pot,(như hình bên dưới), mô phỏng logic Siemens S7 và cung cấp một nền tảng linh hoạt cho các bài tập an ninh mạng CNTT-OT.

Liên kết giới thiệu Honeypot: https://www.linkedin.com/pulse/python-plc-honeypot-project-yuancheng-liu-vks8c
Câu chuyện Bối cảnh Thử thách
Câu chuyện bối cảnh thử thách được hiển thị bên dưới:

Frodo và Sam đang trên đường đến Núi Doom để tiêu diệt chiếc nhẫn. Thời gian không còn nhiều, họ không có đủ thời gian để đi bộ qua dãy núi Gundabad. Sam có một bản đồ Dunland bị hỏng với một số mảnh vỡ, nó cho thấy lối tắt để vượt qua ngọn núi thông qua một đường hầm dưới lòng đất. Trước khi vào đường hầm, họ cần tìm và đi qua "Cánh cửa của Durin". Họ không có chìa khóa, nhưng có một cách nào đó để mở khóa cánh cửa.
Trước khi có thể vào đường hầm, Frodo cần gửi một tin nhắn cho Aragorn để thu hút sự chú ý của Con mắt rực lửa để giúp họ.
Tổng quan về Câu hỏi Thử thách CTF
Thử thách Vượt qua Cánh cửa của Durin được chia thành bốn nhiệm vụ chính, chứa tổng cộng sáu câu hỏi CTF. Mỗi câu hỏi mang một giá trị điểm (1–10) theo mức độ khó của nó và một số câu hỏi cung cấp các gợi ý tùy chọn. Sử dụng gợi ý làm giảm số điểm có sẵn xuống 60% cho câu hỏi đó. Tất cả các câu hỏi đều được triển khai trên nền tảng CTF-D với số lần thử tối đa được xác định, như được tóm tắt bên dưới.
Chi tiết câu hỏi được hiển thị bên dưới:
| Câu hỏi | Mô tả | Điểm | Số lần thử tối đa | Gợi ý |
|---|---|---|---|---|
| Q1: Tìm đường | Frodo và Sam phải xác định con đường chính xác đến Cánh cửa của Durin. Sau khi được tiết lộ, flag sẽ xuất hiện. | 3 | 5 | Hãy thử kết hợp hai mảnh bản đồ. |
| Q2: Xác định Giao thức | Cánh cửa được điều khiển bởi PLC. Xác định giao thức giao tiếp mà nó sử dụng. | 1 | 3 | Tìm kiếm manh mối trong mã nguồn trang web. |
| Q3: Phá khóa cửa | Frodo không có chìa khóa—hãy giúp anh ta vượt qua khóa. Mở khóa cửa sẽ tiết lộ flag. | 6 | 5 | Hãy thử chèn các giá trị số nguyên; kiểm tra địa chỉ bộ nhớ thông qua giao diện người dùng web. |
| Q4: Xác định vị trí Khối Bộ nhớ PLC | Sam phải xác định địa chỉ bộ nhớ PLC chính xác để gửi tin nhắn. | 2 | 3 | Không có |
| Q5: Gửi tin nhắn | Giúp Frodo gửi tin nhắn cho Aragorn. Gửi tin nhắn chính xác sẽ tiết lộ flag. | 5 | 5 | Hãy thử đặt giá trị Boolean trong bộ nhớ. |
| Q6: Giải mã Phản hồi | Aragorn trả lời bằng một tín hiệu ẩn. Điều chỉnh tần số vô tuyến và giải mã phản hồi để trích xuất flag. | 3 | 3 | Hãy thử đặt giá trị float trong bộ nhớ. |
Các bước để Giải quyết Thử thách
Mỗi người tham gia sẽ được chỉ định một Kali-Linux Transaction VM với quyền sudo, cho phép họ chạy các công cụ red teaming khác nhau hoặc tạo các script tấn công. Đăng nhập vào Transaction VM, sau đó làm theo các bước bên dưới để hoàn thành các nhiệm vụ từng bước một.
Bước 1: Truy cập Giao diện Web PLC
Bắt đầu bằng cách quét PLC VM để xác định các cổng mở được sử dụng bởi các giao thức OT và dịch vụ HTTP (cổng 5002), sử dụng lệnh nmap như hình bên dưới:
nmap -sS -Pn -T5 -p- 172.23.155.209
Kết quả quét cổng Nmap:

Từ quá trình quét, bạn sẽ thấy rằng các cổng 5002 (dịch vụ HTTP) và 102 (iso-tsapl) đang mở.
Vì Transaction VM chạy Ubuntu Server (không có môi trường desktop), bạn cần chuyển tiếp cổng giao diện web của PLC đến máy cục bộ của mình. Sử dụng lệnh ssh sau:
ssh -L 127.0.0.1:5000:172.23.155.209:5002 -J @ @172.23.144.1
Sau khi đường hầm được thiết lập, hãy mở URL http://127.0.0.1:5000 trong trình duyệt cục bộ của bạn để truy cập giao diện web PLC. Bạn sẽ được chuyển đến trang giới thiệu câu chuyện và thử thách như hình bên dưới:

Sau khi xem xét câu chuyện bối cảnh, hãy tiếp tục thử thách bằng cách truy cập trang web index http://127.0.0.1:5000/Index, như hình bên dưới để nhận danh sách giới thiệu 4 nhiệm vụ:

Trang này sẽ dẫn bạn đến Câu hỏi 1, nơi nhiệm vụ thực sự bắt đầu.
Bước 2: Giải quyết Câu hỏi CNTT 1 – Tái cấu trúc Bản đồ
-
Câu đố CNTT: Kết hợp ma trận pixel của các bức ảnh để lấy thông tin đăng nhập đăng nhập web PLC.
Câu hỏi 1 là một phần của Nhiệm vụ 1, thách thức người tham gia giúp Sam và Frodo tái cấu trúc một con đường. Theo mô tả nhiệm vụ:
Sam và Frodo nhận được hai mảnh bản đồ từ Gollum. Cố gắng khôi phục bản đồ để tìm ra tuyến đường và hướng đi để bắt đầu cuộc hành trình.
Để giải quyết thử thách này, người tham gia phải tải xuống và kết hợp hai hình ảnh mảnh bản đồ. Chúng được gắn nhãn "Mảnh bản đồ của Sam" và "Mảnh bản đồ của Frodo" như hình bên dưới:

Tuy nhiên, nhấp chuột phải vào hình ảnh để lưu nó sẽ không hoạt động vì menu ngữ cảnh của trình duyệt bị tắt (kiểm tra mã nguồn trang):

Để giải quyết vấn đề này, bạn có thể:
-
Xóa phần được đánh dấu onContextMenu="return false;" khỏi thẻ
bằng các công cụ dành cho nhà phát triển của trình duyệt của bạn. Điều này sẽ kích hoạt lại menu ngữ cảnh nhấp chuột phải để bạn có thể lưu hình ảnh bình thường.

Ngoài ra, bạn có thể mở URL hình ảnh trong một tab trình duyệt mới để truy cập trực tiếp:

Sau khi cả hai hình ảnh được tải xuống, gợi ý cho thấy rằng chúng ta cần “kết hợp” các bức ảnh để tiết lộ bản đồ ẩn. Để đạt được điều này, chúng ta có thể viết một chương trình Python đọc các giá trị pixel (R, G, B) của cả hai hình ảnh vào ma trận và sau đó thử nghiệm với các phương pháp kết hợp khác nhau, như hình bên dưới:

Kết quả (R3, G3, B3) = ((R1+?R2), (G2+?G2), (B3+?B3)
-
Thêm các giá trị pixel của hai ma trận để tạo một hình ảnh mới.
-
Xoay ma trận hình ảnh thứ hai theo 90° / 180° / 270° và sau đó kết hợp các giá trị pixel.
-
Đảo ngược ma trận hình ảnh thứ hai trước khi kết hợp.
-
Lật ma trận hình ảnh thứ hai trước khi kết hợp.
Nếu các giá trị pixel kết quả vượt quá 255 trong bất kỳ kênh RGB nào, thì phương pháp đó không hợp lệ. Giải pháp chính xác là lật từ trên xuống hình ảnh thứ hai và sau đó phủ ma trận của nó lên hình ảnh đầu tiên để tái cấu trúc bản đồ đầy đủ. Một đoạn mã kết hợp ma trận RGB pixel đơn giản của python được hiển thị bên dưới:
image_path1 = "img1.jpg"
img1 = Image.open(image_path1)
width1, height1 = img1.size
pixel_data1 = list(img1.getdata()) # Get pixel values
pixel_2d_lis1 = [pixel_data1[i * width1:(i + 1) * width1] for i in range(height1)]
# Read picture 2 in a matrix and do top-down mirroring
image_path2 = "img2.jpg"
img2 = Image.open(image_path2)
width2, height2 = img2.size
pixel_data2 = list(img2.getdata()) # Get pixel values
pixel_2d_list2 = [pixel_data2[i * width2:(i + 1) * width2] for i in range(height2)]
topdownMirror = pixel_2d_list2[::-1]
# combine the pixels to the new image
img3List = []
for i, item in enumerate(pixel_2d_lis1):
newItem = []
for j, pixel in enumerate(item):
img2Pixel = topdownMirror[i][j]
img3R = pixel[0] + img2Pixel[0]
img3G = pixel[1] + img2Pixel[1]
img3B = pixel[2] + img2Pixel[2]
newItem.append((img3R, img3G, img3B))
img3List.append(newItem)
img3Data = np.array(img3List, dtype=np.uint8)
img3 = Image.fromarray(img3Data, 'RGB')
img3.save("result.jpg")
Ngoài ra, hãy sử dụng script được cung cấp: pictureCombine.py để thử tất cả các hàm kết hợp pixel để có được hàm chính xác, Điều này sẽ tự động tạo ra kết quả kết hợp, như hình bên dưới:

Từ hình ảnh đã hợp nhất, người tham gia có thể trích xuất:
-
Chuỗi Tuyến đường:
FollowSilvertineDarkCliffsUnderstartLight -
Chuỗi Hướng:
WestSideNeArTw0AncientH011yTrEes
Điền vào các trường Tuyến đường và Hướng và nhấn nút Đi đến "Cánh cửa của Durin" để gửi câu trả lời:

Nếu tuyến đường và hướng đi là chính xác, flag Câu hỏi 1 sẽ được hiển thị ở cuối trang:

Flag Câu hỏi 1: CISS_2025_@T_THE_FR0NT_0F_Th3_Ho11in_G@t3
Bước 3: Giải quyết Câu hỏi OT 2 – Xác định Giao thức OT PLC
-
Câu đố OT: Xác định và xác nhận giao thức OT giao tiếp PLC
Từ quá trình quét cổng Nmap trước đó, chúng ta đã phát hiện ra rằng cổng 102 đang mở:

Cổng này được liên kết với giao thức ISO-TSAP. Tuy nhiên, "iso-tsap" không phải là flag chính xác. Để xác định giao thức OT thực tế được sử dụng bởi PLC, hãy thử tìm kiếm truy vấn sau trong Google:
“port 102 operational technology protocol TSAP type used by PLC”
Điều này sẽ dẫn đến hai kết quả phổ biến:
-
Siemens S7 và S7 Plus
-
Giao thức Giao tiếp Trung tâm Điều khiển Liên lạc (ICCP)
Quay lại trang câu chuyện sau khi nhấp vào nút “Bắt đầu cuộc hành trình”. Kiểm tra mã nguồn trang để xác định vị trí hình ảnh ẩn có tên protocol.png (hình ảnh rộng 1 pixel):

Để hiển thị hình ảnh đầy đủ, hãy xóa hoặc sửa đổi kiểu của hình ảnh bằng các công cụ dành cho nhà phát triển của trình duyệt, sau đó hình ảnh được hiển thị xác nhận rằng PLC đang sử dụng giao thức S7Comm như hình bên dưới:

Bạn có thể xác minh giao thức bằng cách chạy một
Ứng dụng khách S7Comm script như được hiển thị trong ví dụ nàyCài đặt thư viện python snap7 https://pypi.org/project/python-snap7/ và sử dụng lib xử lý giao thức giao tiếp S7Comm: https://github.com/LiuYuancheng/PLC_and_RTU_Simulator/blob/main/S7Comm_RTU_Simulator/src/snap7Comm.py để xây dựng kết nối PLC và script đọc và ghi khối bộ nhớ của bạn như được hiển thị bên dưới:
PLC_IP= '172.23.155.209'
client = snap7Comm.s7CommClient(PLC_IP, rtuPort=102, snapLibPath=libpath)
connection = client.checkConn()
print("S7Comm client connection: %s" % str(connection))
Sau khi thực thi script, một thông báo kết nối thành công sẽ được in ra để xác nhận rằng một kết nối đã được thiết lập:

Question 2 Flag : S7COMM
Bước 4: Giải OT-Question 3 – Mở khóa
-
OT puzzle: Tìm ra logic bên trong PLC và điền các giá trị int vào khối địa chỉ bộ nhớ chính xác trong thời gian giới hạn.
Question 3 là một phần của Task 2, sau khi hoàn thành Task 1, tab Task 2 sẽ tự động được hiển thị trong thanh điều hướng:

Điều hướng đến thử thách “Crack the Lock” trong Task 2. Người tham gia sẽ thấy câu chuyện thử thách sau:
Frodo phát hiện ra rằng khóa được điều khiển bởi một PLC. Anh ta có thể sử dụng mã pin của mình (chương trình ứng dụng khách giao tiếp PLC) để đặt một số giá trị trong bộ nhớ PLC để đẩy các chốt khóa đến đúng vị trí.
Trang nhiệm vụ được hiển thị bên dưới:

Người tham gia phải tương tác với PLC để đặt tất cả các rãnh khóa để đẩy các chốt vào đúng vị trí, mô phỏng việc mở khóa một khóa cơ học. Các yếu tố thử thách chính bao gồm:
-
Cơ chế khóa bao gồm 12 thử thách chốt (mỗi hàng có hình chữ nhật màu xanh lá cây, xanh lam, vàng, xám).
-
Các ô vuông màu xanh lam nhạt phải được căn chỉnh với đường cắt nằm ở chỉ số cột = 12
-
Rãnh khóa được điều khiển bằng cách đặt các giá trị trong các địa chỉ bộ nhớ PLC cụ thể, được hiển thị trong cột "add" (địa chỉ):
['1[0]', '1[2]', '1[4]', '1[6]', '2[0]', '2[2]', '2[4]', '2[6]', '3[0]', '3[2]', '3[4]', '3[6]'], với định dạng.[ ] -
Độ dài của chốt (chốt dưới cùng có màu xanh lá cây) được cập nhật sau mỗi 60 giây và bộ hẹn giờ đếm ngược được hiển thị trên trang nhiệm vụ.
-
Sau khi bộ hẹn giờ đặt lại, tất cả các giá trị đã đặt trước đó sẽ bị xóa, bao gồm cả các giá trị rãnh khóa. Người tham gia phải giải quyết thử thách trong vòng 60 giây sau khi các chốt mới được tạo.
Ánh xạ các thành phần chi tiết được hiển thị bên dưới khi người dùng đặt một số giá trị rãnh khóa để đẩy các chốt khóa:

Khi người tham gia nhập các giá trị số nguyên vào PLC, họ sẽ kiểm soát mức độ di chuyển của các chốt. Giá trị chính xác cho mỗi chốt được tính như sau: Key Cut Value = 12 - Bottom Pin Tumbler Length
Ví dụ: nếu độ dài chốt hiện tại là:
[7, 8, 4, 7, 9, 7, 3, 5, 6, 3, 10, 7]
Sau đó, các giá trị rãnh khóa tương ứng mà người tham gia cần đặt cho mỗi vị trí byte bộ nhớ sẽ là [5, 4, 8, 5, 3, 5, 9, 7, 6, 9, 2, 5] dưới dạng danh sách trong bảng bên dưới:
| Chỉ số địa chỉ | Byte Idx=0 | Byte Idx=2 | Byte Idx=4 | Byte Idx=6 |
|---|---|---|---|---|
| 1 | 5 | 4 | 8 | 5 |
| 2 | 3 | 5 | 7 | 9 |
| 3 | 6 | 9 | 2 | 5 |
Người tham gia có thể sử dụng ứng dụng khách Siemens S7Comm (như đã khám phá trong Question 2) để ghi các giá trị này vào đúng địa chỉ bộ nhớ PLC. Người hướng dẫn có thể cung cấp hoặc trình diễn việc sử dụng script doorLockSolver.py, script này tự động ghi các giá trị chính xác vào PLC. Nhật ký thực thi script tấn công được hiển thị bên dưới:

Sau khi các giá trị được ghi vào bộ nhớ, UI sẽ cập nhật và hiển thị cách các chốt thay đổi như hình bên dưới. Khi tất cả các hình chữ nhật màu xanh lá cây (chốt) thẳng hàng với đường cắt (cột 12), khóa có thể được mở:

Question 3 Flag : CISS_2025_P1Ns_@nd_TUm61ers_@T_C0RR3CT_P0S
Bước 5: Giải IT-Question 4 – Tìm địa chỉ bộ nhớ PLC
-
IT puzzle: Tìm tệp ẩn và lấy dữ liệu địa chỉ khối bộ nhớ PLC từ ma trận.
-
OT puzzle: Chèn dữ liệu Bool chính xác vào bộ nhớ để ánh xạ mã morse của các ký tự.
Sau khi Question 3 được giải, tab Task 4 sẽ được mở khóa và hiển thị trong thanh điều hướng:

Từ manh mối, có một số điểm chính để giải quyết thử thách:
-
Yêu cầu xử lý ma trận : Sam được yêu cầu xử lý một ma trận để trích xuất một số dữ liệu có ý nghĩa.
-
Truyền tin nhắn : Người gửi tin nhắn có dấu chấm hỏi được điều khiển bởi PLC, nếu chúng ta kiểm tra trang bắt đầu, chúng ta sẽ biết máy gửi tin nhắn là máy phát điện báo, điều này cho thấy rằng tin nhắn được truyền bằng mã Morse.
-
Gợi ý mã Morse ẩn:
"Hi Sam, got problem to find the address of the PLC memory? Check this -- .- - .-. .. -..-"Giải mã mã Morse:-- .- - .-. .. -..- → MATRIXĐiều này xác nhận rằng tệp ma trận là trung tâm để giải quyết thử thách này.

Mỗi ký tự của tin nhắn trên màn hình có một tọa độ (x, y) bên dưới nó:

Nhấp vào mã ma trận -- .- - .-. .. -..- để tải xuống tệp ma trận địa chỉ như được hiển thị bên dưới:

Để giải quyết thử thách này, người tham gia phải tải xuống tệp ma trận và sử dụng các tọa độ đã cho để tra cứu các giá trị trong ma trận để xác định chuỗi địa chỉ bộ nhớ. Ngoài ra, họ có thể sử dụng script tấn công matrixSeacher.py để truy xuất tất cả các địa chỉ.
Question 4 Flag :CISS_2025_14_33_47_68_105_117_155_198_2025
Bước 6: Giải OT-Question 5 – Gửi tin nhắn qua mã Morse
-
OT puzzle: Chèn các giá trị bool chính xác vào khối địa chỉ bộ nhớ chính xác.
Sau khi giải Question 4, bạn sẽ nhận được chuỗi địa chỉ bộ nhớ PLC tương ứng với tin nhắn WEDIDPASS. Mỗi ký tự ánh xạ tới một địa chỉ bộ nhớ PLC cụ thể, như được hiển thị bên dưới:
W - 14
E - 33
D - 47
I - 68
D - 105
P - 117
A - 155
S - 198
S - 2025
Khi bạn kiểm tra phần tin nhắn trên trang web, bạn sẽ tìm thấy các manh mối chính để giúp bạn giải quyết thử thách, như được minh họa trong hình.

-
Có một gợi ý ẩn (chỉ hiển thị khi được đánh dấu bằng chuột) hiển thị:
Hint: '.' = True, '-' = False -
Mỗi ký tự phải được chuyển đổi thành mã Morse và các giá trị Boolean tương ứng (
Truecho dấu chấm,Falsecho dấu gạch ngang) phải được ghi vào 4 byte liên tiếp trong bộ nhớ PLC (ví dụ: Byte 0, Byte 2, Byte 4, Byte 6). -
Chỉ báo màu xanh lá cây có nghĩa là giá trị byte là chính xác và màu đỏ có nghĩa là không chính xác.
Sử dụng gợi ý và biểu diễn mã Morse cho mỗi ký tự, chúng ta có thể xây dựng bảng sau:
| Ký tự | Địa chỉ bộ nhớ | Mã Morse | Byte_0 | Byte_2 | Byte_4 | Byte_6 |
|---|---|---|---|---|---|---|
| W | 14 | .-- |
True |
False |
False |
|
| E | 33 | . |
True |
|||
| D | 47 | -.. |
False |
True |
True |
|
| I | 68 | .. |
True |
True |
||
| D | 105 | -.. |
False |
True |
True |
|
| P | 117 | .--. |
True |
False |
False |
True |
| A | 155 | .- |
True |
False |
||
| S | 198 | ... |
True |
True |
True |
|
| S | 2025 | ... |
True |
True |
True |
Để đặt các giá trị, hãy sử dụng đoạn mã Python mẫu sau:
memoryIdx = 2025
byteIndex = (0,2, 4)
valueList = (True, True, True)
for i in range(len(byteIndex)):
client.setAddressVal(memoryIdx, byteIndex[i], valueList[i], dataType=BOOL_TYPE)
time.sleep(0.1)
time.sleep(0.5)
Ngoài ra, hãy sử dụng script được cung cấp morseCodeSolver.py để tự động hóa toàn bộ quy trình cho tất cả các ký tự:

Khi tất cả các chỉ báo đã chuyển sang màu xanh lá cây, hãy nhấp vào nút “Gửi tin nhắn”. Nếu các giá trị là chính xác, flag cho Question 5 sẽ xuất hiện trong thẻ bên dưới khu vực tin nhắn.
Question 5 : CISS_2025_--_---_.-._..._.C0DE_MSG_S3NT!
Bước 7 : Giải IT-Question 6 – Trích xuất tin nhắn từ âm thanh
-
IT puzzle: Brute force phá mật khẩu tệp zip, lấy thông tin từ tệp âm thanh.
-
OT puzzle: Chèn các giá trị float chính xác vào khối địa chỉ bộ nhớ chính xác.
Sau khi Question 5 được giải, nhiệm vụ tiếp theo (Question 6) sẽ tự động được hiển thị ở cuối cùng của cùng một trang như được hiển thị bên dưới:

Nó hiển thị tin nhắn để người tham gia điều chỉnh tần số của máy thu điện báo để nhận tin nhắn phản hồi của Aragorn:
Hi Frodo, you need to change your telegraph receiver to the correct frequency (HZ) same as Aragorn's transmitter! The frequency is the start MM.DD of CISS 2025 and the memory block is the XOR of all the send message address block index.
Chúng ta cần ghi một số float vào khối bộ nhớ PLC để điều khiển tần số của máy thu điện báo.
Tin nhắn hiển thị XOR tất cả các chỉ số khối địa chỉ tin nhắn đã gửi, trong question 4, chúng ta đã nhận được flag CISS_2025_14_33_47_68_105_117_155_198_2025, sau đó thực hiện XOR số nguyên để lấy chỉ số khối bộ nhớ chính xác:
14 ^ 33 ^ 47 ^ 68 ^ 105 ^ 117 ^ 155 ^ 198 ^ 2025 = 2028
Tần số là MM.DD bắt đầu của CISS là 07.29 như được hiển thị bên dưới:

Vì vậy, chúng ta cần chèn 7.29 vào khối bộ nhớ 2028 với mã bên dưới:
client.setAddressVal(2028, 0, 7.29, dataType=REAL_TYPE)
client.setAddressVal(2028, 4, 7.29, dataType=REAL_TYPE) # optinoal
Sau khi bạn đặt giá trị trong bộ nhớ PLC, hãy làm mới trang gửi tin nhắn và bạn có thể nhận được tin nhắn của Aragorn ngay bây giờ. Trang sẽ thay đổi thành trạng thái bên dưới để hiển thị task 4:

Nhấp vào liên kết để tải xuống tệp âm thanh .wav. Tuy nhiên, tệp âm thanh này được bảo vệ bằng mật khẩu bên trong một kho lưu trữ ZIP. Để truy cập tệp .wav, bạn phải brute-force mật khẩu ZIP bằng danh sách mật khẩu phổ biến. Bạn có thể sử dụng các công cụ như fcrackzip hoặc [zip2john + john] để thực hiện việc này. Ví dụ: sử dụng fcrackzip và danh sách 1000 mật khẩu hàng đầu (ví dụ: Pwdb_top-1000.txt từ SecLists):
fcrackzip -v -D -p Pwdb_top-1000.txt protected_audio.zip

Sau khi bẻ khóa, hãy trích xuất tệp .wav từ kho lưu trữ ZIP.
Tệp .wav chứa một tin nhắn ẩn bằng cách sử dụng thuật toán ẩn âm thanh. Nghe tệp âm thanh, giọng nói trong âm thanh dường như không phải từ "Aragorn", tiếp tục phát video, trong 7 giây cuối cùng, bạn sẽ nghe thấy một số "âm thanh mã morse", cắt tệp âm thanh và chỉ để lại âm thanh mã morse. Lưu tệp dưới dạng một tệp âm thanh mới morse.wmv
Sử dụng một số bộ giải mã nguồn mã morse trực tuyến như https://morsecode.world/international/decoder/audio-decoder-adaptive.html để phân tích tệp:

Sau đó, lấy mã morse: --. .. - .... ..- -... .... .. -.. -.. . -. .-- .- ...- .
Chuyển đổi trở lại dữ liệu văn bản:

Chúng ta nhận được một số thông tin : GITSUBHIDDENWAVE Sau đó, chúng ta tìm kiếm từ khóa "HiddenWave" trong google và GitHub, chúng ta sẽ tìm thấy một số công cụ https://github.com/techchipnet/HiddenWave.
Bây giờ chúng ta quay lại để trích xuất âm thanh gốc, sử dụng công cụ mã nguồn mở HiddenWave, cụ thể là script ExWave.py, có sẵn tại đây:
Sao chép kho lưu trữ:
git clone https://github.com/techchipnet/HiddenWave.git
cd HiddenWave
Chạy script:
python ExWave.py -f /path/to/your/audio.wavThông điệp ẩn được trích xuất từ file .wav sẽ được hiển thị trong terminal – đây là flag Câu hỏi 6 của bạn, như hình dưới đây:

Question 6 Flag : CISS_2025_H1_Bro_wE11_DON3_FR0Do_@nd_S@m!
Chúc mừng bạn! Bạn đã vượt qua Cánh cửa của Durin và hoàn thành tất cả các nhiệm vụ của thử thách CTF này!
Nếu bạn quan tâm đến các thử thách OT PLC CTF khác, bạn cũng có thể xem thử thách Modbus-PLC này trong CISS2024: https://www.linkedin.com/pulse/hacking-ics-step-by-step-guide-solve-critical-it-ot-ctf-yuancheng-liu-ohjwc
Chỉnh sửa cuối bởi LiuYuancheng([email protected]) vào 15/07/2025, nếu bạn có bất kỳ vấn đề gì, vui lòng gửi tin nhắn cho tôi.
No comment for this article.