pdb在eval中的妙用
1081430910178485 发表于 重庆 CTF 475浏览 · 2024-11-21 14:25

校内赛时有一道题,给出的代码如下:

#!/usr/bin/env python3
WELCOME = '''
    ____           __                __  
   / __ \___  ____/ /________  _____/ /__
  / /_/ / _ \/ __  / ___/ __ \/ ___/ //_/
 / _, _/  __/ /_/ / /  / /_/ / /__/ ,<
/_/ |_|\___/\__,_/_/   \____/\___/_/|_|

'''
blacklist = []

def filter_input(input_data) -> bool :

def filter_input1(input_data) -> bool :

import random
import string
secret_key = ''.join ( random.choices ( string.ascii_letters + string.digits, k=12 ) )
print ( WELCOME )
print ( "放我自由!")
print ( "先告诉我牢笼的密钥,这样我才有机会出来" )
print ( "允许你先问一个问题" )
input_data = input("> ")
if filter_input1(input_data) == False :
    print( "你是黑客!但是能力太低不能放我出来" )
    exit(0)
print('我的回答是:{}'.format(eval(input_data)))
input_key = input("> ")
if input_key != secret_key :
    print ( "你是黑客?" )
    exit(0)
print ( "不错我看好你" ) 
input_data = input("> ")
if filter_input(input_data) == False :
    print( "你是黑客!但是能力太低不能放我出来" )
    exit(0)
print('我的回答是: {}'.format(eval(input_data)))

第一次输入通过第一个过滤就执行并回显,然后输入密钥,正确则验证第二个输入的代码,通过过滤则再执行

密钥可以直接通过locals函数获得,同时可以获得一个黑名单,但是下面的第二次执行却被过滤了,尝试了很久很久后才猜测是不是长度的问题,测试了一下只能执行长度不超过13的代码

配合上黑名单里的点号和引号,花括号,使我们难以构造字符串,而且__import__unicode后虽然可以执行但是长度也很夸张了,即使是eval(input())也有13位,刚好不够
所以就有了标题的pdb,在执行到breakpoint函数时,相当于给程序下了断点,并且可以进行debug

然后就可以进行命令执行和显示代码之类的操作
因此这道题也就出了

注意如果要看代码需要先step进入函数,然后ll查看当前函数的所有源代码
如果有需要更改执行流程之类的操作,可以去详细学习pdb的用法,在此就只抛砖引玉了
另外附上完整题目代码方便师傅们复现:

#!/usr/bin/env python3
WELCOME = '''
    ____           __                __
   / __ \___  ____/ /________  _____/ /__
  / /_/ / _ \/ __  / ___/ __ \/ ___/ //_/
 / _, _/  __/ /_/ / /  / /_/ / /__/ ,<
/_/ |_|\___/\__,_/_/   \____/\___/_/|_|

  '''
blacklist = [ "exec","input","eval","help","os","import",".","\'","\"","{","}" ]

def filter_input(input_data) -> bool :
    if len ( input_data ) > 12 :
        return False
    for word in blacklist :
        if word in input_data :
            return False
    return True

def filter_input1(input_data) -> bool :
    if len ( input_data ) > 9 :
        return False
    for word in blacklist :
        if word in input_data :
            return False
    return True

import random
import string
secret_key = ''.join ( random.choices ( string.ascii_letters + string.digits, k=12 ) )
print ( WELCOME )
print ( "放我自由!")
print ( "先告诉我牢笼的密钥,这样我才有机会出来" )
print ( "允许你先问一个问题" )
input_data = input("> ")
if filter_input1(input_data) == False :
    print( "你是黑客!但是能力太低不能放我出来" )
    exit(0)
print('我的回答是:{}'.format(eval(input_data)))
input_key = input("> ")
if input_key != secret_key :
    print ( "你是黑客?" )
    exit(0)
print ( "不错我看好你" )
input_data = input("> ")
if filter_input(input_data) == False :
    print( "你是黑客!但是能力太低不能放我出来" )
    exit(0)
print('我的回答是: {}'.format(eval(input_data)))
0 条评论
某人
表情
可输入 255

没有评论

目录