PHP开发总结
PHP开发总结
- PHP开发总结
- 漏洞(可控变量 特定函数)
- 文件操作(上传 下载 删除 包含 读取)
- 数据库(SQL注入)
- 输入输出(XSS)
- JS&Ajax
- TP框架

原生代码
漏洞(可控变量 特定函数)
文件操作(上传 下载 删除 包含 读取)
数据库(SQL注入)
输入输出(XSS)
JS&Ajax
传输
参数
状态
区别
TP框架
识别
漏洞
漏洞(可控变量 特定函数)
mysqli_select_db函数介绍
定义和用法
mysqli_select_db() 函数用于更改连接的默认数据库。
语法
mysqli_select_db(connection,dbname);
参数 | 描述 |
---|---|
connection | 必需。规定要使用的 MySQL 连接。 |
dbname | 必需,规定要使用的默认数据库。 |
技术细节
返回值: | 如果成功则返回 TRUE,如果失败则返回 FALSE。 |
---|---|
PHP 版本: | 5+ |
<?php
// 假定数据库用户名:root,密码:123456,数据库:RUNOOB
$con=mysqli_connect("localhost","root","123456","RUNOOB");
if (mysqli_connect_errno($con))
{
echo "连接 MySQL 失败: " . mysqli_connect_error();
}
// ...查询 "RUNOOB" 数据库的一些 PHP 代码...
// 修改数据库为 "test"
mysqli_select_db($con,"test");
// ...查询 "test" 数据库的一些 PHP 代码...
mysqli_close($con);
?>
mysqli_query()函数介绍
定义和用法
mysqli_query() 函数执行某个针对数据库的查询。
语法
mysqli_query(connection,query,resultmode);
参数 | 描述 |
---|---|
connection | 必需。规定要使用的 MySQL 连接。 |
query | 必需,规定查询字符串。 |
resultmode | 可选。一个常量。可以是下列值中的任意一个:MYSQLI_USE_RESULT(如果需要检索大量数据,请使用这个)MYSQLI_STORE_RESULT(默认) |
技术细节
返回值: | 针对成功的 SELECT、SHOW、DESCRIBE 或 EXPLAIN 查询,将返回一个 mysqli_result 对象。针对其他成功的查询,将返回 TRUE。如果失败,则返回 FALSE。 |
---|---|
PHP 版本: | 5+ |
更新日志: | 在 PHP 5.3.0 中新增了异步查询的功能。 |
<?php
// 假定数据库用户名:root,密码:123456,数据库:RUNOOB
$con=mysqli_connect("localhost","root","123456","RUNOOB");
if (mysqli_connect_errno($con))
{
echo "连接 MySQL 失败: " . mysqli_connect_error();
}
// 执行查询
mysqli_query($con,"SELECT * FROM websites");
mysqli_query($con,"INSERT INTO websites (name, url, alexa, country)
VALUES ('百度','https://www.baidu.com/','4','CN')");
mysqli_close($con);
?>
intval()
格式:intval(var,base)
- base:可选,无则十进制
- 如果base是0,通过检测var参数的格式来决定使用的进制
特性
获取变量整数值
eg:4.2取4
传入的字符串存在字母时,只会取字母前面的数字
eg:6e123取6
函数里面有运算式,会把e正确识别为科学计数法符号,并进行运算
eg:intval(1e1+1)=11
在没有运算式时,只会取e前面的数字,并不会把e看作科学计数法符号
在传入的参数非数字字符时,一律返回0
eg:intval('a')0 intval('.')0 intval('/')==0
0与字符串进行弱比较返回值为true
非空数组返回1 空数组返回0
_wakeup()
在反序列化之后立即被调用
将变量数改为大于真实变量数即可绕过
strcmp()
格式:strcmp(str1,str2)
该函数返回值
0
如果两个字符串相等<0
如果str1小于str2>0
如果str1大于str2
strcmp比较的是字符串类型,如果强行传入其他类型参数,会出错,出错后返回值0,正是利用这点进行绕过
例如:传入数组类型 str1[]=666
只有PHP5.3有此漏洞
assert()
会把读到的字符串当作php来执行,末尾不需要引号
eval()
会把督导的字符串当作php来执行,末尾需要有引号
include()
文件包含漏洞,会执行读到的PHP源码
特性:即使路径中的头目录不存在,也可以正确执行包含目标文件
例如: hint.php?/../../../flag.php
hint.php?这个目录不存在,但仍能够往上跳转4级目录,去包含flag.php
常见的文件包含函数还有:
include_once( )
功能与 Include()相同,区别在于当重复调用同一文件时,程序只调用一次
require( )
require()与 include()的区别在于 require()执行如果发生错误,函数会输出
错误信息,并终止脚本的运行。
require_once( )
功能与 require()相同,区别在于当重复调用同一文件时,程序只调用一次。
readfile()
读取一个文件,并写入到输出缓冲
特性:即使路径中的头目录不存在,也可以正确读取目标文件
例如: hint.php?/../../../flag.php
和include相似
call_user_func()
回调函数,call_user_func(a,b,...) a为要执行的函数名,剩下的都为a的参数,可以没有
返回值为将参数带入a函数的执行结果
但该函数还可以接受数组来调用类中的静态方法
例如:call_user_func($array);调用classname这个类里的sya_hello方法 array[0]=$classname 类名array[1]=say_hello say_hello()静态方法
trim()
该函数会移除变量中的
- "\0" - NULL
- "\t" - 制表符
- "\n" - 换行
- "\x0B" - 垂直制表符
- "\r" - 回车
- " " - 空格
但不会移除 \f 换页符,ASCII值为12 url编码为%0c
is_number()
可解析科学计数法
判断变量是否为纯数字,但变量开头有非打印字符(如\f \n)仍会识别为数字
extract()
将数组变量中的键和键值转化为变量名和变量,如果有冲突,则覆盖已有的变量
例子:
<?php
$a = "Original";
$my_array = array("a" => "Cat","b" => "Dog", "c" => "Horse");
extract($my_array);
echo "\$a = $a; \$b = $b; \$c = $c";
?>
// $a=Cat;$b=Dog;$c=Horse
parse_str()
函数把查询字符串(例如这种:*name=Peter&age=43*)解析到变量中
格式: parse_str(string,array)
array可选(规定存储变量的数组名称,该参数指示变量存储到数组中)
如果不设置array参数,将会覆盖同名变量
例如:
<?php
parse_str("name=Peter&age=43");
echo $name."<br>";
echo $age;?>
// Peter
43
get_defined_vars()
返回由所有已定义变量所组成的数组
可配合 var_dump使用
gettext()
gettext() 函数的工作原理是,在翻译前,需要使用 gettext() 函数将要翻译的文本字符串标记为可翻译字符串,然后环境中是什么语言,就会输出相应语言的翻译,该函数可用于凑数
()是gettext()的拓展函数在开启相关设定后,("666")等价于gettext("666")
<?php
echo gettext(666); //输出 666echo "\n";echo _("666"); //输出 666?>
匿名函数(create_function)
php里**默认命名空间是**,所有原生函数和类都在这个命名空间中
调用该函数需要前面加斜杠 /create_function()
该函数内部构造类似于
function fT(,$a) { echo "test".$a;}
该函数不需要第一个参数,并可添加第二个参数,可用于构造闭合
该函数自PHP 7.2起已经弃用
$_SERVER['argv']
$_SERVER['argv']:
1、cli模式(命令行)下
第一个参数$_SERVER['argv'][0]是脚本名,其余的是传递给脚本的参数
2、web网页模式下
在web页模式下必须在php.ini开启register_argc_argv配置项
设置register_argc_argv = On(默认是Off),重启服务,$_SERVER[‘argv’]才会有效果 这时候的$_SERVER[‘argv’][0] = $_SERVER[‘QUERY_STRING’] 此变量为URL问号后面的所有值
$argv,$argc在web模式下不适用
哈希函数
哈希函数(sha1,md5等),无法处理数组,若处理,会返回NULL,可用于===强比较
命令执行函数
有回显:
system()
passthru()
无回显:
exec()
shell_exec() 或者`` 反引号
无回显函数需要添加echo 输出 exec只返回最后一行内容 ,shell_exec()返回完整内容
在题目中如果没有echo的话,需要利用curl来实现flag.php的外带
全局变量
$GLOBALS所有已定义的变量都在此变量数组里存储
var_dump($GLOBALS) 可查看所有的变量信息
自增绕过
payload:
code=$(/.);$=$[''!=''];$%ff=%2b%2b$;$%ff=%2b%2b$.$%ff;$%2b%2b;$%2b%2b;$%ff.=%2b%2b$;$%ff.=%2b%2b$;$=.$%ff;$$_;&=system&__=cat /flag
违规变量名
PHP变量名由数字字母下划线组成,GET或POST方式传进去的变量名,会自动将空格 + . [转换为_
有一种特殊情况,GET或POST方式传参时,变量名中的 [ 也会被替换为_,但其后的字符就不再进行替换了
如 CTF[SHOW.COM = CTF_SHOW.COM
无法处理数组的函数
md5() 返回NULL
sha1() 返回NULL
preg_match() 返回false
intval() 非空数组返回1,空数组返回0
stripos() 返回NULL
strcmp() 返回0
命令运算
php里数字可以和命令可以进行运算,且不影响运行结果
并且也可以使用位运算符 |,或三目运算符
加减乘除运算符
<?php
$v1=1;
$v2=3;
$v3=-phpinfo();+ (url编码)
$code = eval("return $v1$v3$v2;");
echo "$v1$v3$v2 = ".$code;
?>
位运算符
<?php
$v1=1;
$v2=3;
$v3=|phpinfo();| (url编码)
$code = eval("return $v1$v3$v2;");
echo "$v1$v3$v2 = ".$code;
?>
三目运算符
<?php
$v1=1;
$v2=?phpinfo():;
$v3=1;
eval("return $v1$v2$v3;'");
>
PHP代码表示方式
正常写法xml格式
<?php
echo '1111';
?>
短标签
<?
echo '1111';
?>
<?= //相当于<? echo
?>
需要 php.ini 配置文件中的指令 short_open_tag 打开后才可用,或者在 PHP 编译时加入了 --enable-short-tags 选项。自 PHP5.4 起,短格式的 echo 标记 <?= 总会被识别并且合法,而不管 short_open_tag 的设置是什么
asp风格写法
<%
echo '1111';
%>
(注意:这种写法在php配置中默认关闭了的,如果要正常输出,需要配置php.ini文件。在配置文件中找到asp_tags=off ,将off改为on。改动配置文件后需要重启apache。)但是在php7之后被移除了
长标签风格
<script language="php">
</script>
在php7之后被移除了
松散比较
文件操作(上传 下载 删除 包含 读取)
上传
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>
<body>
<form id="upload-form"action="" method="post" enctype="multipart/form-data">
<input type="file" name="upload" id="upload">
<input type="submit" value="Upload">
</form>
</body>
</html>
<?php
$name=$_FILES['upload']['name'];
$type=$_FILES['upload']['type'];
$size=$_FILES['upload']['size'];
$tmp_name=$_FILES['upload']['tmp_name'];
$error=$_FILES['upload']['error'];
echo $name."<br>";
echo $type."<br>";
echo $size."<br>";
echo $tmp_name."<br>";
echo $error."<br>";
//移动文件 ==== 进一步思考,先验证文件,再移动文件
if($type=='image/png'){
if(!move_uploaded_file($tmp_name,'upload/'.$name)){
echo "文件移动失败";
}else{
echo "文件移动成功";
echo 'upload/'.$name;
}
}else{
echo "文件类型不正确";
}
?>
下载
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件下载</title>
</head>
<body>
<h1>直连下载</h1>
//类似与这种 xiaodi8.com/software/tools.rar
<form action="" method="post">
<input type="text" name="filename">
<input type="submit" value="下载">
</form>
<?php
$filename=$_POST['filename'];
filenameurl($filename);
?>
//自定义文件直连下载,需要获得用户提交的文件名称,然后拼凑出url进行下载
<?php
//自定义文件夹读取函数.获取指定路径下的目录
function getfilename(){
$path=getcwd();//获取当前文件所在的目录
$file=scandir($path.'/soft');//获取指定目录存在的文件
foreach ($file as $value){
if($value != '.' && $value != '..') {
$arr[] = $value;
echo $value.'<br>';
}
}
}
getfilename();
?>
<h1>传参下载</h1>
</body>
</html>
<?php
function filenameurl($filename){
$downloadurl='http://'.$_SERVER['HTTP_HOST'].'/conquer_blog/file/soft/'.$filename;
header("location:$downloadurl");
}
?>
删除
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件删除</title>
</head>
<body>
<hr>
<h1>文件删除</h1>
<?php getfilename();?>
<form action="" method="post" enctype="multipart/form-data">
<input type="text" name="name" /> <br />
<input type="submit" value="删除文件" />
</form>
<?php $name=$_POST['name'];delfilename($name);?><br />
<?php getfilename();?>
<form action="" method="post" enctype="multipart/form-data">
<input type="text" name="dir" /> <br />
<input type="submit" value="删除文件夹" />
</form>
<h1>文件夹删除</h1>
<?php $dir=$_POST['dir'];deifiledir($dir);?>
</body>
</html>
<?php
function getfilename()
{ //function 声明函数。后面是命名
$filepath = getcwd(); //读取当前目录
$filename = scandir($filepath); //扫描指定目录
foreach ($filename as $value) { //foreach数组遍历方法
if ($value != '.' && $value != '..') {
$arr[] = $value;
echo $value . '<br>';
}
}
}
function delfilename($name){
unlink($name); //删除文件
}
function deifiledir($dir){
rmdir($dir); //删除文件夹
}
包含
<?php
//include('test.txt');
//把test.txt 当成php文件来执行
//test.txt 即是可控变量
// 远程文件 本地文件
$file=$_GET['x'];
include($file);
//http://localhost/blog/file/file-include.php?x=test.txt
//http://localhost/blog/file/file-include.php?x=www.cctv.com/a.php 远程文件
//攻击: 上传一个图片,得到图片的路径。尝试包含此图片,图片里面有后门代码
?>
读取
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件读写操作</title>
</head>
<body>
<hr>
<?php getfilename();?>
<h1>文件读取</h1>
<form action="" method="post" enctype="multipart/form-data">
<input type="text" name="name" /> <br />
<input type="submit" value="读取文件" />
</form>
<?php $name=$_POST['name'];getfileread($name);?><br />
<h1>文件写入</h1>
<form action="" method="post" enctype="multipart/form-data">
需要写入的文件:<input type="text" name="name" /> <br />
需要写入的代码:<input type="text" name="txt" /> <br />
<input type="submit" value="写入文件" />
</form>
<?php $name=$_POST['name'];$txt=$_POST['txt'];filewrite($name,$txt);?><br />
</body>
</html>
<?php
function getfilename()
{ //function 声明函数。后面是命名
$filepath = getcwd(); //读取当前目录
$filename = scandir($filepath); //扫描指定目录
foreach ($filename as $value) { //foreach数组遍历方法
if ($value != '.' && $value != '..') {
$arr[] = $value;
echo $value . '<br>';
}
}
}
function getfileread($name){
$file = fopen("$name","r"); //fopen打开文件函数,r是模式,r的意思是只读
echo $contents = fread($file,filesize("$name")); //输出一下读取的内容
fclose($file);
}
function filewrite($name,$txt){
$myfile = fopen("$name","a+"); //fopen打开文件函数,a+是模式,a+的意思是写入,如果没有写入的文件就创建再写入
fwrite($myfile,$txt);
fclose($myfile);
}
数据库(SQL注入)
ogin.php
<form action="" method="POST">
帐号:<input type="text" name="user">
密码:<input type="password" name="pass">
<input type="submit" value="提交">
</form>
<?php
header("Content-Type:text/html;charset=utf-8");
include('../config/conn.php');
$username=$_POST['user'];
$password=md5($_POST['pass']);
$captcha=$_POST['captcha'];
//echo $password;
$sql="select * from sy_adminuser where username='$username' and password='$password'";
echo $sql;
$result=mysqli_query($conn,$sql);
while($row=mysqli_fetch_array($result)){ //成功登录后
session_start();
$_SESSION['username'] = $row['username'];//将查询结果的数据进行赋值
//echo $_SESSION['username'];
header('Location: index.php');
}
index.php
<?php
header("Content-Type:text/html;charset=utf-8");
session_start();
$username=$_SESSION['username'];
if($username=='admin'){
echo '欢迎登陆管理员首页!';
}else{
echo "请登录后访问!";
}
输入输出(XSS)
反射
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>小赵同学的博客</title>
<style type="text/css">
.nav li{
background-color: yellow;
padding: 8px 15px;
float: left;
list-style: none;
color:#fff;
}
</style>
</head>
<body>
<ul class="nav">
<li><a href="index.php">网站首页</a></li>
<li><a href="news.php">文章列表</a></li>
<li><a href="file.php">文件操作</a></li>
<li><a href="gbook.php">留言板</a></li>
<li><a href="tools.php">访问查询</a></li>
</ul>
<br><br><hr>
<form id="form1" action="" method="post">
<label for="search">内容搜索:</label>
<input type="search" name="search" id="search">
<input type="submit" name="submit" id="submit" value="提交">
</form>
<?php
include('config/conn.php');
$s=$_POST['search'];
$sql="select * from sy_guestbook where gName like '%$s%'";
$result=mysqli_query($conn,$sql);
if(! $result){
printf("Error: %s\n", mysqli_error($conn));
exit();
}
echo '你搜索的'."'$s'".'结果如下';
while($row=mysqli_fetch_array($result)){
echo '<br><br><hr>';
echo $row['id'].'<br>';
echo $row['gName'].'<br>';
echo $row['gLogo'].'<br>';
}
?>
<?php
$conn = mysqli_connect('localhost','root','123456');
mysqli_select_db($conn,"syguestbook");
?>
存储
留言:
<form id="form1" name="form1" method="post">
<p>
<label for="textfield">ID:</label>
<input type="text" name="id" id="textfield">
</p>
<p>
<label for="textfield2">昵称:</label>
<input type="text" name="name" id="textfield2">
</p>
<p>
<label for="textfield3">QQ:</label>
<input type="text" name="qq" id="textfield3">
</p>
<p>
<label for="textarea">内容:</label>
<textarea name="message" id="message"></textarea>
</p>
<p>
<input type="submit" name="submit" id="submit" value="提交">
</p>
</form>
<p>
<hr>
<p>留言内容:</p>
<hr>
<p> </p>
<?php
//留言内容存储在数据库里
//留言板需要加载之前的留言内容
//可以提交留言
//提交留言之后需要
//留言存储在数据库里面
//可以加载之前的留言内容
//可以提交新的留言
//提交留言后会加载出来
header('Content-Type:text/html;charset=utf-8');
include('config/conn.php');
$i=$_POST['id'];
$n=$_POST['name'];
$q=$_POST['qq'];
$m=$_POST['message'];
//INSERT INTO `sy_message` VALUES (3, '上拉如', '250250', '我要买手机', 192168250);
$sql="INSERT INTO `sy_message` VALUES ('$i','$n', '$q', '$m', 172168250);";
mysqli_query($conn,$sql);
$sql1="select * from sy_message";
$result=mysqli_query($conn,$sql1);
while($row=mysqli_fetch_array($result)) {
echo '<br><br><hr>';
echo 'ID:' . $row['id'] . '<br>';
echo '昵称' . $row['name'] . '<br>';
echo 'qq' . $row['qq'] . '<br>';
echo '内容' . $row['message'] . '<br>';
echo 'ip' . $row['ip'] . '<br>';
}
?>
$_SERVER['HTTP_ACCEPT_LANGUAGE']//浏览器语言
$_SERVER['REMOTE_ADDR'] //当前用户 IP 。
$_SERVER['REMOTE_HOST'] //当前用户主机名
$_SERVER['REQUEST_URI'] //URL
$_SERVER['REMOTE_PORT'] //端口。
$_SERVER['SERVER_NAME'] //服务器主机的名称。
$_SERVER['PHP_SELF']//正在执行脚本的文件名
$_SERVER['argv'] //传递给该脚本的参数。
$_SERVER['argc'] //传递给程序的命令行参数的个数。
$_SERVER['GATEWAY_INTERFACE']//CGI 规范的版本。
$_SERVER['SERVER_SOFTWARE'] //服务器标识的字串
$_SERVER['SERVER_PROTOCOL'] //请求页面时通信协议的名称和版本
$_SERVER['REQUEST_METHOD']//访问页面时的请求方法
$_SERVER['QUERY_STRING'] //查询(query)的字符串。
$_SERVER['DOCUMENT_ROOT'] //当前运行脚本所在的文档根目录
$_SERVER['HTTP_ACCEPT'] //当前请求的 Accept: 头部的内容。
$_SERVER['HTTP_ACCEPT_CHARSET'] //当前请求的 Accept-Charset: 头部的内容。
$_SERVER['HTTP_ACCEPT_ENCODING'] //当前请求的 Accept-Encoding: 头部的内容
$_SERVER['HTTP_CONNECTION'] //当前请求的 Connection: 头部的内容。例如:“Keep-Alive”。
$_SERVER['HTTP_HOST'] //当前请求的 Host: 头部的内容。
$_SERVER['HTTP_REFERER'] //链接到当前页面的前一页面的 URL 地址。
$_SERVER['HTTP_USER_AGENT'] //当前请求的 User_Agent: 头部的内容。
$_SERVER['HTTPS']//如果通过https访问,则被设为一个非空的值(on),否则返回off
$_SERVER['SCRIPT_FILENAME'] #当前执行脚本的绝对路径名。
$_SERVER['SERVER_ADMIN'] #管理员信息
$_SERVER['SERVER_PORT'] #服务器所使用的端口
$_SERVER['SERVER_SIGNATURE'] #包含服务器版本和虚拟主机名的字符串。
$_SERVER['PATH_TRANSLATED'] #当前脚本所在文件系统(不是文档根目录)的基本路径。
$_SERVER['SCRIPT_NAME'] #包含当前脚本的路径。这在页面需要指向自己时非常有用。
$_SERVER['PHP_AUTH_USER'] #当 PHP 运行在 Apache 模块方式下,并且正在使用 HTTP 认证功能,这个变量便是用户输入的用户名。
$_SERVER['PHP_AUTH_PW'] #当 PHP 运行在 Apache 模块方式下,并且正在使用 HTTP 认证功能,这个变量便是用户输入的密码。
$=_SERVER['AUTH_TYPE'] #当 PHP 运行在 Apache 模块方式下,并且正在使用 HTTP 认证功能,这个变量便是认证的类型
JS&Ajax
upload.php
前端代码
<form class="upload" method="post" enctype="multipart/form-data" action="">
<input class="uploadfile" type="file" name="upload" onchange="checkFileExt(this.value)"/><br />
<input class="sub" type="submit" name="submit" value="开始上传" />
</form>
引入js:js相当于封装的代码,类似于c语言的头文件,java中的类
<script src="js/jquery-1.12.4.min.js"></script>
js验证代码
<script>
function checkFileExt(filename)
{
var flag = false; //状态
var arr = ["jpg","png","gif"];
//取出上传文件的扩展名
var index = filename.lastIndexOf(".");
var ext = filename.substr(index+1);
//比较
for(var i=0;i<arr.length;i++)
{
if(ext == arr[i])
{
flag = true; //一旦找到合适的,立即退出循环
alert("上传的文件符合要求!");
break;
}
}
//条件判断
if(!flag)
{
alert("上传的文件不符合要求,请重新选择!");
location.reload(true);
}
}
</script>
前端验证
- 对文件上传的后缀进行验证,符合要求才能上传
- 这个功能可以使用PHP(黑盒测试)和JS(白盒)绕过
php代码
<?php
header("Content-Type:text/html;charset=utf-8");
/**
* Created by PhpStorm.
* User: xiaodi
* Date: 2022/1/1
* Time: 12:50
*/
@$file_name=$_FILES['upload']['name'];
//获取上传文件类型
@$file_type=$_FILES['upload']['type'];
//获取上传文件大小
@$file_size=$_FILES['upload']['size'];
//获取上传文件临时文件名
@$file_tmpname=$_FILES['upload']['tmp_name'];
//获取上传文件是否错误
@$file_error=$_FILES['upload']['error'];
echo $file_name."<hr>";
echo $file_type."<hr>";
echo $file_size."<hr>";
echo $file_tmpname."<hr>";
echo $file_error."<hr>";
if (@$file_error>0){
echo '上传出错!';
}
else{
move_uploaded_file(@$_FILES["upload"]["tmp_name"], "../upload/" . @$_FILES["upload"]["name"]);
echo "文件存储在: " . "upload/" . @$_FILES["upload"]["name"];
}
如何判断代码采用js验证,可以直接右键查看源代码
状态回显-登录-状态码
设计:通过Ajax传递数据进行用户登录验证
Ajax是一种前端js语言,传递数据的一种方式,实现数据交互
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ajax登录</title>
</head>
<body>
帐号:<input type="text" class="user">
密码:<input type="password" class="pass">
<button>用户登录</button>
<script src="../js/jquery-1.12.4.min.js"></script>
<script>
$('button').click(function () {
$.ajax({
type:'post',
url:'ajax.php', //发给ajax.php文件。
dataType:'json',
data:{
myUname:$('.user').val(),
myUpass:$('.pass').val()
},
success:function (res) {
console.log(res);
if(res.infoCode==1){
alert('登录成功');
}else{
alert('登录失败');
}
}
});
});
</script>
</body>
</html>
Ajax.php
<?php
/**
* Created by PhpStorm.
* User: xiaodi
* Date: 2022/1/1
* Time: 12:17
*/
$username=$_POST['myUname'];
$password=$_POST['myUpass'];
$success=array('msg'=>'ok');
if($username=='xiaodi' && $password=='123456'){
$success['infoCode'] = 1;
}else{
$success['infoCode'] = 0;
}
echo json_encode($success);
TP框架
1、框架版本漏洞
2、框架写法安全
3、黑盒白盒看版本
https://github.com/Mochazz/ThinkPHP-Vuln
版本:
黑盒:先判断是不是tp,一般是借助报错,或者返回数据包,URL地址等等。