分享
 
 
 

最新版 URTracker 2.11版 license验证原理剖析- -

王朝other·作者佚名  2006-01-10
窄屏简体版  字體: |||超大  

注 :原创,转载请注明出处。

作 者:草惜草

首 发: http://kokey.blogchina.com

序言:

看了henryouly的文章以后深受启发,决定对URTracker最新的版本来个剖析。在此,特别感谢henryouly!

×××××××××××××××××××××××××××××××××××××××××××××

URTracker事务跟踪系统是一款功能强大而且易于使用的Web方式的协同工作软件 。它用于帮助公司和团队跟踪工作中的问题,管理和记录这些问题的处理过程。

URTracker向您的团队提供了一个全功能的,高度可定制的软件工具用于报告和跟踪问题、需求、缺陷(BUG)或者任务等事务。它拥有丰富的自定义字段、基于项目和角色的权限控制、简化的工作流、友好的用户界面,以及更多的其他特性。我们非常确信您将会喜欢上URTracker,因为我们相信她正是您所需要的。

××××××××××××××××××××××××××××××××××××××××××××

工具介绍:

要研究.NET当然离不开Reflector for .NET 。(Reflector is a class browser for .NET components. It supports assembly and namespace views, type and member search, XML documentation, call and callee graphs, IL, Visual Basic, Delphi and C# decompiler, dependency trees, base type and derived type hierarchies and resource viewers. )

如果想把代码保存下来,那就需要Reflector的插件Reflector.FileDisassembler了。(The Reflector.FileDisassembler is a little add-in for the new version of Lutz Roeder's .NET Reflector that you can use to dump the decompiler output to files of any Reflector supported language (C#, VB.NET, Delphi). This is extremely useful if you are searching for a specific line of code as you can use VS.NET's "Find in Files" or want to convert a class from one language to another.

下载地址:Reflector for .NET http://www.aisto.com/roeder/dotnet/

Reflector.FileDisassembler http://www.denisbauer.com/NETTools/FileDisassembler.aspx

正文:

严重声明:本文只作科研和学习用途。如果由本文产生的法律纠纷,一概与本人无关。

好了,了解了Reflector咱们就可以动手研究URTracker了。

当然首先用Reflector分析bin文件夹下的文件,一共有12个DLL文件,从他们的名称你也可以猜出个八八九九,反正你不怕麻烦你就挨个用Reflector试好了...^_^

最后找到了WebTracker.dll 可疑,因为在Reflector按F3,你可以搜索到很多关于license的东东。哈哈,探究之路开始了。

首先看看Lealsoft.URTracker.BLL下有个ServerLicenseProvider类。

public class ServerLicenseProvider : LicenseProvider

{

// Methods

static ServerLicenseProvider();

public ServerLicenseProvider();

protected virtual ServerLicense CreateEmptyLicense(Type type);

protected virtual ServerLicense CreateLicense(Type type, string key);

public override License GetLicense(LicenseContext context, Type type, object instance, bool allowExceptions);

protected virtual string GetLicenseData(Type type);

protected virtual Stream GetLicenseDataStream(Type type);

protected virtual bool ValidateLicense(ServerLicense license, out string errorMessage);

protected virtual bool ValidateLicenseData(Type type, string licenseData);

// Fields

private static readonly ServerLicenseCollector LicenseCollector;

// Nested Types

private sealed class ServerLicenseCollector

{

// Methods

public ServerLicenseCollector();

public void AddLicense(Type objectType, ServerLicense license);

public ServerLicense GetLicense(Type objectType);

public void RemoveLicense(Type objectType);

// Fields

private IDictionary _collectedLicenses;

}

}

看到没,有几个CreateLicense,GetLicense,ValidateLicense ,ValidateLicenseData,GetLicenseDataStream这几个方法。好,打开看看都是什么东东。

protected virtual ServerLicense CreateLicense(Type type, string key)

{

char[] chArray1 = new char[1] { ':' } ;

string[] textArray1 = key.Split(chArray1);

return new URTrackerLicense(type, key, long.Parse(textArray1[1], CultureInfo.InvariantCulture), long.Parse(textArray1[2], CultureInfo.InvariantCulture), textArray1[3], long.Parse(textArray1[4], CultureInfo.InvariantCulture), long.Parse(textArray1[5], CultureInfo.InvariantCulture), textArray1[6]);

}

哇!就是新建license,URTrackerLicense后面有几个参数,什么也看不出,感觉是要用":"split开一个字符串。来,打开URTrackerLicense构造函数看看。

public URTrackerLicense(Type type, string key, long startTicks, long ticks, string username, long userIndex, long clientCount, string mac) : base(type, key)

{

this._foundMac = false;

this._ticks = ticks;

this._startTicks = startTicks;

this._username = username;

this._userIndex = userIndex;

this._clientCount = clientCount;

this._mac = mac;

this._macArray = URTrackerLicense.GetMacArray();

this._foundMac = this._macArray.IndexOf(this._mac) > -1;

}

哦,看到ticks,startTicks,username,userIndex,clientCount,mac

难道这些就是所需参数"到期时间,使用开始时间,用户名,用户名索引,用户数,本机网卡地址"

有点意思了。呵呵。

找到了 URTrackerLicense 类,你就会知道我们猜测的没有错了。

public class URTrackerLicense : ServerLicense

{

// Methods

public URTrackerLicense(Type type, string key, long startTicks, long ticks, string username, long userIndex, long clientCount, string mac);

public static ArrayList GetMacArray();

// Properties

public long ClientCount { get; }

public bool IsExpired { get; }

public string Mac { get; }

public long StartTicks { get; }

public long Ticks { get; }

public long UserIndex { get; }

public string Username { get; }

// Fields

private long _clientCount;

private bool _foundMac;

private string _mac;

private ArrayList _macArray;

private long _startTicks;

private long _ticks;

private long _userIndex;

private string _username;

}

继续,刚才找了CreateLicense,现在开始找ValidateLicenseData。

protected virtual bool ValidateLicenseData(Type type, string licenseData)

{

bool flag1 = false;

char[] chArray1 = new char[1] { ':' } ;

string[] textArray1 = licenseData.Split(chArray1);

if (textArray1.Length == 7)

{

return (string.Compare("URTracker1Licensed", textArray1[0], true, CultureInfo.InvariantCulture) == 0);

}

return flag1;

}

哈哈,就是说刚才分析那个数组中textArray1[0],必须是URTracker1Licensed!哈哈,这也进一步证实了我们要把注册信息字符串用":"分开的设想。

Come on!离成功越来越近了!接着分析ValidateLicense。

protected virtual bool ValidateLicense(ServerLicense license, out string errorMessage)

{

errorMessage = null;

URTrackerLicense license1 = (URTrackerLicense) license;

if (license1.IsExpired)

{

errorMessage = "The License has expired.";

return false;

}

return true;

}

哦,知道了!原来是判断URTrackerLicense的属性IsExpired的真假!好,咱们看看属性IsExpired。

public bool IsExpired

{

get

{

if ((DateTime.Today.Ticks <= this._ticks) && (DateTime.Now.Ticks >= this._startTicks))

{

return !this._foundMac;

}

return true;

}

}

知道了吧!就是判断当前时间要在ticks和startTicks之间!然后再判断Mac的值。

现在查找Mac的相关类或者方法。找到了GetMacArray

public static ArrayList GetMacArray()

{

ManagementClass class1 = new ManagementClass("Win32_NetworkAdapterConfiguration");

ManagementObjectCollection collection1 = class1.GetInstances();

ArrayList list1 = new ArrayList();

using (ManagementObjectCollection.ManagementObjectEnumerator enumerator1 = collection1.GetEnumerator())

{

while (enumerator1.MoveNext())

{

ManagementObject obj1 = enumerator1.get_Current();

if ((bool) obj1.get_Item("IPEnabled"))

{

list1.Add(obj1.get_Item("MacAddress").ToString().Replace(":", "").ToUpper());

}

obj1.Dispose();

}

}

return list1;

}

咱们从这里可以猜测的出,获得的Mac应该是去掉":" 如:01:AB:9E:6T:AB:9E:6T (注意了,是要大写的!)

对照URTrackerLicense的构造函数,我们就明白各字段的含义了。也可以构造出一个伪license。我随便构造一个,

string data = "URTracker1Licensed:632598806976562500:735608407859509835:CaoxiCao:0:1000:0:AB9E6TAB9E6T";

注意一下那两个ticks字段,需要把当前的ticks时间包含起来才行,否则IsExpired会判断为true的

回到刚才的思路 分析完 CreateLicense,GetLicense,ValidateLicense ,ValidateLicenseData。现在开始分析GetLicenseDataStream

protected virtual Stream GetLicenseDataStream(Type type)

{

string text3 = type.Assembly.GetName().Name;

type.Assembly.GetName().Version.ToString();

string text1 = "~/licenses/URTRACKER.aspx";

string text2 = null;

try

{

text2 = HttpContext.Current.Server.MapPath(text1);

if (!File.Exists(text2))

{

text2 = null;

}

}

catch

{

}

if (text2 != null)

{

return new FileStream(text2, FileMode.Open, FileAccess.Read, FileShare.Read);

}

return null;

}

知道了,这次知道了licenses生成的地方以及名称就是URTRACKER.aspx!!!

现在只是找到了licese格式,名称和位置,但是具体算法还是没有找到。继续在Lealsoft.URTracker.BLL命名空间找。呵呵!发现个叫EncryptedLicenseProvider的类,看看

居然有个东东!眼睛一亮!

protected override Stream GetLicenseDataStream(Type type)

{

Stream stream1 = base.GetLicenseDataStream(type);

if (stream1 == null)

{

return null;

}

DESCryptoServiceProvider provider1 = new DESCryptoServiceProvider();

provider1.Key = EncryptedLicenseProvider.encryptionKeyBytes;

provider1.IV = EncryptedLicenseProvider.encryptionKeyBytes;

ICryptoTransform transform1 = provider1.CreateDecryptor();

return new CryptoStream(stream1, transform1, CryptoStreamMode.Read);

}

因为我们看到了DES!哈哈,知道了,是DES加密!

看到调用base.GetLicenseDataStream了吗?就是取得license的内容!!

而它的基类就是我们刚刚分析过的ServerLicenseProvider。

好,我们下一步搞清楚Key和IV的值。当找到这个静态构造函数时,心一下子揪了起来,成功了吗?快了!

static EncryptedLicenseProvider()

{

EncryptedLicenseProvider.encryptionKeyBytes = new byte[8] { 0x35, 0x37, 0x42, 50, 0x42, 0x31, 70, 0x36 } ;

}

^_^,终于哭了,搞清楚了DES加密啊!

可以写代码生成伪licese文家了!本来俺做了个 注册机出来的,怕太对不起作者了,暂不公布了!

把源代码公布吧!

---------------------------------------------

using System;

using System.Collections.Generic;

using System.Text;

using System.Security.Cryptography;

using System.IO;

namespace ConsoleApplication2

{

class Program

{

static void Main(string[] args)

{

byte[] encryptionBytes = new byte[8] { 0x35, 0x37, 0x42, 50, 0x42, 0x31, 70, 0x36 };

DESCryptoServiceProvider provider = new DESCryptoServiceProvider();

provider.Key = encryptionBytes;

provider.IV = encryptionBytes;

ICryptoTransform transform1 = provider.CreateEncryptor();

string data = "URTracker1Licensed:632572024003281250:735608407859509835:CaoxiCao:0:10000:0111A7C7D865";

Console.WriteLine(System.DateTime.Now.Ticks); //当前的ticks

byte[] message = Encoding.UTF8.GetBytes(data);

FileStream fs = new FileStream("c:\\URTRACKER.aspx", FileMode.Create,

FileAccess.Write, FileShare.Write);

CryptoStream cs = new CryptoStream(fs, transform1, CryptoStreamMode.Write);

cs.Write(message, 0, message.Length);

cs.Flush();

cs.Close();

fs.Close();

}

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有