挖洞经验:看我如何利用你的Kindle邮箱地址盗刷你的信用卡

阅读量    96043 |

分享到: QQ空间 新浪微博 微信 QQ facebook twitter

写在前面的话

我通过这个漏洞拿到了1.8万美元的漏洞奖金,这是一个存在于Amazon Kindle产品中的严重漏洞。

很久之前,我注意到Amazon Kindle有一个有趣的功能,叫做“发送到Kindle”。这项功能允许Kindle用户将电子书作为电子邮件附件发送到他们的设备上。我们立刻想到了这个功能潜在的安全隐患:如果我们可以向毫无戒备的用户发送恶意电子书呢?于是乎,我开始研究潜在的安全问题,果然发现了三个漏洞,它们都将允许攻击者在目标Kindle设备上实现远程代码执行。攻击者只需要知道目标设备绑定的电子邮箱地址,就可以让恶意代码将以root用户权限运行。攻击成功后,攻击者将能够访问设备凭证,并使用目标用户的信用卡在Kindle商城中买东西。攻击者可以在商城里出售电子书,然后把钱转到他们的账户上。

 

漏洞介绍

第一个漏洞允许攻击者向受目标用户的Kindle设备发送电子书。然后,第二个漏洞可以被用于在弱用户场景中解析电子书时运行任意代码。第三个漏洞允许攻击者提升权限并以root用户身份运行代码。
亚马逊已经发布了一个软件更新来解决这个问题,用户无需采取任何操作,因为他们的设备在联网后将自动更新。

 

电子书注入

那么,“发送到Kindle”这个功能的目的是什么呢?如前所述,它允许Kindle用户向他们的设备发送MOBI电子书。为此,Amazon会专门为每个用户生成一个特殊的kindle.com邮件地址。用户可以从预定义的已批准电子邮件列表中将电子书作为附件发送到此电子邮件地址,并且电子书将显示在他们的设备上。

等等,什么叫一个预先确定的地址列表?是的,电子邮件身份验证仍然没有你想象的那么普遍,由于许多电子邮件服务器仍然不支持身份验证,因此假设Amazon不会验证发件人的真实性也不无道理。
为了验证我的想法,我使用了一个电子邮件欺骗服务来伪造了一封电子邮件,并向我的设备发送一本电子书。令我惊喜的是,电子书出现在了设备上!更糟糕的是,没有迹象表明这本电子书是通过电子邮件收到的。这本电子书也出现在Kindle的主页上,封面图片由我们选择,这使得网络钓鱼攻击变得更加容易。
对于这个功能的安全性,Amazon设置了一个目标邮件地址,攻击者必须拿到这个电子邮件地址。但是,这只是用户在kindle.com域名上注册的一个普通邮件,比如说,把name@gmail.com变成了name@kindle.com。某些用户还会在name后面追加随机字符串,比如说name_<random_string>@kindle.com。但大多数地址的熵似乎很低,而且可以暴力破解。虽然现在注册的新用户地址最大熵为32位,但这仍然不够。

 

Kindle固件逆向分析

现在有了一种将电子书发送到任何Kindle设备的方法,我需要找到一种利用电子书执行代码的方法。为此,我在(当时最新的)Kindle固件版本5.13.2上对图书解析代码进行了逆向分析。我们可以使用KindleTool从固件更新文件中提取文件系统,我也有一个旧的已越狱的Kindle PaperWhite 3。它允许我使用固件附带的gdb二进制文件调试任何进程(真是个惊喜!),除此之外我还使用Ghidra对ARM32二进制文件进行了逆向分析。
在查看固件上的各种库时,有一个库引起了我的注意,即libjpegXR.so。它似乎会解析一种名为jpegXR的模糊图像格式,这就是一个完美的攻击面!

 

JPEG XR漏洞分析

JPEG XR是最初由Microsoft开发的图像格式标准,Kindle在解析最新的Kindle文件格式KFX时支持这种格式。我试着寻找其他支持JPEG-XR的代码,竟然发现集成的Web浏览器也支持这种格式。Web浏览器就很合适了,因为MOBI文件支持Web链接(它们甚至在视觉上与TOC链接完全相同),所以点击书中的链接就会打开Web浏览器。

量化参数(Quantization Parameters)缓冲区溢出

为此,我研究了JPEG XR标准的【官方参考代码】。我注意到了jxr_priv.h中定义的jxr_image结构体:

unsigned char dc_quant_ch[MAX_CHANNELS];
unsigned char lp_quant_ch[MAX_CHANNELS][MAX_LP_QPS];
unsigned char hp_quant_ch[MAX_CHANNELS][MAX_HP_QPS];

