file.pm 84: opendir(D, $path) or 132: open(F, $path) orreturnnew #这里的open中的path是可控的,所以可以把文件名拼接入命令导致命令执行。
open函数本身还支持file协议
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
... =head2 File Request
The library supports GET and HEAD methods for file requests. The "If-Modified-Since" header is supported. All other headers are ignored. The I<host> component of the file URL must be empty or set to "localhost". Any other I<host> value will be treated as an error.
Directories are always converted to an HTML document. For normal files, the "Content-Type" and "Content-Encoding" in the response are guessed based on the file suffix.
# test file exists and is readable unless (-e $path) { return HTTP::Response->new( &HTTP::Status::RC_NOT_FOUND, "File `$path' does not exist"); } ... # read the file if ($method ne "HEAD") { open(F, $path) or return new HTTP::Response(&HTTP::Status::RC_INTERNAL_SERVER_ERROR, "Cannot read file '$path': $!");
1.我们输入的内容是由get执行的,get执行的是path,如果path本身是命令,就会直接执行。 2.get执行的对象其实是$path,当我们传入的命令的时候,找不到该path,就会出现$path’ does not exist,所以此时我们需要先建立出同命令的文件名,更合理的说应该是路径。如果我的理解有误一定来和我讨论一下,,,
__author__ = 'r0ker' import tornado.web import db from config import URL, sql fromfunctionimportmd5 classLoginHandler(tornado.web.RequestHandler): defget(self): ifself.get_secure_cookie("username") andself.get_secure_cookie("password"): self.redirect("/") else: self.render("login.html", url=URL) defpost(self): self.set_header("Content-Type", "text/plain") if True not in [f in self.get_argument("email") for f in sql]: row = db.ct( "manager", "*", "username='"+self.get_argument("email")+"' and password='" + md5(self.get_argument('pass'))+"'") if row: self.set_secure_cookie("username", row['username']) self.set_secure_cookie("password", row['password']) self.write("true")