bash 使用 shell 脚本进行 CGI 编程

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1206494/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 21:06:20  来源:igfitidea点击:

CGI programming with shell scripts

securitybashshellcgi

提问by

I need to pass the content of the textbox into a variable. i.e. whatever typed in the texbox of the html page needs to be pass to a variable. This is because I am calling HTML (CGI as well) inside linux shell programming. I need to manipulate that variable as I want. Do you have any idea to do it?

我需要将文本框的内容传递给一个变量。即在 html 页面的 texbox 中输入的任何内容都需要传递给变量。这是因为我在 linux shell 编程中调用了 HTML(以及 CGI)。我需要根据需要操纵该变量。你有什么想法吗?

What I need to do is, I want to get the MAC address as an input from the user. i.e. we should have a HTML page with a text box, that user will be able to input the MAC address. therefore whatever user enters into the text box need to be passed to a variable.

我需要做的是,我想从用户那里获取 MAC 地址作为输入。即我们应该有一个带有文本框的 HTML 页面,该用户将能够输入 MAC 地址。因此,无论用户在文本框中输入什么,都需要传递给变量。

Once we have the variable, this script will automatically add this MAC address into linux firewall to deny the access.

一旦我们有了这个变量,这个脚本就会自动将此 MAC 地址添加到 linux 防火墙中以拒绝访问。

The code should be similar to the following:

代码应类似于以下内容:

!/bin/bash

echo "Content-type: text/html"

echo ""

echo ""

echo "enter the MAC address "

iptables -A INPUT -m mac --mac-source $mac_address -j DROP

service iptables save

service iptables restart

I will save this file (test.cgi) under /var/www/cgi-bin directory and I will run this script from firefox.

我将把这个文件 (test.cgi) 保存在 /var/www/cgi-bin 目录下,然后从 firefox 运行这个脚本。

So the problem now I have the variable $mac_address. The CGI does not pass the textbox input into variable $mac_address.

所以现在的问题是我有变量$mac_address. CGI 不会将文本框输入传递给变量 $mac_address。

回答by Sinan ünür

The real answer to this question is don't.

这个问题的真正答案是不要

Your web server seems to be running with rootprivileges. That is the first no-no.

您的 Web 服务器似乎以root特权运行。这是第一个禁忌。

Do you really want to allow the whole wide world to be able to tinker with your firewall configuration? You have no control over how your shell script gets invoked, what gets passed to it. You are opening majorsecurity holes.

您真的想让整个世界都能够修改您的防火墙配置吗?您无法控制如何调用 shell 脚本,以及传递给它的内容。您正在打开主要的安全漏洞。

See the WWW Security FAQ on CGI scriptsand Writing secure CGI scriptsas well as CGI Security : Better Safe than Sorry.

请参阅有关 CGI 脚本WWW 安全常见问题解答编写安全的 CGI 脚本以及CGI 安全性:比抱歉更安全

回答by Warren Young

First, read the CGI primer.

首先,阅读CGI 入门

You will need an HTML page with code like this:

您将需要一个带有如下代码的 HTML 页面:

<form method="get" action="/cgi-bin/my-fw-script.sh">
    <p>Gimme an IP address: <input name="addr"></p>
    <input type="submit">Block IP</input>
</form>

When the user clicks the form's Submit button, your Bash CGI program will be run. (/path/to/cgi-bin/my-fw-script.shin the above example.) The text input will be in the QUERY_STRING environment variable, in the form variable=value. For simple inputs, you could just call the Bash function eval to turn this into a Bash variable:

当用户单击表单的提交按钮时,您的 Bash CGI 程序将运行。(以上示例中的/path/to/cgi-bin/my-fw-script.sh。)文本输入将在 QUERY_STRING 环境变量中,格式为variable=value。对于简单的输入,您可以调用 Bash 函数 eval 将其转换为 Bash 变量:

#!/bin/sh
eval $QUERY_STRING
echo You asked me to block $addr.

