0%

BJDCTF2020 部分WriteUp

复现平台:https://buuoj.cn/challenges

Crypto

这是base??

base编码原理的实现,百度了一下,找到个脚本,改一下table即可

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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

const char* base64_table = "JKLMNOxyUVzABCDEFGH789PQIabcdefghijklmWXYZ0123456RSTnopqrstuvw+/="; /* base64编码表 */

static int num_strchr(const char* str, char c)
{
const char* p = strchr(str, c);

if (NULL == p)
{
return -1;
}

return p - str;
}

uint32_t base64_get_dest_len(uint32_t src_len)
{
return 4 * ((src_len + 2) / 3);
}

uint32_t src_get_dest_len(uint32_t base64_len)
{
return base64_len / 4 * 3 - 2;
}

int base64_encode(const char* src_str, uint32_t src_len, char* dest_str, uint32_t dest_len)
{
uint32_t i, j, len;

len = base64_get_dest_len(src_len);

if (dest_len < len)
{/* 空间不足 */
return -1;
}

for (i = 0; i < src_len / 3; i++)
{
*dest_str++ = base64_table[(src_str[0] >> 2) & 0x3f]; /* 取第一字符前6bit */
*dest_str++ = base64_table[((src_str[0] << 4) & 0x30) | ((src_str[1] >> 4) & 0x0f)]; /* 第一字符的后2bit与第二字符的前4位进行合并 */
*dest_str++ = base64_table[((src_str[1] << 2) & 0x3c) | ((src_str[2] >> 6) & 0x03)]; /* 将第二字符的后4bit与第三字符的前2bit组合并 */
*dest_str++ = base64_table[src_str[2] & 0x3f]; /* 取第三字符的后6bit */
src_str += 3;
}

/* 非3的整数倍补“=” */
if ((src_len % 3) == 1)
{
*dest_str++ = base64_table[(src_str[0] >> 2) & 0x3f];
*dest_str++ = base64_table[((src_str[0] << 4) & 0x30) | ((src_str[1] >> 4) & 0x0f)];
*dest_str++ = '=';
*dest_str++ = '=';
}
else if ((src_len % 3) == 2)
{
*dest_str++ = base64_table[(src_str[0] >> 2) & 0x3f];
*dest_str++ = base64_table[((src_str[0] << 4) & 0x30) | ((src_str[1] >> 4) & 0x0f)];
*dest_str++ = base64_table[(src_str[j + 1] << 2) & 0x3c];
*dest_str++ = '=';
}
*dest_str = '\0';

return 0;
}

int base64_decode(const char* src_str, uint32_t src_len, char* dest_str, uint32_t dest_len)
{
uint32_t i = 0;
char buf[4] = { 0 };

if (dest_len < src_get_dest_len(src_len))
{
return -1;
}

for (; (src_str[i] != '\0') && (i < src_len); i += 4)
{
/* 四个码译成三个字符 */
buf[0] = num_strchr(base64_table, src_str[i]);
buf[1] = num_strchr(base64_table, src_str[i + 1]);

*dest_str++ = ((buf[0] << 2) & 0xfc) | ((buf[1] >> 4) & 0x03);

if (src_str[i + 2] == '=')
{
break;
}
buf[2] = num_strchr(base64_table, src_str[i + 2]);

*dest_str++ = ((buf[1] << 4) & 0xf0) | ((buf[2] >> 2) & 0x0f);

if (src_str[i + 3] == '=')
{
break;
}
buf[3] = num_strchr(base64_table, src_str[i + 3]);

*dest_str++ = ((buf[2] << 6) & 0xc0) | (buf[3] & 0x3f);
}

*dest_str = '\0';

return 0;
}

