Ghi chú:
My implementation of authentication mechanisms in C turned out to be failures. But my implementation in Rust is unbreakable. Can you retrieve my password?
Chúng ta có thể sử dụng lệnh 'file' để cung cấp cái nhìn tổng quan về loại tệp.
Mở chương trình trong IDA.
Thoạt đầu quan sát, chương trình yêu cầu đầu vào là một chuỗi. Sau một vài lần gỡ lỗi, tôi nhận ra rằng chúng tôi cần vá tại 0x690D từ jz sang jnz
và chúng tôi đã nhận được:
Không thể dễ thế! Dành nhiều thời gian hơn để đọc, tôi nhận thấy nó truy cập vào “salsa20” rất nhiều lần. Sau khi tìm kiếm, chúng tôi nhận được nhiều thông tin chi tiết về Salsa20.
Trạng thái ban đầu của Salsa20 được tạo thành từ mười sáu từ 32 bit được sắp xếp dưới dạng ma trận 4×4 bằng cách sử dụng key
và nonce
. Chúng ta cần tìm 2 tham số. Ta có trạng thái ban đầu của Salsa20, nó sử dụng:
ef39f4f20e76e33bd25f4db338e81b10
là key
(xmmword_39CA0 + xmmword_39CB0)d4c270a3
là nonce
05055FB1A329A8D558D9F556A6CB31F324432A31C99DEC72E33EB66F62AD1BF9
là cipher
(xmmword_39CC0 + xmmword_39CD0)193978899768A08F66D39017B2E040C237193763C581E261
là fake_flag
Chúng ta rút gọn ma trận: expa
ef39f4f20e76e33bnd 3
d4c270a3 2-by
d25f4db338e81b10te k
Phần còn lại là giải mã Salsa, bạn có thể đọc nếu muốn. Cách chương trình in mật khẩu giống như cách in cờ. Bây giờ chúng ta viết mã để giải quyết phần còn lại.
Bây giờ chúng ta có thể bắt đầu làm việc trên dịch vụ từ xa.
Static-Analysis on this program didn't reveal much. There must be a better way to approach this…
Chúng ta có thể sử dụng lệnh 'file' để cung cấp cái nhìn tổng quan về loại tệp.
Mở chương trình trong IDA. Tôi chỉ biết sub_7FF775DF1050
với tham số giải mã để lấy hàm được giải mã nhưng tôi không biết thuật toán. Nếu ai có hình có thể bình luận bên dưới.
A friend gave you an odd executable file, in fact it is very tiny for a simple ELF, what secret can this file hide?
Chúng ta có thể sử dụng lệnh 'file' để cung cấp cái nhìn tổng quan về loại tệp.
Mở chương trình trong IDA.
Sau khi tìm kiếm về NASM, tôi tìm thấy một số thông tin hữu ích
Chương trình cố gắng gọi sys_exit
. Ta có thể bỏ qua nó và đọc đoạn trên, nó sẽ gọi sys_write
với kí tự của flag
được đưa vào ecx
Java streams are great! Why use 10 lines of completely readable code, when you could mash it all into 67 characters? +1, PR Approved!
Ta nhận được tệp stream.jar
và ouput.txt
. Tôi giải nén stream.jar
và nhận được Challenge.class
. Sử dụng https://www.decompiler.com/ để mở Challenge.class
, ta nhận được tệp Challenge.java
.
Đoạn mã mô tả:
hydrate
: Giảm giá trị ASCII của mỗi ký tự đi 1.moisten
: Nếu số là chẵn, giữ nguyên giá trị, ngược lại, làm bình phương giá trị.drench
: Dịch trái số nguyên một bit.dilute
: Chia giá trị cho 2 và cộng lại với giá trị ban đầu.waterlog
: Thực hiện một phép toán phức tạp trên giá trị, sau đó chuyển đổi thành số byte. Nếu một điều kiện được đáp ứng, giá trị được nhân đôi; ngược lại, giá trị được chia cho 2.Bản thân tôi rất ít khi làm các đề java
. Tôi đã tìm hiểu các Stream API
để hiểu rõ hoạt động:
Stream reduction operation
cho phép chúng ta tạo ra một kết quả duy nhất từ các phần tử của Stream bằng cách áp dụng các phép tính lặp đi lặp lại trên các phần tử của nó. Đọc thêm tại đây. Stream peek()
là một phương thức được sử dụng để thực hiện hành động trên mỗi phần tử của một luồng mà không làm thay đổi luồng đó. Đọc thêm tại đây. Ta phân tích luồng chương trình như sau:
Flag
thành một luồng các ký tự trong chuỗi.List
.hydrate()
trên mỗi ký tự trong danh sách, giảm giá trị Unicode của ký tự đi một đơn vị. Tuy nhiên nó dùng trong phương thứcpeek
=> giá trị không đổi.ĐÃ ĐƯỢC ĐẢO NGƯỢC
. Vì họ dùng reduce("", (var0x, var1) -> { return var1 + var0x; }
. Ta có ví dụ như sau: flag=HTB{minhkingkong} => '}gnokgnikhnim{BTH'
int
.moisten(), drench(), waterlog(), dilute()
để mã hóa danh sách trên. Tuy nhiên phương thức waterlog()
dùng trong phương thứcpeek
=> giá trị không đổi.Ta biết chuỗi đầu ra được lặp lại 5 lần, từ đó ta trích được chuỗi: b71bO12cO156O6e43Od8O69c3O5cd3O144Oe4O6e43O37cbOf6O69c3O1e7bO156O3183O69c3O6cO8b3bOc0O1e7bO156OfcO50bbO69c3Oc0O102O6e43OdeOb14bOc6OfcOd8O
Từ đây tôi viết chương trình để tìm ra flag
Bạn có thể đọc đoạn mã ở dưới để hiểu được luồng của chương trình.
After cleaning up we found this old program and wanted to see what it does, but we can't find the licence we had for it anywhere. Can you help?
Chúng ta có thể sử dụng lệnh 'file' để cung cấp cái nhìn tổng quan về loại tệp.
Mở chương trình trong IDA.
Bạn có thể sử dụng z3 hoặc angr, tùy bạn. Nhưng tôi đề cập đến việc sử dụng angr với việc thực hiện điều kiện challange, z3 khi phép tính không kéo dài.
My friend send me a encrypted message by using encryption bot. This is a important message. Can you decrypt the message for me?
Chúng ta có thể sử dụng lệnh 'file' để cung cấp cái nhìn tổng quan về loại tệp.
Mở chương trình trong IDA.
Chương trình kiểm tra độ dài dữ liệu ta nhập vào có là 27, sau đó chuyển nó thành hệ nhị phân.
Mục đích chuyển thành hệ nhị phân để bắc cầu - chuyển đổi dữ liệu theo hệ 6. Kết quả đó sẽ được chuyển thành hệ thập phân và lấy kí tự ASCII.
Malicious actors have infiltrated our systems and we believe they've implanted a custom rootkit. Can you disarm the rootkit and find the hidden data?
Chúng ta có thể sử dụng lệnh 'file' để cung cấp cái nhìn tổng quan về loại tệp.
Loadable kernel modules (. ko files) là một phần mở rộng tệp quan trọng trong hệ điều hành Linux. Nó cho phép người dùng và nhà phát triển mở rộng khả năng của nhân Linux và tùy chỉnh hệ thống của họ theo nhu cầu cụ thể.
Tệp .ko là một tệp đối tượng đã được biên dịch chứa mã được thiết kế đặc biệt để hoạt động với nhân Linux. Tệp này có thể chứa mã cho các tính năng hoặc chức năng mới, chẳng hạn như trình điều khiển thiết bị, mô-đun hệ thống tệp hoặc mô-đun bảo mật.
Mở chương trình trong IDA.
Trong lập trình và bảo mật hệ thống, _fentry__
là một hàm liên quan đến Linux Kernel, nó là nơi mà một hàm sẽ nhảy đến ngay sau khi được gọi, trước khi bất kỳ mã chính nào của hàm đó được thực thi. Đây là một phần của cơ chế ftrace, một công cụ trong hạt nhân Linux được sử dụng để debug và theo dõi hệ thống.
Ngay từ đầu, tôi xác định rằng nó có thể liên quan đến rootkit hoặc một số dạng phần mềm độc hại có thể thay đổi bảng lệnh gọi hệ thống để ẩn mô-đun khỏi một số kiểm tra nhất định.
Ta cần hiểu luồng tư duy như sau: rootkit cần đánh lừa người dùng ở chế độ người dùng, tức là thực hiện kiểm soát giao diện giữa User-mode và Kernel-mode. Một trong số đó có kỹ thuật hooking: chuyển hướng một cuộc gọi hệ thống đến một chức năng tùy chỉnh.
Đầu tiên nó sẽ tìm syscall table
, sau đó là thay thế các cuộc gọi hệ thống bằng các hàm của kẻ tấn công. Trong thực tế, chỉ cần sửa syscall table
- nơi chứa địa chỉ của các lệnh gọi hệ thống.
Hàm get_syscall_table_bf():
Hàm này dùng để lấy địa chỉ của bảng syscall.
module_hide():
Chức năng này dường như được thiết kế để ẩn mô-đun khỏi danh sách mô-đun hạt nhân Linux. Theo link để hiểu thêm
prev
và next
trỏ đến cấu trúc list_head
, đại diện cho một nút trong danh sách liên kết.module_hidden
để chỉ ra mô-đun bị ẩn.Chương trình thực hiện lấy địa chỉ của 3 hàm getdents
getdents64
kill
và thay thế địa chỉ đó bằng các hàm custom.
Đoạn mã khá dài nên mình không upload đoạn mã lên mà tiến hành mô tả từng hàm custom:
hacked_getdents và hacked_getdents64
- Hàm này thay đổi hành vi của hàm getdents. Nó cấp phát bộ nhớ cho một biến v5 và kiểm tra vùng nhớ vừa được cấp. Sau đó, sao chép dữ liệu từ User-space và Kernel-space. Xử lý dữ liệu trả về từ hàm gốc getdents. Cuối cùng, hàm này giải phóng bộ nhớ được cấp phát và trả về kích thước của dữ liệu đã được xử lý. Đọc tại đây để biết thêm chi tiết kĩ thuật https://github.com/m0nad/Diamorphine/blob/masterLà một rootkit, tôi tìm rootkit source. Ta cần cũng tìm thấy một số lệnh để vô hiệu hóa rootkit. Tôi nhận ra rằng mục tiêu của chúng tôi là hiển thị tệp máy chủ để chúng tôi có thể nhận được cờ.
hacked_kill()
- cho phép ta tắt tính năng "hidden" các moduleQuá trình đầu tiên:
"kill -46 0" thao tác này sẽ "tắt khả năng tàn hình" rootkit khiến nó hiển thị. Đọc để hiểu thêm.Quy trình thứ hai:
kill -64 0
nó sửa đổi thông tin xác thực kernel bằng cách sử dụng các hàm prepare_creds
và commit_creds
, đặt một số trường nhất định thành 0. Lưu ý rằng việc sử dụng struct cred
để đặt giá trị UID và GID thành 0 không đảm bảo tiến trình sẽ trở thành root. Nếu các giá trị khác như EUID, SUID, FSUID cũng không được đặt thành 0 thì quyền truy cập có thể vẫn khác với quyền root.Quy trình thứ ba:
kill -31 0
bỏ ẩn bất kỳ tiến trình nào, kill -<num> 0
đang thực hiện orig_kil()
Lệnh lsmod
được sử dụng để hiển thị danh sách các mô-đun hạt nhân đang được tải trong hệ thống.
Ta thực hiện rmmod diamorphine
vì trạng thái các module trong Linux Kernel vẫn diamorphine
, chúng ta phải gỡ bỏ nó và hiển thị tất cả các file. Từ đó ta truy cập hệ thống với người dùng đang đăng nhập là root
The famous hacker Script K. Iddie has finally been caught after many years of cybercrime. Before he was caught, he released a server sending mysterious data, and promised his 0-days to anyone who could solve his multi-level hacking challenge. Now everyone is in an ARMs race to get his exploits. Can you be the one to solve Iddie's puzzle?
Khi kết nối Instance, ta được truy cập đến trang web với nội dung là mã Hex.
Ta đang ở Level 1/50, ta có thể dự đoán rằng khi ta vượt qua 50 level thì ta nhận được flag. Ngoài ra, chuỗi hexa ta cung cấp có thể tạo thành các câu lệnh của ARM. Nó yêu cầu ta tính toán thanh ghi R0 của các câu lệnh ARM ấy. Ta sẽ cần sử dụng socket
để kết nối đến địa chỉ được cấp, cũng như gửi kết quả tính được của thanh ghi R0. Các trường hợp khi ta kết nối:
Timeout! You took too long to provide input.
- khi kết quả gửi chậm.Value not recognized
- khi kết quả gửi không phải là hex.Wrong answer
- khi kết quả gửi không đúng.Level */50:
- kết quả đúng và qua level kế tiếp.Ta viết chương trình để kết nối đến địa chỉ IP được cấp và thực hiện tính toán. Lưu ý:
mov
, movw
, movt
được sử dụng không có quy luật.CF
không có gây ảnh hưởng đến các phép tính có dấu.Phiên bản tốt hơn của đoạn mã