学习日志(二)【linux全部命令,http请求头{有例题},Php语法学习】

1. 任务

1.1.1.1.1.1. 知识部分

1.Linux的命令过一遍

2.自行学习http协议,了解http请求与响应,并理解浏览器与服务器是如何通信的,理解浏览器是如何访问网站的【之前有写过,这里简单把之前笔记再看一遍,请求头使用回忆】

3.php学习https://www.runoob.com/php/php-tutorial.html

4.代码执行函数rce

1.1.1.1.1.2. 题目(第一次一般直接抄或复现,这次看看能否独立完成)

2. 知识点学习

2.1. Linux再学习

【个人感觉Linux的命令得过一遍,我用思维导图的形式展出,感觉更清晰一点】

2.1.1. Linux终端命令格式

2.1.1.1.1.1. -man的使用操作键

2.1.2. 常用Linux命令的基本使用

2.1.2.1. 常用Linux命令的基本使用

|--------------|----------------------|-----------------|
| 命令 | 对应英文 | 作用 |
| ls | list | 查看当前文件夹下面内容 |
| pwd | print work directory | 查看当前所在文件夹 |
| cd[目录名] | changge directory | 切换文件夹 |
| touch[文件名] | touch | 如果文件不存在,新建文件 |
| mkdir[目录名] | make directory | 创建目录 |
| rm[文件名] | remove | 删除指定文件 |
| clear | clear | 清屏 |

2.1.2.2. 快捷方式
复制代码
通过上下方向键 ↑ ↓ 来调取过往执行过的Linux命令;

命令或参数仅需输入前几位就可以用 Tab 键补全;

Ctrl + R :用于查找使用过的命令(history命令用于列出之前使用过的所有命令,然后输入!命令加上编号 (!2) 就可以直接执行该历史命令);

Ctrl + L:清除屏幕并将当前行移到页面顶部;

Ctrl + C:中止当前正在执行的命令;

Ctrl + U:从光标位置剪切到行首;

Ctrl + K:从光标位置剪切到行尾;

Ctrl + W:剪切光标左侧的一个单词;

Ctrl + Y:粘贴Ctrl + U | K | Y剪切的命令;

Ctrl + A:光标跳到命令行的开头;

Ctrl + E:光标跳到命令行的结尾;

Ctrl + D:关闭Shell会话;

ctrl + shift + =: 放大终端窗口的字体显示
  
ctrl + -: 缩小终端窗口的字体显示

2.1.3. 其他命令

2.1.3.1. 总出

思维导图展出,学习完后可以快速回忆,查询

2.1.3.2. 查找文件find

用来在 特定的目录下 搜索 符合条件的文件 【找文件】

find [路径] -name "文件名"

  • 如果省略路径,表示在当前文件夹下查找
2.1.3.2.1.1. 栗子
复制代码
1.搜索桌面目录下,文件名包含 1 的文件
find -name "*1*"

2.搜索桌面目录下,所有以 .txt 为扩展名的文件
find -name "*.txt"

3.搜索桌面目录下,以数字 1 开头的文件
find -name "1*"
2.1.3.3. 软链接和硬链接
2.1.3.3.1. 软链接

ln -s 被链接的源文件 链接文件

建立文件的软链接,用通俗的方式讲类似于 Windows 下的快捷方式

  • 没有**-s 选项建立的是一个 硬链接文件,**两个文件占用相同大小的硬盘空间,工作中几乎不会建立文件的硬链接
  • 源文件要使用绝对路径,不能使用相对路径,这样可以方便移动链接文件后,仍然能够正常使用
2.1.3.3.1.1. 栗子
    1. 将桌面目录下的 01.py 移动到 demo/b/c 目录下

    mkdir -p ~/Desktop/demo/b/c
    mv ~/Desktop/01.py ~/Desktop/demo/b/c/ # 把桌面上的01.py移动到目标目录
    cd ~/Desktop # 回到桌面目录准备创建软链接

    1. 在桌面目录下新建 01.py 的 软链接 FirstPython分别使用 相对路径 和 绝对路径 建立 FirstPython 的软链接【一个是简略写法,一个是详细完整的写法】

    1.相对路径创建(源文件只写相对于当前桌面的路径)
    ln -s demo/b/c/01.py FirstPython_relative

    2.绝对路径创建(源文件写完整路径)
    ln -s /home/你的用户名/Desktop/demo/b/c/01.py FirstPython_absolute

替换成你自己的用户名,比如如果是root就是/root/Desktop/...

    1. 将 FirstPython 移动到 demo 目录下,对比使用 相对路径 和 绝对路径 的区别

    mv FirstPython* ~/Desktop/demo/ # 把两个软链接都移动过去
    cd ~/Desktop/demo

  • 👉 相对路径链接(FirstPython_relative) :打开会提示「No such file or directory」,链接失效,因为它存的路径是demo/b/c/01.py,现在它自己在demo目录,找的就是demo/demo/b/c/01.py,这个文件不存在。
  • 👉 绝对路径链接(FirstPython_absolute):可以正常打开、编辑源文件,因为它存的是完整固定路径,和自己在哪没关系。
2.1.3.4. 硬链接{用不到,知道即可}

ln 被链接的源文件 链接文件

在使用 ln 创建链接时,如果没有 -s 选项,会创建一个 硬链接,而不是软链接

2.1.3.4.1.1. 栗子
    1. 在 ~/Desktop/demo 目录下建立 ~/Desktop/demo/b/c/01.py 的硬链接 01_hard
    2. 使用 ls -l 查看文件的硬链接数(硬链接------有多少种方式可以访问文件或者目录)

    cd ~/Desktop/demo
    ln ~/Desktop/demo/b/c/01.py 01_hard

执行ls -l查看,你会看到源文件和硬链接的inode编号一样,硬链接数都变成了2

    1. 删除 ~/Desktop/demo/b/c/01.py ,并且使用 tree 来确认 demo 目录下的三个链接文件文件软硬链接的示意图

    rm ~/Desktop/demo/b/c/01.py
    tree ~/Desktop/demo # 查看目录结构

  • 现在demo目录里,你创建的两个软链接里,只有绝对路径那个能打开,但它也会提示找不到源文件;但硬链接 01_hard****依然可以 正常打开 ,内容和原来的01.py完全一样
  • 这就是硬链接的特性:删除源文件不影响硬链接,因为它们本来就是同一个文件的不同名字。
  • 在 Linux 中,只有文件的 硬链接数 == 0 才会被删除
  • 使用 ls -l 可以查看一个文件的硬链接的数量

文件软硬链接示意图

【在 Linux 中,文件名 和 文件的数据 是分开存储的】

2.1.4. 打包压缩

  • 在不同操作系统中,常用的打包压缩方式是不同的选项 含义
    Windows 常用 rar
    Mac 常用 zip
    Linux 常用 tar.gz
2.1.4.1. 打包 / 解包

tar 是 Linux 中最常用的 备份工具,

此命令可以 把一系列文件 打包到 一个大文件中,也可以把一个 打包的大文件恢复成一系列文件

2.1.4.1.1.1. 打包文件
复制代码
打包文件
tar -cvf 打包文件.tar 被打包文件/路径

-c:--create,创建新的打包文件,这是打包操作的核心参数
-v:--verbose,显示打包过程的详细信息,
    会把当前正在打包的每个文件/目录名打印在屏幕上,方便你看到打包进度
-f 文件名:--file,指定打包后输出的归档文件名,
    这里就是指定输出为test.tar,-f必须放在所有参数的最后,因为它后面要紧跟文件名

如:

cd ~/Desktop

tar -cvf test.tar test_pack/

就是将test_pack/目录下所有文件都打包进test.tar里面

2.1.4.1.1.2. 解包文件

tar -xvf 打包文件.tar

2.1.4.2. 压缩/解压缩
2.1.4.2.1. gzip【用来压缩tar打包的文件】

tar 与 gzip 命令结合可以使用实现文件 打包和压缩

  • tar 只负责打包文件,但不压缩
  • 用 gzip 压缩 tar 打包后的文件,其扩展名一般用 xxx.tar.gz
  • 【在 tar 命令中有一个选项 -z可以调用 gzip ,从而可以方便的实现压缩和解压缩的】
2.1.4.2.1.1. 压缩文件

tar -zcvf 打包文件.tar.gz 被压缩的文件/路径...

栗子:

复制代码
# 先切换到桌面目录
cd ~/Desktop
  
# 把test_pack目录压缩为test.tar.gz
tar -zcvf test.tar.gz test_pack/
2.1.4.2.1.2. 解压缩文件

tar -zxvf 打包文件.tar.gz

栗子:

复制代码
cd ~/Desktop
tar -zxvf test.tar.gz

执行后会直接在当前桌面目录,重新生成 test_pack 文件夹及其内部所有文件,保持原有目录结构。

2.1.4.2.1.3. 解压缩到指定路径

tar -zxvf 打包文件.tar.gz -C 目标路径

  • -C 解压缩到指定目录,注意:要解压缩的目录必须存在

栗子:

比如我们要解压到 /tmp/test_unpack/ 这个目录:

