攻防世界&&BUUCTF逆向练习

BUUCTF——Youngter-drive

这是一道多线程的题目,主要理解了一下线程运行的一些问题
首先查壳,有壳,进行脱壳,手动失败了,linux里面upx -d就可以了
发现不能运行,应该需要修复,但这里比较懒,直接ida静态分析
攻防世界&&BUUCTF逆向练习_第1张图片
StartAddress开始无法反编译,因为堆栈不平很,这里修改sp value,option-general-Stack-pointer选项可以显示sp值,这时用alt+k修改411a04地址为00便可以F5
攻防世界&&BUUCTF逆向练习_第2张图片
攻防世界&&BUUCTF逆向练习_第3张图片
比较简单的加密,判断输入字符,不是英文,直接退出,大写就减去38,从给的off表里面寻找值替换,小写就减去96
后面还有一个线程就是直接对dword-418008进行-1,这边就涉及到我的知识盲区了,根据大佬wp,两个线程应该算是交替运行的,第一个运行一下sleep,然后第二个-1导致奇数进行加密,偶数不加密,最后得出对照的结果

不过这是我的个人理解,如果出错了,还望大佬们多多指正

然后代码

def ask(m,tab):
    c=""
    for i in range(len(m)):
       ind=tab.index(m[i])
       if(i % 2!=0):
           if(ind<=26):
                c+=chr(ind+96)
           else:
               c+=chr(ind+38)
       else:
           c+=m[i]
    return c
offs="QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm"
m="TOiZiZtOrYaToUwPnToBsOaOapsyS"
print (ask(m,offs))

最后比较的应该是30个字符串,后面要加一个字符,但不知道为什么大佬说在后面随便加,我试了试别的字符提交都失败了,就大佬加的E成功了,这里还是不清楚。。。。

附上大佬的wp,还有error of " positive sp value has been found"的讲解
https://l1b0.fun/2018/08/18/%E5%AE%89%E6%81%92%E6%9D%AF-7%E6%9C%88%E6%9C%88%E8%B5%9B-Reverse-Youngter-drive/
https://www.cnblogs.com/xunbu7/p/7779309.html

攻防世界——babymips

一个单纯的mips架构文件,可以放到jeb直接得到反编译代码,但是为了学习一下mips架构的汇编,这次就直接看的汇编语言,硬核分析,但是逻辑很简单,emmmmmm,还是太菜

.text:00400A1C loc_400A1C:                              # CODE XREF: sub_4009A8+DC↓j
.text:00400A1C                 lw      $v0, 0x48+var_30($fp)  # 将内存中的值加载到v0中
.text:00400A20                 addiu   $v1, $fp, 0x48+var_30
.text:00400A24                 addu    $v0, $v1, $v0    # v0的值就是我们输入的值
.text:00400A28                 lb      $v1, 4($v0)      # 取出我们输入的一个字符,放到v1里面去
.text:00400A2C                 lw      $v0, 0x48+var_30($fp)  # 取下标放到v0去
.text:00400A30                 nop
.text:00400A34                 andi    $v0, 0xFF
.text:00400A38                 li      $a0, 0x20        # 立即数0x20给了a0
.text:00400A3C                 subu    $v0, $a0, $v0    # 0x20-i,给了v0
.text:00400A40                 andi    $v0, 0xFF
.text:00400A44                 sll     $v0, 24
.text:00400A48                 sra     $v0, 24          # 这里都不用管,一个与FF,一个左移24位右移24位,最后没变化
.text:00400A4C                 xor     $v0, $v1, $v0    # v0=v1^v0,既输入值^(0x20-i)
.text:00400A50                 sll     $v1, $v0, 24
.text:00400A54                 sra     $v1, 24
.text:00400A58                 lw      $v0, 0x48+var_30($fp)  # 传回内存
.text:00400A5C                 addiu   $a0, $fp, 0x48+var_30
.text:00400A60                 addu    $v0, $a0, $v0
.text:00400A64                 sb      $v1, 4($v0)
.text:00400A68                 lw      $v0, 0x48+var_30($fp)
.text:00400A6C                 nop
.text:00400A70                 addiu   $v0, 1           	# 下标值加一
.text:00400A74                 sw      $v0, 0x48+var_30($fp)
.text:00400A78 loc_400A78:                              # CODE XREF: sub_4009A8+6C↑j
.text:00400A78                 lw      $v0, 0x48+var_30($fp)
.text:00400A7C                 nop
.text:00400A80                 slti    $v0, 0x20
.text:00400A84                 bnez    $v0, loc_400A1C  
.text:00400A88                 nop
.text:00400A8C                 lui     $v0, 0x41
.text:00400A90                 lw      $v1, _fdata		#这里_fdata里面存着的是检测的五个字符
.text:00400A94                 addiu   $v0, $fp, 0x48+var_2C
.text:00400A98                 li      $a2, 5           # 这里是比较前面的五个字符
.text:00400A9C                 move    $a1, $v1         # s2
.text:00400AA0                 move    $a0, $v0         # s1
.text:00400AA4                 jal     strncmp
.text:00400AA8                 nop
.text:00400AAC                 bnez    $v0, loc_400ACC
.text:00400AB0                 nop
.text:00400AB4                 addiu   $v0, $fp, 0x48+var_2C
.text:00400AB8                 move    $a0, $v0
.text:00400ABC                 jal     sub_4007F0			#第二个关键函数·
.text:00400AC0                 nop
.text:00400AC4                 b       loc_400ADC
.text:00400AC8                 nop

