真的是签到
给的是无后缀的 zip 文件,解压发现需要密码,也没有提示,猜测可能是 zip 伪加密 (走错厂了吧)
zip是否加密
首先就是看开头的6 ,7byte,和中间 01 02 后的 5 ,6byte
成功解压缩,继续做
发现是 Aspack 壳,只能手动脱壳了。
就是使用 ESP 定理,就是最后在哪 dump 后面还需要再学学
这个说是在 push 后的 retn 执行后 dump
这是因为前面的壳压缩或加密导致odbg没有及时的去分析,此时我们需要右键分析选择分析代码
然后在这脱壳
ida打开好像还是不对,继续查看
可能还有一个魔改 UPX壳!
不会 upx 夹杂 aspack 吧 0——0,先试试
下面深红区应该还有一个 vmp 没找到,估计也只能手动再脱了
再 ESP 定律脱一下,再 push , jmp 大跳转后 dump
得到源程序
a = [0x6c,0x2f,0x30,0x31,0x32,0x33,0xb6,0xbf,0xa0,0xcf,0x7c,0x71,0x6a,0x6c,0x70,0x64,0x75,0x63][::-1]
print(bytes([i^v for i,v in enumerate(a)]).decode('gb2312'))
#ctfshow{签到?????}
或者
#include <stdio.h>
int main()
{
int res[18] = { 0x6c,0x2f,0x30,0x31,0x32,0x33,0xffffffb6,0xffffffbf,0xffffffa0,0xffffffcf,0x7c,0x71,0x6a,0x6c,0x70,0x64,0x75,0x63 };
for (int i = 17; i >= 0; i--)
{
res[i] = res[i] ^ (17 - i);
printf("%c", res[i]);
}
printf("\n");
return 0;
}
总结:zip伪加密,upx,aspack脱壳,还有就是中文字符打印即注意字符串比较顺序
批量生产的伪劣产品
一个 apk 文件
点击没有回显,仍 jadx 分析一下
太多包了,找不到 MainActivity ,搜索 flag 也没有什么信息
嗯,想不到了
往里面翻翻
感觉有点草率
总结
android题,找不到 MainActivity 可以先去 xml 文件看看,有入口点,是否可调试啊之类的,一些 Android 基础知识还是要去学学
来一个派森
python 打包的 exe 文件,解包得到 py 文件
def b58encode(tmp: str) -> str:
tmp = list(map(ord, tmp))
temp = tmp[0]
base58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
for i in range(len(tmp) - 1):
temp = temp * 256 + tmp[i + 1]
tmp = []
while 1:
tmp.insert(0, temp % 58)
temp = temp // 58
if temp == 0:
break
temp = ""
for i in tmp:
temp += base58[i]
tmp = []
for i in range(len(temp)):
tmp.append(chr(ord(temp[i]) ^ i))
check = [
'A', '5', 'q', 'O', 'g', 'q', 'd', '\x7f', '[', '\x7f', 's',
'{', 'G', 'A', 'x', '`', 'D', '@', 'K', 'c', '-', 'c', ' ',
'G', '+', '+', '|', 'x', '}', 'J', 'h', '\\', 'l']
if tmp == check:
return 1
else:
return 0
flag = input("输入flag:")
if b58encode(flag):
print("you win")
else:
print("try again")
base58 解了一下发现不对
唉,没注意到,前面 base58 后,还有一个异或
先异或回去,再解 base 58
学习
temp = tmp[0]
for i in range(len(tmp) - 1):
temp = temp * 256 + tmp[i + 1]
将 ASCII 码值列表 tmp 转换为一个大整数 temp,这种操作通常用于将字符串转换为一个数值以便进行进一步的数学运算或加密操作
tmp.insert(0, temp % 58)
tmp 是一个列表,将 temp%58 插入 tmp 的开头
是因为 Base58 编码是从右到左进行的,所以每次得到的余数都应该从列表的开头插入,以便最终生成正确的 Base58 编码字符串
好好学习 天天向上
看上去简单,但真不太好逆
应该是要用到爆破吧
v4,v2是关键,但真不知道怎么建立联系
所以每一次累加没有规律,只能爆破
找到一个 pwntools 脚本
from pwn import *
tab = 'abdefglostuyp{}_'
aa = open("D:\ctf附件2\cStuday.exe", 'rb').read()[0x2400: 0x13400]
def deeptry(i, v4, s):
if v4 < 0:
return False
if i == 0:
# print(i,hex(v4),s)
if v4 == 0:
print('-->' + s)
return False
for j in range(16):
v2 = 17 * (j + 16 * i)
p = 8 * (tab.index(s[0]) + v2)
# print(hex(p))
tmp = v4 - u64(aa[p:p + 8])
deeptry(i - 1, tmp, tab[j] + s)
s = '}'
deeptry(31, 0x1C836D8E5C11047F, s)
但是确实数有点多,跑出来应该也要半天
翻翻wp,都是猜出来的
就难评
不过也再次说明逆向确实很需要猜 0_0
屏幕裂开了
你的手机屏幕能承受住那么多次点击吗?
所以 flag 肯定藏在哪里,找到点击那个函数,修改一下判断条件再调试,这应该是最优解,或者直接找到 flag
jeb试试
表示 v4<v5,就跳转到 BE 标签
可以修改 v4,v5 顺序,也可以改成指令 if-le
然后忘记怎么修改 jeb 指令了,0_0
鼠标点击要下断点的行:ctrl+b 打断点鼠标点击要下断点的行:control+b 打断点
不知道为什么 NP 里的 MainActivity 里面没有那个判断
后面还有一个 Main 类里面找到了,
还有可以通过Android Killer 实现,上述想法,不过还是有一点问题,看看课再说吧
网上看了一下,wp都是直接逆的算法
怎么都不想偷懒吗?唉,都这么勤快
应该就是 RC4,但解出来不对
所以最后异或那部分要重复 99999 次,不对不是异或那,是S盒打乱那
贴个学习大佬的脚本
s = [i for i in range(256)]
k = (b"InfinityLoop"*22) [0:256]
for hit_count in range(99999):
j = 0
for i in range(256):
j = (s[i]+j+k[i])%256
s[i],s[j] = s[j],s[i]
answer = [0xA6,0x3D,0x54,0x0B0,0x74,0xCC,0xBD,0x2A,0x4A,0x0DE,0x0BD,0x35,0x0D1,0x1D,0x80,0x32,0x5F,0x64,0x2F,0x0C5,0x0DD,0x11,0x3E,0x95,0x0CC,0x17,0x13,0x0E5,0x5E,0x65,0x0CE,0x42,0x9E,0x47,0x0C8,0x0F3,0x4D,0x8A,0x0A6,0x1F,0x0F0,0x50,0x27,0x0A2,0x28,0x81,0x24,0x0A7,0x0B4,0x90,0x0FC,0x93,0x8A,0x0C1,0x77,0x0D5,0x16,0x1E,0x0FD,0x87,0x0C7,0x0BB,0x0B3,0x0]
v10,v11 = 0,0
v14 = s
tab = [0]*63
for j in range(63):
v11 = v11+1
v10 = (v14[v11] + v10)& 0xff
v14[v11],v14[v10] = v14[v10],v14[v11]
tab[j] = v14[(v14[v10]+ v14[v11]) %256]
flag = [answer[i]^tab[i] for i in range(63)]
print(bytes(flag))
#flag{i_hope_you_didnt_click_the_button_99999__justRE_in_Static}
i=0
j=0
key='InfinityLoop'
flag='\xa6\x3d\x54\xb0\x74\xcc\xbd\x2a\x4a\xde\xbd\x35\xd1\x1d\x80\x32\x5f\x64\x2f\xc5\xdd\x11\x3e\x95\xcc\x17\x13\xe5\x5e\x65\xce\x42\x9e\x47\xc8\xf3\x4d\x8a\xa6\x1f\xf0\x50\x27\xa2\x28\x81\x24\xa7\xb4\x90\xfc\x93\x8a\xc1\x77\xd5\x16\x1e\xfd\x87\xc7\xbb\xb3'
s=[]
k=[]
for i in range(256):
s.append(i)
k.append(0)
for i in range(256):
k[i]=ord(key[i%len(key)])
for t in range(99999):
j=0
for i in range(256):
j=(j+s[i]+k[i])%256
tmp=s[i]
s[i]=s[j]
s[j]=tmp
for a in range(16):
for b in range(16):
print('%.2x '%s[16*a+b],end='')
print()
i=0
j=0
for k in range(len(flag)):
i=(i+1)%256
j=(j+s[i])%256
tmp=s[i]
s[i]=s[j]
s[j]=tmp
t=(s[i]+s[j])%256
print(chr(ord(flag[k])^s[t]),end='')
这是我能写的 0_0
for a in range(16):
for b in range(16):
print(‘%.2x ’ % s[16*a + b], end=’')
print()
%.2x 是一个格式化字符串,表示输出一个十六进制数,且占两位,不足两位时在前面补0
二进制玩家人均全栈
又是一个 zip 伪加密,这次有两个 50 4B 01 02
第一个没有问题,改第二个
不知道是个什么,丢 010 看看
多了一个 7F ,删掉试试
好像不是 exe ,ida 打开也不是
发现和 elf 文件头也很像,试试
对了,但应该有个壳,没查出来
下一个 die 查一下,说是两个互补用
查到了,但还是待去 010 看看
都改一下吧
exe 只有三个
不知道有些师傅都怎么改的
第一处是特征值 : UPX!
只能先留这了,之后遇到再看看
刚好下面一个是加UPX的64位elf
最后两个也是 UPX!
成功了,elf的UPX壳是有 ==三个特征值 UPX!==分别在开头和结尾两个。
先手动脱一下
ida来dump得到elf文件
调半天,卡在这了
好烦 0_0
找找资料,学学先。
一眼maze题
len(map)=256=488
难道是分四个小地图还是一个三维(只有四个方向键应该不是)
我是就这直接提取的,看了一下 wp:大家是按 dword 提取的 0_0
成功了,把 create as array 取消就行了
但是 shift+e 提取的还是 256 个,不知道为什么,问问其他师傅
这样得到地图