复制代码
# 1. 先创建目标目录(如果不存在)
mkdir -p /tmp/test_unpack/
# 2. 执行解压,指定目标路径
tar -zxvf test.tar.gz -C /tmp/test_unpack/

参数说明:-C(大写)参数的作用是切换解压目标路径,必须放在压缩包文件名之后。

解压后可以用这条命令验证结果:

复制代码
ls /tmp/test_unpack/

你会看到 test_pack 目录已经出现在这个指定路径下了。

2.1.4.2.2. bzip2(two)

【用法与gzip一致】

  • 在 tar 命令中有一个选项**-j**可以调用 bzip2 ,从而可以方便的实现压缩和解压缩的功能

命令格式如下:

压缩文件

tar -jcvf 打包文件.tar.bz2 被压缩的文件/路径...

解压缩文件

tar -jxvf 打包文件.tar.bz2

|----------|----------------------------------------|-------------------------------------|
| 对比维度 | gzip | bzip2 |
| 压缩比 | 较低,对文本通常能压缩到原大小的30%-40%,比bzip2大10%-30% | 更高,相同文件通常比gzip再小10%-30%,对文本类数据优势更明显 |
| 压缩/解压速度 | 更快,计算开销小,实时性好 | 明显更慢,压缩速度通常是gzip的1/4左右 |
| 资源占用 | CPU和内存占用更低 | 内存和CPU消耗更高 |
| 文件后缀 | .gz | .bz2 |

2.1.5. 软件安装

通过 apt 安装/卸载软件

  • apt 是 Advanced Packaging Tool ,是 Linux 下的一款安装包管理工具

  • 可以在终端中方便的 安装/卸载/更新软件包

    1. 安装软件

    $ sudo apt install 软件包

    2. 卸载软件

    $ sudo apt remove 软件名

    3. 更新已安装的包

    $ sudo apt upgrade

2.1.6. 文件和目录常用命令

2.1.6.1. 查看目录内容
2.1.6.1.1. ls 命令说明

ls 是英文单词 list 的简写,其功能为列出目录的内容,是用户最常用的命令之一,类似于 DOS下的 dir 命令

2.1.6.1.2. Linux 下文件和目录的特点

Linux 文件 或者 目录 名称最长可以有 256 个字符参数 含义

  • . 开头的文件为隐藏文件,需要用 -a 参数才能显示
  • . 代表当前目录
  • ... 代表上一级目录
2.1.6.1.3. ls 常用选项

|----|--------------------------|
| 参数 | 含义 |
| -a | 显示指定目录下所有子目录与文件,包括隐藏文件 |
| -l | 以列表方式显示文件的详细信息 |
| -h | 配合 -l 以人性化的方式显示文件大小 |

2.1.6.1.4. ls通配符的使用

|---------|-----------------------|
| 通配符 | 含义 |
| * | 代表任意个数个字符 |
| ? | 代表任意一个字符,至少 1 个 |
| [] | 表示可以匹配字符组中的任一一个 |
| [abc] | 匹配 a、b、c 中的任意一个 |
| [a-f] | 匹配从 a 到 f 范围内的的任意一个字符 |

2.1.6.1.4.1. 栗子
  1. * 代表任意个数(包含0个)的任意字符
  • *.log → 匹配所有.log结尾的日志文件,比如 access.logerror-2024.log
  • data* → 匹配所有以data开头的文件,比如 datadata.csvdatabase
  • *2026* → 匹配文件名中包含2026的任意文件,比如 report-2026.txt2026-04.tar.gz
  1. ? 代表恰好1个任意字符(至少1个,只能是1个)
  • file?.txt → 匹配 file1.txtfileA.txt,不匹配 file.txt(少一个字符)或 file12.txt(多一个字符)
  • ?? → 匹配文件名长度恰好为2个字符的文件/目录
  1. [] 匹配字符组中的任意一个字符

基础用法:

  • [abc].txt → 只匹配 a.txtb.txtc.txt,不匹配 d.txt
    范围用法:
  • file[0-9].txt → 匹配 file0.txt ~ file9.txt 任意一个
  • img[a-z].png → 匹配 imga.pngimgz.png 任意一个
    取反用法(^开头表示不匹配):
  • [^0-9].txt → 匹配文件名第一个字符不是数字的.txt文件,比如 a.txtdata.txt,不匹配 1.txt
2.1.6.2. 切换目录
2.1.6.2.1. cd

cd 是英文单词 change directory 的简写,其功能为更改当前的工作目录,也是用户最常用的命令之一

【注意:Linux 所有的 目录 和 文件名 都是大小写敏感的,即大小写区分,tset与Tset不一样】

|-----------|-------------------------|
| 命令 | 含义 |
| cd | 切换到当前用户的主目录(/home/用户目录) |
| cd ~ | 切换到当前用户的主目录(/home/用户目录) |
| cd . | 保持在当前目录不变 |
| cd ... | 切换到上级目录 |
| cd - | 可以在最近两次工作目录之间来回切换 |

2.1.6.2.2. 相对路径和绝对路径

|--------|----------|--------------|----------------|
| 类型 | 开头特征 | 优点 | 适用场景 |
| 绝对路径 | /~ | 不依赖当前位置,不会出错 | 脚本写固定路径、访问系统目录 |
| 相对路径 | 无斜杠开头 | 更简洁,项目迁移方便 | 日常操作同一项目内的文件 |

2.1.6.2.2.1. 绝对路径示例(以 /~ 开头)

绝对路径是从根目录/家目录开始的完整路径,不管你当前在哪个目录,它都指向唯一位置:

  • /home/yourname/Documents/note.txt:从根目录开始,完整定位到你的文档下的笔记
  • ~/project/ctf/web~ 自动展开为当前用户的家目录,等价于 /home/你的用户名/project/ctf/web
  • /var/www/html/test.php:Apache默认网站根目录的完整绝对路径

回顾:上面的软链接使用绝对路径

ln -s /home/yourname/ctf/payload.php /var/www/html/shell.php

2.1.6.2.2.2. 相对路径示例(不以 / 开头,相对于当前工作目录)

相对路径是相对于你当前所在目录的位置,当前目录变了,同一个相对路径指向的位置也会变:

  • 如果你当前在 /home/你的用户名/ 目录,那么:
    • ./Documents. 代表当前目录 ,等价于 /home/你的用户名/Documents
    • ../opt..代表上级目录 ,等价于 /home/opt
    • project/ctf:从当前目录往下找,等价于 /home/你的用户名/project/ctf
2.1.6.3. 创建和删除操作
2.1.6.3.1. touch**【创建文件或修改文件时间】**
  • 如果文件 不存在,可以创建一个空白文件
  • 如果文件 已经存在,可以修改文件的末次修改日期
2.1.6.3.2. mrdir【创建一个新的目录】

|--------|----------|
| 选项 | 含义 |
| -p | 可以递归创建目录 |

新建目录的名称 不能 与当前目录中 已有的目录或文件 同名

2.1.6.3.3. rm【删除文件或目录】

使用 rm 命令要小心,因为文件删除后不能恢复

|--------|-----------------------------------|
| 选项 | 含义 |
| -f | 强制删除,忽略不存在的文件,无需提示 |
| -r | 递归地删除目录下的内容,删除文件夹 时必须加此参数 |

2.1.6.4. 拷贝和移动文件

|--------------|----------|------------------------|
| 命令 | 对应英文 | 作用 |
| tree [目录名] | tree | 以树状图列出文件目录结构 |
| cp 源文件目标文件 | copy | 复制文件或者目录 |
| mv 源文件 目标文件 | move | 移动文件或者目录/文件或者目录重命名 |

2.1.6.4.1. tree
  • tree 命令可以以树状图列出文件目录结构

|--------|-----------|
| 选项 | 含义 |
| -d | 只显示目录 |

2.1.6.4.1.1. 栗子
  • 展示当前目录所有文件和子目录

    tree

  • 只展示当前目录的子目录(忽略文件):

    tree -d

示例效果:会只列出uploadslogsconfig这类目录,不会列出目录里的脚本文件。

2.1.6.4.2. cp
  • cp 命令的功能是将给出的 文件 或 目录 复制到另一个 文件 或 目录 中,相当DOS 下的 copy命令

|---------|----------------------------------------------------|
| 选 项 | 含义 |
| -i | 覆盖文件前提示 |
| -r | 若给出的源文件是目录文件,则 cp 将递归复制该目录下的所有子目录和文件, 目标文件必须为一个目录名 |

2.1.6.4.2.1. 栗子
  • 复制单个文件:把当前目录的test.php复制一份叫test_backup.php

    cp test.php test_backup.php

  • 复制整个目录 :把dirsearch目录下所有内容,递归复制到/opt/dirsearch

    cp -r ./dirsearch /opt/dirsearch

  • 覆盖前提示:复制payload.txtpayloads目录,如果目标已经有同名文件,会先提示你确认

    cp -i payload.txt payloads/

2.1.6.4.3. mv
  • mv 命令可以用来移动 文件 或 目录,也可以给 文件或目录重命名

|--------|---------|
| 选项 | 含义 |
| -i | 覆盖文件前提示 |