这些被称为“量化参数(Quantization Parameters)”。r_parse.c文件中实现的函数_jxr_r_TILE_HEADER_HIGHPASS会使用图像文件中提供的数据来填充hp_quant_ch。拷贝的数据长度在image->num_channels中定义,这部分内容也由图片文件提供。缓冲区大小是一个常量(MAX_CHANNELS=16),所以这里就可能存在缓冲区溢出问题了。

引用代码通过检查num_channels的值是否小于MAX_CHANNELS(断言)来预防这种问题,然后我用Ghidra分析了libjpegXR.so来看看具体的实现方式。但是,Kindle的开发者大部分都是直接引用了官方代码,却并没有在其中设置任何的断言!这样一来,在Kindle中解析JPEG-XR时,都会出现缓冲区溢出问题。

 

漏洞利用

在jxr_image结构体中,有一个struct jxr_tile_qp tile_quant指针,函数_jxr_r_TILE_HEADER_HIGHPASS会将hp_quant_ch拷贝至该指针:

memcpy(image->tile_quant[ty(image->tile_columns) + tx].hp_quant_ch, image->hp_quant_ch, MAX_CHANNELS*MAX_HP_QPS);

因此,通过缓冲区溢出,tile_quant可以被重写并包含一个绝对写入原语(将攻击者控制的数据写入攻击者控制的地址)。_jxr_r_TILE_HEADER_HIGHPASS的调用次数由image->tile_columns和image->tile_row定义,这些数据也有图片文件提供。因此,绝对写入原语可以在一个图片文件中使用多次。
现在,我们看看Web浏览器进程mesquite的内存映射:

00008000–000a0000 r-xp 00000000 b3:01 1939 /usr/bin/mesquite
000a0000–000a2000 rwxp 00098000 b3:01 1939 /usr/bin/mesquite
000a2000–002b8000 rwxp 00000000 00:00 0 [heap]


二进制文件被加载到一个固定地址,并且它有一个可执行和可写的部分。再加上绝对写原语,利用起来很容易。使用绝对写原语,可以将shellcode写入可执行部分。然后,可以再次使用原语向全局偏移表(GOT)“喷射”shellcode的地址。mesquite进程是多线程的,因此其他线程或多或少不可避免地从GOT调用函数,从而实现shellcode执行。

 

权限提升

mesquite进程是以chroot运行的,因此之前的漏洞是无法直接利用的。所以,我们还需要实现提权。

我开始寻找监听本地socket的root进程:

[root@kindle root]# netstat -ntpl | tail -n +3 | awk '{ print $7 }' | awk -F / '{ print $1 }' | xargs -I {} ps -o uname=,cmd= -p {}
9000 /app/bin/AaMenuApplication
9000 webreader
root stackdumpd
9000 kfxreader -l
9000 /usr/java/bin/cvm -Xmx49m -Xms49m ...
root fastmetrics
9000 kfxview
9000 /usr/java/bin/cvm -Xmx49m -Xms49m ...

stackdumpd貌似有戏,所以我在Ghidra打开它看看它有什么作用。据我所知,这个进程负责生成崩溃进程的堆栈转储。它接收崩溃进程id和线程id等信息,并将其传递给/usr/bin/dump-stack。这是一个用gdb连接到崩溃进程的shell脚本(这就是为什么它出现在固件中!),顾名思义,转储堆栈。下面给出的是shell脚本代码:

${GDB} --quiet \
--se "${PROCESS_EXE}" \
--pid ${CURRENT_TID} \
--batch \
-ex "bt" \
-ex detach

请注意,CURRENT_TID没有被引用,因此可以将参数注入gdb。由于gdb可以运行thecommand参数中给出的任意命令,因此它可以作为root权限运行任意代码。

乎开发人员已经意识到这个问题,并试图通过确保CURRENT_TID是一个数字来预防漏洞利用。第一次检测位于dumpstackd,它会检查atoi是否返回0:

第二次检测位于dump-stack,它使用了下列正则表达式:

“$(echo “$CURRENT_TID” | grep ‘^[0–9]*$’)” != “”

atoi检查可以通过简单地用数字开头的字符串来绕过。通过在数字后面添加新行字符,可以绕过正则表达式检查。因此,像“1\nsome string”这样的简单字符串就可以绕过这两个检查了。这样一来,我们就可以利用这些漏洞以root权限执行任意代码了!

 

漏洞利用PoC

在漏洞演示视频中,我们演示了完整的漏洞利用链,测试设备为新款Kindle 10(固件版本5.13.2)

漏洞利用演示

演示视频:https://youtu.be/S6dPM1KHyYA

分享到: QQ空间 新浪微博 微信 QQ facebook twitter
|推荐阅读
|发表评论
|评论列表
加载更多