web笔记

前言

这是我在打ctf的时候在ctfshow平台学习web方向的记录,建议配合平台中的题目一起查看。
依据本人的学习经验web方向需要依靠大量的知识积累,类似于文科的背诵,再加上对新披露的漏洞的知晓,大部分比赛都是直接拿最新CVE来出题。

1.信息泄露

直接查看网页源码,flag可能再被注释掉的内容里面没有显示出来(强制查看:通过在url头部添加 view-source:)web1 web2
通过burpsuite抓包 flag在返回的响应数据包里面 web3
/robots.txt web4
phps作为备份文件,泄露了源码(index.phps)web5
www源码泄露 web6
url/.git web7
url/.svn web8
vim缓存泄露,在使用vim进行编辑时,会产生缓存文件,如果意外退出,缓存文件保留下来,这时可以通过缓存文件来得到原文件,以index.php来说,第一次退出后,缓存文件名为 .index.php.swp,第二次退出后,缓存文件名为.index.php.swo,第三次退出后文件名为.index.php.swn web9
cookie中也会隐藏数据 web10
nslookup -qt=txt flag.ctfshow.com 其中有: 非权威应答: flag.ctfshow.com text =
“flag{just_seesee}” web11
有时候网站上的公开信息,就是管理员常用密码 web12
找网站的document,操作指南 web13
/editor,暴露作者页面直接在url后面添加/editor 然后查看flag路径并且访问 web14
邮箱会泄露信息 web15
php探针url/tz.php web16
备份的sql文件会泄露敏感信息url/backup.sql web17

—-2023.7.14. 22:25 l1nk

2.爆破

爆破的时候,信息可能藏在Authorization中 web21
子域名爆破 web22
MD5加密 substr()、intval() web23
伪随机数 mt_srand()、mt_rand() web24

3.命令执行

嵌套eval逃逸函数绕过过滤
url + ?c=eval($_GET[1]);&1=system(‘tac flag.php’);
php的filter伪协议,读取文件内容并输出
data伪协议,后面直接加执行的代码
套娃函数?c=eval(array_pop(next(get_defined_vars())));

—-2023.7.16 1:25 l1nk

没有学习,打永劫去了

—-2023.7.17 0:02 l1nk

ls,cat是系统命令,需要包含在system(“”)中进行执行

data伪协议
payload:
url+?c=data://text/plain,
可简写为:url+?c=data:,

filter伪协议

system($c.” >/dev/null 2>&1”);写入黑洞文件中,利用 命令一;ls来执行命令一
当$(())没有参数时。默认为0,0的取反为-1 web57

—-2023.7.18 2:23 l1nk

c=$a=opendir(“./“); while (($file = readdir($a)) !== false){echo $file . “”; };查看当前目录是否有东西
$s = ob_get_contents();
这一句的作用是定义了一个s变量并把ob_get_contents()返回的输出缓冲区的内容赋值给了s
ob_end_clean();
这个函数的作用是以字符串格式返回当前输出缓冲区并关闭输出缓冲
echo preg_replace(“/[0-9]|[a-z]/i”,”?”,$s);
这一句话是把变量s,即缓冲区内容的所有的数字和字母替换成了为?
缓冲区的题目需要在正确命令后面执行exit();及时退出才能成功执行
PDO连数据库

—-2023.7.18 16:34 l1nk

字符拼接,学不了一点,先不学(web118-124)

—-2023.7.19 17:34 l1nk

4.文件包含

nginx原理和日志文件包含,在User-Agent里面写php代码,中间件php-fpm会解析,实现恶意代码。
默认路径url?file=/var/log/nginx/access.log
过滤掉了.的话要用session执行(web82-86)

5.php

只检测数字的时候可以用数组绕过(web89)
m代表多行匹配(web91)
$num=4476只匹配num是不是4476,可以用其他任何值绕过,包括4476的十六进制和八进制
intval($num,0)=4476表示匹配num的十进制值是否为4476

干到web100了呜呜呜0.55了,做完几个条件竞争就去睡觉

当开启session时,服务器会在临时目录下创建session文件来保存会话信息,文件名格式为sess_PHPSESSID。
一般开发的web服务会使用多线程接收用户的请求,而线程同步机制确保两个及以上的并发进程或线程不同时执行某些特定的程序段,依靠临界区,session的临界区就是临时目录。
如果没有应用好同步技术则会产生“竞争条件”问题。意外生成攻击者想要生成的文件,这样攻击者可以在该文件还未被删除的时间段内进行非法操作。
PHP_SESSION_UPLOAD_PROGRESS用于设置/tmp目录下生成的sess_PHPSESSID文件的内容
使用python脚本进行多线程请求,生成sess_PHPSESSID文件,实现rce
脚本链接:https://blog.csdn.net/weixin_46003360/article/details/119045296 (web82中)
—-2023.7.21 1:42 l1nk

临时文件目录:/tmp/php??????

6.文件上传绕过