2.1.6.4.3.1. 栗子
  • 重命名文件:把old.php改名为new.php【文件对文件】

    mv old.php new.php

  • 移动文件:把shell.php移动到uploads目录下【文件移到目录下】

    mv shell.php uploads/

  • 移动并覆盖 提示:把test.txt移动到/tmp目录,如果目标已有同名文件,会提示确认

    mv -i test.txt /tmp/

2.1.6.5. 查看文件内容

|---------------|-------------|----------------------------|
| 命令 | 对应英文 | 作用 |
| cat 文件名 | concatenate | 查看文件内容、创建文件、文件合并、追加文件内容等功能 |
| more 文件名 | more | 分屏显示文件内容 |
| grep 搜索文本 文件名 | grep | 搜索文本文件内容 |

2.1.6.5.1. cat

cat 命令可以用来 查看文件内容、创建文件、文件合并、追加文件内容 等功能

cat 会一次显示所有的内容,适合 查看内容较少 的文本文件

|--------|-----------|
| 选项 | 含义 |
| -b | 对非空输出行编号 |
| -n | 对输出的所有行编号 |

2.1.6.5.1.1. 栗子

这个选项就是编号,

复制代码
     1	<?php

     2	echo "this is webshell";

     3	system($_GET['cmd']);

     4	?>

     1	<?php
     2	
     3	echo "this is webshell";
     4	
     5	system($_GET['cmd']);
     6	
     7	?>
2.1.6.5.2. more
  • more 命令可以用于分屏显示文件内容,每次只显示一页内容
  • 适合于 查看内容较多的文本文件

使用 more 的操作键:

|---------|----------------|
| 操作键 | 功能 |
| 空格键 | 显示手册页的下一屏 |
| Enter键 | 一次滚动手册页的一行 |
| b | 回滚一屏 |
| f | 前滚一屏 |
| q | 退出 |
| /word | 搜索word 字符串 |

2.1.6.6. grep

Linux 系统中 grep 命令是一种强大的文本搜索工具

grep 允许对文本文件进行 模式查找,所谓模式查找,又被称为正则表达式

【grep [选项] "匹配模式" [文件/目录路径]】

|--------|----------------------|
| 选项 | 含义 |
| -n | 显示匹配行及行号 |
| -v | 显示不包含匹配文本的所有行(相当于求反) |
| -i | 忽略大小写 |

2.1.6.6.1.1. 栗子
  • 基础搜索:在指定文件中查找包含关键词的行

    在error.log中查找包含"SQL"的行

    grep "SQL" error.log

  • -i 忽略大小写:不区分大小写匹配,避免漏匹配

    匹配Error、error、ERROR等各种形式

    grep -i "error" access.log

  • -n 显示行号:输出匹配行在文件中的具体行号,方便快速定位

    grep -n "eval" webshell.php

  • -v 反向匹配 :只输出不包含 关键词的行,用来过滤无用信息

    筛选出日志中不是"success"的行(看异常)

    grep -v "success" system.log

  • -c 统计匹配行数 :只输出匹配到的总行数,适合快速统计

    统计访问日志里一共出现了多少次404错误

    grep -c " 404 " /var/log/nginx/access.log

  • -r 递归搜索:遍历指定目录下所有子目录和文件搜索

    在当前目录所有PHP文件里找包含"eval"关键词的一句话木马

    grep -r "eval" . --include="*.php"

  • 上下文显示(看报错前后内容很有用)

    • -A n:显示匹配行 + 后面n

    • -B n:显示匹配行 + 前面n

    • -C n:显示匹配行 + 前后各n

      找日志里的fatal错误,并显示错误前后各1行上下文

      grep -C 1 "fatal" /var/log/nginx/error.log

  • 正则匹配:支持正则表达式实现精准匹配

    查找以"[ERROR]"开头的行

    grep "^\[ERROR\]" system.log

    查找包含IP地址的行

    grep -E "[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}" access.log

  • 结合管道的常用技巧

grep经常和其他命令搭配做过滤,非常高效:

复制代码
# 列出当前目录下所有log后缀的文件
ls | grep ".log"
# 实时监控日志,只输出带Timeout的新日志
tail -f service.log | grep "Timeout"
2.1.6.6.1.2. 常用的两种模式查找

|--------|----------------|
| 参数 | 含义 |
| ^a | 行首,搜寻以 a 开头的行 |
| ke$ | 行尾,搜寻以 ke 结束的行 |

2.1.7. 系统信息相关命令

2.1.7.1. 时间和日期

|--------|-----------------------------------|
| 命令 | 作用 |
| date | 查看系统时间 |
| cal | calendar 查看日历, -y 选项可以查看一年的日历 |

【突然想到黑神话悟空的那道题,要注意date的形式,可以去查日历?】

2.1.7.2. 磁盘信息

|---------------|---------------------------|
| 命令 | 作用 |
| df -h | disk free 显示磁盘剩余空间 |
| du -h [目录名] | disk usage 显示目录下的文件大小 |

2.1.7.3. 进程信息【 当前正在执行的一个程序

|------------------|------------------------------|
| 命令 | 作用 |
| ps aux | process status 查看进程的详细状况 |
| top | 动态显示 运行中的进程并且排序 |
| kill [-9] 进程代号 | 终止 指定代号的进程,-9 表示强行终止 |

2.1.7.3.1. ps

ps 默认只会显示当前用户 通过终端启动 的应用程序

ps 选项说明

|--------|--------------------------|
| 选项 | 含义 |
| a | 显示终端上的所有进程,包括其他用户的进程 |
| u | 显示进程的详细状态 |
| x | 显示没有控制终端的进程 |

2.1.7.3.1.1. 栗子

ps aux | grep nginx

过滤出你想要找的进程,比如找nginx

2.1.7.3.2. top

打开一个交互式界面,实时刷新显示进程的CPU、内存使用率,适合排查服务器卡慢问题。

常用交互操作:

  • P:按CPU使用率排序,找出占CPU最高的进程
  • M:按内存使用率排序
  • q:退出top界面
  • 直接输入top就可以启动了
2.1.7.3.3. kill

使用 kill 命令时,最好只终止由当前用户开启的进程,而不要终止 root 身份开启的进程,否则可能导致系统崩溃

2.1.7.3.3.1. 栗子

实用例子:

  1. 先找到占用端口的PHP-FPM进程PID:

    ps aux | grep php-fpm

假设得到进程ID是 1234

  1. 强制杀死这个进程:

    kill -9 1234

其他常见用法:如果要温和停止进程可以不用-9,用kill 进程PID发送默认终止信号,让进程正常退出。

2.1.8. 用户权限相关命令

2.1.8.1. 组管理

【创建组/删除组的终端命令都需要通过sudo执行】

{sudo 是Linux/Unix系统中临时获取管理员权限执行命令的工具}

|--------------------|-----------------------------|
| 命令 | 作用 |
| groupadd 组名 | 添加组 |
| groupdel 组名 | 删除组 |
| cat /etc/group | 确认组信息 |
| chgrp -R 组名 文件/目录名 | 递归修改 文件 /目录的所属组 |

  • 组信息 保存在 /etc/group 文件中
  • /etc 目录是专门用来保存 系统配置信息 的目录
2.1.8.2. 用户管理

【创建用户 / 删除用户 / 修改其他用户密码 的终端命令都需要通过 sudo 执行】

2.1.8.2.1. 创建用户/设置密码/删除用户

|---------------------------|--------|------------------------------------------------------|
| 命令 | 作用 | 说明 |
| useradd -m -g组 新建用户名 | 添加新用户 | -m是自动建立用户家目录【如果忘记就删除用户重新建立】 -g指定用户所在的组,否则建立一个与用户同名的组 |
| passwd 用户名 | 设置用户密码 | 如果是普通用户,直接用passwd修改自己的密码 |
| userdel -r 用户名 | 删除用户 | -r是自动删除用户的家目录 |
| cat/etc/passwd |grep 用户名 | 确认用户信息 | 新建用户后,用户信息会保存在/etc/passwd |

2.1.8.2.1.1. 疑问?家目录是什么

Linux的家目录是每个用户专属的个人存储空间,是用户登录系统后的默认工作目录,用于存放用户的私人文件、配置文件和应用数据。

标准默认路径

  • 普通用户 :默认存放在 /home/用户名,例如用户test的家目录是/home/test
  • 超级管理员root :家目录为独立的/root,不在/home路径下
2.1.8.2.2. 查看用户信息

|------------|---------------------|
| 命令 | 作用 |
| id [用户名] | 查看用户UID 和 GID信息 |
| who | 查看当前所有登录的用户列表 |
| whoami | 查看当前登录用户的账户名 |

2.1.8.2.2.1. uid,gid是什么意思

UID(User ID,用户ID)和GID(Group ID,组ID)是Linux系统权限管理的核心数字标识符,系统通过它们而非用户名/组名来判断权限。

|---------|----------|---------------------------------|----------------------------------------------------------------------------------|
| 标识符 | 作用对象 | 核心作用 | 常见ID范围 |
| UID | 单个用户 | 唯一标识系统用户, 决定用户对系统资源(文件/进程)的访问权限 | <br>- 0:root超级用户(最高权限)<br>- 1~999:系统服务/守护进程专用(系统用户) <br>- ≥1000:普通用户 |
| GID | 用户组 | 唯一标识用户组, 简化同组用户的共享权限分配 | <br>- 0:root用户组 <br>- 1~999:系统预留组 <br>- ≥1000:普通用户组 |

