测试文件:https://adworld.xctf.org.cn/media/task/attachments/dc14f9a05f2846249336a84aecaf18a2.zip
1.准备
获取信息
- 64位文件
2.IDA打开
前面大部分都是“无用代码”,这里贴上我们需要的代码
while ( 1 ) { memset(flag, 0, 0xC8uLL); numRead = read(pParentWrite[0], flag, 0xC8uLL); if ( numRead == -1 ) break; if ( numRead ) { if ( childCheckDebugResult() ) { responseFalse(); } else if ( flag[0] == '{' ) // flag[0]为'{' { if ( strlen(flag) == 42 ) // len(flag)=42 { if ( !strncmp(&flag[1], "53fc275d81", 10uLL) )// flag[1]~flag[10]为"53fc275d81" { if ( flag[strlen(flag) - 1] == '}' )// flag[41]='}' { if ( !strncmp(&flag[31], "4938ae4efd", 10uLL) )// flag[31]~flag[40]为'4938ae4efd' { if ( !confuseKey(flag, 42) ) // 改变原本flag中字符串的顺序 { responseFalse(); } else if ( !strncmp(flag, "{daf29f59034938ae4efd53fc275d81053ed5be8c}", 42uLL) )// '{}'中间有40个字符,10个为一组,则现在顺序为3,4,1,2 { responseTrue(); } else { responseFalse(); } } else { responseFalse(); } } else { responseFalse(); } } else { responseFalse(); } } else { responseFalse(); } } else { responseFalse(); } } } exit(1); } exit(1); }
bool __cdecl confuseKey(char *szKey, int iKeyLength) { char szPart1[15]; // [rsp+10h] [rbp-50h] char szPart2[15]; // [rsp+20h] [rbp-40h] char szPart3[15]; // [rsp+30h] [rbp-30h] char szPart4[15]; // [rsp+40h] [rbp-20h] unsigned __int64 v7; // [rsp+58h] [rbp-8h] v7 = __readfsqword(0x28u); *(_QWORD *)szPart1 = 0LL; *(_DWORD *)&szPart1[8] = 0; *(_WORD *)&szPart1[12] = 0; szPart1[14] = 0; *(_QWORD *)szPart2 = 0LL; *(_DWORD *)&szPart2[8] = 0; *(_WORD *)&szPart2[12] = 0; szPart2[14] = 0; *(_QWORD *)szPart3 = 0LL; *(_DWORD *)&szPart3[8] = 0; *(_WORD *)&szPart3[12] = 0; szPart3[14] = 0; *(_QWORD *)szPart4 = 0LL; *(_DWORD *)&szPart4[8] = 0; *(_WORD *)&szPart4[12] = 0; szPart4[14] = 0; if ( iKeyLength != 42 ) return 0; if ( !szKey ) return 0; if ( strlen(szKey) != 42 ) return 0; if ( *szKey != 123 ) return 0; strncpy(szPart1, szKey + 1, 0xAuLL); strncpy(szPart2, szKey + 11, 0xAuLL); strncpy(szPart3, szKey + 21, 0xAuLL); strncpy(szPart4, szKey + 31, 0xAuLL); memset(szKey, 0, iKeyLength); *szKey = 123; strcat(szKey, szPart3); strcat(szKey, szPart4); strcat(szKey, szPart1); strcat(szKey, szPart2); szKey[41] = 125; return 1; }
3.代码分析
第一段代码我们能够获取到flag[0],flag[1]~flag[10],flag[31]~flag[40],flag[41],以及调换顺序之后的flag
第二段代码实际上是在对原来的flag字符串的位置进行调换,"{}"中间有40个字符,10个为一组,现在的顺序就是3,4,2,1。
因此,我们通过调换顺序之后的flag,能够获取到原来的flag。这道题最坑的就是真正的flag没有"{}"
4.get flag!
53fc275d81053ed5be8cdaf29f59034938ae4efd