@TOC
[2019红帽杯]easyRE elf文件,ida64打开,感兴趣的同学也可以开Linux系统看一看文件
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 v56 = __readfsqword(0x28 u); v14 = 73 ; v15 = 111 ; v16 = 100 ; v17 = 108 ; v18 = 62 ; v19 = 81 ; v20 = 110 ; v21 = 98 ; v22 = 40 ; v23 = 111 ; v24 = 99 ; v25 = 121 ; v26 = 127 ; v27 = 121 ; v28 = 46 ; v29 = 105 ; v30 = 127 ; v31 = 100 ; v32 = 96 ; v33 = 51 ; v34 = 119 ; v35 = 125 ; v36 = 119 ; v37 = 101 ; v38 = 107 ; v39 = 57 ; v40 = 123 ; v41 = 105 ; v42 = 121 ; v43 = 61 ; v44 = 126 ; v45 = 121 ; v46 = 76 ; v47 = 64 ; v48 = 69 ; v49 = 67 ; memset (v50, 0 , sizeof (v50)); v51 = 0 ; v52 = 0 ; v0 = v50; sub_4406E0(0LL , v50, 37LL ); v52 = 0 ; v1 = v50; if ( sub_424BA0(v50) == 36 ) { for ( i = 0 ; ; ++i ) { v1 = v50; if ( i >= (unsigned __int64)sub_424BA0(v50) ) break ; if ( (unsigned __int8)(v50[i] ^ i) != *(&v14 + i) ) { result = 4294967294LL ; goto LABEL_13; } } sub_410CC0((__int64)"continue!" ); memset (&v53, 0 , 0x40 uLL); v55 = 0 ; v0 = &v53; sub_4406E0(0LL , &v53, 64LL ); v54 = 0 ; v1 = &v53; if ( sub_424BA0(&v53) == 39 ) { v3 = sub_400E44((__int64)&v53); v4 = sub_400E44(v3); v5 = sub_400E44(v4); v6 = sub_400E44(v5); v7 = sub_400E44(v6); v8 = sub_400E44(v7); v9 = sub_400E44(v8); v10 = sub_400E44(v9); v11 = sub_400E44(v10); v12 = sub_400E44(v11); v0 = off_6CC090; v1 = (char *)v12; if ( !(unsigned int )sub_400360(v12, off_6CC090) ) { sub_410CC0((__int64)"You found me!!!" ); v1 = "bye bye~" ; sub_410CC0((__int64)"bye bye~" ); } result = 0LL ; } else { result = 4294967293LL ; } } else { result = 0xFFFFFFFF LL; } LABEL_13: if ( __readfsqword(0x28 u) != v56 ) sub_444020(v1, v0); return result; }
第一部分的处理是个异或,第二部分打开函数之后发现是base64的运算(10次),而且得到的结果与off_6cc090比较 先解出第一部分
1 2 3 4 5 str = [73 ,111 ,100 ,108 ,62 ,81 ,110 ,98 ,40 ,111 ,99 ,121 ,127 ,121 ,46 ,105 ,127 ,100 ,96 ,51 ,119 ,125 ,119 ,101 ,107 ,57 ,123 ,105 ,121 ,61 ,126 ,121 ,76 ,64 ,69 ,67 ]input1 = '' for i in range (len (str )): input1 += chr (str [i]^i) print(input1)
第二部分用在线工具解十次base64,解出来发现是个网站https://bbs.pediy.com/thread-254172.htm 打开发现没有用,是个干扰项 看了其他师傅的wp后才知道,在我们base64加密结束后,下面有调用一个sub_400D35的函数 过去看看 24行判断第一个和第四个是不是f和g,那就猜测这四个字符是flag。
然后循环24次做异或操作。
1 2 3 4 5 6 num2=[0x40 ,0x35 ,0x20 ,0x56 ,0x5D ,0x18 ,0x22 ,0x45 ,0x17 ,0x2F ,0x24 ,0x6E ,0x62 ,0x3C ,0x27 ,0x54 ,0x48 ,0x6C ,0x24 ,0x6E ,0x72 ,0x3C ,0x32 ,0x45 ,0x5B ] text2='flag' key='' for i in range (0 ,4 ): key=key+chr (ord (text2[i])^num2[i]) print (key)
得到v5 == &YA1 在求出v2
1 2 3 4 5 6 num2=[0x40 ,0x35 ,0x20 ,0x56 ,0x5D ,0x18 ,0x22 ,0x45 ,0x17 ,0x2F ,0x24 ,0x6E ,0x62 ,0x3C ,0x27 ,0x54 ,0x48 ,0x6C ,0x24 ,0x6E ,0x72 ,0x3C ,0x32 ,0x45 ,0x5B ] key='&YA1' flag='' for i in range (0 ,25 ): flag=flag+chr (num2[i]^ord (key[i%4 ])) print(flag)
flag是:flag{Act1ve_Defen5e_Test}
[ACTF新生赛2020]rome ida 32 ,通过main函数或者字符串搜索都可以找到函数func()
发现其实就是将输入的字符串大写和小写分开进行变换,然后比较输出 写一个脚本跑一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 v15= [81 ,115 ,119 ,51 ,115 ,106 ,95 ,108 ,122 ,52 ,95 ,85 ,106 ,119 ,64 ,108 ] flag="" for i in range (16 ): for j in range (128 ): x=j if chr (x).isupper(): x=(x-51 )%26 +65 if chr (x).islower(): x=(x-79 )%26 +97 if chr (x)==chr (v15[i]): flag+=chr (j) print ('flag{' +flag+'}' )
flag{Cae3ar_th4_Gre@t}
[FlareOn4]login 网页打开,F12查看HTML源码var rotFlag = flag.replace(/[a-zA-Z]/g, function(c){return String.fromCharCode((c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26);});
这句代码的意思就是将字符后移13位,越界了就转回字母开头,最后得到了字符串PyvragFvqrYbtvafNerRnfl@syner-ba.pbz
其实就是ROT13,找一个在线网站解一下,得到:
1 ClientSideLoginsAreEasy@flare-on.com
flag是:flag{ClientSideLoginsAreEasy@flare-on.com}
Youngter-drive
kali脱壳 ida打开,找到主函数 大致是这样,我们依次看一下 函数sub_4110FF()
输出部分:函数sub_411190()
然后着重看一下两个线程的处理 线程1:StartAddress
看函数sub_41112C
,函数sub_411940
这里会出现报错,函数sub_411940
无法反编译 是由于堆栈不平衡的问题,一般是程序有一些干扰代码,让IDA的反汇编分析出现错误。比如用push + n条指令 + retn来跳转。搜索这个函数,看汇编窗口: Option->General->Disassembly, 将选项Stack pointer打钩 然后就可以看见汇编窗口汇编指令前面有绿色的SP值 找到这串函数的retn指令 可以发现前面的SP值变成了负数,我们需要修改它成0使得堆栈保持平衡。 找到距离retn最近的call指令 alt+k修改SP值 修改之后 然后就可以可以查看 线程2:函数sub_41119F()
线程2并不对代码做任何处理,只是调用一次Sleep然后释放线程。
这里说一个细节,这道题是线程1和线程2 交替执行的,因为函数CreateMutex()
这个函数是创建两个相互排斥的线程的函数,hobject 可以理解为一个“锁”,两个线程依次获取锁(waitforsingleobject),释放锁(releasemutex)。一个线程开始之后,抢占了锁,这时候另一个线程没抢到,处于等待状态,等待运行线程执行完成之后第一个线程解锁。 不能用来控制两个以上的线程,因为剩下的几个线程都有几率抢到,会导致程序逻辑混乱。 两个线程时候,第一次抢到锁的线程在释放后也会和第二个线程抢锁,但是由于它此时没有第二个线程快,所以抢不到,就造成了两个线程交替被调用的现状。
所以这题就是奇数的会被线程1处理而偶数走线程2 不处理(因为是从29往下减的)
写脚本
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 #include <stdio.h> int main () { char off1[] = "TOiZiZtOrYaToUwPnToBsOaOapsyS" ; char off2[] = "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm" ; char flag[30 ]={0 }; int i,j; for (i=28 ;i>-1 ;i--) { if (i%2 ==0 ) { flag[i] = off1[i]; continue ; } for (j=0 ;j<52 ;j++) { if (off1[i] == off2[j]) { flag[i] = j+38 ; if (!(flag[i]>=65 &&flag[i]<=90 )) flag[i] = j+96 ; break ; } } } puts (flag); return 0 ; }
这里还有一个问题,就是最后输出flag的函数,它显示的是比较i<29 而实际上进程处理的时候是到>-1的,也就是其实应该是30个字符 也就是说少了一位我们不知道,需要一个个英文字母试出来,发现是“E”
flag:flag{ThisisthreadofwindowshahaIsESE}