BUU [vnctf2023]电子木鱼
先看看题目,点不了。
看看源码。Rust整数溢出。
在 Rust 中,整数类型默认是有符号整数类型,意味着这些整数类型可以表示正数和负数。对于有符号整数类型,最高位用来表示符号,0 表示正数,1 表示负数。 当一个正数进行整数溢出时,也就是它的值超过了它的类型所能表示的最大值,这个值会被截断为该类型的最小值。因为有符号整数类型的最高位表示符号,当这个值被截断时,最高位的值会变成 1,表示这个值是一个负数。 举个例子,假设使用 Rust 的 i8 类型,它的最大值是 127,最小值是 -128。如果一个 i8 类型的值为 120,然后将它加上 10,那么它的值就会溢出,变成 -126。这是因为 120 + 10 = 130,而 130 超过了 i8 类型的最大值 127,所以这个值会被截断为 -128 + (130 - 128) = -126。 因此,在 Rust 中,正数进行整数溢出后的结果会变成负数,这是由于有符号整数类型的设计所决定的。
核心代码: const PAYLOADS: &[Payload] = &[ Payload { name: "Cost", cost: 10, }, Payload { name: "Loan", cost: -1_000, }, Payload { name: "CCCCCost", cost: 500, }, Payload { name: "Donate", cost: 1, }, Payload { name: "Sleep", cost: 0, } ----------------------------------------------------------------------------------------- if GONGDE.get() > 1_000_000_000 { context.insert( "flag", &std::env::var("FLAG").unwrap_or_else(|_| "flag{test_flag}".to_string()), ); } ----------------------------------------------------------------------------------------- if cost != 0 { GONGDE.set(GONGDE.get() - cost as i32); } ----------------------------------------------------------------------------------------- #[post("/upgrade")] async fn upgrade(body: web::Form<Info>) -> Json<APIResult> { if GONGDE.get() < 0 { return web::Json(APIResult { success: false, message: "功德都搞成负数了,佛祖对你很失望", }); } if body.quantity <= 0 { return web::Json(APIResult { success: false, message: "佛祖面前都敢作弊,真不怕遭报应啊", }); } if let Some(payload) = PAYLOADS.iter().find(|u| u.name == body.name) { let mut cost = payload.cost; if payload.name == "Donate" || payload.name == "Cost" { cost *= body.quantity; } if GONGDE.get() < cost as i32 { return web::Json(APIResult { success: false, message: "功德不足", }); } if cost != 0 { GONGDE.set(GONGDE.get() - cost as i32); } if payload.name == "Cost" { return web::Json(APIResult { success: true, message: "小扣一手功德", }); } else if payload.name == "CCCCCost" { return web::Json(APIResult { success: true, message: "功德都快扣没了,怎么睡得着的", }); } else if payload.name == "Loan" { return web::Json(APIResult { success: true, message: "我向佛祖许愿,佛祖借我功德,快说谢谢佛祖", }); } else if payload.name == "Donate" { return web::Json(APIResult { success: true, message: "好人有好报", }); } else if payload.name == "Sleep" { return web::Json(APIResult { success: true, message: "这是什么?床,睡一下", }); } } web::Json(APIResult { success: false, message: "禁止开摆", }) }
post(“/upgrade”) //在/upgrade后台POST
//如果name=Cost,那么cost=10
//当GONGDE.get() > 1_000_000_000时返回flag
cost *= body.quantity; //在name=Donate或者Cost时,cost=cost乘quantity,超出上限会溢出(截断)
GONGDE.set(GONGDE.get() - cost as i32); //在i32情况下,GONGDE.get() =GONGDE.get() -cost,所以如果GONGDE.get() 要增加,cost<0
payload: name=Cost&quantity=2100000000