iscc reverse

0x01dig_dig_dig

__int64 __fastcall main(int a1, char **a2, char **a3)
{
  size_t v3; // rax
  char *dest; // ST18_8
  size_t v5; // rax
  __int64 v6; // rax
  __int64 v7; // rax
  char *v8; // ST18_8

  if ( a1 != 2 )
  {
    puts("./dec_dec_dec flag_string_is_here ");
    exit(0);
  }
  v3 = strlen(a2[1]);
  dest = (char *)malloc(v3 + 1);
  v5 = strlen(a2[1]);
  strncpy(dest, a2[1], v5);
  v6 = sub_860(dest);
  v7 = sub_F59(v6);
  v8 = (char *)sub_BE7(v7);
  if ( !strcmp(v8, s2) )
    puts("correct  :)");
  else
    puts("incorrect :(");
  return 0LL;
}

从这里可以看出,输入字符串进行了3次加密,没有长度信息。
在这里插入图片描述
第一段看编码表可以猜测是base64
可以验证一下
在这里插入图片描述
验证MTIzNDU2就是123456base64加密后的结果
第二部分
在这里插入图片描述
这个是rot5,这里分享一个爆破脚本

v10='Hv1g_1g_M0if_Tzou_v4v4v'
v11=[]
for i in range(len(v10)):
    v11.append(v10[i])
f=''
for i in range(len(v10)):
    for j in range(0,128):
        if  j > 90 or j< 65 :
            if j > 122 or j < 97:
                continue
            v9 = (j - 83) % 26 + 97
        else:
            v9 = (j - 51) % 26 + 65
        if v10[i]==chr(v9):
            print v10[i],chr(j)
            v11[i]=chr(j)
for i in range(len(v10)):
    f+=v11[i]
print f
print v10

在这里插入图片描述
第三段是uuencode加密更好的
可以从这个加密结果猜测
.rodata:00000000000011C8 a1de440s9w92tY0 db '@1DE!440S9W9,2T%Y07=%<W!Z.3!:1T%S2S-),7-$/3T ',0

总结:需要一个总结关于常用的编码方式
1.编码代码的特点
2.编码明文和密文范围的特点()
3.编码之后明文密文长度的变化特点。
可能会有几种加密方法一起。或者编码之后再进行简单异或,小写转大写等。这些可以动态调试来确定。

0x02pyc.pyc
pyc文件是python字节码文件,可以在线反编译https://tool.lu/pyc/
进行了简单异或

import base64
c = 'eYNzc2tjWV1gXFWPYGlTbQ=='

m = c.decode("base64")
s = ''
for i in m:

        x = ord(i) - 16
        x = x ^ 32
        s=s+chr(x)

print s

0x03 main.exe
用ida打开,有经验的话可以看出来这是一个64位的elf文件,然而知道这些并没有什么用。
没办法,谷歌了一下输出的字符串,找出来了别人解出来的答案。
https://www.megabeets.net/page/4/

0x04 Re2.exe
在这里插入图片描述
输入用户名和密码即可
0x05reverse

搜索输入函数可以找到
在这里插入图片描述
输入的值被放入了v28,追踪v28可以确定
在这里验证
在这里插入图片描述
下断点扒数据


pwndbg> x /50xw 0x7ffff6c2a000
0x7ffff6c2a000:	0x00000154	0x00000180	0x000001fc	0x000001e4
0x7ffff6c2a010:	0x000001f8	0x00000154	0x00000190	0x000001bc
0x7ffff6c2a020:	0x000001bc	0x000001b8	0x00000154	0x000001f8
0x7ffff6c2a030:	0x00000194	0x00000154	0x000001b4	0x000001bc
0x7ffff6c2a040:	0x000001f8	0x00000154	0x000001f4	0x00000188
0x7ffff6c2a050:	0x000001ac	0x000001f8	0x00000154	0x0000018c
0x7ffff6c2a060:	0x000001e4	0x00000154	0x00000190	0x000001bc
0x7ffff6c2a070:	0x000001bc	0x000001b8	0x000001bc	0x000001b8
0x7ffff6c2a080:	0x00000154	0x00000090	0x00000000	0x00000000
0x7ffff6c2a090:	0x00000000	0x00000000	0x00000000	0x00000000
0x7ffff6c2a0a0:	0x00000000	0x00000000	0x00000000	0x00000000
0x7ffff6c2a0b0:	0x00000000	0x00000000	0x00000000	0x00000000
0x7ffff6c2a0c0:	0x00000000	0x00000000

