标签 镜像 下的文章

最近使用Docker下载“官方”容器镜像的时候,我发现这样一句话:

ubuntu:14.04: The image you are pulling has been verified (您所拉取的镜像已经经过验证)

起初我以为这条信息引自Docker大力推广的镜像签名系统,因此也就没有继续跟进。后来,研究加密摘要系统的时候——Docker用这套系统来对镜像进行安全加固——我才有机会更深入的发现,逻辑上整个与镜像安全相关的部分具有一系列系统性问题。

Docker所报告的,一个已下载的镜像经过“验证”,它基于的仅仅是一个标记清单(signed manifest),而Docker却从未据此清单对镜像的校验和进行验证。一名攻击者以此可以提供任意所谓具有标记清单的镜像。一系列严重漏洞的大门就此敞开。

镜像经由HTTPS服务器下载后,通过一个未加密的管道流进入Docker守护进程:

[decompress] -> [tarsum] -> [unpack]

这条管道的性能没有问题,但是却完全没有经过加密。不可信的输入在签名验证之前是不应当进入管道的。不幸的是,Docker在上面处理镜像的三个步骤中,都没有对校验和进行验证。

然而,不论Docker如何声明,实际上镜像的校验和(Checksum)从未经过校验。下面是Docker与镜像校验和的验证相关的代码片段,即使我提交了校验和不匹配的镜像,都无法触发警告信息。

