吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 12619|回复: 23
收起左侧

[原创] 对某校园网跨域软件的逆向分析和重实现

  [复制链接]
BlackNWhite 发表于 2015-8-27 19:55
上学期校园网里突然流行起一款免费的跨域软件(威皮恩),速度非常不错,下载能达到1M/S,但是只能在校园网范围内使用。
最近放假在家,想要翻墙下一款软件,苦于找不到好的威皮恩,所以就想到是不是能把校园网的跨域软件弄到家里来用用。

用DIE查看程序的编写语言和加壳情况(对于壳和混淆的分析我还是新手,只能靠工具,还得加油学习)
1.jpg


发现程序使用.NET服务框架写的,用.NET Reactor加的壳。考虑脱壳后反编译试试。

De4Dot对.NET Reactor的脱壳效果一向不错,考虑直接用它试试
2.jpg

(为了尊重程序作者的权益,程序名已打码,文章中也不会出现程序名)

发现成功了,不知道脱壳玩不完全,但是可以尝试反编译了,就是不知道反编译之后的效果会怎么样。

直接上DotPeek试试
3.jpg

发现反编译后的代码特别干净整齐,应该是成功了,既然反编译成功了,我也就不甘于之解决校园网外的连接问题了。
由于改程序在连接威皮恩时没有要求输入用户凭证,是一键式连接的,怀疑在程序中存有服务器信息和账号密码信息。

上面两款软件已经帮我把它的代码还原得这么干净整齐了,我当然不能浪费了这个资源。

怀疑程序作者在写程序的时候方法使用了"connect"字样,直接搜索试试,得到了下面的代码块:
4.jpg


发现服务器地址了:"jp" + MainWindow.fastest_server.ToString() + ".toven.info"
怀疑程序在启动的时候ping了一下威皮恩服务器,然后按延迟排序,选了延迟最小的服务器来连接。
按格式来看,不用找fastest_server变量了,它肯定是int型。那么按这个格式ping一下服务器试试:

5.jpg

ping到"jp9.toven.info"的时候发现ping不通了,那么怀疑服务器是"jp1"到"jp8"。

这时候服务器地址也有了,只差账服务器的连接凭证了,再在源码中找找,搜"user"和"pass"字符居然一时半会没找到账号密码。
耐下心来,从头开始找,发现了这么个东西:
6.jpg

看到链接中有"reg.php"和"user"的字符,怀疑是通过程序向reg.php页面发送了http请求申请了一个账号,那么打开链接试试:
7.jpg

打开发现是这么个页面,发现注册不用填写验证码,而且“初始预付服务”中有“免费账户”的选项。随便注册一个免费账户后发现免费用户是三十分钟的试用时间,用完之后就只能付费使用了。

这时候能得出结论了:这个校园网跨域软件用的不是用自己的服务器,而是别人威皮恩产品提供的试用服务,通过HTTP请求申请账号(申请账号不要求填写验证码,这个实现起来非常简单),三十分钟一断,断开之后再申请一个,重新连接。

得出这个结论之后,我决定利用作者的成果来写一个自己用的威皮恩(其实是用了别人的服务器)

查看网页的元素发现表单的命名也非常规则,得出了申请账号的post格式:
[Asm] 纯文本查看 复制代码
http://user.tosver.cn/reg.php?cont=store_user&lang=Chinese&username=用户名&password1=密码&password2=再次输入密码&mobile&email&srvid=1&textarea=%E6%8F%90%E7%A4%BA%EF%BC%9A%E8%AF%B7%E4%BB%94%E7%BB%86%E9%98%85%E8%AF%BB%E4%BB%A5%E4%B8%8B%E6%9D%A1%E6%AC%BE%EF%BC%8C%E5%86%8D%E6%B3%A8%E5%86%8C%E5%B8%90%E5%8F%B7%E3%80%82%E4%BD%BF%E7%94%A8%E6%9C%AC%E7%BD%91%E7%AB%99%E8%A1%A8%E7%A4%BA%E6%82%A8%E5%90%8C%E6%84%8F%E9%81%B5%E5%AE%88%E8%BF%99%E4%BA%9B%E6%9D%A1%E6%AC%BE%E5%92%8C%E6%9D%A1%E4%BB%B6%E3%80%82%E5%A6%82%E6%9E%9C%E6%82%A8%E4%B8%8D%E6%8E%A5%E5%8F%97%E8%BF%99%E4%BA%9B%E6%9D%A1%E6%AC%BE%EF%BC%88%E2%80%9C%E6%9D%A1%E6%AC%BE%E2%80%9D%EF%BC%89%EF%BC%8C%E8%AF%B7%E5%8B%BF%E6%B3%A8%E5%86%8C%E3%80%82&acceptterms=1&adduser=%E5%88%9B%E5%BB%BA%E8%B4%A6%E6%88%B7