2.1.8.2.2.2. uid,gid使用栗子

所有用户和组的UID/GID信息都明文存储在两个系统配置文件中:

  1. /etc/passwd:存储所有用户信息,每行格式为:

    用户名:密码占位符(x):UID:GID:用户说明:家目录:登录Shell

示例(root用户条目):

复制代码
root:x:0:0:root:/root:/bin/bash

可以看到:root的UID=0、GID=0。

  1. /etc/group:存储所有用户组信息,包含组成员列表。

查看当前/指定用户的UID/GID

复制代码
# 查看当前登录用户
id
# 查看指定用户(比如test)
id test

输出示例:

复制代码
uid=1000(test) gid=1000(test) groups=1000(test),4(adm)

其中gid是用户主组GID ,后面groups是用户加入的所有附加组。

2.1.8.2.2.3. uid,gid涉及到一个考点(漏洞)

权限提升风险 :只要用户的UID被设置为0,无论用户名是什么,都会被内核识别为root,获得最高权限。攻击者常会通过修改普通用户UID为0来实现提权。

可以用命令排查异常特权用户:

复制代码
# 找所有UID为0的异常用户
awk -F: '$3 == 0 {print $1}' /etc/passwd
2.1.8.2.2.4. which

which命令可以查看执行命令所在位置,【注意,cd不行】

复制代码
which ls
# 输出
# /bin/ls
  
which useradd
# 输出
# /usr/sbin/useradd
2.1.8.2.2.5. bin 和 sbin

在 Linux 中,绝大多数可执行文件都是保存在 /bin 、 /sbin 、 /usr/bin 、 /usr/sbin

/bin ( binary )二进制执行文件目录,主要用于具体应用

/sbin ( system binary )是系统管理员专用的二进制代码存放目录,主要用于系统管理

/usr/bin ( user commands for applications )后期安装的一些软件

/usr/sbin ( super user commands for applications )超级用户的一些管理程序

2.1.8.2.3. 切换用户

|----------|-----------------|---------------------|
| 命令 | 作用 | 说明 |
| su - 用户名 | 切换用户,并且切换目录 | 可以切换到用户家目录,否则保持位置不变 |
| exit | 退出当前登录账户 | |

2.1.8.2.3.1. 注意有没有带-

|------------|--------------|--------------|------------------------|
| 命令 | 环境变量 | 工作目录 | 适用场景 |
| su - 用户名 | 加载目标用户的完整环境 | 自动切到目标用户家目录 | 需要以目标用户完整身份操作时(推荐标准用法) |
| su 用户名 | 保留当前原用户的环境变量 | 留在原用户的当前工作目录 | 只需要切换身份但保留当前环境时 |

  • 普通用户切换到任何其他用户都需要输入目标用户的密码;
  • root切换到任何用户都不需要密码。【我突然在思考一个问题,没别的意思,如果老大要看地下员工工作情况,可以直接切换账号进来吗】
2.1.8.2.4. 切换文件权限

|--------|--------|
| 命令 | 作用 |
| chown | 修改拥有者 |
| chgrp | 修改组 |
| chmod | 修改权限 |

命令:

复制代码
# 修改文件|目录的拥有者
chown 用户名 文件名|目录名
  
# 递归修改文件|目录的组
chgrp -R 组名 文件名|目录名
  
# 递归修改文件权限
chmod -R 755 文件名|目录名

2.1.9. 远程管理常用命令

2.1.9.1. 关机/重启

|----------|----------------|---------|
| 命令 | 对应英文 | 作用 |
| shutdown | 选项 时间 shutdown | 关机/重新启动 |

命令

复制代码
# 重新启动操作系统,其中 now 表示现在
$ shutdown -r now
  
# 立刻关机,其中 now 表示现在
$ shutdown now
  
# 系统在今天的 20:25 会关机
$ shutdown 20:25
  
# 系统再过十分钟后自动关机
$ shutdown +10
  
# 取消之前指定的关机计划
$ shutdown -c
  • 不指定选项和参数,默认表示 1 分钟之后 关闭电脑
  • 远程维护服务器时,最好不要关闭系统,而应该重新启动系统
2.1.9.2. 查看配置网卡信息

|-----------|-------------------------------|------------------------|
| 命令 | 对应英文 | 作用 |
| ifconfig | configure a network interface | 查看/配置计算机当前的网卡配置信息 |
| ping ip地址 | ping | 检测到目标 ip地址 的连接是否正常 |

2.1.9.2.1. ifconfig

ifconfig是Linux早期经典的网卡配置查看工具 ,全称是interface configuration ,属于net-tools工具包(部分新版系统默认不预装)。

2.1.9.2.1.1. 基础用法
  1. 查看全部网卡的完整配置信息

    $ ifconfig

  2. 过滤提取所有IP地址

    $ ifconfig | grep inet

2.1.9.2.1.2. ✅ 补充要点
  • 网卡命名规则:一台计算机通常会包含多种网卡:
    • 物理网卡:新版Linux(CentOS 7+/Ubuntu 15+)默认命名为ensXXenp0sX,老式命名为eth0/eth1
    • 虚拟网卡:比如Docker的docker0、VMware虚拟机的vmnet、本地环回lo
  • 本地回环地址 127.0.0.1:专门用于本机进程间网络通信,永远代表本机本身,通常用来测试本机TCP/IP协议栈是否正常工作。【一般用来测试本机网卡是否正常】
2.1.9.2.2. ping

ping命令用于检测本机到目标主机之间的网络连通性和延迟质量,它的命名取自声纳探测的回声,网络中也常用作动词:比如"ping一下这个IP看看有没有开机"。

【ping 一般用于检测当前计算机到目标计算机之间的网络 是否通畅,数值越大,速度越慢

2.1.9.2.2.1. 基础用法
  1. 检测到目标主机的连通状态

    $ ping <IP地址或域名>

示例:ping www.baidu.com

  1. 检测本地网卡/TCP协议栈是否正常

    $ ping 127.0.0.1

2.1.9.2.2.2. ✅ 补充要点
  • 工作原理 :ping基于ICMP协议,向目标主机发送Echo Request(回声请求)数据包,如果目标主机在线且允许ICMP请求,就会回复Echo Reply(回声应答);
  • 延迟判断 :输出中的time=xx ms就是本次请求往返的延迟,数值越大说明网络延迟越高,连接质量越差;
  • 常用参数 :默认Linux下ping会一直发包,按Ctrl+C停止;如果只需要指定发包次数,可以加-c参数:ping -c 4 127.0.0.1(发送4个包后自动停止);
  • 排坑提示:ping不通不代表目标一定不在线,很多服务器会开启防火墙拦截ICMP数据包,此时需要结合其他端口检测方式(比如telnet、nc)进一步验证。
2.1.9.3. 远程登录和赋值文件

|--------------------|---------|
| 命令 | 作用 |
| ssh 用户@ip | 关机/重新开机 |
| scp 用户名 @ip:文件名或路径 | 远程复制文件 |

2.1.9.3.1. ssh

SSH 全称Secure Shell(安全外壳协议) ,是目前最主流的加密远程通信协议,专为解决传统远程工具的安全缺陷而生。

通过 SSH 客户端 我们可以连接到运行了 SSH 服务器 的远程机器

使用:ssh [-p port] user@remote

  • user 是在远程机器上的用户名,如果不指定的话默认为当前用户
  • remote 是远程机器的地址,可以是 IP/域名,或者是 后面会提到的别名
  • port 是 SSH Server 监听的端口,如果不指定,就为默认值 22

栗子:

如:远程登录服务器

复制代码
# 标准用法:用户名@服务器IP/域名
ssh user@192.168.1.100

# 指定非默认端口
ssh -p 2222 user@your-server.com
2.1.9.3.2. scp

它的地址格式与 ssh 基本相同,需要注意的是,在指定端口时用的是大写的 -P 而不是小写的

scp [参数] 源路径 目标路径

第一个参数永远是要复制的文件/目录,第二个参数是保存位置,不需要刻意区分本地和远端,只需要按照规则写路径即可。】

2.1.9.3.2.1. 常用参数说明

|--------|--------------------------------------------------------------------|
| 参数 | 作用 |
| -r | 递归复制,传输目录时必须加 【若给出的源文件是目录文件,则 scp 将递归复制该目录下的所有子目录和文件,目标文件必须为一个目录名】 |
| -P | 大写P,指定远程 SSH 端口(默认22),非默认端口必须指定 |
| -p | 小写p,保留源文件的修改时间、访问时间和权限 【保留文件的属性】 |
| -C | 启用压缩传输,大文件、慢网络下可节省带宽 |
| -v | 显示详细传输过程,适合调试连接问题 |
| -q | 静默模式,隐藏传输进度条 |
| -l | 限制传输带宽,单位为 kbit/s,避免占满整个网络 |
| -i | 指定密钥文件,适合基于公钥免密登录的场景 |

