比完后速度开肝WP
总分: 850 排名: 33
第一次这么长(shuang)时间肝比赛
3整天+1晚(理论上来说还有一早但我没用)
不得不说还是挺有意思的
PWN2 ememarm
aarch64架构
上网搜到了环境配置:
socat tcp-l:$port,fork exec:"$command",reuseaddr
譬如:
socat tcp-l:10002,fork exec:"qemu-aarch64 -g 1234 ememarm",reuseaddr
这样pwntools访问localhost:10002
, gdb remote localhost:1234
即可调试
当然在之前还要:
- 要有
qemu-aarch64
和patchelf
- 配置
/lib/ld-linux-aarch64.so.1
ln -s `pwd`/ld-linux-aarch64.so.1 /lib/ld-linux-aarch64.so.1
- 修改libc
patchelf --replace-needed libc.so.6 `pwd`/libc.so.6 $elf
这个方法同样适用于PWN1 emarm和IOT3 PPPPPPC以及所有与你本机架构不同的普通PWN题 (一般来说就是非Intel架构,除非你家是arm之类)
然后便可以看libc版本:
$ ./libc.so.6
GNU C Library (Ubuntu GLIBC 2.27-3ubuntu1) stable release version 2.27.
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 7.3.0.
libc ABIs: UNIQUE
For bug reporting instructions, please see:
<https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>.
2.27,有tcache
别忘了查看保护:
$ checksec ememarm
[*] '$PWD/ememarm'
Arch: aarch64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x3ff000)
再看程序逻辑:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int choice; // [xsp+1Ch] [xbp+1Ch]
int var; // [xsp+20h] [xbp+20h]
int count; // [xsp+24h] [xbp+24h]
void *v7; // [xsp+28h] [xbp+28h]
struc_1 *head; // [xsp+30h] [xbp+30h]
struc_1 *a2; // [xsp+38h] [xbp+38h]
struc_1 *ptr; // [xsp+40h] [xbp+40h]
buf_init();
count = 0;
v7 = &unk_412070;
printf("hello every one welcom my note ~~%lld\n", &unk_412070);
head = (struc_1 *)malloc(0x20uLL);
read(0LL, head, 24LL);
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
menu();
scanf("%d", &choice);
if ( choice != 1 )
break;
ptr = request();
puts("do you want delete?");
scanf("%d", &var);
if ( var == 1 )
add(head, ptr);
}
if ( choice != 2 || count > 10 )
break;
scanf("%d", &var);
noprint(head, var);
++count;
}
if ( choice != 3 || count > 10 )
break;
scanf("%d", &var);
edit(head, var);
++count;
}
if ( choice != 4 )
break;
a2 = request_big();
puts("do you want delete?");
scanf("%d", &var);
if ( var == 1 )
add(head, a2);
}
puts("bye bye bye!!\n");
free(head);
return 0;
}
常规菜单式堆题
应该能看出中间有结构体:
struc_1 struc ; (sizeof=0x20, mappedto_30)
x DCQ ?
y DCQ ?
field_10 DCQ ?
next DCQ ?
struc_1 ends
并且用next指针组成一个单向链表:
void __fastcall add(struc_1 *head, struc_1 *ptr)
{
struc_1 *i; // [xsp+8h] [xbp-8h]
for ( i = head; i->next; i = i->next )
;
i->next = ptr;
}
但注意print功能是假的:
__int64 __fastcall noprint(struc_1 *head, int pos)
{
int v3; // [xsp+14h] [xbp+14h]
struc_1 *v4; // [xsp+28h] [xbp+28h]
v3 = pos;
v4 = head->next;
if ( pos <= 0 )
puts("incrrect position to node");
if ( !v4 )
puts("the link empty");
while ( --v3 )
{
v4 = v4->next;
if ( !v4 )
{
puts("can't print it");
return puts("hahah i can't give you");
}
}
return puts("hahah i can't give you");
}
漏洞点是edit功能中有一个null off by one:
void __fastcall edit(struc_1 *head, int pos)
{
int i; // [xsp+14h] [xbp+14h]
struc_1 *ptr; // [xsp+20h] [xbp+20h]
i = pos;
ptr = head->next;
if ( head->x )
{
if ( pos >= 0 )
{
if ( !ptr )
puts("Link is empty");
while ( --i )
{
ptr = ptr->next;
if ( !ptr )
{
printf("no can't find it");
break;
}
}
if ( (unsigned int)read(0LL, ptr, 24LL) == 24 )
LOBYTE(ptr->next) =