-
-
[原创]inctf-noodes
-
2021-8-18 18:22 9004
-
inctf-noodes
这个题算是诈胡出来的
参考链接:
https://linux.die.net/man/7/inotify
https://zh.wikipedia.org/wiki/Inotify
比较的地方
1 2 3 4 5 6 | if ( !strcmp( s1, "dfxXdf5FcwL\\adsUddPedd}UdflZafn~af9TmflZcwlZafilddKYafM^dfxRmfENcwENddXmdf\\Raff\\df{xddL[adeiadJkdfW5cwiTdd7" "Ydf^zadkKcw:jadeudfU=dfj~dd[}dfM9cwp7dfhnmfTjcwTjddyQdfftdd5UdfIxddGydfgnddjYdfqZcwqPcwfpdflLddUoaf~vddWqafZJd" "f=Tcw{Zmf|Fcw|FddnkadUgdfj\\dfr^dd]SdfGJcwwJdfFtcwzFcwXVcwE|cwkPddWMdd]iadu:cwFRad\\IafXrafNxmfElcwElafJvafx9d" "f4|dd8mmfH~cwH~mfT~cwT~afkFafvpdfj5dd}SafVRmfFpmfP|mfThmfNLmf5ZcwFpcwP|cw\\xcw=7cwyncwG|cwThcwNLcw\\pcwI^cw5ZcwOT" ) ) |
s1的生成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | v45 = __readfsqword( 0x28u ); index = 0 ; s_index = 0 ; sub_55D31246E16A(); sub_55D31246E1FA(); fd = inotify_init(); / / 初始化一个 inotify 实例 if ( fd < 0 ) perror( "inotify_init" ); sub_55D31246E4B7( "/tmp/chall/" ); / / 初始化文件 wd = inotify_add_watch(fd, "/tmp/chall/" , 0x33Fu ); / / 将监视添加到初始化的 inotify 实例 pid = fork(); / / 新建进程 if ( !pid ) sub_55D31246E668( "/tmp/chall/" ); / / 用户输入处理,文件变动 if ( waitpid(pid, &stat_loc, 0 ) = = - 1 ) { perror( "waitpid failed\n" ); goto LABEL_35; } v40 = BYTE1(stat_loc); printf( "%d" , BYTE1(stat_loc)); |
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 110 111 112 113 114 115 116 | size = read(fd, buf, 0x8000uLL ); if ( size < 0 ) perror( "read" ); while ( index < size ) { byte = &buf[index]; if ( ! * ((_DWORD * )byte + 3 ) ) goto LABEL_30; if ( ( * ((_DWORD * )byte + 1 ) & 0x100 ) ! = 0 ) / / IN_CREATE { v3 = s_index; if ( ( * ((_DWORD * )byte + 1 ) & 0x40000000 ) ! = 0 ) / / IN_ISDIR { + + s_index; s1[v3] = 'c' ; v4 = s_index + + ; s1[v4] = 'd' ; } else { + + s_index; s1[v3] = 'c' ; v5 = s_index + + ; s1[v5] = 'f' ; } LABEL_26: v23 = byte[ 16 ] + 4 ; v24 = s_index + + ; s1[v24] = v23; v25 = byte[ 17 ] + 4 ; v26 = s_index + + ; s1[v26] = v25; goto LABEL_30; } if ( ( * ((_DWORD * )byte + 1 ) & 0x200 ) ! = 0 ) / / IN_DELETE { v6 = s_index; if ( ( * ((_DWORD * )byte + 1 ) & 0x40000000 ) ! = 0 ) { + + s_index; s1[v6] = 'd' ; v7 = s_index + + ; s1[v7] = 'd' ; } else { + + s_index; s1[v6] = 'd' ; v8 = s_index + + ; s1[v8] = 'f' ; } goto LABEL_26; } if ( ( * ((_DWORD * )byte + 1 ) & 8 ) ! = 0 ) / / IN_CLOSE_WRITE { v9 = s_index + + ; s1[v9] = 'c' ; v10 = s_index + + ; s1[v10] = 'w' ; v11 = byte[ 16 ] + 4 ; v12 = s_index + + ; s1[v12] = v11; v13 = byte[ 17 ] + 4 ; v14 = s_index + + ; s1[v14] = v13; goto LABEL_30; } if ( ( * ((_DWORD * )byte + 1 ) & 1 ) ! = 0 ) / / IN_ACCESS { v15 = s_index + + ; s1[v15] = 'a' ; v16 = s_index + + ; s1[v16] = 'c' ; v17 = byte[ 16 ] + 4 ; v18 = s_index + + ; s1[v18] = v17; v19 = byte[ 17 ] + 4 ; v20 = s_index + + ; s1[v20] = v19; goto LABEL_30; } if ( ( * ((_DWORD * )byte + 1 ) & 4 ) ! = 0 ) / / IN_ATTRIB { v21 = s_index; if ( ( * ((_DWORD * )byte + 1 ) & 0x40000000 ) ! = 0 ) { + + s_index; s1[v21] = 'a' ; v22 = s_index + + ; s1[v22] = 'd' ; } else { + + s_index; s1[v21] = 'a' ; v27 = s_index + + ; s1[v27] = 'f' ; } goto LABEL_26; } if ( ( * ((_DWORD * )byte + 1 ) & 2 ) ! = 0 ) / / IN_MODIFY { v28 = s_index + + ; s1[v28] = 'm' ; v29 = s_index + + ; s1[v29] = 'f' ; v30 = byte[ 16 ] + 4 ; v31 = s_index + + ; s1[v31] = v30; v32 = byte[ 17 ] + 4 ; v33 = s_index + + ; s1[v33] = v32; } LABEL_30: index + = * ((_DWORD * )byte + 3 ) + 16 ; } |
inotify
这个感觉和git有点点像, 监控文件的变动, 变动会生成事件
1 2 3 4 5 6 7 8 | struct inotify_event { int wd; / * Watch descriptor * / uint32_t mask; / * Mask of events * / uint32_t cookie; / * Unique cookie associating related events ( for rename( 2 )) * / uint32_t len ; / * Size of name field * / char name[]; / * Optional null - terminated name * / }; |
这里涉及的事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | IN_ACCESS 0x00000001 文件被访问(读取)( * )。 IN_CLOSE_WRITE 0x00000008 为写入而打开的文件已关闭 ( * )。 IN_ATTRIB 0x00000004 权限修改 IN_ISDIR 0x40000000 事件的目标是文件夹 IN_CREATE 0x00000100 有新文件产生(可能是目录) IN_DELETE 0x00000200 有文件被删除(可能是目录) IN_MODIFY 0x00000002 修改文件 |
这里4字节长度刚好对应index += ((_DWORD )byte + 3) + 16;的加16
处理输入
1 | 1 : stream[v3] = fopen(dest, "a+" ); |
1 | 2 : fclose(stream[ - - v9]); / / 生成cw |
1 | 3 : fwrite( "Wrong" , 1uLL , 5uLL , stream[v9 - 1 ]); / / 生成mf |
1 | 4 : unlink(dest); / / 生成df |
1 | 5 : chmod(dest, 0x164u ); / / 生成af |
1 | 6 : rmdir(dest); / / 生成dd |
1 | 7 : mkdir(dest, 0x1C0u ); / / 生成cd |
1 | 8 :exit( 0 ) |
除了2,3不能有名称之外都有2字节的名称
分析比较字符串
这里的字符串没有新建操作, 前面的文件初始化已经完成了(监控开启之前)
注意:df之后不能再打开文件, 否则会出现新建操作,(这里有一处就是这样df之后才mf的, 这里应该再df之前就打开, 我把这个操作放在了最前面, mf之前和cw之前一定要打开文件指针, 打开操作只需要一次, (mf, cw相同的文件只打开一次, 每次mf都会有cw收尾), exit会关闭所有的文件指针(这里也会被记录, 后打开的先关闭)
生成输入脚本: (因为mf操作不多, 我就直接手动删除多余的新建操作, 最后再加个8)
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 | #include<iostream> using namespace std; int main() { char a[ 437 ] = { 0x64 , 0x66 , 0x78 , 0x58 , 0x64 , 0x66 , 0x35 , 0x46 , 0x63 , 0x77 , 0x4C , 0x5C , 0x61 , 0x64 , 0x73 , 0x55 , 0x64 , 0x64 , 0x50 , 0x65 , 0x64 , 0x64 , 0x7D , 0x55 , 0x64 , 0x66 , 0x6C , 0x5A , 0x61 , 0x66 , 0x6E , 0x7E , 0x61 , 0x66 , 0x39 , 0x54 , 0x6D , 0x66 , 0x6C , 0x5A , 0x63 , 0x77 , 0x6C , 0x5A , 0x61 , 0x66 , 0x69 , 0x6C , 0x64 , 0x64 , 0x4B , 0x59 , 0x61 , 0x66 , 0x4D , 0x5E , 0x64 , 0x66 , 0x78 , 0x52 , 0x6D , 0x66 , 0x45 , 0x4E , 0x63 , 0x77 , 0x45 , 0x4E , 0x64 , 0x64 , 0x58 , 0x6D , 0x64 , 0x66 , 0x5C , 0x52 , 0x61 , 0x66 , 0x66 , 0x5C , 0x64 , 0x66 , 0x7B , 0x78 , 0x64 , 0x64 , 0x4C , 0x5B , 0x61 , 0x64 , 0x65 , 0x69 , 0x61 , 0x64 , 0x4A , 0x6B , 0x64 , 0x66 , 0x57 , 0x35 , 0x63 , 0x77 , 0x69 , 0x54 , 0x64 , 0x64 , 0x37 , 0x59 , 0x64 , 0x66 , 0x5E , 0x7A , 0x61 , 0x64 , 0x6B , 0x4B , 0x63 , 0x77 , 0x3A , 0x6A , 0x61 , 0x64 , 0x65 , 0x75 , 0x64 , 0x66 , 0x55 , 0x3D , 0x64 , 0x66 , 0x6A , 0x7E , 0x64 , 0x64 , 0x5B , 0x7D , 0x64 , 0x66 , 0x4D , 0x39 , 0x63 , 0x77 , 0x70 , 0x37 , 0x64 , 0x66 , 0x68 , 0x6E , 0x6D , 0x66 , 0x54 , 0x6A , 0x63 , 0x77 , 0x54 , 0x6A , 0x64 , 0x64 , 0x79 , 0x51 , 0x64 , 0x66 , 0x66 , 0x74 , 0x64 , 0x64 , 0x35 , 0x55 , 0x64 , 0x66 , 0x49 , 0x78 , 0x64 , 0x64 , 0x47 , 0x79 , 0x64 , 0x66 , 0x67 , 0x6E , 0x64 , 0x64 , 0x6A , 0x59 , 0x64 , 0x66 , 0x71 , 0x5A , 0x63 , 0x77 , 0x71 , 0x50 , 0x63 , 0x77 , 0x66 , 0x70 , 0x64 , 0x66 , 0x6C , 0x4C , 0x64 , 0x64 , 0x55 , 0x6F , 0x61 , 0x66 , 0x7E , 0x76 , 0x64 , 0x64 , 0x57 , 0x71 , 0x61 , 0x66 , 0x5A , 0x4A , 0x64 , 0x66 , 0x3D , 0x54 , 0x63 , 0x77 , 0x7B , 0x5A , 0x6D , 0x66 , 0x7C , 0x46 , 0x63 , 0x77 , 0x7C , 0x46 , 0x64 , 0x64 , 0x6E , 0x6B , 0x61 , 0x64 , 0x55 , 0x67 , 0x64 , 0x66 , 0x6A , 0x5C , 0x64 , 0x66 , 0x72 , 0x5E , 0x64 , 0x64 , 0x5D , 0x53 , 0x64 , 0x66 , 0x47 , 0x4A , 0x63 , 0x77 , 0x77 , 0x4A , 0x64 , 0x66 , 0x46 , 0x74 , 0x63 , 0x77 , 0x7A , 0x46 , 0x63 , 0x77 , 0x58 , 0x56 , 0x63 , 0x77 , 0x45 , 0x7C , 0x63 , 0x77 , 0x6B , 0x50 , 0x64 , 0x64 , 0x57 , 0x4D , 0x64 , 0x64 , 0x5D , 0x69 , 0x61 , 0x64 , 0x75 , 0x3A , 0x63 , 0x77 , 0x46 , 0x52 , 0x61 , 0x64 , 0x5C , 0x49 , 0x61 , 0x66 , 0x58 , 0x72 , 0x61 , 0x66 , 0x4E , 0x78 , 0x6D , 0x66 , 0x45 , 0x6C , 0x63 , 0x77 , 0x45 , 0x6C , 0x61 , 0x66 , 0x4A , 0x76 , 0x61 , 0x66 , 0x78 , 0x39 , 0x64 , 0x66 , 0x34 , 0x7C , 0x64 , 0x64 , 0x38 , 0x6D , 0x6D , 0x66 , 0x48 , 0x7E , 0x63 , 0x77 , 0x48 , 0x7E , 0x6D , 0x66 , 0x54 , 0x7E , 0x63 , 0x77 , 0x54 , 0x7E , 0x61 , 0x66 , 0x6B , 0x46 , 0x61 , 0x66 , 0x76 , 0x70 , 0x64 , 0x66 , 0x6A , 0x35 , 0x64 , 0x64 , 0x7D , 0x53 , 0x61 , 0x66 , 0x56 , 0x52 , 0x6D , 0x66 , 0x46 , 0x70 , 0x6D , 0x66 , 0x50 , 0x7C , 0x6D , 0x66 , 0x54 , 0x68 , 0x6D , 0x66 , 0x4E , 0x4C , 0x6D , 0x66 , 0x35 , 0x5A , 0x63 , 0x77 , 0x46 , 0x70 , 0x63 , 0x77 , 0x50 , 0x7C , 0x63 , 0x77 , 0x5C , 0x78 , 0x63 , 0x77 , 0x3D , 0x37 , 0x63 , 0x77 , 0x79 , 0x6E , 0x63 , 0x77 , 0x47 , 0x7C , 0x63 , 0x77 , 0x54 , 0x68 , 0x63 , 0x77 , 0x4E , 0x4C , 0x63 , 0x77 , 0x5C , 0x70 , 0x63 , 0x77 , 0x49 , 0x5E , 0x63 , 0x77 , 0x35 , 0x5A , 0x63 , 0x77 , 0x4F , 0x54 , 0x00 }; for ( int i = 0 ; i < 437 ; i + = 4 ) { if (a[i] = = 'c' && a[i + 1 ] = = 'f' ) cout << "1" << char((a[i + 2 ] - 4 )) << char((a[i + 3 ] - 4 )); else if (a[i] = = 'c' && a[i + 1 ] = = 'w' ) cout << "1" << char((a[i + 2 ] - 4 )) << char((a[i + 3 ] - 4 )) << "2" ; else if (a[i] = = 'm' && a[i + 1 ] = = 'f' ) cout << "1" << char((a[i + 2 ] - 4 )) << char((a[i + 3 ] - 4 )) << "3" ; else if (a[i] = = 'd' && a[i + 1 ] = = 'f' ) cout << "4" << char((a[i + 2 ] - 4 )) << char((a[i + 3 ] - 4 )); else if (a[i] = = 'a' && a[i + 1 ] = = 'f' ) cout << "5" << char((a[i + 2 ] - 4 )) << char((a[i + 3 ] - 4 )); else if (a[i] = = 'a' && a[i + 1 ] = = 'd' ) cout << "5" << char((a[i + 2 ] - 4 )) << char((a[i + 3 ] - 4 )); else if (a[i] = = 'd' && a[i + 1 ] = = 'd' ) cout << "6" << char((a[i + 2 ] - 4 )) << char((a[i + 3 ] - 4 )); else if (a[i] = = 'c' && a[i + 1 ] = = 'd' ) cout << "7" << char((a[i + 2 ] - 4 )) << char((a[i + 3 ] - 4 )); } system( "pause" ); } |
得到1hV4tT41B1HX25oQ6La6yQ4hV5jz55P325eh6GU5IZ4tN1AJ326Ti4XN5bX4wt6HW5ae5Fg4S11eP263U4Zv5gG16f25aq4Q94fz6Wy4I51l324dj1Pf326uM4bp61Q4Et6Cu4cj6fU4mV1mL21bl24hH6Qk5zr6Sm5VF49P1wV21xB326jg5Qc4fX4nZ6YO4CF1sF24Bp1vB21TR21Ax21gL26SI6Ye5q61BN25XE5Tn5Jt1Ah325Fr5t540x64i1Dz321Pz325gB5rl4f16yO5RN1Bl31Lx31Pd31JH311V3221Xt219321uj21Cx2221Xl21EZ221KP28
最后输入发现有错误, 调试之后发现, 从SafVR之后开始, 这里完全倒了过来,
要求的s1:mfFpmfP|mfThmfNLmf5ZcwFpcwP|cw\xcw=7cwyncwG|cwThcwNLcw\pcwI^cw5ZcwOT
生成的s1:mf5Zcw5ZmfNLcwNLcw\xcw=7cwyncwG|mfThcwThmfP|cwP|cw\pcwI^mfFpcwFpcwOT
具体调试了函数之后(前面有一个闹钟记得patch掉), 这里mf之后并没有把字符串写入, 是在fclose文件指针之后把文件修改, 那到底怎么连续修改之后再关闭文件指针呢, 这里我试了一下exit来关闭文件指针,把输入后面改成:
1hV4tT41B1HX25oQ6La6yQ4hV5jz55P325eh6GU5IZ4tN1AJ326Ti4XN5bX4wt6HW5ae5Fg4S11eP263U4Zv5gG16f25aq4Q94fz6Wy4I51l324dj1Pf326uM4bp61Q4Et6Cu4cj6fU4mV1mL21bl24hH6Qk5zr6Sm5VF49P1wV21xB326jg5Qc4fX4nZ6YO4CF1sF24Bp1vB21TR21Ax21gL26SI6Ye5q61BN25XE5Tn5Jt1Ah325Fr5t540x64i1Dz321Pz325gB5rl4f16yO5RN(这里开始修改)
1KP11V31EZ1Xl1JH31Pd31Cx1uj1931Xt1Lx31Bl38, 成功得到flag
[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界