int main(int argc, char** argv)
{
char* buf = NULL;
uint32_t dest_len, src_len;

if (argc < 3)
return -1;

if (strcmp(argv[1], "decode") == 0)
{
src_len = strlen(argv[2]);
dest_len = src_get_dest_len(src_len);
buf = (char*)malloc(dest_len);
if (buf == NULL)
return -1;
base64_decode(argv[2], src_len, buf, dest_len);
printf("base64 str:%s\n", argv[2]);
printf("base64_decode str:%s\n", buf);
}
else if (strcmp(argv[1], "encode") == 0)
{
src_len = strlen(argv[2]);
dest_len = base64_get_dest_len(src_len);
buf = (char*)malloc(dest_len);
if (buf == NULL)
return -1;
base64_encode(argv[2], src_len, buf, dest_len);
printf("src str:%s\n", argv[2]);
printf("base64_encode str:%s\n", buf);
}

free(buf);
buf = NULL;
return 0;
}
1
2
3
4
root@Kali:~# gcc 0.c
root@Kali:~# ./a.out decode FlZNfnF6Qol6e9w17WwQQoGYBQCgIkGTa9w3IQKw
base64 str:FlZNfnF6Qol6e9w17WwQQoGYBQCgIkGTa9w3IQKw
base64_decode str:BJD{D0_Y0u_kNoW_Th1s_b4se_map}

signin

hex编码

BJD{We1c0me_t4_BJDCTF}

rsa_output

RSA共模攻击

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import gmpy2
import libnum

n= 21058339337354287847534107544613605305015441090508924094198816691219103399526800112802416383088995253908857460266726925615826895303377801614829364034624475195859997943146305588315939130777450485196290766249612340054354622516207681542973756257677388091926549655162490873849955783768663029138647079874278240867932127196686258800146911620730706734103611833179733264096475286491988063990431085380499075005629807702406676707841324660971173253100956362528346684752959937473852630145893796056675793646430793578265418255919376323796044588559726703858429311784705245069845938316802681575653653770883615525735690306674635167111
e1= 2767
e2= 3659
c1= 20152490165522401747723193966902181151098731763998057421967155300933719378216342043730801302534978403741086887969040721959533190058342762057359432663717825826365444996915469039056428416166173920958243044831404924113442512617599426876141184212121677500371236937127571802891321706587610393639446868836987170301813018218408886968263882123084155607494076330256934285171370758586535415136162861138898728910585138378884530819857478609791126971308624318454905992919405355751492789110009313138417265126117273710813843923143381276204802515910527468883224274829962479636527422350190210717694762908096944600267033351813929448599
c2= 11298697323140988812057735324285908480504721454145796535014418738959035245600679947297874517818928181509081545027056523790022598233918011261011973196386395689371526774785582326121959186195586069851592467637819366624044133661016373360885158956955263645614345881350494012328275215821306955212788282617812686548883151066866149060363482958708364726982908798340182288702101023393839781427386537230459436512613047311585875068008210818996941460156589314135010438362447522428206884944952639826677247819066812706835773107059567082822312300721049827013660418610265189288840247186598145741724084351633508492707755206886202876227
gcd, s, t = gmpy2.gcdext(e1, e2)
if s < 0:
s = -s
c1 = gmpy2.invert(c1, n)
if t < 0:
t = -t
c2 = gmpy2.invert(c2, n)

m = gmpy2.powmod(c1,s,n) * gmpy2.powmod(c2,t,n) % n
print libnum.n2s(m)

RSA

n1和n2共用一个q,可以先求最大公约数求出q,然后求出p,然后通过m(或者pow(294,e,n))可以求出e,就把RSA的所有参数求出来了

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
import libnum
import gmpy2

