OffenSive Csharp Development Part1

2021-04-01 14:16:55 浏览数 (1)

写在前面:

公众号偶尔会发广告的时,想必老粉丝已经习惯了,一些新朋友可能有一些对广告有一些误解,广告标题、内容皆为投放商所定,如果觉得广告浪费时间大家可以不点进来,如果想赞助一下,可以点进来看一看,但请不要因为一个广告就在后台留言狂怼,所有的热爱都是在生活的前提上的,感谢理解。

该系列文章将简单的介绍Csharp在渗透测试中的使用方法,主要为win32的使用以及一些库的调用。本文为第一篇文章,将以一个dump lsass进程的程序为例,介绍Csharp的简单使用,文章不会介绍Csharp基础性的东西,对此有兴趣的可以移步微软官方文档,或各类Csharp基础教学书籍、视频进行学习。

win32的调用

在整个Csharp的使用过程中,最重要的就是win32的调用,由于Csharp不向C/C 可以直接调用win32api进行使用,所以我们一般使用一种叫做P/Invoke的方法在DLL中使用win32api。具体可参考官方文档:https://docs.microsoft.com/en-us/archive/msdn-magazine/2003/july/net-column-calling-win32-dlls-in-csharp-with-p-invoke

其基本调用形式可以参考下面的使用:

代码语言:javascript复制
[DllImport("User32.dll")] static extern Boolean MessageBeep(UInt32 beepType);

其数据类型的转换如下表:

windows数据类型的转换如下:

其他类表

那么如果一个一个的来进行修改无非是费时费力的,这里我们一般使用一个叫做http://www.pinvoke.net/的网站来帮我们实现api的调用过程,当然其也支持vs插件。比如我们需要一个messagebox的api,就可以直接在该网站上搜索该api

其给出了C#以及VB的调用方法,C#的调用方法如下:

代码语言:javascript复制
[DllImport("user32.dll", SetLastError = true, CharSet= CharSet.Auto)]
public static extern int MessageBox(int hWnd, String text, String caption, uint type);

下面我们新建一个Csharp程序,然后来使用这个API。记得加入using System.Runtime.InteropServices;因为DllImport是System.Runtime.InteropServices命名空间下的一个属性类,其功能是提供从非托管DLL导出的函数的必要调用信息。

然后放入我们的代码并调用它:

代码语言:javascript复制
using System;
using System.Timers;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;

namespace Basic3
{

    class Program 
    {
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern int MessageBox(int hWnd, String text, String caption, uint type);
        static void Main(string[] args) {
            MessageBox(0, "Hello World!", "Hello Dialog", 0);
        }
    }
}

执行,成功弹框。

SharpDump

知道了如何调用win32,下面我们来编写一个dumplsass进程的小程序。dumplsass进程网上有很多的demo,其实更多的还是在使用MiniDumpWriteDump来进行内存dump,其原型如下:

代码语言:javascript复制
BOOL MiniDumpWriteDump(
  HANDLE                            hProcess,
  DWORD                             ProcessId,
  HANDLE                            hFile,
  MINIDUMP_TYPE                     DumpType,
  PMINIDUMP_EXCEPTION_INFORMATION   ExceptionParam,
  PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
  PMINIDUMP_CALLBACK_INFORMATION    CallbackParam
);

那么这时候我们便可以用之前说的方法来调用这个api来进行使用了。之前的调用方法我们一般称为托管 调用 非托管,关于一些名词的解释请自行百度,这里不再过多解释。除了之前的方法还有一种就是调用UnmanagedFunctionPointer以获得自定义调用约定。一般用以回调函数。

代码语言:javascript复制
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public static delegate {callback};

那我们就可以这样来写

代码语言:javascript复制
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate bool  MiniDumpWriteDump(IntPtr hProcess, uint ProcessId, SafeHandle hFile, int DumpType, IntPtr ExceptionParam, IntPtr UserStreamParam, IntPtr CallbackParam);

一般的此类函数的调用方法如下:

代码语言:javascript复制
var MyFunctionPointer = (DMyUserCallFunction)Marshal.GetDelegateForFunctionPointer(AddressOfFunction, typeof(DMyUserCallFunction));

那我们这里便是:

代码语言:javascript复制
IntPtr createPtr = GetProcAddress(LoadLibrary("Dbghelp.dll"), "MiniDumpWriteDump");
MiniDumpWriteDump miniDumpWriteDump = (MiniDumpWriteDump)Marshal.GetDelegateForFunctionPointer(createPtr, typeof(MiniDumpWriteDump));

GetProcAddress、LoadLibrary可以这样导入:

代码语言:javascript复制
//import Win32API
        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern IntPtr LoadLibrary(string dll);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern IntPtr GetProcAddress(IntPtr hModule, string name);

下面就是查找进程的问题了,Csharp提供了Process类,可以直接使用进程名称或者进程ID来进行查找:

代码语言:javascript复制
Process.GetProcessById

最后就是MINIDUMP_TYPE的问题了,这个关系到dump时如何dump的问题,其原型如下:

代码语言:javascript复制
typedef enum _MINIDUMP_TYPE {
  MiniDumpNormal,
  MiniDumpWithDataSegs,
  MiniDumpWithFullMemory,
  MiniDumpWithHandleData,
  MiniDumpFilterMemory,
  MiniDumpScanMemory,
  MiniDumpWithUnloadedModules,
  MiniDumpWithIndirectlyReferencedMemory,
  MiniDumpFilterModulePaths,
  MiniDumpWithProcessThreadData,
  MiniDumpWithPrivateReadWriteMemory,
  MiniDumpWithoutOptionalData,
  MiniDumpWithFullMemoryInfo,
  MiniDumpWithThreadInfo,
  MiniDumpWithCodeSegs,
  MiniDumpWithoutAuxiliaryState,
  MiniDumpWithFullAuxiliaryState,
  MiniDumpWithPrivateWriteCopyMemory,
  MiniDumpIgnoreInaccessibleMemory,
  MiniDumpWithTokenInformation,
  MiniDumpWithModuleHeaders,
  MiniDumpFilterTriage,
  MiniDumpWithAvxXStateContext,
  MiniDumpWithIptTrace,
  MiniDumpScanInaccessiblePartialPages,
  MiniDumpValidTypeFlags
} MINIDUMP_TYPE;

这里我们如果定义成MINIDUMP_TYPE类型,那么我们将需要把这些内容全部自己定义出来,而我们刚才把其定义成立Int,此时则只需要给其传递一个2进去即可,即表示完整dump。

最后效果如下:

当然这个程序还是又很多其他的问题的,比如还可以加入自动提权等等。最后的代码可以在这里找到:https://github.com/lengjibo/OffenSiveCSharp

下一篇文章中,将会介绍如何将UUID免杀法转换成Csharp程序,并引出Csharp的公开调用Api的库。

0 人点赞