if img.Checksum != "" && img.Checksum != checksum {
  log.Warnf("image layer checksum mismatch: computed %q,
             expected %q", checksum, img.Checksum)
}

不安全的处理管道

解压缩

Docker支持三种压缩算法:gzip、bzip2和xz。前两种使用Go的标准库实现,是内存安全(memory-safe)的,因此这里我预计的攻击类型应该是拒绝服务类的攻击,包括CPU和内存使用上的当机或过载等等。

第三种压缩算法,xz,比较有意思。因为没有现成的Go实现,Docker 通过执行(exec)xz二进制命令来实现解压缩。

xz二进制程序来自于XZ Utils项目,由大概2万行C代码生成而来。而C语言不是一门内存安全的语言。这意味着C程序的恶意输入,在这里也就是Docker镜像的XZ Utils解包程序,潜在地存在可能会执行任意代码的风险。

Docker以root权限运行 xz 命令,更加恶化了这一潜在威胁。这意味着如果在xz中出现了一个漏洞,对docker pull命令的调用就会导致用户整个系统的完全沦陷。

Tarsum

对tarsum的使用,其出发点是好的,但却是最大的败笔。为了得到任意一个加密tar文件的准确校验和,Docker先对tar文件进行解密,然后求出特定部分的哈希值,同时排除剩余的部分,而这些步骤的顺序都是固定的

由于其生成校验和的步骤固定,它解码不可信数据的过程就有可能被设计成攻破tarsum的代码。这里潜在的攻击既包括拒绝服务攻击,还有逻辑上的漏洞攻击,可能导致文件被感染、忽略、进程被篡改、植入等等,这一切攻击的同时,校验和可能都是不变的。

解包

解包的过程包括tar解码和生成硬盘上的文件。这一过程尤其危险,因为在解包写入硬盘的过程中有另外三个已报告的漏洞

任何情形下未经验证的数据都不应当解包后直接写入硬盘。

libtrust

Docker的工具包libtrust,号称“通过一个分布式的信任图表进行认证和访问控制”。很不幸,对此官方没有任何具体的说明,看起来它好像是实现了一些javascript对象标记和加密规格以及其他一些未说明的算法。

使用libtrust下载一个清单经过签名和认证的镜像,就可以触发下面这条不准确的信息(说不准确,是因为事实上它验证的只是清单,并非真正的镜像):

ubuntu:14.04: The image you are pulling has been verified(您所拉取的镜像已经经过验证)

目前只有Docker公司“官方”发布的镜像清单使用了这套签名系统,但是上次我参加Docker管理咨询委员会的会议讨论时,我所理解的是,Docker公司正计划在未来扩大部署这套系统。他们的目标是以Docker公司为中心,控制一个认证授权机构,对镜像进行签名和(或)客户认证。

我试图从Docker的代码中找到签名秘钥,但是没找到。好像它并不像我们所期望的把密钥嵌在二进制代码中,而是在每次镜像下载前,由Docker守护进程通过HTTPS从CDN远程获取。这是一个多么糟糕的方案,有无数种攻击手段可能会将可信密钥替换成恶意密钥。这些攻击包括但不限于:CDN供应商出问题、CDN初始密钥出现问题、客户端下载时的中间人攻击等等。

补救

研究结束前,我报告了一些在tarsum系统中发现的问题,但是截至目前我报告的这些问题仍然没有修复。

要改进Docker镜像下载系统的安全问题,我认为应当有以下措施:

摒弃tarsum并且真正对镜像本身进行验证

出于安全原因tarsum应当被摒弃,同时,镜像在完整下载后、其他步骤开始前,就对镜像的加密签名进行验证。

添加权限隔离

镜像的处理过程中涉及到解压缩或解包的步骤必须在隔离的进程(容器?)中进行,即只给予其操作所需的最小权限。任何场景下都不应当使用root运行xz这样的解压缩工具。

替换 libtrust

应当用更新框架(The Update Framework)替换掉libtrust,这是专门设计用来解决软件二进制签名此类实际问题的。其威胁模型非常全方位,能够解决libtrust中未曾考虑到的诸多问题,目前已经有了完整的说明文档。除了已有的Python实现,我已经开始着手用Go语言实现的工作,也欢迎大家的贡献。

作为将更新框架加入Docker的一部分,还应当加入一个本地密钥存储池,将root密钥与registry的地址进行映射,这样用户就可以拥有他们自己的签名密钥,而不必使用Docker公司的了。

我注意到使用非Docker公司官方的第三方仓库往往会是一种非常糟糕的用户体验。Docker也会将第三方的仓库内容降为二等地位来看待,即使不因为技术上的原因。这个问题不仅仅是生态问题,还是一个终端用户的安全问题。针对第三方仓库的全方位、去中心化的安全模型既必须又迫切。我希望Docker公司在重新设计他们的安全模型和镜像认证系统时能采纳这一点。

结论

Docker用户应当意识到负责下载镜像的代码是非常不安全的。用户们应当只下载那些出处没有问题的镜像。目前,这里的“没有问题”并包括Docker公司的“可信(trusted)”镜像,例如官方的Ubuntu和其他基础镜像。

最好的选择就是在本地屏蔽 index.docker.io,然后使用docker load命令在导入Docker之前手动下载镜像并对其进行验证。Red Hat的安全博客有一篇很好的文章,大家可以看看。

感谢Lewis Marshall指出tarsum从未真正验证。

参考


via: https://titanous.com/posts/docker-insecurity

作者:titanous 译者:Mr小眼儿 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

磁盘镜像包括了整个磁盘卷的文件或者是全部的存储设备的数据,比如说硬盘,光盘(DVD,CD,蓝光光碟),磁带机,USB闪存,软盘。一个完整的磁盘镜像应该包含与原来的存储设备上一样完整、准确,包括数据和结构信息。

磁盘镜像文件格式可以是采用开放的标准,像ISO格式的光盘镜像,或者是专有的软件应用程序的特定格式。"ISO"这个名字来源于用CD存储的ISO 9660文件系统。但是,当用户转向Linux的时候,经常遇到这样的问题,需要把专有的的镜像格式转换为开放的格式。

磁盘镜像有很多不同的用处,像烧录光盘,系统备份,数据恢复,硬盘克隆,电子取证和提供操作系统(即LiveCD/DVDs)。

有很多不同的方法可以把ISO镜像挂载到Linux系统下。强大的mount 命令给我们提供了一个简单的解决方案。但是如果你需要很多工具来操作磁盘镜像,你可以试一试下面的这些强大的开源工具。

很多工具还没有看到最新的版本,所以如果你正在寻找一个很好用的开源工具,你也可以加入,一起来为开源做出一点贡献。

Furius ISO Mount

Furius ISO Mount是一个简单易用的开源应用程序,可以用来挂载镜像文件,它支持直接打开ISO,IMG,BIN,MDF和NRG格式的镜像而不用把他们烧录到磁盘。

特性:

  • 支持自动挂载ISO, IMG, BIN, MDF and NRG镜像文件
  • 支持通过 loop 方式挂载 UDF 镜像
  • 自动在根目录创建挂载点
  • 自动解挂镜像文件
  • 自动删除挂载目录,并返回到主目录之前的状态
  • 自动记录最近10次挂载历史
  • 支持挂载多个镜像文件
  • 支持烧录ISO文件及IMG文件到光盘
  • 支持MD5校验和SHA1校验
  • 自动检索之前解挂的镜像
  • 自动创建手动挂载和解挂的日志文件
  • 语言支持(目前支持保加利亚语,中文(简体),捷克语,荷兰语,法语,德语,匈牙利语,意大利语,希腊语,日语,波兰语,葡萄牙语,俄语,斯洛文尼亚语,西班牙语,瑞典语和土耳其语)

fuseiso

fuseiso 是用来挂载ISO文件系统的一个开源的安全模块。

使用FUSE,我们完全可以在用户空间里运行一个完整的文件系统。

特性:

  • 支持读ISO,BIN和NRG镜像,包括ISO 9660文件系统
  • 支持普通的ISO 9660级别1和级别2
  • 支持一些常用的扩展,想Joliet,RockRidge和zisofs
  • 支持非标准的镜像,包括CloneCD's IMGs 、Alcohol 120%'s MDFs 因为他们的格式看起来恰好像BIN镜像一样

iat

iat(Iso 9660分析工具)是一个通用的开源工具,能够检测很多不同镜像格式文件的结构,包括BIN,MDF,PDI,CDI,NRG和B5I,并转化成ISO 9660格式.

特性:

  • 支持读取(输入)NRG,MDF,PDI,CDI,BIN,CUE 和B5I镜像
  • 支持用 cd 刻录机直接烧录光盘镜像
  • 输出信息包括:进度条,块大小,ECC扇形分区(大小),头分区(大小),镜像偏移地址等等

AcetoneISO

AcetoneISO 是一个功能丰富的开源图形化应用程序,用来挂载和管理CD/DVD镜像。

当你打开这个程序,你就会看到一个图形化的文件管理器用来挂载镜像文件,包括专有的镜像格式,也包括像ISO, BIN, NRG, MDF, IMG 等等,并且允许您执行一系列的操作。

AcetoneISO是用QT 4写的,也就是说,对于基于QT的桌面环境能很好的兼容,像KDE,LXQT或是Razor-qt。

这个软件适用于所有正在寻找Linux版本的Daemon Tools的人。

特性:

  • 支持挂载大多数windows 镜像,界面简洁易用
  • 可以将其所有支持镜像格式转换到ISO,或者是从中提取内容
  • 加密,压缩,解压任何类型的镜像
  • 转换DVD成xvid avi,支持将各种常规视频格式转换成xvid avi
  • 从视频里提取声音
  • 从不同格式中提取镜像中的文件,包括bin mdf nrg img daa dmg cdi b5i bwi pdi
  • 用Kaffeine / VLC / SMplayer播放DVD镜像,可以从Amazon 自动下载封面。
  • 从文件夹或者是CD/DVD生成ISO镜像
  • 可以做镜像的MD5校验,或者是生成镜像的MD5校验码
  • 计算镜像的ShaSums(128,256和384位)
  • 支持加密,解密一个镜像文件
  • 按兆数分拆和合并镜像
  • 以高压缩比将镜像压缩成7z 格式
  • 翻录PSX CD成BIN格式,以便在ePSXe/pSX模拟器里运行
  • 为BIN和IMG格式恢复丢失的 CUE 文件
  • 把MAC OS的DMG镜像转换成可挂载的镜像
  • 从指定的文件夹中挂载镜像
  • 创建数据库来管理一个大的镜像集合
  • 从CD/DVD 或者是ISO镜像中提取启动文件
  • 备份CD成BIN镜像
  • 简单快速的把DVD翻录成Xvid AVI
  • 简单快速的把常见的视频(avi, mpeg, mov, wmv, asf)转换成Xvid AVI
  • 简单快速的把FLV 换换成AVI 格式
  • 从YouTube和一些视频网站下载视频
  • 提取一个有密码的RAR存档
  • 支持转换任何的视频到PSP上
  • 国际化的语言支持支持(英语,意大利语,波兰语,西班牙语,罗马尼亚语,匈牙利语,德语,捷克语和俄语)

ISO Master

ISO Master是一个开源、易用的、图形化CD 镜像编辑器,适用于Linux 和BSD 。可以从ISO 里提取文件,给ISO 里面添加文件,创建一个可引导的ISO,这些都是在一个可视化的用户界面完成的。可以打开ISO,NRG 和一些MDF文件,但是只能保存成ISO 格式。

ISO Master 是基于bkisofs 创建的,这是一个简单、稳定的阅读,修改和编写ISO 镜像的软件库,支持Joliet, RockRidge 和EL Torito扩展,

特性:

  • 支持读ISO 格式文件(ISO9660, Joliet, RockRidge 和 El Torito),大多数的NRG 格式文件和一些单轨道的MDF文件,但是,只能保存成ISO 格式
  • 创建和修改一个CD/DVD 格式文件
  • 支持CD 格式文件的添加或删除文件和目录
  • 支持创建可引导的CD/DVD
  • 国际化的支持


via: http://www.linuxlinks.com/article/20141025082352476/DiskImageTools.html

作者:Frazer Kline 译者:barney-ro 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

前言:最近新入手了一台电信版的Android手机,由于厌恶其中预装的各种应用,也想按照自己的意愿裁剪一下手机中的应用,所以对此进行了一些学习。我找到了一个HTC的RUU包,从中解析到了system.img,发现这个system.img不是EXT4格式的,不能简单的在Ubuntu上挂载,于是在网上找到了一篇说明Android里面各种分区拆解的文章。我做了翻译和补充,供大家参考。

RAMDISK

RAMDISK(initrd)是一个小的分区镜像,在引导时内核以只读方式挂载它。它只保护/init和一些配置文件。它用于初始化和挂载其它的文件系统镜像。RAMDISK是一个标准的Linux特性。

ramdisk.img被包含Google android SDK中($SDK\_ROOT/tools/lib/images/ramdisk.img),也可以编译生成($SDK\_ROOT/out/target/product/$PRODUT\_NAME/ramdisk.img)。这是一个gzip压缩的CPIO文件。

修改Android的RAMDISK镜像

要修改它,首先复制它到你的Linux机器上,并用如下命令解开:

user@computer:$ mv ramdisk.img ramdisk.cpio.gz
gzip -d ramdisk.cpio.gz
mkdir ramdisk
cd ramdisk  
cpio -i -F ../ramdisk.cpio

解开后,做一些你的修改和删除无用的文件后,通过如下命令重新创建ramdisk.cpio:

user@computer:$ cpio -i -t -F ../ramdisk.cpio | cpio -o -H newc -O ../ramdisk_new.cpio

然后可以重新改名并压缩:

user@computer:$ cd ..
gzip ramdisk_new.cpio
mv ramdisk_new.cpio.gz ramdisk.img

SYSTEM和DATA镜像

system.img是挂载到 / 下的镜像,它包含了全部的系统可执行文件。

userdata.img挂载到 /data 下的镜像,它包含了应用及用户相关的数据。

在实际的物理设备中,他们通过ramdisk中的init.rc脚本挂载为文件系统。它们可以有各种不同的格式,如 YAFFS2、EXT4或 UBI-FS。

它们通过Android构建系统生成并刷入到物理设备中。模拟器对它们的使用有所不同(见下文):

Android模拟器镜像

  • system.img 被复制到一个临时文件中,用于模拟器工作。所以你对模拟器中的根目录做的任何改变都会在模拟器退出后丢失。
  • userdata.img 只用于使用了 -wipe-data参数时。通常将~/.android/userdata-qemu.img(linux下)作为 /data 分区镜像挂载,而使用 -wipe-data 时会复制userdata.img中的内容到userdata-qemu.img。
  • sdcard.img 用于使用了-sdcard参数时,挂载到/sdcard
  • cache.img 用于使用了-cache参数来指定/cache内容。如果未指定该参数,模拟器启动时会创建一个空的临时文件挂载到/cache上。这个临时文件会在退出时自动清除。

模拟器不会修改system.img和userdata.img。

拆解Android’s YAFFS2 镜像

一个YAFFS2文件在Linux被识别为“VMS Alpha executable”文件。

user@computer:$ file ${SDK_ROOT}}/out/target/product/imx51_ccwmx51js/system.img
./out/target/product/imx51_ccwmx51js/system.img: VMS Alpha executable

从Google代码站中下载 unyaffs

如果上面的可执行文件在你的系统不工作的话,你也可以下载 源代码 并重新编译它。

user@computer:$ gcc -o unyaffs unyaffs.c
sudo chmod +x /complete/directory/path/to/unyaffs

然后使用这个命令来拆解 YAFF2 镜像文件:

user@computer:$ mkdir image
cd image
unyaffs ../system.img

拆解EXT4镜像

如果镜像是EXT4,那么很简单,直接挂载就可以读取其中的内容了:

user@computer:$ mount -o loop -t ext4 system.img /media

拆解JFFS2镜像

作为补充,这里说一下如何拆解JFFS2镜像:

user@computer:$ modprobe mtdblock
modprobe jffs2
modprobe mtdram total_size=65536 erase_size=256
mknod /tmp/mtdblock0 b 31 0
dd if=/pathtoimage/rootfs.jffs2 of=/tmp/mtdblock0
mount -t jffs2 /tmp/mtdblock0 /mnt

原文链接:http://www.lindusembedded.com/blog/2012/02/23/androids-partition-images/