c1 = 12641635617803746150332232646354596292707861480200207537199141183624438303757120570096741248020236666965755798009656547738616399025300123043766255518596149348930444599820675230046423373053051631932557230849083426859490183732303751744004874183062594856870318614289991675980063548316499486908923209627563871554875612702079100567018698992935818206109087568166097392314105717555482926141030505639571708876213167112187962584484065321545727594135175369233925922507794999607323536976824183162923385005669930403448853465141405846835919842908469787547341752365471892495204307644586161393228776042015534147913888338316244169120
n1 = 13508774104460209743306714034546704137247627344981133461801953479736017021401725818808462898375994767375627749494839671944543822403059978073813122441407612530658168942987820256786583006947001711749230193542370570950705530167921702835627122401475251039000775017381633900222474727396823708695063136246115652622259769634591309421761269548260984426148824641285010730983215377509255011298737827621611158032976420011662547854515610597955628898073569684158225678333474543920326532893446849808112837476684390030976472053905069855522297850688026960701186543428139843783907624317274796926248829543413464754127208843070331063037
c3 = 381631268825806469518166370387352035475775677163615730759454343913563615970881967332407709901235637718936184198930226303761876517101208677107311006065728014220477966000620964056616058676999878976943319063836649085085377577273214792371548775204594097887078898598463892440141577974544939268247818937936607013100808169758675042264568547764031628431414727922168580998494695800403043312406643527637667466318473669542326169218665366423043579003388486634167642663495896607282155808331902351188500197960905672207046579647052764579411814305689137519860880916467272056778641442758940135016400808740387144508156358067955215018
c2 = 979153370552535153498477459720877329811204688208387543826122582132404214848454954722487086658061408795223805022202997613522014736983452121073860054851302343517756732701026667062765906277626879215457936330799698812755973057557620930172778859116538571207100424990838508255127616637334499680058645411786925302368790414768248611809358160197554369255458675450109457987698749584630551177577492043403656419968285163536823819817573531356497236154342689914525321673807925458651854768512396355389740863270148775362744448115581639629326362342160548500035000156097215446881251055505465713854173913142040976382500435185442521721
n2 = 12806210903061368369054309575159360374022344774547459345216907128193957592938071815865954073287532545947370671838372144806539753829484356064919357285623305209600680570975224639214396805124350862772159272362778768036844634760917612708721787320159318432456050806227784435091161119982613987303255995543165395426658059462110056431392517548717447898084915167661172362984251201688639469652283452307712821398857016487590794996544468826705600332208535201443322267298747117528882985955375246424812616478327182399461709978893464093245135530135430007842223389360212803439850867615121148050034887767584693608776323252233254261047

#q = gmpy2.gcd(n1, n2)
#print q
#p1 = n1 / q
#p2 = n2 / q
#print p1
#print p2

q = 99855353761764939308265951492116976798674681282941462516956577712943717850048051273358745095906207085170915794187749954588685850452162165059831749303473106541930948723000882713453679904525655327168665295207423257922666721077747911860159181041422993030618385436504858943615630219459262419715816361781062898911
p1 = 135283423427545651023916134156519717109709399113553907832988770259402226695880524199087896377303631866790192008529658716376684328032075836094156150811025163336681163420875451747389868549203081743561907379260240665153166927504059379076555558704275659133135906827306189040804323574468819553401905127999523676067
p2 = 128247614380441198621646495410948309946997239795951661931273072927374035259759992149357909896141726187046548986417994702167046344214464500647935997258628531837792334712721963467008407166687868929005971168361860024531036817205076054969304421022680304986295959208344157424943500032828301016675631415023886775977

#for e in range(0,100000):
# if pow(294, e, n1) == c3:
# print e
# break

e = 52361
phi = (p1 - 1)*(q - 1)
d = gmpy2.invert(e, phi)
m = pow(c1, d, n1)
print libnum.n2s(m)

flag: BJD{p_is_common_divisor}

easyrsa

实际上z=p^2+q^2

1
2
3
4
5
6
7
8
9
10
11
12
13
import libnum
import gmpy2

e = 65537
c = 7922547866857761459807491502654216283012776177789511549350672958101810281348402284098310147796549430689253803510994877420135537268549410652654479620858691324110367182025648788407041599943091386227543182157746202947099572389676084392706406084307657000104665696654409155006313203957292885743791715198781974205578654792123191584957665293208390453748369182333152809882312453359706147808198922916762773721726681588977103877454119043744889164529383188077499194932909643918696646876907327364751380953182517883134591810800848971719184808713694342985458103006676013451912221080252735948993692674899399826084848622145815461035
z = 32115748677623209667471622872185275070257924766015020072805267359839059393284316595882933372289732127274076434587519333300142473010344694803885168557548801202495933226215437763329280242113556524498457559562872900811602056944423967403777623306961880757613246328729616643032628964072931272085866928045973799374711846825157781056965164178505232524245809179235607571567174228822561697888645968559343608375331988097157145264357626738141646556353500994924115875748198318036296898604097000938272195903056733565880150540275369239637793975923329598716003350308259321436752579291000355560431542229699759955141152914708362494482
n = 15310745161336895413406690009324766200789179248896951942047235448901612351128459309145825547569298479821101249094161867207686537607047447968708758990950136380924747359052570549594098569970632854351825950729752563502284849263730127586382522703959893392329333760927637353052250274195821469023401443841395096410231843592101426591882573405934188675124326997277775238287928403743324297705151732524641213516306585297722190780088180705070359469719869343939106529204798285957516860774384001892777525916167743272419958572055332232056095979448155082465977781482598371994798871917514767508394730447974770329967681767625495394441