username参数是用户名,password1是密码,password2是确认密码输入,srvid是用户类型,1是免费用户,然后是一大串用户协议之类的内容(不知道这个参数有没有必要,总是先弄上去),acceptterms是接受用户协议,给它传递个1应该就是接受了吧。

随便弄一个用户名和密码用postman来post这个页面发现返回了注册成功的页面
8.jpg

那么现在就能写一个程序来方便以后使用了。

9.jpg

界面就这样吧,毕竟是自己用的简易威皮恩

接下来实现账号密码申请功能:

先是post方法:
[C#] 纯文本查看 复制代码
public static string PostWebRequest(string postUrl, string paramData, Encoding dataEncode)
{
    string ret = string.Empty;
    try
    {
        byte[] byteArray = dataEncode.GetBytes(paramData); 
        HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(new Uri(postUrl));
        webReq.Method = "POST";
        webReq.ContentType = "application/x-www-form-urlencoded";
 
        webReq.ContentLength = byteArray.Length;
        Stream newStream = webReq.GetRequestStream();
        newStream.Write(byteArray, 0, byteArray.Length);
        newStream.Close();
        HttpWebResponse response = (HttpWebResponse)webReq.GetResponse();
        StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.Default);
        ret = sr.ReadToEnd();
        sr.Close();
        response.Close();
        newStream.Close();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        return "Error";
    }
    return ret;
}


