java伪造http请求ip地址,简单投票网站重复投票,黑别人网站

注意:伪造Http请求IP地址一般为非推荐使用手段

一般使用:简单投票网站重复投票,黑别人网站

在项目开发中(web项目),我负责的系统(简称PC),需要调其它系统接口,并且该系统需要获取客户端(浏览器访问端)的IP地址,给我愁死了,

正常流程:浏览器---访问PC系统----PC系统需要调第三方系统,此时默认情况下,PC发起的request请求IP地址是PC所在服务器的IP地址,而不是请求浏览器端的IP地址

所以,就想着是否能把request里的IP地址给修改了,因为在PC系统里是能获取到请求IP地址的,结果是修改不了

最后了解到:可以在http请求头里,追加一个头信息(名称:x-forwarded-for),它会位于原始IP地址之前,所以当第三方系统获取地址时,就获取到了真实的浏览器访问地址IP了

本代码以java为列:

X-Forwarded-For:简称XFF头,它代表客户端,也就是HTTP的请求端真实的IP,只有在通过了HTTP 代理或者负载均衡服务器时才会添加该项。

httpPost.addHeader("x-forwarded-for",ip);

详细代码如下:

package com.sh.portal.framework.client.http; import java.io.IOException; import org.apache.commons.lang.StringUtils; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.message.BasicHeader; import org.apache.http.protocol.HTTP; import org.apache.http.util.EntityUtils; import org.springframework.stereotype.Component; import com.sh.portal.framework.client.RemoteServerArgs; import com.sh.portal.framework.client.RemoteServerClient; import com.sh.portal.framework.client.RemoteServerResponse; import com.sh.portal.util.CommonUtils; @Component public class RemoteServerClientImpl implements RemoteServerClient { private static final String DEFAULT_ENCODE = "UTF-8"; private static final String APPLICATION_JSON = "application/json"; @Override public RemoteServerResponse post(RemoteServerArgs args) throws IOException { String ip = CommonUtils.getRequestIpAddress(); // 创建HttpClientBuilder HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); // HttpClient CloseableHttpClient closeableHttpClient = httpClientBuilder.build(); // 请求参数 StringEntity entity = new StringEntity(args.getRequestJson(), DEFAULT_ENCODE); entity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, APPLICATION_JSON)); HttpPost httpPost = new HttpPost(args.getUrl()); httpPost.addHeader(HTTP.CONTENT_TYPE, APPLICATION_JSON); //此处区别PC终端类型 httpPost.addHeader("typeFlg", "9"); //此处增加浏览器端访问IP if(!ip.equals("")){ httpPost.addHeader("x-forwarded-for",ip); } httpPost.setEntity(entity); httpPost.setConfig(RequestConfig.DEFAULT); HttpResponse httpResponse; // post请求 httpResponse = closeableHttpClient.execute(httpPost); HttpEntity httpEntity = httpResponse.getEntity(); RemoteServerResponse response; if (httpEntity != null) { response = new RemoteServerResponse(httpResponse.getStatusLine().getStatusCode(), EntityUtils.toString(httpEntity, DEFAULT_ENCODE)); } else { response = new RemoteServerResponse(httpResponse.getStatusLine().getStatusCode(), StringUtils.EMPTY); } //释放资源 closeableHttpClient.close(); return response; } }

最近做接口开发,需要跟第三方系统对接接口,基于第三方系统接口的保密性,需要将调用方的请求IP加入到他们的白名单中。由于我们公司平常使用的公网的IP是不固定的,每次都需要将代码提交到固定的服务器上(服务器IP加入了第三方系统的白名单),频繁的修改提交合并代码和启动服务器造成了额外的工作量,给接口联调带来了很大的阻碍。

正常的http请求

我们正常发起一个http的请求如下:import org.apache.http.HttpEntity;import org.apache.http.client.config.RequestConfig;import org.apache.http.client.methods.CloseableHttpResponse;import org.apache.http.client.methods.HttpPost;import org.apache.http.entity.StringEntity;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClients;import org.apache.http.util.EntityUtils;public static String getPost4Json(String url, String json) throws Exception {CloseableHttpClient httpClient = HttpClients.createDefault();HttpPost httpPost = new HttpPost(url);/* 设置超时 */RequestConfig defaultRequestConfig = RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(5000).setConnectionRequestTimeout(5000).build();httpPost.setConfig(defaultRequestConfig);httpPost.addHeader("Content-Type", "application/json;charset=UTF-8");httpPost.setEntity(new StringEntity(json, "UTF-8"));CloseableHttpResponse response = null;String result = null;try {response = httpClient.execute(httpPost);HttpEntity entity = response.getEntity();result = EntityUtils.toString(entity, "UTF-8");} catch (Exception e) {throw e;} finally {if (response != null) response.close();httpClient.close();}return result;}

由于没有加入白名单的原因,这样的请求显然无法调用到第三方的接口。这时候考虑能否将请求的ip改为白名单的一个ip,服务器在解析时拿到的不是正常的ip,这样能否正常调用呢?

伪造http请求ip地址

我们知道正常的tcp/ip在通信过程中是无法改变源ip的,也就是说电脑获取到的请求ip是不能改变的。但是可以通过伪造数据包的来源ip,即在http请求头加一个x-forwarded-for的头信息,这个头信息配置的是ip地址,它代表客户端,也就是HTTP的请求端真实的IP。因此在上面代码中加上如下代码:

httpPost.addHeader("x-forwarded-for",ip);

服务端通过x-forwarded-for获取请求ip,并且校验IP安全性,代码如下:

String ip = request.getHeader("x-forwarded-for");

总结

通过请求头追加x-forwarded-for头信息可以伪造http请求ip地址。但是若服务器不直接信任并且不使用传递过来的 X-Forward-For 值的时候伪造IP就不生效了。