2.1.9.3.2.2. 常见场景使用示例
  1. 本地 → 远程:上传文件

    上传单个文件

    scp /本地路径/test.txt root@192.168.1.100:/远程目标路径/

    上传整个目录(必须加 -r)

    scp -r /本地路径/项目目录 root@192.168.1.100:/远程目标路径/

    远程SSH端口非默认(如2222)的情况

    scp -P 2222 ./test.txt root@192.168.1.100:/data/

  2. 远程 → 本地:下载文件

只需要调换源路径和目标路径的顺序即可:

复制代码
# 下载单个文件到本地当前目录(. 代表当前目录)
scp root@192.168.1.100:/var/log/nginx.log .

# 下载整个目录到本地
scp -r root@192.168.1.100:/var/log/nginx ~/本地备份目录/
  1. 远程 → 远程:直接中转(本地当跳板)

如果需要在两台远程服务器之间直接传文件,本地同时能连通两台的情况下可以直接传输,不需要先下载再上传:

复制代码
scp user1@主机1IP:/源文件路径 user2@主机2IP:/目标路径

2.2. http请求头

  • http请求头有哪些?-CSDN博客

    HTTP Request Header 请求头
    Accept:指定客户端能够接收的内容类型。

    Accept-Charset:浏览器可以接受的字符编码集。

    Accept-Encoding:指定浏览器可以支持的web服务器返回内容压缩编码类型。

    Accept-Language:浏览器可接受的语言。

    Accept-Ranges:可以请求网页实体的一个或者多个子范围字段。

    AuthorizationHTTP:授权的授权证书。

    Cache-Control:指定请求和响应遵循的缓存机制。

    Connection:表示是否需要持久连接。(HTTP 1.1默认进行持久连接)

    CookieHTTP:请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器。

    Content-Length:请求的内容长度。

    Content-Type:请求的与实体对应的MIME信息。

    Date:请求发送的日期和时间。

    Expect:请求的特定的服务器行为。

    From:发出请求的用户的Email。

    Host:指定请求的服务器的域名和端口号。

    If-Match:只有请求内容与实体相匹配才有效。

    If-Modified-Since:如果请求的部分在指定时间之后被修改则请求成功,未被修改则返回304代码。

    If-None-Match:如果内容未改变返回304代码,参数为服务器先前发送的Etag,与服务器回应的Etag比较判断是否改变。

    If-Range:如果实体未改变,服务器发送客户端丢失的部分,否则发送整个实体。

    If-Unmodified-Since:只在实体在指定时间之后未被修改才请求成功。

    Max-Forwards:限制信息通过代理和网关传送的时间。

    Pragma:用来包含实现特定的指令。

    Proxy-Authorization:连接到代理的授权证书。

    Range:只请求实体的一部分,指定范围。

    Referer:先前网页的地址,当前请求网页紧随其后,即来路。

    TE:客户端愿意接受的传输编码,并通知服务器接受接受尾加头信息。

    Upgrade:向服务器指定某种传输协议以便服务器进行转换(如果支持。

    User-AgentUser-Agent:的内容包含发出请求的用户信息。

    Via:通知中间网关或代理服务器地址,通信协议。

    Warning:关于消息实体的警告信息

2.2.1.1.1. Host【域名】

Host: xxx.com

  • 作用:告诉服务器访问哪个域名/站点

  • 考点:虚拟主机、绕过限制、子域名探测

2.2.1.1.2. User-Agent(UA)【浏览器,设备】

User-Agent: Mozilla/5.0...

  • 作用:告诉服务器你是什么浏览器/设备

  • 考点:- 过滤禁止爬虫/特定浏览器

  • 伪造手机端、爬虫、绕过WAF

  • CTF常考:UA写入漏洞、UA过滤

2.2.1.1.3. Referer【网页.com,本站访问】

Referer: https://www.baidu.com

  • 作用:记录你从哪个页面跳转过来

  • 考点:- 防盗链检测(只允许本站访问)

  • 伪造来路绕过权限校验

2.2.1.1.4. Cookie【键值对】

Cookie: username=admin; token=123456

  • 核心重点!

  • 作用:存用户登录身份、凭证、权限、自定义参数

  • 考点最多:- 改Cookie伪造管理员

  • Cookie注入、越权、session劫持

  • 题目: isadmin=0 改成 isadmin=1 直接通关

2.2.1.1.5. X-Forwarded-For(XFF)【IP地址限制】

X-Forwarded-For: 127.0.0.1

  • 作用:伪造客户端IP地址

  • 万能考点:- 服务器限制本地访问(仅127.0.0.1可看)

  • 直接加这个头伪装成内网/本地IP绕过

2.2.1.1.6. X-Real-IP【同X-Forwarded-For】
  • 和XFF类似,也是伪造真实IP,部分服务器优先读这个
2.2.1.1.7. Content-Type【数据类型,如图片。。】

Content-Type: application/x-www-form-urlencoded

  • 作用:告诉服务器提交的数据是什么格式

  • 常用:- 表单普通提交: x-www-form-urlencoded

  • JSON提交: application/json

  • 文件上传: multipart/form-data

  • 考点:格式不对403/报错,改格式绕过检测

2.2.1.1.8. Accept / Accept-Language
  • 一般不常考,部分题目用来过滤地区、语言
2.2.1.1.9. Authorization
  • 基础认证登录,用来爆破、伪造账号密码
2.2.1.1.10. Origin
  • 跨域请求源头,配合CSRF漏洞使用
2.2.1.1.11. Cache-Control
  • 控制缓存,部分源码泄露、缓存漏洞用到

2.3. php学习

https://www.runoob.com/php/php-variables.html

2.3.1. php语法

2.3.1.1. 基础语法
  • PHP 脚本以 <?php 开始,以 ?> 结束

    <?php ?>
  • PHP 文件的默认文件扩展名是 .php

  • PHP 文件通常包含 HTML 标签和一些 PHP 脚本代码

  • 每条语句末尾要加 ;

  • 有两种在浏览器输出文本的基础指令:echoprint 【注意区分,后面细说】

2.3.1.2. 注释

|----------|-----------------------|--------------------|
| 用途 | 推荐注释形式 | 示例 |
| 简单说明一行代码 | //# | // 输出信息 |
| 说明一段代码块 | /* ... */ | 用于逻辑分块的注释 |
| 函数/类文档说明 | /** ... */ DocBlock | 用于描述参数、返回值、用途等 |

2.3.2. php变量

变量是用于存储数据的容器

2.3.2.1.1.1. PHP 变量规则:
  • 变量以**$** 符号开始,后面跟着变量的名称
  • 变量名必须以字母或者下划线字符开始
  • 变量名只能包含字母、数字以及下划线(A-z、0-9 和 _ )
  • 变量名不能包含空格
  • 变量名是区分大小写的y 和 Y 是两个不同的变量)
2.3.2.1. 创建(声明)变量
  • 变量在您第一次赋值给它的时候被创建

  • PHP 会根据变量的值,自动把变量转换为正确的数据类型【因为是弱类型】

    <?php $txt="Hello world!"; $x=5; $y=10.5; ?>

当您赋一个文本值给变量时,请在文本值两侧加上引号

2.3.2.2. 变量作用域

变量的作用域是脚本中变量可被引用/使用的部分

PHP 有四种不同的变量作用域:

  • local
  • global
  • static
  • parameter

|---------------------|-----------------------------------------|----------------------------------------------------------------------|
| 概念 | PHP中的核心含义 | 作用域 |
| local(局部变量) | 在函数/类方法内部声明的变量 | 仅当前函数/方法内部可访问,外部无法读取或修改 |
| global(全局变量) | 在函数外部 声明的变量,或在函数内用global 关键字修饰的变量 | - 直接声明在函数外:默认整个脚本全局可访问<br>- 在函数内用global 修饰:可以引入函数外的同名全局变量到函数作用域内 |
| static(静态变量) | 在函数/类内部用static 关键字修饰的变量 | 和局部变量一致,仅函数/类内部可访问 |
| parameter(参数变量) | 函数定义时声明的输入参数,本质也是局部变量 | 仅当前函数内部可访问 |

补充:

【注意:全局与局部

【局部变量,只作用于该函数内】

【如果要在一个函数中访问一个全局变量,需要使用 global 关键字】

2.3.2.2.1. PHP global 关键字

在函数内调用函数外定义的全局变量,我们需要在函数中的变量前加上 global 关键字:

2.3.2.2.2. Static 作用域

当一个函数完成时,它的所有变量通常都会被删除。然而,有时候您希望某个局部变量不要被删除。

要做到这一点,请在您第一次声明变量时使用 static 关键字:

2.3.2.2.2.1. 栗子:

举一个普通局部变量和静态变量的对比

  1. 普通局部变量

    function countVisitor(){
    num = 0; // 普通局部变量 num = num + 1; echo "当前计数:".num."
    ";
    }

    // 连续调用3次
    countVisitor();
    countVisitor();
    countVisitor();

输出结果:

复制代码
当前计数:1
当前计数:1
当前计数:1

为什么每次都是1?因为普通局部变量$num

  • 每次调用函数都会重新 创建、重新赋值为0
  • 函数运行完就销毁,根本不会保留上次的结果

  1. 静态变量(点出核心区别)

把代码改成static

