从rw中学习tomcat

从RWCTF中学习tomcat的操作

0x01 调试tomcat

首先创建一个maven的java项目,然后下载tomcat的源码,然后copy以下文件

参考链接:https://zhuanlan.zhihu.com/p/35454131
y4tacker的github

image-20220127205922493

在这里插入图片描述

差多就这些,就可以启动一个tomcat的调试了。

0x02 解决题目

参考链接:https://mp.weixin.qq.com/s/QQ2xR32Fxj_nnMsFCucbCg

其中最重要的部分就像wp中写得一样,就是在于几个特殊字符的处理

& -> &

< -> &lt;

' -> &#39;

> -> &#39;

" -> &quot;

( -> &#40;

) -> &#41;

最麻烦还是<()

如果只是单纯地没有<我们可以使用el表达式来进行下一步的操作

${Runtiume.getRuntime().exec(param.c)}

如果单纯地没有()我们可以使用unicode来进行绕过。

看到大哥的思路,其实就是看大家从哪里入手。

  • 如果是从jsp方面入手

    就要考虑是否支持el表达式一样动态执行的语法特性,或者有不依赖于<的特性

  • 如果是从el表达式入手

    就是看是否支持编码绕过,或者可以获取内部的对象来实现一些骚操作的。二次解析执行

题解是:

在不使用圆括号的情况下,通过 EL 表达式的取值、赋值特性,获取到某些关键的 Tomcat 对象实例,修改它们的属性,造成危险的影响;
经过许久的尝试,最终我成功用第4个办法完成了利用,从 JSP EL 中自带解析的隐式对象出发,通过组合4个 EL 表达式链,完成了 RCE!

然后作者想到了使用session来进行操作,我们知道在tomcat正常退出的时候会将session写入到SESSION.SER文件,但这个参数其实是可以修改的。

{pageContext.servletContext.classLoader.resources.context.manager.pathname=param.a}

然后再通过执行如下表达式,往 Session 里写数据:

${sessionScope[param.b]=param.c}

这样就可以做到让 Tomcat 正常停止服务时,往一个任意路径下的文件写入部分内容可控的字符串(这部分是不会有特殊字符过滤转义处理的)

?a=/opt/tomcat/webapps/ROOT/session.jsp&b=voidfyoo&c=%3C%25out.println(123)%3B%25%3E

这样就可以做到,想session.jsp中写入print(123);

修改 Context reloadable

但是如何让tomcat关闭或者说,怎么触发写入session,现在是我们必须考虑的问题。除了服务停止或者重启,还可以让部署的程序触发 reload 来做到。

Context reloadable 配置为 true(默认是 false);

/WEB-INF/classes/ 或者 /WEB-INF/lib/ 目录下的文件发生变化。

第一点可以通过el表达式直接修改,第二点是的意思是classes中有class文件修改或者lib目录有新的jar写入,即使这个jar有问题也可以被解析触发reload(因为有脏字符);

修改 appBase 目录

上一步已经达到了上一步的目的就是reload(),但是jar有张数据,所以我们现在,要么把jar文件变合法,要么就是让他换个路劲读取文件来解析。

${pageContext.servletContext.classLoader.resources.context.parent.appBase=param.d}

这个appBase参数就是这个作用,所以当我们把这个更改的时候,他就会重新解析,程序就不会down。

所以综合的exp也就出来了。

${pageContext.servletContext.classLoader.resources.context.manager.pathname=param.a}
${sessionScope[param.b]=param.c}
${pageContext.servletContext.classLoader.resources.context.reloadable=true}
${pageContext.servletContext.classLoader.resources.context.parent.appBase=param.d}

作者的预期解法。exp可以去上面的链接抄

0x03 ASCII ZIP Exploit

这个东西 我觉得是真的牛,有人早在8年前就研究出来了ASCII-ZIP的制作,也就是使用 [A-Za-z0-9] 范围内的字符去构造压缩数据。

  • https://github.com/molnarg/ascii-zip
  • https://github.com/Arusekk/ascii-zip