第一个函数做的大概就是每一个输入值与(0x20-i)进行了异或,然后先和开头的五个字符比较之后进入sub_4007F0函数

.text:00400814 loc_400814:                              # CODE XREF: sub_4007F0+13C↓j
.text:00400814                 lw      $v0, 0x28+var_10($fp)
.text:00400818                 nop
.text:0040081C                 andi    $v0, 1           # 判断奇偶
.text:00400820                 beqz    $v0, loc_400898
.text:00400824                 nop
.text:00400828                 lw      $v0, 0x28+var_10($fp)  # 下标给v0
.text:0040082C                 lw      $v1, 0x28+arg_0($fp)  # 容器给v1
.text:00400830                 nop
.text:00400834                 addu    $v0, $v1, $v0    # 我们输入的值,给v0
.text:00400838                 lb      $v0, 0($v0)
.text:0040083C                 nop
.text:00400840                 sra     $v0, 2
.text:00400844                 sll     $a0, $v0, 24
.text:00400848                 sra     $a0, 24          # a0=v0>>2
.text:0040084C                 lw      $v0, 0x28+var_10($fp)
.text:00400850                 lw      $v1, 0x28+arg_0($fp)
.text:00400854                 nop
.text:00400858                 addu    $v0, $v1, $v0
.text:0040085C                 lb      $v0, 0($v0)
.text:00400860                 nop
.text:00400864                 sll     $v0, 6
.text:00400868                 sll     $v1, $v0, 24
.text:0040086C                 sra     $v1, 24          # v1=v0<<6
.text:00400870                 lw      $v0, 0x28+var_10($fp)
.text:00400874                 lw      $a1, 0x28+arg_0($fp)
.text:00400878                 nop
.text:0040087C                 addu    $v0, $a1, $v0
.text:00400880                 or      $v1, $a0, $v1    # v0=v0|a1
.text:00400884                 sll     $v1, 24
.text:00400888                 sra     $v1, 24
.text:0040088C                 sb      $v1, 0($v0)
.text:00400890                 b       loc_400900
.text:00400894                 nop

这里通过下标奇偶进行不同操作,如果奇数则(v0>>2)|(v0<<6),偶数则(v0<<2)|(v0>>6)

下面这里是对剩下的27个数进行判断的
攻防世界&&BUUCTF逆向练习_第4张图片
最后python脚本

p="Q|j{g"
t=[0x52,0xFD,0x16,0xA4,0x89,0xBD,0x92,0x80,0x13,0x41,0x54,0xA0,0x8D,0x45,0x18,0x81,0xDE,0xFC,0x95,0xF0,0x16,0x79,0x1A,0x15,0x5B,0x75,0x1F]
for i in range(5):
    print(chr(ord(p[i])^0x20-i),end='')
p=0
f=0
for i in range(5,0x20):							#这里是个坑,emmmmmmmm后面函数操作的异或应该是从i=5开始
    for j in range(0,0x100):					的,当时我嫌麻烦,直接从0到27的,因为i变了,所以最后结果也不
        f=(j^((0x20-i)))								对0 -0
        if((i % 2)==0):
            p=((f<<2)%0x100)|(f>>6)
        else:
            p=(f>>2)|((f<<6)%0x100)
        if(p==t[i-5]):
            print(chr(j),end='')
            break

本文借鉴了大佬的wp,这里附上地址
https://blog.csdn.net/qq_40395770/article/details/81585732

还有一些工具地址
https://blog.csdn.net/ben_chong/article/details/51794392 mips指令详解
https://blog.csdn.net/ben_chong/article/details/51794093 mips指令表格
https://blog.csdn.net/yang_hong_/article/details/51016867

继续努力

你可能感兴趣的:(逆向题目练习)