复制代码
function countVisitor(){
    static $num = 0; // 静态变量
    $num = $num + 1;
    echo "当前计数:".$num."<br>";
}

// 同样连续调用3次
countVisitor();
countVisitor();
countVisitor();

输出结果:

复制代码
当前计数:1
当前计数:2
当前计数:3

这就是静态变量的核心特点:

只初始化一次,值会一直保留,整个脚本运行周期都不会销毁,下次调用会沿用上次修改后的值。

而且它还是局部变量:只有这个函数内部能访问它,外部改不了它,既保留了数据,又不会污染全局,非常适合做计数这类场景。

2.3.2.3. 参数作用域

【专门用来接收函数输入的局部变量】

参数是通过调用代码将值传递给函数的局部变量。

参数是在参数列表中声明的,作为函数声明的一部分:

外部不可访问、用完销毁,接收外部输入**【前俩者局部变量也是】**

2.3.3. PHP 5 echo 和 print 语句

2.3.3.1. echo 和 print 区别:

|------------|--------------|-------------|
| 对比维度 | echo | print |
| 返回值 | 无返回值 | 总是固定返回整数1 |
| 参数数量 | 支持多个参数,用逗号分隔 | 仅支持1个参数 |
| 执行性能 | 略快(不需要处理返回值) | 稍慢 |
| 表达式中使用 | 不可以 | 可以(因为有返回值) |

2.3.3.2. 栗子
  1. 参数数量差异

    // echo支持多参数输出
    echo "Hello", " ", "World", "!"; // 正常输出:Hello World!

    // print只能传一个参数,这么写会报错
    // print "Hello", "World"; // 语法错误
    print "Hello World!"; // 正确写法

  2. 返回值和表达式用法差异
    因为print固定返回1,所以可以把它放在条件判断这类表达式里:

    // 这种写法是合法的,print输出内容后返回1,条件恒成立
    if (print "检查输出") {
    echo "会执行这里";
    }
    // echo就不能这么用,语法直接报错

2.3.4. php数据类型

PHP 支持以下几种数据类型:

  • String(字符串)
  • Integer(整型)
  • Float(浮点型)
  • Boolean(布尔型)
  • Array(数组)
  • Object(对象)
  • NULL(空值)
  • Resource(资源类型)
2.3.4.1. php字符串

一个字符串是一串字符的序列,就像 "Hello world!"。

你可以将任何文本放在单引号和双引号中:

复制代码
<?php 
$x = "Hello world!";
echo $x;
echo "<br>"; 
$x = 'Hello world!';
echo $x;
?>
2.3.4.2. PHP 整型

整数是一个没有小数的数字。

整数规则:

  • 整数必须至少有一个数字 (0-9)
  • 整数不能包含逗号或空格
  • 整数是没有小数点的
  • 整数可以是正数或负数
  • 整型可以用三种格式来指定:十进制, 十六进制( 以 0x 为前缀)或八进制(前缀为 0)。

【var_dump是输出这个变量的信息,如数值和数据类型】

2.3.4.3. PHP 浮点型

浮点数是带小数部分的数字,或是指数形式。

2.3.4.4. PHP 布尔型

布尔型可以是 TRUE FALSE

布尔型通常用于条件判断

$x=true;
$y=false;

2.3.4.5. PHP 数组

数组可以在一个变量中存储多个值

复制代码
<?php 
$cars=array("Volvo","BMW","Toyota");
var_dump($cars);
?>

结果,会具体写出长度5,类型string,数值"volvo"

2.3.4.6. PHP 对象

对象数据类型也可以用于存储数据。

在 PHP 中,对象必须声明。

首先,你必须使用class关键字声明类对象。类是可以包含属性和方法的结构。

然后我们在类中定义数据类型,然后在实例化的类中使用数据类型:

复制代码
<?php
class Car
{
  var $color;
  function __construct($color="green") {
    $this->color = $color;
  }
  function what_color() {
    return $this->color;
  }
}
?>

以上实例中PHP关键字this就是指向当前对象实例的指针,不指向任何其他对象或类。

2.3.4.7. PHP NULL 值

NULL 值表示变量没有值。NULL 是数据类型为 NULL 的值。

NULL 值指明一个变量是否为空值。 同样可用于数据空值和NULL值的区别。

可以通过设置变量值为 NULL 来清空变量数据

复制代码
<?php
$x="Hello world!";
$x=null;
var_dump($x);
?>
2.3.4.8. PHP 资源类型

PHP 资源resource是一种特殊变量,保存了到外部资源的一个引用。

常见资源数据类型有打开文件、数据库连接、图形画布区域等。

由于资源类型变量保存有为打开文件、数据库连接、图形画布区域等的特殊句柄,因此将其它类型的值转换为资源没有意义。

使用 get_resource_type() 函数可以返回资源(resource)类型:

get_resource_type(resource $handle): string

2.3.5. PHP 类型比较

虽然 PHP 是弱类型语言,但也需要明白变量类型及它们的意义,因为我们经常需要对 PHP 变量进行比较,包含松散和严格比较。

  • 松散比较:使用两个等号 == 比较,只比较值,不比较类型。
  • 严格比较:用三个等号 === 比较,除了比较值,也比较类型。
2.3.5.1. 栗子
复制代码
<?php
if(42 == "42") {
    echo '1、值相等';
}
 
echo PHP_EOL; // 换行符
 
if(42 === "42") {
    echo '2、类型相等';
} else {
    echo '3、类型不相等';
}
?>

结果:

1、值相等

3、类型不相等

2.3.5.2. PHP中 比较 0、false、null
复制代码
<?php
echo '0 == false: ';
var_dump(0 == false);
echo '0 === false: ';
var_dump(0 === false);
echo PHP_EOL;
echo '0 == null: ';
var_dump(0 == null);
echo '0 === null: ';
var_dump(0 === null);
echo PHP_EOL;
echo 'false == null: ';
var_dump(false == null);
echo 'false === null: ';
var_dump(false === null);
echo PHP_EOL;
echo '"0" == false: ';
var_dump("0" == false);
echo '"0" === false: ';
var_dump("0" === false);
echo PHP_EOL;
echo '"0" == null: ';
var_dump("0" == null);
echo '"0" === null: ';
var_dump("0" === null);
echo PHP_EOL;
echo '"" == false: ';
var_dump("" == false);
echo '"" === false: ';
var_dump("" === false);
echo PHP_EOL;
echo '"" == null: ';
var_dump("" == null);
echo '"" === null: ';
var_dump("" === null);

结果:

复制代码
0 == false: bool(true)
0 === false: bool(false)

0 == null: bool(true)
0 === null: bool(false)

false == null: bool(true)
false === null: bool(false)

"0" == false: bool(true)
"0" === false: bool(false)

"0" == null: bool(false)
"0" === null: bool(false)

"" == false: bool(true)
"" === false: bool(false)

"" == null: bool(true)
"" === null: bool(false)
2.3.5.3. 一些些

2.3.6. php常量

    • PHP 中的常量是指一旦定义后其值不能被改变的标识符。
    • 常量值被定义后,在脚本的其他任何地方都不能被改变。
    • 常量可以用 define() 函数或 const 关键字来定义。
    • 全局作用域 : 常量在定义后,可以在整个脚本的任何地方使用,无需使用 global 关键字。

【在函数内调用函数外定义的全局变量,我们需要在函数中的变量前加上 global 关键字】

    • 一个常量由英文字母、下划线、和数字组成,但数字不能作为首字母出现。 (常量名不需要加 $ 修饰符)。
2.3.6.1. 设置 PHP 常量【define

设置常量,使用 define() 函数,函数语法如下:

bool define ( string $name , mixed $value [, bool $case_insensitive = false ] )

该函数有三个参数:

  • name**:** 必选参数,常量名称,即标志符。
  • value**:** 必选参数,常量的
  • case_insensitive:可选参数,如果设置为 TRUE,该常量则大小写不敏感,默认是大小写敏感的。

栗子:

复制代码
<?php
// 区分大小写的常量名
define("GREETING", "欢迎访问 Runoob.com");
echo GREETING;    // 输出 "欢迎访问 Runoob.com"
echo '<br>';
echo greeting;   // 输出 "greeting",但是有警告信息,表示该常量未定义
?>
2.3.6.2. 设置PHP常量【const】

const CONSTANT_NAME = "value";

以下是一个使用 const 关键字定义常量的实例:

复制代码
const SITE_URL = "https://www.runoob.com";
echo SITE_URL;

// 输出 "https://www.runoob.com"
2.3.6.3. 预定义常量

PHP 提供了一些预定义常量,可以在脚本中直接使用

这些常量通常用于获取 PHP 的配置信息、版本信息等。常见的预定义常量有:

  • PHP_VERSION:当前 PHP 解析器的版本。
  • PHP_OS:服务器的操作系统。
  • PHP_INT_MAX最大的整数值
  • E_ERRORE_WARNINGE_PARSE 等:错误报告级别。

【直接echo就行了,echo PHP_VERSION ; // 输出 PHP 版本,例如 "7.4.1"

2.3.6.4. 常量数组

define是用的("#",[]); const是用的 #=[,];

2.3.7. PHP的字符串

字符串变量用于存储并处理文本

【字符串变量用于包含有字符的值。】

