๐งก fishing ์ค๋ช
pwnable.xyz ๋ฌธ์ ์ค์ ์ฌ๋ฏธ์๊ฒ ํผ ๋ฌธ์ ๊ฐ ์์ด์ ์๊ฐํด๋ณด๋ ค๊ณ ํ๋ค. binary๋ฅผ ๋ด๋ณด๋๋ก ํ์.
undefined8 main(void)
{
undefined4 uVar1;
setup();
banner();
do {
show_menu();
uVar1 = read_int();
switch(uVar1) {
default:
err("Invalid choice");
break;
case 1:
add_group_member();
break;
case 2:
modify_group_member();
break;
case 3:
write_in_book();
break;
case 4:
go_fishing();
break;
case 5:
stop_fishing();
break;
case 6:
puts("Bye. I\'m keeping the deposit");
return 0;
}
} while( true );
}
main ํจ์๋ ์ด๋ ๊ฒ ์๊ฒผ๋ค.
void add_group_member(void)
{
undefined4 uVar1;
void **ppvVar2;
void *pvVar3;
if (group_size < 6) {
ppvVar2 = (void **)malloc(0x20);
pvVar3 = malloc(0x18);
*ppvVar2 = pvVar3;
__printf_chk(1,"Name: ");
read_string(*ppvVar2,0x18);
pvVar3 = malloc(0x18);
ppvVar2[1] = pvVar3;
__printf_chk(1,"Job: ");
read_string(ppvVar2[1],0x18);
__printf_chk(1,"Age: ");
uVar1 = read_int();
*(undefined4 *)(ppvVar2 + 2) = uVar1;
*(void ***)(group + (long)group_size * 8) = ppvVar2;
group_size = group_size + 1;
return;
}
puts("You would sink the boat with that many people");
return;
group member์ ์์ฑํ๋ ํจ์๋ค. heap ๊ตฌ์กฐ๋ ๋์ถฉ ์ด๋ ๊ฒ ์๊ฒผ๋ค.
void modify_group_member(void)
{
undefined8 *puVar1;
uint uVar2;
undefined4 uVar3;
puts("Which person do you need to change?");
uVar2 = read_int();
if (5 < uVar2) {
puts("A group member can only be 0-5");
return;
}
puVar1 = *(undefined8 **)(group + (long)(int)uVar2 * 8);
if (puVar1 != (undefined8 *)0x0) {
__printf_chk(1,"Name: ");
read_string(*puVar1,0x18);
__printf_chk(1,"Job: ");
read_string(puVar1[1],0x18);
__printf_chk(1,"Age: ");
uVar3 = read_int();
*(undefined4 *)(puVar1 + 2) = uVar3;
return;
}
puts("That person doesn\'t exist");
return;
}
๋จ์ํ group member์ ์ ๋ณด๋ฅผ ์์ ํ๋ ํจ์๋ค.
void write_in_book(void)
{
void *pvVar1;
puts("What do you want to say?");
pvVar1 = malloc(0x20);
read_string(pvVar1,0x20);
return;
}
์๋ฌด๋ฐ ์กฐ๊ฑด ์์ด 0x20 size๋ฅผ ๊ฐ์ง heap์ ์์ฑํ ์ ์๋ค.
void go_fishing(void)
{
long in_FS_OFFSET;
pthread_t pStack24;
long local_10;
local_10 = *(long *)(in_FS_OFFSET + 0x28);
if (fishing == 0) {
if (group_size < 2) {
puts("You need 2 or more people to fish");
}
else {
fishing = 1;
pthread_create(&pStack24,(pthread_attr_t *)0x0,gone_fishing,(void *)0x0);
puts("You\'re group has now left to catch some fish");
}
}
else {
puts("You\'re group is already fishing, wait until they come back");
}
if (local_10 == *(long *)(in_FS_OFFSET + 0x28)) {
return;
}
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
์ด ๋ถ๋ถ์ด ์ฌ๋ฏธ์๋๋ฐ, ์ผ๋จ ๋์๋ฅผ ๊ฐ๋ ค๋ฉด group size๊ฐ 2 ์ด์์ด์ด์ผ ํ๋ค. ๊ทธ๋ฆฌ๊ณ , gone_fishing ํจ์๋ฅผ ์คํํ๋๋ฐ ์ด ๋ถ๋ถ์์ ์ค๋ ๋๋ฅผ ์์ฑํ๋ค.
void remove_person(int param_1)
{
void **__ptr;
__ptr = *(void ***)(group + (long)param_1 * 8);
if (__ptr != (void **)0x0) {
free(*__ptr);
free(__ptr[1]);
free(__ptr);
return;
}
return;
}
undefined8 gone_fishing(void)
{
int iVar1;
iVar1 = pthread_mutex_lock((pthread_mutex_t *)mutex);
if (iVar1 != 0) {
err("Fatal locking");
}
iVar1 = group_size + -1;
puts("\n!!!!ALERT!!!");
__printf_chk(1,"%s has fallen over board\n",**(undefined8 **)(group + (long)iVar1 * 8));
puts("We are trying to save them");
remove_person(iVar1);
iVar1 = pthread_cond_wait((pthread_cond_t *)cond,(pthread_mutex_t *)mutex);
if (iVar1 != 0) {
err("Fatal");
}
puts("\nOk we are coming back. Btw they died...");
group_size = group_size + -1;
fishing = 0;
iVar1 = pthread_mutex_unlock((pthread_mutex_t *)mutex);
if (iVar1 != 0) {
err("Fatal unlocking");
}
return 0;
}
์ด ํจ์๋ ์ด๋ ๊ฒ ์๊ฒผ๋ค. ์ผ๋จ ํจ์๋ฅผ ์คํํ๋ฉด mutex๋ฅผ ์ด์ฉํด ์ค๋ ๋์ ๋ฝ์ ๊ฑด๋ค. ๊ทธ๋ฆฌ๊ณ ์์ฃผ ๋ถ์ํ๊ฒ๋ ๋ง์ง๋ง ๊ทธ๋ฃน์ ์๋ ์ฌ๋์ ๊ฐํ ๋ฐ์ผ๋ก ๋จ์ด์ง๊ฒ ๋๋ค ใ ใ .. ๋จ์ด์ง ๊ทธ๋ฃน์ ์ธ์๋ก ๊ฐ๊ณ remove_person์ ์คํํ๋๋ฐ ์ด ํจ์์์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
heap์ ํ ๋นํ๋ ์์๋ name -> job ์์์ธ๋ฐ, ํด๋น ํจ์์์๋ ๋ฐ๋๋ก free ํ๋ค. ๋ํ ์ ์ญ๋ณ์์ ์๋ data์ heap์ ์๋ data๋ฅผ ์ง์ฐ์ง ์๊ธฐ ๋๋ฌธ์ UAF๊ฐ ๋ฐ์ํ๋ค.
๊ทธ๋ฆฌ๊ณ cond signal์ด ์ฌ ๋๊น์ง ์ค๋ ๋๋ฅผ ๋๊ธฐ ์ํ๋ก ์ ํํ๋ค.
void stop_fishing(void)
{
int iVar1;
if (fishing == 0) {
puts("You\'re group is not fishing");
return;
}
iVar1 = pthread_cond_signal((pthread_cond_t *)cond);
if (iVar1 == 0) {
return;
}
err("Fatal signaling");
return;
}
์ด ํจ์๋ฅผ ์คํํ๋ฉด cond signal์ ๋ฐ์์ํจ๋ค.
๐งก Attack Vector
์์์ ๋งํ๋ค ์ถ์ด UAF๋ฅผ ์ด์ฉํด์ heap์ ์กฐ์ํ๋ฉด ๋๋ค. ์ ๋นํ ๋ง์ ธ์ฃผ๊ณ heap_base, pie_base๋ฅผ leakํ ๋ค์์ GOT overwrite๋ก win ํจ์๋ฅผ ์คํํด์ฃผ๋ฉด ๋๋๋ค.
'Wargame > pwnable.xyz' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[pwnable.xyz] All Clear (0) | 2021.07.17 |
---|---|
[pwnable.xyz] Heap - House of Force ๋ณต์ต (note v3) (2) | 2021.07.09 |
[pwnable.xyz] executioner v2 ์ฝ์ง (2) | 2021.07.03 |
[pwnable.xyz] executioner trick(?) (2) | 2021.07.01 |
[pwnable.xyz] Free spirit trick ์๊ฐ (2) | 2021.06.26 |