WEB1
一、信息收集
1.1查看源代码
-
查看源代码的方式:
-
右键查看源代码
-
F12打开开发者⼯具
-
Ctrl+U 查看
-
Burp 抓包查看
-
-
-
源代码中链接的⼀些奇怪路径(⽹站后台⽬录,编辑器)
-
ctfshow-web382(⽹站后台⽬录)
-
访问根目录
-
用户名:admin
密码:admin888(弱口令)
-
-
ctfshow-web14(编辑器)
-
根据文件路径找到相关的编辑器(editor)
-
插入文件
-
进入当前页面文件,找到flag并插入
-
复制url,并访问flag的相对路径
-
-
1.2扫目录
常见目录:
-
robots协议(在网站的根目录域名后加上
/robots.txt
就可以查看网站的robots协议了) -
Allow 代表允许访问,Disallow 就是禁止访问,User-agent 可以判断是哪家爬虫,经常产生新数据网站 sitemap 文件会用的比较多。
-
cftshow-web04
-
访问robots.txt
-
访问flagishere.txt
-
-
-
install安装目录
-
install 目录会提示安装有关操作对文件进行修改
-
cftshow-web385
-
访问/install
-
访问/install/?install
-
输入默认密码
-
-
1.3源码泄露(敏感目录的泄露)
-
.git 泄露
1.漏洞描述
* 开发者在使用 git 作为版本控制时,在一个目录中初始化一个仓库以后 , 会在这个目录下
产生一个名叫 `.git` 的隐藏文件夹,这个文件夹里面保存了这个仓库的所有版本等一系列信
息。
* 如果服务器将`.git`文件夹放在了 web 目录下,就可能导致攻击者利用`.git`文件夹内的
信息获取应用程序所有源代码。
2.修复建议
(1) 删除网站目录下的`.git`文件
(2) 中间件上设置`.git`目录访问权限,禁止访问
-
.svn 泄露
1.漏洞描述:
* 使用`svn`管理本地文件代码的过程,会自动生成一个`.svn`的文件夹---包含这网站的重要
信息
* 如果网站管理员在发布网站的时候,没有使用到处功能,而是直接复制微网站后台的文件夹,
就会导致`.svn`文件暴露在外网环境
* 黑客可以借助其中包含的用于版本信息追踪的`entries`文件,获取站点信息
2. 漏洞危害:
* 攻击者可以利用`.svn/entries`文件,查找网站的应用程序源代码、svn 服务器账号密码等
信息。
* SVN 产生的`.svn`目录还包含了`.svn-base`结尾的源代码文件副本(低版本 SVN 具体路
径为`text-base`目录,高版本 SVN 为`pristine`目录),如果服务器没有对此类后缀做解
析,黑客则可以直接获得文件源代码。
3. 修复建议
- 查找服务器上所有.svn 隐藏文件夹,删除。
- 开发人员在使用 SVN 时,严格使用导出功能,禁止直接复制代码。
-
Vim 临时⽂件缓存
* `vim`编辑的文件,在`vim`**异常退出**的时候,会生成`.filename.swp`的交换文件,用
来恢复文件依次为`.swo``.swn`
* `vim`编辑的文件,在修改的时候,会自动生成一个备份文件(修改之前的版本)
cftshow-web9
-
访问首页/index.php
-
访问交换文件/index.php.swp并下载
-
phps 泄漏
直接访问相关文件的phps后缀名
1.4收集域名信息
1.5寻找真实IP
-
不存在CDN
-
判断是否存在CDN
-
ping ⽬标域名,观察域名解析情况(发现显示的是ping其他⽹站)
-
nslookup:发现返回时多个IP的话,多半使⽤了CDN
-
-
绕过 CDN 寻找真实 IP
-
ping 邮箱服务器
-
分站域名,ping ⼆级域名
-
1.6搜索引擎
1.7子域名信息收集
-
子域名检测工具
-
Layer ⼦域名挖掘机
-
subDomainsBrute 可爆破出三级四级甚⾄五级等不易被探测到的域名
-
-
子域名爆破网站:https://phpinfo.me/domain/
1.8收集端口信息
-
扫描工具
-
Nmap
-
Masscan
-
ZMap
-
御剑TCP端⼝扫描
-
1.9探针信息
PHP 探针
ctdshow-web16
-
访问探针/tz.php
-
php相关参数,打开php信息PHPINFO
-
ctrl+f搜索flag
1.10Banner识别
二、命令执行
2.1 rce(远程代码执行漏洞)中常⽤的php代码执⾏函数
-
eval()
执⾏⼀个字符串表达式,该字符串必须是合法的 PHP 代码,且必须以 分号 结尾。
注意:
-
eval函数的参数的字符串末尾一定要有分号,在最后还要另加一个分号(这个分号是php限制)
-
注意单引号,双引号和反斜杠的运用。如果参数中带有变量时,并且变量有赋值操作的话,变量前的$符号前一定要有\来转义。如果没有赋值操作可以不需要。
-
注意在命令式字符串(包括分号)两边必须要有双引号或者根据需要用单引号。否则报错(命令式字符串是指:字符串中包括echo、print之类的命令的时候)。
-
assert()
直接将传⼊的参数当成 PHP代码 直接,不需要以分号结尾。
assert(mixed $assertion, string $description = ?): bool
-
preg_replace()
1 preg_replace(
2 string|array $pattern,
3 string|array $replacement,
4 string|array $subject,
5 int $limit = -1,
6 int &$count = null
7 ): string|array|null
搜索 subject 中匹配 pattern 的部分,以 replacement 进⾏替换。 preg_replace() 函数原本是执行一个正则表达式的搜索和替换,但因为存在危险 的 /e修饰符,使 preg_replace 将 replacement 参数当作 PHP 代码
-
create_function()
通过传递的参数创建⼀个匿名函数,并且返回函数的⼀个名字
create_function(string $args, string $code): string
第一个参数是函数接受的参数,第二个参数是函数的执行体
-
array_map()
为数组的每个元素应⽤回调函数
array_map(callable $callback, array $array, array ...$arrays): array
array_map():返回数组,是为 array 每个元素应⽤ callback 函数之后的数组。array_map() 返回⼀个 array,数组内容为 array1 的元素按索引顺序为参数调 ⽤ callback 后的结果(有更多数组时,还会传⼊ arrays 的元素)。callback 函数形参的数量必须匹配 array_map() 实参中数组的数量。
-
call_user_func()
把第⼀个参数作为回调函数调⽤
call_user_func(callable $callback, mixed $parameter = ?, mixed $... = ?):
mixed
第⼀个参数是被调⽤的回调函数,后⾯的参数是函数的形参
-
call_user_func_array()
调⽤回调函数,并把⼀个数组参数作为回 调函数的参数
call_user_func_array(callable $callback, array $param_arr): mixed
-
array_filter()
使⽤回调函数过滤数组的元素
array_filter(array $array, ?callable $callback = null, int $mode = 0): arr
ay
遍历 array 数组中的每个值,并将每个值传递给 callback 回调函数。 如果 callback 回调函数返回 true ,则将 array 数组中的当前值返回到结果 array 数组中
-
usort()/uasort()
使⽤⽤户⾃定义的⽐较函数对数组中的值进⾏排序
usort(array &$array, callable $callback): bool
本函数将⽤⽤户⾃定义的⽐较函数对⼀个数组中的值进⾏排序。 如果要排序的数组需要 ⽤⼀种不寻常的标准进⾏排序,那么应该使⽤此函数。
-
file_put_contents()/fputs()
将⼀个字符串写⼊⽂件
1 file_put_contents(
2 string $filename,
3 mixed $data,
4 int $flags = 0,
5 resource $context = ?
6 ): int
2.2 rce中常用的包含文件函数
-
include
当包含 .php ⽂件时,可同时运⾏
-
highlight_file(show_source)
语法⾼亮⼀个⽂件,即将⽂件内容全部展示出来
highlight_file(string $filename, bool $return = false): mixed
2.3 常见的系统执行函数
-
system
将字符串作为OS命令去执行,并且自带输出功能
system(string $command, int &$return_var = ?): string
-
shell_exec()
通过shell环境执行命令,并且将完整的输出以字符串的方式返回
值返回字符串,不会进行输出
该函数和反引号 `` 的执行效果一致
shell_exec(string $cmd): string
-
exec
将字符串作为OS命令去执行,但是自身不带输出功能
exec(string $command, array &$output = ?, int &$return_var = ?): string
本函数执⾏输⼊ command 的外部程序或外部指令。它的返回字符串只是外部程序执⾏后返回的最后⼀ ⾏;若需要完整的返回字符串,可以使⽤ PassThru() 这个函数。
-
popen
打开进程文件指针
popen(string $command , string $mode ): resource
打开⼀个指向进程的管道,该进程由派⽣给定的 command 命令执⾏⽽产⽣。
-
passthru
执行外部程序并且自带输出功能
passthru(string $command , int &$return_var = ?): void
同 exec() 函数类似, passthru() 函数 也是⽤来执⾏外部命令( command )的。 当 所执⾏的 Unix 命令输出⼆进制数据, 并且需要直接传送到浏览器的时候, 需要⽤此函 数来替代 exec() 或 system() 函数。
2.4正则表达式
正则表达式描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。
-
普通字符
普通字符包括没有显式指定为元字符的所有可打印和不可打印字符。这包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号。
字符 | 描述 |
---|---|
[ABC] | 匹配 [...] 中的所有字符 |
[^ABC] | 匹配除了 [...] 中字符的所有字符 |
[A-Z] | [A-Z] 表示一个区间,匹配所有大写字母,[a-z] 表示所有小写字母 |
. | 匹配除换行符(\n、\r)之外的任何单个字符,相等于[\n\r] |
[\s\S] | 匹配所有。\s 是匹配所有空白符,包括换行,\S 非空白符,不包括换行。 |
\w | 匹配字母、数字、下划线。等价于 [A-Za-z0-9_] |
-
非打印字符
字符 | 描述 |
---|---|
\cx | 匹配由x指明的控制字符。 |
\f | 匹配一个换页符。 |
\n | 匹配一个换行符。 |
\r | 匹配一个回车符。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。 |
\S | 匹配任何非空白字符。等价于[ \f\n\r\t\v] 。 |
\t | 匹配一个制表符。 |
\v | 匹配一个垂直制表符。 |
-
特殊字符
特殊字符 | 描述 |
---|---|
$ | 匹配输入字符串的结尾位置。 |
() | 标记一个子表达式的开始和结束位置。 |
* | 匹配前面的子表达式零次或多次。 |
+ | 匹配前面的子表达式一次或多次。 |
. | 匹配除换行符 \n 之外的任何单字符。 |
[ | 标记一个中括号表达式的开始。 |
? | 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。 |
\ | 将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。 |
^ | 匹配输入字符串的开始位置,除非在方括号表达式中使用,当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。 |
{ | 标记限定符表达式的开始。 |
| | 指明两项之间的一个选择。 |
-
限定符
限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有 * 或 + 或 ? 或 {n} 或 {n,} 或 {n,m} 共6种。
字符 | 描述 |
---|---|
* | 匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。 |
+ | 匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。 |
? | 匹配前面的子表达式零次或一次。 |
{n} | n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。 |
{n,} | n 是一个非负整数。至少匹配n 次。 |
{n,m} | m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。 |
*和 +限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们的后面加上一个 ? 就可以实现非贪婪或最小匹配。
-
定位符
定位符用来描述字符串或单词的边界。
字符 | 描述 |
---|---|
^ | 匹配输入字符串开始的位置。 |
$ | 匹配输入字符串结尾的位置。 |
\b | 匹配一个单词边界,即字与空格间的位置。 |
\B | 非单词边界匹配。 |
2.5常见的绕过姿势
-
常用符号
-
命令连接符
cmd1 | cmd2 只执行cmd2
cmd1 || cmd2 只有当cmd1执行失败后,cmd2才被执行
cmd1 & cmd2 先执行cmd1,不管是否成功,都会执行cmd2
cmd1 && cmd2 先执行cmd1,只有cmd1执行成功后才执行cmd2,否则不执行cmd2
cmd1 ; cmd2 按顺序依次执行,先执行cmd1再执行cmd2(Linux特有)
-
通配符
? 单个字符
* 零个、单个或多个字符
-
cat绕过
-
空格绕过
1. ${IFS}替换
2. $IFS$1替换
3. ${IFS替换
${IFS}$9
4. %20替换
5. < 和 <> 重定向符替换
6. %09替换(需要php环境)
7. %0a %0b %0c %0d -
敏感字符绕过
-
变量绕过
ctfshow-web31
-
访问/?c=eval($_GET[1]);&1=system('tac(cat) flag.php');
-
-
base64绕过
Base64是网络上最常见的用于传输8Bit
Base64编码是从二进制到字符的过程,可用于在
-
单双引号
-
反斜线
-
连接符
-
php include+伪协议绕过
-
扫描目录
-
printr_扫描目录
1 c=print_r(scandir('.'));#查看当前目录
2 c=print_r(scandir('/'));#查看根目录
3 c=print_r(glob('*'));#查看当前目录
4 c=print_r(glob('/*'));#查看根目录 -
var_dump扫描目录
1 c=var_dump(scandir('.'));#查看当前目录
2 c=var_dump(scandir('/'));#查看根目录
3 c=var_dump(glob('*'));#查看当前目录
4 c=var_dump(glob('/*'));#查看根目录 -
var_export扫描目录
c=var_export(scandir('.'));#查看当前目录
c=var_export(scandir('/'));#查看根目录
c=var_export(glob('*'));#查看当前目录
c=var_exportdump(glob('/*'));#查看根目录 -
glob目录遍历
-
-
无参RCE构造
1 chr():根据ascii码值将数字转换成字符串
2 get_defined_vars() 获取题目相关变量
3 print_r() 函数用于打印变量,以更容易理解的形式展示
localeconv():是一个编程语言函数,返回包含本地数字及货币信息格式的数组。其中数组中
的第一个为点号(.)
4
5 pos():返回数组中的当前元素的值。这里也可以换成current(),作用和pos类似
6 array_reverse():数组逆序
7 scandir():获取目录下的文件
8 next(): 函数将内部指针指向数组中的下一个元素,并输出。
9 current(): 返回数组当前值
10 reset(): 设置当前数组指针指向第一个单元
11 crypt(): 单项字符串散列,相当于将字符串转换为hash等的复杂字符串
12 floor(): 舍去法取整
13 ceil(): 进一法取整
14 sinh/cosh(): 双曲正弦/余弦
scandir(string $directory): array: 列出指定路径中的文件和目录,返回一个 array,
包含有 directory 中的文件和目录。
15 scandir(string $directory): array: 列出指定路径中的文件和目录,返回一个 array,
包含有 directory 中的文件和目录。
16 getcwd(): 获取当前工作目录
-
.的构造
-
查当前目录
-
查倒数第二个文件
-
读最后一个文件
-
目标文件不在当前目录中
-
系统命令构造数字
1 {_} = ""
2 $(())=0
3 $((~$(())))=-1
-
服务器变量构造查询语句
-
常见的系统变量https://www.runoob.com/php/php-get_defined_vars-function.html
-
构建tac
-
构建base64
-
-
以数字和不敏感函数构造敏感函数
1 base_convert(1231231131,10,36) ===>hex2bin
2 hex2bin(dechex(1598506324))=======>_GET
3 $hex2bin(dechex(1598506324))=======>$_GET
-
open_basedir()绕过
-
传脚本绕过
-
ini_set('open_basedir','/');
-
系统命令不受open_basedir的限制
-
一些其他伪协议不受open_basedir的限制
-
-
无数字字符绕过
-
构造POST数据包
通过构造数据包,向⽬标服务器发送⽂件,⽂件已被保存到tmp⽬录下再根据保存的⽂件名的特 性(最后⼀个字⺟为⼤写),筛选⽂件,利⽤ . 执⾏
-
无数字字母绕过正则
通过汉字或者⼀些不可⻅字符,进⾏异或,求与,取反等操作构建字⺟从⽽构建命令,最后显示 的结果是经过url编码的
-
-
FFI扩展(https://www.php.net/manual/zh/class.ffi.php)
这⼀扩展可以让PHP语⾔中使⽤C语⾔中的函数和库
-
FFI::def
-
创建FFI对象,⼀个字符串,包含常规C语⾔中的⼀系列声明(类型、结构、函数、变量等)。
-
FFi::load
-
FFi::scope
-
FFi::new
-
FFi::cast
-
FFi::memcmp
-
FFI::memcpy
-
-
特定函数绕过
-
parse_url
解析 URL,返回其组成部分
-
call_user_func
把第一个参数作为回调函数调用
-
-
不区分大小写
-
-
preg_match绕过
-
不会匹配换行符
在非多行模式下,$会忽略掉句尾的%0a
-
数组绕过
preg_match只匹配字符串不匹配数组,传入数组时返回false
-
无字母数字的webshell
-
-
filter_var
使⽤特定的过滤器过滤⼀个变量
-
-
语法绕过
提前闭合源文件
?>提前闭合源文件的<?php,之后再新创<?php?>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现