UpLoad-labs靶场通关笔记

2023-11-11

目录

 

UpLoad-labs靶场通关

运行环境

Pass-01

Pass-02

Pass-03

Pass-04

Pass-05

Pass-06

Pass-07

Pass-08

Pass-09

Pass-10

Pass-11

Pass-12

Pass-13

Pass-14

Pass-15

Pass-16

Pass-17

Pass-18

Pass-19

Pass-20

Pass-21


UpLoad-labs靶场通关


 

运行环境

windows2008 + phpstudy

靶场源码:https://github.com/c0ny1/upload-labs

Pass-01

文件上传前端验证

这里我们检查元素,发现在点击上传按钮时,通过事件(onsubmit)触发JS代码检测,在前端进行过滤检查,限制用户非法提交

分析checkFile() 过滤函数

 

function checkFile() {
    //获取到用户上传的文件名
    var file = document.getElementsByName('upload_file')[0].value;
    if (file == null || file == "") {
        alert("请选择要上传的文件!");
        return false;
    }
    //定义允许上传的文件类型 白名单
    var allow_ext = ".jpg|.png|.gif";
    //提取上传文件的类型
    var ext_name = file.substring(file.lastIndexOf("."));
    //判断上传文件类型是否允许上传
    if (allow_ext.indexOf(ext_name + "|") == -1) {
        var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name;
        alert(errMsg);
        return false;
    }
}
//indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。
//lastIndexOf() 方法可返回一个指定的字符串值最后出现的位置,在一个字符串中的指定位置从后向前搜索。

 

这里我们可以通过修改前端代码绕过检测

删除掉这个事件触发的 checkFile 函数

成功绕过,上传成功

每次上传测试成功之后,都清空一下上传文件,防止后面关卡测试时上传文件名冲突

Pass-02

文件上传MIME文件类型检测

直接分析关键代码

 

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    //file_exists() 函数检查文件上传目录是否存在。
    if (file_exists(UPLOAD_PATH)) {
        //通过$_FILES['upload_file']['type']获取并检测文件MIME类型
        if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name']            
            //move_uploaded_file() 函数将上传的文件移动到新位置。
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '文件类型不正确,请重新上传!';
        }
    } else {
        $msg = UPLOAD_PATH.'文件夹不存在,请手工创建!';
    }
}

 

$_FILES['upfile']['name']; //客户端上传文件的名称,不包含路径

$_FILES['upfile']['type']; //上传文件的MIME类型  

$_FILES['upfile']['tmp_name']; //已上传文件在服务器端保存的临时文件名,包含路径

$_FILES['upfile']['error']; //上传文件出现的错误号,为一个整数

$_FILES['upfile']['size']; //已上传文件的大小,单位为字节

 

抓包,直接修改文件类型为容许通过的MIME类型

绕过MIME文件类型检测,成功上传

清空上传文件之后,下一关

Pass-03

