还有一篇忘记复制上去了。。。

encrypt CTF

Creckme01

输入之后直接对比,有些是不可见字符,用pwntools发送或者直接把flag拔下来。。。

from pwn import *
context.log_level = 'debug'
p = process('./crackme01')
p.sendline('1D\x01A  !!e\x19\t')
print(p.recv())

Creckme02

输入username和password后,进行一波加密得到一个int,然后用这个int异或一个byte常量的每一位。知道flag第一个字符是‘e’,求出要异或的数值即可

a =[0x08, 0x03, 0x0E, 0x1F, 0x14, 0x1D, 0x19, 0x2E, 0x39, 0x2B, 
  0x16, 0x2C, 0x01, 0x0A, 0x02, 0x1F, 0x04, 0x19, 0x05, 0x00, 
  0x1E, 0x40, 0x03, 0x02, 0x19, 0x40, 0x08, 0x0C, 0x1E, 0x14, 
  0x10]
b = ord('e')^a[0]
s = ''
for i in range(31):
    s+=chr(a[i]^b)
print(s)

crackme03

分五次对五个不同的输入check,前四次都正常,都是与常量比较。到第五次的时候出了点小问题。第五个check是这样的:

void __cdecl sub_565CD410(const char *a1)
{
  char dest[9]; // [esp+12h] [ebp-16h]
  unsigned int v2; // [esp+1Ch] [ebp-Ch]

  v2 = __readgsdword(0x14u);
  strncpy(dest, a1, 10u);
  puts("Validating Input 4");
  if ( dest[0] + dest[8] != 0xD5 )
    sub_565CD258();
  if ( dest[1] + dest[7] != 0xCE )
    sub_565CD258();
  if ( dest[2] + dest[6] != 0xE7 )
    sub_565CD258();
  if ( dest[3] + dest[5] != 0xC9 )
    sub_565CD258();
  if ( dest[4] == 0x69 )
    puts("you earned it");
  if ( __readgsdword(0x14u) != v2 )
    sub_565CD670();
}

然而我另前4位位0后四位是对应的数据后,迟迟不能通过。最后动调一下才发现问题所在

.text:565CD459                 movzx   eax, [ebp+dest]
.text:565CD45D                 movsx   edx, al
.text:565CD460                 movzx   eax, [ebp+dest+8]
.text:565CD464                 movsx   eax, al
.text:565CD467                 add     eax, edx
.text:565CD469                 cmp     eax, 0D5h

这里用了movsz有符号扩展,导致0xD5被扩展成了0xFFFFFFD5,再与0xD5比较时就出了问题,其实就是有符号数和无符号数之间的区别。其实如果光看C代码并细心一点也能看出来,这里的dest是有符号类型,如果改成无符号类型会看到比对的时候ida把他强制转换成了有符号类型,这样0xD5的大小就不一样了。

unsigned __int8 dest[9]; // [esp+12h] [ebp-16h]
  unsigned int v2; // [esp+1Ch] [ebp-Ch]

  v2 = __readgsdword(0x14u);
  strncpy((char *)dest, (const char *)a1, 10u);
  puts("Validating Input 4");
  if ( (char)dest[0] + (char)dest[8] != 0xD5 )
    sub_565CD258();

脚本:

from pwn import *
context.log_level = 'error'
payload = ["CRACKME02","\xef\xbe\xad\xde","ZXytUb9fl78evgJy3KJN","1","\x75\x7e\x77\x79\x69\x50\x70\x50\x60"]
p = process('./crackme03')
p = remote("104.154.106.182","7777")
for i in range(5):
    print(p.recv())
    p.sendline(payload[i])
print(p.recvall())

dontlook at this Challenge

开始有个ptrace,和signal(5,func),把他们patch掉。

看题目描述以为挺难的,然而在最后比对字符串的地方设个断点运行后,直接看到了flag。。。

直接分析加密算法也不难,前面一大堆操作只是为了生成一个字符串"dontlook",密文是"hbpkjdhMWT{qhyhz00u__1wg_zr_dsqbhh}",所谓的加密只是单纯的把明文减去key

解密脚本:

cipher = "hbpkjdhMWT{qhyhz00u__1wg_zr_dsqbhh}"
key = "dontlook"
plain = ""
t = 0
for i in range(len(cipher)):
    if ord(cipher[i])>=97 and ord(cipher[i])<=ord('z'):
        plain+=chr(((ord(cipher[i]) - 97) - (ord(key[t%8]) - 97) + 26)%26 + 97)
    elif ord(cipher[i])>=65 and ord(cipher[i])<=ord('Z'):
        plain+=chr(((ord(cipher[i]) - 65) - (ord(key[t%8]) - 97) + 26)%26 + 65)
    else:
        plain += cipher[i]
        continue
    t+=1
print(plain)