然后是账号密码部分:
用一串10位的随机数来填充账号部分,短时间内应该不会有重复的用户名:
[C#] 纯文本查看 复制代码
private string CreateUsername()
{
    string username = "crac";
    Random random = new Random();
 
    for (int i = 0; i < 10; ++i)
    {
        username += random.Next(0, 9).ToString();
    }
 
    return username;
}



密码就随便在键盘上敲一下吧,就用dsDW4er2342

然后是账号密码申请方法:
[C#] 纯文本查看 复制代码
public bool Register()
{
    string password = "dsDW4er2342";
    string username = CreateUsername();
 
    string postUrl = "http://user.tosver.cn/reg.php";
    string usernamePart = "cont=store_user&lang=Chinese&username=" + username + "&";
    string passwordPart = "password1=" + password + "&password2=" + password + "&";
    string otherPart = "mobile&email&srvid=1&textarea=%E6%8F%90%E7%A4%BA%EF%BC%9A%E8%AF%B7%E4%BB%94%E7%BB%86%E9%98%85%E8%AF%BB%E4%BB%A5%E4%B8%8B%E6%9D%A1%E6%AC%BE%EF%BC%8C%E5%86%8D%E6%B3%A8%E5%86%8C%E5%B8%90%E5%8F%B7%E3%80%82%E4%BD%BF%E7%94%A8%E6%9C%AC%E7%BD%91%E7%AB%99%E8%A1%A8%E7%A4%BA%E6%82%A8%E5%90%8C%E6%84%8F%E9%81%B5%E5%AE%88%E8%BF%99%E4%BA%9B%E6%9D%A1%E6%AC%BE%E5%92%8C%E6%9D%A1%E4%BB%B6%E3%80%82%E5%A6%82%E6%9E%9C%E6%82%A8%E4%B8%8D%E6%8E%A5%E5%8F%97%E8%BF%99%E4%BA%9B%E6%9D%A1%E6%AC%BE%EF%BC%88%E2%80%9C%E6%9D%A1%E6%AC%BE%E2%80%9D%EF%BC%89%EF%BC%8C%E8%AF%B7%E5%8B%BF%E6%B3%A8%E5%86%8C%E3%80%82&acceptterms=1&adduser=%E5%88%9B%E5%BB%BA%E8%B4%A6%E6%88%B7";
 
    if (PostWebRequest(postUrl, usernamePart + passwordPart + otherPart, Encoding.UTF8).IndexOf("账户已经创建") != -1)
    {
        this.username = username;
        this.password = password;
        return true;
    }
    else
    {
        postUrl = "http://user.tovens.com/reg.php";
        if (PostWebRequest(postUrl, usernamePart + passwordPart + otherPart, Encoding.UTF8).IndexOf("账户已经创建") != -1)
            return true;
        else
            return false;
    }
}


我将它们写在了一个类中,类中有public string型的username和password属性,构造方法中调用Register()方法,
若Register方法返回True则该类对象可用,若返回False则username和password属性为null,该对象不可用。

接下来用DotRas库来实现威皮恩连接功能,这里用到了别人写的VPNHelper类,用来辅助调用DotRas库的方法来创建和链接威皮恩。我重载了一个构造方法,使它接受一个UsernameKeeper类对象(就是上面写的用来申请账号的类)来初始化vpnHelper类对象的账号密码以连接威皮恩。
这个类就不贴出来了,代码太长。

直接到创建和链接威皮恩部分:
[C#] 纯文本查看 复制代码
private void buttonConnect_Click(object sender, EventArgs e)
{
        UsernameKeeper usk = new UsernameKeeper();
        vpnHelper = new VPNHelper("jp1.toven.info", "EasyVPN", usk);
 
       vpnHelper.CreateOrUpdateVPN();
    vpnHelper.TryConnectVPN();
}


然后就搞定了,以后就能在任何地方一键连接威皮恩了。至于半小时断一次的解决方案,我认为每20s ping一次twitter.com是可行的,如果Ping不通的话就断开重连。
为了使文章不过于冗长,就先不实现更多功能了。

至此,整个过程结束。

(由于规定,我就不放出原校园网跨域软件和编译后的威皮恩及完整源码了,只分享思路和一小部分关键部分的C#语言实现,有兴趣的朋友可以自己用任何其他的语言将其完整实现写出来)

免费评分

参与人数 6威望 +2 热心值 +6 收起 理由
daohang + 1 谢谢@Thanks!
azuresky0819 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩.
gqdsc + 1 很详细,但是被玩坏了
XhyEax + 1 经我测试,那个postdata里的很多参数都可以.
纷飞雨雪 + 1 我很赞同!
Hmily + 2 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩.

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

XhyEax 发表于 2015-8-28 16:52
然而网址还是没打码。。。。

楼主,经我测试,那个postdata里的很多参数都可以不带,进行注册。
只需要一下参数:
username=&password1=&password2=&srvid=1&acceptterms=1
///依次是:用户名  密码 重复密码 服务id(1为免费) 是否接受条款(1为接受)
 楼主| BlackNWhite 发表于 2015-9-16 12:50
blueshell1949 发表于 2015-9-9 16:28
请问楼主,怎么样才可以反编译得到源码呀?新手求问。谢谢您

.net程序可以用DOTPEEK或.net reflector等工具实现,C++没有一个好的办法,逆向一般通过OD等调试工具实现
轻狂书生 发表于 2015-8-28 17:29
xiaogao66 发表于 2015-8-28 20:37 来自手机
好东西,
720830 发表于 2015-8-29 00:49 来自手机
看完了,期待发出来
海风爸爸 发表于 2015-8-29 09:30
太厉害了啊  佩服的五体投地啊
 楼主| BlackNWhite 发表于 2015-8-29 10:18 来自手机
XhyEax 发表于 2015-8-28 16:52
然而网址还是没打码。。。。

楼主,经我测试,那个postdata里的很多参数都可以不带,进行注册 ...

哦哦,好的,感谢测试   (^_^)
 楼主| BlackNWhite 发表于 2015-8-29 10:23 来自手机
720830 发表于 2015-8-29 00:49
看完了,期待发出来

不能发,是违规的。
实现的思路和原理应该不难,照上面的自己实现一下就能用了
头像被屏蔽
灬小数学 发表于 2015-8-29 14:53 来自手机
提示: 作者被禁止或删除 内容自动屏蔽
犭王人曰女支 发表于 2015-8-29 16:42
学习了!!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-17 17:35

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表