后缀名黑名单限制

 

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        //定义黑名单
        $deny_ext = array('.asp','.aspx','.php','.jsp');
        //trim()去空格
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//删除文件名末尾的点
        //strrchr() 函数查找'.'在文件名中最后一次出现的位置,并返回从该位置到字符串结尾的所有字符,即取文件后缀名。
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //转换为小写
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //收尾去空格

        if(!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;            
            if (move_uploaded_file($temp_file,$img_path)) {
                 $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

 

绕过黑名单思路也很简单,可以上传.phtml .phps .php5 .pht等后缀

前提是apache的配置文件中存在如下配置

AddType application/x-httpd-php .php .phtml .phps .php5 .pht

直接上传文件后缀 .phtml即可绕过黑名单限制

测试成功

 

Pass-04

.htaccess绕过

限制条件

  • mod_rewrite模块开启

  • AllowOverride All

分析源代码,发现黑名单限制很死

 

$deny_ext = array(".php",".php5",".php4",".php3",".php2","php1",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2","pHp1",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf")

 

此时,我们可以通过上传.htaccess修改当前目录配置

 

SetHandler application/x-httpd-php 

 

将当前目录下的所有文件当作php来解析

上传.htaccess(注意,文件名一定是.htaccess) 配置文件到服务器upload目录下

上传成功之后,再上传任意后缀.png的webshell

成功拿到shell

Pass-05

.uert.ini绕过

查看核心代码,发现该有的防护一样都没落下

 

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//删除文件名末尾的点
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //转换为小写
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //首尾去空

        if (!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.$file_name;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '此文件类型不允许上传!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

 

这关是比较新的一关,跟着前人的脚步,拿下这一关

文件目录目录下的.user.ini 中的字段也会被 php 视为配置文件来处理,从而导致 php 的文件解析漏洞。

那么想要引发.user.ini解析漏洞需要三个条件

服务器脚本语言是PHP

服务器开启了CGI/FastCGI模式

上传目录下有可执行文件(才明白提示说有个readme.php)

phpstudy切换版本,nts就是Fast-CGI模式

确保环境ok之后

上传.user.ini文件,文件内容

auto_prepend_file=phpinfo.png

//auto_append_file,在php文件中自动包含指定的文件

之后上传文件phpinfo.png,文件内容就是我们的webshell

上传成功之后,我们访问readme.php就自动文件包含了webshell

Pass-06

大小写绕过

分析关键代码,发现代码基本和前面一致,但是少了strtolower()函数,将上传文件后缀转换为小写

 

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        //黑名单限制了htaccess
        $deny_ext = array(".php",".php5",...",".htaccess");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//删除文件名末尾的点
        $file_ext = strrchr($file_name, '.');
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //首尾去空

        if (!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '此文件类型不允许上传!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

 

上传phpinfo.PHP

执行成功

Pass-07

空格绕过

分析核心代码,发现在最后少了trim($file_ext)首尾去空格(即".php ",绕过黑名单)

 

$deny_ext = array(".php",".php5",...,".htaccess");
$file_name = $_FILES['upload_file']['name'];
$file_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA

 

这里只需使用bp抓包 在上传文件名后加上空格,即可绕过

测试成功

Pass-08

加”.“绕过

分析核心代码

发现在开始少了没有删除文件末尾的"." deldot()

 

$file_name = trim($_FILES['upload_file']['name']);
$file_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //首尾去空

 

在后缀名中加”.”绕过

由于windows特性,会自动去掉后缀名中最后的”.”,在windwos平台上可测试成功

Pass-09

::$DATA绕过

分析核心代码

缺少了str_ireplace('::$DATA', '', $file_ext)

 

$file_name = trim($_FILES['upload_file']['name']);
$file_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = trim($file_ext); //首尾去空

 

php在window的时候如果文件名+"::$DATA"会把::$DATA之后的数据当成文件流处理,不会检测

后缀名.且保持"::$DATA"之前的文件名

目的便是为了不检查后缀名

上传成功

去掉::$DATA后缀,访问成功

Pass-10

核心代码分析

 

 

$file_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //首尾去空

 

bp抓包修改文件名后缀为 .php. .

访问成功

Pass-11

双写绕过

分析核心代码,发现str_ireplace()函数,自然想到双写绕过

 

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","pht","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess","ini");

        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = str_ireplace($deny_ext,"", $file_name);
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $img_path = UPLOAD_PATH.'/'.$file_name;        
        if (move_uploaded_file($temp_file, $img_path)) {
            $is_upload = true;
        } else {
            $msg = '上传出错!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

 

bp抓包改文件名即可

测试成功

Pass-12

00截断(GET)

需要满足条件

php版本小于5.3.4

magic_quotes_gpc = Off

 

分析源码,发现用户这里的save_path是 get传参,客户端本地可控,可尝试在save_path中添加%00截断,绕过服务端白名单限制

 

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $ext_arr = array('jpg','png','gif');
    $file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
    if(in_array($file_ext,$ext_arr)){
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
        //这里是%00截断的关键,save_path的参数用户可控
        //原本:$img_path="../upload/754379895453.png"
        //而当我们提交save_path=../upload/1.php%00
        //%00截断后面的字段:$img_path="../upload/1.php"

        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        } else {
            $msg = '上传出错!';
        }
    } else{
        $msg = "只允许上传.jpg|.png|.gif类型文件!";
    }
}

 

上传.png后缀的webshell

此时在upload目录下已经成功写入1.php

访问成功

Pass-13

00截断(POST)

条件跟上一关条件一样

这一关与上一关大体类似,只是save_path参数的传递形式由原来的get变为post

注意

get会自动解码 %00

post不会自动解码 %00

所以,我们在上传之前就要对%00进行解码

将解码之后的字符粘过去替换原来的%00,此时该字符不可见

成功

 

Pass-14

图片木马

分析核心代码

 

function getReailFileType($filename){
    $file = fopen($filename, "rb");
    $bin = fread($file, 2); //只读2字节
    fclose($file);
    $strInfo = @unpack("C2chars", $bin);   //解码二进制数据 
    //intval() 函数用于获取变量的整数值
    $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);    
    $fileType = '';   
    //比较判断文件类型 
    switch($typeCode){      
        case 255216:            
            $fileType = 'jpg';
            break;
        case 13780:            
            $fileType = 'png';
            break;        
        case 7173:            
            $fileType = 'gif';
            break;
        default:            
            $fileType = 'unknown';
        }    
        return $fileType;
}

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $file_type = getReailFileType($temp_file);

    if($file_type == 'unknown'){
        $msg = "文件未知,上传失败!";
    }else{
        $img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$file_type;
        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        } else {
            $msg = "上传出错!";
        }
    }
}

 

选择一张图片

制作方法

直接使用记事本打开图片,将webshell加入到末尾

使用命令 copy 1.jpg /b + info.php /a 2.jpg

直接在webshell文件前面加入文件头字段,修改指定后缀

上传成功后,借用文件解析漏洞测试成功

 

Pass-15

getimagesize() //获取图像信息

同14关

Pass-16

exif_imagetype() // 读取一个图像的第一个字节并检查其签名

同14关

Pass-17

部分代码

 

//判断文件后缀和文件类型
if(($fileext == "jpg") && ($filetype=="image/jpeg")){
        if(move_uploaded_file($tmpname,$target_path)){
            //使用上传的图片生成新的图片
            $im = imagecreatefromjpeg($target_path);
            //imagecreatefromjpeg — 由文件或 URL 创建一个新图象
            if($im == false){
                $msg = "该文件不是jpg格式的图片!";
                @unlink($target_path);
            }else{
                //给新图片指定文件名
                srand(time());
                $newfilename = strval(rand()).".jpg";
                //显示二次渲染后的图片(使用用户上传图片生成的新图片)
                $img_path = UPLOAD_PATH.'/'.$newfilename;
                imagejpeg($im,$img_path);
                @unlink($target_path);
                $is_upload = true;
            }
        } else {
            $msg = "上传出错!";
        }

 

本关综合判断了后缀名、content-type,以及利用imagecreatefromjpeg判断是否为jpeg图片,最后再做了一次二次渲染

这一关用常规的图片木马值作方法是无法绕过imagecreatefromjpeg函数的,因为imagecreatefromjpeg二次渲染它相当于是把原本属于图像数据的部分抓了出来,再用自己的API 或函数进行重新渲染,在这个过程中非图像数据的部分直接就隔离开

可以参考某大牛的绕过方式,通过比较gif图片在使用函数imagecreatefromgif转换之前和之后通过python脚本比较转换前后相似的部分,再将其替换为webshell

传送门---> https://secgeek.net/bookfresh-vulnerability/

注意上面文章末尾给出了POC.gif

需要修改php.ini的配置文件,使其支持解析<??>

上传成功测试成功

 

Pass-18

条件竞争

分析核心代码

 

$is_upload = false;
$msg = null;

if(isset($_POST['submit'])){
    //定义上传后缀白名单
    $ext_arr = array('jpg','png','gif');
    $file_name = $_FILES['upload_file']['name'];
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $file_ext = substr($file_name,strrpos($file_name,".")+1);
    $upload_file = UPLOAD_PATH . '/' . $file_name;
    //在文件未作检查之前上传到服务器端
    if(move_uploaded_file($temp_file, $upload_file)){
        //检查文件后缀
        if(in_array($file_ext,$ext_arr)){
             $img_path = UPLOAD_PATH . '/'. rand(10, 99).date("YmdHis").".".$file_ext;
             rename($upload_file, $img_path);
             $is_upload = true;
        }else{
            $msg = "只允许上传.jpg|.png|.gif类型文件!";
            //删除文件
            unlink($upload_file);
        }
    }else{
        $msg = '上传出错!';
    }
}

 

可以发现文件是先上传到upload目录下,之后进行检查后缀,再重命名

但是这里有个逻辑问题,就是先上传文件,再检查后缀名,就是我们可以上传webshell.php文件到服务器端,该文件会在服务器端短暂停留一段时间,之后检测到其后缀不在白名单中,走else ,将其删除。

上传info.php文件

首先bp抓包,将其发送至intruder模块,不断重复发包

持续发包

一直刷新浏览器,终于连上了(手疼)

Pass-19

同上,条件竞争,太菜没有测试成功

Pass-20

/.绕过

核心代码分析

 

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        //黑名单限制
        $deny_ext = array("php","php5",...,"php2",,"htaccess");
        $file_name = $_POST['save_name'];
        //pathinfo() 函数以数组的形式返回文件后缀
        $file_ext = pathinfo($file_name,PATHINFO_EXTENSION);

        if(!in_array($file_ext,$deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH . '/' .$file_name;
            if (move_uploaded_file($temp_file, $img_path)) { 
                $is_upload = true;
            }else{
                $msg = '上传出错!';
            }
        }else{
            $msg = '禁止保存为该类型文件!';
        }

    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

 

pathinfo() 函数以数组的形式返回关于文件路径的信息

  • PATHINFO_DIRNAME - 只返回 dirname

  • PATHINFO_BASENAME - 只返回 basename

  • PATHINFO_EXTENSION - 只返回 extension

  • PATHINFO_FILENAME - 只返回 filename

这里通上传的save_name参数20.php/.此时pathinfo()取到的后缀是.php/. 绕过黑名单限制

保存时 此时的路径变为 ../upload/20.php/.

此时在upload目录下

也可通过00截断过关

 

Pass-21

数组+/绕过

代码审计

 

$is_upload = false;
$msg = null;
if(!empty($_FILES['upload_file'])){
    //检查MIME
    $allow_type = array('image/jpeg','image/png','image/gif');
    if(!in_array($_FILES['upload_file']['type'],$allow_type)){
        $msg = "禁止上传该类型文件!";
    }else{
        //检查文件名(着重注意)
        $file = empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name'];
        if (!is_array($file)) {
            $file = explode('.', strtolower($file));
        }

        $ext = end($file);
        $allow_suffix = array('jpg','png','gif');
        if (!in_array($ext, $allow_suffix)) {
            $msg = "禁止上传该后缀文件!";
        }else{
            //(着重注意)
            $file_name = reset($file) . '.' . $file[count($file) - 1];
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH . '/' .$file_name;
            if (move_uploaded_file($temp_file, $img_path)) {
                $msg = "文件上传成功!";
                $is_upload = true;
            } else {
                $msg = "文件上传失败!";
            }
        }
    }
}else{
    $msg = "请选择要上传的文件!";
}

 

bp抓包修改数据

测试成功

 

参考:

https://www.jianshu.com/p/55a50c4bf576

https://xz.aliyun.com/t/2435#toc-17

https://wooyun.js.org/drops/user.ini%E6%96%87%E4%BB%B6%E6%9E%84%E6%88%90%E7%9A%84PHP%E5%90%8E%E9%97%A8.html

https://secgeek.net/bookfresh-vulnerability/

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

UpLoad-labs靶场通关笔记 的相关文章

  • PHP 相对于 ASP.NET 有什么优势? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 在 Doctrine 2 ORDER BY 中使用 DQL 函数

    我正在使用 MySQL 数据库在 Symfony 2 3 和 Doctrine 2 4 中做一个项目 我有一个 FieldValue 实体 简化 class FieldValue The ID var integer protected f
  • Laravel 5 清除视图缓存

    我注意到 Laravel 缓存视图存储在 storage framework views 随着时间的推移 他们会吃掉我的空间 我该如何删除它们 有什么命令可以吗 我试过php artisan cache clear 但它并没有清除视图缓存
  • 会话变量从 while 循环发送特定变量

    我有这个简单的while 循环它从 mysql 查询中检索数据并在我的主页上显示几个链接 我想避免使用 php get 函数并将查询字符串添加到我的网址中 我正在考虑使用会话变量 但我需要帮助 而且我很确定这是无法完成的 当访问者单击 wh
  • Laravel 模型访问器从缓存中获取 - 性能增强

    我在数据库中有一个项目列表 每个项目都可以选择被否决或赞成 这些投票与其他项目字段一起存储在 MySql 中 例如这样的事情 Schema create items function table table gt increments id
  • 如何通过索引获取 PHP DOMDocument 的子级

    我正在尝试获取 PHP DOMDocument 的子级 假设我有一个这样的 DOM 文档 div h1 h1 div div div class test div div 我有一个索引号3 然后我需要获取该元素 div class test
  • 使用 PHP 发送器和 Swift 在后台未收到 IOS GCM 推送通知

    我正在努力让后台通知在带有 GCM 的 IOS 上工作 非后台通知已经可以工作了 以下是我集成后台通知的步骤 在 UIBackgroundmodes 中启用远程通知标签 将内容可用密钥添加到我的通知负载中 在我的委托中编写 applicat
  • Laravel中间件获取路由参数

    我正在编写诸如 学校俱乐部管理系统 之类的东西 并遇到一些资源授权问题 假设有club and club有经理 我想检查用户是否是经理club在他可以使用中间件管理它之前 使用 Laravel 5 2 My router看起来像这样 Rou
  • php 验证十进制格式的纬度/经度字符串

    好吧 我有一个巨大的经度和纬度坐标列表 也就是说 我还有一些来源来提取这些坐标 其中一些来自 get post 方法 这可能会导致我的网站 服务中存在潜在的安全漏洞 所以我想弄清楚如何通过 PHP 验证经度和纬度 我正在考虑通过 preg
  • PHP imagettftext 返回的边界框与渲染的边界框不同

    我正在使用 imagettftext 渲染 PNG 文件 对 imagettftext 的调用返回渲染文本的边界框 但仔细检查后发现 文本的渲染稍微超出了它自己的边界框 边界框是正确的 我检查了图像的像素坐标 但文本位置不正确 它输出这个
  • PHP Define() 似乎不能与 include() 一起使用

    我一直在尝试 OO PHP 目前拥有三个文件 我有一个 class lib php 目前它只有一个databaseServer 类 一个index php 文件和一个definitions php 文件 我想将所有敏感数据库信息放入定义文件
  • 如果 CodeIgniter 方法不存在,则重定向到默认方法。

    我正在使用 CodeignIter 并且正在寻找一种在被调用方法不存在时为单个控制器编写自定义处理例程的方法 假设你打电话www website com components login In the components控制器 没有一个方
  • 处理 PHP 中的会话劫持

    阅读了 Stackoverflow 上有关会话劫持的许多问题 我发现验证用户会话的唯一 解决方案 是检查用户代理 这是一个薄弱的保护层 我什至懒得去检查实施它 所以 我想知道你们实施了哪些解决方案 您是否使用 PHP 的本机会话或者是否有更
  • PHP 中的依赖注入

    我一直在研究依赖注入 我是在关注某件事还是完全没有关注 代码是好是坏 依赖注入与否 下面的代码是CMS系统的基础 现在有一个名为 page details 的表 其中存储了所有网页 目录 文件结构 htaccess index php cl
  • 使用PHP将大文件上传到谷歌云存储

    我正在尝试将大文件从服务器上传到云存储 文件超过 500mb 但 PHP 超时 我尝试查看 Google 客户端库文档 并在 stackoverflow 中进行爬行 但找不到任何可以帮助我的内容 还有有什么办法可以跟踪上传进度吗 这是我目前
  • Highcharts 异步服务器加载多个系列

    我正在尝试按照其示例使用 Highcharts 的延迟加载 http www highcharts com stock demo lazy loading http www highcharts com stock demo lazy lo
  • 限制在WhereHas内

    所以我想获取最后状态等于给定状态的请求 我尝试过first 但它给了我一个错误并且限制不起作用 requests Request whereHas requestStatus function query use status return
  • 如何使用 mod rewrite / htaccess 创建具有两个或多个参数的友好 URL?

    新手在这里重写Mod 我想在 URL 中传递两个 URL 参数 但采用更友好的格式 如果用户通过 example com blah123 sys 在本例中我应该能够提取 MySQL 记录 blah123 和模式类型 sys 这是例子 URL
  • 如何使用 php $row 检索 sql 日期时间对象?

    例如 sql SELECT FROM db query sqlsrv query conn sql while row sqlsrv fetch array query echo row date column 会崩溃 我找到的大多数答案都
  • 如何使用 PHP 读取/显示 XML

    有没有办法使用 PHP 读取 external xml 来自不同网站的 xml 文件 我知道有一种方法可以使用 JavaScript 读取 XML 但前提是它们都位于同一根目录中 您能否提供有关如何获取 xml 文件的示例 然后阅读以下内容

随机推荐

  • SpringBoot_3

    1 Spring Initializer快速创建Spring Boot项目 src main java 保存java源代码 src main resources application properties Spring Boot应用的配置
  • 二分类指标计算

    加载预训练模型计算测试数据集的LogLoss AUC和EER 需要根据具体场景选择相应的计算方法 以下是三种常见的方法 1 计算LogLoss python import torch from torch utils data import
  • STM32-外部中断

    外部中断概述 STM32的每个IO都可以作为外部中断输入 STM32F1的中断控制器支持19个外部中断 事件请求 线0 15 对应外部IO口的输入中断 线16 连接到PVD输出 线17 连接到RTC闹钟事件 线18 连接到USB唤醒事件 每
  • 【OceanBase概念】国产数据库OceanBase的那些事儿(1)初识OceanBase

    文章目录 写在前面 涉及知识点 1 OceanBase是什么 1 1基本概念 1 2发展历史 2 TPC C认证 2 1什么是TPCC 2 2OceanBase认证成果 3 OceanBase应用场景 3 1行业应用 A 金融行业 B 电信
  • 51单片机键盘、矩阵键盘松手检测

    一 对独立按键进行松手检测 当按键按下时 会导致51单片机相应引脚变为低电平 利用这个原理 可以进行按键检测 就像下面这段代码 if KEY1 0 delay ms 10 if KEY1 0 如果想要对按键是否能够连按进行控制 只需改成下面
  • 【软件测试】自动化测试战零基础教程——Python自动化从入门到实战(一)

    第一章 自动化测试基础 第一节 软件测试分类 关于软件测试领域名词颇多 发现有许多测试新手混淆概念 从不同的角度可以将软件测试有不同的分类的方法 所以 这里汇总常见软件测试的相关名词 对软件测试领域有个概括的了解 根据项目流程阶段划分软件测
  • 常见的数据类型之间的转换--Qt

    前言 在项目中 经常用到一些基本数据类型之间的转换 而记性越发不好的今天 只能每次都去请教度娘 这就很不好 故在此做一些总结 方便查阅 介绍 在写此文章时 查了一些资料 然后发现数据类型之间的转换 也包含有一些之前没注意过的细节 感觉颇有收
  • 前后端学习

    最近和锴哥想搞一下前后端接口的事儿 但是不会 所以打算再学学前后端的基础知识 之后好抄作业 做缝纫机 达哥觉得我浮躁 这次一定要支棱起来 这次开始 面向openai学习 前后端学习 1 前端 1 1 HTML 1 1 1标签 1 1 2属性
  • 介绍一个界面库附防QQ2009教程

    牛人的BLOG http blog csdn net ringphone界面库 http blog csdn net ringphone archive 2010 01 05 5132830 aspx循序渐进实现仿QQ界面 一 园角矩形与双
  • springboot集成mybatis+mysql/impala实现双数据源

    最近大数据服务端项目开发需要springboot框架通过impala查询工具直接查hadoop的HDFS数据源 同时也需要查大数据聚合mysql数据 需要实现双数据源 所以研究了下 在springboot框架下 通过java语言来连接imp
  • shared_ptr在Qt项目中使用,慎重

    偶然查到到了一个崩溃 记录一下 一个继承自QObject的自定义类 里面有什么并不重要 class TestProcess public QObject Q OBJECT 摘取了部分实现 眼尖的大佬不妨看下 下面的代码是不是有问题 shar
  • java初学(九)给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

    给定一个排序数组和一个目标值 在数组中找到目标值 并返回其索引 如果目标值不存在于数组中 返回它将会被按顺序插入的位置 你可以假设数组中无重复元素 示例 1 输入 1 3 5 6 5 输出 2 示例 2 输入 1 3 5 6 2 输出 1
  • 使用WebContext.Items 存储Linq to sql 的DataContext实例引发"InvalidCastException"错误

    为了保证在一次请求过程中 使用同一个DataContext实例 我们项目使用WebContext items 来存储这个实例 最近不知道怎么回事 总是偶然性的抛出下面这个类型转换失败错误 百思不得其解 最后在MSDN的一个帖子里找到一种解释
  • 如何获取li标签中的值

    前言 最近在做动态添加表单 管理员从后台添加了菜单 一般用户登录 可以看到管理员新添加的菜单 和菜单中的属性 但是问题来了 动态添加完了 到展示给一般用户的页面 现在能想到的就是for循环出来的 但是要去到for循环出来的li标签的值怎么取
  • 机器视觉毕业设计 深度学习人脸识别系统设计与实现 - opencv python

    文章目录 0 前言 1 机器学习 人脸识别过程 人脸检测 人脸对其 人脸特征向量化 人脸识别 2 深度学习 人脸识别过程 人脸检测 人脸识别 Metric Larning 0 前言 这两年开始毕业设计和毕业答辩的要求和难度不断提升 传统的毕
  • SpringBoot项目引入token设置

    一 先了解熟悉JWT JSON Web Token 看这些介绍 结构之类的 确实挺无聊的 想直接进入主题的话 就跳过第一大步 望各位同仁给出相关意见 以备我来更加深入的学习 1 JSON Web Token是什么鬼 这个东西 反正理解成一个
  • Ubuntu安装ftp

    1 安装 sudo apt install vsftpd 2 添加一个用户 sudo adduser ftp zhang 然后输入密码Zhang 520 之后会自动在 home 创建ftp zhang目录 3 修改配置文件 sudo vi
  • Python循环语句简单练习题及答案解析

    1 这里的问题是猜出电脑里存储的数字是什么 你将要编写一个能够随机生成一个0到100之间且包括0和100的数字的程序 这个程序提示用户连续地输入数字直到它与那个随机生成的数字相同 对于每个用户输人的数字 程序会提示它是否过高还是过低 所以
  • 7、寻找最好成绩

    问题描述 建立一个对象数组 内放若干个学生的学习数据 学号 成绩 设计一函数max 使用学生对象数组作为参数 在max函数里找出这些学生中成绩最高者 并输出其学号及成绩 在main函数中使用并测试之 在main函数中读入学生数据 创建学生对
  • UpLoad-labs靶场通关笔记

    目录 UpLoad labs靶场通关 运行环境 Pass 01 Pass 02 Pass 03 Pass 04 Pass 05 Pass 06 Pass 07 Pass 08 Pass 09 Pass 10 Pass 11 Pass 12