对应的函数有特别多,https://www.runoob.com/php/php-ref-string.html

这里提三个

  1. 创建字符串

$text="hello word";

  1. PHP 并置运算符

使用.进行连接

如:$text1." ".$text2;

  1. PHP strlen() 函数

echo strlen("Hello world!");

  1. PHP strpos() 函数

strpos() 函数用于在字符串内查找一个字符或一段指定的文本。

echo strpos("Hello world!","world");

注意,从字符0开始算,找"world"第一个字符,即为6(不是7)

2.3.8. PHP运算符

在 PHP 中,赋值运算符 = 用于给变量赋值。

在 PHP 中,算术运算符 + 用于把值加在一起。

2.3.8.1. PHP算术运算符

|-------------|------------|-----------------------------------------|----------------------------|-------|
| 运算符 | 名称 | 描述 | 实例 | 结果 |
| x + y | 加 | x 和 y 的和 | 2 + 2 | 4 |
| x - y | 减 | x 和 y 的差 | 5 - 2 | 3 |
| x * y | 乘 | x 和 y 的积 | 5 * 2 | 10 |
| x / y | 除 | x 和 y 的商 | 15 / 5 | 3 |
| x % y | 模 [除法余数] | x 除以 y 的余数 | 5 % 2 10 % 8 10 % 2 | 1 2 0 |
| intdiv(x,y) | 整除 | 返回值为第一个参数除于第二个参数的值并取整(向下取整) | 10%3 | 3 |
| -x | 设置负数 | 取 x 的相反符号 | <?php $x = 2; echo -$x; ?> | -2 |
| ~x | 取反 | x 取反,按二进制位进行"取反"运算。 运算规则: ~1=-2; ~0=-1; | <?php $x = 2; echo ~$x; ?> | -3 |
| a . b | 并置 | 连接两个字符串 | "Hi" . "Ha" | HiHa |

2.3.8.1.1. 取反【进一步解释栗子】
  • 正数的补码 = 原码(本身的二进制)
  • 负数的补码 = 原码符号位不变,其余位取反后加1
  • 按位取反~操作是:把二进制的所有位0变1、1变0,包括符号位
  • 通用公式:::对整数 n****按位取反,结果永远是 ~n = -(n+1)
2.3.8.1.2. 加减乘除
复制代码
<?php 
$x=10; 
$y=6;
echo ($x + $y); // 输出16
echo '<br>';  // 换行
 
echo ($x - $y); // 输出4
echo '<br>';  // 换行
 
echo ($x * $y); // 输出60
echo '<br>';  // 换行
 
echo ($x / $y); // 输出1.6666666666667
echo '<br>';  // 换行
 
echo ($x % $y); // 输出4
echo '<br>';  // 换行

var_dump(intdiv($x, $y));
//输出int(1)

 
echo -$x;
?>
2.3.8.2. PHP赋值运算符

基本的赋值运算符是 =。它意味着左操作数被设置为右侧表达式的值。

|---------|------------|-----------------|
| 运算符 | 等同于 | 描述 |
| x = y | x = y | 左操作数被设置为右侧表达式的值 |
| x += y | x = x + y | 加 |
| x -= y | x = x - y | 减 |
| x *= y | x = x * y | 乘 |
| x /= y | x = x / y | 除 |
| x %= y | x = x % y | 模(除法的余数) |
| a .= b | a = a . b | 连接两个字符串 |

2.3.8.2.1. 栗子

上面运算符使用

复制代码
<?php 
$x=10; 
echo $x; // 输出10
 
$y=20; 
$y += 100;
echo $y; // 输出120
 
$z=50;
$z -= 25;
echo $z; // 输出25
 
$i=5;
$i *= 6;
echo $i; // 输出30
 
$j=10;
$j /= 5;
echo $j; // 输出2
 
$k=15;
$k %= 4;
echo $k; // 输出3
?>

不同运算符可以得到相同的结论

复制代码
<?php
$a = "Hello";
$b = $a . " world!";
echo $b; // 输出Hello world! 
 
$x="Hello";
$x .= " world!";
echo $x; // 输出Hello world! 
?>
2.3.8.3. PHP递增/递减运算符【已忘,易混】

【符号在变量前面,就先处理符号再返回值】

|------|-----|---------------|
| 运算符 | 名称 | 描述 |
| ++ x | 预递增 | x 加 1,然后返回 x |
| x ++ | 后递增 | 返回 x,然后 x 加 1 |
| -- x | 预递减 | x 减 1,然后返回 x |
| x -- | 后递减 | 返回 x,然后 x 减 1 |

2.3.8.3.1. 栗子
复制代码
<?php
$x=10; 
echo ++$x; // 输出11
 
$y=10; 
echo $y++; // 输出10
 
$z=5;
echo --$z; // 输出4
 
$i=5;
echo $i--; // 输出5
?>
2.3.8.4. PHP比较运算符

|----------|-------|-------------------------------|------------------|
| 运算符 | 名称 | 描述 | 实例 |
| x == y | 等于 | 如果 x 等于 y,则返回 true | 5==8 返回 false |
| x === y | 绝对等于 | 如果 x 等于 y,且它们类型相同,则返回 true | 5==="5" 返回 false |
| x != y | 不等于 | 如果 x 不等于 y,则返回 true | 5!=8 返回 true |
| x <> y | 不等于 | 如果 x 不等于 y,则返回 true | 5<>8 返回 true |
| x !== y | 不绝对等于 | 如果 x 不等于 y, 或它们类型不相同,则返回 true | 5!=="5" 返回 true |
| x > y | 大于 | 如果 x 大于 y,则返回 true | 5>8 返回 false |
| x < y | 小于 | 如果 x 小于 y,则返回 true | 5<8 返回 true |
| x >= y | 大于等于 | 如果 x 大于或者等于 y, 则返回 true | 5>=8 返回 false |
| x <= y | 小于等于 | 如果 x 小于或者等于 y, 则返回 true | 5<=8 返回 true |

2.3.8.4.1. 栗子
2.3.8.5. PHP逻辑运算符

|----------|----|---------------------------------|---------------------------------------|
| 运算符 | 名称 | 描述 | 实例 |
| x and y | 与 | 如果 x 和 y 都为 true,则返回 true | x=6 y=3 (x < 10 and y > 1) 返回 true |
| x && y | 与 | 如果 x 和 y 都为 true,则返回 true | x=6 y=3 (x < 10 && y > 1) 返回 true |
| x or y | 或 | 如果 x 和 y 至少有一个为 true, 则返回 true | x=6 y=3 (x==6 or y==5) 返回 true |
| x || y | 或 | 如果 x 和 y 至少有一个为 true, 则返回 true | x=6 y=3 (x==5 || y==5) 返回 false |
| x xor y | 异或 | 如果 x 和 y 有且仅有一个为 true, 则返回 true | x=6 y=3 (x==6 xor y==3) 返回 false |
| ! x | 非 | 如果 x 不为 true,则返回 true | x=6 y=3 !(x==y) 返回 true |

2.3.8.6. PHP数组运算符【与算数运算符区分】

|----------|-----|---------------------------------------|
| 运算符 | 名称 | 描述 |
| x + y | 集合 | x 和 y 的集合 |
| x == y | 相等 | 如果 x 和 y 具有相同的键/值对,则返回 true |
| x === y | 恒等 | 如果 x 和 y 具有相同的键/值对,且顺序相同类型相同,则返回 true |
| x != y | 不相等 | 如果 x 不等于 y,则返回 true |
| x <> y | 不相等 | 如果 x 不等于 y,则返回 true |
| x !== y | 不恒等 | 如果 x 不等于 y,则返回 true |

2.3.8.6.1. 栗子
复制代码
<?php
$x = array("a" => "red", "b" => "green"); 
$y = array("c" => "blue", "d" => "yellow"); 
$z = $x + $y; // $x 和 $y 数组合并
var_dump($z);
var_dump($x == $y);
var_dump($x === $y);
var_dump($x != $y);
var_dump($x <> $y);
var_dump($x !== $y);
?>

结果:

复制代码
array(4) { ["a"]=> string(3) "red" ["b"]=> string(5) "green" ["c"]=> string(4) "blue" ["d"]=> string(6) "yellow" }
bool(false)
bool(false)
bool(true)
bool(true)
bool(true)
2.3.8.7. 三元运算符【在C也常见】

(expr1) ? (expr2) : (expr3)

对 expr1 求值为 TRUE 时的值为 expr2,在 expr1 求值为 FALSE 时的值为 expr3。

2.3.8.7.1. 栗子
复制代码
<?php
// 普通写法
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
echo $username, PHP_EOL;
 
// PHP 5.3+ 版本写法
$username = $_GET['user'] ?: 'nobody';
echo $username, PHP_EOL;
?>

PHP_EOL 是一个换行符

通过判断 _GET 请求中含有 user 值,如果有返回 _GET['user'],否则返回 nobody

2.3.8.8. 组合比较符(PHP7+)

组合比较符 也称之为太空船操作符 ,符号为 <=>

组合比较运算符可以轻松实现两个变量的比较,当然不仅限于数值类数据的比较。

语法格式如下:

$c = $a <=> $b;

