[TOC]
[Round 1]xor
Flag:YLCTF{1084b64f-9079-49d4-8814-114e958e2e7a}
die查壳发现upx壳
就是异或0x1c
再连靶机拿到密文"EP_HZg-,$(~*(z1%,+%1(%x(1$$-(1--(y%)$y.y+}a"
enc = b"EP_HZg-,$(~*(z1%,+%1(%x(1$$-(1--(y%)$y.y+}a"
flag = ""
for i in range(len(enc)):
flag += chr(enc[i] ^ 0x1c)
print(flag)
# YLCTF{1084b64f-9079-49d4-8814-114e958e2e7a}
[Round 1] xorplus
Flag:YLCTF{540aff55-60c2-4a52-8d36-7d7c960bbe08}
魔改的rc4
连靶机拿到密文0x91,0x86,0x1b,0x2d,0x9e,0x6f,0x58,0x33,0x7a,0xa3,0xef,0xf1,0xd1,0x8d,0x22,0x1a,0x43,0x9d,0x5c,0x2d,0x80,0x56,0x79,0x17,0x6c,0x4f,0x7e,0x49,0x4c,0x26,0xb4,0xea,0x39,0x4b,0x29,0xd2,0xb4,0x4e,0x29,0xc6,0x5,0x3c,0xa6
改了1300和-20两个位置
enc=[0x91,0x86,0x1b,0x2d,0x9e,0x6f,0x58,0x33,0x7a,0xa3,0xef,0xf1,0xd1,0x8d,0x22,0x1a,0x43,0x9d,0x5c,0x2d,0x80,0x56,0x79,0x17,0x6c,0x4f,0x7e,0x49,0x4c,0x26,0xb4,0xea,0x39,0x4b,0x29,0xd2,0xb4,0x4e,0x29,0xc6,0x5,0x3c,0xa6]
a=[0]*256
key="welcometoylctf"
for i in range(256):
a[i]=i
v6 = 0
for j in range(256):
v6=(ord(key[j%len(key)])+v6+a[j] + 1300)%256
v3 = a[j]
a[j] = a[v6]
a[v6] = v3
v7 = 0
v8 = 0
for k in range(len(enc)):
v8 = (v8 + 1) % 256
v7 = (v7 + a[v8]) % 256
temp = a[v8]
a[v8] = a[v7]
a[v7] = temp
enc[k] = (enc[k] - 20) & 0xff
enc[k] ^= a[(a[v7] + a[v8]) % 256]
print(bytes(enc))
# YLCTF{540aff55-60c2-4a52-8d36-7d7c960bbe08}
[Round 1] ezgo
Flag: YLCTF{a450983c-c922-44b6-8aaa-618a85a23ca5}
go写的简单异或
enc = [108,122,116,108,127,65,90,8,8,14,6,120,114,33,110,39,124,116,117,101,125,126,41,122,96,118,46,49,48,127,101,101,109,55,111,109,56,104,104,63,60,107,34]
flag = ""
for i in range(len(enc)):
flag += chr(enc[i] ^ (i + 53))
print(flag)
# YLCTF{a450983c-c922-44b6-8aaa-618a85a23ca5}
[Round 1] calc
Flag: YLCTF{cc04154e-6344-49b2-82e7-10522db358d9}
define UUID_3303b105d2f04754b3a30ae7deccda49(XYD) XYD 这个就是其本身所以
UUID_3303b105d2f04754b3a30ae7deccda49(UUID_74f0162eda254a94a7678169c0f0e982)可以化简成UUID_74f0162eda254a94a7678169c0f0e982再变成UUID_959d51d4bd07424991a221e483964434 UUID_bcd09a4ecaab4dbea290d4cf040fb75f UUID_35388744414b4f2bb3737d8415e6d0bb
此时vscode就可以看到代码
得到
typedef struct Stack{double* top; double* low; int size; }stack;void init(stack *s ){s-> low=( double*)malloc ((sizeof (double)) ) s->top=s ->low;s-> size=100; }void push(stack* s,double e ){ *(s-> top)=e; s->top ++;}void pop(stack*s ,double*e ){ *e=* --(s->top );}int main(){ setbuf( (__acrt_iob_func(0)),0); setbuf((__acrt_iob_func(1)),0 );stack s; char ch;double d,e char num[ 100];int i= 0;init (&s );puts("input data , end of '#'" );scanf("%s", &ch );while(ch !='#'){while (ch >='0'&&ch<= '9'){num[ i]=ch ;scanf("%c", &ch );if(ch ==' ' ){d =atof(num) ;push( &s ,d); i=0;break }}switch (ch) {case'+':pop(& s\ufffd\ufffd&d) ;pop( &s,& e);push( &s,e +d); break;case'-' :pop( &s, &d) ;pop (&s,& e);push (& s,e-d );break ;case'*':pop (& s,&d) ;pop(&s ,&e );push( &s,e* d); break;case'/':pop (&s,& d);pop( &s,&e );push(& s,e /d) break; }scanf("%c", &ch) ;}pop( &s, &d); if(d== 125){printf ("%s",getenv ("GZCTF_FLAG")); }}
拿去格式化一下
再自己改一改
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
typedef struct Stack {
double* top;
double* low;
int size;
}
stack;
void init(stack *s ) {
s-> low=( double*)malloc ((sizeof (double)) ); s->top=s ->low;
s-> size=100;
}
void push(stack* s,double e ) {
*(s-> top)=e;
s->top ++;
}
void pop(stack*s ,double*e ) {
*e=* --(s->top );
}
int main() {
setbuf( (__acrt_iob_func(0)),0);
setbuf((__acrt_iob_func(1)),0 );
stack s;
char ch;
double d,e;
char num[ 100];
int i= 0;
init (&s );
puts("input data , end of '#'" );
scanf("%s", &ch );
while(ch !='#') {
while (ch >='0'&&ch<= '9') {
num[ i]=ch ;
scanf("%c", &ch );
if(ch ==' ' ) {
d =atof(num) ;
push( &s ,d);
i=0;
break;
}
}
switch (ch) {
case'+':pop(&s, &d) ;
pop( &s,& e);
push( &s,e +d);
break;
case'-' :pop( &s, &d) ;
pop (&s,& e);
push (& s,e-d );
break ;
case'*':pop (& s,&d) ;
pop(&s ,&e );
push( &s,e* d);
break;
case'/':pop (&s,& d);
pop( &s,&e );
push(& s,e /d);
break;
}
scanf("%c", &ch) ;
}
pop( &s, &d);
if(d== 125) {
printf ("%s",getenv ("GZCTF_FLAG"));
}
}
这时可以调试就很好做了,就是个计算后缀表达式的
但是由于num[ 100]未初始化导致d =atof(num) 的结果不确定,所以远程要多试几次
[Round 1] math
Flag: YLCTF{7f54eb30-3b78-4f99-88df-95cfd3644688}
要求每行每列加起来等于45,就是数独
把给的表拿出来,再找个填数独脚本
import numpy as np
import time
def col_hang(mat,i,el):
'''
判断一行是否重复
'''
if el in mat[i,:]:
return False
return True
def col_lie(mat,j,el):
'''
判断一列是否重复
'''
if el in mat[:,j]:
return False
return True
def col_fang(mat,i,j,el):
'''
判断一个3×3的矩阵是否重复
'''
i_start=i-i%3
j_start=j-j%3
fang=[]
for m in range(i_start,i_start+3):
for n in range(j_start,j_start+3):
fang.append(mat[m,n])
if el in fang:
return False
return True
def init():
'''
初始化数据
建立第一个副本
'''
mat=np.array([[1, 0, 0, 2, 0, 0, 3, 0, 0],
[0, 4, 0, 0, 5, 0, 0, 6, 0],
[0, 0, 7, 0, 0, 8, 0, 0, 9],
[0, 1, 0, 0, 2, 0, 0, 3, 0],
[0, 0, 4, 0, 0, 5, 0, 0, 6],
[7, 0, 0, 8, 0, 0, 9, 0, 0],
[0, 0, 1, 0, 0, 2, 0, 0, 3],
[4, 0, 0, 5, 0, 0, 6, 0, 0],
[0, 7, 0, 0, 8, 0, 0, 9, 0]])
copy={}
copy[0]=mat.copy()
return mat,copy
def pos_zero(mat):
'''
计算当前数独空缺位置坐标
'''
li=[]
for i in range(9):
for j in range(9):
if mat[i,j]==0:
li.append((i,j))
return li
def pos_value(li,mat):
'''
计算每个空缺位置的可填的数据
储存为一个列表
'''
el={}
for pos in li:
i,j=pos
el[pos]=[]
for num in range(1,10):
if col_hang(mat,i,num) & col_lie(mat,j,num) & col_fang(mat,i,j,num):
el[pos].append(num)
else:
pass
return el
def sort_value(el):
'''
对空缺位置的数据长度进行排序
返回长度最小的位置和数据列表
'''
li_value=[]
pos_value=[]
for pos in el:
li_value.append(len(el[pos]))
pos_value.append(pos)
index=li_value.index(min(li_value))
return pos_value[index],el[pos_value[index]]
def main():
mat,copy=init()
back_value={} #储存每个空缺位置填过的数据
max_index=pos_zero(mat)
for pos in max_index:
back_value[pos]=[]
index=0 #结束的索引,当其等于空缺位置的个数时结束
n=0 #循环次数
while index < len(max_index):
m=copy[index].copy()
li=pos_zero(m)
el=pos_value(li,m)
pos,value=sort_value(el)
value=list(set(value)-set(back_value[pos]))
if len(value)>0: #可填数据非空时,继续下一个坐标填值
m[pos]=value[0]
print(pos,'set:',value[0])
back_value[pos].append(value[0])
index+=1
n+=1
copy[index]=m
elif len(value)==0: #可填数据为空时,回溯到上一个坐标
del copy[index]
print('return')
back_value[pos]=[]
index-=1
n+=1
else: #当index<0时,该数独不正确
print(mat,'is not right!')
print(copy[index],n)
if __name__=="__main__":
begin=time.time()
main()
end=time.time()
print(end-begin)
得到[[1 8 9 2 4 6 3 5 7]
[2 4 3 9 5 7 8 6 1]
[5 6 7 1 3 8 2 4 9]
[9 1 8 6 2 4 7 3 5]
[3 2 4 7 9 5 1 8 6]
[7 5 6 8 1 3 9 2 4]
[8 9 1 4 6 2 5 7 3]
[4 3 2 5 7 9 6 1 8]
[6 7 5 3 8 1 4 9 2]]
再输入进去就行了
from pwn import *
p = remote('challenge.yuanloo.com',32955)
# p = process('./math')
context(arch='amd64', os='linux', log_level='debug')
inp = [8,9,4,6,5,7,2,3,9,7,8,1,5,6,1,3,2,4,9,8,6,4,7,5,3,2,7,9,1,8,5,6,1,3,2,4,8,9,4,6,5,7,3,2,7,9,1,8,6,5,3,1,4,2]
print(len(inp))
p.recv()
for i in range(54):
p.sendline(str(inp[i]))
p.recv()
p.interactive()
[Round 1] ezvvvvm
Flag: YLCTF{d417ab12-f9ce-4611-b069-b5af4a84c93d}
程序也跑不了,纯靠猜
先是连远程,给了一堆数据.观察发现这些数据有的很大有的很小,再根据程序内发现了imul等操作,可以猜出是经过了乘法的.
这里给了一串key,后面又对这串key进行了异或0x2C操作.
发现给出的数据除以异或后的key全都为整数,得到[320.0, 290.0, 279.0, 286.0, 95.0, 178.0, 317.0, 138.0, 245.0, 138.0, 142.0, 119.0, 103.0, 208.0, 289.0, 140.0, 248.0, 292.0, 247.0, 55.0, 176.0, 75.0, 209.0, 241.0, 106.0, 209.0, 116.0, 158.0, 240.0, 120.0, 187.0, 250.0, 115.0, 205.0, 175.0, 254.0, 285.0, 232.0, 157.0, 71.0, 230.0, 109.0, 223.0]
这里我们可以根据之前题目的flag格式YLCTF{xxxx},最后一位223比}的ASCII码多了98,据此可以知道加密过程是先加上key再乘以key异或0x2c的结果.