p_and_q = gmpy2.iroot(z + 2*n,2)[0]
phi = n - p_and_q + 1
d = gmpy2.invert(e, phi)
m = pow(c, d, n)
print libnum.n2s(m)

flag:BJD{Advanced_mathematics_is_too_hard!!!}

Polybius

棋盘密码,特点:密文长度是明文长度的两倍

密文中只出现了aeiou,解密不对,需要爆破顺序,即5!个,不太会写脚本(菜。。。)

官方wp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import itertools

key = []
cipher = "ouauuuoooeeaaiaeauieuooeeiea"
for i in itertools.permutations('aeiou', 5):
key.append(''.join(i))
for each in key:
temp_cipher = ""
result = ""
for temp in cipher:
temp_cipher += str(each.index(temp))
#这里其实是将字母的表换成数字的表以便后续计算
for i in range(0,len(temp_cipher),2):
current_ascii = int(temp_cipher[i])*5+int(temp_cipher[i+1])+97
#因为棋盘密码是采用两位一起表示一个字母
if current_ascii>ord('i'):
current_ascii+=1
result += chr(current_ascii)
if "flag" in result:
print(each,result)

长度14,猜测flag就是flagispolybius

1
2
uoaei flagispolybius
uoaie flagkxoplubkyx

BJD{flagispolybius}

编码与调制

曼彻斯特编码,学习了学习了。。。

1
2
3
4
5
6
7
8
9
msg=0x2559659965656a9a65656996696965a6695669a9695a699569666a5a6a6569666a59695a69aa696569666aa6
s=bin(msg)[2:]
r=""
for i in range(len(s)/2):
if s[i*2:i*2+2] == '10':
r += '1'
else:
r += '0'
print(hex(int(r,2))[2:-1].decode('hex'))

flag:BJD{DifManchestercode}

伏羲六十四卦

这套娃也套得太多了吧。。。

参考:https://github.com/BjdsecCA/BJDCTF2020_January

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
import base64
from binascii import a2b_hex
enc='升随临损巽睽颐萃小过讼艮颐小过震蛊屯未济中孚艮困恒晋升损蛊萃蛊未济巽解艮贲未济观豫损蛊晋噬嗑晋旅解大畜困未济随蒙升解睽未济井困未济旅萃未济震蒙未济师涣归妹大有'
mydisc={'坤': '000000', '剥': '000001', '比': '000010', '观': '000011', '豫': '000100', '晋': '000101', '萃': '000110', '否': '000111', '谦': '001000', '艮': '001001', '蹇': '001010', '渐': '001011', '小过': '001100', '旅': '001101', '咸': '001110', '遁': '001111', '师': '010000', '蒙': '010001', '坎': '010010', '涣': '010011', '解': '010100', '未济': '010101', '困': '010110', '讼': '010111', '升': '011000', '蛊': '011001', '井': '011010', '巽': '011011', '恒': '011100', '鼎': '011101', '大过': '011110', '姤': '011111', '复': '100000', '颐': '100001', '屯': '100010', '益': '100011', '震': '100100', '噬嗑': '100101', '随': '100110', '无妄': '100111', '明夷': '101000', '贲': '101001', '既济': '101010', '家人': '101011', '丰': '101100', '离': '101101', '革': '101110', '同人': '101111', '临': '110000', '损': '110001', '节': '110010', '中孚': '110011', '归妹': '110100', '睽': '110101', '兑': '110110', '履': '110111', '泰': '111000', '大畜': '111001', '需': '111010', '小畜': '111011', '大壮': '111100', '大有': '111101', '夬': '111110', '乾': '111111'}
keys=['坤', '剥', '比', '观', '豫', '晋', '萃', '否', '谦', '艮', '蹇', '渐', '小过', '旅', '咸', '遁', '师', '蒙', '坎', '涣', '解', '未济', '困', '讼', '升', '蛊', '井', '巽', '恒', '鼎', '大过', '姤', '复', '颐', '屯', '益', '震', '噬嗑', '随', '无妄', '明夷', '贲', '既济', '家人', '丰', '离', '革', '同人', '临', '损', '节', '中孚', '归妹', '睽', '兑', '履', '泰', '大畜', '需', '小畜', '大壮', '大有', '夬', '乾']