解析如下:

  • 如果**a \> b** , 则 $c 的值为 1
  • 如果 a == b , 则 $c 的值为 0
  • 如果 a \< b , 则 $c 的值为 -1
2.3.8.8.1. 栗子
复制代码
<?php
// 整型
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1
 
// 浮点型
echo 1.5 <=> 1.5; // 0
echo 1.5 <=> 2.5; // -1
echo 2.5 <=> 1.5; // 1
 
// 字符串
echo "a" <=> "a"; // 0
echo "a" <=> "b"; // -1
echo "b" <=> "a"; // 1
?>
2.3.8.9. 运算符优先级

下表按照优先级从高到低列出了运算符。同一行中的运算符具有相同优先级,此时它们的结合方向决定求值顺序。

|------|-----------------------------------------------------------|--------------|
| 结合方向 | 运算符 | 附加信息 |
| 无 | clone new | clone 和 new |
| => | [ | array() |
| <= | ++ -- ~ (int) (float) (string) (array) (object) (bool) @ | 类型和递增/递减 |
| 无 | instanceof | 类型 |
| <= | ! | 逻辑运算符 |
| => | * / % | 算术运算符 |
| => | + -- . | 算术运算符和字符串运算符 |
| => | << >> | 位运算符 |
| 无 | == != === !== <> | 比较运算符 |
| => | & | 位运算符和引用 |
| => | ^ | 位运算符 |
| => | | | 位运算符 |
| => | && | 逻辑运算符 |
| => | || | 逻辑运算符 |
| => | ? : | 三元运算符 |
| <= | = += -= *= /= .= %= &= |= ^= | 赋值运算符 |
| => | and | 逻辑运算符 |
| => | xor | 逻辑运算符 |
| => | or | 逻辑运算符 |
| => | , | 多处用到 |

2.3.8.9.1. 补充:与,或

运算符优先级中,or 和 ||,&& 和 and 都是逻辑运算符,效果一样,但是其优先级却不一样。

复制代码
<?php
// 优先级: &&  >  =  >  and
// 优先级: ||  >  =  >  or
 
$a = 3;
$b = false;
$c = $a or $b;
var_dump($c);          // 这里的 $c 为 int 值3,而不是 boolean 值 true
$d = $a || $b;
var_dump($d);          //这里的 $d 就是 boolean 值 true 
?>
  • $c = $a or $b;

因为or的优先级比=低,所以执行顺序是:

  1. 先执行赋值操作:$c = $a,此时$a3,所以$c直接被赋值为整数3
  2. 再执行or运算:计算$c or $b,但这个运算结果没有被赋值给任何变量,直接被丢弃了
  • $d = $a || $b;

因为||的优先级比=高,所以执行顺序刚好反过来:

  1. 先执行逻辑运算:$a || $b$a=3在PHP中是真值,所以运算结果是布尔true
  2. 再把运算结果赋值给$d
2.3.8.10. 括号的使用

我们通过括号的配对来明确标明运算顺序,而非靠运算符优先级和结合性来决定,通常能够增加代码的可读性。

// 括号优先运算

3. 题目

3.1. [MoeCTF 2021]Do you know HTTP

3.1.1. 题目

https://www.nssctf.cn/problem/3408

检查一下你的学习成果吧

仅仅学习了HTTP请求头相关内容,你可能会发现浏览器已经不足以让你便利的去解决问题了,试试burpsuite!

https://github.com/XDSEC/moeCTF_2021

3.1.2. 解题

题目已经提示,使用bp来解题

3.1.2.1. 第一步

【1】误区:题目要求,用HS请求,我以为是?HS=

实际上是像get这种的请求方式

用bp对请求方式进行修改

将GET改为HS

【2】误区:

【注意,我发现我在拦截的时候,出现了很多的请求,导致我不知道哪一个是我要修改的】如下面的错误示范

HS/collect/pvoriginFrom=http%3A%2F%2Fnode5.anna.nssctf.cn%3A24911%2F&id=nGp0ycKWRnaOEGGwQW&uin=4746391841&version=1.41.10&aid=dad1ffcb-3dfa-4986-86ed-8f3ed69c9d4b&env=production&platform=3&netType=4&vp=954%20*%20512&sr=1440%20*%20900&sessionId=session&from=http%3A%2F%2Fnode5.anna.nssctf.cn%3A24911%2F&referer= HTTP

这是站点埋点的上报统计请求

  • 请求路径里的collectpv都是固定的统计上报关键词
  • 里面的originFromfromreferer都是用来记录页面来源,idsessionId是用户标识,version是SDK版本------这些全是统计用的参数,和你要做操作的业务功能无关
3.1.2.2. 第二步

改完这个请求方式后,他要求只有本地ip才可以,所以继续在reapter里面修改

可以在右侧修改,也可以直接在左侧修改,然后send

3.1.2.3. 第三步

希望我从这个地点过来

Referer一下就好了

3.1.2.4. 第四步

User-Agent改一下

3.1.3. 总结:

这题其实就是在考察http请求头的修改应用,本人卡在了第一步这个HS这个请求方式没见过,不知道是请求方式,在修改时,因为很多的请求过来,不知道哪一个是我需要修改的,同时其他的请求头内容有点生疏。

3.2. [SWPUCTF 2024 秋季新生赛]http标头

3.2.1. 题目

https://www.nssctf.cn/problem/5942

web签到

3.2.2. 解题

3.2.2.1. 第一步

要在出售第一时间,注意date形式,我们可以去网络这里找到date的格式

Tue, 20 Aug 2024 00:00:00 GMT【这个我是查的,出售时间和几月几号星期几我不知道】

星期缩写, 日 月份缩写 年 时:分:秒 GMT,其中日固定为两位数,不足补前导零。

3.2.2.2. 第二步

浏览器,就用User-Agent

3.2.2.3. 第三步

按他的提示,可以很快写出来

3.3. [SWPUCTF 2021 新生赛]babyrce

3.3.1. 题目

复制代码
<?php
error_reporting(0);
header("Content-Type:text/html;charset=utf-8");
highlight_file(__FILE__);
if($_COOKIE['admin']==1) 
{
    include "../next.php";
}
else
    echo "小饼干最好吃啦!";
?> 小饼干最好吃啦!

3.3.2. 解题

3.3.2.1. 第一步

if else很容易看出要使得COOKIE中admin=1

3.3.2.2. 第二步

访问这个.php文件,发现新的代码

复制代码
<?php
error_reporting(0);
highlight_file(__FILE__);
error_reporting(0);
if (isset($_GET['url'])) {
  $ip=$_GET['url'];
  if(preg_match("/ /", $ip)){
      die('nonono');
  }
  $a = shell_exec($ip);
  echo $a;
}
?>

就是用get的方式输入url来求值,注意有这个过滤(空格)

将空格用%09过滤,发现不报错了,但是无结果?

自以为是,注意flag不一定在/flag里头,你要去寻找

ls查找当前目录下

ls查找主目录下

找到flag在目录fllllllaaaaaagggggggg里头

3.3.3. 总结

注意:不要下意思以为flag在哪里,要去查找,一大坑点之一

4. 补充

发现电脑关闭后仍有轰鸣声,是因为S3模式 没有开,但是我不知道要不要打开,学长要是有看到帮帮忙~~❤️❤️❤️

5. 总结本周

5.1.1.1.1.1. 发牢骚

主要是看这个理论知识,了解基础的命令,真的是很枯燥,看的脑袋晕晕的,无数次想要放弃。。。一直在给自己打气,想说再看一点再看一点,争取把所有的命令的过一遍呀呀呀。。而且我尽量让这些命令在大脑里留下点痕迹,而非只是单纯的看,

5.1.1.1.1.2. 学了个啥知识呢?
  1. linux的命令全部过了一遍【非常久!!!】
  2. http请求头知识在做题时发现有点遗忘,回顾了一下,同时看了以前的Http的笔记【从协议,连接互联网开始】
  3. php的学习,但是没有完全学完,学到运算符【里头运算符种类还挺多】【下周将继续学习这一部分内容】
  4. 两道http题目
5.1.1.1.1.3. 下周要补充:
  1. rce这周没有时间看,下周将继续
  2. php的知识点学习继续
  3. 下周看看能不能把vscode搞好,上学期没有把Php配置弄好
相关推荐
sxjk19872 小时前
WPS表格REGEXP公式提取车牌学习
学习·wps·表格·数据处理
万法若空2 小时前
ANSI转义码详解
linux·c++
计算机安禾2 小时前
【Linux从入门到精通】第21篇:Shell脚本开篇——什么是Shell?写第一个Hello World
linux·运维·服务器
Lumos_7772 小时前
Linux -- 系统调用
linux·运维·算法
Rust研习社2 小时前
使用 Tonic 构建高性能异步 gRPC 服务
开发语言·网络·后端·http·rust
m0_377108142 小时前
PCB学习
学习
U盘失踪了2 小时前
Python 的 urljoin:告别手动拼接 URL 的烦恼
笔记·学习
思麟呀2 小时前
Epoll的学习,在select和poll的基础上
网络·数据库·sql·学习·tcp/ip
坚持就完事了2 小时前
Linux中的cp命令
linux·运维·服务器