key=[0x00000154,0x00000180,0x000001fc,0x000001e4,0x000001f8,0x00000154,0x00000190,0x000001bc,	0x000001bc,	0x000001b8,	0x00000154,	0x000001f8,
	0x00000194,	0x00000154,	0x000001b4,	0x000001bc,
	0x000001f8,	0x00000154,	0x000001f4,	0x00000188,
	0x000001ac,	0x000001f8,	0x00000154,	0x0000018c,
	0x000001e4,	0x00000154,	0x00000190,	0x000001bc,
	0x000001bc,	0x000001b8,	0x000001bc,	0x000001b8,
	0x00000154,	0x00000090]
flag=""
for i in key:
	flag+= chr((i>>2)^0xA)
print flag

0x06 apk
用jeb查看check逻辑。可以得到长度和范围
提取so文件分析check逻辑。
这个题目代码静态调试不好懂(ida反编译过来很乱,需要看汇编)但是具体算法挺简单。这两个特点满足符号执行。
用angr解题

# libnative-lib.so
import angr
import claripy
import binascii

base = 0x400000
p = angr.Project("./libnative-lib.so")
key = claripy.BVS("key", 16 * 8)

state = p.factory.blank_state(addr=0xECC0+base)#设置入口地址
# 0xF19C + base :first_out_call
# 0xF198 check_first_wrapper
# 0xE3C0 check_first
# 0xECC0 check_again

# for i in range(0, 8):
#     state.add_constraints(key.get_byte(i) == claripy.BVV(i + ord('1'), 4))

# state.se.add(key.get_byte(8) == int(binascii.hexlify(b"12345678"), 16))

state.se.add(key.get_byte(0) == int(binascii.hexlify(b"1"), 16))
state.se.add(key.get_byte(1) == int(binascii.hexlify(b"2"), 16))
state.se.add(key.get_byte(2) == int(binascii.hexlify(b"3"), 16))
state.se.add(key.get_byte(3) == int(binascii.hexlify(b"4"), 16))
state.se.add(key.get_byte(4) == int(binascii.hexlify(b"5"), 16))
state.se.add(key.get_byte(5) == int(binascii.hexlify(b"6"), 16))
state.se.add(key.get_byte(6) == int(binascii.hexlify(b"7"), 16))
state.se.add(key.get_byte(7) == int(binascii.hexlify(b"8"), 16))#设置前8位

sm = p.factory.simulation_manager(state)
sm.explore(find=[  # 0xE607 + base,  # first_check
    # 0xE487 + base,  # char+1
    # 0xE4E4 + base,  # cahr+1
    0xF0F5 + base,     #运行到这里是checkAgain正确结果 
    #0xF223 + base  # out of check_second , in check_main
],
    avoid=[0xE5E2 + base,  # check_first
           0xF00F + base, 0xF037 + base, 0xF0B7 + base, 0xF077 + base, 0xEFB4 + base, 0xEF9C + base,
           0xEF81 + base,
            0xF22C+base # behind calculation
           ])  #这些是不正确的结果
found = sm.found[0]

for i in range(8, 16):
    cond_0 = key.get_byte(i) >= ord('1')
    cond_1 = key.get_byte(i) <= ord('8')
    found.add_constraints(found.solver.And(cond_0, cond_1))

    for j in range(i + 1, 16):
        if i == j or j >= 16:
            break
        # found.add_constraints(found.solver.And(key.get_byte(i) != key.get_byte(j), cond_1))
        # print("NOW ADD index(%d) !=index(%d)", i, j)
        cond2 = key.get_byte(i) != key.get_byte(j)
        found.add_constraints(found.solver.And(cond_0, cond2))

    # if i + 1 <= 17:
    #     cond_2 = key.get_byte(i) != key.get_byte(i + 1)
    #     found.add_constraints(found.solver.And(cond_0, cond_2))


tmp_addr = 0x38460 + base
state.regs.rdi = tmp_addr
flag_addr = state.regs.rdi
# found.add_constraints(found.memory.load(flag_addr, 5) == int(binascii.hexlify(b"12345678"), 16))

found.memory.store(flag_addr, key)

if found.solver.satisfiable():
    print("FIND IT")
else:
    print("CANNOT FIND")
    exit(0)

flag_str = found.solver.eval(key, cast_to=bytes)

print(bytes.decode(flag_str).strip('\x00'))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值