m=enc
for each in keys:
m=m.replace(each,mydisc[each])
print(m)

m1 = 0b011000100110110000110001011011110101100001000110001100010111001001100001001100100100011001100010010101110011001001010110011100000101011000110001011001000110011001010101011011010100001001101001010101000011000100110001011001000101100101000101001101010100111001010110010101100110010001011000010100110101010101011010010110010101001101000110010101100100010001010101010000010011110100111101
print (str(hex(m1)))
print (a2b_hex(str(hex(m1)[2::1])))

m2 = 'bl1oXF1ra2FbW2VpV1dfUmBiT11dYE5NVVdXSUZYSFVDUA=='
print (base64.b64decode(m2))

m3 = 'n]h\\]kka[[eiWW_R`bO]]`NMUWWIFXHUCP'
m4=''
offset=5
for i in range(len(m3)):
m4+=chr(ord(m3[i])+offset+i)
print(m4)

m5 = 'scodfuvmhityhirfuxfuvziiruvigzkyhv'
b=7
for i in (1,9,21,15,3,7,23,19,11,5,17,25):
flag = ''
for k in m5:
flag += chr(i*((ord(k)-ord('a'))-b)%26+ord('a'))
print(i,':',flag)

output:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
011000100110110000110001011011110101100001000110001100010111001001100001001100100100011001100010010101110011001001010110011100000101011000110001011001000110011001010101011011010100001001101001010101000011000100110001011001000101100101000101001101010100111001010110010101100110010001011000010100110101010101011010010110010101001101000110010101100100010001010101010000010011110100111101
0x626c316f58463172613246625732567056316466556d4269543131645945354e5656645853555a595346564455413d3d
b'bl1oXF1ra2FbW2VpV1dfUmBiT11dYE5NVVdXSUZYSFVDUA=='
b'n]h\\]kka[[eiWW_R`bO]]`NMUWWIFXHUCP'
scodfuvmhityhirfuxfuvziiruvigzkyhv
1 : lvhwynofabmrabkynqynosbbknobzsdrao
9 : vhlqinwtajexajminoinwgjjmnwjrgbxaw
21 : xzruknibavstavcknykniovvcnivfoltai
15 : jdbswncxapyvapuwngwnckppuncplktvac
3 : hlvounqpadkzadeunwunqcddenqdxcjzaq
7 : zrxymnujahgpahsmnimnuwhhsnuhtwvpau
23 : tpfmgnklaxqbaxwgnegnkyxxwnkxdyrbak
19 : bjdcongratulationsongettingtheflag
11 : rxzienydalcfalgenuenyqllgnylpqhfay
5 : dbjgqnszafihafyqncqnsmffynsfvmphas
17 : ftpksneharwdarosnmsneurronerjuzdae
25 : pftecnmvazojazqcnkcnmizzqnmzbixjam

flag:BJD{bjdcongratulationsongettingtheflag}

Misc

认真你就输了

解压文档,找一下就找到了flag,charts文件夹下flag:flag{M9eVfi2Pcs#}

你猜我是个啥

打开压缩包文件报错,16进制看一下,是个png,改后缀,是个二维码,扫描说flag不在这。。。

继续16进制看看,文件底部找到flag:flag{i_am_fl@g}

藏藏藏

给了一张jpg图片,binwalk发现压缩包,foremost解压得到一个文档,打开扫码得到flag:flag{you are the best!}

just_a_rar

4位数密码爆破,得到:2016,解压得到图片,16进制源码得到flag:flag{Wadf_123}

一叶障目

因为我使用的是honeyview查看图片,显示失败,多半是改了png图片的高,010打开,将第二行的01 4C改成03 4C保存,再打开就得到flag:flag{66666}

纳尼

gif文件打不开,多半是16进制源码出问题了,打开看到少了gif的文件头,添加上47 49 46 38后保存,打开看到字符串,记录下来Q1RGe3dhbmdfYmFvX3FpYW5nX2lzX3NhZH0=

base64:CTF{wang_bao_qiang_is_sad}

鸡你太美

给了两张gif,一个打不开,直接010,看到,第二张少了文件头,加上之后得到
flag:flag{zhi_yin_you_are_beautiful}