This will only work for a single input field, and will break if there are spaces or other special characters. I imagine the bash_cgi thing someone else recommended will take care of these details for you. Do it like the above example only if this program will stay very simple.

这仅适用于单个输入字段,如果有空格或其他特殊字符,则会中断。我想其他人推荐的 bash_cgi 东西会为你处理这些细节。只有当这个程序保持非常简单时,才像上面的例子那样做。

By the way, you almost certainly don't want to be adding MAC addresses to the firewall. That only works for hosts that are on the same LAN as the firewalled box. Packets coming from another LAN, the Internet, etc. will have the MAC address of the LAN's gateway. You should probably be blocking hosts by IP address instead.

顺便说一下,您几乎肯定不想将 MAC 地址添加到防火墙。这仅适用于与防火墙设备位于同一 LAN 上的主机。来自另一个 LAN、Internet 等的数据包将具有 LAN 网关的 MAC 地址。您可能应该通过 IP 地址来阻止主机。

回答by Alex Gray

Check out bashlib - CGI programming with the bash shell

查看bashlib - 使用 bash shell 进行 CGI 编程

bashlib is a shell script that makes CGI programming in the bash shell easier, or at least more tolerable. It contains a few functions that get called automatically and place form elements (from POSTs and GETs) and cookies in your environment. It also contains complete documentation on how to use these variables and how to set cookies manually.

bashlib 是一个 shell 脚本,它使 bash shell 中的 CGI 编程更容易,或者至少更容易接受。它包含一些自动调用的函数,并在您的环境中放置表单元素(来自 POST 和 GET)和 cookie。它还包含有关如何使用这些变量以及如何手动设置 cookie 的完整文档。

It is super easyto use and makes passing url strings as variables, etc a breeze. Don't let the naysayers hate on bash as a web scripting language. It can hold its own... and it's simple, pervasive, and effective... This goes slightly against the grain, but if you're not easily peer pressured, I'd say go for it.

它非常易于使用,并且使将 url 字符串作为变量等传递变得轻而易举。不要让反对者讨厌 bash 作为 Web 脚本语言。它可以自成一格......而且它简单、普遍且有效......这有点违背常理,但如果你不容易受到同龄人的压力,我会说去吧。

#!/bin/bash
# this sources bashlib into your current environment
. /usr/local/lib/bashlib
echo "Content-type: text/html"
echo ""
# OK, so we've sent the header... now send some content
echo "<html><title>Crack This Server</title><body>"

Related and cool: xmlshand shellinabox.

相关且很酷: xmlshshellinabox

回答by Alex Gray

Sorry to keep harping on this point, I just think it's too fun...

抱歉在这一点上一直喋喋不休,我只是觉得这太有趣了......

So for the ultimate do-all CGI script, check this out...

因此,对于最终的全能 CGI 脚本,请查看...

warning...not for security freaks or anyone that isn't perfectly aware of what the below entails...

警告......不适用于安全怪胎或任何不完全了解以下内容的人......

#!/usr/bin/python
# /var/www/cgi-bin/doanything.cgi   r-xr-x---  wwwuser group
# what does this do?  LITERALLY ANYTHING.   Usage: 
# http://server.local/cgi/doanything.cgi?DO="if you can think of how to bash it"; THEN="bash it"; echo $THEN 
# result: bash it


import cgitb; cgitb.enable()
import os, urllib, subprocess as sub

# Retrieve the command from the query string and unencode the escaped %xx chars
str_command = urllib.unquote(os.environ['QUERY_STRING'])
p = sub.Popen(['/bin/bash', '-c', str_command], 
     stdout=sub.PIPE, stderr=sub.STDOUT)
output = urllib.unquote(p.stdout.read())

print """\
Content-Type: text/html\n
<html><body>
<pre>
<!-- UNCOMMENT THE FOLLOWING TO ECHO COMMAND --> 
<!-- $ %s  -->
%s
</pre>
</body></html>
""" % (str_command, output)