使用AppImage打包Freerdp-pth

本篇笔记仅在介绍AppImage的使用

0x00 Intro

肥欣哥正在搞站,拿到了SID500的NTHash,但是无奈另外一台机器没有开SMB\RPC的端口,但是却开了RDP,于是想着对RDP进行PTH。

https://labs.portcullis.co.uk/tools/freerdp-pth/ 这篇文章已经有详细记录,且在Kali自己的博客中也有介绍,加入官方仓库的freerdp-x11版本支持PTH参数。但是在Kali Rolling的发行版中存在两个版本一个是freerdp-x11,这个版本不存在/pth参数,另一个是freerdp2-x11,直接执行带/pth参数的功能会出现内存错误,在FreeRDP的Github Issue已经有人提出来了(见 https://github.com/FreeRDP/FreeRDP/issues/3499 ),同时在这个已经closed的Issue中有人提出了

1
2
3
4
5
6
Not working:
version in ArchLinux (2.0.0-dev (git 6e15931))
master from git (2.0.0-dev (git 1046c9575))
Does work:
version in Kali 1 (1.1.0-beta1 (git n/a), from repo http://old.kali.org/kali)

也就是说在老版本的Kali仓库中,有一个版本是可以使用的。鉴于肥欣哥编译出来的版本总有问题,于是决定通过直接拉取仓库Deb包的方法来在新的Kali Rolling中跑起来这个版本。

0x01 How to

在官方文档中 https://docs.kali.org/general-use/kali-linux-sources-list-repositories 我们能找到对应发行版的Codename是moto。从Pkg Tracer( http://pkg.kali.org/pkg/freerdp )里也可以看到freerdp-x11的具体版本是那个带有beta1标识的包。
我们下载必要包,按顺序执行安装流程应该就可以使用了,这里做了一个简单的Shell脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/bin/bash
apt remove freerdp-x11 freerdp2-x11
apt autoremove
apt purge
apt update
apt install gdebi -y
mkdir freerdp-deb
cd freerdp-deb
wget http://old.kali.org/kali-security/pool/main/o/openssl/libssl1.0.0_1.0.1e-2+deb7u17_amd64.deb
wget http://old.kali.org/kali/pool/main/f/freerdp/libfreerdp1_1.1.0~beta1+git20131203-0kali_amd64.deb
wget http://old.kali.org/kali/pool/main/f/freerdp/freerdp-x11_1.1.0~beta1+git20131203-0kali_amd64.deb
gdebi -q libssl1.0.0_1.0.1e-2+deb7u17_amd64.deb
gdebi -q libfreerdp1_1.1.0~beta1+git20131203-0kali_amd64.deb
gdebi -q freerdp-x11_1.1.0~beta1+git20131203-0kali_amd64.deb

支持在Kali Rolling的发行版中,就能成功运行有pth功能的xfreerdp了。

0x02 Create AppImage

今天我们这篇笔记的主角,其实是AppImage,什么是AppImage可以自行Google一下,简而言之是一种打包技术,能做到一次打包,在N个不同的Linux发行版(或者是不同操作系统)直接运行,而市面上已经有一些类似的打包方式了,具体异同可以参考 https://www.fossmint.com/flatpak-appimage-and-snap-how-do-they-stack/ 。著名“飞跃长城防火墙”项目的某个Qt5版本,也使用了此种打包方法。

关于如何创建AppImage,在项目的Wiki中( https://github.com/AppImage/AppImageKit/wiki/Creating-AppImages )提供了多种方法,其中较为方便的是基于yml与自动pkg2image脚本的只做方法,但是由于我们使用的包没有在主流Linux发行版仓库中,所以这里我们选择使用手动创建AppImage的方法。

首先我们需要下载 AppImageKit 中的 appimagetool,地址在 https://github.com/AppImage/AppImageKit/releases ,64位对应x86_64,需要打包什么版本就下载哪个版本的 appimagetool,同时需要注意打包进去的ELF的位数也要匹配。

首先我们来解压Deb包:

1
2
ar -x pkgname.deb
tar zxvf data.tar.gz

Deb包中的 control.tar.gz 主要存在了一些安装脚本以及Hash等,在这里我们是不关心的,而 data.tar.gz 则主要保存了相应的Bin等,系数将前面下载的三个Deb包解压后,能得到当前目录下的 usr 文件夹。手动创建 AppImage 需要符合特定文件夹结构,以便 appimagetool 能够解析,目录结构大致如下

1
2
3
4
5
6
MyApp.AppDir/
MyApp.AppDir/AppRun
MyApp.AppDir/myapp.desktop
MyApp.AppDir/myapp.png
MyApp.AppDir/usr/bin/myapp
MyApp.AppDir/usr/lib/libfoo.so.0

我们这里将 MyApp.AppDir m命名为 Freerdp-x11.AppDir , 对应如上的目录结构大致像这样

1
2
3
4
5
6
7
8
Freerdp-x11.AppDir/
├── AppRun
├── freerdp-x11.desktop
├── usr
│   ├── bin
│   │   └── xfreerdp
│   ├── lib
...

其中 myapp.desktop 文件是必不可少的,appimagetool 首先会解析这个文件,因为AppImage原来是专门为拥有GUI的程序所准备的,这里我们依照 https://github.com/AppImage/AppImageKit/blob/appimagetool/master/resources/appimagetool.desktop 进行修改即可。

在开始正式打包之前,我们先运行一下 ./usr/bin/xfreerdp 确认是否能正常运行,很显然的会提示找不到动态链接库,我们可以指定一下 LD_LIBRARY_PATH 环境变量到 ./usr/lib/x86_64-linux-gnu,我们发现Deb包中解压的.so文件都位于这个文件夹中,紧接着再运行xfreerdp,仍旧提示缺少了某个.so,在目录下查找确实不存在,所以只能回到原来的源中去下载。

1
2
wget http://old.kali.org/kali/pool/main/libx/libxv/libxv1_1.0.7-1+deb7u1_amd64.deb
wget http://old.kali.org/kali/pool/main/libx/libxkbfile/libxkbfile1_1.0.8-1_amd64.deb

按照前面提供的解压方法,解压DEB包,并在此运行xfreerdp,此时已经可以正常输出帮助提示,现在只差最后一步就是利用appimagetool进行打包了。

AppImage打包后的文件,运行时会首先执行包中的AppRun,这个文件可以是预编译好的ELF或者是Shell脚本,我们可以参考 https://github.com/probonopd/linuxdeployqt/wiki/Custom-wrapper-script-instead-of-AppRun#example-wrapper-in-bash 中给出的例子来对自己的AppRun脚本进行修改,其实无法就是完成两个工作,通过设定LD_LIBRARY_PATH来使用Bin找到相关的动态链接库文件,通过$@来传递Bin所需要的参数,在这里就不再过多赘述了。

最后一步,我们只需要执行 ./appimagetool-x86_64.AppImage Freerdp-x11.AppDir/ 打包操作,就可以生成 xfreerdp-x11-x86_64.AppImage

我的打包环境在VPS上,系统版本是Ubuntu 16.04.4 LTS,拿到Kali Rolling中进行测试,发现已经能够成功跑起来了,如下图:

0x03 Summary

所有项目所需的文件,我已经push到了Github https://github.com/darkr4y/freerdp-pth 。如有任何问题欢迎在issue中提出。