现在的位置: 首页 c/c++ >正文

使用javaAgent解除Burp的时间限制

burp到期了,按照以往的情况,很快就会有大佬放出更新版本,但等待的时间着实难熬。

一直改系统时间有些麻烦,所以写个小东西方便群众。

(我是ms党,所以……linux和mac自求多福。)


0x01 原理


windows上的jre使用GetSystemTimeAsFileTime API获取系统时间,对API下个断点,把poi(esp+4)改成0x01d263c1`feb0c000,就能看到所有的时间都变成了2017/1/1 X:0:0:

bp kernelbase!GetSystemTimeAsFileTime "r @$t0=poi(esp+4);gu;eq @$t0 0x01d263c1`feb0c000;g"

之后burp就能打开了:

1.png

中文操作系统默认时区是东八区,所以时间是2017/1/1 8:0:0,其他系统以此类推。


但现在出现了一个问题:由于所有时间都变成了相同的,所以history等按照时间排序的功能就失效了。

解决方式也很简单,只改日期不改时间即可。GetSystemTimeAsFileTime被我们和谐了,换用GetSystemTime来获取时间,返回的SYSTEMTIME也更方便处理。

(windows时间API基本都是从SharedUserData中直接取值,所以不用担心修改一个API会影响到其他的问题)


0x02 代码


burp的进程是javaw,所以必须要做个hook。

注入+hook的代码网上一找一大把,不过java提供了agent功能进行动态修改,其中native agent本身就是一个dll,这样就不用单独写一个注入的exe了。


native agent需要导出三个函数:Agent_OnLoad和Agent_OnAttach用于初始化,Agent_OnUnload用于卸载,考虑到并不需要访问jvm信息,用PVOID和long代替jvm类型:

long WINAPI Agent_OnLoad(PVOID *vm, char *options, void *reserved);
long WINAPI Agent_OnAttach(PVOID *vm, char *options, void *reserved);
long WINAPI Agent_OnUnload(PVOID *vm);


hook实现方面,需要用到两个API:GetSystemTime获取当前时间,把年月日改成2017/1/1;

SystemTimeToFileTime将修改后的时间转换为FileTime并返回传递给原始调用:

void WINAPI hook(LPFILETIME ft)
{
    SYSTEMTIME st = { 0 };
    GetSystemTime(&st);
    st.wYear = 2017;
    st.wMonth = 1;
    st.wDay = 1;
    SystemTimeToFileTime(&st, ft);
}


之后是hook,直接jmp,考虑到64位jre的问题要写两种:

#ifdef WIN64
    BYTE shellcode[] = 
    { 
        0x48, 0xb8,               //mov rax,
        0, 0, 0, 0, 0, 0, 0, 0,    //hook addr
        0xff, 0xe0                  //jmp rax
    };
#else
    BYTE shellcode[] =
    {
        0x90, 0xb8,               //mov eax,
        0, 0, 0, 0,                   //hook addr
        0xff, 0xe0                  //jmp rax
    };
#endif


编译加载运行,发现burp直接退出了,反编译BurpLoader,看到了一个可疑调用:

2.png

(吐槽一句jd-gui,反编译出的字节码结果还不如javap)

查询官方文档 https://docs.oracle.com/javase/7/docs/api/java/lang/management/RuntimeMXBean.html  得知getInputArguments方法返回jvm参数配置信息,反编译jre发现最终调用了一个native实现:

sun.management.VMManagementImpl.getVmArguments0。

3.png


native实现必然封装于dll中,退出之前加载的最后一个java模块为management.dll:

4.png

查看导出函数,果然发现了名为_Java_sun_management_VMManagementImpl_getVmArguments0@8的导出。

那么和谐这个函数就好了。


由于java层的包装会自动处理null的问题,也就不用费力气写hook函数了,改成return NULL即可:

#ifdef WIN64
    BYTE shellcode2[] =
    {
        0x48, 0x33, 0xc0,         //xor rax,rax
        0xc3, 0x00, 0x00          //ret
    };
    
#else
    BYTE shellcode2[] =
    {
        0x33, 0xc0,               //xor eax,eax
        0xc2, 0x08, 0x00          //ret 8
    };
#endif


编译加载运行,这次没有问题了:

5.png


0x03 下载


编译好的dll为JavaTimeAgent和JavaTimeAgent64,使用方法类似于指定xmx,给java加个启动参数即可:

java -agentpath:JavaTimeAgent.dll java_class
javaw -agentpath:JavaTimeAgent.dll -jar BurpLoader.jar

运行后的日期被锁定在2017/1/1,时间不变。如果有特殊需求的话自行修改编译dll。


注意几个细节:

java的环境变量要去控制面板配置;jar和dll最好写绝对路径。

hook的行为可能被杀软和谐。

dll的版本要和jre匹配。

其他检测时间的java程序应该也许可能好像大概差不多能使用这个工具,请自行尝试。


我测试的环境为win7 x86/win10 x64+jre 1.8,其他版本没有环境来测试(理论上不会有问题……吧)。


下载地址:      JavaTimeAgent.zip

Github: https://github.com/zcgonvh/JavaTimeAgent

解压密码见注释。