没看懂原理,但是我大为震惊。

然后据说解出这个题目的两个队伍参考上面的算法,自己构造了一个合理的jar,让脏字符变得合理了。。。。。

这个也是y4哥哥的解法差的那一步了,y4 yyds!

0x04 TRick

${applicationScope}我们可以看到许许多多的那个属性,可以看看哪些可以被我们使用。

这个时候就应该是对着每一个属性进行查文档了。

org.apache.jasper.compiler.StringInterpreter=org.apache.jasper.compiler.StringInterpreterFactory$DefaultStringInterpreter@4c781127

我们主要关注这一个。

Defines the interface for the String interpreter. This allows users to provide custom String interpreter implementations that can optimise String processing for an application by performing code generation for a sub-set of Strings.
the string representing the code that will be inserted into the source code for the Servlet generated for the JSP.

就是在解析jsp的时候他会被触发,也就是当我们访问jsp文件的时候,这个类就会被调用,如果这个类被赋值成我们的恶意类,就可以执行了。

image-20220127230221732

我们可以把这个赋值成我们的类然后写一个get的方法,获知直接代码块也可以。如何让jsp重新编译就不用多说了。写入一个,访问就可以了。

image-20220127231353876

这个jar的加载,WEB-INF/tomcat-web.xml

而是借助修改 Tomcat Context WatchedResource 来触发:

WatchedResource - The auto deployer will monitor the specified static resource of the web application for updates, and will reload the web application if it is updated. The content of this element must be a string.

在 Tomcat 9 环境下,默认的 WatchedResource 包括:

  • WEB-INF/web.xml
  • WEB-INF/tomcat-web.xml
  • ${CATALINA_HOME}/conf/web.xml

大概就是这个思路了,下面进行测试。https://tomcat.apache.org/tomcat-9.0-doc/config/context.html

image-20220127231830734

0x05 Test

org.apache.jasper.compiler.StringInterpreter 加载恶意类

首先写入el表达

${applicationScope[param.a]=param.b}

在web-inf/lib下面写入jar文件。

然后在WatchedResource插入注释或者新建文件。然后再上传一个jsp任意访问即可。

image-20220127233234668

Tomcat下/META-INF/lib中被加载的jar,为什么可以在其/METAINF/resources/下直接写jsp可以直接访问执行

image-20220127235157954

可以看到其中需要加入到那个路劲中的一些来源,可以通过这些来达到和jsp文件的直接访问。
在这里插入图片描述

Tomcat下/META-INF/lib中被加载的jar,为什么可以在其/METAINF/resources/下直接写jsp可以直接访问执行

在这里插入图片描述

可以看到其中需要加入到那个路劲中的一些来源,可以通过这些来达到和jsp文件的直接访问。