php替换为空,可以1.phphpp双写绕过得到1.php写入木马
00字符截断:123.php%00.jpg,后台以为是.jpg,文件上传的时候遇到%00就舍弃掉了后面的,以为是.php
iconv字符截断:utf-8字符集默认范围在0x00-0x7f,不在这个范围会报异常,后续字符不处理
123.php%df.jpg -> 123.php
asp解析
基于nginx和php-fpm的错误配置:1.txt/1.php如果1.php不存在会找前面的1.txt文件进行php解析(私教课43)
天呐我的脚本一直被删除(把系统的安全中心关了,安全软件全卸载了就行)
—-2023.7.21 21:44 l1nk

apache多后缀解析漏洞:123.txt.ctf ctf后缀不认识,往前找到txt作为后缀,处理为123.txt
伪协议绕过:auto_append_file=php://input
日志文件绕过:auto_append_file=/var/log/nginx/access.log
—-2023.7.22 22:51 l1nk

7.sql注入

sql注入,#和– (有个空格)为注释

—-2023.7.24 21:51 l1nk

盲注(工作量大)
报错注入,用updatexml;
见笔记(sql注入笔记day7)
—-2023.7.25 21:41 l1nk

//filesystemiterator遍历文件类
//directoryItrerator遍历目录类
—-2023.7.28 14:23 l1nk

is_file函数可以使用包装器伪协议来绕过,不影响file_get_contents highlight_file
is_file认为伪协议不是文件,highlight_file认为伪协议是文件
目录溢出会使is_file判断其不是文件,而highlight_file会正常识别
—-2023.7.31 22:00 l1nk

sql注入完了,开始php反序列化
—-2023.8.2 13:02 l1nk

8.反序列化

当用 === 或 !== 进行比较时则不进行类型转换,因为此时类型和数值都要比对。
$a == $b 等于 TRUE,如果类型转换后 $a 等于 $b。
$a === $b 全等 TRUE,如果 $a 等于 $b,并且它们的类型也相同。
$a != $b 不等 TRUE,如果类型转换后 $a 不等于 $b。

_()是一个函数
_()==gettext() 是gettext()的拓展函数,开启text扩展。需要php扩展目录下有php_gettext.dll
dnslog怎么又没用,无语了
—-2023.8.2 17:58 l1nk

反序列化,反不了一点
—-2023.8.9 20:41 l1nk

__wakeup() //执行unserialize()时,先会调用这个函数
__sleep() //执行serialize()时,先会调用这个函数
__destruct() //对象被销毁时触发,当一个对象不再被引用时,PHP会自动销毁该对象,并在销毁之前调用__destruct方法。
__call() //在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //用于从不可访问的属性读取数据或者不存在这个键都会调用此方法
__set() //用于将数据写入不可访问的属性
__isset() //在不可访问的属性上调用isset()或empty()触发
__unset() //在不可访问的属性上使用unset()时触发
__toString() //把类当作字符串使用时触发
__invoke() //当尝试将对象调用为函数时触发

php版本:

​ PHP5 < 5.6.25

​ PHP7 < 7.0.10
序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
class test{
public $a;
public function __construct(){
$this->a = 'abc';
}
public function __wakeup(){
$this->a='666';
}
public function __destruct(){
echo $this->a;
}
}

如果执行unserialize(‘O:4:”test”:1:{s:1:”a”;s:3:”abc”;}’);输出结果为666

而把对象属性个数的值增大,1->2执行unserialize(‘O:4:”test”:2:{s:1:”a”;s:3:”abc”;}’);输出结果为abc

preg_match(‘/^O:\d+/‘)匹配序列化字符串是否是对象字符串开头
利用加号绕过(注意在url里传参时+要编码为%2B)

利用引用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
class test{
public $a;
public $b;
public function __construct(){
$this->a = 'abc';
$this->b= &$this->a;
}
public function __destruct(){
if($this->a===$this->b){
echo 666;
}
}
}
$a = serialize(new test());

上面这个例子将$b设置为$a的引用,可以使$a永远与$b相等

16进制绕过字符的过滤
O:4:”test”:2:{s:4:”%00*%00a”;s:3:”abc”;s:7:”%00test%00b”;s:3:”def”;}
可以写成
O:4:”test”:2:{S:4:”\00*\00\61”;s:3:”abc”;s:7:”%00test%00b”;s:3:”def”;}
表示字符类型的s大写时,会被当成16进制解析。

反序列化的字符逃逸
过滤后字符变多:利用引号闭合和大括号闭合,舍弃掉原有的部分序列化后的结果
过滤后字符变少:前面少了一半,导致后面的字符被吃掉,从而执行了我们后面的代码
—-2023.8.11 20:19 l1nk

pop链没看懂,和之前的字符拼接之后一起学。
—-2023.8.17 13:59 l1nk


web笔记
https://lan041221.github.io/web笔记/
作者
l1nk
发布于
2023年8月17日
许可协议