2022强网杯 Quals Reverse 部分writeup

本文详细讲述了如何通过Frida工具逆向Android应用的Java层逻辑,重点在于解密与47.93.244.181服务器的交互数据,包括通过HttpRequest获取admin权限的过程。作者利用Z3求解器解密算法,并揭示了维吉尼亚解密步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Game

native层其实只有加解密的两个函数,所以没怎么逆,直接用frida hook

  1. 由于有root检测和frida检测,换个端口启动 ./frida-server-15.1.8-android-arm64 -l 0.0.0.0:27049
  2. 然后就可以直接调用加解密函数了:
/*
docs: https://frida.re/docs/javascript-api/

adb root
adb shell
cd /data/local
./frida-server

py3
adb forward tcp:27049 tcp:27049
frida-ps  -H 127.0.0.1:27049
frida  -H 127.0.0.1:27049 -f com.silence.scoreboard -l try.js --no-pause
*/

var HttpRequest = Java.use('com.silence.scoreboard.http.HttpRequest');
var OOOO = Java.use('com.silence.utils.OooOoo0');

OOOO.decrypt("SWeH8ou9yuL8GLThYhY1QlDiWX880+uNZusmIll/Q4Q=");
// "&Od987$2sPa?>l<k^j"
OOOO.decrypt("IbaoQT/3eTXIjHDJ2L5TQE==");
//"admin"

主要还是在逆java层的逻辑,所有数据都是在和47.93.244.181服务器进行交互,因此只要在com.silence.scoreboard.http.HttpRequest 里逆清楚几个交互的逻辑就行。

  1. 通过scoreboard http://47.93.244.181/re/ScoreBoard.php 找到高分admin "IbaoQT/3eTXIjHDJ2L5TQE==”(a.k.a. admin)

  2. 通过加好友获得admin的account $.post(‘AddFriend.php’, {code:‘123125’})

  3. 获得flag username = ‘admin’; account = “&Od987$2sPa?>l<k^j”; $.post(‘GetFlag.php’, {code:‘123125’, account,username})

在这里插入图片描述

easyre

  1. 通过读主程序可知,程序写一个子程序re3并ptrace它,在遇到中断的时候会根据RIP的内容解密、重新加密某一段代码。

  2. 使用strace获得所有系统调用,(所有对子程序的写操作都通过ptrace实现),解析PTRACE_POKETEXT并patch程序(仅限解密部分)

    lines = open(r'stracedump.txt').read().splitlines()
    lines = [line for line in lines if line.startswith('ptrace(PTRACE_POKETEXT, ')]
    delta = 0x555555554000
    lines = [(int(line[31:][:14], 16) - delta, int(line[47:-5].strip(), 16)) for line in lines]
    lines = lines[:0x27]
    [patch_qword(addr, value) for addr, value in lines]
    

    setjmp和longjmp部分代码应该只是写了一个循环比较的过程

  3. 在要比较的两个数组上下硬件断点,注意到子程序开始会将最后两个比较的数组偷换。

  4. 用z3求解对应问题(队内4老师的脚本!我菜菜是自己手画的55):

    linescan = bytes.fromhex('0605010302010100000000000000000000000000000000000008010101010101010100000000000000000000000000000000070301030104010100000000000000000000000000000000000801010102010101010000000000000000000000000000000007010401030201030000000000000000000000000000000000000000000000000000000000000000000000000000000000000604040401010100000000000000000000000000000000000008010202010201020100000000000000000000000000000000080101010103040301000000000000000000000000000000000A01010101010101010101000000000000000000000000000007030103010401010000000000000000000000000000000000010200000000000000000000000000000000000000000000000601010401010400000000000000000000000000000000000007080101010102010000000000000000000000000000000000080101010101010104000000000000000000000000000000000A0202010201010101010100000000000000000000000000000502050101030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060C0201010101000000000000000000000000000000000000090201010101010101010000000000000000000000000000000704070201010101000000000000000000000000000000000009010102010101010101000000000000000000000000000000020C02000000000000000000000000000000000000000000000401010101000000000000000000000000000000000000000004040201010000000000000000000000000000000000000000')
    assert 625 == len(linescan)
    linescan = [[linescan[i*25+j] for j in range(25)] for i in range(25)]
    
    cowscan = bytes.fromhex('050505030103000000000000000000000000000000000000000A0101010101010101010100000000000000000000000000000701010501030101000000000000000000000000000000000005010204050100000000000000000000000000000000000000070502010101010100000000000000000000000000000000000501010101050000000000000000000000000000000000000005010206010300000000000000000000000000000000000000070202010101010100000000000000000000000000000000000602050103010100000000000000000000000000000000000009010101010101010301000000000000000000000000000000070201010101010100000000000000000000000000000000000402050301000000000000000000000000000000000000000005030501010100000000000000000000000000000000000000080101010101010101000000000000000000000000000000000601010103050500000000000000000000000000000000000006010305010101000000000000000000000000000000000000030101030000000000000000000000000000000000000000000505010204010000000000000000000000000000000000000004010104030000000000000000000000000000000000000000050101020401000000000000000000000000000000000000000305040300000000000000000000000000000000000000000004020504010000000000000000000000000000000000000000050503010101000000000000000000000000000000000000000701020101010401000000000000000000000000000000000003010101000000000000000000000000000000000000000000')
    assert 625 == len(cowscan)
    cowscan = [[cowscan[i*25+j] for j in range(25)] for i in range(25)]
    
    def clean(v):
        u = []
        for w 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值