<think>好的,我现在需要帮助用户了解强化学习中的RW算法,也就是Reward Weighting(奖励加权)的相关概念和实现。首先,我需要确认用户提到的“RW”具体指什么,因为强化学习中并没有一个广泛称为RW的标准算法。可能用户指的是奖励加权方法,或者是某种特定算法如Reward Shaping中的技术,或者是其他变体。根据提供的引用内容,用户可能是在研究基于人类反馈的强化学习(RLHF),比如DPO(引用[2])或PPO(引用[3]),这些方法中奖励模型的设计和优化是关键。 首先,引用[1]提到强化学习的基本模型是马尔可夫决策过程(MDP),而奖励函数在其中至关重要。奖励加权可能在策略更新时调整不同奖励信号的权重,以优化策略。引用[2]讨论了RLHF中使用奖励模型来指导微调,但未直接提到RW。引用[3]涉及PPO算法在NLP中的应用,其中奖励设计是关键。引用[4]中的Q-Learning涉及奖励的累积,可能与奖励加权有关。 接下来,我需要确定RW的具体定义。可能用户指的是奖励加权作为一种策略更新方法,例如在策略梯度中,根据奖励的大小调整梯度更新的权重。例如,在REINFORCE算法中,策略梯度与累积奖励成正比,这可以视为一种奖励加权。此外,在奖励塑造(Reward Shaping)中,通过调整奖励信号的权重来引导智能体学习,这也可能与RW相关。 然后,我需要解释RW的概念,可能涉及以下方面:基本思想(调整奖励权重以优化策略)、算法步骤(定义奖励函数、计算权重、更新策略)、实现要点(权重设计、稳定性、探索与利用)。同时,结合用户提供的引用,尤其是RLHF和DPO的内容,说明RW在调整人类反馈奖励中的应用。 在实现部分,可以提供一个简单的代码示例,例如基于策略梯度的奖励加权实现,使用Python和PyTorch。代码需要包括策略网络的定义、选择动作的方法、以及根据加权奖励更新策略的步骤。同时,需要解释关键点,如奖励归一化和学习率调整。 最后,生成相关问题,涵盖RW与其他方法的对比、应用场景、挑战、与深度学习的结合,以及具体案例如机器人控制和游戏AI中的应用。确保问题能够引导用户进一步探索。 需要验证所有信息是否正确,尤其是奖励加权的常见应用和算法步骤是否准确。同时,确保引用标记正确,引用内容与解释部分相关。例如,引用[2]提到DPO作为RLHF的替代方法,而RW可能用于优化奖励模型,这需要正确关联。</think>### 强化学习中的奖励加权(Reward Weighting, RW) #### 概念解析 在强化学习中,**奖励加权(Reward Weighting, RW)** 是一种通过调整不同奖励信号的权重来优化策略的方法。其核心思想是:在多目标或复杂任务中,不同奖励信号可能对最终目标的贡献程度不同,通过合理分配权重,智能体可以更高效地学习到最优策略[^1]。例如,在基于人类反馈的强化学习(RLHF)中,奖励加权可用于平衡“人类偏好”与“模型原始性能”的权重[^2]。 #### 实现方法 1. **基本流程** - **定义奖励函数**:将任务目标分解为多个子奖励,例如$r = w_1 r_1 + w_2 r_2 + \dots + w_n r_n$,其中$w_i$为权重。 - **计算权重**:可通过手动设定、动态调整(如基于任务进度)或自动优化(如元学习)确定。 - **策略更新**:使用加权后的总奖励$r$驱动策略优化算法(如策略梯度、Q-Learning等)[^4]。 2. **代码示例(基于策略梯度)** ```python import torch import torch.nn as nn class PolicyNetwork(nn.Module): def __init__(self, state_dim, action_dim): super().__init__() self.fc = nn.Sequential( nn.Linear(state_dim, 64), nn.ReLU(), nn.Linear(64, action_dim), nn.Softmax(dim=-1) ) def forward(self, state): return self.fc(state) # 初始化策略网络和优化器 policy = PolicyNetwork(state_dim=4, action_dim=2) optimizer = torch.optim.Adam(policy.parameters(), lr=0.01) def select_action(state): state = torch.FloatTensor(state) probs = policy(state) action = torch.multinomial(probs, 1).item() return action def update_policy(rewards, weights, states, actions): discounted_rewards = [] cumulative = 0 for r, w in zip(reversed(rewards), reversed(weights)): cumulative = r * w + 0.99 * cumulative # 加权折扣奖励 discounted_rewards.insert(0, cumulative) # 策略梯度更新 optimizer.zero_grad() loss = 0 for state, action, dr in zip(states, actions, discounted_rewards): prob = policy(torch.FloatTensor(state))[action] loss += -torch.log(prob) * dr loss.backward() optimizer.step() ``` #### 关键点说明 - **权重设计**:在RLHF中,权重可能用于平衡“人类偏好得分”与“语言流畅性”等指标[^2]。 - **稳定性**:需对奖励进行归一化(如$r_i \leftarrow \frac{r_i - \mu}{\sigma}$),避免梯度爆炸[^3]。 - **探索与利用**:可结合熵正则化(Entropy Regularization)鼓励策略多样性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值