web入个门
web入个门
1azy_fish.CTF_web入门
信息泄露
查看源代码
页面源代码是信息的一个重要来处F12和右击查看源代码都可以
目录扫描
dirsearch与御剑
dirsearch安装:apt install dirsearch
git泄露
GitHacker安装与使用
1 | # install |
可以进入对应文件夹然后使用 git log
查看对应日志,通过 git reset --hard xxxxxxxxxxxxxxxxxxxxxxx
以达到恢复已删除内容的效果。
DS_Store泄露
工具下载与使用:https://github.com/lijiejie/ds_store_exp
robots.txt
爬虫协议,有时可以通过它看见一些重要的目录。
1 | User-agent: * |
备份文件源码泄漏
CTF-WEB-信息泄露题目总结 - Ca1m - 博客园 (cnblogs.com)
HTTP学习
web安全中,入门的时候,你需要理解的是http头的内容,至少
HTTP请求中的一些请求头
1、Host:指定目标服务器的主机名或IP地址。
2、User-Agent:指定客户端使用的浏览器或其他应用程序的信息。
3、Accept:指定客户端能够接受的MIME类型。
4、Accept-Language:指定客户端首选的自然语言。
5、Accept-Encoding:指定客户端能够接受的编码方式,例如gzip、deflate等。
6、Connection:指定客户端与服务器之间使用的连接类型,例如keep-alive或close。
7、Content-Type:指定请求体的MIME类型,例如application/json、application/x-www-form-urlencoded等。
8、Content-Length:指定请求体的长度,以字节为单位。
9、Referer:指定请求的来源URL,用于告诉服务器用户从哪个页面跳转到当前页面。
10、Authorization:指定请求的认证信息,例如用户名和密码或访问令牌。
11、Cookie:指定请求的Cookie信息,用于跟踪用户会话。
12、If-Modified-Since:指定上次请求资源的时间,服务器可以根据该头部判断资源是否已经被修改过。
13、User-Agent:指定客户端使用的浏览器或其他应用程序的信息。
14、Accept-Ranges:指定服务器是否支持分段下载,例如bytes。
15、Range:指定客户端请求的资源范围,用于实现分段下载或断点续传。
16、Cache-Control:指定请求或响应的缓存策略,例如max-age、no-cache、no-store等
HTTP请求中的一些常用自定义请求头
X-Forwarded-Host 头部是在HTTP代理或负载均衡器后面使用的。
X-Forwarded-For:用于记录客户端的IP地址,特别在使用代理服务器时。
X-Requested-With:用于指示请求的类型,例如XMLHttpRequest。
X-Csrf-Token:用于防止跨站请求伪造攻击。
X-Content-Type-Options:用于指示浏览器是否应该自动处理响应体的MIME类型,例如nosniff。
X-Frame-Options:用于控制页面是否可以嵌入到iframe中,防止点击劫持攻击。
X-XSS-Protection:用于启用浏览器内置的跨站脚本攻击防护机制。
X-Powered-By:用于指示服务器所使用的软件名称和版本号。
常见的Content-Type类型包括:
application/json:用于传输JSON格式的数据。
application/x-www-form-urlencoded:用于传输HTML表单数据,即URL编码的键值对。
multipart/form-data:用于传输文件和二进制数据。
text/plain:用于传输纯文本数据。
请求方式
HTTP 定义了一组请求方法,以表明要对给定资源执行的操作。指示针对给定资源要执行的期望动作。虽然它们也可以是名词,但这些请求方法有时被称为 HTTP 动词。每一个请求方法都实现了不同的语义,但一些共同的特征由一组共享:例如一个请求方法可以是安全的、幂等的或可缓存的。
GET
方法请求一个指定资源的表示形式,使用GET
的请求应该只被用于获取数据。HEAD
方法请求一个与GET
请求的响应相同的响应,但没有响应体。POST
方法用于将实体提交到指定的资源,通常导致在服务器上的状态变化或副作用。PUT
方法用有效载荷请求替换目标资源的所有当前表示。DELETE
方法删除指定的资源。CONNECT
方法建立一个到由目标资源标识的服务器的隧道。OPTIONS
方法用于描述目标资源的通信选项。TRACE
方法沿着到目标资源的路径执行一个消息环回测试。PATCH
方法用于对资源应用部分修改。
这里常用的是post和get的请求方式
GET&POST
Get和Post操作是传参的基本操作,也是CTF中很常见的常规操作,使用hackbar
可以很轻松的完成这个任务。
GET:在url
中提交参数,如/index.php?a=1
POST:可通过hackbar
或抓包插入post数据提交
最直接的区别:
GET请求的参数是放在URL里的,POST请求参数是放在请求body里的。
HTTP头部绕过姿势
如果提示需要本地ip或指定ip才能访问,则可在报文头部添加以下几种常用信息段:
X-Forwarded-For: 127.0.0.1
X-Client-IP: 127.0.0.1
Client-IP: 127.0.0.1如果需要验证网页来源,如一定要从谷歌跳转过来的页面才允许访问,则可在报文头部添加:
Referer: https://www.google.com
如果网页需要验证cookie,我们可以在http头部加入:
Cookie: xxx=xxxxx
除了以上几种常见的情况,还需根据具体情况来使用不同的操作
Dos命令
1 | ASSOC 显示或修改文件扩展名关联。 |
php语法快速入门(看得懂就行版本)
当你开始学习 PHP 语法时,以下是一些基本概念和语法规则,可以帮助你快速入门:
- 语法标记:PHP 代码通常包含在
<?php
和?>
标记之间。例如:
1 |
|
- 注释:使用注释可以在代码中添加说明性文字,对于自己和其他人来说都很有用。PHP 支持单行注释和多行注释。例如:
1 | // 这是单行注释 |
- 变量:用于存储和操作数据的容器。在 PHP 中,变量以美元符号
$
开头,后面跟着变量名。变量名可以包含字母、数字和下划线,但必须以字母或下划线开头。PHP 是一种弱类型语言,变量的类型会根据赋值的内容自动确定。例如:
1 | $name = "John"; // 字符串类型的变量 |
- 数据类型:PHP 支持多种数据类型,包括字符串、整数、浮点数、布尔值、数组、对象等。根据需要,你可以根据数据类型执行相应的操作。例如:
1 | $str = "Hello"; // 字符串类型 |
- 输出内容:使用
echo
或print
关键字可以将内容输出到浏览器。例如:
1 | echo "Hello, World!"; // 输出字符串 |
- 条件语句:使用条件语句可以根据条件的真假执行不同的代码块。常见的条件语句有
if
、else if
和else
。例如:
1 | $age = 20; |
- 循环语句:使用循环语句可以重复执行一段代码块。常见的循环语句有
for
、while
和foreach
。例如:
1 | for ($i = 1; $i <= 5; $i++) { |
- 函数:
函数是封装了一段可重复使用的代码块。它可以接受参数并返回一个值。以下是一个简单的函数示例:
1 | function greet($name) { |
- 数组:
数组是用于存储多个值的数据结构。在 PHP 中,数组可以包含不同类型的值,并且可以通过索引或关联键进行访问。以下是一个简单的数组示例:
1 | $fruits = array("Apple", "Banana", "Orange"); |
- 类:
类是面向对象编程的核心概念之一,用于封装数据和功能。一个类定义了一种对象的行为和属性。以下是一个简单的类示例:
1 | class Person { |
在上面的示例中,Person
类具有 name
和 age
两个属性,以及 __construct()
构造函数和 greet()
方法。使用 new
关键字可以实例化一个类,并通过 ->
运算符访问类的属性和方法。
php的正则表达式
基础
- 字符匹配:
.
:匹配任意字符(除了换行符)。\w
:匹配字母、数字、下划线。\d
:匹配数字。\s
:匹配空白字符(空格、制表符、换行符等)。
- 重复匹配:
*
:匹配前面的元素零次或多次。+
:匹配前面的元素一次或多次。?
:匹配前面的元素零次或一次。{n}
:匹配前面的元素恰好n次。{n,}
:匹配前面的元素至少n次。{n,m}
:匹配前面的元素至少n次、最多m次。
- 字符类:
[abc]
:匹配’a’、’b’或’c’中的任意一个字符。[^abc]
:匹配除了’a’、’b’和’c’以外的任意字符。[a-z]
:匹配任意小写字母。[A-Z]
:匹配任意大写字母。[0-9]
:匹配任意数字。
- 边界匹配:
^
:匹配字符串的开始位置。$
:匹配字符串的结束位置。\b
:匹配单词的边界。
- 分组和捕获:
(...)
:创建一个捕获组。(?:...)
:创建一个非捕获组。
进阶
反向引用:
使用
(...)
将模式中的一部分捕获为一个组。可以使用
\n
(n为组的编号)来引用先前捕获的组。例如,
(a)\1
将匹配连续出现的两个相同的字母”a”。1
2
3
4
5
6
7
8$str = "Hello Hello World World World";
$pattern = '/(\b\w+\b)\s+\1/';
if (preg_match($pattern, $str, $matches)) {
echo "匹配成功!重复的单词是:" . $matches[1];
} else {
echo "未找到重复的单词。";
}
//"匹配成功!重复的单词是:Hello"在上面的示例中,正则表达式模式
/(\b\w+\b)\s+\1/
包含以下部分:(\b\w+\b)
: 这是一个捕获组,用于匹配一个完整的单词。\s+
: 匹配一个或多个空格字符。\1
: 这是一个反向引用,引用了第一个捕获组所匹配的内容。
平衡组:
使用平衡组可以匹配嵌套结构,如括号、HTML标签等。
通过在模式中使用递归引用来实现平衡组的匹配。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15$str = "(abc(def(ghi)))";
$pattern = '/
(?(DEFINE)
(?<paren> \( (?: [^()]+ | (?&paren) )* \) )
)
^ (?&paren) $
/x';
if (preg_match($pattern, $str, $matches)) {
echo "括号匹配成功!";
} else {
echo "括号匹配失败。";
}
//括号匹配成功在上面的示例中,正则表达式模式使用了平衡组的概念。这个模式包含以下部分:
(?(DEFINE)...)
: 这是一个定义块,定义了一个名为"paren"
的平衡组。(?<paren> \( (?: [^()]+ | (?&paren) )* \) )
: 这是名为"paren"
的平衡组,用于匹配成对出现的括号。它使用了递归的方式,允许嵌套的括号。
详细解析
1
2
3
4
5
6$pattern = '/
(?(DEFINE)
(?<paren> \( (?: [^()]+ | (?&paren) )* \) )
)
^ (?&paren) $
/x';这个模式使用了平衡组的概念来匹配平衡的括号结构。
定义块:
(?(DEFINE)...)
定义了一个定义块,其中包含一个名为paren
的平衡组的定义。在上面的定义块中,我们定义了名为paren的平衡组。它使用了递归的方式来匹配括号内的内容。
"\("
: 匹配左括号"("
。"(?": [^()]+ | (?&paren) )*
: 这是一个非捕获组,用于匹配括号内的内容。它可以匹配非括号字符[^()]+
或者递归引用(?&paren)
。这样就可以实现括号内的嵌套结构。"\)": 匹配右括号 ")"。
引用:
^(?&paren) $
是对paren
平衡组的引用,它用于匹配整个字符串是否符合平衡的括号结构。^
: 匹配字符串的开头。(?&paren)
: 这是对paren
平衡组的引用,用于匹配平衡的括号结构。$
: 匹配字符串的结尾。
断言:
(?=...)
:正向肯定先行断言,要求后面的模式与其匹配,但不消耗字符。(?!...)
:正向否定先行断言,要求后面的模式不与其匹配,但不消耗字符。(?<=...)
:反向肯定后行断言,要求前面的模式与其匹配,但不消耗字符。(?<!...)
:反向否定后行断言,要求前面的模式不与其匹配,但不消耗字符。
修饰符:
i
:忽略大小写。m
:多行模式,使^
和$
匹配每行的开始和结束位置。s
:使.
匹配包括换行符在内的所有字符。x
:忽略模式中的空白和注释。
php中的一些技巧
php弱类型与强类型
== 与 ===
1 | <?php |
如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换成数值并且比较按照数值来进行
1 | <?php |
php
手册:
1 | /* |
md5绕过(Hash比较缺陷)
1 |
|
大意是要输入一个字符串和数字类型,并且他们的md5值相等,就可以成功执行下一步语句
介绍一批md5开头是0e的字符串
0e在比较的时候会将其视作为科学计数法,所以无论0e后面是什么,0的多少次方还是0。
键入**md5(‘240610708’) == md5(‘QNKCDZO’)**成功绕过!
md5开头是0e的字符串(来源于网络):
QNKCDZO
0e830400451993494058024219903391s878926199a
0e545993274517709034328855841020s155964671a
0e342768416822451524974117254469s214587387a
0e848240448830537924465865611904s214587387a
0e848240448830537924465865611904s878926199a
0e545993274517709034328855841020s1091221200a
0e940624217856561557816327384675s1885207154a
0e509367213418206700842008763514
json绕过
1 |
|
输入一个json类型的字符串,json_decode函数解成一个数组,判断数组中key的值是否等于 $key的值,但是$key的值我们不知道,但是可以利用0==”admin”这种形式绕过.
**最终payload **
1 | message={"key":0} |
array_search is_array绕过
1 |
|
先判断传入的是不是数组,然后循环遍历数组中的每个值,并且数组中的每个值不能和admin相等,并且将每个值转化为int类型,再判断传入的数组是否有admin,有则返回flag。
1 | payload: test[]=0//可以绕过 |
官方手册对array_search的介绍
1 | mixed array_search ( mixed $needle , array $haystack [], bool $strict = false ) |
$needle,$haystack必需,$strict可选
函数判断$haystack中的值是存在$needle,存在则返回该值的键值 第三个参数默认为false,如果设置为true则会进行严格过滤。
1 |
|
array_search函数 类似于 == 也就是$a ==”admin” 当然是$a=0 当然如果第三个参数为true则就不能绕过。
strcmp漏洞绕过 php -v <5.3
1 |
|
- strcmp是比较两个字符串,如果str1<str2 则返回<0 如果str1大于str2返回>0 如果两者相等 返回0
- 我们是不知道$password的值的,题目要求strcmp判断的接受的值和$password必需相等,strcmp传入的期望类型是字符串类型,如果传入的是个数组会怎么样呢
- 我们传入 password[]=xxx 可以绕过 是因为函数接受到了不符合的类型,将发生错误,但是还是判断其相等
- payload: password[]=xxx
switch绕过
1 |
|
原理和上面一样
is_numeric()、int()强制类型转换
1 |
|
知识点:
int(),不能正确转换的类型有十六进制型字符串、科学计数法型字符串
is_numeric()支持普通数字型字符串、科学记数法型字符串、部分支持十六进制0x型字符串
先判断是不是数字,然后再进行int长短的限定判断,也就是只能限定在5184000L< time < 7776000
通过is_number() 能传入科学计数法,来进行绕过。
所以根据int不能处理科学计数法,而在is_number上能处理来解决。
php_eval_RCE
eval危险函数利用好就可以完成RCE,所以一般使用的时候会ban掉很多东西,下面就是一个最简单的eval()
的利用。
1 |
|
我们可以通过调用一些函数达到RCE的效果,最经典的就是system()
可以通过这个函数实现命令的执行。
然后就是一些linux的基础知识
Linux系统的文件结构
/bin 二进制文件,系统常规命令
/boot 系统启动分区,系统启动时读取的文件
/dev 设备文件
/etc 大多数配置文件
/home 普通用户的家目录
/lib 32位函数库
/lib64 64位库
/media 手动临时挂载点
/mnt 手动临时挂载点
/opt 第三方软件安装位置
/proc 进程信息及硬件信息
/root 临时设备的默认挂载点
/sbin 系统管理命令
/srv 数据
/var 数据
/sys 内核相关信息
/tmp 临时文件
/usr 用户相关设定
linux的命令
立刻关机
shutdown -h now
poweroff
两分钟后关机
shutdown -h 2
立刻重启
shutdown -r now
reboot
两分钟后重启
shutdown -r 2
帮助命令
(help)ifconfig --help //查看 ifconfig 命令的用法
命令说明书
(man)man shutdown //打开命令说明后,可按"q"键退出
切换用户(su)
su yao //切换为用户"yao",输入后回车需要输入该用户的密码
exit //退出当前用户
切换目录(cd)
cd / //切换到根目录
cd /bin //切换到根目录下的bin目录
cd ../ //切换到上一级目录 或者使用命令:cd ..
cd ~ //切换到home目录
cd - //切换到上次访问的目录
cd xx(文件夹名) //切换到本目录下的名为xx的文件目录,如果目录不存在报错
cd /xxx/xx/x //可以输入完整的路径,直接切换到目标目录,输入过程中可以使用tab键快速补全
查看目录(ls)
ls //查看当前目录下的所有目录和文件
ls -a //查看当前目录下的所有目录和文件(包括隐藏的文件)
ls -l //列表查看当前目录下的所有目录和文件(列表查看,显示更多信息),与命令"ll"效果一样
ls /bin //查看指定目录下的所有目录和文件
创建目录(mkdir)
mkdir tools //在当前目录下创建一个名为tools的目录
mkdir /bin/tools //在指定目录下创建一个名为tools的目录
删除目录与文件(rm)
rm 文件名 //删除当前目录下的文件
rm -f 文件名 //删除当前目录的的文件(不询问)
rm -r 文件夹名 //递归删除当前目录下此名的目录
rm -rf 文件夹名 //递归删除当前目录下此名的目录(不询问)
rm -rf * //将当前目录下的所有目录和文件全部删除
rm -rf /* //将根目录下的所有文件全部删除
修改目录(mv)
mv 当前目录名 新目录名 //修改目录名,同样适用与文件操作
mv /usr/tmp/tool /opt //将/usr/tmp目录下的tool目录剪切到 /opt目录下面
mv -r /usr/tmp/tool /opt //递归剪切目录中所有文件和文件夹
拷贝目录(cp)
cp /usr/tmp/tool /opt //将/usr/tmp目录下的tool目录复制到 /opt目录下面
cp -r /usr/tmp/tool /opt //递归剪复制目录中所有文件和文件夹
搜索目录(find)
find /bin -name 'a*' //查找/bin目录下的所有以a开头的文件或者目录
查看当前目录(pwd)
pwd //显示当前位置路径
新增文件(touch)
touch a.txt //在当前目录下创建名为a的txt文件(文件不存在),如果文件存在,将文件时间属性修改为当前系统时间
删除文件(rm)
rm 文件名 //删除当前目录下的文件
rm -f 文件名 //删除当前目录的的文件(不询问)
编辑文件(vi、vim)
vi 文件名 //打开需要编辑的文件
vim +10 filename.txt //打开文件并跳到第10行
vim -R /etc/passwd //以只读模式打开文件
-进入后,操作界面有三种模式:命令模式(command mode)、插入模式(Insert mode)和底行模式(last line mode)
命令模式
-刚进入文件就是命令模式,通过方向键控制光标位置,
-使用命令”dd”删除当前整行
-使用命令”/字段”进行查找
-按”i”在光标所在字符前开始插入
-按”a”在光标所在字符后开始插入
-按”o”在光标所在行的下面另起一新行插入
-按”:”进入底行模式
插入模式
-此时可以对文件内容进行编辑,左下角会显示 “– 插入 –””
-按”ESC”进入底行模式
底行模式
-退出编辑: :q
-强制退出: :q!
-保存并退出: :wq操作步骤示例
1.保存文件:按”ESC” -> 输入”:” -> 输入”wq”,回车 //保存并退出编辑
2.取消操作:按”ESC” -> 输入”:” -> 输入”q!”,回车 //撤销本次修改并退出编辑
查看文件
cat a.txt //查看文件最后一屏内容
less a.txt //PgUp向上翻页,PgDn向下翻页,"q"退出查看
more a.txt //显示百分比,回车查看下一行,空格查看下一页,"q"退出查看
tail -100 a.txt //查看文件的后100行,"Ctrl+C"退出查看
权限说明
文件权限简介:’r’ 代表可读(4),’w’ 代表可写(2),’x’ 代表执行权限(1),括号内代表”8421法”
##文件权限信息示例:-rwxrw-r–
-第一位:’-‘就代表是文件,’d’代表是文件夹
-第一组三位:拥有者的权限
-第二组三位:拥有者所在的组,组员的权限
-第三组三位:代表的是其他用户的权限
文件权限
普通授权 chmod +x a.txt
8421法 chmod 777 a.txt //1+2+4=7,"7"说明授予所有权限
打包与解压
.zip、.rar //windows系统中压缩文件的扩展名
.tar //Linux中打包文件的扩展名
.gz //Linux中压缩文件的扩展名
.tar.gz //Linux中打包并压缩文件的扩展名
打包文件
tar -zcvf 打包压缩后的文件名 要打包的文件
参数说明:z:调用gzip压缩命令进行压缩; c:打包文件; v:显示运行过程; f:指定文件名;
tar -zcvf a.tar file1 file2,... //多个文件压缩打包
解压文件
tar -zxvf a.tar //解包至当前目录
tar -zxvf a.tar -C /usr------ //指定解压的位置
unzip test.zip //解压*.zip文件
unzip -l test.zip //查看*.zip文件的内容
其他常用命令
find
find . -name "*.c" //将目前目录及其子目录下所有延伸档名是 c 的文件列出来
find . -type f //将目前目录其其下子目录中所有一般文件列出
find . -ctime -20 //将目前目录及其子目录下所有最近 20 天内更新过的文件列出
find /var/log -type f -mtime +7 -ok rm {} \; //查找/var/log目录中更改时间在7日以前的普通文件,并在删除之前询问它们
find . -type f -perm 644 -exec ls -l {} \; //查找前目录中文件属主具有读、写权限,并且文件所属组的用户和其他用户具有读权限的文件
find / -type f -size 0 -exec ls -l {} \; //为了查找系统中所有文件长度为0的普通文件,并列出它们的完整路径
whereis
whereis ls //将和ls文件相关的文件都查找出来
which
说明:which指令会在环境变量$PATH设置的目录里查找符合条件的文件。
which bash //查看指令"bash"的绝对路径
sudo
说明:sudo命令以系统管理者的身份执行指令,也就是说,经由 sudo 所执行的指令就好像是 root 亲自执行。需要输入自己账户密码。
使用权限:在 /etc/sudoers 中有出现的使用者
sudo -l //列出目前的权限
$ sudo -u yao vi ~www/index.html //以 yao 用户身份编辑 home 目录下www目录中的 index.html 文件
grep
grep -i "the" demo_file //在文件中查找字符串(不区分大小写)
grep -A 3 -i "example" demo_text //输出成功匹配的行,以及该行之后的三行
grep -r "ramesh" * //在一个文件夹中递归查询包含指定字符串的文件
service
说明:service命令用于运行System V init脚本,这些脚本一般位于/etc/init.d文件下,这个命令可以直接运行这个文件夹里面的脚本,而不用加上路径
service ssh status //查看服务状态
service --status-all //查看所有服务状态
service ssh restart //重启服务
free
说明:这个命令用于显示系统当前内存的使用情况,包括已用内存、可用内存和交换内存的情况
free -g //以G为单位输出内存的使用量,-g为GB,-m为MB,-k为KB,-b为字节
free -t //查看所有内存的汇总
top
top //显示当前系统中占用资源最多的一些进程, shift+m 按照内存大小查看
df
说明:显示文件系统的磁盘使用情况
df -h //一种易看的显示
mount
mount /dev/sdb1 /u01 //挂载一个文件系统,需要先创建一个目录,然后将这个文件系统挂载到这个目录上
mount dev/sdb1 /u01 ext2 defaults 0 2 //添加到fstab中进行自动挂载,这样任何时候系统重启的时候,文件系统都会被加载
uname
说明:uname可以显示一些重要的系统信息,例如内核名称、主机名、内核版本号、处理器类型之类的信息
uname -a
yum
说明:安装插件命令
yum install httpd //使用yum安装apache
yum update httpd //更新apache
yum remove httpd //卸载/删除apache
rpm
说明:插件安装命令
rpm -ivh httpd-2.2.3-22.0.1.el5.i386.rpm //使用rpm文件安装apache
rpm -uvh httpd-2.2.3-22.0.1.el5.i386.rpm //使用rpm更新apache
rpm -ev httpd //卸载/删除apache
date
date -s "01/31/2010 23:59:53" ///设置系统时间
wget
说明:使用wget从网上下载软件、音乐、视频
示例:wget http://prdownloads.sourceforge.net/sourceforge/nagios/nagios-3.2.1.tar.gz
//下载文件并以指定的文件名保存文件
wget -O Lazy_fish.tar.gz http://prdownloads.sourceforge.net/sourceforge/nagios/nagios-3.2.1.tar.gz
ftp
ftp IP/hostname //访问ftp服务器
mls *.html - //显示远程主机上文件列表
scp
scp /opt/data.txt 192.168.1.101:/opt/ //将本地opt目录下的data文件发送到192.168.1.101服务器的opt目录下
防火墙操作
service iptables status //查看iptables服务的状态
service iptables start //开启iptables服务
service iptables stop //停止iptables服务
service iptables restart //重启iptables服务
chkconfig iptables off //关闭iptables服务的开机自启动
chkconfig iptables on //开启iptables服务的开机自启动
centos7 防火墙操作
systemctl status firewalld.service //查看防火墙状态
systemctl stop firewalld.service //关闭运行的防火墙
systemctl disable firewalld.service //永久禁止防火墙服务
修改主机名(CentOS 7)
hostnamectl set-hostname 主机名
查看网络
ifconfig
修改IP
修改网络配置文件,文件地址:/etc/sysconfig/network-scripts/ifcfg-eth0
主要修改以下配置:
TYPE=Ethernet //网络类型
BOOTPROTO=static //静态IP
DEVICE=ens00 //网卡名
IPADDR=192.168.1.100 //设置的IP
NETMASK=255.255.255.0 //子网掩码
GATEWAY=192.168.1.1 //网关
DNS1=192.168.1.1 //DNS
DNS2=8.8.8.8 //备用DNS
ONBOOT=yes //系统启动时启动此设置
修改保存以后使用命令重启网卡:service network restart
配置映射
修改文件: vi /etc/hosts
在文件最后添加映射地址,示例如下:
192.168.1.101 node1
192.168.1.102 node2
192.168.1.103 node3
配置好以后保存退出,输入命令:ping node1
,可见实际 ping 的是 192.168.1.101。
查看进程
ps -ef //查看所有正在运行的进程
结束进程
kill pid //杀死该pid的进程
kill -9 pid //强制杀死该进程
查看链接
ping IP //查看与此IP地址的连接情况
netstat -an //查看当前系统端口
netstat -an | grep 8080 //查看指定端口
快速清屏
ctrl+l //清屏,往上翻可以查看历史操作
远程主机
ssh IP //远程主机,需要输入用户名和密码
无字母RCE
无字母RCE虽然在现实环境中不会出现,但是在CTF中也是常见的考点,最简单的如下。
1 |
|
我在冲浪的时候不小心找到了一个佬写的文章,他开发的一个工具,挺有用的。
php的一些特性
你喜欢preg_match吗?
首先是大家喜闻乐见的%0a
,什么?你也喜欢,他的原理是什么呢?
我们随便写个php测一下,$
似乎会忽略在句尾的%0a
,无论是换行模式还是不换行?
测了一下,这似乎是个错误的理解()。
1 |
|
我们可以看到,m
是一定要搭配^
或者$
来使用的,也就是说有m
必须要有^
或者$
,否则无意义。
还有一个东西,也是%0a
所导致的一个小问题,那就是非s
模式下.
不匹配%0a
1 |
|
众所周知,preg_match()函数是可以绕过的,详细参考p神PHP利用PCRE回溯次数限制绕过某些安全限制
正好测试一下
1 |
|
讨厌的intval
date函数的解析
在date函数中转义字符
date函数完整声明如下:date(string format,int timestamp)
其中timestamp有默认值time()一般不考虑。
关键在第一个参数,他会按照“Y为年,M为月”等一系列格式化参数,来将time()的值转化为格式化的日期。如
date(“Y-m-d h:i:m”);
而想要将字符原样输出,不参与日期格式化,则可以用反斜杠来进行转义
date("\T\a\d\a\y \i\s Y-m-d h:i:m");
1 |
|
这类属于可能存在的逻辑漏洞
realpath导致的文件异常删除
1 | //2023强网拟态 |
可以利用realpath($dev_dir) == $dir
构造 dev=/tmp/.
删除.htaccess。
创建和解压也/tmp作为目录
1 | ?action=create&subdir=/tmp |
解压后就没有.htaccess了
php反序列化
序列化其实就是将数据转化成一种可逆的数据结构,自然,逆向的过程就叫做反序列化。
- 常见的魔术方法
1 | __wakeup() //执行unserialize()时,先会调用这个函数 |
一般类型
示例题目
1 | //MRCTF2020-Ezpop |
很显然构造链子__wakeup() -> __toString() -> __get -> __invoke()
1 |
|
使用php原生类
- 例如
1 | //[GDOUCTF 2023]反方向的钟 |
一道反序列化,链子:__wakeup->hahaha()->IPO()->echo new $_POST['a']($_POST['b']);
然后调用php的内置类SplFileObject来读取文件内容,但是读取之后没有输出,所以使用伪协议输出。
1 |
|
最终payload:
get:d=Tzo2OiJzY2hvb2wiOjI6e3M6MTA6ImRlcGFydG1lbnQiO086OToiY2xhc3Nyb29tIjoyOntzOjQ6Im5hbWUiO3M6OToib25lIGNsYXNzIjtzOjY6ImxlYWRlciI7Tzo3OiJ0ZWFjaGVyIjoyOntzOjQ6Im5hbWUiO3M6MzoiaW5nIjtzOjQ6InJhbmsiO3M6MTA6ImRlcGFydG1lbnQiO319czoxMDoiaGVhZG1hc3RlciI7czozOiJvbmciO30=
post:a=SplFileObject&b=php://filter/convert.base64-encode/resource=flag.php
2.
1 | //[NUAACTF2022]superpop |
很简单的一条pop链子,用到了Error原生类绕过hash
__wakeup() -> __get -> __invoke()
1 |
|
__destruct的触发
正常情况下
在PHP中,正常触发析构函数(__destruct)有三种方法:
①程序正常结束
②主动调用unset($aa)
③将原先指向类的变量取消对类的引用
throw Error会使得我们的程序没有正常结束,所以类没有被销毁
1 |
|
SSTI
SSTI,又称服务器模板注入攻击,发生在MVC框架的view层,ssti的导致原因是由于使用了render_template
由于模板引擎使用静态模板文件,并在运用时用HTML页面中的实际值替换变量/占位符,从而让HTML页面的设计更容易。当前广泛应用的模板有Smarty,Twig,Jinja2,FreeMarker和Velocity
服务器接收了用户的输入,将其作为web应用模板内容的一部分,在进行部分目标编译渲染的过程中,执行了用户插入的恶意内容,因而可能导致了敏感信息泄露、代码执行、Getshell等问题
模板引擎可以让网站程序实现界面和数据分离,业务代码和逻辑代码的分离,大大提升了开发效率,也使得代码重用变得更加容易,但是往往新的开发都会导致一些安全问题,虽然模板引擎会提供沙箱机制,但是也同样存在沙箱逃逸技术来绕过
模板是一种提供给程序来解析的语法,换句话说,模板是从数据(变量)到实际的视觉表现(HTML)这项工作的一种实现手段。
最重要的是模板渲染,你可以使用 render_template() 方法来渲染模板。你需要做的一切就是将模板名和你想作为关键字的参数传入模板的变量。实际上,ssti引发的问题主要就是render_template渲染函数的问题
这个函数作用就是把HTML涉及的页面与用户数据分离开,这样方便展示和管理。当用户输入自己的数据信息,HTML页面可以根据用户自身的信息来展示页面。
注入思想是不断调用我们要使用的命令,如file,read,open,ls等,来读取和写入配置文件
判断模板引擎
1.根据编程语言
各种编程语言对应的模板引擎如下:
Java:
- FreeMarker
- Thymeleaf
- Velocity
- JSP (JavaServer Pages)
Python:
- Jinja2
- Django模板
PHP:
- Blade (Laravel框架自带)
- Smarty
JavaScript:
- Handlebars.js
- EJS (Embedded JavaScript)
- Pug (formerly Jade)
Ruby:
- ERB (Embedded Ruby)
- Haml
Go:
- html/template
2.根据此图片
1 | {{7*'7'}}->7777777->Jinja2 |
判断模板注入的注入点方法
找这样的场景:输入什么,就输出什么!
这样的常见有两种比较大可能的类型:
1.SSTI
2.XSS(需要bot)
Smarty SSTI
1 | {$smarty.version} |
Twig SSTI
1 | {{self}} |
Flask Jinja2 SSTI
下面是一些会用到的魔术对象:
1 | __class__ :返回类型所属的对象 |
用魔术对象可以构造一些简单的语句:
我们在里面运行以下:
解读一下:
class返回[]所属的对象;
class+base:返回这个对象所继承的基类
class+base+subclasses:找到了这个对象的基类,那么就返回这个基类下所具有的子类
Jinja模板引擎特点:
1 | {{...}}: 装载一个变量,模板渲染的时候,会使用传进来的同名参数将这个变量代表的值替换掉 |
核心思路:找__globals__
1 | {{((g.pop.__globals__.__builtins__.__import__('os').popen('whoami')).read())}} |