您的位置:首页 > 理论基础 > 计算机网络

crackmenet1 网络验证破解之入门级

2015-04-28 16:45 190 查看
前言: 今天无聊的很,看到看雪很早以前的一篇文章,手痒,加上很久没写什么技术文章了,入门级又简单写,为了给自己多加篇日志隧写此文,大牛就不必浪费时间看了

感谢:
crackmenet1作者 riijj 、 看雪论坛平台

原贴地址: http://bbs.pediy.com/showthread.php?t=32100
难度: 入门级

作者批注: 这是一个网络验证的 crackme,两个档案分别是 crackme 和 server,操作方法是,先运行 server,然后运行 crackme。这个 crackme 是十分容易的入门级,新手
可以尝试爆破,或找出正确序号。

要求: 这个 crackme 理论上没有 keygen ,但是兄弟们可以试试,不调试 server 程序(假设自己触摸不到 server 程序真身)只从crackme的结构分析,写出一个可 以替代
真正server的“伪server程序”如果能够使用自己的“伪server程序”成功完成注册的话(任何注册名字都成功),那便算是这个crackme的完美破解

解:

直接将 crackmenet1.exe 托入IDA Pro 看关键算法



流程:

1、 取注册名,计算其各个字节的和总值(范围不超过char) ,最后得到异或运算的 keyValue

2、将服务器返回的值前6字节与 keyValue 进行异或运算,得到比较值 cmpRes

3、用 cmpRes 与 "CHKPS" 进行字符串对比,相等则成功

破解思路:

1、以客户端同算法算出注册名的异或关键值

2、发送异或后的"CHKPS"

实现代码:

#include "stdafx.h"
#include <WinSock2.h>
#include <windows.h>

#pragma comment(lib, "Ws2_32.lib")

int _tmain(int argc, _TCHAR* argv[])
{
// MSDN copy listen Example Code
WSADATA wsaData;
int iResult = 0;
SOCKET ListenSocket = INVALID_SOCKET;
sockaddr_in service;
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
wprintf(L"Error at WSAStartup()\n");
return 1;
}
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ListenSocket == INVALID_SOCKET) {
wprintf(L"socket function failed with error: %u\n", WSAGetLastError());
WSACleanup();
return 1;
}
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr("127.0.0.1");
service.sin_port = htons(8877);
iResult = bind(ListenSocket, (SOCKADDR *)&service, sizeof (service));
if (iResult == SOCKET_ERROR) {
wprintf(L"bind failed with error %u\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
else
wprintf(L"bind returned success\n");

if (listen(ListenSocket, SOMAXCONN) == SOCKET_ERROR)
wprintf(L"listen function failed with error: %d\n", WSAGetLastError());
// 下面开始关键算法计算
fd_set readfds;
while ( true )
{
char name[24] = { 0 };
char regkey[24] = { 0 };

readfds.fd_array[0] = ListenSocket;
readfds.fd_count = 1;
iResult = select(NULL, &readfds, NULL, NULL, NULL);
int aptFD = accept(ListenSocket, NULL, NULL);

recv(aptFD, name, 20, 0);
recv(aptFD, regkey, 20, 0);
Sleep(500);
// 根据客户端逆出来的算法计算异或的key值
UCHAR orKey = 1;
int namelen = strlen(name);
for (int i = 0; i < namelen; ++i)
orKey += name[i];
// 计算异或后的返回值
CHAR reskey[6] = { "CHKPS" };
for (int i = 0; i < 6; ++i)
reskey[i] ^= orKey;
send(aptFD, reskey, 6, 0);
}
closesocket(ListenSocket);
WSACleanup();
return 0;
}


运行伪server后任何注册都将成功,效果图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: